blob: 45a18f95cef6eed46f86facad802bcf8b6415063 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/*
* XSEC
*
* DSIGXPathFilterExpr := Class that holds an XPath Filter expression
*
* Author(s): Berin Lautenbach
*
* $Id$
*
*/
#include <xsec/dsig/DSIGSignature.hpp>
#include <xsec/dsig/DSIGXPathFilterExpr.hpp>
#include <xsec/framework/XSECDefs.hpp>
#include <xsec/framework/XSECException.hpp>
#include <xsec/framework/XSECEnv.hpp>
#include "../utils/XSECDOMUtils.hpp"
#include <xercesc/dom/DOMNode.hpp>
#include <xercesc/dom/DOMNamedNodeMap.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
XERCES_CPP_NAMESPACE_USE
XMLCh filterStr[] = {
chLatin_F,
chLatin_i,
chLatin_l,
chLatin_t,
chLatin_e,
chLatin_r,
chNull
};
// --------------------------------------------------------------------------------
// Constructors and Destructors
// --------------------------------------------------------------------------------
DSIGXPathFilterExpr::DSIGXPathFilterExpr(const XSECEnv* env, DOMNode* node) :
mp_env(env),
mp_xpathFilterNode(node),
mp_exprTextNode(NULL),
mp_NSMap(NULL),
m_filterType(FILTER_UNION),
m_loaded(false) {
}
DSIGXPathFilterExpr::DSIGXPathFilterExpr(const XSECEnv* env) :
mp_env(env),
mp_xpathFilterNode(NULL),
mp_exprTextNode(NULL),
mp_NSMap(NULL),
m_filterType(FILTER_UNION),
m_loaded(false) {
}
DSIGXPathFilterExpr::~DSIGXPathFilterExpr() {}
// --------------------------------------------------------------------------------
// Load existing DOM structure
// --------------------------------------------------------------------------------
void DSIGXPathFilterExpr::load() {
// Find the XPath expression
if (mp_xpathFilterNode == NULL ||
!strEquals(getXPFLocalName(mp_xpathFilterNode), "XPath")) {
throw XSECException(XSECException::ExpectedDSIGChildNotFound,
"Expected <XPath> as first node in DSIGXPathFilterExpr::load");
}
// Check for attributes - in particular any namespaces
mp_NSMap = mp_xpathFilterNode->getAttributes();
// Find the filter type
DOMNode * a;
if (mp_NSMap == NULL ||
((a = mp_NSMap->getNamedItem(filterStr)) == NULL)) {
throw XSECException(XSECException::ExpectedDSIGChildNotFound,
"Expected Filter attribute of <XPath> node in in DSIGXPathFilterExpr::load");
}
const XMLCh * f = a->getNodeValue();
if (strEquals(f, "intersect")) {
m_filterType = FILTER_INTERSECT;
}
else if (strEquals(f, "union")) {
m_filterType = FILTER_UNION;
}
else if (strEquals(f, "subtract")) {
m_filterType = FILTER_SUBTRACT;
}
else {
throw XSECException(XSECException::ExpectedDSIGChildNotFound,
"DSIGXPathFilterExpr::load Expected on of intersect, union or subtract as filter type");
}
// Find the text node
mp_exprTextNode = findFirstChildOfType(mp_xpathFilterNode, DOMNode::TEXT_NODE);
if (mp_exprTextNode == NULL) {
throw XSECException(XSECException::ExpectedDSIGChildNotFound,
"Expected Text Node in beneath <XPath> in DSIGXPathFilterExpr::load");
}
// Gather the text - hold it in UTF16 format
gatherChildrenText(mp_xpathFilterNode, m_expr);
m_loaded = true;
}
// --------------------------------------------------------------------------------
// Create a new filter
// --------------------------------------------------------------------------------
DOMElement* DSIGXPathFilterExpr::setFilter(DSIGXPathFilterExpr::XPathFilterType filterType,
const XMLCh * filterExpr) {
if (m_loaded == true) {
throw XSECException(XSECException::XPathFilterError,
"DSIGXPathFilterExpr::setFilter - called when already loaded");
}
safeBuffer str;
const XMLCh * prefix;
DOMDocument *doc = mp_env->getParentDocument();
DOMElement * xe;
// Create the XPath element
prefix = mp_env->getXPFNSPrefix();
makeQName(str, prefix, "XPath");
xe = doc->createElementNS(DSIGConstants::s_unicodeStrURIXPF, str.rawXMLChBuffer());
mp_xpathFilterNode = xe;
// Put in correct namespace
prefix = mp_env->getXPFNSPrefix();
// Set the namespace attribute
if (prefix[0] == '\0') {
str.sbTranscodeIn("xmlns");
}
else {
str.sbTranscodeIn("xmlns:");
str.sbXMLChCat(prefix);
}
xe->setAttributeNS(DSIGConstants::s_unicodeStrURIXMLNS,
str.rawXMLChBuffer(),
DSIGConstants::s_unicodeStrURIXPF);
// Set the filter type
m_filterType = filterType;
switch (filterType) {
case FILTER_INTERSECT :
xe->setAttributeNS(NULL,MAKE_UNICODE_STRING("Filter"), MAKE_UNICODE_STRING("intersect"));
break;
case FILTER_SUBTRACT :
xe->setAttributeNS(NULL,MAKE_UNICODE_STRING("Filter"), MAKE_UNICODE_STRING("subtract"));
break;
case FILTER_UNION :
xe->setAttributeNS(NULL,MAKE_UNICODE_STRING("Filter"), MAKE_UNICODE_STRING("union"));
break;
default :
mp_xpathFilterNode->release();
throw XSECException(XSECException::XPathFilterError,
"DSIGXPathFilterExpr::appendFilter - Unexpected Filter Type");
}
// Now add the actual filter
mp_exprTextNode = doc->createTextNode(filterExpr);
mp_xpathFilterNode->appendChild(mp_exprTextNode);
mp_NSMap = mp_xpathFilterNode->getAttributes();
m_expr.sbXMLChIn(filterExpr);
m_loaded = true;
return xe;
}
// --------------------------------------------------------------------------------
// Find the type
// --------------------------------------------------------------------------------
DSIGXPathFilterExpr::XPathFilterType DSIGXPathFilterExpr::getFilterType() const {
if (m_loaded == false) {
throw XSECException(XSECException::LoadEmptyXPathFilter,
"DSIGXPathFilterExpr::Element node loaded");
}
return m_filterType;
}
// --------------------------------------------------------------------------------
// Set and clear namespaces
// --------------------------------------------------------------------------------
void DSIGXPathFilterExpr::setNamespace(const XMLCh* prefix, const XMLCh* value) {
if (mp_xpathFilterNode == NULL) {
throw XSECException(XSECException::XPathFilterError,
"DSIGXPathFilterExpr::setNamespace - load not called");
}
safeBuffer str;
str.sbTranscodeIn("xmlns:");
str.sbXMLChCat(prefix);
DOMElement* x = static_cast <DOMElement *> (mp_xpathFilterNode);
x->setAttributeNS(DSIGConstants::s_unicodeStrURIXMLNS,
str.rawXMLChBuffer(),
value);
mp_NSMap = mp_xpathFilterNode->getAttributes();
}
void DSIGXPathFilterExpr::deleteNamespace(const XMLCh* prefix) {
if (mp_xpathFilterNode == NULL) {
throw XSECException(XSECException::XPathFilterError,
"DSIGXPathFilterExpr::deleteNamespace - load not called");
}
DOMElement* x = static_cast <DOMElement *> (mp_xpathFilterNode);
x->removeAttributeNS(DSIGConstants::s_unicodeStrURIXMLNS, prefix);
}