blob: 289294ff0b2673620993409b768cef5c7e3102f3 [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
*
* TXFMEnvelope := Class that calculates an Envelope with an XPath evaluator
*
* $Id$
*
*/
#include <xsec/framework/XSECException.hpp>
#include <xsec/transformers/TXFMEnvelope.hpp>
#include "../utils/XSECDOMUtils.hpp"
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
XERCES_CPP_NAMESPACE_USE
TXFMEnvelope::TXFMEnvelope(DOMDocument *doc) :
TXFMBase(doc) {
}
TXFMEnvelope::~TXFMEnvelope() {
}
// Methods to set the inputs
void TXFMEnvelope::setInput(TXFMBase *newInput) {
input = newInput;
if (newInput->getOutputType() != TXFMBase::DOM_NODES) {
throw XSECException(XSECException::TransformInputOutputFail, "XPath requires DOM_NODES input type");
}
// Expand if necessary
//this->expandNameSpaces();
keepComments = input->getCommentsStatus();
// Set up for the new document
mp_document = input->getDocument();
// Now work out what we have to set up in the new processing
TXFMBase::nodeType inputType = input->getNodeType();
switch (inputType) {
case DOM_NODE_DOCUMENT :
mp_startNode = mp_document;
break;
case DOM_NODE_DOCUMENT_FRAGMENT :
mp_startNode = input->getFragmentNode();
break;
default :
throw XSECException(XSECException::EnvelopeError); // Should never get here
}
// Ready to evaluate
}
// Methods to get tranform output type and input requirement
TXFMBase::ioType TXFMEnvelope::getInputType(void) const {
return TXFMBase::DOM_NODES;
}
TXFMBase::ioType TXFMEnvelope::getOutputType(void) const {
return TXFMBase::DOM_NODES;
}
TXFMBase::nodeType TXFMEnvelope::getNodeType(void) const {
return TXFMBase::DOM_NODE_XPATH_NODESET;
}
// Envelope (and XPath) unique
void addEnvelopeNode(DOMNode *startNode, XSECXPathNodeList & XPathMap, DOMNode * sigNode) {
XSEC_USING_XERCES(DOMNamedNodeMap);
DOMNode *tmp;
DOMNamedNodeMap *atts;
XMLSize_t attsSize, i;
if (startNode == sigNode)
return;
XPathMap.addNode(startNode);
if (startNode->getNodeType() == DOMNode::ELEMENT_NODE) {
atts = startNode->getAttributes();
if (atts != NULL)
attsSize = atts->getLength();
else
attsSize = 0;
for (i = 0; i < attsSize; ++i) {
tmp = atts->item(i);
XPathMap.addNode(tmp);
}
}
// Now do any childeren
tmp = startNode->getFirstChild();
while (tmp != NULL) {
addEnvelopeNode(tmp, XPathMap, sigNode);
tmp = tmp->getNextSibling();
}
}
void addEnvelopeParentNSNodes(DOMNode *startNode, XSECXPathNodeList & XPathMap) {
XSEC_USING_XERCES(DOMNamedNodeMap);
DOMNode *tmp;
DOMNamedNodeMap *atts;
XMLSize_t attsSize, i;
if (startNode == NULL)
return;
if (startNode->getNodeType() == DOMNode::ELEMENT_NODE) {
atts = startNode->getAttributes();
if (atts != NULL)
attsSize = atts->getLength();
else
attsSize = 0;
for (i = 0; i < attsSize; ++i) {
tmp = atts->item(i);
if (XMLString::compareNString(tmp->getNodeName(), DSIGConstants::s_unicodeStrXmlns, 5) == 0 &&
(tmp->getNodeName()[5] == chNull || tmp->getNodeName()[5] == chColon))
XPathMap.addNode(tmp);
}
}
// Now do parent
addEnvelopeParentNSNodes(startNode->getParentNode(), XPathMap);
}
void TXFMEnvelope::evaluateEnvelope(DOMNode *t) {
DOMNode *sigNode;
// Find the signature node
sigNode = t->getParentNode();
while (sigNode != NULL && !strEquals(getDSIGLocalName(sigNode), "Signature"))
sigNode = sigNode->getParentNode();
if (sigNode == NULL) {
throw XSECException(XSECException::EnvelopeError,
"Unable to find signature owner of node passed to Envelope Transform");
}
// Check if sigNode is an ancestor of mp_startNode - if so, just return
DOMNode * c = mp_startNode;
while (c != NULL) {
if (c == sigNode)
return;
c = c->getParentNode();
}
addEnvelopeNode(mp_startNode, m_XPathMap, sigNode);
addEnvelopeParentNSNodes(mp_startNode->getParentNode(), m_XPathMap);
}
// Methods to get output data
unsigned int TXFMEnvelope::readBytes(XMLByte * const toFill, unsigned int maxToFill) {
return 0;
}
DOMDocument *TXFMEnvelope::getDocument() const {
return mp_document;
}