| /** |
| * 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 |
| * |
| * XSECNameSpaceExander := Class for expanding out a document's name space axis |
| * and then shrinking again |
| * |
| * $Id$ |
| * |
| */ |
| |
| // XSEC Includes |
| #include <xsec/utils/XSECNameSpaceExpander.hpp> |
| #include <xsec/dsig/DSIGConstants.hpp> |
| #include <xsec/framework/XSECError.hpp> |
| |
| #include "XSECDOMUtils.hpp" |
| |
| XERCES_CPP_NAMESPACE_USE |
| |
| XSECNameSpaceExpander::XSECNameSpaceExpander(DOMDocument *d) { |
| |
| mp_doc = d; |
| mp_fragment = d->getDocumentElement(); |
| XSECnew(mp_formatter, XSECSafeBufferFormatter("UTF-8",XMLFormatter::NoEscapes, |
| XMLFormatter::UnRep_CharRef)); |
| |
| m_expanded = false; |
| |
| } |
| |
| XSECNameSpaceExpander::XSECNameSpaceExpander(DOMElement *f) { |
| |
| mp_doc = NULL; |
| mp_fragment = f; |
| XSECnew(mp_formatter, XSECSafeBufferFormatter("UTF-8",XMLFormatter::NoEscapes, |
| XMLFormatter::UnRep_CharRef)); |
| |
| m_expanded = false; |
| |
| } |
| |
| XSECNameSpaceExpander::~XSECNameSpaceExpander() { |
| |
| if (mp_formatter != NULL) |
| delete mp_formatter; |
| |
| } |
| |
| void XSECNameSpaceExpander::recurse(DOMElement *n) { |
| |
| // Recursively go down the tree adding namespaces |
| |
| DOMNode *p = n->getParentNode(); |
| if (p->getNodeType() != DOMNode::ELEMENT_NODE) |
| return; |
| |
| DOMNamedNodeMap *pmap = p->getAttributes(); |
| XMLSize_t psize = pmap->getLength(); |
| |
| DOMNamedNodeMap *nmap = n->getAttributes(); |
| |
| safeBuffer pname, pURI, nURI; |
| DOMNode *finder; |
| |
| XSECNameSpaceEntry * tmpEnt; |
| |
| for (XMLSize_t i = 0; i < psize; i++) { |
| |
| // Run through each parent node to find namespaces |
| pname << (*mp_formatter << pmap->item(i)->getNodeName()); |
| |
| // See if this is an xmlns node |
| |
| if (pname.sbStrncmp("xmlns", 5) == 0) { |
| |
| // It is - see if it already exists |
| finder = nmap->getNamedItem(pname.sbStrToXMLCh()); |
| if (finder == 0) { |
| |
| // Need to add |
| n->setAttributeNS(DSIGConstants::s_unicodeStrURIXMLNS, |
| pmap->item(i)->getNodeName(), |
| pmap->item(i)->getNodeValue()); |
| |
| // Add it to the list so it can be removed later |
| XSECnew(tmpEnt, XSECNameSpaceEntry); |
| tmpEnt->m_name.sbStrcpyIn(pname); |
| tmpEnt->mp_node = n; |
| tmpEnt->mp_att = nmap->getNamedItem(pname.sbStrToXMLCh()); |
| m_lst.push_back(tmpEnt); |
| |
| } |
| |
| } |
| |
| } |
| |
| // Do the children |
| |
| DOMNode *c; |
| |
| c = n->getFirstChild(); |
| |
| while (c != NULL) { |
| if (c->getNodeType() == DOMNode::ELEMENT_NODE) |
| recurse((DOMElement *) c); |
| c = c->getNextSibling(); |
| } |
| |
| } |
| |
| int attNodeCount(DOMElement * d) { |
| |
| XMLSize_t ret; |
| |
| ret = d->getAttributes()->getLength(); |
| |
| DOMNode *c; |
| |
| c = d->getFirstChild(); |
| |
| while (c != NULL) { |
| |
| if (c->getNodeType() == DOMNode::ELEMENT_NODE) |
| ret += attNodeCount((DOMElement *) c); |
| |
| c = c->getNextSibling(); |
| |
| } |
| |
| return (int) ret; |
| |
| } |
| |
| void XSECNameSpaceExpander::expandNameSpaces() { |
| |
| if (m_expanded) |
| return; // Don't do this twice! |
| |
| DOMElement *docElt; // The document element - do not expand it's namespaces |
| |
| docElt = mp_fragment; //mp_doc->getDocumentElement(); |
| |
| DOMNode *c; |
| |
| c = docElt->getFirstChild(); |
| |
| while (c != NULL) { |
| if (c->getNodeType() == DOMNode::ELEMENT_NODE) |
| recurse((DOMElement *) c); |
| c = c->getNextSibling(); |
| } |
| |
| m_expanded = true; |
| |
| } |
| |
| |
| void XSECNameSpaceExpander::deleteAddedNamespaces() { |
| |
| NameSpaceEntryListVectorType::size_type size = m_lst.size(); |
| XSECNameSpaceEntry *e; |
| |
| NameSpaceEntryListVectorType::size_type i; |
| |
| for (i = 0; i < size; ++i) { |
| |
| // Delete the element attribute, and then this node |
| e = m_lst[i]; |
| if (e->m_name[5] == ':') |
| e->mp_node->removeAttributeNS(DSIGConstants::s_unicodeStrURIXMLNS, |
| MAKE_UNICODE_STRING((char *) &((e->m_name.rawBuffer())[6]))); |
| else |
| e->mp_node->removeAttributeNS(DSIGConstants::s_unicodeStrURIXMLNS, |
| MAKE_UNICODE_STRING((char *) e->m_name.rawBuffer())); |
| |
| // Delete the entry |
| delete e; |
| |
| } |
| |
| // Now done - empty everything |
| m_lst.clear(); |
| m_expanded = false; |
| |
| } |
| |
| bool XSECNameSpaceExpander::nodeWasAdded(DOMNode *n) const { |
| |
| NameSpaceEntryListVectorType::size_type size = m_lst.size(); |
| XSECNameSpaceEntry *e; |
| |
| NameSpaceEntryListVectorType::size_type i; |
| for (i = 0; i < size; ++i) { |
| |
| // Delete the element attribute, and then this node |
| e = m_lst[i]; |
| |
| if (e->mp_att == n) |
| return true; |
| |
| } |
| |
| return false; |
| |
| } |