X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=xmltooling%2Fimpl%2FUnknownElement.cpp;h=270b50faca43ed9994f47e58737fa9e694926c0a;hb=HEAD;hp=50c19542e151793380f0d83134a5e69ee7e950b9;hpb=f317cde408dda5e51d043ceda0353705a3c8f407;p=shibboleth%2Fcpp-xmltooling.git diff --git a/xmltooling/impl/UnknownElement.cpp b/xmltooling/impl/UnknownElement.cpp index 50c1954..270b50f 100644 --- a/xmltooling/impl/UnknownElement.cpp +++ b/xmltooling/impl/UnknownElement.cpp @@ -1,195 +1,279 @@ -/* -* Copyright 2001-2006 Internet2 - * -* Licensed 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. - */ - -/** - * UnknownElement.cpp - * - * Basic implementation suitable for use as default for unrecognized content - */ - -#include "internal.h" -#include "exceptions.h" -#include "impl/UnknownElement.h" -#include "util/NDC.h" -#include "util/XMLHelper.h" - -#include -#include -#include -#include - -using namespace xmltooling; -using namespace log4cpp; -using namespace std; - -void UnknownElementImpl::releaseDOM() -{ -#ifdef _DEBUG - xmltooling::NDC ndc("releaseDOM"); -#endif - Category& log=Category::getInstance(XMLTOOLING_LOGCAT".UnknownElementImpl"); - log.debug("releasing DOM for unknown content, preserving current DOM in XML form"); - - // We're losing our DOM, so assuming we have one, we preserve it. - serialize(m_xml); - - // This takes care of the generic housekeeping now that we've preserved things. - AbstractDOMCachingXMLObject::releaseDOM(); -} - -XMLObject* UnknownElementImpl::clone() const -{ - UnknownElementImpl* ret=new UnknownElementImpl(); - - // If there's no XML locally, serialize this object into the new one. - // Otherwise just copy it over. - if (m_xml.empty()) - serialize(ret->m_xml); - else - ret->m_xml=m_xml; - - return ret; -} - -void UnknownElementImpl::serialize(string& s) const -{ - if (getDOM()) - XMLHelper::serialize(getDOM(),s); -} - -DOMElement* UnknownElementImpl::marshall(DOMDocument* document, MarshallingContext* ctx) const -{ -#ifdef _DEBUG - xmltooling::NDC ndc("marshall"); -#endif - - Category& log=Category::getInstance(XMLTOOLING_LOGCAT".Marshaller"); - log.debug("marshalling unknown content"); - - DOMElement* cachedDOM=getDOM(); - if (cachedDOM) { - if (!document || document==cachedDOM->getOwnerDocument()) { - log.debug("XMLObject has a usable cached DOM, reusing it"); - if (document) - setDocumentElement(cachedDOM->getOwnerDocument(),cachedDOM); - releaseParentDOM(true); - return cachedDOM; - } - - // We have a DOM but it doesn't match the document we were given, so we import - // it into the new document. - cachedDOM=static_cast(document->importNode(cachedDOM, true)); - - // Recache the DOM. - setDocumentElement(document, cachedDOM); - log.debug("caching imported DOM for XMLObject"); - setDOM(cachedDOM, false); - releaseParentDOM(true); - return cachedDOM; - } - - // If we get here, we didn't have a usable DOM. - // We need to reparse the XML we saved off into a new DOM. - bool bindDocument=false; - MemBufInputSource src(reinterpret_cast(m_xml.c_str()),m_xml.length(),"UnknownElementImpl"); - Wrapper4InputSource dsrc(&src,false); - log.debug("parsing XML back into DOM tree"); - DOMDocument* internalDoc=XMLToolingInternalConfig::getInternalConfig().m_parserPool->parse(dsrc); - if (document) { - // The caller insists on using his own document, so we now have to import the thing - // into it. Then we're just dumping the one we built. - log.debug("reimporting new DOM into caller-supplied document"); - cachedDOM=static_cast(document->importNode(internalDoc->getDocumentElement(), true)); - internalDoc->release(); - } - else { - // We just bind the document we built to the object as the result. - cachedDOM=static_cast(internalDoc->getDocumentElement()); - document=internalDoc; - bindDocument=true; - } - - // Recache the DOM and clear the serialized copy. - setDocumentElement(document, cachedDOM); - log.debug("caching DOM for XMLObject (document is %sbound)", bindDocument ? "" : "not "); - setDOM(cachedDOM, bindDocument); - releaseParentDOM(true); - m_xml.erase(); - return cachedDOM; -} - -DOMElement* UnknownElementImpl::marshall(DOMElement* parentElement, MarshallingContext* ctx) const -{ -#ifdef _DEBUG - xmltooling::NDC ndc("marshall"); -#endif - - Category& log=Category::getInstance(XMLTOOLING_LOGCAT".Marshaller"); - log.debug("marshalling unknown content"); - - DOMElement* cachedDOM=getDOM(); - if (cachedDOM) { - if (parentElement->getOwnerDocument()==cachedDOM->getOwnerDocument()) { - log.debug("XMLObject has a usable cached DOM, reusing it"); - parentElement->appendChild(cachedDOM); - releaseParentDOM(true); - return cachedDOM; - } - - // We have a DOM but it doesn't match the document we were given, so we import - // it into the new document. - cachedDOM=static_cast(parentElement->getOwnerDocument()->importNode(cachedDOM, true)); - - // Recache the DOM. - parentElement->appendChild(cachedDOM); - log.debug("caching imported DOM for XMLObject"); - setDOM(cachedDOM, false); - releaseParentDOM(true); - return cachedDOM; - } - - // If we get here, we didn't have a usable DOM (and/or we flushed the one we had). - // We need to reparse the XML we saved off into a new DOM. - MemBufInputSource src(reinterpret_cast(m_xml.c_str()),m_xml.length(),"UnknownElementImpl"); - Wrapper4InputSource dsrc(&src,false); - log.debug("parsing XML back into DOM tree"); - DOMDocument* internalDoc=XMLToolingInternalConfig::getInternalConfig().m_parserPool->parse(dsrc); - - log.debug("reimporting new DOM into caller-supplied document"); - cachedDOM=static_cast(parentElement->getOwnerDocument()->importNode(internalDoc->getDocumentElement(), true)); - internalDoc->release(); - - // Recache the DOM and clear the serialized copy. - parentElement->appendChild(cachedDOM); - log.debug("caching DOM for XMLObject"); - setDOM(cachedDOM, false); - releaseParentDOM(true); - m_xml.erase(); - return cachedDOM; -} - -XMLObject* UnknownElementImpl::unmarshall(DOMElement* element, bool bindDocument) -{ - setDOM(element, bindDocument); - return this; -} - -XMLObject* UnknownElementBuilder::buildObject( - const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType - ) const { - return new UnknownElementImpl(nsURI,localName,prefix); -} - +/** + * Licensed to the University Corporation for Advanced Internet + * Development, Inc. (UCAID) under one or more contributor license + * agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * UCAID 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. + */ + +/** + * UnknownElement.cpp + * + * Basic implementation suitable for use as default for unrecognized content. + */ + +#include "internal.h" +#include "exceptions.h" +#include "logging.h" +#include "impl/UnknownElement.h" +#include "util/NDC.h" +#include "util/XMLHelper.h" + +#include +#include +#include + +using namespace xmltooling::logging; +using namespace xmltooling; +using namespace xercesc; +using namespace std; +#ifndef XMLTOOLING_NO_XMLSEC +using xmlsignature::Signature; +#endif + +UnknownElementImpl::UnknownElementImpl(const XMLCh* namespaceURI, const XMLCh* elementLocalName, const XMLCh* namespacePrefix) + : AbstractXMLObject(namespaceURI, elementLocalName, namespacePrefix) +{ +} + +UnknownElementImpl::~UnknownElementImpl() +{ +} + +void UnknownElementImpl::releaseDOM() const +{ +#ifdef _DEBUG + xmltooling::NDC ndc("releaseDOM"); +#endif + Category& log=Category::getInstance(XMLTOOLING_LOGCAT ".XMLObject"); + log.debug("releasing DOM for unknown content, preserving current DOM in XML form"); + + // We're losing our DOM, so assuming we have one, we preserve it. + serialize(m_xml); + + // This takes care of the generic housekeeping now that we've preserved things. + AbstractDOMCachingXMLObject::releaseDOM(); +} + +XMLObject* UnknownElementImpl::clone() const +{ + UnknownElementImpl* ret=new UnknownElementImpl(); + + // If there's no XML locally, serialize this object into the new one. + // Otherwise just copy it over. + if (m_xml.empty()) + serialize(ret->m_xml); + else + ret->m_xml=m_xml; + + return ret; +} + +const XMLCh* UnknownElementImpl::getTextContent(unsigned int position) const +{ + throw XMLObjectException("Direct access to content is not permitted."); +} + +void UnknownElementImpl::setTextContent(const XMLCh*, unsigned int position) +{ + throw XMLObjectException("Direct access to content is not permitted."); +} + +void UnknownElementImpl::setDocumentElement(DOMDocument* document, DOMElement* element) const +{ + DOMElement* documentRoot = document->getDocumentElement(); + if (documentRoot) + document->replaceChild(element, documentRoot); + else + document->appendChild(element); +} + +void UnknownElementImpl::serialize(string& s) const +{ + if (getDOM()) + XMLHelper::serialize(getDOM(),s); +} + +DOMElement* UnknownElementImpl::marshall( + DOMDocument* document +#ifndef XMLTOOLING_NO_XMLSEC + ,const vector* sigs + ,const Credential* credential +#endif + ) const +{ +#ifdef _DEBUG + xmltooling::NDC ndc("marshall"); +#endif + + Category& log=Category::getInstance(XMLTOOLING_LOGCAT ".XMLObject"); + log.debug("marshalling unknown content"); + + DOMElement* cachedDOM=getDOM(); + if (cachedDOM) { + if (!document || document==cachedDOM->getOwnerDocument()) { + log.debug("XMLObject has a usable cached DOM, reusing it"); + if (document) + setDocumentElement(cachedDOM->getOwnerDocument(),cachedDOM); + releaseParentDOM(true); + return cachedDOM; + } + + // We have a DOM but it doesn't match the document we were given, so we import + // it into the new document. + try { + cachedDOM=static_cast(document->importNode(cachedDOM, true)); + } + catch (XMLException& ex) { + auto_ptr_char temp(ex.getMessage()); + throw XMLParserException( + string("Error importing DOM into caller-supplied document: ") + (temp.get() ? temp.get() : "no message") + ); + } + + // Recache the DOM. + setDocumentElement(document, cachedDOM); + log.debug("caching imported DOM for XMLObject"); + setDOM(cachedDOM, false); + releaseParentDOM(true); + return cachedDOM; + } + + // If we get here, we didn't have a usable DOM. + // We need to reparse the XML we saved off into a new DOM. + bool bindDocument=false; + MemBufInputSource src(reinterpret_cast(m_xml.c_str()),m_xml.length(),"UnknownElementImpl"); + Wrapper4InputSource dsrc(&src,false); + log.debug("parsing XML back into DOM tree"); + DOMDocument* internalDoc=XMLToolingConfig::getConfig().getParser().parse(dsrc); + if (document) { + // The caller insists on using his own document, so we now have to import the thing + // into it. Then we're just dumping the one we built. + log.debug("reimporting new DOM into caller-supplied document"); + try { + cachedDOM=static_cast(document->importNode(internalDoc->getDocumentElement(), true)); + } + catch (XMLException& ex) { + internalDoc->release(); + auto_ptr_char temp(ex.getMessage()); + throw XMLParserException( + string("Error importing DOM into caller-supplied document: ") + (temp.get() ? temp.get() : "no message") + ); + } + internalDoc->release(); + } + else { + // We just bind the document we built to the object as the result. + cachedDOM=static_cast(internalDoc->getDocumentElement()); + document=internalDoc; + bindDocument=true; + } + + // Recache the DOM and clear the serialized copy. + setDocumentElement(document, cachedDOM); + log.debug("caching DOM for XMLObject (document is %sbound)", bindDocument ? "" : "not "); + setDOM(cachedDOM, bindDocument); + releaseParentDOM(true); + m_xml.erase(); + return cachedDOM; +} + + +DOMElement* UnknownElementImpl::marshall( + DOMElement* parentElement +#ifndef XMLTOOLING_NO_XMLSEC + ,const vector* sigs + ,const Credential* credential +#endif + ) const +{ +#ifdef _DEBUG + xmltooling::NDC ndc("marshall"); +#endif + + Category& log=Category::getInstance(XMLTOOLING_LOGCAT ".XMLObject"); + log.debug("marshalling unknown content"); + + DOMElement* cachedDOM=getDOM(); + if (cachedDOM) { + if (parentElement->getOwnerDocument()==cachedDOM->getOwnerDocument()) { + log.debug("XMLObject has a usable cached DOM, reusing it"); + parentElement->appendChild(cachedDOM); + releaseParentDOM(true); + return cachedDOM; + } + + // We have a DOM but it doesn't match the document we were given, so we import + // it into the new document. + try { + cachedDOM=static_cast(parentElement->getOwnerDocument()->importNode(cachedDOM, true)); + } + catch (XMLException& ex) { + auto_ptr_char temp(ex.getMessage()); + throw XMLParserException( + string("Error importing DOM into caller-supplied document: ") + (temp.get() ? temp.get() : "no message") + ); + } + + // Recache the DOM. + parentElement->appendChild(cachedDOM); + log.debug("caching imported DOM for XMLObject"); + setDOM(cachedDOM, false); + releaseParentDOM(true); + return cachedDOM; + } + + // If we get here, we didn't have a usable DOM (and/or we flushed the one we had). + // We need to reparse the XML we saved off into a new DOM. + MemBufInputSource src(reinterpret_cast(m_xml.c_str()),m_xml.length(),"UnknownElementImpl"); + Wrapper4InputSource dsrc(&src,false); + log.debug("parsing XML back into DOM tree"); + DOMDocument* internalDoc=XMLToolingConfig::getConfig().getParser().parse(dsrc); + + log.debug("reimporting new DOM into caller-supplied document"); + try { + cachedDOM=static_cast(parentElement->getOwnerDocument()->importNode(internalDoc->getDocumentElement(), true)); + } + catch (XMLException& ex) { + internalDoc->release(); + auto_ptr_char temp(ex.getMessage()); + throw XMLParserException( + string("Error importing DOM into caller-supplied document: ") + (temp.get() ? temp.get() : "no message") + ); + } + internalDoc->release(); + + // Recache the DOM and clear the serialized copy. + parentElement->appendChild(cachedDOM); + log.debug("caching DOM for XMLObject"); + setDOM(cachedDOM, false); + releaseParentDOM(true); + m_xml.erase(); + return cachedDOM; +} + +XMLObject* UnknownElementImpl::unmarshall(DOMElement* element, bool bindDocument) +{ + setDOM(element, bindDocument); + return this; +} + +XMLObject* UnknownElementBuilder::buildObject( + const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType + ) const +{ + return new UnknownElementImpl(nsURI,localName,prefix); +} +