| /** |
| * 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); |
| } |