From: Scott Cantor Date: Thu, 2 Mar 2006 05:54:02 +0000 (+0000) Subject: Bug fixes and API changes from second unit test. X-Git-Tag: 1.0-alpha1~311 X-Git-Url: http://www.project-moonshot.org/gitweb/?p=shibboleth%2Fcpp-xmltooling.git;a=commitdiff_plain;h=cc0bfa6146fb0a556e80ae5f83c330dbe2ddf3c9 Bug fixes and API changes from second unit test. --- diff --git a/xmltooling/AbstractDOMCachingXMLObject.cpp b/xmltooling/AbstractDOMCachingXMLObject.cpp index 86f8bf7..750e3f9 100644 --- a/xmltooling/AbstractDOMCachingXMLObject.cpp +++ b/xmltooling/AbstractDOMCachingXMLObject.cpp @@ -43,15 +43,9 @@ void AbstractDOMCachingXMLObject::setDOM(DOMElement* dom, bool bindDocument) m_dom=dom; if (dom) { if (bindDocument) { - DOMDocument* tmp=setDocument(dom->getOwnerDocument()); - if (tmp) - tmp->release(); + setDocument(dom->getOwnerDocument()); } } - else if (m_document) { - m_document->release(); - m_document=NULL; - } } void AbstractDOMCachingXMLObject::releaseDOM() diff --git a/xmltooling/AbstractDOMCachingXMLObject.h b/xmltooling/AbstractDOMCachingXMLObject.h index dba39e7..453c634 100644 --- a/xmltooling/AbstractDOMCachingXMLObject.h +++ b/xmltooling/AbstractDOMCachingXMLObject.h @@ -56,10 +56,10 @@ namespace xmltooling { /** * @see DOMCachingXMLObject::setDocument() */ - DOMDocument* setDocument(DOMDocument* doc) { - DOMDocument* ret=m_document; + void setDocument(DOMDocument* doc) { + if (m_document) + m_document->release(); m_document=doc; - return ret; } /** @@ -112,7 +112,7 @@ namespace xmltooling { XMLCh* newString = XMLString::replicate(newValue); XMLString::trim(newString); - if (oldValue && !newValue || !oldValue && newValue || XMLString::compareString(oldValue,newValue)) + if (!XMLString::equals(oldValue,newValue)) releaseThisandParentDOM(); return newString; diff --git a/xmltooling/DOMCachingXMLObject.h b/xmltooling/DOMCachingXMLObject.h index dfbe84c..84f33e2 100644 --- a/xmltooling/DOMCachingXMLObject.h +++ b/xmltooling/DOMCachingXMLObject.h @@ -60,7 +60,7 @@ namespace xmltooling { * * @param doc DOM document bound to this object */ - virtual DOMDocument* setDocument(DOMDocument* doc)=0; + virtual void setDocument(DOMDocument* doc)=0; /** * Releases the DOM representation of this XMLObject, if there is one. diff --git a/xmltooling/XMLObjectBuilder.cpp b/xmltooling/XMLObjectBuilder.cpp index 24d434d..33c4225 100644 --- a/xmltooling/XMLObjectBuilder.cpp +++ b/xmltooling/XMLObjectBuilder.cpp @@ -42,7 +42,7 @@ const XMLObjectBuilder* XMLObjectBuilder::getBuilder(const DOMElement* domElemen Category& log=Category::getInstance(XMLTOOLING_LOGCAT".XMLObjectBuilder"); auto_ptr schemaType(XMLHelper::getXSIType(domElement)); - const XMLObjectBuilder* xmlObjectBuilder = getBuilder(*(schemaType.get())); + const XMLObjectBuilder* xmlObjectBuilder = schemaType.get() ? getBuilder(*(schemaType.get())) : NULL; if (xmlObjectBuilder) { if (log.isDebugEnabled()) { log.debug("located XMLObjectBuilder for schema type: %s", schemaType->toString().c_str()); diff --git a/xmltooling/base.h b/xmltooling/base.h index d7c6016..5194776 100644 --- a/xmltooling/base.h +++ b/xmltooling/base.h @@ -81,4 +81,55 @@ #define NULL 0 #endif +#include + +namespace xmltooling { + + /** + * Template function for cloning a sequence of XMLObjects. + * Invokes the clone() member on each element of the input sequence and adds the copy to + * the output sequence. Order is preserved. + * + * @param in input sequence to clone + * @param out output sequence to copy cloned pointers into + */ + template void clone(const InputSequence& in, OutputSequence& out) { + for (InputSequence::const_iterator i=in.begin(); i!=in.end(); i++) + out.push_back((*i)->clone()); + } + + /* + * Functor for cleaning up heap objects in containers. + */ + template struct cleanup + { + /** + * Function operator to delete an object. + * + * @param ptr object to delete + */ + void operator()(T* ptr) {delete ptr;} + + /** + * Function operator to delete an object stored as const. + * + * @param ptr object to delete after casting away const + */ + void operator()(const T* ptr) {delete const_cast(ptr);} + }; + + /* + * Functor for cleaning up heap objects in key/value containers. + */ + template struct cleanup_pair + { + /** + * Function operator to delete an object. + * + * @param p a pair in which the second component is the object to delete + */ + void operator()(const std::pair& p) {delete p.second;} + }; +}; + #endif /* __xmltooling_base_h__ */ diff --git a/xmltooling/impl/UnknownElement.h b/xmltooling/impl/UnknownElement.h index 787cea1..c22fa55 100644 --- a/xmltooling/impl/UnknownElement.h +++ b/xmltooling/impl/UnknownElement.h @@ -46,9 +46,6 @@ namespace xmltooling { class XMLTOOL_DLLLOCAL UnknownElementImpl : public AbstractDOMCachingXMLObject { public: - UnknownElementImpl() {} - virtual ~UnknownElementImpl() {} - /** * Overridden to ensure XML content of DOM isn't lost. * @@ -92,9 +89,6 @@ namespace xmltooling { class XMLTOOL_DLLLOCAL UnknownElementBuilder : public virtual XMLObjectBuilder { public: - UnknownElementBuilder() {} - virtual ~UnknownElementBuilder() {} - /** * @see XMLObjectBuilder::buildObject() */ @@ -109,9 +103,6 @@ namespace xmltooling { class XMLTOOL_DLLLOCAL UnknownElementMarshaller : public virtual Marshaller { public: - UnknownElementMarshaller() {} - virtual ~UnknownElementMarshaller() {} - /** * @see Marshaller::marshall(XMLObject*,DOMDocument*) */ @@ -138,9 +129,6 @@ namespace xmltooling { class XMLTOOL_DLLLOCAL UnknownElementUnmarshaller : public virtual Unmarshaller { public: - UnknownElementUnmarshaller() {} - virtual ~UnknownElementUnmarshaller() {} - /** * @see Unmarshaller::unmarshall() */ diff --git a/xmltooling/internal.h b/xmltooling/internal.h index 199c644..2d7c6fa 100644 --- a/xmltooling/internal.h +++ b/xmltooling/internal.h @@ -71,18 +71,6 @@ namespace xmltooling { //XSECProvider* m_xsec; //PlugManager m_plugMgr; }; - - // Template cleanup functors for use with for_each algorithm - template struct cleanup - { - void operator()(T* ptr) {delete ptr;} - void operator()(const T* ptr) {delete const_cast(ptr);} - }; - - template struct cleanup_pair - { - void operator()(const std::pair& p) {delete p.second;} - }; }; #endif /* __xmltooling_internal_h__ */ diff --git a/xmltooling/io/AbstractXMLObjectMarshaller.cpp b/xmltooling/io/AbstractXMLObjectMarshaller.cpp index 0b09c3e..2c0d537 100644 --- a/xmltooling/io/AbstractXMLObjectMarshaller.cpp +++ b/xmltooling/io/AbstractXMLObjectMarshaller.cpp @@ -92,7 +92,7 @@ DOMElement* AbstractXMLObjectMarshaller::marshall(XMLObject* xmlObject, DOMDocum xmlObject->getElementQName().getNamespaceURI(), xmlObject->getElementQName().getLocalPart() ); setDocumentElement(document, domElement); - marshallInto(xmlObject, domElement); + marshallInto(*xmlObject, domElement); //Recache the DOM. if (dc) { @@ -151,7 +151,7 @@ DOMElement* AbstractXMLObjectMarshaller::marshall(XMLObject* xmlObject, DOMEleme xmlObject->getElementQName().getNamespaceURI(), xmlObject->getElementQName().getLocalPart() ); parentElement->appendChild(domElement); - marshallInto(xmlObject, domElement); + marshallInto(*xmlObject, domElement); //Recache the DOM. if (dc) { @@ -163,9 +163,9 @@ DOMElement* AbstractXMLObjectMarshaller::marshall(XMLObject* xmlObject, DOMEleme return domElement; } -void AbstractXMLObjectMarshaller::marshallInto(XMLObject* xmlObject, DOMElement* targetElement) const +void AbstractXMLObjectMarshaller::marshallInto(XMLObject& xmlObject, DOMElement* targetElement) const { - targetElement->setPrefix(xmlObject->getElementQName().getPrefix()); + targetElement->setPrefix(xmlObject.getElementQName().getPrefix()); marshallElementType(xmlObject, targetElement); marshallNamespaces(xmlObject, targetElement); marshallAttributes(xmlObject, targetElement); @@ -183,9 +183,9 @@ void AbstractXMLObjectMarshaller::marshallInto(XMLObject* xmlObject, DOMElement* */ } -void AbstractXMLObjectMarshaller::marshallElementType(XMLObject* xmlObject, DOMElement* domElement) const +void AbstractXMLObjectMarshaller::marshallElementType(XMLObject& xmlObject, DOMElement* domElement) const { - const QName* type = xmlObject->getSchemaType(); + const QName* type = xmlObject.getSchemaType(); if (type) { XT_log.debug("setting xsi:type attribute for XMLObject"); @@ -213,7 +213,7 @@ void AbstractXMLObjectMarshaller::marshallElementType(XMLObject* xmlObject, DOME XMLString::release(&xsivalue); XT_log.debug("Adding XSI namespace to list of namespaces used by XMLObject"); - xmlObject->addNamespace(Namespace(XMLConstants::XSI_NS, XMLConstants::XSI_PREFIX)); + xmlObject.addNamespace(Namespace(XMLConstants::XSI_NS, XMLConstants::XSI_PREFIX)); } } @@ -243,10 +243,10 @@ public: } }; -void AbstractXMLObjectMarshaller::marshallNamespaces(const XMLObject* xmlObject, DOMElement* domElement) const +void AbstractXMLObjectMarshaller::marshallNamespaces(const XMLObject& xmlObject, DOMElement* domElement) const { XT_log.debug("marshalling namespace attributes for XMLObject"); - const set& namespaces = xmlObject->getNamespaces(); + const set& namespaces = xmlObject.getNamespaces(); for_each(namespaces.begin(),namespaces.end(),bind1st(_addns(),domElement)); } @@ -271,12 +271,12 @@ public: } }; -void AbstractXMLObjectMarshaller::marshallChildElements(const XMLObject* xmlObject, DOMElement* domElement) const +void AbstractXMLObjectMarshaller::marshallChildElements(const XMLObject& xmlObject, DOMElement* domElement) const { XT_log.debug("marshalling child elements for XMLObject"); vector children; - if (xmlObject->getOrderedChildren(children)) { + if (xmlObject.getOrderedChildren(children)) { for_each(children.begin(),children.end(),bind2nd(_marshallchild(m_log),domElement)); } } diff --git a/xmltooling/io/AbstractXMLObjectMarshaller.h b/xmltooling/io/AbstractXMLObjectMarshaller.h index e93a4b3..2fd6511 100644 --- a/xmltooling/io/AbstractXMLObjectMarshaller.h +++ b/xmltooling/io/AbstractXMLObjectMarshaller.h @@ -80,7 +80,7 @@ namespace xmltooling { * @param targetElement the Element into which the XMLObject is marshalled into * @throws MarshallingException thrown if there is a problem marshalling the object */ - void marshallInto(XMLObject* xmlObject, DOMElement* targetElement) const; + void marshallInto(XMLObject& xmlObject, DOMElement* targetElement) const; /** * Creates an xsi:type attribute, corresponding to the given type of the XMLObject, on the DOM element. @@ -91,7 +91,7 @@ namespace xmltooling { * @throws MarshallingException thrown if the type on the XMLObject is doesn't contain * a local name, prefix, and namespace URI */ - void marshallElementType(XMLObject* xmlObject, DOMElement* domElement) const; + void marshallElementType(XMLObject& xmlObject, DOMElement* domElement) const; /** * Creates the xmlns attributes for any namespaces set on the given XMLObject. @@ -99,7 +99,7 @@ namespace xmltooling { * @param xmlObject the XMLObject * @param domElement the DOM element the namespaces will be added to */ - void marshallNamespaces(const XMLObject* xmlObject, DOMElement* domElement) const; + void marshallNamespaces(const XMLObject& xmlObject, DOMElement* domElement) const; /** * Marshalls the child elements of the given XMLObject. @@ -109,7 +109,7 @@ namespace xmltooling { * * @throws MarshallingException thrown if there is a problem marshalling a child element */ - void marshallChildElements(const XMLObject* xmlObject, DOMElement* domElement) const; + void marshallChildElements(const XMLObject& xmlObject, DOMElement* domElement) const; /** * Marshalls the attributes from the given XMLObject into the given DOM element. @@ -121,7 +121,7 @@ namespace xmltooling { * * @throws UnmarshallingException thrown if there is a problem unmarshalling an attribute */ - virtual void marshallAttributes(const XMLObject* xmlObject, DOMElement* domElement) const=0; + virtual void marshallAttributes(const XMLObject& xmlObject, DOMElement* domElement) const=0; /** * Marshalls data from the XMLObject into content of the DOM Element. @@ -129,7 +129,7 @@ namespace xmltooling { * @param xmlObject the XMLObject * @param domElement the DOM element recieving the content */ - virtual void marshallElementContent(const XMLObject* xmlObject, DOMElement* domElement) const=0; + virtual void marshallElementContent(const XMLObject& xmlObject, DOMElement* domElement) const=0; void* m_log; private: diff --git a/xmltooling/io/AbstractXMLObjectUnmarshaller.cpp b/xmltooling/io/AbstractXMLObjectUnmarshaller.cpp index 18b09cd..ad168d1 100644 --- a/xmltooling/io/AbstractXMLObjectUnmarshaller.cpp +++ b/xmltooling/io/AbstractXMLObjectUnmarshaller.cpp @@ -59,14 +59,14 @@ XMLObject* AbstractXMLObjectUnmarshaller::unmarshall(DOMElement* element, bool b XMLObject* xmlObject = buildXMLObject(element); if (element->hasAttributes()) { - unmarshallAttributes(element, xmlObject); + unmarshallAttributes(element, *xmlObject); } if (element->getTextContent()) { - processElementContent(xmlObject, element->getTextContent()); + processElementContent(*xmlObject, element->getTextContent()); } - unmarshallChildElements(element, xmlObject); + unmarshallChildElements(element, *xmlObject); /* TODO: Signing if (xmlObject instanceof SignableXMLObject) { @@ -89,7 +89,7 @@ XMLObject* AbstractXMLObjectUnmarshaller::buildXMLObject(const DOMElement* domEl throw UnmarshallingException("Failed to locate XMLObjectBuilder for element."); } -void AbstractXMLObjectUnmarshaller::unmarshallAttributes(const DOMElement* domElement, XMLObject* xmlObject) const +void AbstractXMLObjectUnmarshaller::unmarshallAttributes(const DOMElement* domElement, XMLObject& xmlObject) const { #ifdef _DEBUG xmltooling::NDC ndc("unmarshallAttributes"); @@ -123,18 +123,18 @@ void AbstractXMLObjectUnmarshaller::unmarshallAttributes(const DOMElement* domEl const XMLCh* nsuri=attribute->getNamespaceURI(); if (XMLString::equals(nsuri,XMLConstants::XMLNS_NS)) { XT_log.debug("found namespace declaration, adding it to the list of namespaces on the XMLObject"); - xmlObject->addNamespace(Namespace(attribute->getValue(), attribute->getLocalName(), true)); + xmlObject.addNamespace(Namespace(attribute->getValue(), attribute->getLocalName(), true)); continue; } else if (XMLString::equals(nsuri,XMLConstants::XSI_NS) && XMLString::equals(attribute->getLocalName(),type)) { XT_log.debug("found xsi:type declaration, setting the schema type of the XMLObject"); auto_ptr xsitype(XMLHelper::getAttributeValueAsQName(attribute)); - xmlObject->setSchemaType(xsitype.get()); + xmlObject.setSchemaType(xsitype.get()); continue; } else if (nsuri) { XT_log.debug("found namespace-qualified attribute, adding prefix to the list of namespaces on the XMLObject"); - xmlObject->addNamespace(Namespace(nsuri, attribute->getPrefix())); + xmlObject.addNamespace(Namespace(nsuri, attribute->getPrefix())); } XT_log.debug("processing generic attribute"); @@ -142,7 +142,7 @@ void AbstractXMLObjectUnmarshaller::unmarshallAttributes(const DOMElement* domEl } } -void AbstractXMLObjectUnmarshaller::unmarshallChildElements(const DOMElement* domElement, XMLObject* xmlObject) const +void AbstractXMLObjectUnmarshaller::unmarshallChildElements(const DOMElement* domElement, XMLObject& xmlObject) const { #ifdef _DEBUG xmltooling::NDC ndc("unmarshallChildElements"); diff --git a/xmltooling/io/AbstractXMLObjectUnmarshaller.h b/xmltooling/io/AbstractXMLObjectUnmarshaller.h index 56189c1..acab0d2 100644 --- a/xmltooling/io/AbstractXMLObjectUnmarshaller.h +++ b/xmltooling/io/AbstractXMLObjectUnmarshaller.h @@ -77,7 +77,7 @@ namespace xmltooling { * * @throws UnmarshallingException thrown if there is a problem unmarshalling an attribute */ - virtual void unmarshallAttributes(const DOMElement* domElement, XMLObject* xmlObject) const; + virtual void unmarshallAttributes(const DOMElement* domElement, XMLObject& xmlObject) const; /** * Unmarshalls a given Element's children. For each child an unmarshaller is retrieved using @@ -89,17 +89,17 @@ namespace xmltooling { * * @throws UnmarshallingException thrown if an error occurs unmarshalling the child elements */ - virtual void unmarshallChildElements(const DOMElement* domElement, XMLObject* xmlObject) const; + virtual void unmarshallChildElements(const DOMElement* domElement, XMLObject& xmlObject) const; /** * Called after a child element has been unmarshalled so that it can be added to the parent XMLObject. * * @param parent the parent XMLObject - * @param child the child XMLObject + * @param child pointer to the child XMLObject * * @throws UnmarshallingException thrown if there is a problem adding the child to the parent */ - virtual void processChildElement(XMLObject* parent, XMLObject* child) const=0; + virtual void processChildElement(XMLObject& parent, XMLObject* child) const=0; /** * Called after an attribute has been unmarshalled so that it can be added to the XMLObject. @@ -109,7 +109,7 @@ namespace xmltooling { * * @throws UnmarshallingException thrown if there is a problem adding the attribute to the XMLObject */ - virtual void processAttribute(XMLObject* xmlObject, const DOMAttr* attribute) const=0; + virtual void processAttribute(XMLObject& xmlObject, const DOMAttr* attribute) const=0; /** * Called if the element being unmarshalled contained textual content so that it can be added to the XMLObject. @@ -117,7 +117,7 @@ namespace xmltooling { * @param xmlObject XMLObject the content will be given to * @param elementContent the Element's text content */ - virtual void processElementContent(XMLObject* xmlObject, const XMLCh* elementContent) const=0; + virtual void processElementContent(XMLObject& xmlObject, const XMLCh* elementContent) const=0; void* m_log; private: diff --git a/xmltooling/io/Unmarshaller.cpp b/xmltooling/io/Unmarshaller.cpp index 41acae8..4c3aef4 100644 --- a/xmltooling/io/Unmarshaller.cpp +++ b/xmltooling/io/Unmarshaller.cpp @@ -43,7 +43,7 @@ const Unmarshaller* Unmarshaller::getUnmarshaller(const DOMElement* domElement) Category& log=Category::getInstance(XMLTOOLING_LOGCAT".Unmarshaller"); auto_ptr schemaType(XMLHelper::getXSIType(domElement)); - const Unmarshaller* m = getUnmarshaller(*(schemaType.get())); + const Unmarshaller* m = schemaType.get() ? getUnmarshaller(*(schemaType.get())) : NULL; if (m) { if (log.isDebugEnabled()) { log.debug("located Unmarshaller for schema type: %s", schemaType->toString().c_str()); diff --git a/xmltoolingtest/UnknownTest.h b/xmltoolingtest/UnknownTest.h index 46196e5..31dbec9 100644 --- a/xmltoolingtest/UnknownTest.h +++ b/xmltoolingtest/UnknownTest.h @@ -17,8 +17,6 @@ #include "XMLObjectBaseTestCase.h" #include -#include -#include class UnknownTest : public CxxTest::TestSuite { diff --git a/xmltoolingtest/UnmarshallingTest.h b/xmltoolingtest/UnmarshallingTest.h new file mode 100644 index 0000000..efe505f --- /dev/null +++ b/xmltoolingtest/UnmarshallingTest.h @@ -0,0 +1,75 @@ +/* + * Copyright 2001-2005 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. + */ + +#include "XMLObjectBaseTestCase.h" + +#include +#include + +const XMLCh SimpleXMLObject::NAMESPACE[] = { + chLatin_h, chLatin_t, chLatin_t, chLatin_p, chColon, chForwardSlash, chForwardSlash, + chLatin_w, chLatin_w, chLatin_w, chPeriod, + chLatin_e, chLatin_x, chLatin_a, chLatin_m, chLatin_p, chLatin_l, chLatin_e, chPeriod, + chLatin_o, chLatin_r, chLatin_g, chForwardSlash, + chLatin_t, chLatin_e, chLatin_s, chLatin_t, + chLatin_O, chLatin_b, chLatin_j, chLatin_e, chLatin_c, chLatin_t, chLatin_s, chNull +}; + +const XMLCh SimpleXMLObject::NAMESPACE_PREFIX[] = { + chLatin_t, chLatin_e, chLatin_s, chLatin_t, chNull +}; + +const XMLCh SimpleXMLObject::LOCAL_NAME[] = { + chLatin_S, chLatin_i, chLatin_m, chLatin_p, chLatin_l, chLatin_e, + chLatin_E, chLatin_l, chLatin_e, chLatin_m, chLatin_e, chLatin_n, chLatin_t, chNull +}; + +const XMLCh SimpleXMLObject::ID_ATTRIB_NAME[] = { + chLatin_I, chLatin_d, chNull +}; + +class UnmarshallingTest : public CxxTest::TestSuite { + QName m_qname; +public: + UnmarshallingTest() : m_qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME) {} + + void setUp() { + XMLObjectBuilder::registerBuilder(m_qname, new SimpleXMLObjectBuilder()); + Marshaller::registerMarshaller(m_qname, new SimpleXMLObjectMarshaller()); + Unmarshaller::registerUnmarshaller(m_qname, new SimpleXMLObjectUnmarshaller()); + } + + void tearDown() { + XMLObjectBuilder::deregisterBuilder(m_qname); + Marshaller::deregisterMarshaller(m_qname); + Unmarshaller::deregisterUnmarshaller(m_qname); + } + + void testUnmarshallingWithAttributes() { + ifstream fs("../xmltoolingtest/data/SimpleXMLObjectWithAttribute.xml"); + DOMDocument* doc=nonvalidatingPool->parse(fs); + TS_ASSERT(doc!=NULL); + + const Unmarshaller* u = Unmarshaller::getUnmarshaller(doc->getDocumentElement()); + TS_ASSERT(u!=NULL); + + auto_ptr sxObject(dynamic_cast(u->unmarshall(doc->getDocumentElement(),true))); + TS_ASSERT(sxObject.get()!=NULL); + + auto_ptr_XMLCh expectedId("Firefly"); + TSM_ASSERT_SAME_DATA("ID was not expected value", expectedId.get(), sxObject->getId(), XMLString::stringLen(expectedId.get())); + } +}; diff --git a/xmltoolingtest/XMLObjectBaseTestCase.h b/xmltoolingtest/XMLObjectBaseTestCase.h index 99e878a..d0fb2d0 100644 --- a/xmltoolingtest/XMLObjectBaseTestCase.h +++ b/xmltoolingtest/XMLObjectBaseTestCase.h @@ -15,7 +15,12 @@ */ #include +#include +#include +#include #include +#include +#include #include #include @@ -25,3 +30,124 @@ using namespace std; extern ParserPool* validatingPool; extern ParserPool* nonvalidatingPool; +#if defined (_MSC_VER) + #pragma warning( push ) + #pragma warning( disable : 4250 4251 ) +#endif + +class SimpleXMLObjectUnmarshaller; + +class SimpleXMLObject : public AbstractDOMCachingXMLObject +{ +public: + static const XMLCh NAMESPACE[]; + static const XMLCh NAMESPACE_PREFIX[]; + static const XMLCh LOCAL_NAME[]; + static const XMLCh ID_ATTRIB_NAME[]; + + SimpleXMLObject() : AbstractDOMCachingXMLObject(NAMESPACE, LOCAL_NAME, NAMESPACE_PREFIX), m_id(NULL), m_value(NULL) {} + virtual ~SimpleXMLObject() { + XMLString::release(&m_id); + XMLString::release(&m_value); + for_each(m_children.begin(), m_children.end(), cleanup()); + } + + const XMLCh* getId() const { return m_id; } + void setId(const XMLCh* id) { m_id=prepareForAssignment(m_id,id); } + + const XMLCh* getValue() const { return m_value; } + void setValue(const XMLCh* value) { m_value=prepareForAssignment(m_value,value); } + + const list& getSimpleXMLObjects() const { return m_children; } + + bool hasChildren() const { return !m_children.empty(); } + size_t getOrderedChildren(vector& children) const { + children.assign(m_children.begin(),m_children.end()); + return children.size(); + } + SimpleXMLObject* clone() const { + SimpleXMLObject* ret=new SimpleXMLObject(); + ret->setId(m_id); + ret->setValue(m_value); + xmltooling::clone(m_children, ret->m_children); + return ret; + } + +private: + XMLCh* m_id; + XMLCh* m_value; + list m_children; + + friend class SimpleXMLObjectUnmarshaller; +}; + +class SimpleXMLObjectBuilder : public XMLObjectBuilder +{ +public: + XMLObject* buildObject() const { + return new SimpleXMLObject(); + } +}; + +class SimpleXMLObjectMarshaller : public AbstractXMLObjectMarshaller +{ +public: + SimpleXMLObjectMarshaller() : AbstractXMLObjectMarshaller(SimpleXMLObject::NAMESPACE, SimpleXMLObject::LOCAL_NAME) {} + +private: + void marshallAttributes(const XMLObject& xmlObject, DOMElement* domElement) const { + const SimpleXMLObject& simpleXMLObject = dynamic_cast(xmlObject); + + if(simpleXMLObject.getId()) { + domElement->setAttributeNS(NULL, SimpleXMLObject::ID_ATTRIB_NAME, simpleXMLObject.getId()); + domElement->setIdAttributeNS(NULL, SimpleXMLObject::ID_ATTRIB_NAME); + } + } + + void marshallElementContent(const XMLObject& xmlObject, DOMElement* domElement) const { + const SimpleXMLObject& simpleXMLObject = dynamic_cast(xmlObject); + + if(simpleXMLObject.getValue()) { + domElement->setTextContent(simpleXMLObject.getValue()); + } + } +}; + +class SimpleXMLObjectUnmarshaller : public AbstractXMLObjectUnmarshaller +{ +public: + SimpleXMLObjectUnmarshaller() : AbstractXMLObjectUnmarshaller(SimpleXMLObject::NAMESPACE, SimpleXMLObject::LOCAL_NAME) {} + +private: + void processChildElement(XMLObject& parentXMLObject, XMLObject* childXMLObject) const { + SimpleXMLObject& simpleXMLObject = dynamic_cast(parentXMLObject); + + SimpleXMLObject* child = dynamic_cast(childXMLObject); + if (child) { + simpleXMLObject.m_children.push_back(child); + } + else { + throw UnmarshallingException("Unknown child element cannot be added to parent object."); + } + } + + void processAttribute(XMLObject& xmlObject, const DOMAttr* attribute) const { + SimpleXMLObject& simpleXMLObject = dynamic_cast(xmlObject); + + if (XMLString::equals(attribute->getLocalName(),SimpleXMLObject::ID_ATTRIB_NAME)) { + simpleXMLObject.setId(attribute->getValue()); + } + } + + void processElementContent(XMLObject& xmlObject, const XMLCh* elementContent) const { + SimpleXMLObject& simpleXMLObject = dynamic_cast(xmlObject); + + simpleXMLObject.setValue(elementContent); + } + +}; + + +#if defined (_MSC_VER) + #pragma warning( pop ) +#endif diff --git a/xmltoolingtest/data/SimpleXMLObjectWithAttribute.xml b/xmltoolingtest/data/SimpleXMLObjectWithAttribute.xml new file mode 100644 index 0000000..0b75784 Binary files /dev/null and b/xmltoolingtest/data/SimpleXMLObjectWithAttribute.xml differ diff --git a/xmltoolingtest/data/SimpleXMLObjectWithContent.xml b/xmltoolingtest/data/SimpleXMLObjectWithContent.xml new file mode 100644 index 0000000..d6df345 Binary files /dev/null and b/xmltoolingtest/data/SimpleXMLObjectWithContent.xml differ diff --git a/xmltoolingtest/xmltoolingtest.vcproj b/xmltoolingtest/xmltoolingtest.vcproj index a19b4f1..1da845b 100644 --- a/xmltoolingtest/xmltoolingtest.vcproj +++ b/xmltoolingtest/xmltoolingtest.vcproj @@ -184,6 +184,10 @@ > + + @@ -216,6 +220,28 @@ + + + + + + + +