2 * Licensed to the University Corporation for Advanced Internet
3 * Development, Inc. (UCAID) under one or more contributor license
4 * agreements. See the NOTICE file distributed with this work for
5 * additional information regarding copyright ownership.
7 * UCAID licenses this file to you under the Apache License,
8 * Version 2.0 (the "License"); you may not use this file except
9 * in compliance with the License. You may obtain a copy of the
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
17 * either express or implied. See the License for the specific
18 * language governing permissions and limitations under the License.
24 * Basic implementation suitable for use as default for unrecognized content.
28 #include "exceptions.h"
30 #include "impl/UnknownElement.h"
32 #include "util/XMLHelper.h"
34 #include <xercesc/framework/MemBufInputSource.hpp>
35 #include <xercesc/framework/Wrapper4InputSource.hpp>
36 #include <xercesc/util/XMLUniDefs.hpp>
38 using namespace xmltooling::logging;
39 using namespace xmltooling;
40 using namespace xercesc;
42 #ifndef XMLTOOLING_NO_XMLSEC
43 using xmlsignature::Signature;
46 UnknownElementImpl::UnknownElementImpl(const XMLCh* namespaceURI, const XMLCh* elementLocalName, const XMLCh* namespacePrefix)
47 : AbstractXMLObject(namespaceURI, elementLocalName, namespacePrefix)
51 UnknownElementImpl::~UnknownElementImpl()
55 void UnknownElementImpl::releaseDOM() const
58 xmltooling::NDC ndc("releaseDOM");
60 Category& log=Category::getInstance(XMLTOOLING_LOGCAT".XMLObject");
61 log.debug("releasing DOM for unknown content, preserving current DOM in XML form");
63 // We're losing our DOM, so assuming we have one, we preserve it.
66 // This takes care of the generic housekeeping now that we've preserved things.
67 AbstractDOMCachingXMLObject::releaseDOM();
70 XMLObject* UnknownElementImpl::clone() const
72 UnknownElementImpl* ret=new UnknownElementImpl();
74 // If there's no XML locally, serialize this object into the new one.
75 // Otherwise just copy it over.
77 serialize(ret->m_xml);
84 const XMLCh* UnknownElementImpl::getTextContent(unsigned int position) const
86 throw XMLObjectException("Direct access to content is not permitted.");
89 void UnknownElementImpl::setTextContent(const XMLCh*, unsigned int position)
91 throw XMLObjectException("Direct access to content is not permitted.");
94 void UnknownElementImpl::setDocumentElement(DOMDocument* document, DOMElement* element) const
96 DOMElement* documentRoot = document->getDocumentElement();
98 document->replaceChild(element, documentRoot);
100 document->appendChild(element);
103 void UnknownElementImpl::serialize(string& s) const
106 XMLHelper::serialize(getDOM(),s);
109 DOMElement* UnknownElementImpl::marshall(
110 DOMDocument* document
111 #ifndef XMLTOOLING_NO_XMLSEC
112 ,const vector<Signature*>* sigs
113 ,const Credential* credential
118 xmltooling::NDC ndc("marshall");
121 Category& log=Category::getInstance(XMLTOOLING_LOGCAT".XMLObject");
122 log.debug("marshalling unknown content");
124 DOMElement* cachedDOM=getDOM();
126 if (!document || document==cachedDOM->getOwnerDocument()) {
127 log.debug("XMLObject has a usable cached DOM, reusing it");
129 setDocumentElement(cachedDOM->getOwnerDocument(),cachedDOM);
130 releaseParentDOM(true);
134 // We have a DOM but it doesn't match the document we were given, so we import
135 // it into the new document.
137 cachedDOM=static_cast<DOMElement*>(document->importNode(cachedDOM, true));
139 catch (XMLException& ex) {
140 auto_ptr_char temp(ex.getMessage());
141 throw XMLParserException(
142 string("Error importing DOM into caller-supplied document: ") + (temp.get() ? temp.get() : "no message")
147 setDocumentElement(document, cachedDOM);
148 log.debug("caching imported DOM for XMLObject");
149 setDOM(cachedDOM, false);
150 releaseParentDOM(true);
154 // If we get here, we didn't have a usable DOM.
155 // We need to reparse the XML we saved off into a new DOM.
156 bool bindDocument=false;
157 MemBufInputSource src(reinterpret_cast<const XMLByte*>(m_xml.c_str()),m_xml.length(),"UnknownElementImpl");
158 Wrapper4InputSource dsrc(&src,false);
159 log.debug("parsing XML back into DOM tree");
160 DOMDocument* internalDoc=XMLToolingConfig::getConfig().getParser().parse(dsrc);
162 // The caller insists on using his own document, so we now have to import the thing
163 // into it. Then we're just dumping the one we built.
164 log.debug("reimporting new DOM into caller-supplied document");
166 cachedDOM=static_cast<DOMElement*>(document->importNode(internalDoc->getDocumentElement(), true));
168 catch (XMLException& ex) {
169 internalDoc->release();
170 auto_ptr_char temp(ex.getMessage());
171 throw XMLParserException(
172 string("Error importing DOM into caller-supplied document: ") + (temp.get() ? temp.get() : "no message")
175 internalDoc->release();
178 // We just bind the document we built to the object as the result.
179 cachedDOM=static_cast<DOMElement*>(internalDoc->getDocumentElement());
180 document=internalDoc;
184 // Recache the DOM and clear the serialized copy.
185 setDocumentElement(document, cachedDOM);
186 log.debug("caching DOM for XMLObject (document is %sbound)", bindDocument ? "" : "not ");
187 setDOM(cachedDOM, bindDocument);
188 releaseParentDOM(true);
194 DOMElement* UnknownElementImpl::marshall(
195 DOMElement* parentElement
196 #ifndef XMLTOOLING_NO_XMLSEC
197 ,const vector<Signature*>* sigs
198 ,const Credential* credential
203 xmltooling::NDC ndc("marshall");
206 Category& log=Category::getInstance(XMLTOOLING_LOGCAT".XMLObject");
207 log.debug("marshalling unknown content");
209 DOMElement* cachedDOM=getDOM();
211 if (parentElement->getOwnerDocument()==cachedDOM->getOwnerDocument()) {
212 log.debug("XMLObject has a usable cached DOM, reusing it");
213 parentElement->appendChild(cachedDOM);
214 releaseParentDOM(true);
218 // We have a DOM but it doesn't match the document we were given, so we import
219 // it into the new document.
221 cachedDOM=static_cast<DOMElement*>(parentElement->getOwnerDocument()->importNode(cachedDOM, true));
223 catch (XMLException& ex) {
224 auto_ptr_char temp(ex.getMessage());
225 throw XMLParserException(
226 string("Error importing DOM into caller-supplied document: ") + (temp.get() ? temp.get() : "no message")
231 parentElement->appendChild(cachedDOM);
232 log.debug("caching imported DOM for XMLObject");
233 setDOM(cachedDOM, false);
234 releaseParentDOM(true);
238 // If we get here, we didn't have a usable DOM (and/or we flushed the one we had).
239 // We need to reparse the XML we saved off into a new DOM.
240 MemBufInputSource src(reinterpret_cast<const XMLByte*>(m_xml.c_str()),m_xml.length(),"UnknownElementImpl");
241 Wrapper4InputSource dsrc(&src,false);
242 log.debug("parsing XML back into DOM tree");
243 DOMDocument* internalDoc=XMLToolingConfig::getConfig().getParser().parse(dsrc);
245 log.debug("reimporting new DOM into caller-supplied document");
247 cachedDOM=static_cast<DOMElement*>(parentElement->getOwnerDocument()->importNode(internalDoc->getDocumentElement(), true));
249 catch (XMLException& ex) {
250 internalDoc->release();
251 auto_ptr_char temp(ex.getMessage());
252 throw XMLParserException(
253 string("Error importing DOM into caller-supplied document: ") + (temp.get() ? temp.get() : "no message")
256 internalDoc->release();
258 // Recache the DOM and clear the serialized copy.
259 parentElement->appendChild(cachedDOM);
260 log.debug("caching DOM for XMLObject");
261 setDOM(cachedDOM, false);
262 releaseParentDOM(true);
267 XMLObject* UnknownElementImpl::unmarshall(DOMElement* element, bool bindDocument)
269 setDOM(element, bindDocument);
273 XMLObject* UnknownElementBuilder::buildObject(
274 const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType
277 return new UnknownElementImpl(nsURI,localName,prefix);