gcc const fix, converted linefeeds
authorScott Cantor <cantor.2@osu.edu>
Fri, 13 Oct 2006 18:40:48 +0000 (18:40 +0000)
committerScott Cantor <cantor.2@osu.edu>
Fri, 13 Oct 2006 18:40:48 +0000 (18:40 +0000)
77 files changed:
xmltooling/AbstractAttributeExtensibleXMLObject.cpp
xmltooling/AbstractAttributeExtensibleXMLObject.h
xmltooling/AbstractComplexElement.h
xmltooling/AbstractDOMCachingXMLObject.cpp
xmltooling/AbstractDOMCachingXMLObject.h
xmltooling/AbstractElementProxy.h
xmltooling/AbstractSimpleElement.cpp
xmltooling/AbstractSimpleElement.h
xmltooling/AbstractXMLObject.cpp
xmltooling/AbstractXMLObject.h
xmltooling/AttributeExtensibleXMLObject.h
xmltooling/ElementProxy.h
xmltooling/Lockable.h
xmltooling/Namespace.cpp
xmltooling/Namespace.h
xmltooling/PluginManager.h
xmltooling/QName.cpp
xmltooling/QName.h
xmltooling/XMLObject.h
xmltooling/XMLObjectBuilder.cpp
xmltooling/XMLToolingConfig.h
xmltooling/config_pub_win32.h
xmltooling/encryption/EncryptedKeyResolver.h
xmltooling/impl/MemoryStorageService.cpp
xmltooling/impl/UnknownElement.cpp
xmltooling/impl/UnknownElement.h
xmltooling/io/AbstractXMLObjectMarshaller.cpp
xmltooling/io/AbstractXMLObjectMarshaller.h
xmltooling/io/AbstractXMLObjectUnmarshaller.h
xmltooling/security/OpenSSLCryptoX509CRL.h
xmltooling/security/TrustEngine.h
xmltooling/security/X509TrustEngine.h
xmltooling/security/XSECCryptoX509CRL.h
xmltooling/security/impl/ExplicitKeyTrustEngine.cpp
xmltooling/security/impl/OpenSSLCryptoX509CRL.cpp
xmltooling/security/impl/XSECCryptoX509CRL.cpp
xmltooling/signature/CachingKeyResolver.h
xmltooling/signature/ContentReference.h
xmltooling/signature/CredentialResolver.h
xmltooling/signature/KeyResolver.h
xmltooling/signature/OpenSSLCredentialResolver.h
xmltooling/signature/Signature.h
xmltooling/signature/SignatureValidator.h
xmltooling/signature/impl/FilesystemCredentialResolver.cpp
xmltooling/signature/impl/InlineKeyResolver.cpp
xmltooling/signature/impl/SignatureValidator.cpp
xmltooling/signature/impl/XMLSecSignatureImpl.cpp
xmltooling/soap/impl/SOAPImpl.cpp
xmltooling/unicode.cpp
xmltooling/unicode.h
xmltooling/util/DateTime.cpp
xmltooling/util/DateTime.h
xmltooling/util/NDC.cpp
xmltooling/util/NDC.h
xmltooling/util/ParserPool.h
xmltooling/util/ReplayCache.h
xmltooling/util/StorageService.h
xmltooling/util/Win32Threads.cpp
xmltooling/util/XMLConstants.cpp
xmltooling/util/XMLConstants.h
xmltooling/util/XMLHelper.cpp
xmltooling/util/XMLHelper.h
xmltooling/validation/Validator.h
xmltooling/validation/ValidatorSuite.cpp
xmltooling/validation/ValidatorSuite.h
xmltooling/version.h
xmltoolingtest/ComplexXMLObjectTest.h
xmltoolingtest/EncryptionTest.h
xmltoolingtest/ExceptionTest.h
xmltoolingtest/FilesystemCredentialResolverTest.h
xmltoolingtest/InlineKeyResolverTest.h
xmltoolingtest/KeyInfoTest.h
xmltoolingtest/MarshallingTest.h
xmltoolingtest/MemoryStorageServiceTest.h
xmltoolingtest/SignatureTest.h
xmltoolingtest/UnmarshallingTest.h
xmltoolingtest/xmltoolingtest.h

index 3ebf6c5..a445248 100644 (file)
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * AbstractAttributeExtensibleXMLObject.cpp\r
- * \r
- * Extension of AbstractDOMCachingXMLObject that implements an AttributeExtensibleXMLObject. \r
- */\r
-\r
-#include "internal.h"\r
-#include "AbstractAttributeExtensibleXMLObject.h"\r
-\r
-#include <algorithm>\r
-#include <functional>\r
-\r
-using namespace xmltooling;\r
-using namespace std;\r
-\r
-set<QName> AttributeExtensibleXMLObject::m_idAttributeSet;\r
-\r
-AbstractAttributeExtensibleXMLObject::~AbstractAttributeExtensibleXMLObject()\r
-{\r
-    for (map<QName,XMLCh*>::iterator i=m_attributeMap.begin(); i!=m_attributeMap.end(); i++)\r
-        XMLString::release(&(i->second));\r
-}\r
-\r
-AbstractAttributeExtensibleXMLObject::AbstractAttributeExtensibleXMLObject(const AbstractAttributeExtensibleXMLObject& src)\r
-    : AbstractXMLObject(src)\r
-{\r
-    m_idAttribute = m_attributeMap.end();\r
-    for (map<QName,XMLCh*>::const_iterator i=src.m_attributeMap.begin(); i!=src.m_attributeMap.end(); i++) {\r
-        m_attributeMap[i->first] = XMLString::replicate(i->second);\r
-    }\r
-    if (src.m_idAttribute != src.m_attributeMap.end()) {\r
-        m_idAttribute = m_attributeMap.find(src.m_idAttribute->first);\r
-    }\r
-}\r
-\r
-void AbstractAttributeExtensibleXMLObject::setAttribute(const QName& qualifiedName, const XMLCh* value, bool ID)\r
-{\r
-    map<QName,XMLCh*>::iterator i=m_attributeMap.find(qualifiedName);\r
-    if (i!=m_attributeMap.end()) {\r
-        releaseThisandParentDOM();\r
-        XMLString::release(&(i->second));\r
-        if (value) {\r
-            i->second=XMLString::replicate(value);\r
-        }\r
-        else {\r
-            if (m_idAttribute==i)\r
-                m_idAttribute=m_attributeMap.end();\r
-            m_attributeMap.erase(i);\r
-        }\r
-        \r
-        if (ID) {\r
-            m_idAttribute=i;\r
-        }\r
-    }\r
-    else if (value) {\r
-        releaseThisandParentDOM();\r
-        m_attributeMap[qualifiedName]=XMLString::replicate(value);\r
-        if (ID) {\r
-            m_idAttribute = m_attributeMap.find(qualifiedName);\r
-        } \r
-    }\r
-}\r
-\r
-void AbstractAttributeExtensibleXMLObject::unmarshallExtensionAttribute(const DOMAttr* attribute)\r
-{\r
-    QName q(attribute->getNamespaceURI(),attribute->getLocalName(),attribute->getPrefix());\r
-    bool ID = isRegisteredIDAttribute(q); \r
-    setAttribute(q,attribute->getNodeValue(),ID);\r
-    if (ID) {\r
-        attribute->getOwnerElement()->setIdAttributeNode(attribute);\r
-    }\r
-}\r
-\r
-void AbstractAttributeExtensibleXMLObject::marshallExtensionAttributes(DOMElement* domElement) const\r
-{\r
-    for (map<QName,XMLCh*>::const_iterator i=m_attributeMap.begin(); i!=m_attributeMap.end(); i++) {\r
-        DOMAttr* attr=domElement->getOwnerDocument()->createAttributeNS(i->first.getNamespaceURI(),i->first.getLocalPart());\r
-        if (i->first.hasPrefix())\r
-            attr->setPrefix(i->first.getPrefix());\r
-        attr->setNodeValue(i->second);\r
-        domElement->setAttributeNode(attr);\r
-        if (m_idAttribute==i)\r
-            domElement->setIdAttributeNode(attr);\r
-    }\r
-}\r
+/*
+ *  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.
+ */
+
+/**
+ * AbstractAttributeExtensibleXMLObject.cpp
+ * 
+ * Extension of AbstractDOMCachingXMLObject that implements an AttributeExtensibleXMLObject. 
+ */
+
+#include "internal.h"
+#include "AbstractAttributeExtensibleXMLObject.h"
+
+#include <algorithm>
+#include <functional>
+
+using namespace xmltooling;
+using namespace std;
+
+set<QName> AttributeExtensibleXMLObject::m_idAttributeSet;
+
+AbstractAttributeExtensibleXMLObject::~AbstractAttributeExtensibleXMLObject()
+{
+    for (map<QName,XMLCh*>::iterator i=m_attributeMap.begin(); i!=m_attributeMap.end(); i++)
+        XMLString::release(&(i->second));
+}
+
+AbstractAttributeExtensibleXMLObject::AbstractAttributeExtensibleXMLObject(const AbstractAttributeExtensibleXMLObject& src)
+    : AbstractXMLObject(src)
+{
+    m_idAttribute = m_attributeMap.end();
+    for (map<QName,XMLCh*>::const_iterator i=src.m_attributeMap.begin(); i!=src.m_attributeMap.end(); i++) {
+        m_attributeMap[i->first] = XMLString::replicate(i->second);
+    }
+    if (src.m_idAttribute != src.m_attributeMap.end()) {
+        m_idAttribute = m_attributeMap.find(src.m_idAttribute->first);
+    }
+}
+
+void AbstractAttributeExtensibleXMLObject::setAttribute(const QName& qualifiedName, const XMLCh* value, bool ID)
+{
+    map<QName,XMLCh*>::iterator i=m_attributeMap.find(qualifiedName);
+    if (i!=m_attributeMap.end()) {
+        releaseThisandParentDOM();
+        XMLString::release(&(i->second));
+        if (value) {
+            i->second=XMLString::replicate(value);
+        }
+        else {
+            if (m_idAttribute==i)
+                m_idAttribute=m_attributeMap.end();
+            m_attributeMap.erase(i);
+        }
+        
+        if (ID) {
+            m_idAttribute=i;
+        }
+    }
+    else if (value) {
+        releaseThisandParentDOM();
+        m_attributeMap[qualifiedName]=XMLString::replicate(value);
+        if (ID) {
+            m_idAttribute = m_attributeMap.find(qualifiedName);
+        } 
+    }
+}
+
+void AbstractAttributeExtensibleXMLObject::unmarshallExtensionAttribute(const DOMAttr* attribute)
+{
+    QName q(attribute->getNamespaceURI(),attribute->getLocalName(),attribute->getPrefix());
+    bool ID = isRegisteredIDAttribute(q); 
+    setAttribute(q,attribute->getNodeValue(),ID);
+    if (ID) {
+        attribute->getOwnerElement()->setIdAttributeNode(attribute);
+    }
+}
+
+void AbstractAttributeExtensibleXMLObject::marshallExtensionAttributes(DOMElement* domElement) const
+{
+    for (map<QName,XMLCh*>::const_iterator i=m_attributeMap.begin(); i!=m_attributeMap.end(); i++) {
+        DOMAttr* attr=domElement->getOwnerDocument()->createAttributeNS(i->first.getNamespaceURI(),i->first.getLocalPart());
+        if (i->first.hasPrefix())
+            attr->setPrefix(i->first.getPrefix());
+        attr->setNodeValue(i->second);
+        domElement->setAttributeNode(attr);
+        if (m_idAttribute==i)
+            domElement->setIdAttributeNode(attr);
+    }
+}
index 9480cff..3f50678 100644 (file)
@@ -1,98 +1,98 @@
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file AbstractAttributeExtensibleXMLObject.h\r
- * \r
- * AbstractXMLObject mixin that implements AttributeExtensibleXMLObject\r
- */\r
-\r
-#ifndef __xmltooling_absattrextxmlobj_h__\r
-#define __xmltooling_absattrextxmlobj_h__\r
-\r
-#include <map>\r
-#include <xmltooling/AbstractXMLObject.h>\r
-#include <xmltooling/AttributeExtensibleXMLObject.h>\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( push )\r
-    #pragma warning( disable : 4250 4251 )\r
-#endif\r
-\r
-namespace xmltooling {\r
-\r
-    /**\r
-     * AbstractXMLObject mixin that implements AttributeExtensibleXMLObject.\r
-     * Inherit from this class to add support for attribute wildcarding.\r
-     */\r
-    class XMLTOOL_API AbstractAttributeExtensibleXMLObject\r
-        : public virtual AttributeExtensibleXMLObject, public virtual AbstractXMLObject\r
-    {\r
-    public:\r
-        virtual ~AbstractAttributeExtensibleXMLObject();\r
-        \r
-        const XMLCh* getAttribute(const QName& qualifiedName) const {\r
-            std::map<QName,XMLCh*>::const_iterator i=m_attributeMap.find(qualifiedName);\r
-            return (i==m_attributeMap.end()) ? NULL : i->second;\r
-        }\r
-        \r
-        void setAttribute(const QName& qualifiedName, const XMLCh* value, bool ID=false);\r
-    \r
-        const std::map<QName,XMLCh*>& getExtensionAttributes() const {\r
-            return m_attributeMap;\r
-        }\r
-        \r
-        const XMLCh* getXMLID() const {\r
-            return (m_idAttribute == m_attributeMap.end()) ? NULL : m_idAttribute->second;\r
-        }\r
-    \r
-     protected:\r
-        AbstractAttributeExtensibleXMLObject() {\r
-            m_idAttribute = m_attributeMap.end();\r
-        }\r
-\r
-        /** Copy constructor. */\r
-        AbstractAttributeExtensibleXMLObject(const AbstractAttributeExtensibleXMLObject& src);\r
-\r
-        /**\r
-         * Assists in the unmarshalling of extension attributes.\r
-         * \r
-         * @param attribute the DOM attribute node being unmarshalled\r
-         */\r
-        void unmarshallExtensionAttribute(const DOMAttr* attribute);\r
-\r
-        /**\r
-         * Assists in the marshalling of extension attributes.\r
-         * \r
-         * @param domElement    the DOM element against which to marshall the attributes\r
-         */\r
-        void marshallExtensionAttributes(DOMElement* domElement) const;\r
-    \r
-    private:\r
-        /** Map of arbitrary attributes. */\r
-        std::map<QName,XMLCh*> m_attributeMap;\r
-        \r
-        /** Points to the last attribute designated as an XML ID. */\r
-        std::map<QName,XMLCh*>::const_iterator m_idAttribute;\r
-    };\r
-    \r
-};\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( pop )\r
-#endif\r
-\r
-#endif /* __xmltooling_absattrextxmlobj_h__ */\r
+/*
+ *  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.
+ */
+
+/**
+ * @file AbstractAttributeExtensibleXMLObject.h
+ * 
+ * AbstractXMLObject mixin that implements AttributeExtensibleXMLObject
+ */
+
+#ifndef __xmltooling_absattrextxmlobj_h__
+#define __xmltooling_absattrextxmlobj_h__
+
+#include <map>
+#include <xmltooling/AbstractXMLObject.h>
+#include <xmltooling/AttributeExtensibleXMLObject.h>
+
+#if defined (_MSC_VER)
+    #pragma warning( push )
+    #pragma warning( disable : 4250 4251 )
+#endif
+
+namespace xmltooling {
+
+    /**
+     * AbstractXMLObject mixin that implements AttributeExtensibleXMLObject.
+     * Inherit from this class to add support for attribute wildcarding.
+     */
+    class XMLTOOL_API AbstractAttributeExtensibleXMLObject
+        : public virtual AttributeExtensibleXMLObject, public virtual AbstractXMLObject
+    {
+    public:
+        virtual ~AbstractAttributeExtensibleXMLObject();
+        
+        const XMLCh* getAttribute(const QName& qualifiedName) const {
+            std::map<QName,XMLCh*>::const_iterator i=m_attributeMap.find(qualifiedName);
+            return (i==m_attributeMap.end()) ? NULL : i->second;
+        }
+        
+        void setAttribute(const QName& qualifiedName, const XMLCh* value, bool ID=false);
+    
+        const std::map<QName,XMLCh*>& getExtensionAttributes() const {
+            return m_attributeMap;
+        }
+        
+        const XMLCh* getXMLID() const {
+            return (m_idAttribute == m_attributeMap.end()) ? NULL : m_idAttribute->second;
+        }
+    
+     protected:
+        AbstractAttributeExtensibleXMLObject() {
+            m_idAttribute = m_attributeMap.end();
+        }
+
+        /** Copy constructor. */
+        AbstractAttributeExtensibleXMLObject(const AbstractAttributeExtensibleXMLObject& src);
+
+        /**
+         * Assists in the unmarshalling of extension attributes.
+         * 
+         * @param attribute the DOM attribute node being unmarshalled
+         */
+        void unmarshallExtensionAttribute(const DOMAttr* attribute);
+
+        /**
+         * Assists in the marshalling of extension attributes.
+         * 
+         * @param domElement    the DOM element against which to marshall the attributes
+         */
+        void marshallExtensionAttributes(DOMElement* domElement) const;
+    
+    private:
+        /** Map of arbitrary attributes. */
+        std::map<QName,XMLCh*> m_attributeMap;
+        
+        /** Points to the last attribute designated as an XML ID. */
+        std::map<QName,XMLCh*>::const_iterator m_idAttribute;
+    };
+    
+};
+
+#if defined (_MSC_VER)
+    #pragma warning( pop )
+#endif
+
+#endif /* __xmltooling_absattrextxmlobj_h__ */
index ba8b862..636b042 100644 (file)
@@ -1,85 +1,85 @@
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file xmltooling/AbstractComplexElement.h\r
- * \r
- * AbstractXMLObject mixin that implements children\r
- */\r
-\r
-#ifndef __xmltooling_abscomplexel_h__\r
-#define __xmltooling_abscomplexel_h__\r
-\r
-#include <xmltooling/AbstractXMLObject.h>\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( push )\r
-    #pragma warning( disable : 4250 4251 )\r
-#endif\r
-\r
-namespace xmltooling {\r
-\r
-    /**\r
-     * AbstractXMLObject mixin that implements children.\r
-     * Inherit from this class to implement an element with child objects and mixed content.\r
-     */\r
-    class XMLTOOL_API AbstractComplexElement : public virtual AbstractXMLObject\r
-    {\r
-    public:\r
-        virtual ~AbstractComplexElement();\r
-        \r
-        bool hasChildren() const {\r
-            return !m_children.empty();\r
-        }\r
-\r
-        const std::list<XMLObject*>& getOrderedChildren() const {\r
-            return m_children;\r
-        }\r
-\r
-        void removeChild(XMLObject* child);\r
-\r
-        const XMLCh* getTextContent(unsigned int position=0) const {\r
-            return (m_text.size() > position) ? m_text[position] : NULL; \r
-        }\r
-        \r
-        void setTextContent(const XMLCh* value, unsigned int position=0);\r
-\r
-    protected:\r
-        AbstractComplexElement() {}\r
-        \r
-        /** Copy constructor. */\r
-        AbstractComplexElement(const AbstractComplexElement& src);\r
-\r
-        /**\r
-         * Underlying list of child objects.\r
-         * Manages the lifetime of the children.\r
-         */\r
-        std::list<XMLObject*> m_children;\r
-        \r
-        /**\r
-         * Interstitial text nodes.\r
-         * Needed to support mixed content, and preserve DOM whitespace across rebuilds.\r
-         */\r
-        std::vector<XMLCh*> m_text;\r
-    };\r
-    \r
-};\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( pop )\r
-#endif\r
-\r
-#endif /* __xmltooling_abscomplexel_h__ */\r
+/*
+ *  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.
+ */
+
+/**
+ * @file xmltooling/AbstractComplexElement.h
+ * 
+ * AbstractXMLObject mixin that implements children
+ */
+
+#ifndef __xmltooling_abscomplexel_h__
+#define __xmltooling_abscomplexel_h__
+
+#include <xmltooling/AbstractXMLObject.h>
+
+#if defined (_MSC_VER)
+    #pragma warning( push )
+    #pragma warning( disable : 4250 4251 )
+#endif
+
+namespace xmltooling {
+
+    /**
+     * AbstractXMLObject mixin that implements children.
+     * Inherit from this class to implement an element with child objects and mixed content.
+     */
+    class XMLTOOL_API AbstractComplexElement : public virtual AbstractXMLObject
+    {
+    public:
+        virtual ~AbstractComplexElement();
+        
+        bool hasChildren() const {
+            return !m_children.empty();
+        }
+
+        const std::list<XMLObject*>& getOrderedChildren() const {
+            return m_children;
+        }
+
+        void removeChild(XMLObject* child);
+
+        const XMLCh* getTextContent(unsigned int position=0) const {
+            return (m_text.size() > position) ? m_text[position] : NULL; 
+        }
+        
+        void setTextContent(const XMLCh* value, unsigned int position=0);
+
+    protected:
+        AbstractComplexElement() {}
+        
+        /** Copy constructor. */
+        AbstractComplexElement(const AbstractComplexElement& src);
+
+        /**
+         * Underlying list of child objects.
+         * Manages the lifetime of the children.
+         */
+        std::list<XMLObject*> m_children;
+        
+        /**
+         * Interstitial text nodes.
+         * Needed to support mixed content, and preserve DOM whitespace across rebuilds.
+         */
+        std::vector<XMLCh*> m_text;
+    };
+    
+};
+
+#if defined (_MSC_VER)
+    #pragma warning( pop )
+#endif
+
+#endif /* __xmltooling_abscomplexel_h__ */
index bee23c2..4966156 100644 (file)
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * AbstractDOMCachingXMLObject.cpp\r
- * \r
- * Extension of AbstractXMLObject that implements a DOMCachingXMLObject. \r
- */\r
-\r
-#include "internal.h"\r
-#include "AbstractDOMCachingXMLObject.h"\r
-#include "exceptions.h"\r
-#include "XMLObjectBuilder.h"\r
-#include "util/XMLHelper.h"\r
-\r
-#include <algorithm>\r
-#include <functional>\r
-#include <log4cpp/Category.hh>\r
-\r
-using namespace xmltooling;\r
-using namespace log4cpp;\r
-using namespace std;\r
-\r
-AbstractDOMCachingXMLObject::~AbstractDOMCachingXMLObject()\r
-{\r
-    if (m_document)\r
-        m_document->release();\r
-}\r
-\r
-void AbstractDOMCachingXMLObject::setDOM(DOMElement* dom, bool bindDocument) const\r
-{\r
-    m_dom=dom;\r
-    if (dom) {\r
-        if (bindDocument) {\r
-            setDocument(dom->getOwnerDocument());\r
-        }\r
-    }\r
-}\r
-\r
-void AbstractDOMCachingXMLObject::releaseDOM() const\r
-{\r
-    if (m_dom) {\r
-        Category& log=Category::getInstance(XMLTOOLING_LOGCAT".DOM");\r
-        if (log.isDebugEnabled()) {\r
-            string qname=getElementQName().toString();\r
-            log.debug("releasing cached DOM representation for (%s)", qname.empty() ? "unknown" : qname.c_str());\r
-        }\r
-        setDOM(NULL);\r
-    }\r
-}\r
-\r
-void AbstractDOMCachingXMLObject::releaseParentDOM(bool propagateRelease) const\r
-{\r
-    if (getParent() && getParent()->getDOM()) {\r
-        Category::getInstance(XMLTOOLING_LOGCAT".DOM").debug(\r
-            "releasing cached DOM representation for parent object with propagation set to %s",\r
-            propagateRelease ? "true" : "false"\r
-            );\r
-        getParent()->releaseDOM();\r
-        if (propagateRelease)\r
-            getParent()->releaseParentDOM(propagateRelease);\r
-    }\r
-}\r
-\r
-class _release : public binary_function<XMLObject*,bool,void> {\r
-public:\r
-    void operator()(XMLObject* obj, bool propagate) const {\r
-        if (obj) {\r
-            obj->releaseDOM();\r
-            if (propagate)\r
-                obj->releaseChildrenDOM(propagate);\r
-        }\r
-    }\r
-};\r
-\r
-void AbstractDOMCachingXMLObject::releaseChildrenDOM(bool propagateRelease) const\r
-{\r
-    if (hasChildren()) {\r
-        Category::getInstance(XMLTOOLING_LOGCAT".DOM").debug(\r
-            "releasing cached DOM representation for children with propagation set to %s",\r
-            propagateRelease ? "true" : "false"\r
-            );\r
-        const list<XMLObject*>& children=getOrderedChildren();\r
-        for_each(children.begin(),children.end(),bind2nd(_release(),propagateRelease));\r
-    }\r
-}\r
-\r
-DOMElement* AbstractDOMCachingXMLObject::cloneDOM(DOMDocument* doc) const\r
-{\r
-    if (getDOM()) {\r
-        if (!doc)\r
-            doc=DOMImplementationRegistry::getDOMImplementation(NULL)->createDocument();\r
-        return static_cast<DOMElement*>(doc->importNode(getDOM(),true));\r
-    }\r
-    return NULL;\r
-}\r
-\r
-XMLObject* AbstractDOMCachingXMLObject::clone() const\r
-{\r
-    // See if we can clone via the DOM.\r
-    DOMElement* domCopy=cloneDOM();\r
-    if (domCopy) {\r
-        // Seemed to work, so now we unmarshall the DOM to produce the clone.\r
-        const XMLObjectBuilder* b=XMLObjectBuilder::getBuilder(domCopy);\r
-        if (!b) {\r
-            auto_ptr<QName> q(XMLHelper::getNodeQName(domCopy));\r
-            Category::getInstance(XMLTOOLING_LOGCAT".DOM").error(\r
-                "DOM clone failed, unable to locate builder for element (%s)", q->toString().c_str()\r
-                );\r
-            domCopy->getOwnerDocument()->release();\r
-            throw UnmarshallingException("Unable to locate builder for cloned element.");\r
-        }\r
-        XercesJanitor<DOMDocument> janitor(domCopy->getOwnerDocument());\r
-        XMLObject* ret = b->buildFromElement(domCopy,true); // bind document\r
-        janitor.release(); // safely transferred\r
-        return ret;\r
-    }\r
-    return NULL;\r
-}\r
-\r
-void AbstractDOMCachingXMLObject::detach()\r
-{\r
-    // This is an override that duplicates some of the checking in the base class but\r
-    // adds document management in preparation for deletion of the parent.\r
-\r
-    if (!getParent())\r
-        return;\r
-\r
-    if (getParent()->hasParent())\r
-        throw XMLObjectException("Cannot detach an object whose parent is itself a child.");\r
-\r
-    AbstractDOMCachingXMLObject* parent = dynamic_cast<AbstractDOMCachingXMLObject*>(getParent());\r
-    if (parent && parent->m_document) {\r
-        // Transfer control of document to me...\r
-        setDocument(parent->m_document);\r
-        parent->m_document = NULL;\r
-    }\r
-    // The rest is done by the base.\r
-    AbstractXMLObject::detach();\r
-}\r
+/*
+ *  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.
+ */
+
+/**
+ * AbstractDOMCachingXMLObject.cpp
+ * 
+ * Extension of AbstractXMLObject that implements a DOMCachingXMLObject. 
+ */
+
+#include "internal.h"
+#include "AbstractDOMCachingXMLObject.h"
+#include "exceptions.h"
+#include "XMLObjectBuilder.h"
+#include "util/XMLHelper.h"
+
+#include <algorithm>
+#include <functional>
+#include <log4cpp/Category.hh>
+
+using namespace xmltooling;
+using namespace log4cpp;
+using namespace std;
+
+AbstractDOMCachingXMLObject::~AbstractDOMCachingXMLObject()
+{
+    if (m_document)
+        m_document->release();
+}
+
+void AbstractDOMCachingXMLObject::setDOM(DOMElement* dom, bool bindDocument) const
+{
+    m_dom=dom;
+    if (dom) {
+        if (bindDocument) {
+            setDocument(dom->getOwnerDocument());
+        }
+    }
+}
+
+void AbstractDOMCachingXMLObject::releaseDOM() const
+{
+    if (m_dom) {
+        Category& log=Category::getInstance(XMLTOOLING_LOGCAT".DOM");
+        if (log.isDebugEnabled()) {
+            string qname=getElementQName().toString();
+            log.debug("releasing cached DOM representation for (%s)", qname.empty() ? "unknown" : qname.c_str());
+        }
+        setDOM(NULL);
+    }
+}
+
+void AbstractDOMCachingXMLObject::releaseParentDOM(bool propagateRelease) const
+{
+    if (getParent() && getParent()->getDOM()) {
+        Category::getInstance(XMLTOOLING_LOGCAT".DOM").debug(
+            "releasing cached DOM representation for parent object with propagation set to %s",
+            propagateRelease ? "true" : "false"
+            );
+        getParent()->releaseDOM();
+        if (propagateRelease)
+            getParent()->releaseParentDOM(propagateRelease);
+    }
+}
+
+class _release : public binary_function<XMLObject*,bool,void> {
+public:
+    void operator()(XMLObject* obj, bool propagate) const {
+        if (obj) {
+            obj->releaseDOM();
+            if (propagate)
+                obj->releaseChildrenDOM(propagate);
+        }
+    }
+};
+
+void AbstractDOMCachingXMLObject::releaseChildrenDOM(bool propagateRelease) const
+{
+    if (hasChildren()) {
+        Category::getInstance(XMLTOOLING_LOGCAT".DOM").debug(
+            "releasing cached DOM representation for children with propagation set to %s",
+            propagateRelease ? "true" : "false"
+            );
+        const list<XMLObject*>& children=getOrderedChildren();
+        for_each(children.begin(),children.end(),bind2nd(_release(),propagateRelease));
+    }
+}
+
+DOMElement* AbstractDOMCachingXMLObject::cloneDOM(DOMDocument* doc) const
+{
+    if (getDOM()) {
+        if (!doc)
+            doc=DOMImplementationRegistry::getDOMImplementation(NULL)->createDocument();
+        return static_cast<DOMElement*>(doc->importNode(getDOM(),true));
+    }
+    return NULL;
+}
+
+XMLObject* AbstractDOMCachingXMLObject::clone() const
+{
+    // See if we can clone via the DOM.
+    DOMElement* domCopy=cloneDOM();
+    if (domCopy) {
+        // Seemed to work, so now we unmarshall the DOM to produce the clone.
+        const XMLObjectBuilder* b=XMLObjectBuilder::getBuilder(domCopy);
+        if (!b) {
+            auto_ptr<QName> q(XMLHelper::getNodeQName(domCopy));
+            Category::getInstance(XMLTOOLING_LOGCAT".DOM").error(
+                "DOM clone failed, unable to locate builder for element (%s)", q->toString().c_str()
+                );
+            domCopy->getOwnerDocument()->release();
+            throw UnmarshallingException("Unable to locate builder for cloned element.");
+        }
+        XercesJanitor<DOMDocument> janitor(domCopy->getOwnerDocument());
+        XMLObject* ret = b->buildFromElement(domCopy,true); // bind document
+        janitor.release(); // safely transferred
+        return ret;
+    }
+    return NULL;
+}
+
+void AbstractDOMCachingXMLObject::detach()
+{
+    // This is an override that duplicates some of the checking in the base class but
+    // adds document management in preparation for deletion of the parent.
+
+    if (!getParent())
+        return;
+
+    if (getParent()->hasParent())
+        throw XMLObjectException("Cannot detach an object whose parent is itself a child.");
+
+    AbstractDOMCachingXMLObject* parent = dynamic_cast<AbstractDOMCachingXMLObject*>(getParent());
+    if (parent && parent->m_document) {
+        // Transfer control of document to me...
+        setDocument(parent->m_document);
+        parent->m_document = NULL;
+    }
+    // The rest is done by the base.
+    AbstractXMLObject::detach();
+}
index 1e357b9..94a9e56 100644 (file)
@@ -1,92 +1,92 @@
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file AbstractDOMCachingXMLObject.h\r
- * \r
- * AbstractXMLObject mixin that implements DOM caching\r
- */\r
-\r
-#if !defined(__xmltooling_abstractdomxmlobj_h__)\r
-#define __xmltooling_abstractdomxmlobj_h__\r
-\r
-#include <xmltooling/AbstractXMLObject.h>\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( push )\r
-    #pragma warning( disable : 4250 4251 )\r
-#endif\r
-\r
-namespace xmltooling {\r
-\r
-    /**\r
-     * AbstractXMLObject mixin that implements DOM caching.\r
-     * Inherit from this class to implement standard DOM caching behavior.\r
-     */\r
-    class XMLTOOL_API AbstractDOMCachingXMLObject : public virtual AbstractXMLObject\r
-    {\r
-    public:\r
-        virtual ~AbstractDOMCachingXMLObject();\r
-        \r
-        DOMElement* getDOM() const {\r
-            return m_dom;\r
-        }\r
-        \r
-        void setDOM(DOMElement* dom, bool bindDocument=false) const;\r
-        \r
-        void setDocument(DOMDocument* doc) const {\r
-            if (m_document)\r
-                m_document->release();\r
-            m_document=doc;\r
-        }\r
-    \r
-        virtual void releaseDOM() const;\r
-        \r
-        virtual void releaseParentDOM(bool propagateRelease=true) const;\r
-        \r
-        virtual void releaseChildrenDOM(bool propagateRelease=true) const;\r
-    \r
-        XMLObject* clone() const;\r
-\r
-        void detach();\r
-\r
-     protected:\r
-        AbstractDOMCachingXMLObject() : m_dom(NULL), m_document(NULL) {}\r
-\r
-        /** Copy constructor. */\r
-        AbstractDOMCachingXMLObject(const AbstractDOMCachingXMLObject& src)\r
-            : AbstractXMLObject(src), m_dom(NULL), m_document(NULL) {}\r
-\r
-        /**\r
-         * If a DOM representation exists, this clones it into a new document.\r
-         * \r
-         * @param doc   the document to clone into, or NULL, in which case a new document is created\r
-         * @return  the cloned DOM\r
-         */\r
-        DOMElement* cloneDOM(DOMDocument* doc=NULL) const;\r
-\r
-    private:\r
-        mutable DOMElement* m_dom;\r
-        mutable DOMDocument* m_document;\r
-    };\r
-    \r
-};\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( pop )\r
-#endif\r
-\r
-#endif /* __xmltooling_abstractdomxmlobj_h__ */\r
+/*
+ *  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.
+ */
+
+/**
+ * @file AbstractDOMCachingXMLObject.h
+ * 
+ * AbstractXMLObject mixin that implements DOM caching
+ */
+
+#if !defined(__xmltooling_abstractdomxmlobj_h__)
+#define __xmltooling_abstractdomxmlobj_h__
+
+#include <xmltooling/AbstractXMLObject.h>
+
+#if defined (_MSC_VER)
+    #pragma warning( push )
+    #pragma warning( disable : 4250 4251 )
+#endif
+
+namespace xmltooling {
+
+    /**
+     * AbstractXMLObject mixin that implements DOM caching.
+     * Inherit from this class to implement standard DOM caching behavior.
+     */
+    class XMLTOOL_API AbstractDOMCachingXMLObject : public virtual AbstractXMLObject
+    {
+    public:
+        virtual ~AbstractDOMCachingXMLObject();
+        
+        DOMElement* getDOM() const {
+            return m_dom;
+        }
+        
+        void setDOM(DOMElement* dom, bool bindDocument=false) const;
+        
+        void setDocument(DOMDocument* doc) const {
+            if (m_document)
+                m_document->release();
+            m_document=doc;
+        }
+    
+        virtual void releaseDOM() const;
+        
+        virtual void releaseParentDOM(bool propagateRelease=true) const;
+        
+        virtual void releaseChildrenDOM(bool propagateRelease=true) const;
+    
+        XMLObject* clone() const;
+
+        void detach();
+
+     protected:
+        AbstractDOMCachingXMLObject() : m_dom(NULL), m_document(NULL) {}
+
+        /** Copy constructor. */
+        AbstractDOMCachingXMLObject(const AbstractDOMCachingXMLObject& src)
+            : AbstractXMLObject(src), m_dom(NULL), m_document(NULL) {}
+
+        /**
+         * If a DOM representation exists, this clones it into a new document.
+         * 
+         * @param doc   the document to clone into, or NULL, in which case a new document is created
+         * @return  the cloned DOM
+         */
+        DOMElement* cloneDOM(DOMDocument* doc=NULL) const;
+
+    private:
+        mutable DOMElement* m_dom;
+        mutable DOMDocument* m_document;
+    };
+    
+};
+
+#if defined (_MSC_VER)
+    #pragma warning( pop )
+#endif
+
+#endif /* __xmltooling_abstractdomxmlobj_h__ */
index ed95e53..473a942 100644 (file)
@@ -1,67 +1,67 @@
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file xmltooling/AbstractElementProxy.h\r
- * \r
- * AbstractXMLObject mixin that implements an open content model \r
- */\r
-\r
-#ifndef __xmltooling_abseleproxy_h__\r
-#define __xmltooling_abseleproxy_h__\r
-\r
-#include <xmltooling/AbstractComplexElement.h>\r
-#include <xmltooling/ElementProxy.h>\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( push )\r
-    #pragma warning( disable : 4250 4251 )\r
-#endif\r
-\r
-namespace xmltooling {\r
-\r
-    /**\r
-     * AbstractXMLObject mixin that layers ElementProxy on top of a complex element.\r
-     * Inherit from this class to implement complex content\r
-     * and expose the underlying child collection in read/write mode.\r
-     */\r
-    class XMLTOOL_API AbstractElementProxy : public virtual ElementProxy, public AbstractComplexElement\r
-    {\r
-    public:\r
-        virtual ~AbstractElementProxy() {}\r
-        \r
-        virtual ListOf(XMLObject) getXMLObjects() {\r
-            return ListOf(XMLObject)(this,m_children,NULL,m_children.end());\r
-        }\r
-    \r
-        virtual const std::list<XMLObject*>& getXMLObjects() const {\r
-            return m_children;\r
-        }\r
-\r
-    protected:\r
-        AbstractElementProxy() {}\r
-        \r
-        /** Copy constructor. */\r
-        AbstractElementProxy(const AbstractElementProxy& src) : AbstractXMLObject(src), AbstractComplexElement(src) {}\r
-    };\r
-    \r
-};\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( pop )\r
-#endif\r
-\r
-#endif /* __xmltooling_abseleproxy_h__ */\r
+/*
+ *  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.
+ */
+
+/**
+ * @file xmltooling/AbstractElementProxy.h
+ * 
+ * AbstractXMLObject mixin that implements an open content model 
+ */
+
+#ifndef __xmltooling_abseleproxy_h__
+#define __xmltooling_abseleproxy_h__
+
+#include <xmltooling/AbstractComplexElement.h>
+#include <xmltooling/ElementProxy.h>
+
+#if defined (_MSC_VER)
+    #pragma warning( push )
+    #pragma warning( disable : 4250 4251 )
+#endif
+
+namespace xmltooling {
+
+    /**
+     * AbstractXMLObject mixin that layers ElementProxy on top of a complex element.
+     * Inherit from this class to implement complex content
+     * and expose the underlying child collection in read/write mode.
+     */
+    class XMLTOOL_API AbstractElementProxy : public virtual ElementProxy, public AbstractComplexElement
+    {
+    public:
+        virtual ~AbstractElementProxy() {}
+        
+        virtual ListOf(XMLObject) getXMLObjects() {
+            return ListOf(XMLObject)(this,m_children,NULL,m_children.end());
+        }
+    
+        virtual const std::list<XMLObject*>& getXMLObjects() const {
+            return m_children;
+        }
+
+    protected:
+        AbstractElementProxy() {}
+        
+        /** Copy constructor. */
+        AbstractElementProxy(const AbstractElementProxy& src) : AbstractXMLObject(src), AbstractComplexElement(src) {}
+    };
+    
+};
+
+#if defined (_MSC_VER)
+    #pragma warning( pop )
+#endif
+
+#endif /* __xmltooling_abseleproxy_h__ */
index 920aa3b..90fb717 100644 (file)
@@ -1,36 +1,36 @@
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * AbstractSimpleElement.cpp\r
- * \r
- * Extension of AbstractXMLObject that implements simple elements \r
- */\r
-\r
-#include "internal.h"\r
-#include "AbstractSimpleElement.h"\r
-\r
-using namespace xmltooling;\r
-using namespace std;\r
-\r
-// shared "empty" list of children for childless objects\r
-\r
-list<XMLObject*> AbstractSimpleElement::m_no_children;\r
-\r
-void AbstractSimpleElement::removeChild(XMLObject* child)\r
-{\r
-    throw XMLObjectException("Cannot remove child from a childless object.");\r
-}\r
+/*
+ *  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.
+ */
+
+/**
+ * AbstractSimpleElement.cpp
+ * 
+ * Extension of AbstractXMLObject that implements simple elements 
+ */
+
+#include "internal.h"
+#include "AbstractSimpleElement.h"
+
+using namespace xmltooling;
+using namespace std;
+
+// shared "empty" list of children for childless objects
+
+list<XMLObject*> AbstractSimpleElement::m_no_children;
+
+void AbstractSimpleElement::removeChild(XMLObject* child)
+{
+    throw XMLObjectException("Cannot remove child from a childless object.");
+}
index 86e0e80..b034533 100644 (file)
@@ -1,85 +1,85 @@
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file xmltooling/AbstractSimpleElement.h\r
- * \r
- * AbstractXMLObject mixin that implements a simple string-based content model \r
- */\r
-\r
-#ifndef __xmltooling_abssimpleel_h__\r
-#define __xmltooling_abssimpleel_h__\r
-\r
-#include <xmltooling/AbstractXMLObject.h>\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( push )\r
-    #pragma warning( disable : 4250 4251 )\r
-#endif\r
-\r
-namespace xmltooling {\r
-\r
-    /**\r
-     * AbstractXMLObject mixin that implements a simple string-based content model.\r
-     * Inherit from this class to support string-based element content.\r
-     */\r
-    class XMLTOOL_API AbstractSimpleElement : public virtual AbstractXMLObject\r
-    {\r
-    public:\r
-        virtual ~AbstractSimpleElement() {\r
-            XMLString::release(&m_value);\r
-        }\r
-        \r
-        bool hasChildren() const {\r
-            return false;\r
-        }\r
-\r
-        const std::list<XMLObject*>& getOrderedChildren() const {\r
-            return m_no_children;\r
-        }\r
-\r
-        void removeChild(XMLObject* child);\r
-\r
-        virtual const XMLCh* getTextContent(unsigned int position=0) const {\r
-            return (position==0) ? m_value : NULL;\r
-        }\r
-        \r
-        virtual void setTextContent(const XMLCh* value, unsigned int position=0) {\r
-            if (position > 0)\r
-                throw XMLObjectException("Cannot set text content in simple element at position > 0.");\r
-            m_value=prepareForAssignment(m_value,value);\r
-        }\r
-        \r
-    protected:\r
-        AbstractSimpleElement() : m_value(NULL) {}\r
-        \r
-        /** Copy constructor. */\r
-        AbstractSimpleElement(const AbstractSimpleElement& src)\r
-            : AbstractXMLObject(src), m_value(XMLString::replicate(src.m_value)) {}\r
-\r
-    private:\r
-        XMLCh* m_value;\r
-\r
-        static std::list<XMLObject*> m_no_children;\r
-    };\r
-    \r
-};\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( pop )\r
-#endif\r
-\r
-#endif /* __xmltooling_abssimpleel_h__ */\r
+/*
+ *  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.
+ */
+
+/**
+ * @file xmltooling/AbstractSimpleElement.h
+ * 
+ * AbstractXMLObject mixin that implements a simple string-based content model 
+ */
+
+#ifndef __xmltooling_abssimpleel_h__
+#define __xmltooling_abssimpleel_h__
+
+#include <xmltooling/AbstractXMLObject.h>
+
+#if defined (_MSC_VER)
+    #pragma warning( push )
+    #pragma warning( disable : 4250 4251 )
+#endif
+
+namespace xmltooling {
+
+    /**
+     * AbstractXMLObject mixin that implements a simple string-based content model.
+     * Inherit from this class to support string-based element content.
+     */
+    class XMLTOOL_API AbstractSimpleElement : public virtual AbstractXMLObject
+    {
+    public:
+        virtual ~AbstractSimpleElement() {
+            XMLString::release(&m_value);
+        }
+        
+        bool hasChildren() const {
+            return false;
+        }
+
+        const std::list<XMLObject*>& getOrderedChildren() const {
+            return m_no_children;
+        }
+
+        void removeChild(XMLObject* child);
+
+        virtual const XMLCh* getTextContent(unsigned int position=0) const {
+            return (position==0) ? m_value : NULL;
+        }
+        
+        virtual void setTextContent(const XMLCh* value, unsigned int position=0) {
+            if (position > 0)
+                throw XMLObjectException("Cannot set text content in simple element at position > 0.");
+            m_value=prepareForAssignment(m_value,value);
+        }
+        
+    protected:
+        AbstractSimpleElement() : m_value(NULL) {}
+        
+        /** Copy constructor. */
+        AbstractSimpleElement(const AbstractSimpleElement& src)
+            : AbstractXMLObject(src), m_value(XMLString::replicate(src.m_value)) {}
+
+    private:
+        XMLCh* m_value;
+
+        static std::list<XMLObject*> m_no_children;
+    };
+    
+};
+
+#if defined (_MSC_VER)
+    #pragma warning( pop )
+#endif
+
+#endif /* __xmltooling_abssimpleel_h__ */
index e019f4e..21ec488 100644 (file)
-/*\r
-*  Copyright 2001-2006 Internet2\r
- * \r
-* Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * AbstractXMLObject.cpp\r
- * \r
- * An abstract implementation of XMLObject.\r
- */\r
-\r
-#include "internal.h"\r
-#include "AbstractXMLObject.h"\r
-#include "exceptions.h"\r
-\r
-#include <algorithm>\r
-#include <log4cpp/Category.hh>\r
-\r
-using namespace xmltooling;\r
-\r
-AbstractXMLObject::AbstractXMLObject(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)\r
-    : m_log(&log4cpp::Category::getInstance(XMLTOOLING_LOGCAT".XMLObject")), m_schemaLocation(NULL),\r
-        m_parent(NULL), m_elementQname(nsURI, localName, prefix), m_typeQname(NULL)\r
-{\r
-    addNamespace(Namespace(nsURI, prefix));\r
-    if (schemaType) {\r
-        m_typeQname = new QName(*schemaType);\r
-        addNamespace(Namespace(m_typeQname->getNamespaceURI(), m_typeQname->getPrefix()));\r
-    }\r
-}\r
-\r
-AbstractXMLObject::AbstractXMLObject(const AbstractXMLObject& src)\r
-    : m_namespaces(src.m_namespaces), m_log(src.m_log), m_schemaLocation(XMLString::replicate(src.m_schemaLocation)),\r
-        m_parent(NULL), m_elementQname(src.m_elementQname), m_typeQname(NULL)\r
-{\r
-    if (src.m_typeQname)\r
-        m_typeQname=new QName(*src.m_typeQname);\r
-}\r
-\r
-XMLCh* AbstractXMLObject::prepareForAssignment(XMLCh* oldValue, const XMLCh* newValue)\r
-{\r
-    if (!XMLString::equals(oldValue,newValue)) {\r
-        releaseThisandParentDOM();\r
-        XMLCh* newString = XMLString::replicate(newValue);\r
-        XMLString::release(&oldValue);\r
-        return newString;\r
-    }\r
-    return oldValue;\r
-}\r
-\r
-QName* AbstractXMLObject::prepareForAssignment(QName* oldValue, const QName* newValue)\r
-{\r
-    if (!oldValue) {\r
-        if (newValue) {\r
-            releaseThisandParentDOM();\r
-            Namespace newNamespace(newValue->getNamespaceURI(), newValue->getPrefix());\r
-            addNamespace(newNamespace);\r
-            return new QName(*newValue);\r
-        }\r
-        return NULL;\r
-    }\r
-\r
-    delete oldValue;\r
-    releaseThisandParentDOM();\r
-    if (newValue) {\r
-        Namespace newNamespace(newValue->getNamespaceURI(), newValue->getPrefix());\r
-        addNamespace(newNamespace);\r
-        return new QName(*newValue);\r
-    }\r
-    return NULL;\r
-}\r
-\r
-DateTime* AbstractXMLObject::prepareForAssignment(DateTime* oldValue, const DateTime* newValue)\r
-{\r
-    if (!oldValue) {\r
-        if (newValue) {\r
-            releaseThisandParentDOM();\r
-            return new DateTime(*newValue);\r
-        }\r
-        return NULL;\r
-    }\r
-\r
-    delete oldValue;\r
-    releaseThisandParentDOM();\r
-    return newValue ? new DateTime(*newValue) : NULL;\r
-}\r
-\r
-DateTime* AbstractXMLObject::prepareForAssignment(DateTime* oldValue, time_t newValue)\r
-{\r
-    delete oldValue;\r
-    releaseThisandParentDOM();\r
-    DateTime* ret = new DateTime(newValue);\r
-    ret->parseDateTime();\r
-    return ret;\r
-}\r
-\r
-DateTime* AbstractXMLObject::prepareForAssignment(DateTime* oldValue, const XMLCh* newValue)\r
-{\r
-    delete oldValue;\r
-    releaseThisandParentDOM();\r
-    DateTime* ret = new DateTime(newValue);\r
-    ret->parseDateTime();\r
-    return ret;\r
-}\r
-\r
-XMLObject* AbstractXMLObject::prepareForAssignment(XMLObject* oldValue, XMLObject* newValue)\r
-{\r
-    if (newValue && newValue->hasParent())\r
-        throw XMLObjectException("child XMLObject cannot be added - it is already the child of another XMLObject");\r
-\r
-    if (!oldValue) {\r
-        if (newValue) {\r
-            releaseThisandParentDOM();\r
-            newValue->setParent(this);\r
-        }\r
-        return newValue;\r
-    }\r
-\r
-    if (oldValue != newValue) {\r
-        delete oldValue;\r
-        releaseThisandParentDOM();\r
-        if (newValue)\r
-            newValue->setParent(this);\r
-    }\r
-\r
-    return newValue;\r
-}\r
-\r
-void AbstractXMLObject::detach()\r
-{\r
-    if (!getParent())\r
-        return;\r
-    else if (getParent()->hasParent())\r
-        throw XMLObjectException("Cannot detach an object whose parent is itself a child.");\r
-\r
-    // Pull ourselves out of the parent and then blast him.\r
-    getParent()->removeChild(this);\r
-    delete m_parent;\r
-    m_parent = NULL;\r
-}\r
+/*
+*  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.
+ */
+
+/**
+ * AbstractXMLObject.cpp
+ * 
+ * An abstract implementation of XMLObject.
+ */
+
+#include "internal.h"
+#include "AbstractXMLObject.h"
+#include "exceptions.h"
+
+#include <algorithm>
+#include <log4cpp/Category.hh>
+
+using namespace xmltooling;
+
+AbstractXMLObject::AbstractXMLObject(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+    : m_log(&log4cpp::Category::getInstance(XMLTOOLING_LOGCAT".XMLObject")), m_schemaLocation(NULL),
+        m_parent(NULL), m_elementQname(nsURI, localName, prefix), m_typeQname(NULL)
+{
+    addNamespace(Namespace(nsURI, prefix));
+    if (schemaType) {
+        m_typeQname = new QName(*schemaType);
+        addNamespace(Namespace(m_typeQname->getNamespaceURI(), m_typeQname->getPrefix()));
+    }
+}
+
+AbstractXMLObject::AbstractXMLObject(const AbstractXMLObject& src)
+    : m_namespaces(src.m_namespaces), m_log(src.m_log), m_schemaLocation(XMLString::replicate(src.m_schemaLocation)),
+        m_parent(NULL), m_elementQname(src.m_elementQname), m_typeQname(NULL)
+{
+    if (src.m_typeQname)
+        m_typeQname=new QName(*src.m_typeQname);
+}
+
+XMLCh* AbstractXMLObject::prepareForAssignment(XMLCh* oldValue, const XMLCh* newValue)
+{
+    if (!XMLString::equals(oldValue,newValue)) {
+        releaseThisandParentDOM();
+        XMLCh* newString = XMLString::replicate(newValue);
+        XMLString::release(&oldValue);
+        return newString;
+    }
+    return oldValue;
+}
+
+QName* AbstractXMLObject::prepareForAssignment(QName* oldValue, const QName* newValue)
+{
+    if (!oldValue) {
+        if (newValue) {
+            releaseThisandParentDOM();
+            Namespace newNamespace(newValue->getNamespaceURI(), newValue->getPrefix());
+            addNamespace(newNamespace);
+            return new QName(*newValue);
+        }
+        return NULL;
+    }
+
+    delete oldValue;
+    releaseThisandParentDOM();
+    if (newValue) {
+        Namespace newNamespace(newValue->getNamespaceURI(), newValue->getPrefix());
+        addNamespace(newNamespace);
+        return new QName(*newValue);
+    }
+    return NULL;
+}
+
+DateTime* AbstractXMLObject::prepareForAssignment(DateTime* oldValue, const DateTime* newValue)
+{
+    if (!oldValue) {
+        if (newValue) {
+            releaseThisandParentDOM();
+            return new DateTime(*newValue);
+        }
+        return NULL;
+    }
+
+    delete oldValue;
+    releaseThisandParentDOM();
+    return newValue ? new DateTime(*newValue) : NULL;
+}
+
+DateTime* AbstractXMLObject::prepareForAssignment(DateTime* oldValue, time_t newValue)
+{
+    delete oldValue;
+    releaseThisandParentDOM();
+    DateTime* ret = new DateTime(newValue);
+    ret->parseDateTime();
+    return ret;
+}
+
+DateTime* AbstractXMLObject::prepareForAssignment(DateTime* oldValue, const XMLCh* newValue)
+{
+    delete oldValue;
+    releaseThisandParentDOM();
+    DateTime* ret = new DateTime(newValue);
+    ret->parseDateTime();
+    return ret;
+}
+
+XMLObject* AbstractXMLObject::prepareForAssignment(XMLObject* oldValue, XMLObject* newValue)
+{
+    if (newValue && newValue->hasParent())
+        throw XMLObjectException("child XMLObject cannot be added - it is already the child of another XMLObject");
+
+    if (!oldValue) {
+        if (newValue) {
+            releaseThisandParentDOM();
+            newValue->setParent(this);
+        }
+        return newValue;
+    }
+
+    if (oldValue != newValue) {
+        delete oldValue;
+        releaseThisandParentDOM();
+        if (newValue)
+            newValue->setParent(this);
+    }
+
+    return newValue;
+}
+
+void AbstractXMLObject::detach()
+{
+    if (!getParent())
+        return;
+    else if (getParent()->hasParent())
+        throw XMLObjectException("Cannot detach an object whose parent is itself a child.");
+
+    // Pull ourselves out of the parent and then blast him.
+    getParent()->removeChild(this);
+    delete m_parent;
+    m_parent = NULL;
+}
index 3f2e801..80f3871 100644 (file)
-/*\r
-*  Copyright 2001-2006 Internet2\r
- * \r
-* Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file AbstractXMLObject.h\r
- * \r
- * An abstract implementation of XMLObject.\r
- */\r
-\r
-#if !defined(__xmltooling_abstractxmlobj_h__)\r
-#define __xmltooling_abstractxmlobj_h__\r
-\r
-#include <xmltooling/XMLObject.h>\r
-#include <xmltooling/util/DateTime.h>\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( push )\r
-    #pragma warning( disable : 4250 4251 )\r
-#endif\r
-\r
-namespace xmltooling {\r
-\r
-    /**\r
-     * An abstract implementation of XMLObject.\r
-     * This is the primary concrete base class, and supplies basic namespace,\r
-     * type, and parent handling. Most implementation classes should not\r
-     * directly inherit from this class, but rather from the various mixins\r
-     * that supply the rest of the XMLObject interface, as required.\r
-     */\r
-    class XMLTOOL_API AbstractXMLObject : public virtual XMLObject\r
-    {\r
-    public:\r
-        virtual ~AbstractXMLObject() {\r
-            delete m_typeQname;\r
-            XMLString::release(&m_schemaLocation);\r
-        }\r
-\r
-        void detach();\r
-\r
-        const QName& getElementQName() const {\r
-            return m_elementQname;\r
-        }\r
-\r
-        const std::set<Namespace>& getNamespaces() const {\r
-            return m_namespaces;\r
-        }\r
-    \r
-        void addNamespace(const Namespace& ns) const {\r
-            std::set<Namespace>::iterator i = m_namespaces.find(ns);\r
-            if (i == m_namespaces.end())\r
-                m_namespaces.insert(ns);\r
-            else if (ns.alwaysDeclare())\r
-                i->setAlwaysDeclare(true);\r
-        }\r
-    \r
-        void removeNamespace(const Namespace& ns) {\r
-            m_namespaces.erase(ns);\r
-        }\r
-        \r
-        const QName* getSchemaType() const {\r
-            return m_typeQname;\r
-        }\r
-        \r
-        const XMLCh* getXMLID() const {\r
-            return NULL;\r
-        }\r
-    \r
-        bool hasParent() const {\r
-            return m_parent != NULL;\r
-        }\r
-     \r
-        XMLObject* getParent() const {\r
-            return m_parent;\r
-        }\r
-    \r
-        void setParent(XMLObject* parent) {\r
-            m_parent = parent;\r
-        }\r
-\r
-     protected:\r
-        /**\r
-         * Constructor\r
-         * \r
-         * @param nsURI         the namespace of the element\r
-         * @param localName     the local name of the XML element this Object represents\r
-         * @param prefix        the namespace prefix to use\r
-         * @param schemaType    the xsi:type to use\r
-         */\r
-        AbstractXMLObject(\r
-            const XMLCh* nsURI=NULL, const XMLCh* localName=NULL, const XMLCh* prefix=NULL, const QName* schemaType=NULL\r
-            );\r
-\r
-        /** Copy constructor. */\r
-        AbstractXMLObject(const AbstractXMLObject& src);\r
-        \r
-        /**\r
-         * A helper function for derived classes, for assignment of strings.\r
-         *\r
-         * This 'normalizes' newString, and then if it is different from oldString,\r
-         * it invalidates the DOM, frees the old string, and returns the new.\r
-         * If not different, it frees the new string and just returns the old value.\r
-         * \r
-         * @param oldValue - the current value\r
-         * @param newValue - the new value\r
-         * \r
-         * @return the value that should be assigned\r
-         */\r
-        XMLCh* prepareForAssignment(XMLCh* oldValue, const XMLCh* newValue);\r
-\r
-        /**\r
-         * A helper function for derived classes, for assignment of date/time data.\r
-         *\r
-         * It invalidates the DOM, frees the old object, and returns the new.\r
-         * \r
-         * @param oldValue - the current value\r
-         * @param newValue - the new value\r
-         * \r
-         * @return the value that should be assigned\r
-         */\r
-        DateTime* prepareForAssignment(DateTime* oldValue, const DateTime* newValue);\r
-\r
-        /**\r
-         * A helper function for derived classes, for assignment of date/time data.\r
-         *\r
-         * It invalidates the DOM, frees the old object, and returns the new.\r
-         * \r
-         * @param oldValue - the current value\r
-         * @param newValue - the epoch to assign as the new value\r
-         * \r
-         * @return the value that should be assigned\r
-         */\r
-        DateTime* prepareForAssignment(DateTime* oldValue, time_t newValue);\r
-\r
-        /**\r
-         * A helper function for derived classes, for assignment of date/time data.\r
-         *\r
-         * It invalidates the DOM, frees the old object, and returns the new.\r
-         * \r
-         * @param oldValue - the current value\r
-         * @param newValue - the new value in string form\r
-         * \r
-         * @return the value that should be assigned\r
-         */\r
-        DateTime* prepareForAssignment(DateTime* oldValue, const XMLCh* newValue);\r
-\r
-        /**\r
-         * A helper function for derived classes, for assignment of QName data.\r
-         *\r
-         * It invalidates the DOM, frees the old object, and returns the new.\r
-         * \r
-         * @param oldValue - the current value\r
-         * @param newValue - the new value\r
-         * \r
-         * @return the value that should be assigned\r
-         */\r
-        QName* prepareForAssignment(QName* oldValue, const QName* newValue);\r
-\r
-        /**\r
-         * A helper function for derived classes, for assignment of (singleton) XML objects.\r
-         * \r
-         * It is indifferent to whether either the old or the new version of the value is null. \r
-         * This method will do a safe compare of the objects and will also invalidate the DOM if appropriate.\r
-         * Note that since the new value (even if NULL) is always returned, it may be more efficient\r
-         * to discard the return value and just assign independently if a dynamic cast would be involved.\r
-         * \r
-         * @param oldValue - current value\r
-         * @param newValue - proposed new value\r
-         * @return the new value \r
-         * \r
-         * @throws XMLObjectException if the new child already has a parent.\r
-         */\r
-        XMLObject* prepareForAssignment(XMLObject* oldValue, XMLObject* newValue);\r
-\r
-        /**\r
-         * Set of namespaces associated with the object.\r
-         */\r
-        mutable std::set<Namespace> m_namespaces;\r
-\r
-        /**\r
-         * Logging object.\r
-         */\r
-        void* m_log;\r
-\r
-        /**\r
-         * Stores off xsi:schemaLocation attribute.\r
-         */\r
-        XMLCh* m_schemaLocation;\r
-\r
-    private:\r
-        XMLObject* m_parent;\r
-        QName m_elementQname;\r
-        QName* m_typeQname;\r
-    };\r
-\r
-};\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( pop )\r
-#endif\r
-\r
-#endif /* __xmltooling_abstractxmlobj_h__ */\r
+/*
+*  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.
+ */
+
+/**
+ * @file AbstractXMLObject.h
+ * 
+ * An abstract implementation of XMLObject.
+ */
+
+#if !defined(__xmltooling_abstractxmlobj_h__)
+#define __xmltooling_abstractxmlobj_h__
+
+#include <xmltooling/XMLObject.h>
+#include <xmltooling/util/DateTime.h>
+
+#if defined (_MSC_VER)
+    #pragma warning( push )
+    #pragma warning( disable : 4250 4251 )
+#endif
+
+namespace xmltooling {
+
+    /**
+     * An abstract implementation of XMLObject.
+     * This is the primary concrete base class, and supplies basic namespace,
+     * type, and parent handling. Most implementation classes should not
+     * directly inherit from this class, but rather from the various mixins
+     * that supply the rest of the XMLObject interface, as required.
+     */
+    class XMLTOOL_API AbstractXMLObject : public virtual XMLObject
+    {
+    public:
+        virtual ~AbstractXMLObject() {
+            delete m_typeQname;
+            XMLString::release(&m_schemaLocation);
+        }
+
+        void detach();
+
+        const QName& getElementQName() const {
+            return m_elementQname;
+        }
+
+        const std::set<Namespace>& getNamespaces() const {
+            return m_namespaces;
+        }
+    
+        void addNamespace(const Namespace& ns) const {
+            std::set<Namespace>::iterator i = m_namespaces.find(ns);
+            if (i == m_namespaces.end())
+                m_namespaces.insert(ns);
+            else if (ns.alwaysDeclare())
+                const_cast<Namespace&>(*i).setAlwaysDeclare(true);
+        }
+    
+        void removeNamespace(const Namespace& ns) {
+            m_namespaces.erase(ns);
+        }
+        
+        const QName* getSchemaType() const {
+            return m_typeQname;
+        }
+        
+        const XMLCh* getXMLID() const {
+            return NULL;
+        }
+    
+        bool hasParent() const {
+            return m_parent != NULL;
+        }
+     
+        XMLObject* getParent() const {
+            return m_parent;
+        }
+    
+        void setParent(XMLObject* parent) {
+            m_parent = parent;
+        }
+
+     protected:
+        /**
+         * Constructor
+         * 
+         * @param nsURI         the namespace of the element
+         * @param localName     the local name of the XML element this Object represents
+         * @param prefix        the namespace prefix to use
+         * @param schemaType    the xsi:type to use
+         */
+        AbstractXMLObject(
+            const XMLCh* nsURI=NULL, const XMLCh* localName=NULL, const XMLCh* prefix=NULL, const QName* schemaType=NULL
+            );
+
+        /** Copy constructor. */
+        AbstractXMLObject(const AbstractXMLObject& src);
+        
+        /**
+         * A helper function for derived classes, for assignment of strings.
+         *
+         * This 'normalizes' newString, and then if it is different from oldString,
+         * it invalidates the DOM, frees the old string, and returns the new.
+         * If not different, it frees the new string and just returns the old value.
+         * 
+         * @param oldValue - the current value
+         * @param newValue - the new value
+         * 
+         * @return the value that should be assigned
+         */
+        XMLCh* prepareForAssignment(XMLCh* oldValue, const XMLCh* newValue);
+
+        /**
+         * A helper function for derived classes, for assignment of date/time data.
+         *
+         * It invalidates the DOM, frees the old object, and returns the new.
+         * 
+         * @param oldValue - the current value
+         * @param newValue - the new value
+         * 
+         * @return the value that should be assigned
+         */
+        DateTime* prepareForAssignment(DateTime* oldValue, const DateTime* newValue);
+
+        /**
+         * A helper function for derived classes, for assignment of date/time data.
+         *
+         * It invalidates the DOM, frees the old object, and returns the new.
+         * 
+         * @param oldValue - the current value
+         * @param newValue - the epoch to assign as the new value
+         * 
+         * @return the value that should be assigned
+         */
+        DateTime* prepareForAssignment(DateTime* oldValue, time_t newValue);
+
+        /**
+         * A helper function for derived classes, for assignment of date/time data.
+         *
+         * It invalidates the DOM, frees the old object, and returns the new.
+         * 
+         * @param oldValue - the current value
+         * @param newValue - the new value in string form
+         * 
+         * @return the value that should be assigned
+         */
+        DateTime* prepareForAssignment(DateTime* oldValue, const XMLCh* newValue);
+
+        /**
+         * A helper function for derived classes, for assignment of QName data.
+         *
+         * It invalidates the DOM, frees the old object, and returns the new.
+         * 
+         * @param oldValue - the current value
+         * @param newValue - the new value
+         * 
+         * @return the value that should be assigned
+         */
+        QName* prepareForAssignment(QName* oldValue, const QName* newValue);
+
+        /**
+         * A helper function for derived classes, for assignment of (singleton) XML objects.
+         * 
+         * It is indifferent to whether either the old or the new version of the value is null. 
+         * This method will do a safe compare of the objects and will also invalidate the DOM if appropriate.
+         * Note that since the new value (even if NULL) is always returned, it may be more efficient
+         * to discard the return value and just assign independently if a dynamic cast would be involved.
+         * 
+         * @param oldValue - current value
+         * @param newValue - proposed new value
+         * @return the new value 
+         * 
+         * @throws XMLObjectException if the new child already has a parent.
+         */
+        XMLObject* prepareForAssignment(XMLObject* oldValue, XMLObject* newValue);
+
+        /**
+         * Set of namespaces associated with the object.
+         */
+        mutable std::set<Namespace> m_namespaces;
+
+        /**
+         * Logging object.
+         */
+        void* m_log;
+
+        /**
+         * Stores off xsi:schemaLocation attribute.
+         */
+        XMLCh* m_schemaLocation;
+
+    private:
+        XMLObject* m_parent;
+        QName m_elementQname;
+        QName* m_typeQname;
+    };
+
+};
+
+#if defined (_MSC_VER)
+    #pragma warning( pop )
+#endif
+
+#endif /* __xmltooling_abstractxmlobj_h__ */
index 87bc6d3..05377f1 100644 (file)
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file AttributeExtensibleXMLObject.h\r
- * \r
- * An XMLObject that supports arbitrary attributes \r
- */\r
-\r
-#if !defined(__xmltooling_attrextxmlobj_h__)\r
-#define __xmltooling_attrextxmlobj_h__\r
-\r
-#include <xmltooling/XMLObject.h>\r
-\r
-using namespace xercesc;\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( push )\r
-    #pragma warning( disable : 4250 4251 )\r
-#endif\r
-\r
-namespace xmltooling {\r
-\r
-    /**\r
-     * An XMLObject that supports arbitrary attributes.\r
-     */\r
-    class XMLTOOL_API AttributeExtensibleXMLObject : public virtual XMLObject\r
-    {\r
-    protected:\r
-        AttributeExtensibleXMLObject() {}\r
-        \r
-    public:\r
-        virtual ~AttributeExtensibleXMLObject() {}\r
-        \r
-        /**\r
-         * Gets the value of an XML attribute of the object.\r
-         * \r
-         * @param   qualifiedName   qualified name of the attribute   \r
-         * @return the attribute value, or NULL\r
-         */\r
-        virtual const XMLCh* getAttribute(const QName& qualifiedName) const=0;\r
-        \r
-        /**\r
-         * Sets (or clears) an XML attribute of the object.\r
-         * \r
-         * @param qualifiedName qualified name of the attribute   \r
-         * @param value         value to set, or NULL to clear\r
-         * @param ID            true iff the attribute is an XML ID\r
-         */\r
-        virtual void setAttribute(const QName& qualifiedName, const XMLCh* value, bool ID=false)=0;\r
-\r
-        /**\r
-         * Gets an immutable map of the extended XML attributes of the object.\r
-         * \r
-         * This set is not guaranteed to (and generally will not) include\r
-         * attributes defined directly on the object's "type".\r
-         */\r
-        virtual const std::map<QName,XMLCh*>& getExtensionAttributes() const=0;\r
-        \r
-        /**\r
-         * Gets an immutable list of all the ID attributes currently registered.\r
-         * \r
-         * @return list of all the ID attributes currently registered\r
-         */\r
-        static const std::set<QName>& getRegisteredIDAttributes() {\r
-            return m_idAttributeSet;\r
-        }\r
-        \r
-        /**\r
-         * Tests whether an XML attribute is registered as an XML ID.\r
-         * \r
-         * @return true iff the attribute name matches a registered XML ID attribute \r
-         */\r
-        static bool isRegisteredIDAttribute(const QName& name) {\r
-            return m_idAttributeSet.find(name)!=m_idAttributeSet.end();\r
-        }\r
-    \r
-        /**\r
-         * Registers a new attribute as being of XML ID type.\r
-         * \r
-         * @param name the qualified attribute name\r
-         */\r
-        static void registerIDAttribute(const QName& name) {\r
-            m_idAttributeSet.insert(name);\r
-        }\r
-\r
-        /**\r
-         * Deregisters an ID attribute.\r
-         * \r
-         * @param name the qualified attribute name\r
-         */\r
-        static void deregisterIDAttribute(const QName& name) {\r
-            m_idAttributeSet.erase(name);\r
-        }\r
-        \r
-        /**\r
-         * Deregisters all ID attributes.\r
-         */\r
-        static void deregisterIDAttributes() {\r
-            m_idAttributeSet.clear();\r
-        }\r
-\r
-    private:\r
-        /** Set of attributes to treat as XML IDs. */\r
-        static std::set<QName> m_idAttributeSet;\r
-    };\r
-    \r
-};\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( pop )\r
-#endif\r
-\r
-#endif /* __xmltooling_attrextxmlobj_h__ */\r
+/*
+ *  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.
+ */
+
+/**
+ * @file AttributeExtensibleXMLObject.h
+ * 
+ * An XMLObject that supports arbitrary attributes 
+ */
+
+#if !defined(__xmltooling_attrextxmlobj_h__)
+#define __xmltooling_attrextxmlobj_h__
+
+#include <xmltooling/XMLObject.h>
+
+using namespace xercesc;
+
+#if defined (_MSC_VER)
+    #pragma warning( push )
+    #pragma warning( disable : 4250 4251 )
+#endif
+
+namespace xmltooling {
+
+    /**
+     * An XMLObject that supports arbitrary attributes.
+     */
+    class XMLTOOL_API AttributeExtensibleXMLObject : public virtual XMLObject
+    {
+    protected:
+        AttributeExtensibleXMLObject() {}
+        
+    public:
+        virtual ~AttributeExtensibleXMLObject() {}
+        
+        /**
+         * Gets the value of an XML attribute of the object.
+         * 
+         * @param   qualifiedName   qualified name of the attribute   
+         * @return the attribute value, or NULL
+         */
+        virtual const XMLCh* getAttribute(const QName& qualifiedName) const=0;
+        
+        /**
+         * Sets (or clears) an XML attribute of the object.
+         * 
+         * @param qualifiedName qualified name of the attribute   
+         * @param value         value to set, or NULL to clear
+         * @param ID            true iff the attribute is an XML ID
+         */
+        virtual void setAttribute(const QName& qualifiedName, const XMLCh* value, bool ID=false)=0;
+
+        /**
+         * Gets an immutable map of the extended XML attributes of the object.
+         * 
+         * This set is not guaranteed to (and generally will not) include
+         * attributes defined directly on the object's "type".
+         */
+        virtual const std::map<QName,XMLCh*>& getExtensionAttributes() const=0;
+        
+        /**
+         * Gets an immutable list of all the ID attributes currently registered.
+         * 
+         * @return list of all the ID attributes currently registered
+         */
+        static const std::set<QName>& getRegisteredIDAttributes() {
+            return m_idAttributeSet;
+        }
+        
+        /**
+         * Tests whether an XML attribute is registered as an XML ID.
+         * 
+         * @return true iff the attribute name matches a registered XML ID attribute 
+         */
+        static bool isRegisteredIDAttribute(const QName& name) {
+            return m_idAttributeSet.find(name)!=m_idAttributeSet.end();
+        }
+    
+        /**
+         * Registers a new attribute as being of XML ID type.
+         * 
+         * @param name the qualified attribute name
+         */
+        static void registerIDAttribute(const QName& name) {
+            m_idAttributeSet.insert(name);
+        }
+
+        /**
+         * Deregisters an ID attribute.
+         * 
+         * @param name the qualified attribute name
+         */
+        static void deregisterIDAttribute(const QName& name) {
+            m_idAttributeSet.erase(name);
+        }
+        
+        /**
+         * Deregisters all ID attributes.
+         */
+        static void deregisterIDAttributes() {
+            m_idAttributeSet.clear();
+        }
+
+    private:
+        /** Set of attributes to treat as XML IDs. */
+        static std::set<QName> m_idAttributeSet;
+    };
+    
+};
+
+#if defined (_MSC_VER)
+    #pragma warning( pop )
+#endif
+
+#endif /* __xmltooling_attrextxmlobj_h__ */
index a10d873..6b5c44e 100644 (file)
@@ -1,59 +1,59 @@
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file xmltooling/ElementProxy.h\r
- * \r
- * An XMLObject with an open content model \r
- */\r
-\r
-#ifndef __xmltooling_eleproxy_h__\r
-#define __xmltooling_eleproxy_h__\r
-\r
-#include <xmltooling/XMLObject.h>\r
-#include <xmltooling/util/XMLObjectChildrenList.h>\r
-\r
-using namespace xercesc;\r
-\r
-namespace xmltooling {\r
-\r
-    /**\r
-     * An XMLObject that exposes its children via mutable list.\r
-     */\r
-    class XMLTOOL_API ElementProxy : public virtual XMLObject\r
-    {\r
-    public:\r
-        ElementProxy() {}\r
-        virtual ~ElementProxy() {}\r
-        \r
-        /**\r
-         * Gets a mutable list of child objects\r
-         * \r
-         * @return  mutable list of child objects\r
-         */\r
-        virtual ListOf(XMLObject) getXMLObjects()=0;\r
-\r
-        /**\r
-         * Gets an immutable list of child objects\r
-         * \r
-         * @return  immutable list of child objects\r
-         */\r
-        virtual const std::list<XMLObject*>& getXMLObjects() const=0;\r
-    };\r
-    \r
-};\r
-\r
-#endif /* __xmltooling_eleproxy_h__ */\r
+/*
+ *  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.
+ */
+
+/**
+ * @file xmltooling/ElementProxy.h
+ * 
+ * An XMLObject with an open content model 
+ */
+
+#ifndef __xmltooling_eleproxy_h__
+#define __xmltooling_eleproxy_h__
+
+#include <xmltooling/XMLObject.h>
+#include <xmltooling/util/XMLObjectChildrenList.h>
+
+using namespace xercesc;
+
+namespace xmltooling {
+
+    /**
+     * An XMLObject that exposes its children via mutable list.
+     */
+    class XMLTOOL_API ElementProxy : public virtual XMLObject
+    {
+    public:
+        ElementProxy() {}
+        virtual ~ElementProxy() {}
+        
+        /**
+         * Gets a mutable list of child objects
+         * 
+         * @return  mutable list of child objects
+         */
+        virtual ListOf(XMLObject) getXMLObjects()=0;
+
+        /**
+         * Gets an immutable list of child objects
+         * 
+         * @return  immutable list of child objects
+         */
+        virtual const std::list<XMLObject*>& getXMLObjects() const=0;
+    };
+    
+};
+
+#endif /* __xmltooling_eleproxy_h__ */
index 0047a94..42d4b47 100644 (file)
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file Lockable.h\r
- * \r
- * Locking abstraction \r
- */\r
-\r
-#ifndef __xmltooling_lockable_h__\r
-#define __xmltooling_lockable_h__\r
-\r
-#include <xmltooling/base.h>\r
-\r
-namespace xmltooling {\r
-\r
-    /**\r
-     * Abstract mixin interface for interfaces that support locking\r
-     */\r
-    struct XMLTOOL_API Lockable\r
-    {\r
-        virtual ~Lockable() {}\r
-        \r
-        /**\r
-         * Lock the associated object for exclusive access.\r
-         * \r
-         * @return a pointer to the object being locked\r
-         */\r
-        virtual Lockable* lock()=0;\r
-\r
-        /**\r
-         * Unlock the associated object from exclusive access.\r
-         */\r
-        virtual void unlock()=0;\r
-    };\r
-\r
-    /**\r
-     * RAII wrapper for lockable objects to ensure lock release\r
-     */\r
-    class XMLTOOL_API Locker\r
-    {\r
-    MAKE_NONCOPYABLE(Locker);\r
-    public:\r
-        /**\r
-         * Optionally locks an object and stores it for later release.\r
-         * \r
-         * @param lockee    pointer to an object to hold, and optionally lock\r
-         * @param lock      true iff object is not yet locked\r
-         */\r
-        Locker(Lockable* lockee=NULL, bool lock=true) {\r
-            if (lockee && lock)\r
-                m_lockee=lockee->lock();\r
-            else\r
-                m_lockee=lockee;\r
-        }\r
-\r
-        /**\r
-         * Optionally locks an object and stores it for later release.\r
-         * If an object is already held, it is unlocked and detached.\r
-         * \r
-         * @param lockee    pointer to an object to hold, and optionally lock\r
-         * @param lock      true iff object is not yet locked\r
-         */\r
-        void assign(Lockable* lockee=NULL, bool lock=true) {\r
-            if (m_lockee)\r
-                m_lockee->unlock();\r
-            m_lockee=NULL;\r
-            if (lockee && lock)\r
-                m_lockee=lockee->lock();\r
-            else\r
-                m_lockee=lockee;\r
-        }\r
-        \r
-        /**\r
-         * Destructor releases lock on held pointer, if any.\r
-         */\r
-        ~Locker() {\r
-            if (m_lockee)\r
-                m_lockee->unlock();\r
-         }\r
-        \r
-    private:\r
-        Lockable* m_lockee;\r
-    };\r
-\r
-};\r
-\r
-#endif /* __xmltooling_lockable_h__ */\r
+/*
+ *  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.
+ */
+
+/**
+ * @file Lockable.h
+ * 
+ * Locking abstraction 
+ */
+
+#ifndef __xmltooling_lockable_h__
+#define __xmltooling_lockable_h__
+
+#include <xmltooling/base.h>
+
+namespace xmltooling {
+
+    /**
+     * Abstract mixin interface for interfaces that support locking
+     */
+    struct XMLTOOL_API Lockable
+    {
+        virtual ~Lockable() {}
+        
+        /**
+         * Lock the associated object for exclusive access.
+         * 
+         * @return a pointer to the object being locked
+         */
+        virtual Lockable* lock()=0;
+
+        /**
+         * Unlock the associated object from exclusive access.
+         */
+        virtual void unlock()=0;
+    };
+
+    /**
+     * RAII wrapper for lockable objects to ensure lock release
+     */
+    class XMLTOOL_API Locker
+    {
+    MAKE_NONCOPYABLE(Locker);
+    public:
+        /**
+         * Optionally locks an object and stores it for later release.
+         * 
+         * @param lockee    pointer to an object to hold, and optionally lock
+         * @param lock      true iff object is not yet locked
+         */
+        Locker(Lockable* lockee=NULL, bool lock=true) {
+            if (lockee && lock)
+                m_lockee=lockee->lock();
+            else
+                m_lockee=lockee;
+        }
+
+        /**
+         * Optionally locks an object and stores it for later release.
+         * If an object is already held, it is unlocked and detached.
+         * 
+         * @param lockee    pointer to an object to hold, and optionally lock
+         * @param lock      true iff object is not yet locked
+         */
+        void assign(Lockable* lockee=NULL, bool lock=true) {
+            if (m_lockee)
+                m_lockee->unlock();
+            m_lockee=NULL;
+            if (lockee && lock)
+                m_lockee=lockee->lock();
+            else
+                m_lockee=lockee;
+        }
+        
+        /**
+         * Destructor releases lock on held pointer, if any.
+         */
+        ~Locker() {
+            if (m_lockee)
+                m_lockee->unlock();
+         }
+        
+    private:
+        Lockable* m_lockee;
+    };
+
+};
+
+#endif /* __xmltooling_lockable_h__ */
index 21bf4b2..3369aa1 100644 (file)
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * Namespace.cpp\r
- * \r
- * Representing XML namespace attributes \r
- */\r
-\r
-#include "internal.h"\r
-#include "Namespace.h"\r
-\r
-using namespace xmltooling;\r
-\r
-Namespace::Namespace(const XMLCh* uri, const XMLCh* prefix, bool alwaysDeclare) : m_pinned(alwaysDeclare)\r
-{\r
-#ifndef HAVE_GOOD_STL\r
-    m_uri=m_prefix=NULL;\r
-#endif\r
-    setNamespaceURI(uri);\r
-    setNamespacePrefix(prefix);\r
-}\r
-\r
-Namespace::~Namespace()\r
-{\r
-#ifndef HAVE_GOOD_STL\r
-    XMLString::release(&m_uri);\r
-    XMLString::release(&m_prefix);\r
-#endif\r
-}\r
-\r
-void Namespace::setNamespacePrefix(const XMLCh* prefix)\r
-{\r
-#ifdef HAVE_GOOD_STL\r
-    if (prefix)\r
-        m_prefix=prefix;\r
-    else\r
-        m_prefix.erase();\r
-#else\r
-    if (m_prefix)\r
-        XMLString::release(&m_prefix);\r
-    m_prefix=XMLString::replicate(prefix);\r
-#endif\r
-}\r
-\r
-void Namespace::setNamespaceURI(const XMLCh* uri)\r
-{\r
-#ifdef HAVE_GOOD_STL\r
-    if (uri)\r
-        m_uri=uri;\r
-    else\r
-        m_uri.erase();\r
-#else\r
-    if (m_uri)\r
-        XMLString::release(&m_uri);\r
-    m_uri=XMLString::replicate(uri);\r
-#endif\r
-}\r
-\r
-#ifndef HAVE_GOOD_STL\r
-Namespace::Namespace(const Namespace& src)\r
-{\r
-    m_uri=XMLString::replicate(src.getNamespaceURI());\r
-    m_prefix=XMLString::replicate(src.getNamespacePrefix());\r
-    m_pinned=src.getAlwaysDeclare();\r
-}\r
-\r
-Namespace& Namespace::operator=(const Namespace& src)\r
-{\r
-    m_uri=XMLString::replicate(src.getNamespaceURI());\r
-    m_prefix=XMLString::replicate(src.getNamespacePrefix());\r
-    m_pinned=src.getAlwaysDeclare();\r
-    return *this;\r
-}\r
-\r
-bool xmltooling::operator==(const Namespace& op1, const Namespace& op2)\r
-{\r
-    return (XMLString::equals(op1.getNamespaceURI(),op2.getNamespaceURI()) &&\r
-            XMLString::equals(op1.getNamespacePrefix(),op2.getNamespacePrefix()));\r
-}\r
-#endif\r
-\r
-bool xmltooling::operator<(const Namespace& op1, const Namespace& op2)\r
-{\r
-    int i=XMLString::compareString(op1.getNamespaceURI(),op2.getNamespaceURI());\r
-    if (i<0)\r
-        return true;\r
-    else if (i==0)\r
-        return (XMLString::compareString(op1.getNamespacePrefix(),op2.getNamespacePrefix())<0);\r
-    else\r
-        return false;\r
-}\r
+/*
+ *  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.
+ */
+
+/**
+ * Namespace.cpp
+ * 
+ * Representing XML namespace attributes 
+ */
+
+#include "internal.h"
+#include "Namespace.h"
+
+using namespace xmltooling;
+
+Namespace::Namespace(const XMLCh* uri, const XMLCh* prefix, bool alwaysDeclare) : m_pinned(alwaysDeclare)
+{
+#ifndef HAVE_GOOD_STL
+    m_uri=m_prefix=NULL;
+#endif
+    setNamespaceURI(uri);
+    setNamespacePrefix(prefix);
+}
+
+Namespace::~Namespace()
+{
+#ifndef HAVE_GOOD_STL
+    XMLString::release(&m_uri);
+    XMLString::release(&m_prefix);
+#endif
+}
+
+void Namespace::setNamespacePrefix(const XMLCh* prefix)
+{
+#ifdef HAVE_GOOD_STL
+    if (prefix)
+        m_prefix=prefix;
+    else
+        m_prefix.erase();
+#else
+    if (m_prefix)
+        XMLString::release(&m_prefix);
+    m_prefix=XMLString::replicate(prefix);
+#endif
+}
+
+void Namespace::setNamespaceURI(const XMLCh* uri)
+{
+#ifdef HAVE_GOOD_STL
+    if (uri)
+        m_uri=uri;
+    else
+        m_uri.erase();
+#else
+    if (m_uri)
+        XMLString::release(&m_uri);
+    m_uri=XMLString::replicate(uri);
+#endif
+}
+
+#ifndef HAVE_GOOD_STL
+Namespace::Namespace(const Namespace& src)
+{
+    m_uri=XMLString::replicate(src.getNamespaceURI());
+    m_prefix=XMLString::replicate(src.getNamespacePrefix());
+    m_pinned=src.getAlwaysDeclare();
+}
+
+Namespace& Namespace::operator=(const Namespace& src)
+{
+    m_uri=XMLString::replicate(src.getNamespaceURI());
+    m_prefix=XMLString::replicate(src.getNamespacePrefix());
+    m_pinned=src.getAlwaysDeclare();
+    return *this;
+}
+
+bool xmltooling::operator==(const Namespace& op1, const Namespace& op2)
+{
+    return (XMLString::equals(op1.getNamespaceURI(),op2.getNamespaceURI()) &&
+            XMLString::equals(op1.getNamespacePrefix(),op2.getNamespacePrefix()));
+}
+#endif
+
+bool xmltooling::operator<(const Namespace& op1, const Namespace& op2)
+{
+    int i=XMLString::compareString(op1.getNamespaceURI(),op2.getNamespaceURI());
+    if (i<0)
+        return true;
+    else if (i==0)
+        return (XMLString::compareString(op1.getNamespacePrefix(),op2.getNamespacePrefix())<0);
+    else
+        return false;
+}
index 3e9bfc8..1177693 100644 (file)
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file Namespace.h\r
- * \r
- * Representing XML namespace attributes \r
- */\r
-\r
-#if !defined(__xmltooling_namespace_h__)\r
-#define __xmltooling_namespace_h__\r
-\r
-#include <xmltooling/unicode.h>\r
-\r
-namespace xmltooling {\r
-    \r
-    /**\r
-     * A data structure for encapsulating XML Namespace attributes\r
-     */\r
-    class XMLTOOL_API Namespace\r
-    {\r
-    public:\r
-        /**\r
-         * Constructor\r
-         * @param uri               namespace URI\r
-         * @param prefix            namespace prefix (without the colon)\r
-         * @param alwaysDeclare     true iff the namespace should always be declared regardless of in-scope declarations\r
-         */\r
-        Namespace(const XMLCh* uri=NULL, const XMLCh* prefix=NULL, bool alwaysDeclare=false);\r
-        \r
-        ~Namespace();\r
-#ifndef HAVE_GOOD_STL\r
-        /**\r
-         * Deep copy constructor\r
-         */\r
-        Namespace(const Namespace& src);\r
-\r
-        /**\r
-         * Deep assignment operator\r
-         */\r
-        Namespace& operator=(const Namespace& src);\r
-#endif\r
-        \r
-#ifdef HAVE_GOOD_STL\r
-        /**\r
-         * Returns the namespace prefix\r
-         * @return  Null-terminated Unicode string containing the prefix, without the colon\r
-         */\r
-        const XMLCh* getNamespacePrefix() const { return m_prefix.c_str(); }\r
-\r
-        /**\r
-         * Returns the namespace URI\r
-         * @return  Null-terminated Unicode string containing the URI\r
-         */\r
-        const XMLCh* getNamespaceURI() const { return m_uri.c_str(); }\r
-#else\r
-        /**\r
-         * Returns the namespace prefix\r
-         * @return  Null-terminated Unicode string containing the prefix, without the colon\r
-         */\r
-        const XMLCh* getNamespacePrefix() const { return m_prefix; }\r
-\r
-        /**\r
-         * Returns the namespace URI\r
-         * @return  Null-terminated Unicode string containing the URI\r
-         */\r
-        const XMLCh* getNamespaceURI() const { return m_uri; }\r
-#endif\r
-\r
-        /**\r
-         * Returns true iff the namespace should always be declared regardless of in-scope declarations\r
-         * @return the alwaysDeclared setting\r
-         */\r
-        const bool alwaysDeclare() const { return m_pinned; } \r
-\r
-        /**\r
-         * Sets the namespace prefix\r
-         * @param prefix    Null-terminated Unicode string containing the prefix, without the colon\r
-         */\r
-        void setNamespacePrefix(const XMLCh* prefix);\r
-\r
-        /**\r
-         * Sets the namespace URI\r
-         * @param uri  Null-terminated Unicode string containing the URI\r
-         */\r
-        void setNamespaceURI(const XMLCh* uri);\r
-\r
-        /**\r
-         * Sets the alwaysDeclared property\r
-         * @param alwaysDeclare     true iff the namespace should always be declared regardless of in-scope declarations\r
-         */\r
-        void setAlwaysDeclare(bool alwaysDeclare) { m_pinned = alwaysDeclare; } \r
-        \r
-    private:\r
-        bool m_pinned;\r
-#ifdef HAVE_GOOD_STL\r
-        xstring m_uri;\r
-        xstring m_prefix;\r
-#else\r
-        XMLCh* m_uri;\r
-        XMLCh* m_prefix;\r
-#endif\r
-    };\r
-\r
-    /**\r
-     * Returns true iff op1's namespace lexically compares less than op2's namespace,\r
-     * or if equal, iff op1's prefix lexically compares less than op2's prefix.\r
-     * \r
-     * Needed for use with sorted STL containers.\r
-     * \r
-     * @param op1   First namspace to compare\r
-     * @param op2   Second namespace to compare\r
-     */\r
-    extern XMLTOOL_API bool operator<(const Namespace& op1, const Namespace& op2);\r
-\r
-#ifndef HAVE_GOOD_STL\r
-    /**\r
-     * Returns true iff op1's namespace and prefix are equal to op2's namespace and prefix.\r
-     * @param op1   First namspace to compare\r
-     * @param op2   Second namespace to compare\r
-     */\r
-    extern XMLTOOL_API bool operator==(const Namespace& op1, const Namespace& op2);\r
-#endif\r
-\r
-};\r
-\r
-#endif /* __xmltooling_namespace_h__ */\r
+/*
+ *  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.
+ */
+
+/**
+ * @file Namespace.h
+ * 
+ * Representing XML namespace attributes 
+ */
+
+#if !defined(__xmltooling_namespace_h__)
+#define __xmltooling_namespace_h__
+
+#include <xmltooling/unicode.h>
+
+namespace xmltooling {
+    
+    /**
+     * A data structure for encapsulating XML Namespace attributes
+     */
+    class XMLTOOL_API Namespace
+    {
+    public:
+        /**
+         * Constructor
+         * @param uri               namespace URI
+         * @param prefix            namespace prefix (without the colon)
+         * @param alwaysDeclare     true iff the namespace should always be declared regardless of in-scope declarations
+         */
+        Namespace(const XMLCh* uri=NULL, const XMLCh* prefix=NULL, bool alwaysDeclare=false);
+        
+        ~Namespace();
+#ifndef HAVE_GOOD_STL
+        /**
+         * Deep copy constructor
+         */
+        Namespace(const Namespace& src);
+
+        /**
+         * Deep assignment operator
+         */
+        Namespace& operator=(const Namespace& src);
+#endif
+        
+#ifdef HAVE_GOOD_STL
+        /**
+         * Returns the namespace prefix
+         * @return  Null-terminated Unicode string containing the prefix, without the colon
+         */
+        const XMLCh* getNamespacePrefix() const { return m_prefix.c_str(); }
+
+        /**
+         * Returns the namespace URI
+         * @return  Null-terminated Unicode string containing the URI
+         */
+        const XMLCh* getNamespaceURI() const { return m_uri.c_str(); }
+#else
+        /**
+         * Returns the namespace prefix
+         * @return  Null-terminated Unicode string containing the prefix, without the colon
+         */
+        const XMLCh* getNamespacePrefix() const { return m_prefix; }
+
+        /**
+         * Returns the namespace URI
+         * @return  Null-terminated Unicode string containing the URI
+         */
+        const XMLCh* getNamespaceURI() const { return m_uri; }
+#endif
+
+        /**
+         * Returns true iff the namespace should always be declared regardless of in-scope declarations
+         * @return the alwaysDeclared setting
+         */
+        const bool alwaysDeclare() const { return m_pinned; } 
+
+        /**
+         * Sets the namespace prefix
+         * @param prefix    Null-terminated Unicode string containing the prefix, without the colon
+         */
+        void setNamespacePrefix(const XMLCh* prefix);
+
+        /**
+         * Sets the namespace URI
+         * @param uri  Null-terminated Unicode string containing the URI
+         */
+        void setNamespaceURI(const XMLCh* uri);
+
+        /**
+         * Sets the alwaysDeclared property
+         * @param alwaysDeclare     true iff the namespace should always be declared regardless of in-scope declarations
+         */
+        void setAlwaysDeclare(bool alwaysDeclare) { m_pinned = alwaysDeclare; } 
+        
+    private:
+        bool m_pinned;
+#ifdef HAVE_GOOD_STL
+        xstring m_uri;
+        xstring m_prefix;
+#else
+        XMLCh* m_uri;
+        XMLCh* m_prefix;
+#endif
+    };
+
+    /**
+     * Returns true iff op1's namespace lexically compares less than op2's namespace,
+     * or if equal, iff op1's prefix lexically compares less than op2's prefix.
+     * 
+     * Needed for use with sorted STL containers.
+     * 
+     * @param op1   First namspace to compare
+     * @param op2   Second namespace to compare
+     */
+    extern XMLTOOL_API bool operator<(const Namespace& op1, const Namespace& op2);
+
+#ifndef HAVE_GOOD_STL
+    /**
+     * Returns true iff op1's namespace and prefix are equal to op2's namespace and prefix.
+     * @param op1   First namspace to compare
+     * @param op2   Second namespace to compare
+     */
+    extern XMLTOOL_API bool operator==(const Namespace& op1, const Namespace& op2);
+#endif
+
+};
+
+#endif /* __xmltooling_namespace_h__ */
index 5f248e0..f882891 100644 (file)
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file xmltooling/PluginManager.h\r
- * \r
- * Plugin management template\r
- */\r
-\r
-#ifndef __xmltooling_plugin_h__\r
-#define __xmltooling_plugin_h__\r
-\r
-#include <xmltooling/base.h>\r
-#include <xmltooling/exceptions.h>\r
-\r
-#include <map>\r
-#include <string>\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( push )\r
-    #pragma warning( disable : 4250 4251 )\r
-#endif\r
-\r
-namespace xmltooling {\r
-\r
-    /**\r
-     * Template for management/access to plugins constructed based on a string type\r
-     * and arbitrary parameters.\r
-     * \r
-     * @param T         class of plugin to manage\r
-     * @param Params    parameters for plugin construction\r
-     */\r
-    template <class T, typename Params> class PluginManager\r
-    {\r
-    public:\r
-        PluginManager() {}\r
-        ~PluginManager() {}\r
-\r
-        /** Factory function for plugin. */\r
-        typedef T* Factory(const Params&);\r
-\r
-        /**\r
-         * Registers the factory for a given type.\r
-         * \r
-         * @param type      the name of the plugin type\r
-         * @param factory   the factory function for the plugin type\r
-         */\r
-        void registerFactory(const std::string& type, typename PluginManager::Factory* factory) {\r
-            if (!type.empty() && factory)\r
-                m_map[type]=factory;\r
-        }\r
-\r
-        /**\r
-         * Unregisters the factory for a given type.\r
-         * \r
-         * @param type  the name of the plugin type\r
-         */\r
-        void deregisterFactory(const std::string& type) {\r
-            if (!type.empty())\r
-                m_map.erase(type);\r
-        }\r
-\r
-        /**\r
-         * Unregisters all registered factories.\r
-         */\r
-        void deregisterFactories() {\r
-            m_map.clear();\r
-        }\r
-\r
-        /**\r
-         * Builds a new instance of a plugin of a given type, configuring it\r
-         * with the supplied parameters.\r
-         * \r
-         * @param type  the name of the plugin type\r
-         * @param p     parameters to configure plugin\r
-         * @return      the constructed plugin  \r
-         */\r
-        T* newPlugin(const std::string& type, const Params& p) {\r
-            typename std::map<std::string, typename PluginManager::Factory*>::const_iterator i=m_map.find(type);\r
-            if (i==m_map.end())\r
-                throw UnknownExtensionException("Unable to build plugin of type '$1'",params(1,type.c_str()));\r
-            return i->second(p);\r
-        }\r
-        \r
-    private:\r
-        std::map<std::string, typename PluginManager::Factory*> m_map;\r
-    };\r
-\r
-};\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( pop )\r
-#endif\r
-\r
-#endif /* __xmltooling_plugin_h__ */\r
+/*
+ *  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.
+ */
+
+/**
+ * @file xmltooling/PluginManager.h
+ * 
+ * Plugin management template
+ */
+
+#ifndef __xmltooling_plugin_h__
+#define __xmltooling_plugin_h__
+
+#include <xmltooling/base.h>
+#include <xmltooling/exceptions.h>
+
+#include <map>
+#include <string>
+
+#if defined (_MSC_VER)
+    #pragma warning( push )
+    #pragma warning( disable : 4250 4251 )
+#endif
+
+namespace xmltooling {
+
+    /**
+     * Template for management/access to plugins constructed based on a string type
+     * and arbitrary parameters.
+     * 
+     * @param T         class of plugin to manage
+     * @param Params    parameters for plugin construction
+     */
+    template <class T, typename Params> class PluginManager
+    {
+    public:
+        PluginManager() {}
+        ~PluginManager() {}
+
+        /** Factory function for plugin. */
+        typedef T* Factory(const Params&);
+
+        /**
+         * Registers the factory for a given type.
+         * 
+         * @param type      the name of the plugin type
+         * @param factory   the factory function for the plugin type
+         */
+        void registerFactory(const std::string& type, typename PluginManager::Factory* factory) {
+            if (!type.empty() && factory)
+                m_map[type]=factory;
+        }
+
+        /**
+         * Unregisters the factory for a given type.
+         * 
+         * @param type  the name of the plugin type
+         */
+        void deregisterFactory(const std::string& type) {
+            if (!type.empty())
+                m_map.erase(type);
+        }
+
+        /**
+         * Unregisters all registered factories.
+         */
+        void deregisterFactories() {
+            m_map.clear();
+        }
+
+        /**
+         * Builds a new instance of a plugin of a given type, configuring it
+         * with the supplied parameters.
+         * 
+         * @param type  the name of the plugin type
+         * @param p     parameters to configure plugin
+         * @return      the constructed plugin  
+         */
+        T* newPlugin(const std::string& type, const Params& p) {
+            typename std::map<std::string, typename PluginManager::Factory*>::const_iterator i=m_map.find(type);
+            if (i==m_map.end())
+                throw UnknownExtensionException("Unable to build plugin of type '$1'",params(1,type.c_str()));
+            return i->second(p);
+        }
+        
+    private:
+        std::map<std::string, typename PluginManager::Factory*> m_map;
+    };
+
+};
+
+#if defined (_MSC_VER)
+    #pragma warning( pop )
+#endif
+
+#endif /* __xmltooling_plugin_h__ */
index 6ca7f79..a54fcca 100644 (file)
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * QName.cpp\r
- * \r
- * Representing XML QNames \r
- */\r
-\r
-#include "internal.h"\r
-#include "QName.h"\r
-\r
-using namespace xmltooling;\r
-using namespace std;\r
-\r
-QName::QName(const XMLCh* uri, const XMLCh* localPart, const XMLCh* prefix)\r
-{\r
-#ifndef HAVE_GOOD_STL\r
-    m_uri=m_prefix=m_local=NULL;\r
-#endif\r
-    setNamespaceURI(uri);\r
-    setLocalPart(localPart);\r
-    setPrefix(prefix);\r
-}\r
-\r
-QName::~QName()\r
-{\r
-#ifndef HAVE_GOOD_STL\r
-    XMLString::release(&m_uri);\r
-    XMLString::release(&m_prefix);\r
-    XMLString::release(&m_local);\r
-#endif\r
-}\r
-\r
-void QName::setPrefix(const XMLCh* prefix)\r
-{\r
-#ifdef HAVE_GOOD_STL\r
-    if (prefix)\r
-        m_prefix=prefix;\r
-    else\r
-        m_prefix.erase();\r
-#else\r
-    if (m_prefix)\r
-        XMLString::release(&m_prefix);\r
-    m_prefix=XMLString::replicate(prefix);\r
-#endif\r
-}\r
-\r
-void QName::setNamespaceURI(const XMLCh* uri)\r
-{\r
-#ifdef HAVE_GOOD_STL\r
-    if (uri)\r
-        m_uri=uri;\r
-    else\r
-        m_uri.erase();\r
-#else\r
-    if (m_uri)\r
-        XMLString::release(&m_uri);\r
-    m_uri=XMLString::replicate(uri);\r
-#endif\r
-}\r
-\r
-void QName::setLocalPart(const XMLCh* localPart)\r
-{\r
-#ifdef HAVE_GOOD_STL\r
-    if (localPart)\r
-        m_local=localPart;\r
-    else\r
-        m_local.erase();\r
-#else\r
-    if (m_local)\r
-        XMLString::release(&m_local);\r
-    m_local=XMLString::replicate(localPart);\r
-#endif\r
-}\r
-\r
-#ifndef HAVE_GOOD_STL\r
-QName::QName(const QName& src)\r
-{\r
-    m_uri=XMLString::replicate(src.getNamespaceURI());\r
-    m_prefix=XMLString::replicate(src.getPrefix());\r
-    m_local=XMLString::replicate(src.getLocalPart());\r
-}\r
-\r
-QName& QName::operator=(const QName& src)\r
-{\r
-    m_uri=XMLString::replicate(src.getNamespaceURI());\r
-    m_prefix=XMLString::replicate(src.getPrefix());\r
-    m_local=XMLString::replicate(src.getLocalPart());\r
-    return *this;\r
-}\r
-#endif\r
-\r
-bool xmltooling::operator==(const QName& op1, const QName& op2)\r
-{\r
-    return (!XMLString::compareString(op1.getNamespaceURI(),op2.getNamespaceURI()) &&\r
-            !XMLString::compareString(op1.getLocalPart(),op2.getLocalPart()));\r
-}\r
-\r
-bool xmltooling::operator!=(const QName& op1, const QName& op2)\r
-{\r
-    return !(op1==op2);\r
-}\r
-\r
-bool xmltooling::operator<(const QName& op1, const QName& op2)\r
-{\r
-    int i=XMLString::compareString(op1.getNamespaceURI(),op2.getNamespaceURI());\r
-    if (i<0)\r
-        return true;\r
-    else if (i==0)\r
-        return (XMLString::compareString(op1.getLocalPart(),op2.getLocalPart())<0);\r
-    else\r
-        return false;\r
-}\r
-\r
-string QName::toString() const\r
-{\r
-    if (!hasLocalPart())\r
-        return "";\r
-    auto_ptr_char local(getLocalPart());\r
-    if (hasPrefix()) {\r
-        auto_ptr_char pre(getPrefix());\r
-        return string(pre.get()) + ':' + local.get(); \r
-    }\r
-    else if (hasNamespaceURI()) {\r
-        auto_ptr_char ns(getNamespaceURI());\r
-        return string("{") + ns.get() + '}' + local.get(); \r
-    }\r
-    else\r
-        return local.get();\r
-}\r
+/*
+ *  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.
+ */
+
+/**
+ * QName.cpp
+ * 
+ * Representing XML QNames 
+ */
+
+#include "internal.h"
+#include "QName.h"
+
+using namespace xmltooling;
+using namespace std;
+
+QName::QName(const XMLCh* uri, const XMLCh* localPart, const XMLCh* prefix)
+{
+#ifndef HAVE_GOOD_STL
+    m_uri=m_prefix=m_local=NULL;
+#endif
+    setNamespaceURI(uri);
+    setLocalPart(localPart);
+    setPrefix(prefix);
+}
+
+QName::~QName()
+{
+#ifndef HAVE_GOOD_STL
+    XMLString::release(&m_uri);
+    XMLString::release(&m_prefix);
+    XMLString::release(&m_local);
+#endif
+}
+
+void QName::setPrefix(const XMLCh* prefix)
+{
+#ifdef HAVE_GOOD_STL
+    if (prefix)
+        m_prefix=prefix;
+    else
+        m_prefix.erase();
+#else
+    if (m_prefix)
+        XMLString::release(&m_prefix);
+    m_prefix=XMLString::replicate(prefix);
+#endif
+}
+
+void QName::setNamespaceURI(const XMLCh* uri)
+{
+#ifdef HAVE_GOOD_STL
+    if (uri)
+        m_uri=uri;
+    else
+        m_uri.erase();
+#else
+    if (m_uri)
+        XMLString::release(&m_uri);
+    m_uri=XMLString::replicate(uri);
+#endif
+}
+
+void QName::setLocalPart(const XMLCh* localPart)
+{
+#ifdef HAVE_GOOD_STL
+    if (localPart)
+        m_local=localPart;
+    else
+        m_local.erase();
+#else
+    if (m_local)
+        XMLString::release(&m_local);
+    m_local=XMLString::replicate(localPart);
+#endif
+}
+
+#ifndef HAVE_GOOD_STL
+QName::QName(const QName& src)
+{
+    m_uri=XMLString::replicate(src.getNamespaceURI());
+    m_prefix=XMLString::replicate(src.getPrefix());
+    m_local=XMLString::replicate(src.getLocalPart());
+}
+
+QName& QName::operator=(const QName& src)
+{
+    m_uri=XMLString::replicate(src.getNamespaceURI());
+    m_prefix=XMLString::replicate(src.getPrefix());
+    m_local=XMLString::replicate(src.getLocalPart());
+    return *this;
+}
+#endif
+
+bool xmltooling::operator==(const QName& op1, const QName& op2)
+{
+    return (!XMLString::compareString(op1.getNamespaceURI(),op2.getNamespaceURI()) &&
+            !XMLString::compareString(op1.getLocalPart(),op2.getLocalPart()));
+}
+
+bool xmltooling::operator!=(const QName& op1, const QName& op2)
+{
+    return !(op1==op2);
+}
+
+bool xmltooling::operator<(const QName& op1, const QName& op2)
+{
+    int i=XMLString::compareString(op1.getNamespaceURI(),op2.getNamespaceURI());
+    if (i<0)
+        return true;
+    else if (i==0)
+        return (XMLString::compareString(op1.getLocalPart(),op2.getLocalPart())<0);
+    else
+        return false;
+}
+
+string QName::toString() const
+{
+    if (!hasLocalPart())
+        return "";
+    auto_ptr_char local(getLocalPart());
+    if (hasPrefix()) {
+        auto_ptr_char pre(getPrefix());
+        return string(pre.get()) + ':' + local.get(); 
+    }
+    else if (hasNamespaceURI()) {
+        auto_ptr_char ns(getNamespaceURI());
+        return string("{") + ns.get() + '}' + local.get(); 
+    }
+    else
+        return local.get();
+}
index c26e900..ac17d27 100644 (file)
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file QName.h\r
- * \r
- * Representing XML QNames \r
- */\r
-\r
-#if !defined(__xmltooling_qname_h__)\r
-#define __xmltooling_qname_h__\r
-\r
-#include <algorithm>\r
-#include <xmltooling/unicode.h>\r
-\r
-namespace xmltooling {\r
-    \r
-    /**\r
-     * A data structure for encapsulating XML QNames.\r
-     * The Xerces class is too limited to use at the moment.\r
-     */\r
-    class XMLTOOL_API QName\r
-    {\r
-    public:\r
-        /**\r
-         * Constructor\r
-         * @param uri       namespace URI\r
-         * @param localPart local name\r
-         * @param prefix    namespace prefix (without the colon)\r
-         */\r
-        QName(const XMLCh* uri=NULL, const XMLCh* localPart=NULL, const XMLCh* prefix=NULL);\r
-        \r
-        ~QName();\r
-#ifndef HAVE_GOOD_STL\r
-        /**\r
-         * Deep copy constructor\r
-         */\r
-        QName(const QName& src);\r
-\r
-        /**\r
-         * Deep assignment operator\r
-         */\r
-        QName& operator=(const QName& src);\r
-#endif\r
-        \r
-#ifdef HAVE_GOOD_STL\r
-        /**\r
-         * Indicates whether the QName has a prefix.\r
-         * @return  true iff the prefix is non-empty\r
-         */\r
-        bool hasPrefix() const { return !m_prefix.empty(); }\r
-\r
-        /**\r
-         * Indicates whether the QName has a non-empty namespace.\r
-         * @return  true iff the namespace is non-empty\r
-         */\r
-        bool hasNamespaceURI() const { return !m_uri.empty(); }\r
-\r
-        /**\r
-         * Indicates whether the QName has a non-empty local name.\r
-         * @return  true iff the local name is non-empty\r
-         */\r
-        bool hasLocalPart() const { return !m_local.empty(); }\r
-\r
-        /**\r
-         * Returns the namespace prefix\r
-         * @return  Null-terminated Unicode string containing the prefix, without the colon\r
-         */\r
-        const XMLCh* getPrefix() const { return m_prefix.c_str(); }\r
-\r
-        /**\r
-         * Returns the namespace URI\r
-         * @return  Null-terminated Unicode string containing the URI\r
-         */\r
-        const XMLCh* getNamespaceURI() const { return m_uri.c_str(); }\r
-\r
-        /**\r
-         * Returns the local part of the name\r
-         * @return  Null-terminated Unicode string containing the local name\r
-         */\r
-        const XMLCh* getLocalPart() const { return m_local.c_str(); }\r
-#else\r
-        /**\r
-         * Indicates whether the QName has a prefix.\r
-         * @return  true iff the prefix is non-empty\r
-         */\r
-        bool hasPrefix() const { return m_prefix && *m_prefix; }\r
-\r
-        /**\r
-         * Indicates whether the QName has a non-empty namespace.\r
-         * @return  true iff the namespace is non-empty\r
-         */\r
-        bool hasNamespaceURI() const { return m_uri && *m_uri; }\r
-\r
-        /**\r
-         * Indicates whether the QName has a non-empty local name.\r
-         * @return  true iff the local name is non-empty\r
-         */\r
-        bool hasLocalPart() const { return m_local && *m_local; }\r
-\r
-        /**\r
-         * Returns the namespace prefix\r
-         * @return  Null-terminated Unicode string containing the prefix, without the colon\r
-         */\r
-        const XMLCh* getPrefix() const { return m_prefix; }\r
-\r
-        /**\r
-         * Returns the namespace URI\r
-         * @return  Null-terminated Unicode string containing the URI\r
-         */\r
-        const XMLCh* getNamespaceURI() const { return m_uri; }\r
-\r
-        /**\r
-         * Returns the local part of the name\r
-         * @return  Null-terminated Unicode string containing the local name\r
-         */\r
-        const XMLCh* getLocalPart() const { return m_local; }\r
-#endif\r
-\r
-        /**\r
-         * Sets the namespace prefix\r
-         * @param prefix    Null-terminated Unicode string containing the prefix, without the colon\r
-         */\r
-        void setPrefix(const XMLCh* prefix);\r
-\r
-        /**\r
-         * Sets the namespace URI\r
-         * @param uri  Null-terminated Unicode string containing the URI\r
-         */\r
-        void setNamespaceURI(const XMLCh* uri);\r
-        \r
-        /**\r
-         * Sets the local part of the name\r
-         * @param localPart  Null-terminated Unicode string containing the local name\r
-         */\r
-        void setLocalPart(const XMLCh* localPart);\r
-        \r
-        /**\r
-         * Gets a string representation of the QName for logging, etc.\r
-         * Format is prefix:localPart or {namespaceURI}localPart if no prefix.\r
-         * \r
-         * @return the string representation\r
-         */\r
-        std::string toString() const;\r
-        \r
-    private:\r
-#ifdef HAVE_GOOD_STL\r
-        xstring m_uri;\r
-        xstring m_local;\r
-        xstring m_prefix;\r
-#else\r
-        XMLCh* m_uri;\r
-        XMLCh* m_local;\r
-        XMLCh* m_prefix;\r
-#endif\r
-    };\r
-\r
-    /**\r
-     * Returns true iff op1's namespace lexically compares less than op2's namespace,\r
-     * or if equal, iff op1's prefix lexically compares less than op2's prefix.\r
-     * \r
-     * Needed for use with sorted STL containers.\r
-     * \r
-     * @param op1   First qname to compare\r
-     * @param op2   Second qname to compare\r
-     */\r
-    extern XMLTOOL_API bool operator<(const QName& op1, const QName& op2);\r
-\r
-    /**\r
-     * Returns true iff op1's components are equal to op2's components, excluding prefix.\r
-     * @param op1   First qname to compare\r
-     * @param op2   Second qname to compare\r
-     */\r
-    extern XMLTOOL_API bool operator==(const QName& op1, const QName& op2);\r
-\r
-    /**\r
-     * Returns true iff op1's components are not equal to op2's components, excluding prefix.\r
-     * @param op1   First qname to compare\r
-     * @param op2   Second qname to compare\r
-     */\r
-    extern XMLTOOL_API bool operator!=(const QName& op1, const QName& op2);\r
-\r
-};\r
-\r
-#endif /* __xmltooling_qname_h__ */\r
+/*
+ *  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.
+ */
+
+/**
+ * @file QName.h
+ * 
+ * Representing XML QNames 
+ */
+
+#if !defined(__xmltooling_qname_h__)
+#define __xmltooling_qname_h__
+
+#include <algorithm>
+#include <xmltooling/unicode.h>
+
+namespace xmltooling {
+    
+    /**
+     * A data structure for encapsulating XML QNames.
+     * The Xerces class is too limited to use at the moment.
+     */
+    class XMLTOOL_API QName
+    {
+    public:
+        /**
+         * Constructor
+         * @param uri       namespace URI
+         * @param localPart local name
+         * @param prefix    namespace prefix (without the colon)
+         */
+        QName(const XMLCh* uri=NULL, const XMLCh* localPart=NULL, const XMLCh* prefix=NULL);
+        
+        ~QName();
+#ifndef HAVE_GOOD_STL
+        /**
+         * Deep copy constructor
+         */
+        QName(const QName& src);
+
+        /**
+         * Deep assignment operator
+         */
+        QName& operator=(const QName& src);
+#endif
+        
+#ifdef HAVE_GOOD_STL
+        /**
+         * Indicates whether the QName has a prefix.
+         * @return  true iff the prefix is non-empty
+         */
+        bool hasPrefix() const { return !m_prefix.empty(); }
+
+        /**
+         * Indicates whether the QName has a non-empty namespace.
+         * @return  true iff the namespace is non-empty
+         */
+        bool hasNamespaceURI() const { return !m_uri.empty(); }
+
+        /**
+         * Indicates whether the QName has a non-empty local name.
+         * @return  true iff the local name is non-empty
+         */
+        bool hasLocalPart() const { return !m_local.empty(); }
+
+        /**
+         * Returns the namespace prefix
+         * @return  Null-terminated Unicode string containing the prefix, without the colon
+         */
+        const XMLCh* getPrefix() const { return m_prefix.c_str(); }
+
+        /**
+         * Returns the namespace URI
+         * @return  Null-terminated Unicode string containing the URI
+         */
+        const XMLCh* getNamespaceURI() const { return m_uri.c_str(); }
+
+        /**
+         * Returns the local part of the name
+         * @return  Null-terminated Unicode string containing the local name
+         */
+        const XMLCh* getLocalPart() const { return m_local.c_str(); }
+#else
+        /**
+         * Indicates whether the QName has a prefix.
+         * @return  true iff the prefix is non-empty
+         */
+        bool hasPrefix() const { return m_prefix && *m_prefix; }
+
+        /**
+         * Indicates whether the QName has a non-empty namespace.
+         * @return  true iff the namespace is non-empty
+         */
+        bool hasNamespaceURI() const { return m_uri && *m_uri; }
+
+        /**
+         * Indicates whether the QName has a non-empty local name.
+         * @return  true iff the local name is non-empty
+         */
+        bool hasLocalPart() const { return m_local && *m_local; }
+
+        /**
+         * Returns the namespace prefix
+         * @return  Null-terminated Unicode string containing the prefix, without the colon
+         */
+        const XMLCh* getPrefix() const { return m_prefix; }
+
+        /**
+         * Returns the namespace URI
+         * @return  Null-terminated Unicode string containing the URI
+         */
+        const XMLCh* getNamespaceURI() const { return m_uri; }
+
+        /**
+         * Returns the local part of the name
+         * @return  Null-terminated Unicode string containing the local name
+         */
+        const XMLCh* getLocalPart() const { return m_local; }
+#endif
+
+        /**
+         * Sets the namespace prefix
+         * @param prefix    Null-terminated Unicode string containing the prefix, without the colon
+         */
+        void setPrefix(const XMLCh* prefix);
+
+        /**
+         * Sets the namespace URI
+         * @param uri  Null-terminated Unicode string containing the URI
+         */
+        void setNamespaceURI(const XMLCh* uri);
+        
+        /**
+         * Sets the local part of the name
+         * @param localPart  Null-terminated Unicode string containing the local name
+         */
+        void setLocalPart(const XMLCh* localPart);
+        
+        /**
+         * Gets a string representation of the QName for logging, etc.
+         * Format is prefix:localPart or {namespaceURI}localPart if no prefix.
+         * 
+         * @return the string representation
+         */
+        std::string toString() const;
+        
+    private:
+#ifdef HAVE_GOOD_STL
+        xstring m_uri;
+        xstring m_local;
+        xstring m_prefix;
+#else
+        XMLCh* m_uri;
+        XMLCh* m_local;
+        XMLCh* m_prefix;
+#endif
+    };
+
+    /**
+     * Returns true iff op1's namespace lexically compares less than op2's namespace,
+     * or if equal, iff op1's prefix lexically compares less than op2's prefix.
+     * 
+     * Needed for use with sorted STL containers.
+     * 
+     * @param op1   First qname to compare
+     * @param op2   Second qname to compare
+     */
+    extern XMLTOOL_API bool operator<(const QName& op1, const QName& op2);
+
+    /**
+     * Returns true iff op1's components are equal to op2's components, excluding prefix.
+     * @param op1   First qname to compare
+     * @param op2   Second qname to compare
+     */
+    extern XMLTOOL_API bool operator==(const QName& op1, const QName& op2);
+
+    /**
+     * Returns true iff op1's components are not equal to op2's components, excluding prefix.
+     * @param op1   First qname to compare
+     * @param op2   Second qname to compare
+     */
+    extern XMLTOOL_API bool operator!=(const QName& op1, const QName& op2);
+
+};
+
+#endif /* __xmltooling_qname_h__ */
index 1fb26d6..fc9225e 100644 (file)
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file XMLObject.h\r
- * \r
- * Abstract interface to objects that can be manipulated in and out of XML form. \r
- */\r
-\r
-#ifndef __xmltooling_xmlobj_h__\r
-#define __xmltooling_xmlobj_h__\r
-\r
-#include <set>\r
-#include <list>\r
-#include <vector>\r
-#include <xercesc/dom/DOM.hpp>\r
-#include <xmltooling/QName.h>\r
-#include <xmltooling/Namespace.h>\r
-\r
-using namespace xercesc;\r
-\r
-#ifndef XMLTOOLING_NO_XMLSEC\r
-namespace xmlsignature {\r
-    class XMLTOOL_API Signature;\r
-};\r
-#endif\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( push )\r
-    #pragma warning( disable : 4250 4251 )\r
-#endif\r
-\r
-namespace xmltooling {\r
-\r
-    /**\r
-     * Object that represents an XML Element that has been unmarshalled into this C++ object.\r
-     */\r
-    class XMLTOOL_API XMLObject\r
-    {\r
-    public:\r
-        virtual ~XMLObject() {}\r
-        \r
-        /**\r
-         * Creates a copy of the object, along with all of its children.\r
-         * \r
-         * The new object tree will be completely distinct and independent of\r
-         * the original in all respects.\r
-         */\r
-        virtual XMLObject* clone() const=0;\r
-        \r
-        /**\r
-         * Specialized function for detaching a child object from its parent\r
-         * <strong>while disposing of the parent</strong>.\r
-         *\r
-         * This is not a generic way of detaching any child object, but only of\r
-         * pruning a single child from the root of an XMLObject tree. If the\r
-         * detached XMLObject's parent is itself a child, an exception will be\r
-         * thrown. It's mainly useful for turning a child into the new root of\r
-         * the tree without having to clone the child.\r
-         */\r
-        virtual void detach()=0;\r
-\r
-        /**\r
-         * Gets the QName for this element.  This QName <strong>MUST</strong> \r
-         * contain the namespace URI, namespace prefix, and local element name.\r
-         * \r
-         * @return constant reference to the QName for this object\r
-         */\r
-        virtual const QName& getElementQName() const=0;\r
-        \r
-        /**\r
-         * Gets the namespaces that are scoped to this element.\r
-         * \r
-         * The caller MUST NOT modify the set returned, but may use any\r
-         * non-modifying operations or algorithms on it. Iterators will\r
-         * remain valid unless the set member referenced is removed using\r
-         * the removeNamespace method.\r
-         * \r
-         * @return the namespaces that are scoped to this element\r
-         */\r
-        virtual const std::set<Namespace>& getNamespaces() const=0;\r
-        \r
-        /**\r
-         * Adds a namespace to the ones already scoped to this element\r
-         * \r
-         * @param ns the namespace to add\r
-         */\r
-        virtual void addNamespace(const Namespace& ns) const=0;\r
-        \r
-        /**\r
-         * Removes a namespace from this element\r
-         * \r
-         * @param ns the namespace to remove\r
-         */\r
-        virtual void removeNamespace(const Namespace& ns)=0;\r
-        \r
-        /**\r
-         * Gets the XML schema type of this element.  This translates to contents the xsi:type\r
-         * attribute for the element.\r
-         * \r
-         * @return XML schema type of this element\r
-         */\r
-        virtual const QName* getSchemaType() const=0;\r
-        \r
-        /**\r
-         * Gets the value of the ID attribute set on this object, if any.\r
-         * \r
-         * @return an ID value or NULL \r
-         */\r
-        virtual const XMLCh* getXMLID() const=0;\r
-        \r
-        /**\r
-         * Checks to see if this object has a parent.\r
-         * \r
-         * @return true if the object has a parent, false if not\r
-         */\r
-        virtual bool hasParent() const=0;\r
-        \r
-        /**\r
-         * Gets the parent of this element or null if there is no parent.\r
-         * \r
-         * @return the parent of this element or null\r
-         */\r
-        virtual XMLObject* getParent() const=0;\r
-        \r
-        /**\r
-         * Sets the parent of this element.\r
-         * \r
-         * @param parent the parent of this element\r
-         */\r
-        virtual void setParent(XMLObject* parent)=0;\r
-        \r
-        /**\r
-         * Checks if this XMLObject has children.\r
-         * \r
-         * @return true if this XMLObject has children, false if not\r
-         */\r
-        virtual bool hasChildren() const=0;\r
-        \r
-        /**\r
-         * Returns an unmodifiable list of child objects in the order that they\r
-         * should appear in the serialized representation.\r
-         * \r
-         * The validity of the returned list is not maintained if any non-const\r
-         * operations are performed on the parent object. \r
-         * \r
-         * @return the list of children\r
-         */\r
-        virtual const std::list<XMLObject*>& getOrderedChildren() const=0;\r
-\r
-        /**\r
-         * Used by a child's detach method to isolate the child from\r
-         * this parent object in preparation for destroying the parent\r
-         * (this object).\r
-         * \r
-         * @param child the child object to remove\r
-         */\r
-        virtual void removeChild(XMLObject* child)=0;\r
-\r
-        /**\r
-         * Returns the text content at the specified position relative to\r
-         * any child elements. A zero represents leading text, 1 comes after\r
-         * the first child, and so forth.\r
-         *\r
-         * @param position  the relative child element position of the text  \r
-         * @return the designated text value\r
-         */\r
-        virtual const XMLCh* getTextContent(unsigned int position=0) const=0;\r
-\r
-        /**\r
-         * Sets (or clears) text content relative to a child element's position. \r
-         * \r
-         * @param value         value to set, or NULL to clear\r
-         * @param position      position relative to child element \r
-         */\r
-        virtual void setTextContent(const XMLCh* value, unsigned int position=0)=0;\r
-\r
-        /**\r
-         * Gets the DOM representation of this XMLObject, if one exists.\r
-         * \r
-         * @return the DOM representation of this XMLObject\r
-         */\r
-        virtual DOMElement* getDOM() const=0;\r
-        \r
-        /**\r
-         * Sets the DOM representation of this XMLObject.\r
-         * \r
-         * @param dom       DOM representation of this XMLObject\r
-         * @param bindDocument  true if the object should take ownership of the associated Document\r
-         */\r
-        virtual void setDOM(DOMElement* dom, bool bindDocument=false) const=0;\r
-    \r
-        /**\r
-         * Assigns ownership of a DOM document to the XMLObject.\r
-         * This binds the lifetime of the document to the lifetime of the object.\r
-         * \r
-         * @param doc DOM document bound to this object \r
-         */\r
-        virtual void setDocument(DOMDocument* doc) const=0;\r
-\r
-        /**\r
-         * Releases the DOM representation of this XMLObject, if there is one.\r
-         */\r
-        virtual void releaseDOM() const=0;\r
-        \r
-        /**\r
-         * Releases the DOM representation of this XMLObject's parent.\r
-         * \r
-         * @param propagateRelease true if all ancestors of this element should release their DOM\r
-         */\r
-        virtual void releaseParentDOM(bool propagateRelease=true) const=0;\r
-        \r
-        /**\r
-         * Releases the DOM representation of this XMLObject's children.\r
-         * \r
-         * @param propagateRelease true if all descendants of this element should release their DOM\r
-         */\r
-        virtual void releaseChildrenDOM(bool propagateRelease=true) const=0;\r
-\r
-        /**\r
-         * A convenience method that is equal to calling releaseDOM() then releaseParentDOM(true).\r
-         */\r
-        void releaseThisandParentDOM() const {\r
-            if (getDOM()) {\r
-                releaseDOM();\r
-                releaseParentDOM(true);\r
-            }\r
-        }\r
-    \r
-        /**\r
-         * A convenience method that is equal to calling releaseChildrenDOM(true) then releaseDOM().\r
-         */\r
-        void releaseThisAndChildrenDOM() const {\r
-            if (getDOM()) {\r
-                releaseChildrenDOM(true);\r
-                releaseDOM();\r
-            }\r
-        }\r
-\r
-        /**\r
-         * Marshalls the XMLObject, and its children, into a DOM element.\r
-         * If a document is supplied, then it will be used to create the resulting elements.\r
-         * If the document does not have a Document Element set, then the resulting\r
-         * element will be set as the Document Element. If no document is supplied, then\r
-         * a new document will be created and bound to the lifetime of the root object being\r
-         * marshalled, unless an existing DOM can be reused without creating a new document. \r
-         * \r
-         * @param document  the DOM document the marshalled element will be placed in, or NULL\r
-         * @param sigs      ordered array of signatures to create after marshalling is complete\r
-         * @return the DOM element representing this XMLObject\r
-         * \r
-         * @throws MarshallingException thrown if there is a problem marshalling the given object\r
-         * @throws SignatureException thrown if a problem occurs during signature creation \r
-         */\r
-        virtual DOMElement* marshall(\r
-            DOMDocument* document=NULL\r
-#ifndef XMLTOOLING_NO_XMLSEC\r
-            ,const std::vector<xmlsignature::Signature*>* sigs=NULL\r
-#endif\r
-            ) const=0;\r
-        \r
-        /**\r
-         * Marshalls the XMLObject and appends it as a child of the given parent element.\r
-         * \r
-         * <strong>NOTE:</strong> The given Element must be within a DOM tree rooted in \r
-         * the Document owning the given Element.\r
-         * \r
-         * @param parentElement the parent element to append the resulting DOM tree\r
-         * @param sigs          ordered array of signatures to create after marshalling is complete\r
-         * @return the marshalled element tree\r
-\r
-         * @throws MarshallingException thrown if the given XMLObject can not be marshalled.\r
-         * @throws SignatureException thrown if a problem occurs during signature creation \r
-         */\r
-        virtual DOMElement* marshall(\r
-            DOMElement* parentElement\r
-#ifndef XMLTOOLING_NO_XMLSEC\r
-            ,const std::vector<xmlsignature::Signature*>* sigs=NULL\r
-#endif\r
-            ) const=0;\r
-\r
-        /**\r
-         * Unmarshalls the given W3C DOM element into the XMLObject.\r
-         * The root of a given XML construct should be unmarshalled with the bindDocument parameter\r
-         * set to true.\r
-         * \r
-         * @param element       the DOM element to unmarshall\r
-         * @param bindDocument  true iff the resulting XMLObject should take ownership of the DOM's Document \r
-         * \r
-         * @return the unmarshalled XMLObject\r
-         * \r
-         * @throws UnmarshallingException thrown if an error occurs unmarshalling the DOM element into the XMLObject\r
-         */\r
-        virtual XMLObject* unmarshall(DOMElement* element, bool bindDocument=false)=0;\r
-\r
-    protected:\r
-        XMLObject() {}\r
-    private:\r
-        XMLObject& operator=(const XMLObject& src);\r
-    };\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( pop )\r
-#endif\r
-\r
-};\r
-\r
-#endif /* __xmltooling_xmlobj_h__ */\r
+/*
+ *  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.
+ */
+
+/**
+ * @file XMLObject.h
+ * 
+ * Abstract interface to objects that can be manipulated in and out of XML form. 
+ */
+
+#ifndef __xmltooling_xmlobj_h__
+#define __xmltooling_xmlobj_h__
+
+#include <set>
+#include <list>
+#include <vector>
+#include <xercesc/dom/DOM.hpp>
+#include <xmltooling/QName.h>
+#include <xmltooling/Namespace.h>
+
+using namespace xercesc;
+
+#ifndef XMLTOOLING_NO_XMLSEC
+namespace xmlsignature {
+    class XMLTOOL_API Signature;
+};
+#endif
+
+#if defined (_MSC_VER)
+    #pragma warning( push )
+    #pragma warning( disable : 4250 4251 )
+#endif
+
+namespace xmltooling {
+
+    /**
+     * Object that represents an XML Element that has been unmarshalled into this C++ object.
+     */
+    class XMLTOOL_API XMLObject
+    {
+    public:
+        virtual ~XMLObject() {}
+        
+        /**
+         * Creates a copy of the object, along with all of its children.
+         * 
+         * The new object tree will be completely distinct and independent of
+         * the original in all respects.
+         */
+        virtual XMLObject* clone() const=0;
+        
+        /**
+         * Specialized function for detaching a child object from its parent
+         * <strong>while disposing of the parent</strong>.
+         *
+         * This is not a generic way of detaching any child object, but only of
+         * pruning a single child from the root of an XMLObject tree. If the
+         * detached XMLObject's parent is itself a child, an exception will be
+         * thrown. It's mainly useful for turning a child into the new root of
+         * the tree without having to clone the child.
+         */
+        virtual void detach()=0;
+
+        /**
+         * Gets the QName for this element.  This QName <strong>MUST</strong> 
+         * contain the namespace URI, namespace prefix, and local element name.
+         * 
+         * @return constant reference to the QName for this object
+         */
+        virtual const QName& getElementQName() const=0;
+        
+        /**
+         * Gets the namespaces that are scoped to this element.
+         * 
+         * The caller MUST NOT modify the set returned, but may use any
+         * non-modifying operations or algorithms on it. Iterators will
+         * remain valid unless the set member referenced is removed using
+         * the removeNamespace method.
+         * 
+         * @return the namespaces that are scoped to this element
+         */
+        virtual const std::set<Namespace>& getNamespaces() const=0;
+        
+        /**
+         * Adds a namespace to the ones already scoped to this element
+         * 
+         * @param ns the namespace to add
+         */
+        virtual void addNamespace(const Namespace& ns) const=0;
+        
+        /**
+         * Removes a namespace from this element
+         * 
+         * @param ns the namespace to remove
+         */
+        virtual void removeNamespace(const Namespace& ns)=0;
+        
+        /**
+         * Gets the XML schema type of this element.  This translates to contents the xsi:type
+         * attribute for the element.
+         * 
+         * @return XML schema type of this element
+         */
+        virtual const QName* getSchemaType() const=0;
+        
+        /**
+         * Gets the value of the ID attribute set on this object, if any.
+         * 
+         * @return an ID value or NULL 
+         */
+        virtual const XMLCh* getXMLID() const=0;
+        
+        /**
+         * Checks to see if this object has a parent.
+         * 
+         * @return true if the object has a parent, false if not
+         */
+        virtual bool hasParent() const=0;
+        
+        /**
+         * Gets the parent of this element or null if there is no parent.
+         * 
+         * @return the parent of this element or null
+         */
+        virtual XMLObject* getParent() const=0;
+        
+        /**
+         * Sets the parent of this element.
+         * 
+         * @param parent the parent of this element
+         */
+        virtual void setParent(XMLObject* parent)=0;
+        
+        /**
+         * Checks if this XMLObject has children.
+         * 
+         * @return true if this XMLObject has children, false if not
+         */
+        virtual bool hasChildren() const=0;
+        
+        /**
+         * Returns an unmodifiable list of child objects in the order that they
+         * should appear in the serialized representation.
+         * 
+         * The validity of the returned list is not maintained if any non-const
+         * operations are performed on the parent object. 
+         * 
+         * @return the list of children
+         */
+        virtual const std::list<XMLObject*>& getOrderedChildren() const=0;
+
+        /**
+         * Used by a child's detach method to isolate the child from
+         * this parent object in preparation for destroying the parent
+         * (this object).
+         * 
+         * @param child the child object to remove
+         */
+        virtual void removeChild(XMLObject* child)=0;
+
+        /**
+         * Returns the text content at the specified position relative to
+         * any child elements. A zero represents leading text, 1 comes after
+         * the first child, and so forth.
+         *
+         * @param position  the relative child element position of the text  
+         * @return the designated text value
+         */
+        virtual const XMLCh* getTextContent(unsigned int position=0) const=0;
+
+        /**
+         * Sets (or clears) text content relative to a child element's position. 
+         * 
+         * @param value         value to set, or NULL to clear
+         * @param position      position relative to child element 
+         */
+        virtual void setTextContent(const XMLCh* value, unsigned int position=0)=0;
+
+        /**
+         * Gets the DOM representation of this XMLObject, if one exists.
+         * 
+         * @return the DOM representation of this XMLObject
+         */
+        virtual DOMElement* getDOM() const=0;
+        
+        /**
+         * Sets the DOM representation of this XMLObject.
+         * 
+         * @param dom       DOM representation of this XMLObject
+         * @param bindDocument  true if the object should take ownership of the associated Document
+         */
+        virtual void setDOM(DOMElement* dom, bool bindDocument=false) const=0;
+    
+        /**
+         * Assigns ownership of a DOM document to the XMLObject.
+         * This binds the lifetime of the document to the lifetime of the object.
+         * 
+         * @param doc DOM document bound to this object 
+         */
+        virtual void setDocument(DOMDocument* doc) const=0;
+
+        /**
+         * Releases the DOM representation of this XMLObject, if there is one.
+         */
+        virtual void releaseDOM() const=0;
+        
+        /**
+         * Releases the DOM representation of this XMLObject's parent.
+         * 
+         * @param propagateRelease true if all ancestors of this element should release their DOM
+         */
+        virtual void releaseParentDOM(bool propagateRelease=true) const=0;
+        
+        /**
+         * Releases the DOM representation of this XMLObject's children.
+         * 
+         * @param propagateRelease true if all descendants of this element should release their DOM
+         */
+        virtual void releaseChildrenDOM(bool propagateRelease=true) const=0;
+
+        /**
+         * A convenience method that is equal to calling releaseDOM() then releaseParentDOM(true).
+         */
+        void releaseThisandParentDOM() const {
+            if (getDOM()) {
+                releaseDOM();
+                releaseParentDOM(true);
+            }
+        }
+    
+        /**
+         * A convenience method that is equal to calling releaseChildrenDOM(true) then releaseDOM().
+         */
+        void releaseThisAndChildrenDOM() const {
+            if (getDOM()) {
+                releaseChildrenDOM(true);
+                releaseDOM();
+            }
+        }
+
+        /**
+         * Marshalls the XMLObject, and its children, into a DOM element.
+         * If a document is supplied, then it will be used to create the resulting elements.
+         * If the document does not have a Document Element set, then the resulting
+         * element will be set as the Document Element. If no document is supplied, then
+         * a new document will be created and bound to the lifetime of the root object being
+         * marshalled, unless an existing DOM can be reused without creating a new document. 
+         * 
+         * @param document  the DOM document the marshalled element will be placed in, or NULL
+         * @param sigs      ordered array of signatures to create after marshalling is complete
+         * @return the DOM element representing this XMLObject
+         * 
+         * @throws MarshallingException thrown if there is a problem marshalling the given object
+         * @throws SignatureException thrown if a problem occurs during signature creation 
+         */
+        virtual DOMElement* marshall(
+            DOMDocument* document=NULL
+#ifndef XMLTOOLING_NO_XMLSEC
+            ,const std::vector<xmlsignature::Signature*>* sigs=NULL
+#endif
+            ) const=0;
+        
+        /**
+         * Marshalls the XMLObject and appends it as a child of the given parent element.
+         * 
+         * <strong>NOTE:</strong> The given Element must be within a DOM tree rooted in 
+         * the Document owning the given Element.
+         * 
+         * @param parentElement the parent element to append the resulting DOM tree
+         * @param sigs          ordered array of signatures to create after marshalling is complete
+         * @return the marshalled element tree
+
+         * @throws MarshallingException thrown if the given XMLObject can not be marshalled.
+         * @throws SignatureException thrown if a problem occurs during signature creation 
+         */
+        virtual DOMElement* marshall(
+            DOMElement* parentElement
+#ifndef XMLTOOLING_NO_XMLSEC
+            ,const std::vector<xmlsignature::Signature*>* sigs=NULL
+#endif
+            ) const=0;
+
+        /**
+         * Unmarshalls the given W3C DOM element into the XMLObject.
+         * The root of a given XML construct should be unmarshalled with the bindDocument parameter
+         * set to true.
+         * 
+         * @param element       the DOM element to unmarshall
+         * @param bindDocument  true iff the resulting XMLObject should take ownership of the DOM's Document 
+         * 
+         * @return the unmarshalled XMLObject
+         * 
+         * @throws UnmarshallingException thrown if an error occurs unmarshalling the DOM element into the XMLObject
+         */
+        virtual XMLObject* unmarshall(DOMElement* element, bool bindDocument=false)=0;
+
+    protected:
+        XMLObject() {}
+    private:
+        XMLObject& operator=(const XMLObject& src);
+    };
+
+#if defined (_MSC_VER)
+    #pragma warning( pop )
+#endif
+
+};
+
+#endif /* __xmltooling_xmlobj_h__ */
index 33c4225..38d739b 100644 (file)
@@ -1,73 +1,73 @@
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * XMLObjectBuilder.cpp\r
- * \r
- * Factory interface for XMLObjects \r
- */\r
-\r
-#include "internal.h"\r
-#include "XMLObjectBuilder.h"\r
-#include "util/NDC.h"\r
-#include "util/XMLHelper.h"\r
-\r
-#include <log4cpp/Category.hh>\r
-\r
-using namespace xmltooling;\r
-using namespace log4cpp;\r
-using namespace std;\r
-\r
-map<QName,XMLObjectBuilder*> XMLObjectBuilder::m_map;\r
-XMLObjectBuilder* XMLObjectBuilder::m_default=NULL;\r
-\r
-const XMLObjectBuilder* XMLObjectBuilder::getBuilder(const DOMElement* domElement)\r
-{\r
-#ifdef _DEBUG\r
-    xmltooling::NDC ndc("getBuilder");\r
-#endif\r
-    Category& log=Category::getInstance(XMLTOOLING_LOGCAT".XMLObjectBuilder");\r
\r
-    auto_ptr<QName> schemaType(XMLHelper::getXSIType(domElement));\r
-    const XMLObjectBuilder* xmlObjectBuilder = schemaType.get() ? getBuilder(*(schemaType.get())) : NULL;\r
-    if (xmlObjectBuilder) {\r
-        if (log.isDebugEnabled()) {\r
-            log.debug("located XMLObjectBuilder for schema type: %s", schemaType->toString().c_str());\r
-        }\r
-        return xmlObjectBuilder;\r
-    }\r
-    \r
-    auto_ptr<QName> elementName(XMLHelper::getNodeQName(domElement));\r
-    xmlObjectBuilder = getBuilder(*(elementName.get()));\r
-    if (xmlObjectBuilder) {\r
-        if (log.isDebugEnabled()) {\r
-            log.debug("located XMLObjectBuilder for element name: %s", elementName->toString().c_str());\r
-        }\r
-        return xmlObjectBuilder;\r
-    }\r
-\r
-    if (log.isDebugEnabled()) {\r
-        log.debug("no XMLObjectBuilder registered for element (%s), returning default", elementName->toString().c_str());\r
-    }\r
-    return m_default;\r
-}\r
-\r
-void XMLObjectBuilder::destroyBuilders()\r
-{\r
-    for_each(m_map.begin(),m_map.end(),cleanup_pair<QName,XMLObjectBuilder>());\r
-    m_map.clear();\r
-    deregisterDefaultBuilder();\r
-}\r
+/*
+ *  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.
+ */
+
+/**
+ * XMLObjectBuilder.cpp
+ * 
+ * Factory interface for XMLObjects 
+ */
+
+#include "internal.h"
+#include "XMLObjectBuilder.h"
+#include "util/NDC.h"
+#include "util/XMLHelper.h"
+
+#include <log4cpp/Category.hh>
+
+using namespace xmltooling;
+using namespace log4cpp;
+using namespace std;
+
+map<QName,XMLObjectBuilder*> XMLObjectBuilder::m_map;
+XMLObjectBuilder* XMLObjectBuilder::m_default=NULL;
+
+const XMLObjectBuilder* XMLObjectBuilder::getBuilder(const DOMElement* domElement)
+{
+#ifdef _DEBUG
+    xmltooling::NDC ndc("getBuilder");
+#endif
+    Category& log=Category::getInstance(XMLTOOLING_LOGCAT".XMLObjectBuilder");
+    auto_ptr<QName> schemaType(XMLHelper::getXSIType(domElement));
+    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());
+        }
+        return xmlObjectBuilder;
+    }
+    
+    auto_ptr<QName> elementName(XMLHelper::getNodeQName(domElement));
+    xmlObjectBuilder = getBuilder(*(elementName.get()));
+    if (xmlObjectBuilder) {
+        if (log.isDebugEnabled()) {
+            log.debug("located XMLObjectBuilder for element name: %s", elementName->toString().c_str());
+        }
+        return xmlObjectBuilder;
+    }
+
+    if (log.isDebugEnabled()) {
+        log.debug("no XMLObjectBuilder registered for element (%s), returning default", elementName->toString().c_str());
+    }
+    return m_default;
+}
+
+void XMLObjectBuilder::destroyBuilders()
+{
+    for_each(m_map.begin(),m_map.end(),cleanup_pair<QName,XMLObjectBuilder>());
+    m_map.clear();
+    deregisterDefaultBuilder();
+}
index 737fe31..f29f706 100644 (file)
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file XMLToolingConfig.h\r
- * \r
- * Library configuration \r
- */\r
-\r
-#ifndef __xmltooling_config_h__\r
-#define __xmltooling_config_h__\r
-\r
-#include <xmltooling/Lockable.h>\r
-#include <xmltooling/PluginManager.h>\r
-#include <xmltooling/util/ParserPool.h>\r
-\r
-#ifndef XMLTOOLING_NO_XMLSEC\r
-namespace xmlsignature {\r
-    class XMLTOOL_API CredentialResolver;\r
-    class XMLTOOL_API KeyResolver;\r
-};\r
-#endif\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( push )\r
-    #pragma warning( disable : 4251 )\r
-#endif\r
-\r
-namespace xmltooling {\r
-    \r
-    class XMLTOOL_API ReplayCache;\r
-    class XMLTOOL_API StorageService;\r
-    class XMLTOOL_API TrustEngine;\r
-    class XMLTOOL_API XSECCryptoX509CRL;\r
-\r
-    /**\r
-     * Singleton object that manages library startup/shutdown.configuration.\r
-     * \r
-     * A locking interface is supplied as a convenience for code that wants to\r
-     * obtain a global system lock, but the actual configuration itself is not\r
-     * synchronized.\r
-     */\r
-    class XMLTOOL_API XMLToolingConfig : public Lockable\r
-    {\r
-        MAKE_NONCOPYABLE(XMLToolingConfig);\r
-    protected:\r
-        XMLToolingConfig() : m_replayCache(NULL), clock_skew_secs(180) {}\r
-        \r
-        /** Global ReplayCache instance. */\r
-        ReplayCache* m_replayCache;\r
-    public:\r
-        virtual ~XMLToolingConfig() {}\r
-\r
-        /**\r
-         * Returns the global configuration object for the library.\r
-         * \r
-         * @return reference to the global library configuration object\r
-         */\r
-        static XMLToolingConfig& getConfig();\r
-        \r
-        /**\r
-         * Initializes library\r
-         * \r
-         * Each process using the library MUST call this function exactly once\r
-         * before using any library classes except for the LogConfig method.\r
-         * \r
-         * @return true iff initialization was successful \r
-         */\r
-        virtual bool init()=0;\r
-        \r
-        /**\r
-         * Shuts down library\r
-         * \r
-         * Each process using the library SHOULD call this function exactly once\r
-         * before terminating itself\r
-         */\r
-        virtual void term()=0;\r
-\r
-        /**\r
-         * Loads a shared/dynamic library extension.\r
-         * \r
-         * Extension libraries are managed using a pair of "C" linkage functions:<br>\r
-         *      extern "C" int xmltooling_extension_init(void* context);<br>\r
-         *      extern "C" void xmltooling_extension_term();\r
-         * \r
-         * This method is internally synchronized.\r
-         * \r
-         * @param path      pathname of shared library to load into process\r
-         * @param context   arbitrary data to pass to library initialization hook\r
-         * @return true iff library was loaded successfully\r
-         */\r
-        virtual bool load_library(const char* path, void* context=NULL)=0;\r
-        \r
-        /**\r
-         * Configure logging system.\r
-         * \r
-         * May be called first, before initializing the library. Other calls to it\r
-         * must be externally synchronized. \r
-         * \r
-         * @param config    either a logging configuration file, or a level from the set\r
-         *                  (DEBUG, INFO, NOTICE, WARN, ERROR, CRIT, ALERT, FATAL, EMERG)\r
-         * @return true iff configuration was successful\r
-         */\r
-        virtual bool log_config(const char* config=NULL)=0;\r
-\r
-        /**\r
-         * Obtains a non-validating parser pool.\r
-         * Library must be initialized first.\r
-         *\r
-         * @return reference to a non-validating parser pool.\r
-         */\r
-        virtual ParserPool& getParser() const=0;\r
-\r
-        /**\r
-         * Obtains a validating parser pool.\r
-         * Library must be initialized first. Schema/catalog registration must be\r
-         * externally synchronized.\r
-         *\r
-         * @return reference to a validating parser pool.\r
-         */\r
-        virtual ParserPool& getValidatingParser() const=0;\r
-\r
-        /**\r
-         * Sets the global ReplayCache instance.\r
-         * This method must be externally synchronized with any code that uses the object.\r
-         * Any previously set object is destroyed.\r
-         * \r
-         * @param replayCache   new ReplayCache instance to store\r
-         */\r
-        void setReplayCache(ReplayCache* replayCache);\r
-\r
-        /**\r
-         * Returns the global ReplayCache instance.\r
-         * \r
-         * @return  global ReplayCache or NULL\r
-         */\r
-        ReplayCache* getReplayCache() const {\r
-            return m_replayCache;\r
-        }\r
-                \r
-        /**\r
-         * List of catalog files to load into validating parser pool at initialization time.\r
-         * Like other path settings, the separator depends on the platform\r
-         * (semicolon on Windows, colon otherwise). \r
-         */\r
-        std::string catalog_path;\r
-        \r
-        /**\r
-         * Adjusts any clock comparisons to be more liberal/permissive by the\r
-         * indicated number of seconds.\r
-         */\r
-        unsigned int clock_skew_secs;\r
-\r
-#ifndef XMLTOOLING_NO_XMLSEC\r
-        /**\r
-         * Returns an X.509 CRL implementation object.\r
-         */\r
-        virtual XSECCryptoX509CRL* X509CRL() const=0;\r
-\r
-        /**\r
-         * Manages factories for KeyResolver plugins.\r
-         */\r
-        PluginManager<xmlsignature::KeyResolver,const DOMElement*> KeyResolverManager;\r
-\r
-        /**\r
-         * Manages factories for CredentialResolver plugins.\r
-         */\r
-        PluginManager<xmlsignature::CredentialResolver,const DOMElement*> CredentialResolverManager;\r
-\r
-        /**\r
-         * Manages factories for TrustEngine plugins.\r
-         */\r
-        PluginManager<TrustEngine,const DOMElement*> TrustEngineManager;\r
-#endif\r
-\r
-        /**\r
-         * Manages factories for StorageService plugins.\r
-         */\r
-        PluginManager<StorageService,const DOMElement*> StorageServiceManager;\r
-    };\r
-\r
-};\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( pop )\r
-#endif\r
-\r
-#endif /* __xmltooling_config_h__ */\r
+/*
+ *  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.
+ */
+
+/**
+ * @file XMLToolingConfig.h
+ * 
+ * Library configuration 
+ */
+
+#ifndef __xmltooling_config_h__
+#define __xmltooling_config_h__
+
+#include <xmltooling/Lockable.h>
+#include <xmltooling/PluginManager.h>
+#include <xmltooling/util/ParserPool.h>
+
+#ifndef XMLTOOLING_NO_XMLSEC
+namespace xmlsignature {
+    class XMLTOOL_API CredentialResolver;
+    class XMLTOOL_API KeyResolver;
+};
+#endif
+
+#if defined (_MSC_VER)
+    #pragma warning( push )
+    #pragma warning( disable : 4251 )
+#endif
+
+namespace xmltooling {
+    
+    class XMLTOOL_API ReplayCache;
+    class XMLTOOL_API StorageService;
+    class XMLTOOL_API TrustEngine;
+    class XMLTOOL_API XSECCryptoX509CRL;
+
+    /**
+     * Singleton object that manages library startup/shutdown.configuration.
+     * 
+     * A locking interface is supplied as a convenience for code that wants to
+     * obtain a global system lock, but the actual configuration itself is not
+     * synchronized.
+     */
+    class XMLTOOL_API XMLToolingConfig : public Lockable
+    {
+        MAKE_NONCOPYABLE(XMLToolingConfig);
+    protected:
+        XMLToolingConfig() : m_replayCache(NULL), clock_skew_secs(180) {}
+        
+        /** Global ReplayCache instance. */
+        ReplayCache* m_replayCache;
+    public:
+        virtual ~XMLToolingConfig() {}
+
+        /**
+         * Returns the global configuration object for the library.
+         * 
+         * @return reference to the global library configuration object
+         */
+        static XMLToolingConfig& getConfig();
+        
+        /**
+         * Initializes library
+         * 
+         * Each process using the library MUST call this function exactly once
+         * before using any library classes except for the LogConfig method.
+         * 
+         * @return true iff initialization was successful 
+         */
+        virtual bool init()=0;
+        
+        /**
+         * Shuts down library
+         * 
+         * Each process using the library SHOULD call this function exactly once
+         * before terminating itself
+         */
+        virtual void term()=0;
+
+        /**
+         * Loads a shared/dynamic library extension.
+         * 
+         * Extension libraries are managed using a pair of "C" linkage functions:<br>
+         *      extern "C" int xmltooling_extension_init(void* context);<br>
+         *      extern "C" void xmltooling_extension_term();
+         * 
+         * This method is internally synchronized.
+         * 
+         * @param path      pathname of shared library to load into process
+         * @param context   arbitrary data to pass to library initialization hook
+         * @return true iff library was loaded successfully
+         */
+        virtual bool load_library(const char* path, void* context=NULL)=0;
+        
+        /**
+         * Configure logging system.
+         * 
+         * May be called first, before initializing the library. Other calls to it
+         * must be externally synchronized. 
+         * 
+         * @param config    either a logging configuration file, or a level from the set
+         *                  (DEBUG, INFO, NOTICE, WARN, ERROR, CRIT, ALERT, FATAL, EMERG)
+         * @return true iff configuration was successful
+         */
+        virtual bool log_config(const char* config=NULL)=0;
+
+        /**
+         * Obtains a non-validating parser pool.
+         * Library must be initialized first.
+         *
+         * @return reference to a non-validating parser pool.
+         */
+        virtual ParserPool& getParser() const=0;
+
+        /**
+         * Obtains a validating parser pool.
+         * Library must be initialized first. Schema/catalog registration must be
+         * externally synchronized.
+         *
+         * @return reference to a validating parser pool.
+         */
+        virtual ParserPool& getValidatingParser() const=0;
+
+        /**
+         * Sets the global ReplayCache instance.
+         * This method must be externally synchronized with any code that uses the object.
+         * Any previously set object is destroyed.
+         * 
+         * @param replayCache   new ReplayCache instance to store
+         */
+        void setReplayCache(ReplayCache* replayCache);
+
+        /**
+         * Returns the global ReplayCache instance.
+         * 
+         * @return  global ReplayCache or NULL
+         */
+        ReplayCache* getReplayCache() const {
+            return m_replayCache;
+        }
+                
+        /**
+         * List of catalog files to load into validating parser pool at initialization time.
+         * Like other path settings, the separator depends on the platform
+         * (semicolon on Windows, colon otherwise). 
+         */
+        std::string catalog_path;
+        
+        /**
+         * Adjusts any clock comparisons to be more liberal/permissive by the
+         * indicated number of seconds.
+         */
+        unsigned int clock_skew_secs;
+
+#ifndef XMLTOOLING_NO_XMLSEC
+        /**
+         * Returns an X.509 CRL implementation object.
+         */
+        virtual XSECCryptoX509CRL* X509CRL() const=0;
+
+        /**
+         * Manages factories for KeyResolver plugins.
+         */
+        PluginManager<xmlsignature::KeyResolver,const DOMElement*> KeyResolverManager;
+
+        /**
+         * Manages factories for CredentialResolver plugins.
+         */
+        PluginManager<xmlsignature::CredentialResolver,const DOMElement*> CredentialResolverManager;
+
+        /**
+         * Manages factories for TrustEngine plugins.
+         */
+        PluginManager<TrustEngine,const DOMElement*> TrustEngineManager;
+#endif
+
+        /**
+         * Manages factories for StorageService plugins.
+         */
+        PluginManager<StorageService,const DOMElement*> StorageServiceManager;
+    };
+
+};
+
+#if defined (_MSC_VER)
+    #pragma warning( pop )
+#endif
+
+#endif /* __xmltooling_config_h__ */
index a121d61..50af9d3 100644 (file)
@@ -1,6 +1,6 @@
-/* Define to 1 if you have an STL implementation that supports useful string\r
-   specialization. */\r
-#define HAVE_GOOD_STL 1\r
-\r
-/* Define to 1 to disable XML-Security-dependent features. */\r
-/* #undef XMLTOOLING_NO_XMLSEC */\r
+/* Define to 1 if you have an STL implementation that supports useful string
+   specialization. */
+#define HAVE_GOOD_STL 1
+
+/* Define to 1 to disable XML-Security-dependent features. */
+/* #undef XMLTOOLING_NO_XMLSEC */
index 01dcf85..39a9cb0 100644 (file)
@@ -1,49 +1,49 @@
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file EncryptedKeyResolver.h\r
- * \r
- * Resolves encrypted keys based on EncryptedData information or other external factors.\r
- */\r
-\r
-#if !defined(__xmltooling_enckeyres_h__) && !defined(XMLTOOLING_NO_XMLSEC)\r
-#define __xmltooling_enckeyres_h__\r
-\r
-#include <xmltooling/encryption/Encryption.h>\r
-#include <xmltooling/signature/KeyResolver.h>\r
-\r
-namespace xmlencryption {\r
-\r
-    /**\r
-     * An API for resolving encrypted decryption keys.\r
-     */\r
-    class XMLTOOL_API EncryptedKeyResolver : public xmlsignature::KeyResolver {\r
-    public:\r
-        virtual ~EncryptedKeyResolver() {}\r
-        \r
-        /**\r
-         * Returns an encrypted key based on the supplied KeyInfo information.\r
-         * \r
-         * @param encryptedData an encrypted object\r
-         * @return  the resolved EncryptedKey object\r
-         */\r
-        virtual EncryptedKey* resolveKey(EncryptedData* encryptedData)=0;\r
-    };\r
-\r
-};\r
-\r
-#endif /* __xmltooling_enckeyres_h__ */\r
+/*
+ *  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.
+ */
+
+/**
+ * @file EncryptedKeyResolver.h
+ * 
+ * Resolves encrypted keys based on EncryptedData information or other external factors.
+ */
+
+#if !defined(__xmltooling_enckeyres_h__) && !defined(XMLTOOLING_NO_XMLSEC)
+#define __xmltooling_enckeyres_h__
+
+#include <xmltooling/encryption/Encryption.h>
+#include <xmltooling/signature/KeyResolver.h>
+
+namespace xmlencryption {
+
+    /**
+     * An API for resolving encrypted decryption keys.
+     */
+    class XMLTOOL_API EncryptedKeyResolver : public xmlsignature::KeyResolver {
+    public:
+        virtual ~EncryptedKeyResolver() {}
+        
+        /**
+         * Returns an encrypted key based on the supplied KeyInfo information.
+         * 
+         * @param encryptedData an encrypted object
+         * @return  the resolved EncryptedKey object
+         */
+        virtual EncryptedKey* resolveKey(EncryptedData* encryptedData)=0;
+    };
+
+};
+
+#endif /* __xmltooling_enckeyres_h__ */
index 505eea8..a7e8768 100644 (file)
-/*\r
- *  Copyright 2001-2005 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * MemoryStorageService.cpp\r
- * \r
- * In-memory "persistent" storage, suitable for simple applications.\r
- */\r
-\r
-#include "internal.h"\r
-#include "util/NDC.h"\r
-#include "util/StorageService.h"\r
-#include "util/Threads.h"\r
-#include "util/XMLHelper.h"\r
-\r
-#include <log4cpp/Category.hh>\r
-#include <xercesc/util/XMLUniDefs.hpp>\r
-\r
-using namespace xmltooling;\r
-using namespace log4cpp;\r
-using namespace std;\r
-\r
-namespace xmltooling {\r
-    class XMLTOOL_DLLLOCAL MemoryStorageService : public StorageService\r
-    {\r
-    public:\r
-        MemoryStorageService(const DOMElement* e);\r
-        virtual ~MemoryStorageService();\r
-        \r
-        void createString(const char* context, const char* key, const char* value, time_t expiration);\r
-        bool readString(const char* context, const char* key, string* pvalue=NULL, time_t* pexpiration=NULL);\r
-        bool updateString(const char* context, const char* key, const char* value=NULL, time_t expiration=0);\r
-        bool deleteString(const char* context, const char* key);\r
-        \r
-        void createText(const char* context, const char* key, const char* value, time_t expiration) {\r
-            return createString(context, key, value, expiration);\r
-        }\r
-        bool readText(const char* context, const char* key, string* pvalue=NULL, time_t* pexpiration=NULL) {\r
-            return readString(context, key, pvalue, pexpiration);\r
-        }\r
-        bool updateText(const char* context, const char* key, const char* value=NULL, time_t expiration=0) {\r
-            return updateString(context, key, value, expiration);\r
-        }\r
-        bool deleteText(const char* context, const char* key) {\r
-            return deleteString(context, key);\r
-        }\r
-        \r
-        void reap(const char* context);\r
-        void deleteContext(const char* context) {\r
-            Lock wrapper(contextLock);\r
-            m_contextMap.erase(context);\r
-        }\r
-\r
-    private:\r
-        void cleanup();\r
-    \r
-        struct XMLTOOL_DLLLOCAL Record {\r
-            Record() : expiration(0) {}\r
-            Record(string s, time_t t) : data(s), expiration(t) {}\r
-            string data;\r
-            time_t expiration;\r
-        };\r
-        \r
-        struct XMLTOOL_DLLLOCAL Context {\r
-            Context() : m_lock(RWLock::create()) {}\r
-            Context(const Context& src) {\r
-                m_dataMap = src.m_dataMap;\r
-                m_expMap = src.m_expMap;\r
-                m_lock = RWLock::create();\r
-            }\r
-            ~Context() { delete m_lock; }\r
-            map<string,Record> m_dataMap;\r
-            multimap<time_t,string> m_expMap;\r
-            RWLock* m_lock;\r
-            unsigned long reap();\r
-        };\r
-\r
-        Context& getContext(const char* context) {\r
-            Lock wrapper(contextLock);\r
-            return m_contextMap[context];\r
-        }\r
-\r
-        map<string,Context> m_contextMap;\r
-        Mutex* contextLock;\r
-        CondWait* shutdown_wait;\r
-        Thread* cleanup_thread;\r
-        static void* cleanup_fn(void*);\r
-        bool shutdown;\r
-        int m_cleanupInterval;\r
-        Category& m_log;\r
-    };\r
-\r
-    StorageService* XMLTOOL_DLLLOCAL MemoryStorageServiceFactory(const DOMElement* const & e)\r
-    {\r
-        return new MemoryStorageService(e);\r
-    }\r
-\r
-};\r
-\r
-static const XMLCh cleanupInterval[] = UNICODE_LITERAL_15(c,l,e,a,n,u,p,I,n,t,e,r,v,a,l);\r
-\r
-MemoryStorageService::MemoryStorageService(const DOMElement* e)\r
-    : contextLock(NULL), shutdown_wait(NULL), cleanup_thread(NULL), shutdown(false), m_cleanupInterval(0),\r
-        m_log(Category::getInstance(XMLTOOLING_LOGCAT".StorageService"))\r
-{\r
-    const XMLCh* tag=e ? e->getAttributeNS(NULL,cleanupInterval) : NULL;\r
-    if (tag && *tag) {\r
-        m_cleanupInterval = XMLString::parseInt(tag);\r
-    }\r
-    if (!m_cleanupInterval)\r
-        m_cleanupInterval=300;\r
-\r
-    contextLock = Mutex::create();\r
-    shutdown_wait = CondWait::create();\r
-    cleanup_thread = Thread::create(&cleanup_fn, (void*)this);\r
-}\r
-\r
-MemoryStorageService::~MemoryStorageService()\r
-{\r
-    // Shut down the cleanup thread and let it know...\r
-    shutdown = true;\r
-    shutdown_wait->signal();\r
-    cleanup_thread->join(NULL);\r
-\r
-    delete shutdown_wait;\r
-    delete contextLock;\r
-}\r
-\r
-void* MemoryStorageService::cleanup_fn(void* cache_p)\r
-{\r
-    MemoryStorageService* cache = reinterpret_cast<MemoryStorageService*>(cache_p);\r
-\r
-#ifndef WIN32\r
-    // First, let's block all signals \r
-    Thread::mask_all_signals();\r
-#endif\r
-\r
-    // Now run the cleanup process.\r
-    cache->cleanup();\r
-    return NULL;\r
-}\r
-\r
-void MemoryStorageService::cleanup()\r
-{\r
-#ifdef _DEBUG\r
-    NDC ndc("cleanup");\r
-#endif\r
-    \r
-\r
-    Mutex* mutex = Mutex::create();\r
-    mutex->lock();\r
-\r
-    m_log.info("cleanup thread started...running every %d seconds", m_cleanupInterval);\r
-\r
-    while (!shutdown) {\r
-        shutdown_wait->timedwait(mutex, m_cleanupInterval);\r
-        if (shutdown)\r
-            break;\r
-        \r
-        unsigned long count=0;\r
-        Lock wrapper(contextLock);\r
-        for (map<string,Context>::iterator i=m_contextMap.begin(); i!=m_contextMap.end(); ++i)\r
-            count += i->second.reap();\r
-        \r
-        if (count)\r
-            m_log.info("purged %d record(s) from storage", count);\r
-    }\r
-\r
-    m_log.info("cleanup thread finished");\r
-\r
-    mutex->unlock();\r
-    delete mutex;\r
-    Thread::exit(NULL);\r
-}\r
-\r
-void MemoryStorageService::reap(const char* context)\r
-{\r
-    getContext(context).reap();\r
-}\r
-\r
-unsigned long MemoryStorageService::Context::reap()\r
-{\r
-    // Lock the "database".\r
-    m_lock->wrlock();\r
-    SharedLock wrapper(m_lock, false);\r
-    \r
-    // Garbage collect any expired entries.\r
-    unsigned long count=0;\r
-    multimap<time_t,string>::iterator stop=m_expMap.upper_bound(time(NULL));\r
-    for (multimap<time_t,string>::iterator i=m_expMap.begin(); i!=stop; m_expMap.erase(i++)) {\r
-        m_dataMap.erase(i->second);\r
-        ++count;\r
-    }\r
-\r
-    return count;\r
-}\r
-\r
-void MemoryStorageService::createString(const char* context, const char* key, const char* value, time_t expiration)\r
-{\r
-    Context& ctx = getContext(context);\r
-\r
-    // Lock the maps.\r
-    ctx.m_lock->wrlock();\r
-    SharedLock wrapper(ctx.m_lock, false);\r
-    \r
-    // Check for a duplicate.\r
-    map<string,Record>::iterator i=ctx.m_dataMap.find(key);\r
-    if (i!=ctx.m_dataMap.end()) {\r
-        // Not yet expired?\r
-        if (time(NULL) < i->second.expiration)\r
-            throw IOException("attempted to insert a record with duplicate key ($1)", params(1,key));\r
-        // It's dead, so we can just remove it now and create the new record.\r
-        // Now find the reversed index of expiration to key, so we can clear it.\r
-        pair<multimap<time_t,string>::iterator,multimap<time_t,string>::iterator> range =\r
-            ctx.m_expMap.equal_range(i->second.expiration);\r
-        for (; range.first != range.second; ++range.first) {\r
-            if (range.first->second == i->first) {\r
-                ctx.m_expMap.erase(range.first);\r
-                break;\r
-            }\r
-        }\r
-        // And finally delete the record itself.\r
-        ctx.m_dataMap.erase(i);\r
-    }\r
-    \r
-    ctx.m_dataMap[key]=Record(value,expiration);\r
-    ctx.m_expMap.insert(multimap<time_t,string>::value_type(expiration,key));\r
-    \r
-    m_log.debug("inserted record (%s) in context (%s)", key, context);\r
-}\r
-\r
-bool MemoryStorageService::readString(const char* context, const char* key, string* pvalue, time_t* pexpiration)\r
-{\r
-    Context& ctx = getContext(context);\r
-\r
-    SharedLock wrapper(ctx.m_lock);\r
-    map<string,Record>::iterator i=ctx.m_dataMap.find(key);\r
-    if (i==ctx.m_dataMap.end())\r
-        return false;\r
-    else if (time(NULL) >= i->second.expiration)\r
-        return false;\r
-    if (pvalue)\r
-        *pvalue = i->second.data;\r
-    if (pexpiration)\r
-        *pexpiration = i->second.expiration;\r
-    return true;\r
-}\r
-\r
-bool MemoryStorageService::updateString(const char* context, const char* key, const char* value, time_t expiration)\r
-{\r
-    Context& ctx = getContext(context);\r
-\r
-    // Lock the maps.\r
-    ctx.m_lock->wrlock();\r
-    SharedLock wrapper(ctx.m_lock, false);\r
-\r
-    map<string,Record>::iterator i=ctx.m_dataMap.find(key);\r
-    if (i==ctx.m_dataMap.end())\r
-        return false;\r
-    else if (time(NULL) >= i->second.expiration)\r
-        return false;\r
-        \r
-    if (value)\r
-        i->second.data = value;\r
-        \r
-    if (expiration && expiration != i->second.expiration) {\r
-        // Update secondary map.\r
-        pair<multimap<time_t,string>::iterator,multimap<time_t,string>::iterator> range =\r
-            ctx.m_expMap.equal_range(i->second.expiration);\r
-        for (; range.first != range.second; ++range.first) {\r
-            if (range.first->second == i->first) {\r
-                ctx.m_expMap.erase(range.first);\r
-                break;\r
-            }\r
-        }\r
-        i->second.expiration = expiration;\r
-        ctx.m_expMap.insert(multimap<time_t,string>::value_type(expiration,key));\r
-    }\r
-\r
-    m_log.debug("updated record (%s) in context (%s)", key, context);\r
-    return true;\r
-}\r
-\r
-bool MemoryStorageService::deleteString(const char* context, const char* key)\r
-{\r
-    Context& ctx = getContext(context);\r
-\r
-    // Lock the maps.\r
-    ctx.m_lock->wrlock();\r
-    SharedLock wrapper(ctx.m_lock, false);\r
-    \r
-    // Find the record.\r
-    map<string,Record>::iterator i=ctx.m_dataMap.find(key);\r
-    if (i!=ctx.m_dataMap.end()) {\r
-        // Now find the reversed index of expiration to key, so we can clear it.\r
-        pair<multimap<time_t,string>::iterator,multimap<time_t,string>::iterator> range =\r
-            ctx.m_expMap.equal_range(i->second.expiration);\r
-        for (; range.first != range.second; ++range.first) {\r
-            if (range.first->second == i->first) {\r
-                ctx.m_expMap.erase(range.first);\r
-                break;\r
-            }\r
-        }\r
-        // And finally delete the record itself.\r
-        ctx.m_dataMap.erase(i);\r
-        m_log.debug("deleted record (%s) in context (%s)", key, context);\r
-        return true;\r
-    }\r
-\r
-    m_log.debug("deleting record (%s) in context (%s)....not found", key, context);\r
-    return false;\r
-}\r
+/*
+ *  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.
+ */
+
+/**
+ * MemoryStorageService.cpp
+ * 
+ * In-memory "persistent" storage, suitable for simple applications.
+ */
+
+#include "internal.h"
+#include "util/NDC.h"
+#include "util/StorageService.h"
+#include "util/Threads.h"
+#include "util/XMLHelper.h"
+
+#include <log4cpp/Category.hh>
+#include <xercesc/util/XMLUniDefs.hpp>
+
+using namespace xmltooling;
+using namespace log4cpp;
+using namespace std;
+
+namespace xmltooling {
+    class XMLTOOL_DLLLOCAL MemoryStorageService : public StorageService
+    {
+    public:
+        MemoryStorageService(const DOMElement* e);
+        virtual ~MemoryStorageService();
+        
+        void createString(const char* context, const char* key, const char* value, time_t expiration);
+        bool readString(const char* context, const char* key, string* pvalue=NULL, time_t* pexpiration=NULL);
+        bool updateString(const char* context, const char* key, const char* value=NULL, time_t expiration=0);
+        bool deleteString(const char* context, const char* key);
+        
+        void createText(const char* context, const char* key, const char* value, time_t expiration) {
+            return createString(context, key, value, expiration);
+        }
+        bool readText(const char* context, const char* key, string* pvalue=NULL, time_t* pexpiration=NULL) {
+            return readString(context, key, pvalue, pexpiration);
+        }
+        bool updateText(const char* context, const char* key, const char* value=NULL, time_t expiration=0) {
+            return updateString(context, key, value, expiration);
+        }
+        bool deleteText(const char* context, const char* key) {
+            return deleteString(context, key);
+        }
+        
+        void reap(const char* context);
+        void deleteContext(const char* context) {
+            Lock wrapper(contextLock);
+            m_contextMap.erase(context);
+        }
+
+    private:
+        void cleanup();
+    
+        struct XMLTOOL_DLLLOCAL Record {
+            Record() : expiration(0) {}
+            Record(string s, time_t t) : data(s), expiration(t) {}
+            string data;
+            time_t expiration;
+        };
+        
+        struct XMLTOOL_DLLLOCAL Context {
+            Context() : m_lock(RWLock::create()) {}
+            Context(const Context& src) {
+                m_dataMap = src.m_dataMap;
+                m_expMap = src.m_expMap;
+                m_lock = RWLock::create();
+            }
+            ~Context() { delete m_lock; }
+            map<string,Record> m_dataMap;
+            multimap<time_t,string> m_expMap;
+            RWLock* m_lock;
+            unsigned long reap();
+        };
+
+        Context& getContext(const char* context) {
+            Lock wrapper(contextLock);
+            return m_contextMap[context];
+        }
+
+        map<string,Context> m_contextMap;
+        Mutex* contextLock;
+        CondWait* shutdown_wait;
+        Thread* cleanup_thread;
+        static void* cleanup_fn(void*);
+        bool shutdown;
+        int m_cleanupInterval;
+        Category& m_log;
+    };
+
+    StorageService* XMLTOOL_DLLLOCAL MemoryStorageServiceFactory(const DOMElement* const & e)
+    {
+        return new MemoryStorageService(e);
+    }
+
+};
+
+static const XMLCh cleanupInterval[] = UNICODE_LITERAL_15(c,l,e,a,n,u,p,I,n,t,e,r,v,a,l);
+
+MemoryStorageService::MemoryStorageService(const DOMElement* e)
+    : contextLock(NULL), shutdown_wait(NULL), cleanup_thread(NULL), shutdown(false), m_cleanupInterval(0),
+        m_log(Category::getInstance(XMLTOOLING_LOGCAT".StorageService"))
+{
+    const XMLCh* tag=e ? e->getAttributeNS(NULL,cleanupInterval) : NULL;
+    if (tag && *tag) {
+        m_cleanupInterval = XMLString::parseInt(tag);
+    }
+    if (!m_cleanupInterval)
+        m_cleanupInterval=300;
+
+    contextLock = Mutex::create();
+    shutdown_wait = CondWait::create();
+    cleanup_thread = Thread::create(&cleanup_fn, (void*)this);
+}
+
+MemoryStorageService::~MemoryStorageService()
+{
+    // Shut down the cleanup thread and let it know...
+    shutdown = true;
+    shutdown_wait->signal();
+    cleanup_thread->join(NULL);
+
+    delete shutdown_wait;
+    delete contextLock;
+}
+
+void* MemoryStorageService::cleanup_fn(void* cache_p)
+{
+    MemoryStorageService* cache = reinterpret_cast<MemoryStorageService*>(cache_p);
+
+#ifndef WIN32
+    // First, let's block all signals 
+    Thread::mask_all_signals();
+#endif
+
+    // Now run the cleanup process.
+    cache->cleanup();
+    return NULL;
+}
+
+void MemoryStorageService::cleanup()
+{
+#ifdef _DEBUG
+    NDC ndc("cleanup");
+#endif
+    
+
+    Mutex* mutex = Mutex::create();
+    mutex->lock();
+
+    m_log.info("cleanup thread started...running every %d seconds", m_cleanupInterval);
+
+    while (!shutdown) {
+        shutdown_wait->timedwait(mutex, m_cleanupInterval);
+        if (shutdown)
+            break;
+        
+        unsigned long count=0;
+        Lock wrapper(contextLock);
+        for (map<string,Context>::iterator i=m_contextMap.begin(); i!=m_contextMap.end(); ++i)
+            count += i->second.reap();
+        
+        if (count)
+            m_log.info("purged %d record(s) from storage", count);
+    }
+
+    m_log.info("cleanup thread finished");
+
+    mutex->unlock();
+    delete mutex;
+    Thread::exit(NULL);
+}
+
+void MemoryStorageService::reap(const char* context)
+{
+    getContext(context).reap();
+}
+
+unsigned long MemoryStorageService::Context::reap()
+{
+    // Lock the "database".
+    m_lock->wrlock();
+    SharedLock wrapper(m_lock, false);
+    
+    // Garbage collect any expired entries.
+    unsigned long count=0;
+    multimap<time_t,string>::iterator stop=m_expMap.upper_bound(time(NULL));
+    for (multimap<time_t,string>::iterator i=m_expMap.begin(); i!=stop; m_expMap.erase(i++)) {
+        m_dataMap.erase(i->second);
+        ++count;
+    }
+
+    return count;
+}
+
+void MemoryStorageService::createString(const char* context, const char* key, const char* value, time_t expiration)
+{
+    Context& ctx = getContext(context);
+
+    // Lock the maps.
+    ctx.m_lock->wrlock();
+    SharedLock wrapper(ctx.m_lock, false);
+    
+    // Check for a duplicate.
+    map<string,Record>::iterator i=ctx.m_dataMap.find(key);
+    if (i!=ctx.m_dataMap.end()) {
+        // Not yet expired?
+        if (time(NULL) < i->second.expiration)
+            throw IOException("attempted to insert a record with duplicate key ($1)", params(1,key));
+        // It's dead, so we can just remove it now and create the new record.
+        // Now find the reversed index of expiration to key, so we can clear it.
+        pair<multimap<time_t,string>::iterator,multimap<time_t,string>::iterator> range =
+            ctx.m_expMap.equal_range(i->second.expiration);
+        for (; range.first != range.second; ++range.first) {
+            if (range.first->second == i->first) {
+                ctx.m_expMap.erase(range.first);
+                break;
+            }
+        }
+        // And finally delete the record itself.
+        ctx.m_dataMap.erase(i);
+    }
+    
+    ctx.m_dataMap[key]=Record(value,expiration);
+    ctx.m_expMap.insert(multimap<time_t,string>::value_type(expiration,key));
+    
+    m_log.debug("inserted record (%s) in context (%s)", key, context);
+}
+
+bool MemoryStorageService::readString(const char* context, const char* key, string* pvalue, time_t* pexpiration)
+{
+    Context& ctx = getContext(context);
+
+    SharedLock wrapper(ctx.m_lock);
+    map<string,Record>::iterator i=ctx.m_dataMap.find(key);
+    if (i==ctx.m_dataMap.end())
+        return false;
+    else if (time(NULL) >= i->second.expiration)
+        return false;
+    if (pvalue)
+        *pvalue = i->second.data;
+    if (pexpiration)
+        *pexpiration = i->second.expiration;
+    return true;
+}
+
+bool MemoryStorageService::updateString(const char* context, const char* key, const char* value, time_t expiration)
+{
+    Context& ctx = getContext(context);
+
+    // Lock the maps.
+    ctx.m_lock->wrlock();
+    SharedLock wrapper(ctx.m_lock, false);
+
+    map<string,Record>::iterator i=ctx.m_dataMap.find(key);
+    if (i==ctx.m_dataMap.end())
+        return false;
+    else if (time(NULL) >= i->second.expiration)
+        return false;
+        
+    if (value)
+        i->second.data = value;
+        
+    if (expiration && expiration != i->second.expiration) {
+        // Update secondary map.
+        pair<multimap<time_t,string>::iterator,multimap<time_t,string>::iterator> range =
+            ctx.m_expMap.equal_range(i->second.expiration);
+        for (; range.first != range.second; ++range.first) {
+            if (range.first->second == i->first) {
+                ctx.m_expMap.erase(range.first);
+                break;
+            }
+        }
+        i->second.expiration = expiration;
+        ctx.m_expMap.insert(multimap<time_t,string>::value_type(expiration,key));
+    }
+
+    m_log.debug("updated record (%s) in context (%s)", key, context);
+    return true;
+}
+
+bool MemoryStorageService::deleteString(const char* context, const char* key)
+{
+    Context& ctx = getContext(context);
+
+    // Lock the maps.
+    ctx.m_lock->wrlock();
+    SharedLock wrapper(ctx.m_lock, false);
+    
+    // Find the record.
+    map<string,Record>::iterator i=ctx.m_dataMap.find(key);
+    if (i!=ctx.m_dataMap.end()) {
+        // Now find the reversed index of expiration to key, so we can clear it.
+        pair<multimap<time_t,string>::iterator,multimap<time_t,string>::iterator> range =
+            ctx.m_expMap.equal_range(i->second.expiration);
+        for (; range.first != range.second; ++range.first) {
+            if (range.first->second == i->first) {
+                ctx.m_expMap.erase(range.first);
+                break;
+            }
+        }
+        // And finally delete the record itself.
+        ctx.m_dataMap.erase(i);
+        m_log.debug("deleted record (%s) in context (%s)", key, context);
+        return true;
+    }
+
+    m_log.debug("deleting record (%s) in context (%s)....not found", key, context);
+    return false;
+}
index e8ea23e..00b234e 100644 (file)
-/*\r
-*  Copyright 2001-2006 Internet2\r
- * \r
-* Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * UnknownElement.cpp\r
- * \r
- * Basic implementation suitable for use as default for unrecognized content\r
- */\r
-\r
-#include "internal.h"\r
-#include "exceptions.h"\r
-#include "impl/UnknownElement.h"\r
-#include "util/NDC.h"\r
-#include "util/XMLHelper.h"\r
-\r
-#include <log4cpp/Category.hh>\r
-#include <xercesc/framework/MemBufInputSource.hpp>\r
-#include <xercesc/framework/Wrapper4InputSource.hpp>\r
-#include <xercesc/util/XMLUniDefs.hpp>\r
-\r
-using namespace xmltooling;\r
-using namespace log4cpp;\r
-using namespace std;\r
-\r
-void UnknownElementImpl::releaseDOM() const\r
-{\r
-#ifdef _DEBUG\r
-    xmltooling::NDC ndc("releaseDOM");\r
-#endif\r
-    Category& log=Category::getInstance(XMLTOOLING_LOGCAT".UnknownElementImpl");\r
-    log.debug("releasing DOM for unknown content, preserving current DOM in XML form");\r
-\r
-    // We're losing our DOM, so assuming we have one, we preserve it.\r
-    serialize(m_xml);\r
-\r
-    // This takes care of the generic housekeeping now that we've preserved things.\r
-    AbstractDOMCachingXMLObject::releaseDOM();\r
-}\r
-\r
-XMLObject* UnknownElementImpl::clone() const\r
-{\r
-    UnknownElementImpl* ret=new UnknownElementImpl();\r
-\r
-    // If there's no XML locally, serialize this object into the new one.\r
-    // Otherwise just copy it over.\r
-    if (m_xml.empty())\r
-        serialize(ret->m_xml);\r
-    else\r
-        ret->m_xml=m_xml;\r
-\r
-    return ret;\r
-}\r
-\r
-void UnknownElementImpl::serialize(string& s) const\r
-{\r
-    if (getDOM())\r
-        XMLHelper::serialize(getDOM(),s);\r
-}\r
-\r
-DOMElement* UnknownElementImpl::marshall(\r
-    DOMDocument* document\r
-#ifndef XMLTOOLING_NO_XMLSEC\r
-    ,const std::vector<xmlsignature::Signature*>* sigs\r
-#endif\r
-    ) const\r
-{\r
-#ifdef _DEBUG\r
-    xmltooling::NDC ndc("marshall");\r
-#endif\r
-    \r
-    Category& log=Category::getInstance(XMLTOOLING_LOGCAT".Marshaller");\r
-    log.debug("marshalling unknown content");\r
-\r
-    DOMElement* cachedDOM=getDOM();\r
-    if (cachedDOM) {\r
-        if (!document || document==cachedDOM->getOwnerDocument()) {\r
-            log.debug("XMLObject has a usable cached DOM, reusing it");\r
-            if (document)\r
-                setDocumentElement(cachedDOM->getOwnerDocument(),cachedDOM);\r
-            releaseParentDOM(true);\r
-            return cachedDOM;\r
-        }\r
-        \r
-        // We have a DOM but it doesn't match the document we were given, so we import\r
-        // it into the new document.\r
-        cachedDOM=static_cast<DOMElement*>(document->importNode(cachedDOM, true));\r
-\r
-        // Recache the DOM.\r
-        setDocumentElement(document, cachedDOM);\r
-        log.debug("caching imported DOM for XMLObject");\r
-        setDOM(cachedDOM, false);\r
-        releaseParentDOM(true);\r
-        return cachedDOM;\r
-    }\r
-    \r
-    // If we get here, we didn't have a usable DOM.\r
-    // We need to reparse the XML we saved off into a new DOM.\r
-    bool bindDocument=false;\r
-    MemBufInputSource src(reinterpret_cast<const XMLByte*>(m_xml.c_str()),m_xml.length(),"UnknownElementImpl");\r
-    Wrapper4InputSource dsrc(&src,false);\r
-    log.debug("parsing XML back into DOM tree");\r
-    DOMDocument* internalDoc=XMLToolingConfig::getConfig().getParser().parse(dsrc);\r
-    if (document) {\r
-        // The caller insists on using his own document, so we now have to import the thing\r
-        // into it. Then we're just dumping the one we built.\r
-        log.debug("reimporting new DOM into caller-supplied document");\r
-        cachedDOM=static_cast<DOMElement*>(document->importNode(internalDoc->getDocumentElement(), true));\r
-        internalDoc->release();\r
-    }\r
-    else {\r
-        // We just bind the document we built to the object as the result.\r
-        cachedDOM=static_cast<DOMElement*>(internalDoc->getDocumentElement());\r
-        document=internalDoc;\r
-        bindDocument=true;\r
-    }\r
-\r
-    // Recache the DOM and clear the serialized copy.\r
-    setDocumentElement(document, cachedDOM);\r
-    log.debug("caching DOM for XMLObject (document is %sbound)", bindDocument ? "" : "not ");\r
-    setDOM(cachedDOM, bindDocument);\r
-    releaseParentDOM(true);\r
-    m_xml.erase();\r
-    return cachedDOM;\r
-}\r
-\r
-\r
-DOMElement* UnknownElementImpl::marshall(\r
-    DOMElement* parentElement\r
-#ifndef XMLTOOLING_NO_XMLSEC\r
-    ,const std::vector<xmlsignature::Signature*>* sigs\r
-#endif\r
-    ) const\r
-{\r
-#ifdef _DEBUG\r
-    xmltooling::NDC ndc("marshall");\r
-#endif\r
-    \r
-    Category& log=Category::getInstance(XMLTOOLING_LOGCAT".Marshaller");\r
-    log.debug("marshalling unknown content");\r
-\r
-    DOMElement* cachedDOM=getDOM();\r
-    if (cachedDOM) {\r
-        if (parentElement->getOwnerDocument()==cachedDOM->getOwnerDocument()) {\r
-            log.debug("XMLObject has a usable cached DOM, reusing it");\r
-            parentElement->appendChild(cachedDOM);\r
-            releaseParentDOM(true);\r
-            return cachedDOM;\r
-        }\r
-        \r
-        // We have a DOM but it doesn't match the document we were given, so we import\r
-        // it into the new document.\r
-        cachedDOM=static_cast<DOMElement*>(parentElement->getOwnerDocument()->importNode(cachedDOM, true));\r
-\r
-        // Recache the DOM.\r
-        parentElement->appendChild(cachedDOM);\r
-        log.debug("caching imported DOM for XMLObject");\r
-        setDOM(cachedDOM, false);\r
-        releaseParentDOM(true);\r
-        return cachedDOM;\r
-    }\r
-    \r
-    // If we get here, we didn't have a usable DOM (and/or we flushed the one we had).\r
-    // We need to reparse the XML we saved off into a new DOM.\r
-    MemBufInputSource src(reinterpret_cast<const XMLByte*>(m_xml.c_str()),m_xml.length(),"UnknownElementImpl");\r
-    Wrapper4InputSource dsrc(&src,false);\r
-    log.debug("parsing XML back into DOM tree");\r
-    DOMDocument* internalDoc=XMLToolingConfig::getConfig().getParser().parse(dsrc);\r
-    \r
-    log.debug("reimporting new DOM into caller-supplied document");\r
-    cachedDOM=static_cast<DOMElement*>(parentElement->getOwnerDocument()->importNode(internalDoc->getDocumentElement(), true));\r
-    internalDoc->release();\r
-\r
-    // Recache the DOM and clear the serialized copy.\r
-    parentElement->appendChild(cachedDOM);\r
-    log.debug("caching DOM for XMLObject");\r
-    setDOM(cachedDOM, false);\r
-    releaseParentDOM(true);\r
-    m_xml.erase();\r
-    return cachedDOM;\r
-}\r
-\r
-XMLObject* UnknownElementImpl::unmarshall(DOMElement* element, bool bindDocument)\r
-{\r
-    setDOM(element, bindDocument);\r
-    return this;\r
-}\r
-\r
-XMLObject* UnknownElementBuilder::buildObject(\r
-            const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType\r
-            ) const {\r
-            return new UnknownElementImpl(nsURI,localName,prefix);\r
-}\r
-\r
+/*
+*  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 <log4cpp/Category.hh>
+#include <xercesc/framework/MemBufInputSource.hpp>
+#include <xercesc/framework/Wrapper4InputSource.hpp>
+#include <xercesc/util/XMLUniDefs.hpp>
+
+using namespace xmltooling;
+using namespace log4cpp;
+using namespace std;
+
+void UnknownElementImpl::releaseDOM() const
+{
+#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
+#ifndef XMLTOOLING_NO_XMLSEC
+    ,const std::vector<xmlsignature::Signature*>* sigs
+#endif
+    ) 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<DOMElement*>(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<const XMLByte*>(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");
+        cachedDOM=static_cast<DOMElement*>(document->importNode(internalDoc->getDocumentElement(), true));
+        internalDoc->release();
+    }
+    else {
+        // We just bind the document we built to the object as the result.
+        cachedDOM=static_cast<DOMElement*>(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 std::vector<xmlsignature::Signature*>* sigs
+#endif
+    ) 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<DOMElement*>(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<const XMLByte*>(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");
+    cachedDOM=static_cast<DOMElement*>(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);
+}
+
index ce23b31..61129b2 100644 (file)
-/*\r
-*  Copyright 2001-2006 Internet2\r
- * \r
-* Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file xmltooling/impl/UnknownElement.h\r
- * \r
- * Basic implementation suitable for use as default for unrecognized content\r
- */\r
-\r
-#ifndef __xmltooling_unkelement_h__\r
-#define __xmltooling_unkelement_h__\r
-\r
-#include <xmltooling/AbstractSimpleElement.h>\r
-#include <xmltooling/exceptions.h>\r
-#include <xmltooling/XMLObjectBuilder.h>\r
-#include <xmltooling/io/AbstractXMLObjectMarshaller.h>\r
-#include <xmltooling/io/AbstractXMLObjectUnmarshaller.h>\r
-\r
-#include <string>\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( push )\r
-    #pragma warning( disable : 4250 4251 )\r
-#endif\r
-\r
-namespace xmltooling {\r
-\r
-    /// @cond off\r
-    class XMLTOOL_DLLLOCAL UnknownElementImpl : public AbstractSimpleElement, public AbstractDOMCachingXMLObject\r
-    {\r
-    public:\r
-        UnknownElementImpl(const XMLCh* namespaceURI=NULL, const XMLCh* elementLocalName=NULL, const XMLCh* namespacePrefix=NULL)\r
-            : AbstractXMLObject(namespaceURI, elementLocalName, namespacePrefix) {}\r
-    \r
-        void releaseDOM() const;\r
-\r
-        XMLObject* clone() const;\r
-\r
-        const XMLCh* getTextContent(unsigned int position=0) const {\r
-            throw XMLObjectException("Direct access to content is not permitted.");\r
-        }\r
-\r
-        void setTextContent(const XMLCh*, unsigned int position=0) {\r
-            throw XMLObjectException("Direct access to content is not permitted.");\r
-        }\r
-\r
-        DOMElement* marshall(\r
-            DOMDocument* document=NULL\r
-#ifndef XMLTOOLING_NO_XMLSEC\r
-            ,const std::vector<xmlsignature::Signature*>* sigs=NULL\r
-#endif\r
-            ) const;\r
-\r
-        DOMElement* marshall(\r
-            DOMElement* parentElement\r
-#ifndef XMLTOOLING_NO_XMLSEC\r
-            ,const std::vector<xmlsignature::Signature*>* sigs=NULL\r
-#endif\r
-            ) const;\r
-        XMLObject* unmarshall(DOMElement* element, bool bindDocument=false);\r
-        \r
-    protected:\r
-        void setDocumentElement(DOMDocument* document, DOMElement* element) const {\r
-            DOMElement* documentRoot = document->getDocumentElement();\r
-            if (documentRoot)\r
-                document->replaceChild(element, documentRoot);\r
-            else\r
-                document->appendChild(element);\r
-        }\r
-\r
-        mutable std::string m_xml;\r
-\r
-        void serialize(std::string& s) const;\r
-    };\r
-    /// @endcond\r
-    \r
-    /**\r
-     * Builder for UnknownElementImpl objects.\r
-     * Use as the default builder when you want unknown DOM content treated as raw/ignored XML.\r
-     */\r
-    class XMLTOOL_API UnknownElementBuilder : public XMLObjectBuilder\r
-    {\r
-    public:\r
-        XMLObject* buildObject(\r
-            const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix=NULL, const QName* schemaType=NULL\r
-            ) const;\r
-    };\r
-\r
-};\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( pop )\r
-#endif\r
-\r
-#endif /* __xmltooling_unkelement_h__ */\r
+/*
+*  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.
+ */
+
+/**
+ * @file xmltooling/impl/UnknownElement.h
+ * 
+ * Basic implementation suitable for use as default for unrecognized content
+ */
+
+#ifndef __xmltooling_unkelement_h__
+#define __xmltooling_unkelement_h__
+
+#include <xmltooling/AbstractSimpleElement.h>
+#include <xmltooling/exceptions.h>
+#include <xmltooling/XMLObjectBuilder.h>
+#include <xmltooling/io/AbstractXMLObjectMarshaller.h>
+#include <xmltooling/io/AbstractXMLObjectUnmarshaller.h>
+
+#include <string>
+
+#if defined (_MSC_VER)
+    #pragma warning( push )
+    #pragma warning( disable : 4250 4251 )
+#endif
+
+namespace xmltooling {
+
+    /// @cond off
+    class XMLTOOL_DLLLOCAL UnknownElementImpl : public AbstractSimpleElement, public AbstractDOMCachingXMLObject
+    {
+    public:
+        UnknownElementImpl(const XMLCh* namespaceURI=NULL, const XMLCh* elementLocalName=NULL, const XMLCh* namespacePrefix=NULL)
+            : AbstractXMLObject(namespaceURI, elementLocalName, namespacePrefix) {}
+    
+        void releaseDOM() const;
+
+        XMLObject* clone() const;
+
+        const XMLCh* getTextContent(unsigned int position=0) const {
+            throw XMLObjectException("Direct access to content is not permitted.");
+        }
+
+        void setTextContent(const XMLCh*, unsigned int position=0) {
+            throw XMLObjectException("Direct access to content is not permitted.");
+        }
+
+        DOMElement* marshall(
+            DOMDocument* document=NULL
+#ifndef XMLTOOLING_NO_XMLSEC
+            ,const std::vector<xmlsignature::Signature*>* sigs=NULL
+#endif
+            ) const;
+
+        DOMElement* marshall(
+            DOMElement* parentElement
+#ifndef XMLTOOLING_NO_XMLSEC
+            ,const std::vector<xmlsignature::Signature*>* sigs=NULL
+#endif
+            ) const;
+        XMLObject* unmarshall(DOMElement* element, bool bindDocument=false);
+        
+    protected:
+        void setDocumentElement(DOMDocument* document, DOMElement* element) const {
+            DOMElement* documentRoot = document->getDocumentElement();
+            if (documentRoot)
+                document->replaceChild(element, documentRoot);
+            else
+                document->appendChild(element);
+        }
+
+        mutable std::string m_xml;
+
+        void serialize(std::string& s) const;
+    };
+    /// @endcond
+    
+    /**
+     * Builder for UnknownElementImpl objects.
+     * Use as the default builder when you want unknown DOM content treated as raw/ignored XML.
+     */
+    class XMLTOOL_API UnknownElementBuilder : public XMLObjectBuilder
+    {
+    public:
+        XMLObject* buildObject(
+            const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix=NULL, const QName* schemaType=NULL
+            ) const;
+    };
+
+};
+
+#if defined (_MSC_VER)
+    #pragma warning( pop )
+#endif
+
+#endif /* __xmltooling_unkelement_h__ */
index a33016c..d2cd392 100644 (file)
-/*\r
-*  Copyright 2001-2006 Internet2\r
- * \r
-* Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * AbstractXMLObjectMarshaller.cpp\r
- * \r
- * A thread-safe abstract marshaller.\r
- */\r
-\r
-#include "internal.h"\r
-#include "exceptions.h"\r
-#include "io/AbstractXMLObjectMarshaller.h"\r
-#ifndef XMLTOOLING_NO_XMLSEC\r
-    #include "signature/Signature.h"\r
-#endif\r
-#include "util/NDC.h"\r
-#include "util/XMLConstants.h"\r
-#include "util/XMLHelper.h"\r
-\r
-#include <algorithm>\r
-#include <functional>\r
-#include <xercesc/util/XMLUniDefs.hpp>\r
-#include <log4cpp/Category.hh>\r
-\r
-#ifndef XMLTOOLING_NO_XMLSEC\r
-    using namespace xmlsignature;\r
-#endif\r
-using namespace xmltooling;\r
-using namespace log4cpp;\r
-using namespace std;\r
-\r
-#define XT_log (*static_cast<Category*>(m_log))\r
-\r
-DOMElement* AbstractXMLObjectMarshaller::marshall(\r
-    DOMDocument* document\r
-#ifndef XMLTOOLING_NO_XMLSEC\r
-    ,const std::vector<xmlsignature::Signature*>* sigs\r
-#endif\r
-    ) const\r
-{\r
-#ifdef _DEBUG\r
-    xmltooling::NDC ndc("marshall");\r
-#endif\r
-\r
-    if (XT_log.isDebugEnabled()) {\r
-        XT_log.debug("starting to marshal %s", getElementQName().toString().c_str());\r
-    }\r
-\r
-    DOMElement* cachedDOM=getDOM();\r
-    if (cachedDOM) {\r
-        if (!document || document==cachedDOM->getOwnerDocument()) {\r
-            XT_log.debug("XMLObject has a usable cached DOM, reusing it");\r
-            if (document)\r
-                setDocumentElement(cachedDOM->getOwnerDocument(),cachedDOM);\r
-            releaseParentDOM(true);\r
-            return cachedDOM;\r
-        }\r
-        \r
-        // We have a DOM but it doesn't match the document we were given. This both sucks and blows.\r
-        // Without an adoptNode option to maintain the child pointers, we have to either import the\r
-        // DOM while somehow reassigning all the nested references (which amounts to a complete\r
-        // *unmarshall* operation), or we just release the existing DOM and hope that we can get\r
-        // it back. This depends on all objects being able to preserve their DOM at all costs.\r
-        releaseChildrenDOM(true);\r
-        releaseDOM();\r
-    }\r
-    \r
-    // If we get here, we didn't have a usable DOM (and/or we released the one we had).\r
-    // We may need to create our own document.\r
-    bool bindDocument=false;\r
-    if (!document) {\r
-        document=DOMImplementationRegistry::getDOMImplementation(NULL)->createDocument();\r
-        bindDocument=true;\r
-    }\r
-    \r
-    XercesJanitor<DOMDocument> janitor(bindDocument ? document : NULL);\r
-\r
-    XT_log.debug("creating root element to marshall");\r
-    DOMElement* domElement = document->createElementNS(\r
-        getElementQName().getNamespaceURI(), getElementQName().getLocalPart()\r
-        );\r
-    setDocumentElement(document, domElement);\r
-#ifndef XMLTOOLING_NO_XMLSEC\r
-    marshallInto(domElement, sigs);\r
-#else\r
-    marshallInto(domElement);\r
-#endif\r
-    //Recache the DOM.\r
-    XT_log.debug("caching DOM for XMLObject (document is %sbound)", bindDocument ? "" : "not ");\r
-    setDOM(domElement, bindDocument);\r
-    janitor.release();  // safely transferred\r
-    releaseParentDOM(true);\r
-\r
-    return domElement;\r
-}\r
-\r
-DOMElement* AbstractXMLObjectMarshaller::marshall(\r
-    DOMElement* parentElement\r
-#ifndef XMLTOOLING_NO_XMLSEC\r
-    ,const std::vector<xmlsignature::Signature*>* sigs\r
-#endif\r
-    ) const\r
-{\r
-#ifdef _DEBUG\r
-    xmltooling::NDC ndc("marshall");\r
-#endif\r
-\r
-    if (XT_log.isDebugEnabled()) {\r
-        XT_log.debug("starting to marshalling %s", getElementQName().toString().c_str());\r
-    }\r
-\r
-    DOMElement* cachedDOM=getDOM();\r
-    if (cachedDOM) {\r
-        if (parentElement->getOwnerDocument()==cachedDOM->getOwnerDocument()) {\r
-            XT_log.debug("XMLObject has a usable cached DOM, reusing it");\r
-            if (parentElement!=cachedDOM->getParentNode()) {\r
-                parentElement->appendChild(cachedDOM);\r
-                releaseParentDOM(true);\r
-            }\r
-            return cachedDOM;\r
-        }\r
-        \r
-        // We have a DOM but it doesn't match the document we were given. This both sucks and blows.\r
-        // Without an adoptNode option to maintain the child pointers, we have to either import the\r
-        // DOM while somehow reassigning all the nested references (which amounts to a complete\r
-        // *unmarshall* operation), or we just release the existing DOM and hope that we can get\r
-        // it back. This depends on all objects being able to preserve their DOM at all costs.\r
-        releaseChildrenDOM(true);\r
-        releaseDOM();\r
-    }\r
-    \r
-    // If we get here, we didn't have a usable DOM (and/or we released the one we had).\r
-    XT_log.debug("creating root element to marshall");\r
-    DOMElement* domElement = parentElement->getOwnerDocument()->createElementNS(\r
-        getElementQName().getNamespaceURI(), getElementQName().getLocalPart()\r
-        );\r
-    parentElement->appendChild(domElement);\r
-#ifndef XMLTOOLING_NO_XMLSEC\r
-    marshallInto(domElement, sigs);\r
-#else\r
-    marshallInto(domElement);\r
-#endif\r
-\r
-    //Recache the DOM.\r
-    XT_log.debug("caching DOM for XMLObject");\r
-    setDOM(domElement, false);\r
-    releaseParentDOM(true);\r
-\r
-    return domElement;\r
-}\r
-\r
-void AbstractXMLObjectMarshaller::marshallInto(\r
-    DOMElement* targetElement\r
-#ifndef XMLTOOLING_NO_XMLSEC\r
-    ,const std::vector<xmlsignature::Signature*>* sigs\r
-#endif\r
-    ) const\r
-{\r
-    if (getElementQName().hasPrefix())\r
-        targetElement->setPrefix(getElementQName().getPrefix());\r
-\r
-    if (m_schemaLocation) {\r
-        static const XMLCh schemaLocation[]= UNICODE_LITERAL_14(s,c,h,e,m,a,L,o,c,a,t,i,o,n);\r
-        if (targetElement->getParentNode()==NULL || targetElement->getParentNode()->getNodeType()==DOMNode::DOCUMENT_NODE)\r
-            targetElement->setAttributeNS(XMLConstants::XSI_NS,schemaLocation,m_schemaLocation); \r
-    }\r
-\r
-    marshallElementType(targetElement);\r
-    marshallNamespaces(targetElement);\r
-    marshallAttributes(targetElement);\r
-    marshallContent(targetElement);\r
-    \r
-#ifndef XMLTOOLING_NO_XMLSEC\r
-    if (sigs) {\r
-        for_each(sigs->begin(),sigs->end(),mem_fun<void,Signature>(&Signature::sign));\r
-    }\r
-#endif\r
-}\r
-\r
-void AbstractXMLObjectMarshaller::marshallElementType(DOMElement* domElement) const\r
-{\r
-    const QName* type = getSchemaType();\r
-    if (type) {\r
-        XT_log.debug("setting xsi:type attribute for XMLObject");\r
-        \r
-        const XMLCh* typeLocalName = type->getLocalPart();\r
-        if (!typeLocalName || !*typeLocalName) {\r
-            throw MarshallingException("Schema type of XMLObject may not have an empty local name.");\r
-        }\r
-\r
-        static const XMLCh xsitype[] = {\r
-            chLatin_x, chLatin_s, chLatin_i, chColon, chLatin_t, chLatin_y, chLatin_p, chLatin_e, chNull\r
-            };\r
-        \r
-        XMLCh* xsivalue=const_cast<XMLCh*>(typeLocalName);\r
-        const XMLCh* prefix=type->getPrefix();\r
-        if (prefix && *prefix) {\r
-            xsivalue=new XMLCh[XMLString::stringLen(typeLocalName) + XMLString::stringLen(prefix) + 2*sizeof(XMLCh)];\r
-            *xsivalue=chNull;\r
-            XMLString::catString(xsivalue,prefix);\r
-            static const XMLCh colon[] = {chColon, chNull};\r
-            XMLString::catString(xsivalue,colon);\r
-            XMLString::catString(xsivalue,typeLocalName);\r
-        }   \r
-        domElement->setAttributeNS(XMLConstants::XSI_NS, xsitype, xsivalue);\r
-        if (xsivalue != typeLocalName)\r
-            XMLString::release(&xsivalue);\r
-\r
-        XT_log.debug("Adding XSI namespace to list of namespaces used by XMLObject");\r
-        addNamespace(Namespace(XMLConstants::XSI_NS, XMLConstants::XSI_PREFIX));\r
-    }\r
-}\r
-\r
-class _addns : public binary_function<DOMElement*,Namespace,void> {\r
-public:\r
-    void operator()(DOMElement* domElement, const Namespace& ns) const {\r
-        const XMLCh* prefix=ns.getNamespacePrefix();\r
-        const XMLCh* uri=ns.getNamespaceURI();\r
-        \r
-        // Check to see if the prefix is already declared properly above this node.\r
-        if (!ns.alwaysDeclare()) {\r
-            const XMLCh* declared=lookupNamespaceURI(domElement->getParentNode(),prefix);\r
-            if (declared && XMLString::equals(declared,uri))\r
-                return;\r
-        }\r
-            \r
-        if (prefix && *prefix) {\r
-            XMLCh* xmlns=new XMLCh[XMLString::stringLen(XMLConstants::XMLNS_PREFIX) + XMLString::stringLen(prefix) + 2*sizeof(XMLCh)];\r
-            *xmlns=chNull;\r
-            XMLString::catString(xmlns,XMLConstants::XMLNS_PREFIX);\r
-            static const XMLCh colon[] = {chColon, chNull};\r
-            XMLString::catString(xmlns,colon);\r
-            XMLString::catString(xmlns,prefix);\r
-            domElement->setAttributeNS(XMLConstants::XMLNS_NS, xmlns, uri);\r
-        }\r
-        else {\r
-            domElement->setAttributeNS(XMLConstants::XMLNS_NS, XMLConstants::XMLNS_PREFIX, uri);\r
-        }\r
-    }\r
-\r
-    const XMLCh* lookupNamespaceURI(const DOMNode* n, const XMLCh* prefix) const {\r
-        // Return NULL if no declaration in effect. The empty string signifies the null namespace.\r
-        if (!n || n->getNodeType()!=DOMNode::ELEMENT_NODE) {\r
-            // At the root, the default namespace is set to the null namespace.\r
-            if (!prefix || !*prefix)\r
-                return &chNull;\r
-            return NULL;    // we're done\r
-        }\r
-        DOMNamedNodeMap* attributes = static_cast<const DOMElement*>(n)->getAttributes();\r
-        if (!attributes)\r
-            return lookupNamespaceURI(n->getParentNode(),prefix);   // defer to parent\r
-        DOMNode* childNode;\r
-        DOMAttr* attribute;\r
-        for (XMLSize_t i=0; i<attributes->getLength(); i++) {\r
-            childNode = attributes->item(i);\r
-            if (childNode->getNodeType() != DOMNode::ATTRIBUTE_NODE)    // not an attribute?\r
-                continue;\r
-            attribute = static_cast<DOMAttr*>(childNode);\r
-            if (!XMLString::equals(attribute->getNamespaceURI(),XMLConstants::XMLNS_NS))\r
-                continue;   // not a namespace declaration\r
-            // Local name should be the prefix and the value would be the URI, except for the default namespace.\r
-            if ((!prefix || !*prefix) && XMLString::equals(attribute->getLocalName(),XMLConstants::XMLNS_PREFIX))\r
-                return attribute->getNodeValue();\r
-            else if (XMLString::equals(prefix,attribute->getLocalName()))\r
-                return attribute->getNodeValue();\r
-        }\r
-        // Defer to parent.\r
-        return lookupNamespaceURI(n->getParentNode(),prefix);\r
-    }\r
-};\r
-\r
-void AbstractXMLObjectMarshaller::marshallNamespaces(DOMElement* domElement) const\r
-{\r
-    XT_log.debug("marshalling namespace attributes for XMLObject");\r
-    const set<Namespace>& namespaces = getNamespaces();\r
-    for_each(namespaces.begin(),namespaces.end(),bind1st(_addns(),domElement));\r
-}\r
-\r
-void AbstractXMLObjectMarshaller::marshallContent(DOMElement* domElement) const\r
-{\r
-    XT_log.debug("marshalling text and child elements for XMLObject");\r
-    \r
-    const XMLCh* val;\r
-    unsigned int pos=0;\r
-    const list<XMLObject*>& children=getOrderedChildren();\r
-    for (list<XMLObject*>::const_iterator i=children.begin(); i!=children.end(); ++i, ++pos) {\r
-        val = getTextContent(pos);\r
-        if (val && *val)\r
-            domElement->appendChild(domElement->getOwnerDocument()->createTextNode(val));\r
-        if (*i)\r
-            (*i)->marshall(domElement);\r
-    }\r
-    val = getTextContent(pos);\r
-    if (val && *val)\r
-        domElement->appendChild(domElement->getOwnerDocument()->createTextNode(val));\r
-}\r
+/*
+*  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.
+ */
+
+/**
+ * AbstractXMLObjectMarshaller.cpp
+ * 
+ * A thread-safe abstract marshaller.
+ */
+
+#include "internal.h"
+#include "exceptions.h"
+#include "io/AbstractXMLObjectMarshaller.h"
+#ifndef XMLTOOLING_NO_XMLSEC
+    #include "signature/Signature.h"
+#endif
+#include "util/NDC.h"
+#include "util/XMLConstants.h"
+#include "util/XMLHelper.h"
+
+#include <algorithm>
+#include <functional>
+#include <xercesc/util/XMLUniDefs.hpp>
+#include <log4cpp/Category.hh>
+
+#ifndef XMLTOOLING_NO_XMLSEC
+    using namespace xmlsignature;
+#endif
+using namespace xmltooling;
+using namespace log4cpp;
+using namespace std;
+
+#define XT_log (*static_cast<Category*>(m_log))
+
+DOMElement* AbstractXMLObjectMarshaller::marshall(
+    DOMDocument* document
+#ifndef XMLTOOLING_NO_XMLSEC
+    ,const std::vector<xmlsignature::Signature*>* sigs
+#endif
+    ) const
+{
+#ifdef _DEBUG
+    xmltooling::NDC ndc("marshall");
+#endif
+
+    if (XT_log.isDebugEnabled()) {
+        XT_log.debug("starting to marshal %s", getElementQName().toString().c_str());
+    }
+
+    DOMElement* cachedDOM=getDOM();
+    if (cachedDOM) {
+        if (!document || document==cachedDOM->getOwnerDocument()) {
+            XT_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. This both sucks and blows.
+        // Without an adoptNode option to maintain the child pointers, we have to either import the
+        // DOM while somehow reassigning all the nested references (which amounts to a complete
+        // *unmarshall* operation), or we just release the existing DOM and hope that we can get
+        // it back. This depends on all objects being able to preserve their DOM at all costs.
+        releaseChildrenDOM(true);
+        releaseDOM();
+    }
+    
+    // If we get here, we didn't have a usable DOM (and/or we released the one we had).
+    // We may need to create our own document.
+    bool bindDocument=false;
+    if (!document) {
+        document=DOMImplementationRegistry::getDOMImplementation(NULL)->createDocument();
+        bindDocument=true;
+    }
+    
+    XercesJanitor<DOMDocument> janitor(bindDocument ? document : NULL);
+
+    XT_log.debug("creating root element to marshall");
+    DOMElement* domElement = document->createElementNS(
+        getElementQName().getNamespaceURI(), getElementQName().getLocalPart()
+        );
+    setDocumentElement(document, domElement);
+#ifndef XMLTOOLING_NO_XMLSEC
+    marshallInto(domElement, sigs);
+#else
+    marshallInto(domElement);
+#endif
+    //Recache the DOM.
+    XT_log.debug("caching DOM for XMLObject (document is %sbound)", bindDocument ? "" : "not ");
+    setDOM(domElement, bindDocument);
+    janitor.release();  // safely transferred
+    releaseParentDOM(true);
+
+    return domElement;
+}
+
+DOMElement* AbstractXMLObjectMarshaller::marshall(
+    DOMElement* parentElement
+#ifndef XMLTOOLING_NO_XMLSEC
+    ,const std::vector<xmlsignature::Signature*>* sigs
+#endif
+    ) const
+{
+#ifdef _DEBUG
+    xmltooling::NDC ndc("marshall");
+#endif
+
+    if (XT_log.isDebugEnabled()) {
+        XT_log.debug("starting to marshalling %s", getElementQName().toString().c_str());
+    }
+
+    DOMElement* cachedDOM=getDOM();
+    if (cachedDOM) {
+        if (parentElement->getOwnerDocument()==cachedDOM->getOwnerDocument()) {
+            XT_log.debug("XMLObject has a usable cached DOM, reusing it");
+            if (parentElement!=cachedDOM->getParentNode()) {
+                parentElement->appendChild(cachedDOM);
+                releaseParentDOM(true);
+            }
+            return cachedDOM;
+        }
+        
+        // We have a DOM but it doesn't match the document we were given. This both sucks and blows.
+        // Without an adoptNode option to maintain the child pointers, we have to either import the
+        // DOM while somehow reassigning all the nested references (which amounts to a complete
+        // *unmarshall* operation), or we just release the existing DOM and hope that we can get
+        // it back. This depends on all objects being able to preserve their DOM at all costs.
+        releaseChildrenDOM(true);
+        releaseDOM();
+    }
+    
+    // If we get here, we didn't have a usable DOM (and/or we released the one we had).
+    XT_log.debug("creating root element to marshall");
+    DOMElement* domElement = parentElement->getOwnerDocument()->createElementNS(
+        getElementQName().getNamespaceURI(), getElementQName().getLocalPart()
+        );
+    parentElement->appendChild(domElement);
+#ifndef XMLTOOLING_NO_XMLSEC
+    marshallInto(domElement, sigs);
+#else
+    marshallInto(domElement);
+#endif
+
+    //Recache the DOM.
+    XT_log.debug("caching DOM for XMLObject");
+    setDOM(domElement, false);
+    releaseParentDOM(true);
+
+    return domElement;
+}
+
+void AbstractXMLObjectMarshaller::marshallInto(
+    DOMElement* targetElement
+#ifndef XMLTOOLING_NO_XMLSEC
+    ,const std::vector<xmlsignature::Signature*>* sigs
+#endif
+    ) const
+{
+    if (getElementQName().hasPrefix())
+        targetElement->setPrefix(getElementQName().getPrefix());
+
+    if (m_schemaLocation) {
+        static const XMLCh schemaLocation[]= UNICODE_LITERAL_14(s,c,h,e,m,a,L,o,c,a,t,i,o,n);
+        if (targetElement->getParentNode()==NULL || targetElement->getParentNode()->getNodeType()==DOMNode::DOCUMENT_NODE)
+            targetElement->setAttributeNS(XMLConstants::XSI_NS,schemaLocation,m_schemaLocation); 
+    }
+
+    marshallElementType(targetElement);
+    marshallNamespaces(targetElement);
+    marshallAttributes(targetElement);
+    marshallContent(targetElement);
+    
+#ifndef XMLTOOLING_NO_XMLSEC
+    if (sigs) {
+        for_each(sigs->begin(),sigs->end(),mem_fun<void,Signature>(&Signature::sign));
+    }
+#endif
+}
+
+void AbstractXMLObjectMarshaller::marshallElementType(DOMElement* domElement) const
+{
+    const QName* type = getSchemaType();
+    if (type) {
+        XT_log.debug("setting xsi:type attribute for XMLObject");
+        
+        const XMLCh* typeLocalName = type->getLocalPart();
+        if (!typeLocalName || !*typeLocalName) {
+            throw MarshallingException("Schema type of XMLObject may not have an empty local name.");
+        }
+
+        static const XMLCh xsitype[] = {
+            chLatin_x, chLatin_s, chLatin_i, chColon, chLatin_t, chLatin_y, chLatin_p, chLatin_e, chNull
+            };
+        
+        XMLCh* xsivalue=const_cast<XMLCh*>(typeLocalName);
+        const XMLCh* prefix=type->getPrefix();
+        if (prefix && *prefix) {
+            xsivalue=new XMLCh[XMLString::stringLen(typeLocalName) + XMLString::stringLen(prefix) + 2*sizeof(XMLCh)];
+            *xsivalue=chNull;
+            XMLString::catString(xsivalue,prefix);
+            static const XMLCh colon[] = {chColon, chNull};
+            XMLString::catString(xsivalue,colon);
+            XMLString::catString(xsivalue,typeLocalName);
+        }   
+        domElement->setAttributeNS(XMLConstants::XSI_NS, xsitype, xsivalue);
+        if (xsivalue != typeLocalName)
+            XMLString::release(&xsivalue);
+
+        XT_log.debug("Adding XSI namespace to list of namespaces used by XMLObject");
+        addNamespace(Namespace(XMLConstants::XSI_NS, XMLConstants::XSI_PREFIX));
+    }
+}
+
+class _addns : public binary_function<DOMElement*,Namespace,void> {
+public:
+    void operator()(DOMElement* domElement, const Namespace& ns) const {
+        const XMLCh* prefix=ns.getNamespacePrefix();
+        const XMLCh* uri=ns.getNamespaceURI();
+        
+        // Check to see if the prefix is already declared properly above this node.
+        if (!ns.alwaysDeclare()) {
+            const XMLCh* declared=lookupNamespaceURI(domElement->getParentNode(),prefix);
+            if (declared && XMLString::equals(declared,uri))
+                return;
+        }
+            
+        if (prefix && *prefix) {
+            XMLCh* xmlns=new XMLCh[XMLString::stringLen(XMLConstants::XMLNS_PREFIX) + XMLString::stringLen(prefix) + 2*sizeof(XMLCh)];
+            *xmlns=chNull;
+            XMLString::catString(xmlns,XMLConstants::XMLNS_PREFIX);
+            static const XMLCh colon[] = {chColon, chNull};
+            XMLString::catString(xmlns,colon);
+            XMLString::catString(xmlns,prefix);
+            domElement->setAttributeNS(XMLConstants::XMLNS_NS, xmlns, uri);
+        }
+        else {
+            domElement->setAttributeNS(XMLConstants::XMLNS_NS, XMLConstants::XMLNS_PREFIX, uri);
+        }
+    }
+
+    const XMLCh* lookupNamespaceURI(const DOMNode* n, const XMLCh* prefix) const {
+        // Return NULL if no declaration in effect. The empty string signifies the null namespace.
+        if (!n || n->getNodeType()!=DOMNode::ELEMENT_NODE) {
+            // At the root, the default namespace is set to the null namespace.
+            if (!prefix || !*prefix)
+                return &chNull;
+            return NULL;    // we're done
+        }
+        DOMNamedNodeMap* attributes = static_cast<const DOMElement*>(n)->getAttributes();
+        if (!attributes)
+            return lookupNamespaceURI(n->getParentNode(),prefix);   // defer to parent
+        DOMNode* childNode;
+        DOMAttr* attribute;
+        for (XMLSize_t i=0; i<attributes->getLength(); i++) {
+            childNode = attributes->item(i);
+            if (childNode->getNodeType() != DOMNode::ATTRIBUTE_NODE)    // not an attribute?
+                continue;
+            attribute = static_cast<DOMAttr*>(childNode);
+            if (!XMLString::equals(attribute->getNamespaceURI(),XMLConstants::XMLNS_NS))
+                continue;   // not a namespace declaration
+            // Local name should be the prefix and the value would be the URI, except for the default namespace.
+            if ((!prefix || !*prefix) && XMLString::equals(attribute->getLocalName(),XMLConstants::XMLNS_PREFIX))
+                return attribute->getNodeValue();
+            else if (XMLString::equals(prefix,attribute->getLocalName()))
+                return attribute->getNodeValue();
+        }
+        // Defer to parent.
+        return lookupNamespaceURI(n->getParentNode(),prefix);
+    }
+};
+
+void AbstractXMLObjectMarshaller::marshallNamespaces(DOMElement* domElement) const
+{
+    XT_log.debug("marshalling namespace attributes for XMLObject");
+    const set<Namespace>& namespaces = getNamespaces();
+    for_each(namespaces.begin(),namespaces.end(),bind1st(_addns(),domElement));
+}
+
+void AbstractXMLObjectMarshaller::marshallContent(DOMElement* domElement) const
+{
+    XT_log.debug("marshalling text and child elements for XMLObject");
+    
+    const XMLCh* val;
+    unsigned int pos=0;
+    const list<XMLObject*>& children=getOrderedChildren();
+    for (list<XMLObject*>::const_iterator i=children.begin(); i!=children.end(); ++i, ++pos) {
+        val = getTextContent(pos);
+        if (val && *val)
+            domElement->appendChild(domElement->getOwnerDocument()->createTextNode(val));
+        if (*i)
+            (*i)->marshall(domElement);
+    }
+    val = getTextContent(pos);
+    if (val && *val)
+        domElement->appendChild(domElement->getOwnerDocument()->createTextNode(val));
+}
index cbab2fe..5cea6ae 100644 (file)
-/*\r
-*  Copyright 2001-2006 Internet2\r
- * \r
-* Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file AbstractXMLObjectMarshaller.h\r
- * \r
- * A thread-safe abstract marshaller.\r
- */\r
-\r
-#if !defined(__xmltooling_xmlmarshaller_h__)\r
-#define __xmltooling_xmlmarshaller_h__\r
-\r
-#include <xmltooling/AbstractDOMCachingXMLObject.h>\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( push )\r
-    #pragma warning( disable : 4250 4251 )\r
-#endif\r
-\r
-namespace xmltooling {\r
-\r
-    /**\r
-     * A thread-safe abstract marshaller.\r
-     */\r
-    class XMLTOOL_API AbstractXMLObjectMarshaller : public virtual AbstractXMLObject\r
-    {\r
-    public:\r
-        virtual ~AbstractXMLObjectMarshaller() {}\r
-\r
-        DOMElement* marshall(\r
-            DOMDocument* document=NULL\r
-#ifndef XMLTOOLING_NO_XMLSEC\r
-            ,const std::vector<xmlsignature::Signature*>* sigs=NULL\r
-#endif\r
-            ) const;\r
-\r
-        DOMElement* marshall(\r
-            DOMElement* parentElement\r
-#ifndef XMLTOOLING_NO_XMLSEC\r
-            ,const std::vector<xmlsignature::Signature*>* sigs=NULL\r
-#endif\r
-            ) const;\r
-        \r
-    protected:\r
-        AbstractXMLObjectMarshaller() {}\r
-\r
-        /**\r
-         * Sets the given element as the Document Element of the given Document.\r
-         * If the document already has a Document Element it is replaced by the given element.\r
-         * \r
-         * @param document the document\r
-         * @param element the Element that will serve as the Document Element\r
-         */\r
-        void setDocumentElement(DOMDocument* document, DOMElement* element) const {\r
-            DOMElement* documentRoot = document->getDocumentElement();\r
-            if (documentRoot)\r
-                document->replaceChild(element, documentRoot);\r
-            else\r
-                document->appendChild(element);\r
-        }\r
-    \r
-        /**\r
-         * Marshalls the XMLObject into the given DOM Element.\r
-         * The DOM Element must be within a DOM tree rooted in the owning Document.\r
-         * \r
-         * @param targetElement the Element into which the XMLObject is marshalled into\r
-         * @param ctx           optional marshalling context\r
-         * \r
-         * @throws MarshallingException thrown if there is a problem marshalling the object\r
-         * @throws SignatureException thrown if a problem occurs during signature creation \r
-         */\r
-        void marshallInto(\r
-            DOMElement* targetElement\r
-#ifndef XMLTOOLING_NO_XMLSEC\r
-            ,const std::vector<xmlsignature::Signature*>* sigs\r
-#endif\r
-            ) const;\r
-    \r
-        /**\r
-         * Creates an xsi:type attribute, corresponding to the given type of the XMLObject, on the DOM element.\r
-         * \r
-         * @param domElement the DOM element\r
-         * \r
-         * @throws MarshallingException thrown if the type on the XMLObject is doesn't contain\r
-         * a local name, prefix, and namespace URI\r
-         */\r
-        void marshallElementType(DOMElement* domElement) const;\r
-\r
-        /**\r
-         * Creates the xmlns attributes for any namespaces set on the XMLObject.\r
-         * \r
-         * @param domElement the DOM element the namespaces will be added to\r
-         */\r
-        void marshallNamespaces(DOMElement* domElement) const;\r
-    \r
-        /**\r
-         * Marshalls the text content and/or child elements of the XMLObject.\r
-         * \r
-         * @param domElement the DOM element that will recieved the marshalled children\r
-         * \r
-         * @throws MarshallingException thrown if there is a problem marshalling a child element\r
-         */\r
-        void marshallContent(DOMElement* domElement) const;\r
-\r
-        /**\r
-         * Marshalls the attributes from the XMLObject into the given DOM element.\r
-         * \r
-         * @param domElement the DOM Element into which attributes will be marshalled\r
-         * \r
-         * @throws MarshallingException thrown if there is a problem marshalling an attribute\r
-         */\r
-        virtual void marshallAttributes(DOMElement* domElement) const {}\r
-    };\r
-    \r
-};\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( pop )\r
-#endif\r
-\r
-#endif /* __xmltooling_xmlmarshaller_h__ */\r
+/*
+*  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.
+ */
+
+/**
+ * @file AbstractXMLObjectMarshaller.h
+ * 
+ * A thread-safe abstract marshaller.
+ */
+
+#if !defined(__xmltooling_xmlmarshaller_h__)
+#define __xmltooling_xmlmarshaller_h__
+
+#include <xmltooling/AbstractDOMCachingXMLObject.h>
+
+#if defined (_MSC_VER)
+    #pragma warning( push )
+    #pragma warning( disable : 4250 4251 )
+#endif
+
+namespace xmltooling {
+
+    /**
+     * A thread-safe abstract marshaller.
+     */
+    class XMLTOOL_API AbstractXMLObjectMarshaller : public virtual AbstractXMLObject
+    {
+    public:
+        virtual ~AbstractXMLObjectMarshaller() {}
+
+        DOMElement* marshall(
+            DOMDocument* document=NULL
+#ifndef XMLTOOLING_NO_XMLSEC
+            ,const std::vector<xmlsignature::Signature*>* sigs=NULL
+#endif
+            ) const;
+
+        DOMElement* marshall(
+            DOMElement* parentElement
+#ifndef XMLTOOLING_NO_XMLSEC
+            ,const std::vector<xmlsignature::Signature*>* sigs=NULL
+#endif
+            ) const;
+        
+    protected:
+        AbstractXMLObjectMarshaller() {}
+
+        /**
+         * Sets the given element as the Document Element of the given Document.
+         * If the document already has a Document Element it is replaced by the given element.
+         * 
+         * @param document the document
+         * @param element the Element that will serve as the Document Element
+         */
+        void setDocumentElement(DOMDocument* document, DOMElement* element) const {
+            DOMElement* documentRoot = document->getDocumentElement();
+            if (documentRoot)
+                document->replaceChild(element, documentRoot);
+            else
+                document->appendChild(element);
+        }
+    
+        /**
+         * Marshalls the XMLObject into the given DOM Element.
+         * The DOM Element must be within a DOM tree rooted in the owning Document.
+         * 
+         * @param targetElement the Element into which the XMLObject is marshalled into
+         * @param ctx           optional marshalling context
+         * 
+         * @throws MarshallingException thrown if there is a problem marshalling the object
+         * @throws SignatureException thrown if a problem occurs during signature creation 
+         */
+        void marshallInto(
+            DOMElement* targetElement
+#ifndef XMLTOOLING_NO_XMLSEC
+            ,const std::vector<xmlsignature::Signature*>* sigs
+#endif
+            ) const;
+    
+        /**
+         * Creates an xsi:type attribute, corresponding to the given type of the XMLObject, on the DOM element.
+         * 
+         * @param domElement the DOM element
+         * 
+         * @throws MarshallingException thrown if the type on the XMLObject is doesn't contain
+         * a local name, prefix, and namespace URI
+         */
+        void marshallElementType(DOMElement* domElement) const;
+
+        /**
+         * Creates the xmlns attributes for any namespaces set on the XMLObject.
+         * 
+         * @param domElement the DOM element the namespaces will be added to
+         */
+        void marshallNamespaces(DOMElement* domElement) const;
+    
+        /**
+         * Marshalls the text content and/or child elements of the XMLObject.
+         * 
+         * @param domElement the DOM element that will recieved the marshalled children
+         * 
+         * @throws MarshallingException thrown if there is a problem marshalling a child element
+         */
+        void marshallContent(DOMElement* domElement) const;
+
+        /**
+         * Marshalls the attributes from the XMLObject into the given DOM element.
+         * 
+         * @param domElement the DOM Element into which attributes will be marshalled
+         * 
+         * @throws MarshallingException thrown if there is a problem marshalling an attribute
+         */
+        virtual void marshallAttributes(DOMElement* domElement) const {}
+    };
+    
+};
+
+#if defined (_MSC_VER)
+    #pragma warning( pop )
+#endif
+
+#endif /* __xmltooling_xmlmarshaller_h__ */
index 80d0909..a69ef1b 100644 (file)
@@ -1,96 +1,96 @@
-/*\r
-*  Copyright 2001-2006 Internet2\r
- * \r
-* Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file AbstractXMLObjectUnmarshaller.h\r
- * \r
- * A thread-safe abstract unmarshaller.\r
- */\r
-\r
-#ifndef __xmltooling_xmlunmarshaller_h__\r
-#define __xmltooling_xmlunmarshaller_h__\r
-\r
-#include <xmltooling/AbstractDOMCachingXMLObject.h>\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( push )\r
-    #pragma warning( disable : 4250 4251 )\r
-#endif\r
-\r
-namespace xmltooling {\r
-\r
-    /**\r
-     * A thread-safe abstract unmarshaller.\r
-     */\r
-    class XMLTOOL_API AbstractXMLObjectUnmarshaller : public virtual AbstractXMLObject\r
-    {\r
-    public:\r
-        virtual ~AbstractXMLObjectUnmarshaller() {}\r
-\r
-        XMLObject* unmarshall(DOMElement* element, bool bindDocument=false);\r
-            \r
-    protected:\r
-        AbstractXMLObjectUnmarshaller() {}\r
-\r
-        /**\r
-         * Unmarshalls the attributes from the given DOM Element into the XMLObject. If the attribute\r
-         * is an XML namespace declaration the namespace is added via XMLObject::addNamespace().\r
-         * If it is a schema type (xsi:type) the schema type is added via XMLObject::setSchemaType().\r
-         * All other attributes are passed to the processAttribute hook.\r
-         * \r
-         * @param domElement the DOM Element whose attributes will be unmarshalled\r
-         * \r
-         * @throws UnmarshallingException thrown if there is a problem unmarshalling an attribute\r
-         */\r
-        virtual void unmarshallAttributes(const DOMElement* domElement);\r
-\r
-        /**\r
-         * Unmarshalls a given Element's child nodes. The resulting XMLObject children and content\r
-         * are passed to processChildElement() or processText() for further processing.\r
-         * \r
-         * @param domElement the DOM Element whose children will be unmarshalled\r
-         * \r
-         * @throws UnmarshallingException thrown if an error occurs unmarshalling the child elements\r
-         */\r
-        virtual void unmarshallContent(const DOMElement* domElement);\r
-\r
-        /**\r
-         * Called after a child element has been unmarshalled so that it can be added to the parent XMLObject.\r
-         * \r
-         * @param child     pointer to the child XMLObject\r
-         * @param childRoot root element of the child (must not be stored, just a hint)\r
-         * \r
-         * @throws UnmarshallingException thrown if there is a problem adding the child to the parent\r
-         */\r
-        virtual void processChildElement(XMLObject* child, const DOMElement* childRoot);\r
-    \r
-        /**\r
-         * Called after an attribute has been unmarshalled so that it can be added to the XMLObject.\r
-         * \r
-         * @param attribute the attribute being unmarshalled\r
-         * \r
-         * @throws UnmarshallingException thrown if there is a problem adding the attribute to the XMLObject\r
-         */\r
-        virtual void processAttribute(const DOMAttr* attribute);\r
-    };\r
-    \r
-};\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( pop )\r
-#endif\r
-\r
-#endif /* __xmltooling_xmlunmarshaller_h__ */\r
+/*
+*  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.
+ */
+
+/**
+ * @file AbstractXMLObjectUnmarshaller.h
+ * 
+ * A thread-safe abstract unmarshaller.
+ */
+
+#ifndef __xmltooling_xmlunmarshaller_h__
+#define __xmltooling_xmlunmarshaller_h__
+
+#include <xmltooling/AbstractDOMCachingXMLObject.h>
+
+#if defined (_MSC_VER)
+    #pragma warning( push )
+    #pragma warning( disable : 4250 4251 )
+#endif
+
+namespace xmltooling {
+
+    /**
+     * A thread-safe abstract unmarshaller.
+     */
+    class XMLTOOL_API AbstractXMLObjectUnmarshaller : public virtual AbstractXMLObject
+    {
+    public:
+        virtual ~AbstractXMLObjectUnmarshaller() {}
+
+        XMLObject* unmarshall(DOMElement* element, bool bindDocument=false);
+            
+    protected:
+        AbstractXMLObjectUnmarshaller() {}
+
+        /**
+         * Unmarshalls the attributes from the given DOM Element into the XMLObject. If the attribute
+         * is an XML namespace declaration the namespace is added via XMLObject::addNamespace().
+         * If it is a schema type (xsi:type) the schema type is added via XMLObject::setSchemaType().
+         * All other attributes are passed to the processAttribute hook.
+         * 
+         * @param domElement the DOM Element whose attributes will be unmarshalled
+         * 
+         * @throws UnmarshallingException thrown if there is a problem unmarshalling an attribute
+         */
+        virtual void unmarshallAttributes(const DOMElement* domElement);
+
+        /**
+         * Unmarshalls a given Element's child nodes. The resulting XMLObject children and content
+         * are passed to processChildElement() or processText() for further processing.
+         * 
+         * @param domElement the DOM Element whose children will be unmarshalled
+         * 
+         * @throws UnmarshallingException thrown if an error occurs unmarshalling the child elements
+         */
+        virtual void unmarshallContent(const DOMElement* domElement);
+
+        /**
+         * Called after a child element has been unmarshalled so that it can be added to the parent XMLObject.
+         * 
+         * @param child     pointer to the child XMLObject
+         * @param childRoot root element of the child (must not be stored, just a hint)
+         * 
+         * @throws UnmarshallingException thrown if there is a problem adding the child to the parent
+         */
+        virtual void processChildElement(XMLObject* child, const DOMElement* childRoot);
+    
+        /**
+         * Called after an attribute has been unmarshalled so that it can be added to the XMLObject.
+         * 
+         * @param attribute the attribute being unmarshalled
+         * 
+         * @throws UnmarshallingException thrown if there is a problem adding the attribute to the XMLObject
+         */
+        virtual void processAttribute(const DOMAttr* attribute);
+    };
+    
+};
+
+#if defined (_MSC_VER)
+    #pragma warning( pop )
+#endif
+
+#endif /* __xmltooling_xmlunmarshaller_h__ */
index a689ebf..ac3c090 100644 (file)
@@ -1,66 +1,66 @@
-/*\r
- * Copyright 2006 The Apache Software Foundation.\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * OpenSSLCryptoX509CRL.h\r
- * \r
- * OpenSSL-based class for handling X.509 CRLs\r
- */\r
-\r
-#if !defined(__xmltooling_opensslx509crl_h__) && !defined(XMLTOOLING_NO_XMLSEC)\r
-#define __xmltooling_opensslx509crl_h__\r
-\r
-#include <xmltooling/security/XSECCryptoX509CRL.h>\r
-\r
-#include <openssl/bio.h>\r
-#include <openssl/x509v3.h>\r
-#include <xsec/utils/XSECSafeBuffer.hpp>\r
-\r
-namespace xmltooling {\r
-    class XMLTOOL_API OpenSSLCryptoX509CRL : public XSECCryptoX509CRL {\r
-    public:\r
-       OpenSSLCryptoX509CRL() : mp_X509CRL(NULL), m_DERX509CRL("") {}\r
-       virtual ~OpenSSLCryptoX509CRL();\r
-\r
-       virtual const XMLCh* getProviderName() const {\r
-            return DSIGConstants::s_unicodeStrPROVOpenSSL;\r
-        }\r
-       virtual void loadX509CRLBase64Bin(const char* buf, unsigned int len);\r
-    \r
-       virtual safeBuffer& getDEREncodingSB(void) {\r
-            return m_DERX509CRL;\r
-        }\r
-    \r
-       OpenSSLCryptoX509CRL(X509_CRL* x);\r
-       X509_CRL* getOpenSSLX509CRL(void) {\r
-            return mp_X509CRL;\r
-        }\r
-\r
-        XSECCryptoX509CRL* clone() const {\r
-            OpenSSLCryptoX509CRL* copy = new OpenSSLCryptoX509CRL();\r
-            copy->mp_X509CRL = X509_CRL_dup(mp_X509CRL);\r
-            copy->m_DERX509CRL = m_DERX509CRL;\r
-            return copy;\r
-        }\r
-    \r
-    private:\r
-       X509_CRL* mp_X509CRL;\r
-       safeBuffer m_DERX509CRL;\r
-    };\r
-};\r
-\r
-#endif /* __xmltooling_opensslx509crl_h__ */\r
-\r
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * 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.
+ */
+
+/**
+ * OpenSSLCryptoX509CRL.h
+ * 
+ * OpenSSL-based class for handling X.509 CRLs
+ */
+
+#if !defined(__xmltooling_opensslx509crl_h__) && !defined(XMLTOOLING_NO_XMLSEC)
+#define __xmltooling_opensslx509crl_h__
+
+#include <xmltooling/security/XSECCryptoX509CRL.h>
+
+#include <openssl/bio.h>
+#include <openssl/x509v3.h>
+#include <xsec/utils/XSECSafeBuffer.hpp>
+
+namespace xmltooling {
+    class XMLTOOL_API OpenSSLCryptoX509CRL : public XSECCryptoX509CRL {
+    public:
+       OpenSSLCryptoX509CRL() : mp_X509CRL(NULL), m_DERX509CRL("") {}
+       virtual ~OpenSSLCryptoX509CRL();
+
+       virtual const XMLCh* getProviderName() const {
+            return DSIGConstants::s_unicodeStrPROVOpenSSL;
+        }
+       virtual void loadX509CRLBase64Bin(const char* buf, unsigned int len);
+    
+       virtual safeBuffer& getDEREncodingSB(void) {
+            return m_DERX509CRL;
+        }
+    
+       OpenSSLCryptoX509CRL(X509_CRL* x);
+       X509_CRL* getOpenSSLX509CRL(void) {
+            return mp_X509CRL;
+        }
+
+        XSECCryptoX509CRL* clone() const {
+            OpenSSLCryptoX509CRL* copy = new OpenSSLCryptoX509CRL();
+            copy->mp_X509CRL = X509_CRL_dup(mp_X509CRL);
+            copy->m_DERX509CRL = m_DERX509CRL;
+            return copy;
+        }
+    
+    private:
+       X509_CRL* mp_X509CRL;
+       safeBuffer m_DERX509CRL;
+    };
+};
+
+#endif /* __xmltooling_opensslx509crl_h__ */
+
index abc887f..33049a0 100644 (file)
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file xmltooling/security/TrustEngine.h\r
- * \r
- * Evaluates the trustworthiness and validity of XML Signatures against\r
- * implementation-specific requirements.\r
- */\r
-\r
-#if !defined(__xmltooling_trust_h__) && !defined(XMLTOOLING_NO_XMLSEC)\r
-#define __xmltooling_trust_h__\r
-\r
-#include <xmltooling/signature/KeyResolver.h>\r
-#include <xmltooling/signature/Signature.h>\r
-\r
-namespace xmltooling {\r
-\r
-    /**\r
-     * Evaluates the trustworthiness and validity of XML Signatures against\r
-     * implementation-specific requirements.\r
-     */\r
-    class XMLTOOL_API TrustEngine {\r
-        MAKE_NONCOPYABLE(TrustEngine);\r
-    protected:\r
-        /**\r
-         * Constructor.\r
-         * \r
-         * If a DOM is supplied, the following XML content is supported:\r
-         * \r
-         * <ul>\r
-         *  <li>&lt;KeyResolver&gt; elements with a type attribute\r
-         * </ul>\r
-         * \r
-         * XML namespaces are ignored in the processing of this content.\r
-         * \r
-         * @param e DOM to supply configuration for provider\r
-         */\r
-        TrustEngine(const DOMElement* e=NULL);\r
-        \r
-        /** Default KeyResolver instance. */\r
-        xmlsignature::KeyResolver* m_keyResolver;\r
-        \r
-    public:\r
-        virtual ~TrustEngine();\r
-        \r
-        /**\r
-         * Callback interface to supply KeyInfo objects to a TrustEngine.\r
-         * Applications can adapt TrustEngines to their environment by supplying\r
-         * implementations of this interface, or create specialized TrustEngine APIs\r
-         * by combining a KeyInfoIterator with a delegated TrustEngine. \r
-         */\r
-        class XMLTOOL_API KeyInfoIterator {\r
-            MAKE_NONCOPYABLE(KeyInfoIterator);\r
-        protected:\r
-            KeyInfoIterator() {}\r
-        public:\r
-            virtual ~KeyInfoIterator() {}\r
-            \r
-            /**\r
-             * Indicates whether additional KeyInfo objects are available.\r
-             * \r
-             * @return true iff another KeyInfo object can be fetched\r
-             */\r
-            virtual bool hasNext() const=0;\r
-            \r
-            /**\r
-             * Returns the next KeyInfo object available.\r
-             * \r
-             * @return the next KeyInfo object, or NULL if none are left\r
-             */\r
-            virtual const xmlsignature::KeyInfo* next()=0;\r
-        };\r
-        \r
-        /**\r
-         * Determines whether a signature is correct and valid with respect to the\r
-         * KeyInfo data supplied. It is the responsibility of the application to\r
-         * ensure that the KeyInfo information supplied is in fact associated with\r
-         * the peer who created the signature. \r
-         * \r
-         * A custom KeyResolver can be supplied from outside the TrustEngine.\r
-         * Alternatively, one may be specified to the plugin constructor.\r
-         * A non-caching, inline resolver will be used as a fallback.\r
-         * \r
-         * @param sig           reference to a signature object to validate\r
-         * @param keyInfoSource supplies KeyInfo objects to the TrustEngine\r
-         * @param keyResolver   optional externally supplied KeyResolver, or NULL\r
-         */\r
-        virtual bool validate(\r
-            xmlsignature::Signature& sig,\r
-            KeyInfoIterator& keyInfoSource,\r
-            const xmlsignature::KeyResolver* keyResolver=NULL\r
-            ) const=0;\r
-    };\r
-\r
-    /**\r
-     * Registers TrustEngine classes into the runtime.\r
-     */\r
-    void XMLTOOL_API registerTrustEngines();\r
-\r
-    /** TrustEngine based on explicit knowledge of peer key information. */\r
-    #define EXPLICIT_KEY_TRUSTENGINE  "org.opensaml.xmlooling.security.ExplicitKeyTrustEngine"\r
-};\r
-\r
-#endif /* __xmltooling_trust_h__ */\r
+/*
+ *  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.
+ */
+
+/**
+ * @file xmltooling/security/TrustEngine.h
+ * 
+ * Evaluates the trustworthiness and validity of XML Signatures against
+ * implementation-specific requirements.
+ */
+
+#if !defined(__xmltooling_trust_h__) && !defined(XMLTOOLING_NO_XMLSEC)
+#define __xmltooling_trust_h__
+
+#include <xmltooling/signature/KeyResolver.h>
+#include <xmltooling/signature/Signature.h>
+
+namespace xmltooling {
+
+    /**
+     * Evaluates the trustworthiness and validity of XML Signatures against
+     * implementation-specific requirements.
+     */
+    class XMLTOOL_API TrustEngine {
+        MAKE_NONCOPYABLE(TrustEngine);
+    protected:
+        /**
+         * Constructor.
+         * 
+         * If a DOM is supplied, the following XML content is supported:
+         * 
+         * <ul>
+         *  <li>&lt;KeyResolver&gt; elements with a type attribute
+         * </ul>
+         * 
+         * XML namespaces are ignored in the processing of this content.
+         * 
+         * @param e DOM to supply configuration for provider
+         */
+        TrustEngine(const DOMElement* e=NULL);
+        
+        /** Default KeyResolver instance. */
+        xmlsignature::KeyResolver* m_keyResolver;
+        
+    public:
+        virtual ~TrustEngine();
+        
+        /**
+         * Callback interface to supply KeyInfo objects to a TrustEngine.
+         * Applications can adapt TrustEngines to their environment by supplying
+         * implementations of this interface, or create specialized TrustEngine APIs
+         * by combining a KeyInfoIterator with a delegated TrustEngine. 
+         */
+        class XMLTOOL_API KeyInfoIterator {
+            MAKE_NONCOPYABLE(KeyInfoIterator);
+        protected:
+            KeyInfoIterator() {}
+        public:
+            virtual ~KeyInfoIterator() {}
+            
+            /**
+             * Indicates whether additional KeyInfo objects are available.
+             * 
+             * @return true iff another KeyInfo object can be fetched
+             */
+            virtual bool hasNext() const=0;
+            
+            /**
+             * Returns the next KeyInfo object available.
+             * 
+             * @return the next KeyInfo object, or NULL if none are left
+             */
+            virtual const xmlsignature::KeyInfo* next()=0;
+        };
+        
+        /**
+         * Determines whether a signature is correct and valid with respect to the
+         * KeyInfo data supplied. It is the responsibility of the application to
+         * ensure that the KeyInfo information supplied is in fact associated with
+         * the peer who created the signature. 
+         * 
+         * A custom KeyResolver can be supplied from outside the TrustEngine.
+         * Alternatively, one may be specified to the plugin constructor.
+         * A non-caching, inline resolver will be used as a fallback.
+         * 
+         * @param sig           reference to a signature object to validate
+         * @param keyInfoSource supplies KeyInfo objects to the TrustEngine
+         * @param keyResolver   optional externally supplied KeyResolver, or NULL
+         */
+        virtual bool validate(
+            xmlsignature::Signature& sig,
+            KeyInfoIterator& keyInfoSource,
+            const xmlsignature::KeyResolver* keyResolver=NULL
+            ) const=0;
+    };
+
+    /**
+     * Registers TrustEngine classes into the runtime.
+     */
+    void XMLTOOL_API registerTrustEngines();
+
+    /** TrustEngine based on explicit knowledge of peer key information. */
+    #define EXPLICIT_KEY_TRUSTENGINE  "org.opensaml.xmlooling.security.ExplicitKeyTrustEngine"
+};
+
+#endif /* __xmltooling_trust_h__ */
index b0b2cf8..3aabe05 100644 (file)
@@ -1,80 +1,80 @@
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file xmltooling/security/X509TrustEngine.h\r
- * \r
- * Extended TrustEngine interface that adds validation of X.509 credentials.\r
- */\r
-\r
-#if !defined(__xmltooling_x509trust_h__) && !defined(XMLTOOLING_NO_XMLSEC)\r
-#define __xmltooling_x509trust_h__\r
-\r
-#include <xmltooling/security/TrustEngine.h>\r
-\r
-namespace xmltooling {\r
-\r
-    /**\r
-     * Extended TrustEngine interface that adds validation of X.509 credentials.\r
-     */\r
-    class XMLTOOL_API X509TrustEngine : public TrustEngine {\r
-    protected:\r
-        /**\r
-         * Constructor.\r
-         * \r
-         * If a DOM is supplied, the following XML content is supported:\r
-         * \r
-         * <ul>\r
-         *  <li>&lt;KeyResolver&gt; elements with a type attribute\r
-         * </ul>\r
-         * \r
-         * XML namespaces are ignored in the processing of this content.\r
-         * \r
-         * @param e DOM to supply configuration for provider\r
-         */\r
-        X509TrustEngine(const DOMElement* e=NULL) : TrustEngine(e) {}\r
-        \r
-    public:\r
-        virtual ~X509TrustEngine() {}\r
-        \r
-        /**\r
-         * Determines whether an X.509 credential is valid with respect to the\r
-         * KeyInfo data supplied. It is the responsibility of the application to\r
-         * ensure that the KeyInfo information supplied is in fact associated with\r
-         * the peer who presented the signature. \r
-         * \r
-         * A custom KeyResolver can be supplied from outside the TrustEngine.\r
-         * Alternatively, one may be specified to the plugin constructor.\r
-         * A non-caching, inline resolver will be used as a fallback.\r
-         * \r
-         * @param certEE        end-entity certificate to validate\r
-         * @param certChain     the complete set of certificates presented for validation (includes certEE)\r
-         * @param keyInfoSource supplies KeyInfo objects to the TrustEngine\r
-         * @param checkName     true iff certificate subject/name checking has <b>NOT</b> already occurred\r
-         * @param keyResolver   optional externally supplied KeyResolver, or NULL\r
-         */\r
-        virtual bool validate(\r
-            XSECCryptoX509* certEE,\r
-            const std::vector<XSECCryptoX509*>& certChain,\r
-            TrustEngine::KeyInfoIterator& keyInfoSource,\r
-            bool checkName=true,\r
-            const xmlsignature::KeyResolver* keyResolver=NULL\r
-            ) const=0;\r
-    };\r
-    \r
-};\r
-\r
-#endif /* __xmltooling_x509trust_h__ */\r
+/*
+ *  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.
+ */
+
+/**
+ * @file xmltooling/security/X509TrustEngine.h
+ * 
+ * Extended TrustEngine interface that adds validation of X.509 credentials.
+ */
+
+#if !defined(__xmltooling_x509trust_h__) && !defined(XMLTOOLING_NO_XMLSEC)
+#define __xmltooling_x509trust_h__
+
+#include <xmltooling/security/TrustEngine.h>
+
+namespace xmltooling {
+
+    /**
+     * Extended TrustEngine interface that adds validation of X.509 credentials.
+     */
+    class XMLTOOL_API X509TrustEngine : public TrustEngine {
+    protected:
+        /**
+         * Constructor.
+         * 
+         * If a DOM is supplied, the following XML content is supported:
+         * 
+         * <ul>
+         *  <li>&lt;KeyResolver&gt; elements with a type attribute
+         * </ul>
+         * 
+         * XML namespaces are ignored in the processing of this content.
+         * 
+         * @param e DOM to supply configuration for provider
+         */
+        X509TrustEngine(const DOMElement* e=NULL) : TrustEngine(e) {}
+        
+    public:
+        virtual ~X509TrustEngine() {}
+        
+        /**
+         * Determines whether an X.509 credential is valid with respect to the
+         * KeyInfo data supplied. It is the responsibility of the application to
+         * ensure that the KeyInfo information supplied is in fact associated with
+         * the peer who presented the signature. 
+         * 
+         * A custom KeyResolver can be supplied from outside the TrustEngine.
+         * Alternatively, one may be specified to the plugin constructor.
+         * A non-caching, inline resolver will be used as a fallback.
+         * 
+         * @param certEE        end-entity certificate to validate
+         * @param certChain     the complete set of certificates presented for validation (includes certEE)
+         * @param keyInfoSource supplies KeyInfo objects to the TrustEngine
+         * @param checkName     true iff certificate subject/name checking has <b>NOT</b> already occurred
+         * @param keyResolver   optional externally supplied KeyResolver, or NULL
+         */
+        virtual bool validate(
+            XSECCryptoX509* certEE,
+            const std::vector<XSECCryptoX509*>& certChain,
+            TrustEngine::KeyInfoIterator& keyInfoSource,
+            bool checkName=true,
+            const xmlsignature::KeyResolver* keyResolver=NULL
+            ) const=0;
+    };
+    
+};
+
+#endif /* __xmltooling_x509trust_h__ */
index 4bca77b..fd67f20 100644 (file)
@@ -1,88 +1,88 @@
-/*\r
- * Copyright 2006 The Apache Software Foundation.\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file xmltooling/security/XSECCryptoX509CRL.h\r
- * \r
- * Wrapper for X.509 CRL objects, similar to existing XSEC wrappers.\r
- */\r
-\r
-#if !defined(__xmltooling_x509crl_h__) && !defined(XMLTOOLING_NO_XMLSEC)\r
-#define __xmltooling_x509crl_h__\r
-\r
-#include <xmltooling/base.h>\r
-\r
-#include <xsec/framework/XSECDefs.hpp>\r
-#include <xsec/utils/XSECSafeBuffer.hpp>\r
-\r
-namespace xmltooling {\r
-    /**\r
-     * Interface class for X.509 CRLs\r
-     * The library uses classes derived from this to process X.509 CRLs.\r
-     */\r
-    class XMLTOOL_API XSECCryptoX509CRL {\r
-        MAKE_NONCOPYABLE(XSECCryptoX509CRL);\r
-    protected:\r
-        XSECCryptoX509CRL() {}\r
-    public:\r
-       virtual ~XSECCryptoX509CRL() {}\r
-    \r
-       /**\r
-        * Returns a string that identifies the crypto owner of this library.\r
-         * \r
-         * @return  the crypto provider name\r
-        */\r
-       virtual const XMLCh* getProviderName() const=0;\r
-    \r
-       /**\r
-        * Load a CRL into the object.\r
-        * Takes a base64 DER-encoded CRL and loads it.\r
-        *\r
-        * @param buf buffer containing the Base64 encoded CRL\r
-        * @param len number of bytes of data in the CRL buffer\r
-        */\r
-    \r
-        /**\r
-         * Returns a duplicate of the original object.\r
-         *\r
-         * @return  the duplicate\r
-         */\r
-        virtual XSECCryptoX509CRL* clone() const=0;\r
-\r
-       virtual void loadX509CRLBase64Bin(const char* buf, unsigned int len)=0;\r
-    \r
-       /**\r
-        * Load a PEM encoded CRL into the object.\r
-        *\r
-        * Takes a PEM encoded CRL and loads it.\r
-        *\r
-        * @param buf buffer containing the PEM encoded CRL\r
-        * @param len number of bytes of data in the CRL buffer (0 if the string is null terminated)\r
-        */\r
-       void loadX509CRLPEM(const char* buf, unsigned int len=0);\r
-    \r
-       /**\r
-        * Get a Base64 DER encoded copy of the CRL\r
-        *\r
-        * @return A safeBuffer containing the DER encoded certificate\r
-        */\r
-       virtual safeBuffer& getDEREncodingSB(void)=0;\r
-    };\r
-};\r
-\r
-#endif /* __xmltooling_x509crl_h__ */\r
-\r
-\r
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * 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.
+ */
+
+/**
+ * @file xmltooling/security/XSECCryptoX509CRL.h
+ * 
+ * Wrapper for X.509 CRL objects, similar to existing XSEC wrappers.
+ */
+
+#if !defined(__xmltooling_x509crl_h__) && !defined(XMLTOOLING_NO_XMLSEC)
+#define __xmltooling_x509crl_h__
+
+#include <xmltooling/base.h>
+
+#include <xsec/framework/XSECDefs.hpp>
+#include <xsec/utils/XSECSafeBuffer.hpp>
+
+namespace xmltooling {
+    /**
+     * Interface class for X.509 CRLs
+     * The library uses classes derived from this to process X.509 CRLs.
+     */
+    class XMLTOOL_API XSECCryptoX509CRL {
+        MAKE_NONCOPYABLE(XSECCryptoX509CRL);
+    protected:
+        XSECCryptoX509CRL() {}
+    public:
+       virtual ~XSECCryptoX509CRL() {}
+    
+       /**
+        * Returns a string that identifies the crypto owner of this library.
+         * 
+         * @return  the crypto provider name
+        */
+       virtual const XMLCh* getProviderName() const=0;
+    
+       /**
+        * Load a CRL into the object.
+        * Takes a base64 DER-encoded CRL and loads it.
+        *
+        * @param buf buffer containing the Base64 encoded CRL
+        * @param len number of bytes of data in the CRL buffer
+        */
+    
+        /**
+         * Returns a duplicate of the original object.
+         *
+         * @return  the duplicate
+         */
+        virtual XSECCryptoX509CRL* clone() const=0;
+
+       virtual void loadX509CRLBase64Bin(const char* buf, unsigned int len)=0;
+    
+       /**
+        * Load a PEM encoded CRL into the object.
+        *
+        * Takes a PEM encoded CRL and loads it.
+        *
+        * @param buf buffer containing the PEM encoded CRL
+        * @param len number of bytes of data in the CRL buffer (0 if the string is null terminated)
+        */
+       void loadX509CRLPEM(const char* buf, unsigned int len=0);
+    
+       /**
+        * Get a Base64 DER encoded copy of the CRL
+        *
+        * @return A safeBuffer containing the DER encoded certificate
+        */
+       virtual safeBuffer& getDEREncodingSB(void)=0;
+    };
+};
+
+#endif /* __xmltooling_x509crl_h__ */
+
+
index 4d1eeb2..f64cf12 100644 (file)
-/*\r
- *  Copyright 2001-2005 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * ExplicitKeyTrustEngine.cpp\r
- * \r
- * TrustEngine based on explicit knowledge of peer key information.\r
- */\r
-\r
-#include "internal.h"\r
-#include "security/X509TrustEngine.h"\r
-#include "signature/SignatureValidator.h"\r
-#include "util/NDC.h"\r
-\r
-#include <log4cpp/Category.hh>\r
-#include <xercesc/util/XMLUniDefs.hpp>\r
-#include <xsec/enc/OpenSSL/OpenSSLCryptoX509.hpp>\r
-\r
-using namespace xmlsignature;\r
-using namespace xmltooling;\r
-using namespace log4cpp;\r
-using namespace std;\r
-\r
-namespace xmltooling {\r
-    class XMLTOOL_DLLLOCAL ExplicitKeyTrustEngine : public X509TrustEngine\r
-    {\r
-    public:\r
-        ExplicitKeyTrustEngine(const DOMElement* e) : X509TrustEngine(e) {}\r
-        virtual ~ExplicitKeyTrustEngine() {}\r
-\r
-        virtual bool validate(\r
-            Signature& sig,\r
-            TrustEngine::KeyInfoIterator& keyInfoSource,\r
-            const KeyResolver* keyResolver=NULL\r
-            ) const;\r
-        virtual bool validate(\r
-            XSECCryptoX509* certEE,\r
-            const vector<XSECCryptoX509*>& certChain,\r
-            TrustEngine::KeyInfoIterator& keyInfoSource,\r
-            bool checkName=true,\r
-            const KeyResolver* keyResolver=NULL\r
-            ) const;\r
-    };\r
-\r
-    TrustEngine* XMLTOOL_DLLLOCAL ExplicitKeyTrustEngineFactory(const DOMElement* const & e)\r
-    {\r
-        return new ExplicitKeyTrustEngine(e);\r
-    }\r
-};\r
-\r
-bool ExplicitKeyTrustEngine::validate(\r
-    Signature& sig,\r
-    TrustEngine::KeyInfoIterator& keyInfoSource,\r
-    const KeyResolver* keyResolver\r
-    ) const\r
-{\r
-#ifdef _DEBUG\r
-    NDC ndc("validate");\r
-#endif\r
-    Category& log=Category::getInstance(XMLTOOLING_LOGCAT".TrustEngine");\r
-    \r
-    if (!keyInfoSource.hasNext()) {\r
-        log.warn("unable to validate signature, no key information available for peer");\r
-        return false;\r
-    }\r
-    \r
-    log.debug("attempting to validate signature with the key information for peer");\r
-    SignatureValidator sigValidator;\r
-    while (keyInfoSource.hasNext()) {\r
-        XSECCryptoKey* key = (keyResolver ? keyResolver : m_keyResolver)->resolveKey(keyInfoSource.next());\r
-        if (key) {\r
-            log.debug("attempting to validate signature with public key...");\r
-            try {\r
-                sigValidator.setKey(key);   // key now owned by validator\r
-                sigValidator.validate(&sig);\r
-                log.info("signature validated with public key");\r
-                return true;\r
-            }\r
-            catch (ValidationException& e) {\r
-                if (log.isDebugEnabled()) {\r
-                    log.debug("public key did not validate signature: %s", e.what());\r
-                }\r
-            }\r
-        }\r
-        else {\r
-            log.debug("key information does not resolve to a public key, skipping it");\r
-        }\r
-    }\r
-\r
-    log.error("no peer key information validated the signature");\r
-    return false;\r
-}\r
-\r
-bool ExplicitKeyTrustEngine::validate(\r
-    XSECCryptoX509* certEE,\r
-    const vector<XSECCryptoX509*>& certChain,\r
-    TrustEngine::KeyInfoIterator& keyInfoSource,\r
-    bool checkName,\r
-    const KeyResolver* keyResolver\r
-    ) const\r
-{\r
-#ifdef _DEBUG\r
-    NDC ndc("validate");\r
-#endif\r
-    Category& log=Category::getInstance(XMLTOOLING_LOGCAT".TrustEngine");\r
-    \r
-    if (!certEE) {\r
-        log.error("unable to validate, end-entity certificate was null");\r
-        return false;\r
-    }\r
-    else if (certEE->getProviderName()!=DSIGConstants::s_unicodeStrPROVOpenSSL) {\r
-        log.error("only the OpenSSL XSEC provider is supported");\r
-        return false;\r
-    }\r
-    else if (!keyInfoSource.hasNext()) {\r
-        log.warn("unable to validate, no key information available for peer");\r
-        return false;\r
-    }\r
-\r
-    // The new "basic" trust implementation relies solely on certificates living within the\r
-    // role interface to verify the EE certificate.\r
-\r
-    log.debug("attempting to match key information from peer with end-entity certificate");\r
-    while (keyInfoSource.hasNext()) {\r
-        KeyResolver::ResolvedCertificates resolvedCerts;\r
-        if (0 == (keyResolver ? keyResolver : m_keyResolver)->resolveCertificates(keyInfoSource.next(),resolvedCerts)) {\r
-            log.debug("key information does not resolve to a certificate, skipping it");\r
-            continue;\r
-        }\r
-\r
-        log.debug("checking if certificates contained within key information match end-entity certificate");\r
-        if (resolvedCerts.v().front()->getProviderName()!=DSIGConstants::s_unicodeStrPROVOpenSSL) {\r
-            log.error("only the OpenSSL XSEC provider is supported");\r
-            continue;\r
-        }\r
-        else if (!X509_cmp(static_cast<OpenSSLCryptoX509*>(certEE)->getOpenSSLX509(),static_cast<OpenSSLCryptoX509*>(resolvedCerts.v().front())->getOpenSSLX509())) {\r
-            log.info("end-entity certificate matches certificate from peer key information");\r
-            return true;\r
-        }\r
-    }\r
-\r
-    log.debug("no certificates within this peer's key information matched the given end-entity certificate");\r
-    return false;\r
-}\r
+/*
+ *  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.
+ */
+
+/**
+ * ExplicitKeyTrustEngine.cpp
+ * 
+ * TrustEngine based on explicit knowledge of peer key information.
+ */
+
+#include "internal.h"
+#include "security/X509TrustEngine.h"
+#include "signature/SignatureValidator.h"
+#include "util/NDC.h"
+
+#include <log4cpp/Category.hh>
+#include <xercesc/util/XMLUniDefs.hpp>
+#include <xsec/enc/OpenSSL/OpenSSLCryptoX509.hpp>
+
+using namespace xmlsignature;
+using namespace xmltooling;
+using namespace log4cpp;
+using namespace std;
+
+namespace xmltooling {
+    class XMLTOOL_DLLLOCAL ExplicitKeyTrustEngine : public X509TrustEngine
+    {
+    public:
+        ExplicitKeyTrustEngine(const DOMElement* e) : X509TrustEngine(e) {}
+        virtual ~ExplicitKeyTrustEngine() {}
+
+        virtual bool validate(
+            Signature& sig,
+            TrustEngine::KeyInfoIterator& keyInfoSource,
+            const KeyResolver* keyResolver=NULL
+            ) const;
+        virtual bool validate(
+            XSECCryptoX509* certEE,
+            const vector<XSECCryptoX509*>& certChain,
+            TrustEngine::KeyInfoIterator& keyInfoSource,
+            bool checkName=true,
+            const KeyResolver* keyResolver=NULL
+            ) const;
+    };
+
+    TrustEngine* XMLTOOL_DLLLOCAL ExplicitKeyTrustEngineFactory(const DOMElement* const & e)
+    {
+        return new ExplicitKeyTrustEngine(e);
+    }
+};
+
+bool ExplicitKeyTrustEngine::validate(
+    Signature& sig,
+    TrustEngine::KeyInfoIterator& keyInfoSource,
+    const KeyResolver* keyResolver
+    ) const
+{
+#ifdef _DEBUG
+    NDC ndc("validate");
+#endif
+    Category& log=Category::getInstance(XMLTOOLING_LOGCAT".TrustEngine");
+    
+    if (!keyInfoSource.hasNext()) {
+        log.warn("unable to validate signature, no key information available for peer");
+        return false;
+    }
+    
+    log.debug("attempting to validate signature with the key information for peer");
+    SignatureValidator sigValidator;
+    while (keyInfoSource.hasNext()) {
+        XSECCryptoKey* key = (keyResolver ? keyResolver : m_keyResolver)->resolveKey(keyInfoSource.next());
+        if (key) {
+            log.debug("attempting to validate signature with public key...");
+            try {
+                sigValidator.setKey(key);   // key now owned by validator
+                sigValidator.validate(&sig);
+                log.info("signature validated with public key");
+                return true;
+            }
+            catch (ValidationException& e) {
+                if (log.isDebugEnabled()) {
+                    log.debug("public key did not validate signature: %s", e.what());
+                }
+            }
+        }
+        else {
+            log.debug("key information does not resolve to a public key, skipping it");
+        }
+    }
+
+    log.error("no peer key information validated the signature");
+    return false;
+}
+
+bool ExplicitKeyTrustEngine::validate(
+    XSECCryptoX509* certEE,
+    const vector<XSECCryptoX509*>& certChain,
+    TrustEngine::KeyInfoIterator& keyInfoSource,
+    bool checkName,
+    const KeyResolver* keyResolver
+    ) const
+{
+#ifdef _DEBUG
+    NDC ndc("validate");
+#endif
+    Category& log=Category::getInstance(XMLTOOLING_LOGCAT".TrustEngine");
+    
+    if (!certEE) {
+        log.error("unable to validate, end-entity certificate was null");
+        return false;
+    }
+    else if (certEE->getProviderName()!=DSIGConstants::s_unicodeStrPROVOpenSSL) {
+        log.error("only the OpenSSL XSEC provider is supported");
+        return false;
+    }
+    else if (!keyInfoSource.hasNext()) {
+        log.warn("unable to validate, no key information available for peer");
+        return false;
+    }
+
+    // The new "basic" trust implementation relies solely on certificates living within the
+    // role interface to verify the EE certificate.
+
+    log.debug("attempting to match key information from peer with end-entity certificate");
+    while (keyInfoSource.hasNext()) {
+        KeyResolver::ResolvedCertificates resolvedCerts;
+        if (0 == (keyResolver ? keyResolver : m_keyResolver)->resolveCertificates(keyInfoSource.next(),resolvedCerts)) {
+            log.debug("key information does not resolve to a certificate, skipping it");
+            continue;
+        }
+
+        log.debug("checking if certificates contained within key information match end-entity certificate");
+        if (resolvedCerts.v().front()->getProviderName()!=DSIGConstants::s_unicodeStrPROVOpenSSL) {
+            log.error("only the OpenSSL XSEC provider is supported");
+            continue;
+        }
+        else if (!X509_cmp(static_cast<OpenSSLCryptoX509*>(certEE)->getOpenSSLX509(),static_cast<OpenSSLCryptoX509*>(resolvedCerts.v().front())->getOpenSSLX509())) {
+            log.info("end-entity certificate matches certificate from peer key information");
+            return true;
+        }
+    }
+
+    log.debug("no certificates within this peer's key information matched the given end-entity certificate");
+    return false;
+}
index 245f76b..74dfd3e 100644 (file)
-/*\r
- * Copyright 2006 The Apache Software Foundation.\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * OpenSSLCryptoX509CRL.cpp\r
- * \r
- * OpenSSL-based class for handling X.509 CRLs\r
- */\r
-\r
-#include "internal.h"\r
-#include "security/OpenSSLCryptoX509CRL.h"\r
-\r
-#include <xsec/framework/XSECError.hpp>\r
-#include <xsec/enc/XSECCryptoException.hpp>\r
-#include <xsec/enc/XSCrypt/XSCryptCryptoBase64.hpp>\r
-\r
-#include <xercesc/util/Janitor.hpp>\r
-\r
-XSEC_USING_XERCES(ArrayJanitor);\r
-XSEC_USING_XERCES(Janitor);\r
-\r
-using namespace xmltooling;\r
-\r
-OpenSSLCryptoX509CRL::~OpenSSLCryptoX509CRL()\r
-{\r
-       if (mp_X509CRL)\r
-               X509_CRL_free(mp_X509CRL);\r
-}\r
-\r
-OpenSSLCryptoX509CRL::OpenSSLCryptoX509CRL(X509_CRL* x) {\r
-\r
-       // Build this from an existing X509_CRL structure\r
-\r
-       mp_X509CRL = X509_CRL_dup(x);\r
-       \r
-       // Now need to create the DER encoding\r
-\r
-       BIO* b64 = BIO_new(BIO_f_base64());\r
-       BIO* bmem = BIO_new(BIO_s_mem());\r
-\r
-       BIO_set_mem_eof_return(bmem, 0);\r
-       b64 = BIO_push(b64, bmem);\r
-\r
-       // Translate X509 to Base64\r
-\r
-       i2d_X509_CRL_bio(b64, x);\r
-\r
-       BIO_flush(b64);\r
-\r
-       char buf[1024];\r
-       unsigned int l;\r
-       \r
-       m_DERX509CRL.sbStrcpyIn("");\r
-\r
-       while ((l = BIO_read(bmem, buf, 1023)) > 0) {\r
-               buf[l] = '\0';\r
-               m_DERX509CRL.sbStrcatIn(buf);\r
-       }\r
-\r
-       BIO_free_all(b64);\r
-}\r
-\r
-void OpenSSLCryptoX509CRL::loadX509CRLBase64Bin(const char* buf, unsigned int len) {\r
-\r
-       // Free anything currently held.\r
-       \r
-       if (mp_X509CRL)\r
-               X509_CRL_free(mp_X509CRL);\r
-       \r
-       int bufLen = len;\r
-       unsigned char* outBuf;\r
-       XSECnew(outBuf, unsigned char[len + 1]);\r
-       ArrayJanitor<unsigned char> j_outBuf(outBuf);\r
-\r
-       XSCryptCryptoBase64 *b64;\r
-       XSECnew(b64, XSCryptCryptoBase64);\r
-       Janitor<XSCryptCryptoBase64> j_b64(b64);\r
-\r
-       b64->decodeInit();\r
-       bufLen = b64->decode((unsigned char *) buf, len, outBuf, len);\r
-       bufLen += b64->decodeFinish(&outBuf[bufLen], len-bufLen);\r
-\r
-       if (bufLen > 0) {\r
-#if defined(XSEC_OPENSSL_D2IX509_CONST_BUFFER)\r
-               mp_X509CRL=  d2i_X509_CRL(NULL, (const unsigned char **) (&outBuf), bufLen);\r
-#else\r
-               mp_X509CRL=  d2i_X509_CRL(NULL, &outBuf, bufLen);\r
-#endif\r
-       }\r
-\r
-       // Check to see if we have a CRL....\r
-       if (mp_X509CRL == NULL) {\r
-               throw XSECCryptoException(XSECCryptoException::X509Error,\r
-               "OpenSSL:X509CRL - Error translating Base64 DER encoding into OpenSSL X509 CRL structure");\r
-       }\r
-\r
-       m_DERX509CRL.sbStrcpyIn(buf);\r
-\r
-}\r
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * 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.
+ */
+
+/**
+ * OpenSSLCryptoX509CRL.cpp
+ * 
+ * OpenSSL-based class for handling X.509 CRLs
+ */
+
+#include "internal.h"
+#include "security/OpenSSLCryptoX509CRL.h"
+
+#include <xsec/framework/XSECError.hpp>
+#include <xsec/enc/XSECCryptoException.hpp>
+#include <xsec/enc/XSCrypt/XSCryptCryptoBase64.hpp>
+
+#include <xercesc/util/Janitor.hpp>
+
+XSEC_USING_XERCES(ArrayJanitor);
+XSEC_USING_XERCES(Janitor);
+
+using namespace xmltooling;
+
+OpenSSLCryptoX509CRL::~OpenSSLCryptoX509CRL()
+{
+       if (mp_X509CRL)
+               X509_CRL_free(mp_X509CRL);
+}
+
+OpenSSLCryptoX509CRL::OpenSSLCryptoX509CRL(X509_CRL* x) {
+
+       // Build this from an existing X509_CRL structure
+
+       mp_X509CRL = X509_CRL_dup(x);
+       
+       // Now need to create the DER encoding
+
+       BIO* b64 = BIO_new(BIO_f_base64());
+       BIO* bmem = BIO_new(BIO_s_mem());
+
+       BIO_set_mem_eof_return(bmem, 0);
+       b64 = BIO_push(b64, bmem);
+
+       // Translate X509 to Base64
+
+       i2d_X509_CRL_bio(b64, x);
+
+       BIO_flush(b64);
+
+       char buf[1024];
+       unsigned int l;
+       
+       m_DERX509CRL.sbStrcpyIn("");
+
+       while ((l = BIO_read(bmem, buf, 1023)) > 0) {
+               buf[l] = '\0';
+               m_DERX509CRL.sbStrcatIn(buf);
+       }
+
+       BIO_free_all(b64);
+}
+
+void OpenSSLCryptoX509CRL::loadX509CRLBase64Bin(const char* buf, unsigned int len) {
+
+       // Free anything currently held.
+       
+       if (mp_X509CRL)
+               X509_CRL_free(mp_X509CRL);
+       
+       int bufLen = len;
+       unsigned char* outBuf;
+       XSECnew(outBuf, unsigned char[len + 1]);
+       ArrayJanitor<unsigned char> j_outBuf(outBuf);
+
+       XSCryptCryptoBase64 *b64;
+       XSECnew(b64, XSCryptCryptoBase64);
+       Janitor<XSCryptCryptoBase64> j_b64(b64);
+
+       b64->decodeInit();
+       bufLen = b64->decode((unsigned char *) buf, len, outBuf, len);
+       bufLen += b64->decodeFinish(&outBuf[bufLen], len-bufLen);
+
+       if (bufLen > 0) {
+#if defined(XSEC_OPENSSL_D2IX509_CONST_BUFFER)
+               mp_X509CRL=  d2i_X509_CRL(NULL, (const unsigned char **) (&outBuf), bufLen);
+#else
+               mp_X509CRL=  d2i_X509_CRL(NULL, &outBuf, bufLen);
+#endif
+       }
+
+       // Check to see if we have a CRL....
+       if (mp_X509CRL == NULL) {
+               throw XSECCryptoException(XSECCryptoException::X509Error,
+               "OpenSSL:X509CRL - Error translating Base64 DER encoding into OpenSSL X509 CRL structure");
+       }
+
+       m_DERX509CRL.sbStrcpyIn(buf);
+
+}
index 0c8eea8..e009f58 100644 (file)
@@ -1,86 +1,86 @@
-/*\r
- * Copyright 2006 The Apache Software Foundation.\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * XSECCryptoX509CRL.cpp\r
- * \r
- * Wrapper for X.509 CRL objects, similar to existing XSEC wrappers.\r
- */\r
-\r
-#include "internal.h"\r
-#include "security/XSECCryptoX509CRL.h"\r
-\r
-#include <xsec/framework/XSECError.hpp>\r
-#include <xsec/enc/XSECCryptoException.hpp>\r
-\r
-using namespace xmltooling;\r
-\r
-void XSECCryptoX509CRL::loadX509CRLPEM(const char* buf, unsigned int len)\r
-{\r
-       const char * b;\r
-       char * b1 = NULL;\r
-       if (len == 0)\r
-               b = buf;\r
-       else {\r
-               XSECnew(b1, char[len+1]);\r
-               memcpy(b1, buf, len);\r
-               b1[len] = '\0';\r
-               b = b1;\r
-       }\r
-\r
-       const char *p = strstr(buf, "-----BEGIN X509 CRL-----");\r
-\r
-       if (p == NULL) {\r
-\r
-               if (b1 != NULL)\r
-                       delete[] b1;\r
-\r
-               throw XSECCryptoException(XSECCryptoException::X509Error,\r
-               "X509CRL::loadX509CRLPEM - Cannot find start of PEM CRL");\r
-\r
-       }\r
-\r
-       p += strlen("-----BEGIN X509 CRL-----");\r
-\r
-       while (*p == '\n' || *p == '\r' || *p == '-')\r
-               p++;\r
-\r
-       safeBuffer output;\r
-       int i = 0;\r
-       while (*p != '\0' && *p != '-') {\r
-               output[i++] = *p;\r
-               ++p;\r
-       }\r
-\r
-       if (strstr(p, "-----END X509 CRL-----") != p) {\r
-\r
-               if (b1 != NULL)\r
-                       delete[] b1;\r
-\r
-               throw XSECCryptoException(XSECCryptoException::X509Error,\r
-               "X509CRL::loadX509PEMCRL - Cannot find end of PEM certificate");\r
-\r
-       }\r
-       \r
-       if (b1 != NULL)\r
-               delete[] b1;\r
-\r
-       output[i] = '\0';\r
-\r
-       this->loadX509CRLBase64Bin(output.rawCharBuffer(), i);\r
-\r
-}\r
-\r
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * 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.
+ */
+
+/**
+ * XSECCryptoX509CRL.cpp
+ * 
+ * Wrapper for X.509 CRL objects, similar to existing XSEC wrappers.
+ */
+
+#include "internal.h"
+#include "security/XSECCryptoX509CRL.h"
+
+#include <xsec/framework/XSECError.hpp>
+#include <xsec/enc/XSECCryptoException.hpp>
+
+using namespace xmltooling;
+
+void XSECCryptoX509CRL::loadX509CRLPEM(const char* buf, unsigned int len)
+{
+       const char * b;
+       char * b1 = NULL;
+       if (len == 0)
+               b = buf;
+       else {
+               XSECnew(b1, char[len+1]);
+               memcpy(b1, buf, len);
+               b1[len] = '\0';
+               b = b1;
+       }
+
+       const char *p = strstr(buf, "-----BEGIN X509 CRL-----");
+
+       if (p == NULL) {
+
+               if (b1 != NULL)
+                       delete[] b1;
+
+               throw XSECCryptoException(XSECCryptoException::X509Error,
+               "X509CRL::loadX509CRLPEM - Cannot find start of PEM CRL");
+
+       }
+
+       p += strlen("-----BEGIN X509 CRL-----");
+
+       while (*p == '\n' || *p == '\r' || *p == '-')
+               p++;
+
+       safeBuffer output;
+       int i = 0;
+       while (*p != '\0' && *p != '-') {
+               output[i++] = *p;
+               ++p;
+       }
+
+       if (strstr(p, "-----END X509 CRL-----") != p) {
+
+               if (b1 != NULL)
+                       delete[] b1;
+
+               throw XSECCryptoException(XSECCryptoException::X509Error,
+               "X509CRL::loadX509PEMCRL - Cannot find end of PEM certificate");
+
+       }
+       
+       if (b1 != NULL)
+               delete[] b1;
+
+       output[i] = '\0';
+
+       this->loadX509CRLBase64Bin(output.rawCharBuffer(), i);
+
+}
+
index 361a397..dec9b02 100644 (file)
@@ -1,45 +1,45 @@
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file xmltooling/signature/CachingKeyResolver.h\r
- * \r
- * A KeyResolver that caches content across method calls.\r
- */\r
-\r
-#if !defined(__xmltooling_cachekeyres_h__) && !defined(XMLTOOLING_NO_XMLSEC)\r
-#define __xmltooling_cachekeyres_h__\r
-\r
-#include <xmltooling/signature/KeyResolver.h>\r
-\r
-namespace xmlsignature {\r
-\r
-    /**\r
-     * An API for resolving encrypted decryption keys.\r
-     */\r
-    class XMLTOOL_API CachingKeyResolver : public xmlsignature::KeyResolver {\r
-    public:\r
-        virtual ~CachingKeyResolver() {}\r
-        \r
-        /**\r
-         * Clears any cache state.\r
-         */\r
-        virtual void clearCache()=0;\r
-    };\r
-\r
-};\r
-\r
-#endif /* __xmltooling_cachekeyres_h__ */\r
+/*
+ *  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.
+ */
+
+/**
+ * @file xmltooling/signature/CachingKeyResolver.h
+ * 
+ * A KeyResolver that caches content across method calls.
+ */
+
+#if !defined(__xmltooling_cachekeyres_h__) && !defined(XMLTOOLING_NO_XMLSEC)
+#define __xmltooling_cachekeyres_h__
+
+#include <xmltooling/signature/KeyResolver.h>
+
+namespace xmlsignature {
+
+    /**
+     * An API for resolving encrypted decryption keys.
+     */
+    class XMLTOOL_API CachingKeyResolver : public xmlsignature::KeyResolver {
+    public:
+        virtual ~CachingKeyResolver() {}
+        
+        /**
+         * Clears any cache state.
+         */
+        virtual void clearCache()=0;
+    };
+
+};
+
+#endif /* __xmltooling_cachekeyres_h__ */
index 672dbea..6a83175 100644 (file)
@@ -1,62 +1,62 @@
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file ContentReference.h\r
- * \r
- * Interface for creating signature references \r
- */\r
-\r
-#if !defined(__xmltooling_sigref_h__) && !defined(XMLTOOLING_NO_XMLSEC)\r
-#define __xmltooling_sigref_h__\r
-\r
-#include <vector>\r
-#include <xsec/dsig/DSIGSignature.hpp>\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( push )\r
-    #pragma warning( disable : 4250 4251 )\r
-#endif\r
-\r
-namespace xmlsignature {\r
-\r
-    /**\r
-     * Interface for creating signature references based on application requirements.\r
-     */\r
-    class XMLTOOL_API ContentReference\r
-    {\r
-        MAKE_NONCOPYABLE(ContentReference);\r
-    public:\r
-        virtual ~ContentReference() {}\r
-\r
-        /**\r
-         * Given a native signature, asks the object to create the reference(s).\r
-         * \r
-         * @param sig   native signature interface\r
-         */\r
-        virtual void createReferences(DSIGSignature* sig)=0;\r
-        \r
-    protected:\r
-        ContentReference() {}\r
-    };\r
-\r
-};\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( pop )\r
-#endif\r
-\r
-#endif /* __xmltooling_sigref_h__ */\r
+/*
+ *  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.
+ */
+
+/**
+ * @file ContentReference.h
+ * 
+ * Interface for creating signature references 
+ */
+
+#if !defined(__xmltooling_sigref_h__) && !defined(XMLTOOLING_NO_XMLSEC)
+#define __xmltooling_sigref_h__
+
+#include <vector>
+#include <xsec/dsig/DSIGSignature.hpp>
+
+#if defined (_MSC_VER)
+    #pragma warning( push )
+    #pragma warning( disable : 4250 4251 )
+#endif
+
+namespace xmlsignature {
+
+    /**
+     * Interface for creating signature references based on application requirements.
+     */
+    class XMLTOOL_API ContentReference
+    {
+        MAKE_NONCOPYABLE(ContentReference);
+    public:
+        virtual ~ContentReference() {}
+
+        /**
+         * Given a native signature, asks the object to create the reference(s).
+         * 
+         * @param sig   native signature interface
+         */
+        virtual void createReferences(DSIGSignature* sig)=0;
+        
+    protected:
+        ContentReference() {}
+    };
+
+};
+
+#if defined (_MSC_VER)
+    #pragma warning( pop )
+#endif
+
+#endif /* __xmltooling_sigref_h__ */
index f955f37..cb42fc8 100644 (file)
@@ -1,72 +1,72 @@
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file xmltooling/signature/CredentialResolver.h\r
- * \r
- * Resolves keys and certificates "owned" by an entity \r
- */\r
-\r
-#if !defined(__xmltooling_credres_h__) && !defined(XMLTOOLING_NO_XMLSEC)\r
-#define __xmltooling_credres_h__\r
-\r
-#include <xmltooling/Lockable.h>\r
-\r
-#include <vector>\r
-#include <xsec/enc/XSECCryptoKey.hpp>\r
-#include <xsec/enc/XSECCryptoX509.hpp>\r
-\r
-namespace xmlsignature {\r
-\r
-    /**\r
-     * An API for resolving local/owned keys and certificates\r
-     */\r
-    class XMLTOOL_API CredentialResolver : public xmltooling::Lockable\r
-    {\r
-        MAKE_NONCOPYABLE(CredentialResolver);\r
-    protected:\r
-        CredentialResolver() {}\r
-        \r
-    public:\r
-        virtual ~CredentialResolver() {}\r
-        \r
-        /**\r
-         * Returns a secret or private key to use for signing operations.\r
-         * The caller is responsible for deleting the key when finished with it.\r
-         * \r
-         * @return  a secret or private key\r
-         */\r
-        virtual XSECCryptoKey* getKey() const=0;\r
-        \r
-        /**\r
-         * Returns a set of certificates to publish during signing operations.\r
-         * The certificates must be cloned if kept beyond the scope of a lock.\r
-         * \r
-         * @return  a set of certificates\r
-         */\r
-        virtual const std::vector<XSECCryptoX509*>& getCertificates() const=0;\r
-    };\r
-\r
-    /**\r
-     * Registers CredentialResolver classes into the runtime.\r
-     */\r
-    void XMLTOOL_API registerCredentialResolvers();\r
-\r
-    /** CredentialResolver based on local files */\r
-    #define FILESYSTEM_CREDENTIAL_RESOLVER  "org.opensaml.xmlooling.FilesystemCredentialResolver"\r
-};\r
-\r
-#endif /* __xmltooling_credres_h__ */\r
+/*
+ *  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.
+ */
+
+/**
+ * @file xmltooling/signature/CredentialResolver.h
+ * 
+ * Resolves keys and certificates "owned" by an entity 
+ */
+
+#if !defined(__xmltooling_credres_h__) && !defined(XMLTOOLING_NO_XMLSEC)
+#define __xmltooling_credres_h__
+
+#include <xmltooling/Lockable.h>
+
+#include <vector>
+#include <xsec/enc/XSECCryptoKey.hpp>
+#include <xsec/enc/XSECCryptoX509.hpp>
+
+namespace xmlsignature {
+
+    /**
+     * An API for resolving local/owned keys and certificates
+     */
+    class XMLTOOL_API CredentialResolver : public xmltooling::Lockable
+    {
+        MAKE_NONCOPYABLE(CredentialResolver);
+    protected:
+        CredentialResolver() {}
+        
+    public:
+        virtual ~CredentialResolver() {}
+        
+        /**
+         * Returns a secret or private key to use for signing operations.
+         * The caller is responsible for deleting the key when finished with it.
+         * 
+         * @return  a secret or private key
+         */
+        virtual XSECCryptoKey* getKey() const=0;
+        
+        /**
+         * Returns a set of certificates to publish during signing operations.
+         * The certificates must be cloned if kept beyond the scope of a lock.
+         * 
+         * @return  a set of certificates
+         */
+        virtual const std::vector<XSECCryptoX509*>& getCertificates() const=0;
+    };
+
+    /**
+     * Registers CredentialResolver classes into the runtime.
+     */
+    void XMLTOOL_API registerCredentialResolvers();
+
+    /** CredentialResolver based on local files */
+    #define FILESYSTEM_CREDENTIAL_RESOLVER  "org.opensaml.xmlooling.FilesystemCredentialResolver"
+};
+
+#endif /* __xmltooling_credres_h__ */
index 9270b1f..2e04dc4 100644 (file)
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file KeyResolver.h\r
- * \r
- * Resolves public keys and certificates based on KeyInfo information or\r
- * external factors. \r
- */\r
-\r
-#if !defined(__xmltooling_keyres_h__) && !defined(XMLTOOLING_NO_XMLSEC)\r
-#define __xmltooling_keyres_h__\r
-\r
-#include <xmltooling/security/XSECCryptoX509CRL.h>\r
-\r
-#include <xsec/dsig/DSIGKeyInfoList.hpp>\r
-#include <xsec/enc/XSECCryptoKey.hpp>\r
-#include <xsec/enc/XSECCryptoX509.hpp>\r
-\r
-#include <algorithm>\r
-#include <vector>\r
-\r
-namespace xmlsignature {\r
-    class XMLTOOL_API KeyInfo;\r
-    class XMLTOOL_API Signature;\r
-\r
-    /**\r
-     * An API for resolving keys. The default/simple implementation\r
-     * allows a hard-wired key to be supplied. This is mostly\r
-     * useful for testing, or to adapt another mechanism for supplying\r
-     * keys to this interface.\r
-     */\r
-    class XMLTOOL_API KeyResolver {\r
-        MAKE_NONCOPYABLE(KeyResolver);\r
-    public:\r
-        /**\r
-         * Constructor based on a single externally supplied key.\r
-         * The key will be destroyed when the resolver is. \r
-         * \r
-         * @param key   external key\r
-         */\r
-        KeyResolver(XSECCryptoKey* key=NULL) : m_key(key) {}\r
-        \r
-        virtual ~KeyResolver() {\r
-            delete m_key;\r
-        }\r
-        \r
-        /**\r
-         * Returns a key based on the supplied KeyInfo information.\r
-         * The caller must delete the key when done with it.\r
-         * \r
-         * @param keyInfo   the key information\r
-         * @return  the resolved key\r
-         */\r
-        virtual XSECCryptoKey* resolveKey(const KeyInfo* keyInfo) const {\r
-            return m_key ? m_key->clone() : NULL;\r
-        }\r
-\r
-        /**\r
-         * Returns a key based on the supplied KeyInfo information.\r
-         * The caller must delete the key when done with it.\r
-         * \r
-         * @param keyInfo   the key information\r
-         * @return  the resolved key\r
-         */\r
-        virtual XSECCryptoKey* resolveKey(DSIGKeyInfoList* keyInfo) const {\r
-            return m_key ? m_key->clone() : NULL;\r
-        }\r
-\r
-        /**\r
-         * Returns a key based on the supplied KeyInfo information.\r
-         * The caller must delete the key when done with it.\r
-         * \r
-         * @param sig   signature containing the key information\r
-         * @return  the resolved key\r
-         */\r
-        XSECCryptoKey* resolveKey(const Signature* sig) const;\r
-\r
-        /**\r
-         * A wrapper that handles disposal of certificates when required.\r
-         */\r
-        class XMLTOOL_API ResolvedCertificates {\r
-            MAKE_NONCOPYABLE(ResolvedCertificates);\r
-            bool m_owned;\r
-            std::vector<XSECCryptoX509*> m_certs;\r
-        public:\r
-            ResolvedCertificates() : m_owned(false) {}\r
-            ~ResolvedCertificates() {\r
-                if (m_owned) {\r
-                    std::for_each(m_certs.begin(), m_certs.end(), xmltooling::cleanup<XSECCryptoX509>());\r
-                }\r
-            }\r
-            const std::vector<XSECCryptoX509*>& v() const {\r
-                return m_certs;\r
-            }\r
-            friend class XMLTOOL_API KeyResolver;\r
-        };\r
-\r
-        /**\r
-         * Returns a set of certificates based on the supplied KeyInfo information.\r
-         * The certificates must be cloned if kept beyond the lifetime of the KeyInfo source.\r
-         * \r
-         * @param keyInfo   the key information\r
-         * @param certs     reference to object to hold certificates\r
-         * @return  number of certificates returned\r
-         */\r
-        virtual std::vector<XSECCryptoX509*>::size_type resolveCertificates(\r
-            const KeyInfo* keyInfo, ResolvedCertificates& certs\r
-            ) const;\r
-        \r
-        /**\r
-         * Returns a set of certificates based on the supplied KeyInfo information.\r
-         * The certificates must be cloned if kept beyond the lifetime of the KeyInfo source.\r
-         * \r
-         * @param keyInfo   the key information\r
-         * @param certs     reference to object to hold certificates\r
-         * @return  number of certificates returned\r
-         */\r
-        virtual std::vector<XSECCryptoX509*>::size_type resolveCertificates(\r
-            DSIGKeyInfoList* keyInfo, ResolvedCertificates& certs \r
-            ) const;\r
-\r
-        /**\r
-         * Returns a set of certificates based on the supplied KeyInfo information.\r
-         * The certificates must be cloned if kept beyond the lifetime of the KeyInfo source.\r
-         * \r
-         * @param sig   signature containing the key information\r
-         * @param certs     reference to object to hold certificates\r
-         * @return  number of certificates returned\r
-         */\r
-        std::vector<XSECCryptoX509*>::size_type resolveCertificates(\r
-            const Signature* sig, ResolvedCertificates& certs\r
-            ) const;\r
-\r
-        /**\r
-         * Returns a CRL based on the supplied KeyInfo information.\r
-         * The caller must delete the CRL when done with it.\r
-         * \r
-         * @param keyInfo   the key information\r
-         * @return  the resolved CRL\r
-         */\r
-        virtual xmltooling::XSECCryptoX509CRL* resolveCRL(const KeyInfo* keyInfo) const;\r
-        \r
-        /**\r
-         * Returns a CRL based on the supplied KeyInfo information.\r
-         * The caller must delete the CRL when done with it.\r
-         * \r
-         * @param keyInfo   the key information\r
-         * @return  the resolved CRL\r
-         */\r
-        virtual xmltooling::XSECCryptoX509CRL* resolveCRL(DSIGKeyInfoList* keyInfo) const;\r
-\r
-        /**\r
-         * Returns a CRL based on the supplied KeyInfo information.\r
-         * The caller must delete the CRL when done with it.\r
-         * \r
-         * @param sig   signature containing the key information\r
-         * @return  the resolved CRL\r
-         */\r
-        xmltooling::XSECCryptoX509CRL* resolveCRL(const Signature* sig) const;\r
-\r
-    protected:\r
-        XSECCryptoKey* m_key;\r
-\r
-        /**\r
-         * Accessor for certificate vector from derived KeyResolver classes.\r
-         *\r
-         * @param certs certificate wrapper to access\r
-         * @return modifiable reference to vector inside wrapper\r
-         */\r
-        std::vector<XSECCryptoX509*>& accessCertificates(ResolvedCertificates& certs) const {\r
-            return certs.m_certs;\r
-        }\r
-\r
-        /**\r
-         * Accessor for certificate ownership flag from derived KeyResolver classes.\r
-         *\r
-         * @param certs certificate wrapper to access\r
-         * @return modifiable reference to ownership flag inside wrapper\r
-         */\r
-        bool& accessOwned(ResolvedCertificates& certs) const {\r
-            return certs.m_owned;\r
-        }\r
-    };\r
-\r
-    /**\r
-     * Registers KeyResolver classes into the runtime.\r
-     */\r
-    void XMLTOOL_API registerKeyResolvers();\r
-\r
-    /** KeyResolver based on hard-wired key */\r
-    #define FILESYSTEM_KEY_RESOLVER  "org.opensaml.xmlooling.FilesystemKeyResolver"\r
-\r
-    /** KeyResolver based on extracting information directly out of a KeyInfo */\r
-    #define INLINE_KEY_RESOLVER  "org.opensaml.xmlooling.InlineKeyResolver"\r
-};\r
-\r
-#endif /* __xmltooling_keyres_h__ */\r
+/*
+ *  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.
+ */
+
+/**
+ * @file KeyResolver.h
+ * 
+ * Resolves public keys and certificates based on KeyInfo information or
+ * external factors. 
+ */
+
+#if !defined(__xmltooling_keyres_h__) && !defined(XMLTOOLING_NO_XMLSEC)
+#define __xmltooling_keyres_h__
+
+#include <xmltooling/security/XSECCryptoX509CRL.h>
+
+#include <xsec/dsig/DSIGKeyInfoList.hpp>
+#include <xsec/enc/XSECCryptoKey.hpp>
+#include <xsec/enc/XSECCryptoX509.hpp>
+
+#include <algorithm>
+#include <vector>
+
+namespace xmlsignature {
+    class XMLTOOL_API KeyInfo;
+    class XMLTOOL_API Signature;
+
+    /**
+     * An API for resolving keys. The default/simple implementation
+     * allows a hard-wired key to be supplied. This is mostly
+     * useful for testing, or to adapt another mechanism for supplying
+     * keys to this interface.
+     */
+    class XMLTOOL_API KeyResolver {
+        MAKE_NONCOPYABLE(KeyResolver);
+    public:
+        /**
+         * Constructor based on a single externally supplied key.
+         * The key will be destroyed when the resolver is. 
+         * 
+         * @param key   external key
+         */
+        KeyResolver(XSECCryptoKey* key=NULL) : m_key(key) {}
+        
+        virtual ~KeyResolver() {
+            delete m_key;
+        }
+        
+        /**
+         * Returns a key based on the supplied KeyInfo information.
+         * The caller must delete the key when done with it.
+         * 
+         * @param keyInfo   the key information
+         * @return  the resolved key
+         */
+        virtual XSECCryptoKey* resolveKey(const KeyInfo* keyInfo) const {
+            return m_key ? m_key->clone() : NULL;
+        }
+
+        /**
+         * Returns a key based on the supplied KeyInfo information.
+         * The caller must delete the key when done with it.
+         * 
+         * @param keyInfo   the key information
+         * @return  the resolved key
+         */
+        virtual XSECCryptoKey* resolveKey(DSIGKeyInfoList* keyInfo) const {
+            return m_key ? m_key->clone() : NULL;
+        }
+
+        /**
+         * Returns a key based on the supplied KeyInfo information.
+         * The caller must delete the key when done with it.
+         * 
+         * @param sig   signature containing the key information
+         * @return  the resolved key
+         */
+        XSECCryptoKey* resolveKey(const Signature* sig) const;
+
+        /**
+         * A wrapper that handles disposal of certificates when required.
+         */
+        class XMLTOOL_API ResolvedCertificates {
+            MAKE_NONCOPYABLE(ResolvedCertificates);
+            bool m_owned;
+            std::vector<XSECCryptoX509*> m_certs;
+        public:
+            ResolvedCertificates() : m_owned(false) {}
+            ~ResolvedCertificates() {
+                if (m_owned) {
+                    std::for_each(m_certs.begin(), m_certs.end(), xmltooling::cleanup<XSECCryptoX509>());
+                }
+            }
+            const std::vector<XSECCryptoX509*>& v() const {
+                return m_certs;
+            }
+            friend class XMLTOOL_API KeyResolver;
+        };
+
+        /**
+         * Returns a set of certificates based on the supplied KeyInfo information.
+         * The certificates must be cloned if kept beyond the lifetime of the KeyInfo source.
+         * 
+         * @param keyInfo   the key information
+         * @param certs     reference to object to hold certificates
+         * @return  number of certificates returned
+         */
+        virtual std::vector<XSECCryptoX509*>::size_type resolveCertificates(
+            const KeyInfo* keyInfo, ResolvedCertificates& certs
+            ) const;
+        
+        /**
+         * Returns a set of certificates based on the supplied KeyInfo information.
+         * The certificates must be cloned if kept beyond the lifetime of the KeyInfo source.
+         * 
+         * @param keyInfo   the key information
+         * @param certs     reference to object to hold certificates
+         * @return  number of certificates returned
+         */
+        virtual std::vector<XSECCryptoX509*>::size_type resolveCertificates(
+            DSIGKeyInfoList* keyInfo, ResolvedCertificates& certs 
+            ) const;
+
+        /**
+         * Returns a set of certificates based on the supplied KeyInfo information.
+         * The certificates must be cloned if kept beyond the lifetime of the KeyInfo source.
+         * 
+         * @param sig   signature containing the key information
+         * @param certs     reference to object to hold certificates
+         * @return  number of certificates returned
+         */
+        std::vector<XSECCryptoX509*>::size_type resolveCertificates(
+            const Signature* sig, ResolvedCertificates& certs
+            ) const;
+
+        /**
+         * Returns a CRL based on the supplied KeyInfo information.
+         * The caller must delete the CRL when done with it.
+         * 
+         * @param keyInfo   the key information
+         * @return  the resolved CRL
+         */
+        virtual xmltooling::XSECCryptoX509CRL* resolveCRL(const KeyInfo* keyInfo) const;
+        
+        /**
+         * Returns a CRL based on the supplied KeyInfo information.
+         * The caller must delete the CRL when done with it.
+         * 
+         * @param keyInfo   the key information
+         * @return  the resolved CRL
+         */
+        virtual xmltooling::XSECCryptoX509CRL* resolveCRL(DSIGKeyInfoList* keyInfo) const;
+
+        /**
+         * Returns a CRL based on the supplied KeyInfo information.
+         * The caller must delete the CRL when done with it.
+         * 
+         * @param sig   signature containing the key information
+         * @return  the resolved CRL
+         */
+        xmltooling::XSECCryptoX509CRL* resolveCRL(const Signature* sig) const;
+
+    protected:
+        XSECCryptoKey* m_key;
+
+        /**
+         * Accessor for certificate vector from derived KeyResolver classes.
+         *
+         * @param certs certificate wrapper to access
+         * @return modifiable reference to vector inside wrapper
+         */
+        std::vector<XSECCryptoX509*>& accessCertificates(ResolvedCertificates& certs) const {
+            return certs.m_certs;
+        }
+
+        /**
+         * Accessor for certificate ownership flag from derived KeyResolver classes.
+         *
+         * @param certs certificate wrapper to access
+         * @return modifiable reference to ownership flag inside wrapper
+         */
+        bool& accessOwned(ResolvedCertificates& certs) const {
+            return certs.m_owned;
+        }
+    };
+
+    /**
+     * Registers KeyResolver classes into the runtime.
+     */
+    void XMLTOOL_API registerKeyResolvers();
+
+    /** KeyResolver based on hard-wired key */
+    #define FILESYSTEM_KEY_RESOLVER  "org.opensaml.xmlooling.FilesystemKeyResolver"
+
+    /** KeyResolver based on extracting information directly out of a KeyInfo */
+    #define INLINE_KEY_RESOLVER  "org.opensaml.xmlooling.InlineKeyResolver"
+};
+
+#endif /* __xmltooling_keyres_h__ */
index e119380..77c2b95 100644 (file)
@@ -1,54 +1,54 @@
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file xmltooling/signature/OpenSSLCredentialResolver.h\r
- * \r
- * OpenSSL-specific credential resolver\r
- */\r
-\r
-#if !defined(__xmltooling_opensslcredres_h__) && !defined(XMLTOOLING_NO_XMLSEC)\r
-#define __xmltooling_opensslcredres_h__\r
-\r
-#include <xmltooling/signature/CredentialResolver.h>\r
-\r
-#include <openssl/ssl.h>\r
-\r
-namespace xmlsignature {\r
-\r
-    /**\r
-     * An OpenSSL-specific API for resolving local/owned keys and certificates\r
-     */\r
-    class XMLTOOL_API OpenSSLCredentialResolver : public CredentialResolver\r
-    {\r
-    protected:\r
-        OpenSSLCredentialResolver() {}\r
-        \r
-    public:\r
-        virtual ~OpenSSLCredentialResolver() {}\r
-        \r
-        /**\r
-         * Attaches credentials to an OpenSSL SSL context object.\r
-         * The resolver is unlockable after attachment.\r
-         * \r
-         * @param ctx   an SSL context\r
-         */\r
-        virtual void attach(SSL_CTX* ctx) const=0;\r
-    };\r
-\r
-};\r
-\r
-#endif /* __xmltooling_opensslcredres_h__ */\r
+/*
+ *  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.
+ */
+
+/**
+ * @file xmltooling/signature/OpenSSLCredentialResolver.h
+ * 
+ * OpenSSL-specific credential resolver
+ */
+
+#if !defined(__xmltooling_opensslcredres_h__) && !defined(XMLTOOLING_NO_XMLSEC)
+#define __xmltooling_opensslcredres_h__
+
+#include <xmltooling/signature/CredentialResolver.h>
+
+#include <openssl/ssl.h>
+
+namespace xmlsignature {
+
+    /**
+     * An OpenSSL-specific API for resolving local/owned keys and certificates
+     */
+    class XMLTOOL_API OpenSSLCredentialResolver : public CredentialResolver
+    {
+    protected:
+        OpenSSLCredentialResolver() {}
+        
+    public:
+        virtual ~OpenSSLCredentialResolver() {}
+        
+        /**
+         * Attaches credentials to an OpenSSL SSL context object.
+         * The resolver is unlockable after attachment.
+         * 
+         * @param ctx   an SSL context
+         */
+        virtual void attach(SSL_CTX* ctx) const=0;
+    };
+
+};
+
+#endif /* __xmltooling_opensslcredres_h__ */
index 6ccc49c..71314ac 100644 (file)
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file Signature.h\r
- * \r
- * XMLObject representing XML Digital Signature, version 20020212, Signature element. \r
- */\r
-\r
-#if !defined(__xmltooling_sig_h__) && !defined(XMLTOOLING_NO_XMLSEC)\r
-#define __xmltooling_sig_h__\r
-\r
-#include <xmltooling/exceptions.h>\r
-#include <xmltooling/XMLObjectBuilder.h>\r
-#include <xmltooling/signature/ContentReference.h>\r
-#include <xmltooling/util/XMLConstants.h>\r
-\r
-#include <xsec/dsig/DSIGSignature.hpp>\r
-\r
-/**\r
- * @namespace xmlsignature\r
- * Public namespace of XML Signature classes\r
- */\r
-namespace xmlsignature {\r
-\r
-    class XMLTOOL_API KeyInfo;\r
-\r
-    /**\r
-     * XMLObject representing XML Digital Signature, version 20020212, Signature element.\r
-     * The default signature settings include Exclusive c14n w/o comments, SHA-1 digests,\r
-     * and RSA-SHA1 signing. \r
-     */\r
-    class XMLTOOL_API Signature : public virtual xmltooling::XMLObject\r
-    {\r
-    public:\r
-        virtual ~Signature() {}\r
-\r
-        /** Element local name */\r
-        static const XMLCh LOCAL_NAME[];\r
-\r
-        /**\r
-         * Sets the canonicalization method for the ds:SignedInfo element\r
-         * \r
-         * @param c14n  the canonicalization method\r
-         */\r
-        virtual void setCanonicalizationMethod(const XMLCh* c14n)=0;\r
-        \r
-        /**\r
-         * Sets the signing algorithm for the signature.\r
-         * \r
-         * @param sm    the signature algorithm\r
-         */\r
-        virtual void setSignatureAlgorithm(const XMLCh* sm)=0;\r
-\r
-        /**\r
-         * Sets the signing key used to create the signature.\r
-         * \r
-         * @param signingKey the secret/private key used to create the signature\r
-         */\r
-        virtual void setSigningKey(XSECCryptoKey* signingKey)=0;\r
-\r
-        /**\r
-         * Sets a KeyInfo object to embed in the Signature.\r
-         * \r
-         * @param keyInfo   pointer to a KeyInfo object, or NULL\r
-         */\r
-        virtual void setKeyInfo(KeyInfo* keyInfo)=0;\r
-\r
-        /**\r
-         * Gets the KeyInfo object associated with the Signature.\r
-         * This is <strong>NOT</strong> provided for access to the\r
-         * data associated with an unmarshalled signature. It is\r
-         * used only in the creation of signatures. Access to data\r
-         * for validation purposes is provided through the native\r
-         * DSIGSignature object.\r
-         * \r
-         * @return  pointer to a KeyInfo object, or NULL\r
-         */\r
-        virtual KeyInfo* getKeyInfo() const=0;\r
-\r
-        /**\r
-         * Sets the ContentReference object to the Signature to be applied\r
-         * when the signature is created.\r
-         * \r
-         * @param reference the reference to attach, or NULL \r
-         */\r
-        virtual void setContentReference(ContentReference* reference)=0;\r
-\r
-        /**\r
-         * Gets the ContentReference object associated with the Signature.\r
-         * This is <strong>NOT</strong> provided for access to the\r
-         * data associated with an unmarshalled signature. It is\r
-         * used only in the creation of signatures. Access to data\r
-         * for validation purposes is provided through the native\r
-         * DSIGSignature object.\r
-         * \r
-         * @return  pointer to a ContentReference object, or NULL\r
-         */\r
-        virtual ContentReference* getContentReference() const=0;\r
-\r
-        \r
-        /**\r
-         * Gets the native Apache signature object, if present.\r
-         * \r
-         * @return  the native Apache signature interface\r
-         */\r
-        virtual DSIGSignature* getXMLSignature() const=0;\r
-\r
-        /**\r
-         * Compute and append the signature based on the assigned\r
-         * ContentReference, KeyInfo, and signing key.\r
-         */\r
-        virtual void sign()=0;\r
-\r
-        /**\r
-         * Type-safe clone operation.\r
-         * \r
-         * @return  copy of object\r
-         */\r
-        virtual Signature* cloneSignature() const=0;\r
-\r
-    protected:\r
-        Signature() {}\r
-    };\r
-\r
-    /**\r
-     * Builder for Signature objects.\r
-     */\r
-    class XMLTOOL_API SignatureBuilder : public xmltooling::XMLObjectBuilder\r
-    {\r
-    public:\r
-        virtual Signature* buildObject(\r
-            const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix=NULL, const xmltooling::QName* schemaType=NULL\r
-            ) const;\r
-            \r
-        /**\r
-         * Default builder\r
-         * \r
-         * @return empty Signature object\r
-         */\r
-        virtual Signature* buildObject() const;\r
-\r
-        static Signature* buildSignature() {\r
-            const SignatureBuilder* b = dynamic_cast<const SignatureBuilder*>(\r
-                xmltooling::XMLObjectBuilder::getBuilder(\r
-                    xmltooling::QName(xmltooling::XMLConstants::XMLSIG_NS,Signature::LOCAL_NAME)\r
-                    )\r
-                );\r
-            if (b)\r
-                return b->buildObject();\r
-            throw xmltooling::XMLObjectException("Unable to obtain typed builder for Signature.");\r
-        }\r
-    };\r
-\r
-    DECL_XMLTOOLING_EXCEPTION(SignatureException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmlsignature,xmltooling::XMLSecurityException,Exceptions in signature processing);\r
-\r
-};\r
-\r
-#endif /* __xmltooling_sig_h__ */\r
+/*
+ *  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.
+ */
+
+/**
+ * @file Signature.h
+ * 
+ * XMLObject representing XML Digital Signature, version 20020212, Signature element. 
+ */
+
+#if !defined(__xmltooling_sig_h__) && !defined(XMLTOOLING_NO_XMLSEC)
+#define __xmltooling_sig_h__
+
+#include <xmltooling/exceptions.h>
+#include <xmltooling/XMLObjectBuilder.h>
+#include <xmltooling/signature/ContentReference.h>
+#include <xmltooling/util/XMLConstants.h>
+
+#include <xsec/dsig/DSIGSignature.hpp>
+
+/**
+ * @namespace xmlsignature
+ * Public namespace of XML Signature classes
+ */
+namespace xmlsignature {
+
+    class XMLTOOL_API KeyInfo;
+
+    /**
+     * XMLObject representing XML Digital Signature, version 20020212, Signature element.
+     * The default signature settings include Exclusive c14n w/o comments, SHA-1 digests,
+     * and RSA-SHA1 signing. 
+     */
+    class XMLTOOL_API Signature : public virtual xmltooling::XMLObject
+    {
+    public:
+        virtual ~Signature() {}
+
+        /** Element local name */
+        static const XMLCh LOCAL_NAME[];
+
+        /**
+         * Sets the canonicalization method for the ds:SignedInfo element
+         * 
+         * @param c14n  the canonicalization method
+         */
+        virtual void setCanonicalizationMethod(const XMLCh* c14n)=0;
+        
+        /**
+         * Sets the signing algorithm for the signature.
+         * 
+         * @param sm    the signature algorithm
+         */
+        virtual void setSignatureAlgorithm(const XMLCh* sm)=0;
+
+        /**
+         * Sets the signing key used to create the signature.
+         * 
+         * @param signingKey the secret/private key used to create the signature
+         */
+        virtual void setSigningKey(XSECCryptoKey* signingKey)=0;
+
+        /**
+         * Sets a KeyInfo object to embed in the Signature.
+         * 
+         * @param keyInfo   pointer to a KeyInfo object, or NULL
+         */
+        virtual void setKeyInfo(KeyInfo* keyInfo)=0;
+
+        /**
+         * Gets the KeyInfo object associated with the Signature.
+         * This is <strong>NOT</strong> provided for access to the
+         * data associated with an unmarshalled signature. It is
+         * used only in the creation of signatures. Access to data
+         * for validation purposes is provided through the native
+         * DSIGSignature object.
+         * 
+         * @return  pointer to a KeyInfo object, or NULL
+         */
+        virtual KeyInfo* getKeyInfo() const=0;
+
+        /**
+         * Sets the ContentReference object to the Signature to be applied
+         * when the signature is created.
+         * 
+         * @param reference the reference to attach, or NULL 
+         */
+        virtual void setContentReference(ContentReference* reference)=0;
+
+        /**
+         * Gets the ContentReference object associated with the Signature.
+         * This is <strong>NOT</strong> provided for access to the
+         * data associated with an unmarshalled signature. It is
+         * used only in the creation of signatures. Access to data
+         * for validation purposes is provided through the native
+         * DSIGSignature object.
+         * 
+         * @return  pointer to a ContentReference object, or NULL
+         */
+        virtual ContentReference* getContentReference() const=0;
+
+        
+        /**
+         * Gets the native Apache signature object, if present.
+         * 
+         * @return  the native Apache signature interface
+         */
+        virtual DSIGSignature* getXMLSignature() const=0;
+
+        /**
+         * Compute and append the signature based on the assigned
+         * ContentReference, KeyInfo, and signing key.
+         */
+        virtual void sign()=0;
+
+        /**
+         * Type-safe clone operation.
+         * 
+         * @return  copy of object
+         */
+        virtual Signature* cloneSignature() const=0;
+
+    protected:
+        Signature() {}
+    };
+
+    /**
+     * Builder for Signature objects.
+     */
+    class XMLTOOL_API SignatureBuilder : public xmltooling::XMLObjectBuilder
+    {
+    public:
+        virtual Signature* buildObject(
+            const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix=NULL, const xmltooling::QName* schemaType=NULL
+            ) const;
+            
+        /**
+         * Default builder
+         * 
+         * @return empty Signature object
+         */
+        virtual Signature* buildObject() const;
+
+        static Signature* buildSignature() {
+            const SignatureBuilder* b = dynamic_cast<const SignatureBuilder*>(
+                xmltooling::XMLObjectBuilder::getBuilder(
+                    xmltooling::QName(xmltooling::XMLConstants::XMLSIG_NS,Signature::LOCAL_NAME)
+                    )
+                );
+            if (b)
+                return b->buildObject();
+            throw xmltooling::XMLObjectException("Unable to obtain typed builder for Signature.");
+        }
+    };
+
+    DECL_XMLTOOLING_EXCEPTION(SignatureException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmlsignature,xmltooling::XMLSecurityException,Exceptions in signature processing);
+
+};
+
+#endif /* __xmltooling_sig_h__ */
index 7f7fa7d..5ba231d 100644 (file)
@@ -1,94 +1,94 @@
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file SignatureValidator.h\r
- * \r
- * Validator for signatures based on an externally-supplied key \r
- */\r
-\r
-#if !defined(__xmltooling_sigval_h__) && !defined(XMLTOOLING_NO_XMLSEC)\r
-#define __xmltooling_sigval_h__\r
-\r
-#include <xmltooling/signature/KeyResolver.h>\r
-#include <xmltooling/signature/Signature.h>\r
-#include <xmltooling/validation/Validator.h>\r
-\r
-namespace xmlsignature {\r
-\r
-    /**\r
-     * Validator for signatures based on a Key or a KeyResolver\r
-     */\r
-    class XMLTOOL_API SignatureValidator : public xmltooling::Validator\r
-    {\r
-    public:\r
-        /**\r
-         * Constructor using a KeyResolver\r
-         * \r
-         * @param resolver the key resolver to use, will be freed by Validator\r
-         */\r
-        SignatureValidator(KeyResolver* resolver) : m_key(NULL), m_resolver(resolver) {\r
-        }\r
-\r
-        /**\r
-         * Constructor using a Key\r
-         * \r
-         * @param key the verification key to use, will be freed by Validator\r
-         */\r
-        SignatureValidator(XSECCryptoKey* key=NULL) : m_key(key), m_resolver(NULL) {\r
-        }\r
-        \r
-        virtual ~SignatureValidator() {\r
-            delete m_key;\r
-            delete m_resolver;\r
-        }\r
-\r
-        virtual void validate(const xmltooling::XMLObject* xmlObject) const;\r
-\r
-        virtual void validate(const Signature* signature) const;\r
-        \r
-        /**\r
-         * Replace the current Key, if any, with a new one.\r
-         * \r
-         * @param key  the Key to attach \r
-         */\r
-        void setKey(XSECCryptoKey* key) {\r
-            delete m_key;\r
-            delete m_resolver;\r
-            m_resolver=NULL;\r
-            m_key=key;\r
-        }\r
-\r
-        /**\r
-         * Replace the current KeyResolver, if any, with a new one.\r
-         * \r
-         * @param resolver  the KeyResolver to attach \r
-         */\r
-        void setKeyResolver(KeyResolver* resolver) {\r
-            delete m_key;\r
-            delete m_resolver;\r
-            m_key=NULL;\r
-            m_resolver=resolver;\r
-        }\r
-    \r
-    protected:\r
-        XSECCryptoKey* m_key;\r
-        KeyResolver* m_resolver;\r
-    };\r
-\r
-};\r
-\r
-#endif /* __xmltooling_sigval_h__ */\r
+/*
+ *  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.
+ */
+
+/**
+ * @file SignatureValidator.h
+ * 
+ * Validator for signatures based on an externally-supplied key 
+ */
+
+#if !defined(__xmltooling_sigval_h__) && !defined(XMLTOOLING_NO_XMLSEC)
+#define __xmltooling_sigval_h__
+
+#include <xmltooling/signature/KeyResolver.h>
+#include <xmltooling/signature/Signature.h>
+#include <xmltooling/validation/Validator.h>
+
+namespace xmlsignature {
+
+    /**
+     * Validator for signatures based on a Key or a KeyResolver
+     */
+    class XMLTOOL_API SignatureValidator : public xmltooling::Validator
+    {
+    public:
+        /**
+         * Constructor using a KeyResolver
+         * 
+         * @param resolver the key resolver to use, will be freed by Validator
+         */
+        SignatureValidator(KeyResolver* resolver) : m_key(NULL), m_resolver(resolver) {
+        }
+
+        /**
+         * Constructor using a Key
+         * 
+         * @param key the verification key to use, will be freed by Validator
+         */
+        SignatureValidator(XSECCryptoKey* key=NULL) : m_key(key), m_resolver(NULL) {
+        }
+        
+        virtual ~SignatureValidator() {
+            delete m_key;
+            delete m_resolver;
+        }
+
+        virtual void validate(const xmltooling::XMLObject* xmlObject) const;
+
+        virtual void validate(const Signature* signature) const;
+        
+        /**
+         * Replace the current Key, if any, with a new one.
+         * 
+         * @param key  the Key to attach 
+         */
+        void setKey(XSECCryptoKey* key) {
+            delete m_key;
+            delete m_resolver;
+            m_resolver=NULL;
+            m_key=key;
+        }
+
+        /**
+         * Replace the current KeyResolver, if any, with a new one.
+         * 
+         * @param resolver  the KeyResolver to attach 
+         */
+        void setKeyResolver(KeyResolver* resolver) {
+            delete m_key;
+            delete m_resolver;
+            m_key=NULL;
+            m_resolver=resolver;
+        }
+    
+    protected:
+        XSECCryptoKey* m_key;
+        KeyResolver* m_resolver;
+    };
+
+};
+
+#endif /* __xmltooling_sigval_h__ */
index 2389c14..f838142 100644 (file)
-/*\r
- *  Copyright 2001-2005 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * FilesystemCredentialResolver.cpp\r
- * \r
- * Supplies credentials from local files\r
- */\r
-\r
-#include "internal.h"\r
-#include "signature/KeyResolver.h"\r
-#include "signature/OpenSSLCredentialResolver.h"\r
-#include "util/NDC.h"\r
-#include "util/XMLHelper.h"\r
-\r
-#include <sys/types.h>\r
-#include <sys/stat.h>\r
-#include <algorithm>\r
-#include <openssl/pkcs12.h>\r
-#include <log4cpp/Category.hh>\r
-#include <xercesc/util/XMLUniDefs.hpp>\r
-#include <xsec/enc/OpenSSL/OpenSSLCryptoX509.hpp>\r
-#include <xsec/enc/OpenSSL/OpenSSLCryptoKeyRSA.hpp>\r
-#include <xsec/enc/OpenSSL/OpenSSLCryptoKeyDSA.hpp>\r
-\r
-using namespace xmlsignature;\r
-using namespace xmltooling;\r
-using namespace log4cpp;\r
-using namespace std;\r
-\r
-// OpenSSL password callback...\r
-static int passwd_callback(char* buf, int len, int verify, void* passwd)\r
-{\r
-    if(!verify)\r
-    {\r
-        if(passwd && len > strlen(reinterpret_cast<char*>(passwd)))\r
-        {\r
-            strcpy(buf,reinterpret_cast<char*>(passwd));\r
-            return strlen(buf);\r
-        }\r
-    }  \r
-    return 0;\r
-}\r
-\r
-namespace xmlsignature {\r
-    class FilesystemCredentialResolver : public OpenSSLCredentialResolver, public KeyResolver\r
-    {\r
-    public:\r
-        FilesystemCredentialResolver(const DOMElement* e);\r
-        virtual ~FilesystemCredentialResolver();\r
-\r
-        Lockable* lock() { return this; }\r
-        void unlock() {}\r
-        \r
-        XSECCryptoKey* loadKey();\r
-        \r
-        XSECCryptoKey* getKey() const { return m_key ? m_key->clone() : NULL; }\r
-        const vector<XSECCryptoX509*>& getCertificates() const { return m_xseccerts; }\r
-        void attach(SSL_CTX* ctx) const;\r
-        \r
-        XSECCryptoKey* resolveKey(const KeyInfo* keyInfo) const { return m_key ? m_key->clone() : NULL; }\r
-        XSECCryptoKey* resolveKey(DSIGKeyInfoList* keyInfo) const { return m_key ? m_key->clone() : NULL; }\r
-        vector<XSECCryptoX509*>::size_type resolveCertificates(const KeyInfo* keyInfo, ResolvedCertificates& certs) const {\r
-            accessCertificates(certs).assign(m_xseccerts.begin(), m_xseccerts.end());\r
-            accessOwned(certs) = false;\r
-            return accessCertificates(certs).size();\r
-        }\r
-        vector<XSECCryptoX509*>::size_type resolveCertificates(DSIGKeyInfoList* keyInfo, ResolvedCertificates& certs) const {\r
-            accessCertificates(certs).assign(m_xseccerts.begin(), m_xseccerts.end());\r
-            accessOwned(certs) = false;\r
-            return accessCertificates(certs).size();\r
-        }\r
-        \r
-    private:\r
-        enum format_t { PEM=SSL_FILETYPE_PEM, DER=SSL_FILETYPE_ASN1, _PKCS12, UNKNOWN };\r
-    \r
-        format_t getEncodingFormat(BIO* in) const;\r
-        string formatToString(format_t format) const;\r
-        format_t xmlFormatToFormat(const XMLCh* format_xml) const;\r
-    \r
-        format_t m_keyformat;\r
-        string m_keypath,m_keypass;\r
-        vector<X509*> m_certs;\r
-        vector<XSECCryptoX509*> m_xseccerts;\r
-        XSECCryptoKey* m_key;\r
-    };\r
-\r
-    CredentialResolver* XMLTOOL_DLLLOCAL FilesystemCredentialResolverFactory(const DOMElement* const & e)\r
-    {\r
-        return new FilesystemCredentialResolver(e);\r
-    }\r
-\r
-    KeyResolver* XMLTOOL_DLLLOCAL FilesystemKeyResolverFactory(const DOMElement* const & e)\r
-    {\r
-        return new FilesystemCredentialResolver(e);\r
-    }\r
-};\r
-\r
-static const XMLCh CAPath[] =           UNICODE_LITERAL_6(C,A,P,a,t,h);\r
-static const XMLCh Certificate[] =      UNICODE_LITERAL_11(C,e,r,t,i,f,i,c,a,t,e);\r
-static const XMLCh format[] =           UNICODE_LITERAL_6(f,o,r,m,a,t);\r
-static const XMLCh Key[] =              UNICODE_LITERAL_3(K,e,y);\r
-static const XMLCh password[] =         UNICODE_LITERAL_8(p,a,s,s,w,o,r,d);\r
-static const XMLCh Path[] =             UNICODE_LITERAL_4(P,a,t,h);\r
-\r
-FilesystemCredentialResolver::FilesystemCredentialResolver(const DOMElement* e) : m_key(NULL)\r
-{\r
-#ifdef _DEBUG\r
-    NDC ndc("FilesystemCredentialResolver");\r
-#endif\r
-    Category& log=Category::getInstance(XMLTOOLING_LOGCAT".CredentialResolver");\r
-\r
-    format_t fformat;\r
-    const XMLCh* format_xml=NULL;\r
-    BIO* in = NULL;\r
-    \r
-    // Move to Key\r
-    const DOMElement* root=e;\r
-    e=XMLHelper::getFirstChildElement(root,Key);\r
-    if (e) {\r
-\r
-        // Get raw format attrib value, but defer processing til later since may need to \r
-        // determine format dynamically, and we need the Path for that.\r
-        format_xml=e->getAttributeNS(NULL,format);\r
-            \r
-        const XMLCh* password_xml=e->getAttributeNS(NULL,password);\r
-        if (password_xml) {\r
-            auto_ptr_char kp(password_xml);\r
-            m_keypass=kp.get();\r
-        }\r
-        \r
-        e=XMLHelper::getFirstChildElement(e,Path);\r
-        if (e && e->hasChildNodes()) {\r
-            const XMLCh* s=e->getFirstChild()->getNodeValue();\r
-            auto_ptr_char kpath(s);\r
-#ifdef WIN32\r
-            struct _stat stat_buf;\r
-            if (_stat(kpath.get(), &stat_buf) != 0)\r
-#else\r
-            struct stat stat_buf;\r
-            if (stat(kpath.get(), &stat_buf) != 0)\r
-#endif\r
-            {\r
-                log.error("key file (%s) can't be opened", kpath.get());\r
-                throw XMLSecurityException("FilesystemCredentialResolver can't access key file ($1)",params(1,kpath.get()));\r
-            }\r
-            m_keypath=kpath.get();\r
-        }\r
-        else {\r
-            log.error("Path element missing inside Key element");\r
-            throw XMLSecurityException("FilesystemCredentialResolver can't access key file, no Path element specified.");\r
-        }\r
-\r
-        // Determine the key encoding format dynamically, if not explicitly specified\r
-        if (format_xml && *format_xml) {\r
-            fformat = xmlFormatToFormat(format_xml);\r
-            if (fformat != UNKNOWN) {\r
-                m_keyformat = fformat;\r
-            }\r
-            else {\r
-                auto_ptr_char unknown(format_xml);\r
-                log.error("configuration specifies unknown key encoding format (%s)", unknown.get());\r
-                throw XMLSecurityException("FilesystemCredentialResolver configuration contains unknown key encoding format ($1)",params(1,unknown.get()));\r
-            }\r
-        }\r
-        else {\r
-            in=BIO_new(BIO_s_file_internal());\r
-            if (in && BIO_read_filename(in,m_keypath.c_str())>0) {\r
-                m_keyformat = getEncodingFormat(in);\r
-                log.debug("key encoding format for (%s) dynamically resolved as (%s)", m_keypath.c_str(), formatToString(m_keyformat).c_str());\r
-            }\r
-            else {\r
-                log.error("key file (%s) can't be read to determine encoding format", m_keypath.c_str());\r
-                throw XMLSecurityException("FilesystemCredentialResolver can't read key file ($1) to determine encoding format",params(1,m_keypath.c_str()));\r
-            }\r
-            if (in)\r
-                BIO_free(in);\r
-            in = NULL;    \r
-        }\r
-        \r
-        // Load the key.\r
-        m_key = loadKey();\r
-    }\r
-        \r
-    // Check for Certificate\r
-    e=XMLHelper::getFirstChildElement(root,Certificate);\r
-    if (!e)\r
-        return;\r
-    auto_ptr_char certpass(e->getAttributeNS(NULL,password));\r
-    \r
-    DOMElement* ep=XMLHelper::getFirstChildElement(e,Path);\r
-    if (!ep || !ep->hasChildNodes()) {\r
-        log.error("Path element missing inside Certificate element or is empty");\r
-        throw XMLSecurityException("FilesystemCredentialResolver can't access certificate file, missing or empty Path element.");\r
-    }\r
-    \r
-    auto_ptr_char certpath(ep->getFirstChild()->getNodeValue());\r
-    format_xml=e->getAttributeNS(NULL,format);\r
-    if (format_xml && *format_xml) {\r
-        fformat = xmlFormatToFormat(format_xml);\r
-        if (fformat == UNKNOWN) {\r
-            auto_ptr_char unknown(format_xml);\r
-            log.error("configuration specifies unknown certificate encoding format (%s)", unknown.get());\r
-            throw XMLSecurityException("FilesystemCredentialResolver configuration contains unknown certificate encoding format ($1)",params(1,unknown.get()));\r
-        }\r
-    }\r
-    \r
-    try {\r
-        X509* x=NULL;\r
-        PKCS12* p12=NULL;\r
-        in=BIO_new(BIO_s_file_internal());\r
-        if (in && BIO_read_filename(in,certpath.get())>0) {\r
-            if (!format_xml || !*format_xml) {\r
-                // Determine the cert encoding format dynamically, if not explicitly specified\r
-                fformat = getEncodingFormat(in);\r
-                log.debug("certificate encoding format for (%s) dynamically resolved as (%s)", certpath.get(), formatToString(fformat).c_str());\r
-            }\r
-\r
-            switch(fformat) {\r
-                case PEM:\r
-                    while (x=PEM_read_bio_X509(in,NULL,passwd_callback,const_cast<char*>(certpass.get())))\r
-                        m_certs.push_back(x);\r
-                    break;\r
-                                \r
-                case DER:\r
-                    x=d2i_X509_bio(in,NULL);\r
-                    if (x)\r
-                        m_certs.push_back(x);\r
-                    else {\r
-                        log_openssl();\r
-                        BIO_free(in);\r
-                        throw XMLSecurityException("FilesystemCredentialResolver unable to load DER certificate from file ($1)",params(1,certpath.get()));\r
-                    }\r
-                    break;\r
-\r
-                case _PKCS12:\r
-                    p12=d2i_PKCS12_bio(in,NULL);\r
-                    if (p12) {\r
-                        PKCS12_parse(p12, certpass.get(), NULL, &x, NULL);\r
-                        PKCS12_free(p12);\r
-                    }\r
-                    if (x) {\r
-                        m_certs.push_back(x);\r
-                        x=NULL;\r
-                    } else {\r
-                        log_openssl();\r
-                        BIO_free(in);\r
-                        throw XMLSecurityException("FilesystemCredentialResolver unable to load PKCS12 certificate from file ($1)",params(1,certpath.get()));\r
-                    }\r
-                    break;\r
-            } // end switch\r
-\r
-        } else {\r
-            log_openssl();\r
-            if (in) {\r
-                BIO_free(in);\r
-                in=NULL;\r
-            }\r
-            throw XMLSecurityException("FilesystemCredentialResolver unable to load certificate(s) from file ($1)",params(1,certpath.get()));\r
-        }\r
-        if (in) {\r
-            BIO_free(in);\r
-            in=NULL;\r
-        }\r
-\r
-        if (m_certs.empty()) {\r
-            throw XMLSecurityException("FilesystemCredentialResolver unable to load any certificate(s)");\r
-        }\r
-\r
-        // Load any extra CA files.\r
-        DOMElement* extra=XMLHelper::getFirstChildElement(e,CAPath);\r
-        while (extra) {\r
-            if (!extra->hasChildNodes()) {\r
-                log.warn("skipping empty CAPath element");\r
-                extra = XMLHelper::getNextSiblingElement(extra,CAPath);\r
-                continue;\r
-            }\r
-            auto_ptr_char capath(extra->getFirstChild()->getNodeValue());\r
-            x=NULL;\r
-            p12=NULL;\r
-            in=BIO_new(BIO_s_file_internal());\r
-            if (in && BIO_read_filename(in,capath.get())>0) {\r
-                if (!format_xml || !*format_xml) {\r
-                    // Determine the cert encoding format dynamically, if not explicitly specified\r
-                    fformat = getEncodingFormat(in);\r
-                    log.debug("CA certificate encoding format for (%s) dynamically resolved as (%s)", certpath.get(), formatToString(fformat).c_str());\r
-                }\r
-\r
-                switch (fformat) {\r
-                    case PEM:\r
-                        while (x=PEM_read_bio_X509(in,NULL,passwd_callback,const_cast<char*>(certpass.get())))\r
-                            m_certs.push_back(x);\r
-                        break;\r
-\r
-                    case DER:\r
-                        x=d2i_X509_bio(in,NULL);\r
-                        if (x)\r
-                            m_certs.push_back(x);\r
-                        else {\r
-                            log_openssl();\r
-                            BIO_free(in);\r
-                            throw XMLSecurityException("FilesystemCredentialResolver unable to load DER CA certificate from file ($1)",params(1,capath.get()));\r
-                        }\r
-                        break;\r
-\r
-                    case _PKCS12:\r
-                        p12 = d2i_PKCS12_bio(in, NULL);\r
-                        if (p12) {\r
-                            PKCS12_parse(p12, certpass.get(), NULL, &x, NULL);\r
-                            PKCS12_free(p12);\r
-                        }\r
-                        if (x) {\r
-                            m_certs.push_back(x);\r
-                            x=NULL;\r
-                        }\r
-                        else {\r
-                            log_openssl();\r
-                            BIO_free(in);\r
-                            throw XMLSecurityException("FilesystemCredentialResolver unable to load PKCS12 CA certificate from file ($1)",params(1,capath.get()));\r
-                        }\r
-                        break;\r
-                } //end switch\r
-\r
-                BIO_free(in);\r
-            }\r
-            else {\r
-                if (in)\r
-                    BIO_free(in);\r
-                log_openssl();\r
-                log.error("CA file (%s) can't be opened", capath.get());\r
-                throw XMLSecurityException("FilesystemCredentialResolver can't open CA file ($1)",params(1,capath.get()));\r
-            }\r
-            \r
-            extra = XMLHelper::getNextSiblingElement(extra,CAPath);\r
-        }\r
-    }\r
-    catch (XMLToolingException&) {\r
-        for (vector<X509*>::iterator j=m_certs.begin(); j!=m_certs.end(); j++)\r
-            X509_free(*j);\r
-        throw;\r
-    }\r
-\r
-    // Reflect certs over to XSEC form.\r
-    for (vector<X509*>::iterator j=m_certs.begin(); j!=m_certs.end(); j++)\r
-        m_xseccerts.push_back(new OpenSSLCryptoX509(*j));\r
-}\r
-\r
-XSECCryptoKey* FilesystemCredentialResolver::loadKey()\r
-{\r
-#ifdef _DEBUG\r
-    NDC ndc("loadKey");\r
-#endif\r
-\r
-    // Get a EVP_PKEY.\r
-    EVP_PKEY* pkey=NULL;\r
-    BIO* in=BIO_new(BIO_s_file_internal());\r
-    if (in && BIO_read_filename(in,m_keypath.c_str())>0) {\r
-        switch (m_keyformat) {\r
-            case PEM:\r
-                pkey=PEM_read_bio_PrivateKey(in, NULL, passwd_callback, const_cast<char*>(m_keypass.c_str()));\r
-                break;\r
-            \r
-            case DER:\r
-                pkey=d2i_PrivateKey_bio(in, NULL);\r
-                break;\r
-                \r
-            default: {\r
-                PKCS12* p12 = d2i_PKCS12_bio(in, NULL);\r
-                if (p12) {\r
-                    PKCS12_parse(p12, const_cast<char*>(m_keypass.c_str()), &pkey, NULL, NULL);\r
-                    PKCS12_free(p12);\r
-                }\r
-            }\r
-        }\r
-    }\r
-    if (in)\r
-        BIO_free(in);\r
-    \r
-    // Now map it to an XSEC wrapper.\r
-    if (pkey) {\r
-        XSECCryptoKey* ret=NULL;\r
-        switch (pkey->type) {\r
-            case EVP_PKEY_RSA:\r
-                ret=new OpenSSLCryptoKeyRSA(pkey);\r
-                break;\r
-                \r
-            case EVP_PKEY_DSA:\r
-                ret=new OpenSSLCryptoKeyDSA(pkey);\r
-                break;\r
-            \r
-            default:\r
-                Category::getInstance(XMLTOOLING_LOGCAT".CredentialResolver").error("unsupported private key type");\r
-        }\r
-        EVP_PKEY_free(pkey);\r
-        if (ret)\r
-            return ret;\r
-    }\r
-\r
-    log_openssl();\r
-    throw XMLSecurityException("FilesystemCredentialResolver unable to load private key from file."); \r
-}\r
-\r
-FilesystemCredentialResolver::~FilesystemCredentialResolver()\r
-{\r
-    delete m_key;\r
-    for_each(m_certs.begin(),m_certs.end(),X509_free);\r
-    for_each(m_xseccerts.begin(),m_xseccerts.end(),xmltooling::cleanup<XSECCryptoX509>());\r
-}\r
-\r
-void FilesystemCredentialResolver::attach(SSL_CTX* ctx) const\r
-{\r
-#ifdef _DEBUG\r
-    NDC ndc("attach");\r
-#endif\r
-    \r
-    // Attach key.\r
-    SSL_CTX_set_default_passwd_cb(ctx, passwd_callback);\r
-    SSL_CTX_set_default_passwd_cb_userdata(ctx, const_cast<char*>(m_keypass.c_str()));\r
-\r
-    int ret=0;\r
-    switch (m_keyformat) {\r
-        case PEM:\r
-            ret=SSL_CTX_use_PrivateKey_file(ctx, m_keypath.c_str(), m_keyformat);\r
-            break;\r
-            \r
-        case DER:\r
-            ret=SSL_CTX_use_RSAPrivateKey_file(ctx, m_keypath.c_str(), m_keyformat);\r
-            break;\r
-            \r
-        default: {\r
-            BIO* in=BIO_new(BIO_s_file_internal());\r
-            if (in && BIO_read_filename(in,m_keypath.c_str())>0) {\r
-                EVP_PKEY* pkey=NULL;\r
-                PKCS12* p12 = d2i_PKCS12_bio(in, NULL);\r
-                if (p12) {\r
-                    PKCS12_parse(p12, const_cast<char*>(m_keypass.c_str()), &pkey, NULL, NULL);\r
-                    PKCS12_free(p12);\r
-                    if (pkey) {\r
-                        ret=SSL_CTX_use_PrivateKey(ctx, pkey);\r
-                        EVP_PKEY_free(pkey);\r
-                    }\r
-                }\r
-            }\r
-            if (in)\r
-                BIO_free(in);\r
-        }\r
-    }\r
-    \r
-    if (ret!=1) {\r
-        log_openssl();\r
-        throw XMLSecurityException("Unable to attach private key to SSL context.");\r
-    }\r
-\r
-    // Attach certs.\r
-    for (vector<X509*>::const_iterator i=m_certs.begin(); i!=m_certs.end(); i++) {\r
-        if (i==m_certs.begin()) {\r
-            if (SSL_CTX_use_certificate(ctx, *i) != 1) {\r
-                log_openssl();\r
-                throw XMLSecurityException("Unable to attach client certificate to SSL context.");\r
-            }\r
-        }\r
-        else {\r
-            // When we add certs, they don't get ref counted, so we need to duplicate them.\r
-            X509* dup = X509_dup(*i);\r
-            if (SSL_CTX_add_extra_chain_cert(ctx, dup) != 1) {\r
-                X509_free(dup);\r
-                log_openssl();\r
-                throw XMLSecurityException("Unable to attach CA certificate to SSL context.");\r
-            }\r
-        }\r
-    }\r
-}\r
-\r
-// Used to determine the encoding format of credentials files\r
-// dynamically. Supports: PEM, DER, PKCS12.\r
-FilesystemCredentialResolver::format_t FilesystemCredentialResolver::getEncodingFormat(BIO* in) const\r
-{\r
-    PKCS12* p12 = NULL;\r
-    format_t format;\r
-\r
-    const int READSIZE = 1;\r
-    char buf[READSIZE];\r
-    char b1;\r
-    int mark;\r
-\r
-    try {\r
-        if ( (mark = BIO_tell(in)) < 0 ) \r
-            throw XMLSecurityException("getEncodingFormat: BIO_tell() can't get the file position");\r
-        if ( BIO_read(in, buf, READSIZE) <= 0 ) \r
-            throw XMLSecurityException("getEncodingFormat: BIO_read() can't read from the stream");\r
-        if ( BIO_seek(in, mark) < 0 ) \r
-            throw XMLSecurityException("getEncodingFormat: BIO_seek() can't reset the file position");\r
-    }\r
-    catch (...) {\r
-        log_openssl();\r
-        throw;\r
-    }\r
-\r
-    b1 = buf[0];\r
-\r
-    // This is a slight variation of the Java code by Chad La Joie.\r
-    //\r
-    // Check the first byte of the file.  If it's some kind of\r
-    // DER-encoded structure (including PKCS12), it will begin with ASCII 048.\r
-    // Otherwise, assume it's PEM.\r
-    if (b1 !=  48) {\r
-        format = PEM;\r
-    } else {\r
-        // Here we know it's DER-encoded, now try to parse it as a PKCS12\r
-        // ASN.1 structure.  If it fails, must be another kind of DER-encoded\r
-        // key/cert structure.  A little inefficient...but it works.\r
-        if ( (p12=d2i_PKCS12_bio(in,NULL)) == NULL ) {\r
-            format = DER;\r
-        } else {\r
-            format = _PKCS12;\r
-        }\r
-        if (p12)\r
-            PKCS12_free(p12);    \r
-        if ( BIO_seek(in, mark) < 0 ) {\r
-            log_openssl();\r
-            throw XMLSecurityException("getEncodingFormat: BIO_seek() can't reset the file position");\r
-        }\r
-    }\r
-\r
-    return format;\r
-}\r
-\r
-// Convert key/cert format_t types to a human-meaningful string for debug output\r
-string FilesystemCredentialResolver::formatToString(format_t format) const\r
-{\r
-    switch(format) {\r
-        case PEM:\r
-            return "PEM";\r
-        case DER:\r
-            return "DER";\r
-        case _PKCS12:\r
-            return "PKCS12";\r
-        default:\r
-            return "UNKNOWN";\r
-    }\r
-}\r
-\r
-// Convert key/cert raw XML format attribute (XMLCh[]) to format_t type\r
-FilesystemCredentialResolver::format_t FilesystemCredentialResolver::xmlFormatToFormat(const XMLCh* format_xml) const\r
-{\r
-    static const XMLCh cPEM[] = UNICODE_LITERAL_3(P,E,M);\r
-    static const XMLCh cDER[] = UNICODE_LITERAL_3(D,E,R);\r
-    static const XMLCh cPKCS12[] = { chLatin_P, chLatin_K, chLatin_C, chLatin_S, chDigit_1, chDigit_2, chNull };\r
-    format_t format;\r
-\r
-    if (!XMLString::compareString(format_xml,cPEM))\r
-        format=PEM;\r
-    else if (!XMLString::compareString(format_xml,cDER))\r
-        format=DER;\r
-    else if (!XMLString::compareString(format_xml,cPKCS12))\r
-        format=_PKCS12;\r
-    else\r
-        format=UNKNOWN;\r
-\r
-    return format;\r
-}\r
+/*
+ *  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.
+ */
+
+/**
+ * FilesystemCredentialResolver.cpp
+ * 
+ * Supplies credentials from local files
+ */
+
+#include "internal.h"
+#include "signature/KeyResolver.h"
+#include "signature/OpenSSLCredentialResolver.h"
+#include "util/NDC.h"
+#include "util/XMLHelper.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <algorithm>
+#include <openssl/pkcs12.h>
+#include <log4cpp/Category.hh>
+#include <xercesc/util/XMLUniDefs.hpp>
+#include <xsec/enc/OpenSSL/OpenSSLCryptoX509.hpp>
+#include <xsec/enc/OpenSSL/OpenSSLCryptoKeyRSA.hpp>
+#include <xsec/enc/OpenSSL/OpenSSLCryptoKeyDSA.hpp>
+
+using namespace xmlsignature;
+using namespace xmltooling;
+using namespace log4cpp;
+using namespace std;
+
+// OpenSSL password callback...
+static int passwd_callback(char* buf, int len, int verify, void* passwd)
+{
+    if(!verify)
+    {
+        if(passwd && len > strlen(reinterpret_cast<char*>(passwd)))
+        {
+            strcpy(buf,reinterpret_cast<char*>(passwd));
+            return strlen(buf);
+        }
+    }  
+    return 0;
+}
+
+namespace xmlsignature {
+    class FilesystemCredentialResolver : public OpenSSLCredentialResolver, public KeyResolver
+    {
+    public:
+        FilesystemCredentialResolver(const DOMElement* e);
+        virtual ~FilesystemCredentialResolver();
+
+        Lockable* lock() { return this; }
+        void unlock() {}
+        
+        XSECCryptoKey* loadKey();
+        
+        XSECCryptoKey* getKey() const { return m_key ? m_key->clone() : NULL; }
+        const vector<XSECCryptoX509*>& getCertificates() const { return m_xseccerts; }
+        void attach(SSL_CTX* ctx) const;
+        
+        XSECCryptoKey* resolveKey(const KeyInfo* keyInfo) const { return m_key ? m_key->clone() : NULL; }
+        XSECCryptoKey* resolveKey(DSIGKeyInfoList* keyInfo) const { return m_key ? m_key->clone() : NULL; }
+        vector<XSECCryptoX509*>::size_type resolveCertificates(const KeyInfo* keyInfo, ResolvedCertificates& certs) const {
+            accessCertificates(certs).assign(m_xseccerts.begin(), m_xseccerts.end());
+            accessOwned(certs) = false;
+            return accessCertificates(certs).size();
+        }
+        vector<XSECCryptoX509*>::size_type resolveCertificates(DSIGKeyInfoList* keyInfo, ResolvedCertificates& certs) const {
+            accessCertificates(certs).assign(m_xseccerts.begin(), m_xseccerts.end());
+            accessOwned(certs) = false;
+            return accessCertificates(certs).size();
+        }
+        
+    private:
+        enum format_t { PEM=SSL_FILETYPE_PEM, DER=SSL_FILETYPE_ASN1, _PKCS12, UNKNOWN };
+    
+        format_t getEncodingFormat(BIO* in) const;
+        string formatToString(format_t format) const;
+        format_t xmlFormatToFormat(const XMLCh* format_xml) const;
+    
+        format_t m_keyformat;
+        string m_keypath,m_keypass;
+        vector<X509*> m_certs;
+        vector<XSECCryptoX509*> m_xseccerts;
+        XSECCryptoKey* m_key;
+    };
+
+    CredentialResolver* XMLTOOL_DLLLOCAL FilesystemCredentialResolverFactory(const DOMElement* const & e)
+    {
+        return new FilesystemCredentialResolver(e);
+    }
+
+    KeyResolver* XMLTOOL_DLLLOCAL FilesystemKeyResolverFactory(const DOMElement* const & e)
+    {
+        return new FilesystemCredentialResolver(e);
+    }
+};
+
+static const XMLCh CAPath[] =           UNICODE_LITERAL_6(C,A,P,a,t,h);
+static const XMLCh Certificate[] =      UNICODE_LITERAL_11(C,e,r,t,i,f,i,c,a,t,e);
+static const XMLCh format[] =           UNICODE_LITERAL_6(f,o,r,m,a,t);
+static const XMLCh Key[] =              UNICODE_LITERAL_3(K,e,y);
+static const XMLCh password[] =         UNICODE_LITERAL_8(p,a,s,s,w,o,r,d);
+static const XMLCh Path[] =             UNICODE_LITERAL_4(P,a,t,h);
+
+FilesystemCredentialResolver::FilesystemCredentialResolver(const DOMElement* e) : m_key(NULL)
+{
+#ifdef _DEBUG
+    NDC ndc("FilesystemCredentialResolver");
+#endif
+    Category& log=Category::getInstance(XMLTOOLING_LOGCAT".CredentialResolver");
+
+    format_t fformat;
+    const XMLCh* format_xml=NULL;
+    BIO* in = NULL;
+    
+    // Move to Key
+    const DOMElement* root=e;
+    e=XMLHelper::getFirstChildElement(root,Key);
+    if (e) {
+
+        // Get raw format attrib value, but defer processing til later since may need to 
+        // determine format dynamically, and we need the Path for that.
+        format_xml=e->getAttributeNS(NULL,format);
+            
+        const XMLCh* password_xml=e->getAttributeNS(NULL,password);
+        if (password_xml) {
+            auto_ptr_char kp(password_xml);
+            m_keypass=kp.get();
+        }
+        
+        e=XMLHelper::getFirstChildElement(e,Path);
+        if (e && e->hasChildNodes()) {
+            const XMLCh* s=e->getFirstChild()->getNodeValue();
+            auto_ptr_char kpath(s);
+#ifdef WIN32
+            struct _stat stat_buf;
+            if (_stat(kpath.get(), &stat_buf) != 0)
+#else
+            struct stat stat_buf;
+            if (stat(kpath.get(), &stat_buf) != 0)
+#endif
+            {
+                log.error("key file (%s) can't be opened", kpath.get());
+                throw XMLSecurityException("FilesystemCredentialResolver can't access key file ($1)",params(1,kpath.get()));
+            }
+            m_keypath=kpath.get();
+        }
+        else {
+            log.error("Path element missing inside Key element");
+            throw XMLSecurityException("FilesystemCredentialResolver can't access key file, no Path element specified.");
+        }
+
+        // Determine the key encoding format dynamically, if not explicitly specified
+        if (format_xml && *format_xml) {
+            fformat = xmlFormatToFormat(format_xml);
+            if (fformat != UNKNOWN) {
+                m_keyformat = fformat;
+            }
+            else {
+                auto_ptr_char unknown(format_xml);
+                log.error("configuration specifies unknown key encoding format (%s)", unknown.get());
+                throw XMLSecurityException("FilesystemCredentialResolver configuration contains unknown key encoding format ($1)",params(1,unknown.get()));
+            }
+        }
+        else {
+            in=BIO_new(BIO_s_file_internal());
+            if (in && BIO_read_filename(in,m_keypath.c_str())>0) {
+                m_keyformat = getEncodingFormat(in);
+                log.debug("key encoding format for (%s) dynamically resolved as (%s)", m_keypath.c_str(), formatToString(m_keyformat).c_str());
+            }
+            else {
+                log.error("key file (%s) can't be read to determine encoding format", m_keypath.c_str());
+                throw XMLSecurityException("FilesystemCredentialResolver can't read key file ($1) to determine encoding format",params(1,m_keypath.c_str()));
+            }
+            if (in)
+                BIO_free(in);
+            in = NULL;    
+        }
+        
+        // Load the key.
+        m_key = loadKey();
+    }
+        
+    // Check for Certificate
+    e=XMLHelper::getFirstChildElement(root,Certificate);
+    if (!e)
+        return;
+    auto_ptr_char certpass(e->getAttributeNS(NULL,password));
+    
+    DOMElement* ep=XMLHelper::getFirstChildElement(e,Path);
+    if (!ep || !ep->hasChildNodes()) {
+        log.error("Path element missing inside Certificate element or is empty");
+        throw XMLSecurityException("FilesystemCredentialResolver can't access certificate file, missing or empty Path element.");
+    }
+    
+    auto_ptr_char certpath(ep->getFirstChild()->getNodeValue());
+    format_xml=e->getAttributeNS(NULL,format);
+    if (format_xml && *format_xml) {
+        fformat = xmlFormatToFormat(format_xml);
+        if (fformat == UNKNOWN) {
+            auto_ptr_char unknown(format_xml);
+            log.error("configuration specifies unknown certificate encoding format (%s)", unknown.get());
+            throw XMLSecurityException("FilesystemCredentialResolver configuration contains unknown certificate encoding format ($1)",params(1,unknown.get()));
+        }
+    }
+    
+    try {
+        X509* x=NULL;
+        PKCS12* p12=NULL;
+        in=BIO_new(BIO_s_file_internal());
+        if (in && BIO_read_filename(in,certpath.get())>0) {
+            if (!format_xml || !*format_xml) {
+                // Determine the cert encoding format dynamically, if not explicitly specified
+                fformat = getEncodingFormat(in);
+                log.debug("certificate encoding format for (%s) dynamically resolved as (%s)", certpath.get(), formatToString(fformat).c_str());
+            }
+
+            switch(fformat) {
+                case PEM:
+                    while (x=PEM_read_bio_X509(in,NULL,passwd_callback,const_cast<char*>(certpass.get())))
+                        m_certs.push_back(x);
+                    break;
+                                
+                case DER:
+                    x=d2i_X509_bio(in,NULL);
+                    if (x)
+                        m_certs.push_back(x);
+                    else {
+                        log_openssl();
+                        BIO_free(in);
+                        throw XMLSecurityException("FilesystemCredentialResolver unable to load DER certificate from file ($1)",params(1,certpath.get()));
+                    }
+                    break;
+
+                case _PKCS12:
+                    p12=d2i_PKCS12_bio(in,NULL);
+                    if (p12) {
+                        PKCS12_parse(p12, certpass.get(), NULL, &x, NULL);
+                        PKCS12_free(p12);
+                    }
+                    if (x) {
+                        m_certs.push_back(x);
+                        x=NULL;
+                    } else {
+                        log_openssl();
+                        BIO_free(in);
+                        throw XMLSecurityException("FilesystemCredentialResolver unable to load PKCS12 certificate from file ($1)",params(1,certpath.get()));
+                    }
+                    break;
+            } // end switch
+
+        } else {
+            log_openssl();
+            if (in) {
+                BIO_free(in);
+                in=NULL;
+            }
+            throw XMLSecurityException("FilesystemCredentialResolver unable to load certificate(s) from file ($1)",params(1,certpath.get()));
+        }
+        if (in) {
+            BIO_free(in);
+            in=NULL;
+        }
+
+        if (m_certs.empty()) {
+            throw XMLSecurityException("FilesystemCredentialResolver unable to load any certificate(s)");
+        }
+
+        // Load any extra CA files.
+        DOMElement* extra=XMLHelper::getFirstChildElement(e,CAPath);
+        while (extra) {
+            if (!extra->hasChildNodes()) {
+                log.warn("skipping empty CAPath element");
+                extra = XMLHelper::getNextSiblingElement(extra,CAPath);
+                continue;
+            }
+            auto_ptr_char capath(extra->getFirstChild()->getNodeValue());
+            x=NULL;
+            p12=NULL;
+            in=BIO_new(BIO_s_file_internal());
+            if (in && BIO_read_filename(in,capath.get())>0) {
+                if (!format_xml || !*format_xml) {
+                    // Determine the cert encoding format dynamically, if not explicitly specified
+                    fformat = getEncodingFormat(in);
+                    log.debug("CA certificate encoding format for (%s) dynamically resolved as (%s)", certpath.get(), formatToString(fformat).c_str());
+                }
+
+                switch (fformat) {
+                    case PEM:
+                        while (x=PEM_read_bio_X509(in,NULL,passwd_callback,const_cast<char*>(certpass.get())))
+                            m_certs.push_back(x);
+                        break;
+
+                    case DER:
+                        x=d2i_X509_bio(in,NULL);
+                        if (x)
+                            m_certs.push_back(x);
+                        else {
+                            log_openssl();
+                            BIO_free(in);
+                            throw XMLSecurityException("FilesystemCredentialResolver unable to load DER CA certificate from file ($1)",params(1,capath.get()));
+                        }
+                        break;
+
+                    case _PKCS12:
+                        p12 = d2i_PKCS12_bio(in, NULL);
+                        if (p12) {
+                            PKCS12_parse(p12, certpass.get(), NULL, &x, NULL);
+                            PKCS12_free(p12);
+                        }
+                        if (x) {
+                            m_certs.push_back(x);
+                            x=NULL;
+                        }
+                        else {
+                            log_openssl();
+                            BIO_free(in);
+                            throw XMLSecurityException("FilesystemCredentialResolver unable to load PKCS12 CA certificate from file ($1)",params(1,capath.get()));
+                        }
+                        break;
+                } //end switch
+
+                BIO_free(in);
+            }
+            else {
+                if (in)
+                    BIO_free(in);
+                log_openssl();
+                log.error("CA file (%s) can't be opened", capath.get());
+                throw XMLSecurityException("FilesystemCredentialResolver can't open CA file ($1)",params(1,capath.get()));
+            }
+            
+            extra = XMLHelper::getNextSiblingElement(extra,CAPath);
+        }
+    }
+    catch (XMLToolingException&) {
+        for (vector<X509*>::iterator j=m_certs.begin(); j!=m_certs.end(); j++)
+            X509_free(*j);
+        throw;
+    }
+
+    // Reflect certs over to XSEC form.
+    for (vector<X509*>::iterator j=m_certs.begin(); j!=m_certs.end(); j++)
+        m_xseccerts.push_back(new OpenSSLCryptoX509(*j));
+}
+
+XSECCryptoKey* FilesystemCredentialResolver::loadKey()
+{
+#ifdef _DEBUG
+    NDC ndc("loadKey");
+#endif
+
+    // Get a EVP_PKEY.
+    EVP_PKEY* pkey=NULL;
+    BIO* in=BIO_new(BIO_s_file_internal());
+    if (in && BIO_read_filename(in,m_keypath.c_str())>0) {
+        switch (m_keyformat) {
+            case PEM:
+                pkey=PEM_read_bio_PrivateKey(in, NULL, passwd_callback, const_cast<char*>(m_keypass.c_str()));
+                break;
+            
+            case DER:
+                pkey=d2i_PrivateKey_bio(in, NULL);
+                break;
+                
+            default: {
+                PKCS12* p12 = d2i_PKCS12_bio(in, NULL);
+                if (p12) {
+                    PKCS12_parse(p12, const_cast<char*>(m_keypass.c_str()), &pkey, NULL, NULL);
+                    PKCS12_free(p12);
+                }
+            }
+        }
+    }
+    if (in)
+        BIO_free(in);
+    
+    // Now map it to an XSEC wrapper.
+    if (pkey) {
+        XSECCryptoKey* ret=NULL;
+        switch (pkey->type) {
+            case EVP_PKEY_RSA:
+                ret=new OpenSSLCryptoKeyRSA(pkey);
+                break;
+                
+            case EVP_PKEY_DSA:
+                ret=new OpenSSLCryptoKeyDSA(pkey);
+                break;
+            
+            default:
+                Category::getInstance(XMLTOOLING_LOGCAT".CredentialResolver").error("unsupported private key type");
+        }
+        EVP_PKEY_free(pkey);
+        if (ret)
+            return ret;
+    }
+
+    log_openssl();
+    throw XMLSecurityException("FilesystemCredentialResolver unable to load private key from file."); 
+}
+
+FilesystemCredentialResolver::~FilesystemCredentialResolver()
+{
+    delete m_key;
+    for_each(m_certs.begin(),m_certs.end(),X509_free);
+    for_each(m_xseccerts.begin(),m_xseccerts.end(),xmltooling::cleanup<XSECCryptoX509>());
+}
+
+void FilesystemCredentialResolver::attach(SSL_CTX* ctx) const
+{
+#ifdef _DEBUG
+    NDC ndc("attach");
+#endif
+    
+    // Attach key.
+    SSL_CTX_set_default_passwd_cb(ctx, passwd_callback);
+    SSL_CTX_set_default_passwd_cb_userdata(ctx, const_cast<char*>(m_keypass.c_str()));
+
+    int ret=0;
+    switch (m_keyformat) {
+        case PEM:
+            ret=SSL_CTX_use_PrivateKey_file(ctx, m_keypath.c_str(), m_keyformat);
+            break;
+            
+        case DER:
+            ret=SSL_CTX_use_RSAPrivateKey_file(ctx, m_keypath.c_str(), m_keyformat);
+            break;
+            
+        default: {
+            BIO* in=BIO_new(BIO_s_file_internal());
+            if (in && BIO_read_filename(in,m_keypath.c_str())>0) {
+                EVP_PKEY* pkey=NULL;
+                PKCS12* p12 = d2i_PKCS12_bio(in, NULL);
+                if (p12) {
+                    PKCS12_parse(p12, const_cast<char*>(m_keypass.c_str()), &pkey, NULL, NULL);
+                    PKCS12_free(p12);
+                    if (pkey) {
+                        ret=SSL_CTX_use_PrivateKey(ctx, pkey);
+                        EVP_PKEY_free(pkey);
+                    }
+                }
+            }
+            if (in)
+                BIO_free(in);
+        }
+    }
+    
+    if (ret!=1) {
+        log_openssl();
+        throw XMLSecurityException("Unable to attach private key to SSL context.");
+    }
+
+    // Attach certs.
+    for (vector<X509*>::const_iterator i=m_certs.begin(); i!=m_certs.end(); i++) {
+        if (i==m_certs.begin()) {
+            if (SSL_CTX_use_certificate(ctx, *i) != 1) {
+                log_openssl();
+                throw XMLSecurityException("Unable to attach client certificate to SSL context.");
+            }
+        }
+        else {
+            // When we add certs, they don't get ref counted, so we need to duplicate them.
+            X509* dup = X509_dup(*i);
+            if (SSL_CTX_add_extra_chain_cert(ctx, dup) != 1) {
+                X509_free(dup);
+                log_openssl();
+                throw XMLSecurityException("Unable to attach CA certificate to SSL context.");
+            }
+        }
+    }
+}
+
+// Used to determine the encoding format of credentials files
+// dynamically. Supports: PEM, DER, PKCS12.
+FilesystemCredentialResolver::format_t FilesystemCredentialResolver::getEncodingFormat(BIO* in) const
+{
+    PKCS12* p12 = NULL;
+    format_t format;
+
+    const int READSIZE = 1;
+    char buf[READSIZE];
+    char b1;
+    int mark;
+
+    try {
+        if ( (mark = BIO_tell(in)) < 0 ) 
+            throw XMLSecurityException("getEncodingFormat: BIO_tell() can't get the file position");
+        if ( BIO_read(in, buf, READSIZE) <= 0 ) 
+            throw XMLSecurityException("getEncodingFormat: BIO_read() can't read from the stream");
+        if ( BIO_seek(in, mark) < 0 ) 
+            throw XMLSecurityException("getEncodingFormat: BIO_seek() can't reset the file position");
+    }
+    catch (...) {
+        log_openssl();
+        throw;
+    }
+
+    b1 = buf[0];
+
+    // This is a slight variation of the Java code by Chad La Joie.
+    //
+    // Check the first byte of the file.  If it's some kind of
+    // DER-encoded structure (including PKCS12), it will begin with ASCII 048.
+    // Otherwise, assume it's PEM.
+    if (b1 !=  48) {
+        format = PEM;
+    } else {
+        // Here we know it's DER-encoded, now try to parse it as a PKCS12
+        // ASN.1 structure.  If it fails, must be another kind of DER-encoded
+        // key/cert structure.  A little inefficient...but it works.
+        if ( (p12=d2i_PKCS12_bio(in,NULL)) == NULL ) {
+            format = DER;
+        } else {
+            format = _PKCS12;
+        }
+        if (p12)
+            PKCS12_free(p12);    
+        if ( BIO_seek(in, mark) < 0 ) {
+            log_openssl();
+            throw XMLSecurityException("getEncodingFormat: BIO_seek() can't reset the file position");
+        }
+    }
+
+    return format;
+}
+
+// Convert key/cert format_t types to a human-meaningful string for debug output
+string FilesystemCredentialResolver::formatToString(format_t format) const
+{
+    switch(format) {
+        case PEM:
+            return "PEM";
+        case DER:
+            return "DER";
+        case _PKCS12:
+            return "PKCS12";
+        default:
+            return "UNKNOWN";
+    }
+}
+
+// Convert key/cert raw XML format attribute (XMLCh[]) to format_t type
+FilesystemCredentialResolver::format_t FilesystemCredentialResolver::xmlFormatToFormat(const XMLCh* format_xml) const
+{
+    static const XMLCh cPEM[] = UNICODE_LITERAL_3(P,E,M);
+    static const XMLCh cDER[] = UNICODE_LITERAL_3(D,E,R);
+    static const XMLCh cPKCS12[] = { chLatin_P, chLatin_K, chLatin_C, chLatin_S, chDigit_1, chDigit_2, chNull };
+    format_t format;
+
+    if (!XMLString::compareString(format_xml,cPEM))
+        format=PEM;
+    else if (!XMLString::compareString(format_xml,cDER))
+        format=DER;
+    else if (!XMLString::compareString(format_xml,cPKCS12))
+        format=_PKCS12;
+    else
+        format=UNKNOWN;
+
+    return format;
+}
index 9ad79df..9f06f64 100644 (file)
-/*\r
- *  Copyright 2001-2005 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * InlineKeyResolver.cpp\r
- * \r
- * Resolves key information directly from recognized KeyInfo structures.\r
- */\r
-\r
-#include "internal.h"\r
-#include "signature/CachingKeyResolver.h"\r
-#include "signature/KeyInfo.h"\r
-#include "util/NDC.h"\r
-#include "util/Threads.h"\r
-#include "util/XMLConstants.h"\r
-#include "validation/ValidatorSuite.h"\r
-\r
-#include <log4cpp/Category.hh>\r
-#include <xercesc/util/XMLUniDefs.hpp>\r
-#include <xsec/dsig/DSIGKeyInfoX509.hpp>\r
-#include <xsec/enc/XSECKeyInfoResolverDefault.hpp>\r
-#include <xsec/enc/OpenSSL/OpenSSLCryptoX509.hpp>\r
-#include <xsec/enc/OpenSSL/OpenSSLCryptoKeyRSA.hpp>\r
-#include <xsec/enc/OpenSSL/OpenSSLCryptoKeyDSA.hpp>\r
-#include <xsec/enc/XSECCryptoException.hpp>\r
-#include <xsec/framework/XSECException.hpp>\r
-\r
-using namespace xmlsignature;\r
-using namespace xmltooling;\r
-using namespace log4cpp;\r
-using namespace std;\r
-\r
-namespace xmlsignature {\r
-    class XMLTOOL_DLLLOCAL InlineKeyResolver : public CachingKeyResolver\r
-    {\r
-    public:\r
-        InlineKeyResolver(const DOMElement* e);\r
-        virtual ~InlineKeyResolver();\r
-\r
-        XSECCryptoKey* resolveKey(const KeyInfo* keyInfo) const;\r
-        XSECCryptoKey* resolveKey(DSIGKeyInfoList* keyInfo) const;\r
-        vector<XSECCryptoX509*>::size_type resolveCertificates(const KeyInfo* keyInfo, ResolvedCertificates& certs) const;\r
-        vector<XSECCryptoX509*>::size_type resolveCertificates(DSIGKeyInfoList* keyInfo, ResolvedCertificates& certs) const;\r
-        XSECCryptoX509CRL* resolveCRL(const KeyInfo* keyInfo) const;\r
-        XSECCryptoX509CRL* resolveCRL(DSIGKeyInfoList* keyInfo) const;\r
-        \r
-        void clearCache() {\r
-            if (m_lock)\r
-                m_lock->wrlock();\r
-            m_cache.clear();\r
-            if (m_lock)\r
-                m_lock->unlock();\r
-        }\r
-        \r
-    private:\r
-        struct XMLTOOL_DLLLOCAL CacheEntry {\r
-            CacheEntry() : m_key(NULL), m_crl(NULL) {}\r
-            ~CacheEntry() {\r
-                delete m_key;\r
-                for_each(m_certs.begin(),m_certs.end(),xmltooling::cleanup<XSECCryptoX509>());\r
-                delete m_crl;\r
-            }\r
-            XSECCryptoKey* m_key;\r
-            vector<XSECCryptoX509*> m_certs;\r
-            XSECCryptoX509CRL* m_crl;\r
-        };\r
-\r
-        void _resolve(const KeyInfo* keyInfo, CacheEntry& entry) const;\r
-        XSECCryptoKey* _resolveKey(const KeyInfo* keyInfo) const;\r
-        vector<XSECCryptoX509*>::size_type _resolveCertificates(const KeyInfo* keyInfo, vector<XSECCryptoX509*>& certs) const;\r
-        XSECCryptoX509CRL* _resolveCRL(const KeyInfo* keyInfo) const;\r
-\r
-        RWLock* m_lock;\r
-        mutable map<const KeyInfo*,CacheEntry> m_cache;\r
-    };\r
-\r
-    KeyResolver* XMLTOOL_DLLLOCAL InlineKeyResolverFactory(const DOMElement* const & e)\r
-    {\r
-        return new InlineKeyResolver(e);\r
-    }\r
-};\r
-\r
-static const XMLCh cache[] = UNICODE_LITERAL_5(c,a,c,h,e);\r
-\r
-InlineKeyResolver::InlineKeyResolver(const DOMElement* e) : m_lock(NULL)\r
-{\r
-    const XMLCh* flag = e ? e->getAttributeNS(NULL,cache) : NULL;\r
-    if (flag && XMLString::equals(flag,XMLConstants::XML_TRUE) || XMLString::equals(flag,XMLConstants::XML_ONE))\r
-        m_lock=RWLock::create();\r
-}\r
-\r
-InlineKeyResolver::~InlineKeyResolver()\r
-{\r
-    clearCache();\r
-    delete m_lock;\r
-}\r
-\r
-void InlineKeyResolver::_resolve(const KeyInfo* keyInfo, CacheEntry& entry) const\r
-{\r
-    if (_resolveCertificates(keyInfo, entry.m_certs)>0)\r
-        entry.m_key = entry.m_certs.front()->clonePublicKey();\r
-    else\r
-        entry.m_key = _resolveKey(keyInfo);\r
-    entry.m_crl = _resolveCRL(keyInfo);\r
-}\r
-\r
-XSECCryptoKey* InlineKeyResolver::_resolveKey(const KeyInfo* keyInfo) const\r
-{\r
-#ifdef _DEBUG\r
-    NDC ndc("_resolveKey");\r
-#endif\r
-    Category& log=Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver");\r
-\r
-    if (!keyInfo)\r
-        return NULL;\r
-\r
-    // Check for ds:X509Data\r
-    const vector<X509Data*>& x509Datas=keyInfo->getX509Datas();\r
-    for (vector<X509Data*>::const_iterator j=x509Datas.begin(); j!=x509Datas.end(); ++j) {\r
-        try {\r
-            const vector<X509Certificate*> x509Certs=const_cast<const X509Data*>(*j)->getX509Certificates();\r
-            if (!x509Certs.empty()) {\r
-                auto_ptr_char x(x509Certs.front()->getValue());\r
-                if (!x.get()) {\r
-                    log.warn("skipping empty ds:X509Certificate");\r
-                }\r
-                else {\r
-                    log.debug("resolving ds:X509Certificate");\r
-                    auto_ptr<XSECCryptoX509> x509(XSECPlatformUtils::g_cryptoProvider->X509());\r
-                    x509->loadX509Base64Bin(x.get(), strlen(x.get()));\r
-                    return x509->clonePublicKey();\r
-                }\r
-            }\r
-        }\r
-        catch(XSECException& e) {\r
-            auto_ptr_char temp(e.getMsg());\r
-            log.error("caught XML-Security exception loading certificate: %s", temp.get());\r
-        }\r
-        catch(XSECCryptoException& e) {\r
-            log.error("caught XML-Security exception loading certificate: %s", e.getMsg());\r
-        }\r
-    }\r
-\r
-    // Check for ds:KeyValue\r
-    const vector<KeyValue*>& keyValues = keyInfo->getKeyValues();\r
-    for (vector<KeyValue*>::const_iterator i=keyValues.begin(); i!=keyValues.end(); ++i) {\r
-        try {\r
-            SchemaValidators.validate(*i);    // see if it's a "valid" key\r
-            RSAKeyValue* rsakv = (*i)->getRSAKeyValue();\r
-            if (rsakv) {\r
-                log.debug("resolving ds:RSAKeyValue");\r
-                auto_ptr_char mod(rsakv->getModulus()->getValue());\r
-                auto_ptr_char exp(rsakv->getExponent()->getValue());\r
-                auto_ptr<XSECCryptoKeyRSA> rsa(XSECPlatformUtils::g_cryptoProvider->keyRSA());\r
-                rsa->loadPublicModulusBase64BigNums(mod.get(), strlen(mod.get()));\r
-                rsa->loadPublicExponentBase64BigNums(exp.get(), strlen(exp.get()));\r
-                return rsa.release();\r
-            }\r
-            DSAKeyValue* dsakv = (*i)->getDSAKeyValue();\r
-            if (dsakv) {\r
-                log.debug("resolving ds:DSAKeyValue");\r
-                auto_ptr<XSECCryptoKeyDSA> dsa(XSECPlatformUtils::g_cryptoProvider->keyDSA());\r
-                auto_ptr_char y(dsakv->getY()->getValue());\r
-                dsa->loadYBase64BigNums(y.get(), strlen(y.get()));\r
-                if (dsakv->getP()) {\r
-                    auto_ptr_char p(dsakv->getP()->getValue());\r
-                    dsa->loadPBase64BigNums(p.get(), strlen(p.get()));\r
-                }\r
-                if (dsakv->getQ()) {\r
-                    auto_ptr_char q(dsakv->getQ()->getValue());\r
-                    dsa->loadQBase64BigNums(q.get(), strlen(q.get()));\r
-                }\r
-                if (dsakv->getG()) {\r
-                    auto_ptr_char g(dsakv->getG()->getValue());\r
-                    dsa->loadGBase64BigNums(g.get(), strlen(g.get()));\r
-                }\r
-                return dsa.release();\r
-            }\r
-        }\r
-        catch (ValidationException& ex) {\r
-            log.warn("skipping invalid ds:KeyValue (%s)", ex.what());\r
-        }\r
-        catch(XSECException& e) {\r
-            auto_ptr_char temp(e.getMsg());\r
-            log.error("caught XML-Security exception loading key: %s", temp.get());\r
-        }\r
-        catch(XSECCryptoException& e) {\r
-            log.error("caught XML-Security exception loading key: %s", e.getMsg());\r
-        }\r
-    }\r
-\r
-    log.warn("unable to resolve key");\r
-    return NULL;\r
-}\r
-\r
-vector<XSECCryptoX509*>::size_type InlineKeyResolver::_resolveCertificates(\r
-    const KeyInfo* keyInfo, vector<XSECCryptoX509*>& certs\r
-    ) const\r
-{\r
-#ifdef _DEBUG\r
-    NDC ndc("_resolveCertificates");\r
-#endif\r
-    Category& log=Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver");\r
-\r
-    if (!keyInfo)\r
-        return 0;\r
-\r
-    // Check for ds:X509Data\r
-    const vector<X509Data*>& x509Datas=keyInfo->getX509Datas();\r
-    for (vector<X509Data*>::const_iterator j=x509Datas.begin(); certs.empty() && j!=x509Datas.end(); ++j) {\r
-        const vector<X509Certificate*> x509Certs=const_cast<const X509Data*>(*j)->getX509Certificates();\r
-        for (vector<X509Certificate*>::const_iterator k=x509Certs.begin(); k!=x509Certs.end(); ++k) {\r
-            try {\r
-                auto_ptr_char x((*k)->getValue());\r
-                if (!x.get()) {\r
-                    log.warn("skipping empty ds:X509Certificate");\r
-                }\r
-                else {\r
-                    log.debug("resolving ds:X509Certificate");\r
-                    auto_ptr<XSECCryptoX509> x509(XSECPlatformUtils::g_cryptoProvider->X509());\r
-                    x509->loadX509Base64Bin(x.get(), strlen(x.get()));\r
-                    certs.push_back(x509.release());\r
-                }\r
-            }\r
-            catch(XSECException& e) {\r
-                auto_ptr_char temp(e.getMsg());\r
-                log.error("caught XML-Security exception loading certificate: %s", temp.get());\r
-            }\r
-            catch(XSECCryptoException& e) {\r
-                log.error("caught XML-Security exception loading certificate: %s", e.getMsg());\r
-            }\r
-        }\r
-    }\r
-    if (log.isDebugEnabled()) {\r
-        log.debug("resolved %d certificate%s", certs.size(), certs.size()==1 ? "" : "s");\r
-    }\r
-    return certs.size();\r
-}\r
-\r
-XSECCryptoX509CRL* InlineKeyResolver::_resolveCRL(const KeyInfo* keyInfo) const\r
-{\r
-#ifdef _DEBUG\r
-    NDC ndc("_resolveCRL");\r
-#endif\r
-    Category& log=Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver");\r
-\r
-    if (!keyInfo)\r
-        return NULL;\r
-\r
-    // Check for ds:X509Data\r
-    const vector<X509Data*>& x509Datas=keyInfo->getX509Datas();\r
-    for (vector<X509Data*>::const_iterator j=x509Datas.begin(); j!=x509Datas.end(); ++j) {\r
-        const vector<X509CRL*> x509CRLs=const_cast<const X509Data*>(*j)->getX509CRLs();\r
-        for (vector<X509CRL*>::const_iterator k=x509CRLs.begin(); k!=x509CRLs.end(); ++k) {\r
-            try {\r
-                auto_ptr_char x((*k)->getValue());\r
-                if (!x.get()) {\r
-                    log.warn("skipping empty ds:X509CRL");\r
-                }\r
-                else {\r
-                    log.debug("resolving ds:X509CRL");\r
-                    auto_ptr<XSECCryptoX509CRL> crl(XMLToolingConfig::getConfig().X509CRL());\r
-                    crl->loadX509CRLBase64Bin(x.get(), strlen(x.get()));\r
-                    return crl.release();\r
-                }\r
-            }\r
-            catch(XSECException& e) {\r
-                auto_ptr_char temp(e.getMsg());\r
-                log.error("caught XML-Security exception loading certificate: %s", temp.get());\r
-            }\r
-            catch(XSECCryptoException& e) {\r
-                log.error("caught XML-Security exception loading certificate: %s", e.getMsg());\r
-            }\r
-        }\r
-    }\r
-    return NULL;\r
-}\r
-\r
-XSECCryptoKey* InlineKeyResolver::resolveKey(const KeyInfo* keyInfo) const\r
-{\r
-    // Caching?\r
-    if (m_lock) {\r
-        // Get read lock.\r
-        m_lock->rdlock();\r
-        map<const KeyInfo*,CacheEntry>::iterator i=m_cache.find(keyInfo);\r
-        if (i != m_cache.end()) {\r
-            // Found in cache, so just return the results.\r
-            SharedLock locker(m_lock,false);\r
-            return i->second.m_key ? i->second.m_key->clone() : NULL;\r
-        }\r
-        else {\r
-            // Elevate lock.\r
-            m_lock->unlock();\r
-            m_lock->wrlock();\r
-            SharedLock locker(m_lock,false);\r
-            // Recheck cache.\r
-            i=m_cache.find(keyInfo);\r
-            if (i == m_cache.end()) {\r
-                i = m_cache.insert(make_pair(keyInfo,CacheEntry())).first;\r
-                _resolve(i->first, i->second);\r
-            }\r
-            return i->second.m_key ? i->second.m_key->clone() : NULL;\r
-        }\r
-    }\r
-    return _resolveKey(keyInfo);\r
-}\r
-\r
-XSECCryptoX509CRL* InlineKeyResolver::resolveCRL(const KeyInfo* keyInfo) const\r
-{\r
-    // Caching?\r
-    if (m_lock) {\r
-        // Get read lock.\r
-        m_lock->rdlock();\r
-        map<const KeyInfo*,CacheEntry>::iterator i=m_cache.find(keyInfo);\r
-        if (i != m_cache.end()) {\r
-            // Found in cache, so just return the results.\r
-            SharedLock locker(m_lock,false);\r
-            return i->second.m_crl ? i->second.m_crl->clone() : NULL;\r
-        }\r
-        else {\r
-            // Elevate lock.\r
-            m_lock->unlock();\r
-            m_lock->wrlock();\r
-            SharedLock locker(m_lock,false);\r
-            // Recheck cache.\r
-            i=m_cache.find(keyInfo);\r
-            if (i == m_cache.end()) {\r
-                i = m_cache.insert(make_pair(keyInfo,CacheEntry())).first;\r
-                _resolve(i->first, i->second);\r
-            }\r
-            return i->second.m_crl ? i->second.m_crl->clone() : NULL;\r
-        }\r
-    }\r
-    return _resolveCRL(keyInfo);\r
-}\r
-\r
-vector<XSECCryptoX509*>::size_type InlineKeyResolver::resolveCertificates(\r
-    const KeyInfo* keyInfo, ResolvedCertificates& certs\r
-    ) const\r
-{\r
-    // Caching?\r
-    if (m_lock) {\r
-        // Get read lock.\r
-        m_lock->rdlock();\r
-        map<const KeyInfo*,CacheEntry>::iterator i=m_cache.find(keyInfo);\r
-        if (i != m_cache.end()) {\r
-            // Found in cache, so just return the results.\r
-            SharedLock locker(m_lock,false);\r
-            accessCertificates(certs).assign(i->second.m_certs.begin(), i->second.m_certs.end());\r
-            accessOwned(certs) = false;\r
-            return accessCertificates(certs).size();\r
-        }\r
-        else {\r
-            // Elevate lock.\r
-            m_lock->unlock();\r
-            m_lock->wrlock();\r
-            SharedLock locker(m_lock,false);\r
-            // Recheck cache.\r
-            i=m_cache.find(keyInfo);\r
-            if (i == m_cache.end()) {\r
-                i = m_cache.insert(make_pair(keyInfo,CacheEntry())).first;\r
-                _resolve(i->first, i->second);\r
-            }\r
-            accessCertificates(certs).assign(i->second.m_certs.begin(), i->second.m_certs.end());\r
-            accessOwned(certs) = false;\r
-            return accessCertificates(certs).size();\r
-        }\r
-    }\r
-    accessOwned(certs) = true;\r
-    return _resolveCertificates(keyInfo, accessCertificates(certs));\r
-}\r
-\r
-XSECCryptoKey* InlineKeyResolver::resolveKey(DSIGKeyInfoList* keyInfo) const\r
-{\r
-#ifdef _DEBUG\r
-    NDC ndc("resolveKey");\r
-#endif\r
-\r
-    if (!keyInfo)\r
-        return NULL;\r
-\r
-    // Default resolver handles RSA/DSAKeyValue and X509Certificate elements.\r
-    try {\r
-        XSECKeyInfoResolverDefault def;\r
-        return def.resolveKey(keyInfo);\r
-    }\r
-    catch(XSECException& e) {\r
-        auto_ptr_char temp(e.getMsg());\r
-        Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver").error("caught XML-Security exception loading certificate: %s", temp.get());\r
-    }\r
-    catch(XSECCryptoException& e) {\r
-        Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver").error("caught XML-Security exception loading certificate: %s", e.getMsg());\r
-    }\r
-    return NULL;\r
-}\r
-\r
-vector<XSECCryptoX509*>::size_type InlineKeyResolver::resolveCertificates(\r
-    DSIGKeyInfoList* keyInfo, ResolvedCertificates& certs\r
-    ) const\r
-{\r
-    accessCertificates(certs).clear();\r
-    accessOwned(certs) = false;\r
-\r
-    if (!keyInfo)\r
-        return 0;\r
-\r
-       DSIGKeyInfoList::size_type sz = keyInfo->getSize();\r
-    for (DSIGKeyInfoList::size_type i=0; accessCertificates(certs).empty() && i<sz; ++i) {\r
-        if (keyInfo->item(i)->getKeyInfoType()==DSIGKeyInfo::KEYINFO_X509) {\r
-            DSIGKeyInfoX509* x509 = static_cast<DSIGKeyInfoX509*>(keyInfo->item(i));\r
-            int count = x509->getCertificateListSize();\r
-            for (int j=0; j<count; ++j) {\r
-                accessCertificates(certs).push_back(x509->getCertificateCryptoItem(j));\r
-            }\r
-        }\r
-    }\r
-    return accessCertificates(certs).size();\r
-}\r
-\r
-XSECCryptoX509CRL* InlineKeyResolver::resolveCRL(DSIGKeyInfoList* keyInfo) const\r
-{\r
-#ifdef _DEBUG\r
-    NDC ndc("resolveCRL");\r
-#endif\r
-\r
-    if (!keyInfo)\r
-        return NULL;\r
-\r
-    DSIGKeyInfoList::size_type sz = keyInfo->getSize();\r
-    for (DSIGKeyInfoList::size_type i=0; i<sz; ++i) {\r
-        if (keyInfo->item(i)->getKeyInfoType()==DSIGKeyInfo::KEYINFO_X509) {\r
-            auto_ptr_char buf(static_cast<DSIGKeyInfoX509*>(keyInfo->item(i))->getX509CRL());\r
-            if (buf.get()) {\r
-                try {\r
-                    auto_ptr<XSECCryptoX509CRL> crlobj(XMLToolingConfig::getConfig().X509CRL());\r
-                    crlobj->loadX509CRLBase64Bin(buf.get(), strlen(buf.get()));\r
-                    return crlobj.release();\r
-                }\r
-                catch(XSECException& e) {\r
-                    auto_ptr_char temp(e.getMsg());\r
-                    Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver").error("caught XML-Security exception loading CRL: %s", temp.get());\r
-                }\r
-                catch(XSECCryptoException& e) {\r
-                    Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver").error("caught XML-Security exception loading CRL: %s", e.getMsg());\r
-                }\r
-            }\r
-        }\r
-    }\r
-    return NULL;\r
-}\r
+/*
+ *  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.
+ */
+
+/**
+ * InlineKeyResolver.cpp
+ * 
+ * Resolves key information directly from recognized KeyInfo structures.
+ */
+
+#include "internal.h"
+#include "signature/CachingKeyResolver.h"
+#include "signature/KeyInfo.h"
+#include "util/NDC.h"
+#include "util/Threads.h"
+#include "util/XMLConstants.h"
+#include "validation/ValidatorSuite.h"
+
+#include <log4cpp/Category.hh>
+#include <xercesc/util/XMLUniDefs.hpp>
+#include <xsec/dsig/DSIGKeyInfoX509.hpp>
+#include <xsec/enc/XSECKeyInfoResolverDefault.hpp>
+#include <xsec/enc/OpenSSL/OpenSSLCryptoX509.hpp>
+#include <xsec/enc/OpenSSL/OpenSSLCryptoKeyRSA.hpp>
+#include <xsec/enc/OpenSSL/OpenSSLCryptoKeyDSA.hpp>
+#include <xsec/enc/XSECCryptoException.hpp>
+#include <xsec/framework/XSECException.hpp>
+
+using namespace xmlsignature;
+using namespace xmltooling;
+using namespace log4cpp;
+using namespace std;
+
+namespace xmlsignature {
+    class XMLTOOL_DLLLOCAL InlineKeyResolver : public CachingKeyResolver
+    {
+    public:
+        InlineKeyResolver(const DOMElement* e);
+        virtual ~InlineKeyResolver();
+
+        XSECCryptoKey* resolveKey(const KeyInfo* keyInfo) const;
+        XSECCryptoKey* resolveKey(DSIGKeyInfoList* keyInfo) const;
+        vector<XSECCryptoX509*>::size_type resolveCertificates(const KeyInfo* keyInfo, ResolvedCertificates& certs) const;
+        vector<XSECCryptoX509*>::size_type resolveCertificates(DSIGKeyInfoList* keyInfo, ResolvedCertificates& certs) const;
+        XSECCryptoX509CRL* resolveCRL(const KeyInfo* keyInfo) const;
+        XSECCryptoX509CRL* resolveCRL(DSIGKeyInfoList* keyInfo) const;
+        
+        void clearCache() {
+            if (m_lock)
+                m_lock->wrlock();
+            m_cache.clear();
+            if (m_lock)
+                m_lock->unlock();
+        }
+        
+    private:
+        struct XMLTOOL_DLLLOCAL CacheEntry {
+            CacheEntry() : m_key(NULL), m_crl(NULL) {}
+            ~CacheEntry() {
+                delete m_key;
+                for_each(m_certs.begin(),m_certs.end(),xmltooling::cleanup<XSECCryptoX509>());
+                delete m_crl;
+            }
+            XSECCryptoKey* m_key;
+            vector<XSECCryptoX509*> m_certs;
+            XSECCryptoX509CRL* m_crl;
+        };
+
+        void _resolve(const KeyInfo* keyInfo, CacheEntry& entry) const;
+        XSECCryptoKey* _resolveKey(const KeyInfo* keyInfo) const;
+        vector<XSECCryptoX509*>::size_type _resolveCertificates(const KeyInfo* keyInfo, vector<XSECCryptoX509*>& certs) const;
+        XSECCryptoX509CRL* _resolveCRL(const KeyInfo* keyInfo) const;
+
+        RWLock* m_lock;
+        mutable map<const KeyInfo*,CacheEntry> m_cache;
+    };
+
+    KeyResolver* XMLTOOL_DLLLOCAL InlineKeyResolverFactory(const DOMElement* const & e)
+    {
+        return new InlineKeyResolver(e);
+    }
+};
+
+static const XMLCh cache[] = UNICODE_LITERAL_5(c,a,c,h,e);
+
+InlineKeyResolver::InlineKeyResolver(const DOMElement* e) : m_lock(NULL)
+{
+    const XMLCh* flag = e ? e->getAttributeNS(NULL,cache) : NULL;
+    if (flag && XMLString::equals(flag,XMLConstants::XML_TRUE) || XMLString::equals(flag,XMLConstants::XML_ONE))
+        m_lock=RWLock::create();
+}
+
+InlineKeyResolver::~InlineKeyResolver()
+{
+    clearCache();
+    delete m_lock;
+}
+
+void InlineKeyResolver::_resolve(const KeyInfo* keyInfo, CacheEntry& entry) const
+{
+    if (_resolveCertificates(keyInfo, entry.m_certs)>0)
+        entry.m_key = entry.m_certs.front()->clonePublicKey();
+    else
+        entry.m_key = _resolveKey(keyInfo);
+    entry.m_crl = _resolveCRL(keyInfo);
+}
+
+XSECCryptoKey* InlineKeyResolver::_resolveKey(const KeyInfo* keyInfo) const
+{
+#ifdef _DEBUG
+    NDC ndc("_resolveKey");
+#endif
+    Category& log=Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver");
+
+    if (!keyInfo)
+        return NULL;
+
+    // Check for ds:X509Data
+    const vector<X509Data*>& x509Datas=keyInfo->getX509Datas();
+    for (vector<X509Data*>::const_iterator j=x509Datas.begin(); j!=x509Datas.end(); ++j) {
+        try {
+            const vector<X509Certificate*> x509Certs=const_cast<const X509Data*>(*j)->getX509Certificates();
+            if (!x509Certs.empty()) {
+                auto_ptr_char x(x509Certs.front()->getValue());
+                if (!x.get()) {
+                    log.warn("skipping empty ds:X509Certificate");
+                }
+                else {
+                    log.debug("resolving ds:X509Certificate");
+                    auto_ptr<XSECCryptoX509> x509(XSECPlatformUtils::g_cryptoProvider->X509());
+                    x509->loadX509Base64Bin(x.get(), strlen(x.get()));
+                    return x509->clonePublicKey();
+                }
+            }
+        }
+        catch(XSECException& e) {
+            auto_ptr_char temp(e.getMsg());
+            log.error("caught XML-Security exception loading certificate: %s", temp.get());
+        }
+        catch(XSECCryptoException& e) {
+            log.error("caught XML-Security exception loading certificate: %s", e.getMsg());
+        }
+    }
+
+    // Check for ds:KeyValue
+    const vector<KeyValue*>& keyValues = keyInfo->getKeyValues();
+    for (vector<KeyValue*>::const_iterator i=keyValues.begin(); i!=keyValues.end(); ++i) {
+        try {
+            SchemaValidators.validate(*i);    // see if it's a "valid" key
+            RSAKeyValue* rsakv = (*i)->getRSAKeyValue();
+            if (rsakv) {
+                log.debug("resolving ds:RSAKeyValue");
+                auto_ptr_char mod(rsakv->getModulus()->getValue());
+                auto_ptr_char exp(rsakv->getExponent()->getValue());
+                auto_ptr<XSECCryptoKeyRSA> rsa(XSECPlatformUtils::g_cryptoProvider->keyRSA());
+                rsa->loadPublicModulusBase64BigNums(mod.get(), strlen(mod.get()));
+                rsa->loadPublicExponentBase64BigNums(exp.get(), strlen(exp.get()));
+                return rsa.release();
+            }
+            DSAKeyValue* dsakv = (*i)->getDSAKeyValue();
+            if (dsakv) {
+                log.debug("resolving ds:DSAKeyValue");
+                auto_ptr<XSECCryptoKeyDSA> dsa(XSECPlatformUtils::g_cryptoProvider->keyDSA());
+                auto_ptr_char y(dsakv->getY()->getValue());
+                dsa->loadYBase64BigNums(y.get(), strlen(y.get()));
+                if (dsakv->getP()) {
+                    auto_ptr_char p(dsakv->getP()->getValue());
+                    dsa->loadPBase64BigNums(p.get(), strlen(p.get()));
+                }
+                if (dsakv->getQ()) {
+                    auto_ptr_char q(dsakv->getQ()->getValue());
+                    dsa->loadQBase64BigNums(q.get(), strlen(q.get()));
+                }
+                if (dsakv->getG()) {
+                    auto_ptr_char g(dsakv->getG()->getValue());
+                    dsa->loadGBase64BigNums(g.get(), strlen(g.get()));
+                }
+                return dsa.release();
+            }
+        }
+        catch (ValidationException& ex) {
+            log.warn("skipping invalid ds:KeyValue (%s)", ex.what());
+        }
+        catch(XSECException& e) {
+            auto_ptr_char temp(e.getMsg());
+            log.error("caught XML-Security exception loading key: %s", temp.get());
+        }
+        catch(XSECCryptoException& e) {
+            log.error("caught XML-Security exception loading key: %s", e.getMsg());
+        }
+    }
+
+    log.warn("unable to resolve key");
+    return NULL;
+}
+
+vector<XSECCryptoX509*>::size_type InlineKeyResolver::_resolveCertificates(
+    const KeyInfo* keyInfo, vector<XSECCryptoX509*>& certs
+    ) const
+{
+#ifdef _DEBUG
+    NDC ndc("_resolveCertificates");
+#endif
+    Category& log=Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver");
+
+    if (!keyInfo)
+        return 0;
+
+    // Check for ds:X509Data
+    const vector<X509Data*>& x509Datas=keyInfo->getX509Datas();
+    for (vector<X509Data*>::const_iterator j=x509Datas.begin(); certs.empty() && j!=x509Datas.end(); ++j) {
+        const vector<X509Certificate*> x509Certs=const_cast<const X509Data*>(*j)->getX509Certificates();
+        for (vector<X509Certificate*>::const_iterator k=x509Certs.begin(); k!=x509Certs.end(); ++k) {
+            try {
+                auto_ptr_char x((*k)->getValue());
+                if (!x.get()) {
+                    log.warn("skipping empty ds:X509Certificate");
+                }
+                else {
+                    log.debug("resolving ds:X509Certificate");
+                    auto_ptr<XSECCryptoX509> x509(XSECPlatformUtils::g_cryptoProvider->X509());
+                    x509->loadX509Base64Bin(x.get(), strlen(x.get()));
+                    certs.push_back(x509.release());
+                }
+            }
+            catch(XSECException& e) {
+                auto_ptr_char temp(e.getMsg());
+                log.error("caught XML-Security exception loading certificate: %s", temp.get());
+            }
+            catch(XSECCryptoException& e) {
+                log.error("caught XML-Security exception loading certificate: %s", e.getMsg());
+            }
+        }
+    }
+    if (log.isDebugEnabled()) {
+        log.debug("resolved %d certificate%s", certs.size(), certs.size()==1 ? "" : "s");
+    }
+    return certs.size();
+}
+
+XSECCryptoX509CRL* InlineKeyResolver::_resolveCRL(const KeyInfo* keyInfo) const
+{
+#ifdef _DEBUG
+    NDC ndc("_resolveCRL");
+#endif
+    Category& log=Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver");
+
+    if (!keyInfo)
+        return NULL;
+
+    // Check for ds:X509Data
+    const vector<X509Data*>& x509Datas=keyInfo->getX509Datas();
+    for (vector<X509Data*>::const_iterator j=x509Datas.begin(); j!=x509Datas.end(); ++j) {
+        const vector<X509CRL*> x509CRLs=const_cast<const X509Data*>(*j)->getX509CRLs();
+        for (vector<X509CRL*>::const_iterator k=x509CRLs.begin(); k!=x509CRLs.end(); ++k) {
+            try {
+                auto_ptr_char x((*k)->getValue());
+                if (!x.get()) {
+                    log.warn("skipping empty ds:X509CRL");
+                }
+                else {
+                    log.debug("resolving ds:X509CRL");
+                    auto_ptr<XSECCryptoX509CRL> crl(XMLToolingConfig::getConfig().X509CRL());
+                    crl->loadX509CRLBase64Bin(x.get(), strlen(x.get()));
+                    return crl.release();
+                }
+            }
+            catch(XSECException& e) {
+                auto_ptr_char temp(e.getMsg());
+                log.error("caught XML-Security exception loading certificate: %s", temp.get());
+            }
+            catch(XSECCryptoException& e) {
+                log.error("caught XML-Security exception loading certificate: %s", e.getMsg());
+            }
+        }
+    }
+    return NULL;
+}
+
+XSECCryptoKey* InlineKeyResolver::resolveKey(const KeyInfo* keyInfo) const
+{
+    // Caching?
+    if (m_lock) {
+        // Get read lock.
+        m_lock->rdlock();
+        map<const KeyInfo*,CacheEntry>::iterator i=m_cache.find(keyInfo);
+        if (i != m_cache.end()) {
+            // Found in cache, so just return the results.
+            SharedLock locker(m_lock,false);
+            return i->second.m_key ? i->second.m_key->clone() : NULL;
+        }
+        else {
+            // Elevate lock.
+            m_lock->unlock();
+            m_lock->wrlock();
+            SharedLock locker(m_lock,false);
+            // Recheck cache.
+            i=m_cache.find(keyInfo);
+            if (i == m_cache.end()) {
+                i = m_cache.insert(make_pair(keyInfo,CacheEntry())).first;
+                _resolve(i->first, i->second);
+            }
+            return i->second.m_key ? i->second.m_key->clone() : NULL;
+        }
+    }
+    return _resolveKey(keyInfo);
+}
+
+XSECCryptoX509CRL* InlineKeyResolver::resolveCRL(const KeyInfo* keyInfo) const
+{
+    // Caching?
+    if (m_lock) {
+        // Get read lock.
+        m_lock->rdlock();
+        map<const KeyInfo*,CacheEntry>::iterator i=m_cache.find(keyInfo);
+        if (i != m_cache.end()) {
+            // Found in cache, so just return the results.
+            SharedLock locker(m_lock,false);
+            return i->second.m_crl ? i->second.m_crl->clone() : NULL;
+        }
+        else {
+            // Elevate lock.
+            m_lock->unlock();
+            m_lock->wrlock();
+            SharedLock locker(m_lock,false);
+            // Recheck cache.
+            i=m_cache.find(keyInfo);
+            if (i == m_cache.end()) {
+                i = m_cache.insert(make_pair(keyInfo,CacheEntry())).first;
+                _resolve(i->first, i->second);
+            }
+            return i->second.m_crl ? i->second.m_crl->clone() : NULL;
+        }
+    }
+    return _resolveCRL(keyInfo);
+}
+
+vector<XSECCryptoX509*>::size_type InlineKeyResolver::resolveCertificates(
+    const KeyInfo* keyInfo, ResolvedCertificates& certs
+    ) const
+{
+    // Caching?
+    if (m_lock) {
+        // Get read lock.
+        m_lock->rdlock();
+        map<const KeyInfo*,CacheEntry>::iterator i=m_cache.find(keyInfo);
+        if (i != m_cache.end()) {
+            // Found in cache, so just return the results.
+            SharedLock locker(m_lock,false);
+            accessCertificates(certs).assign(i->second.m_certs.begin(), i->second.m_certs.end());
+            accessOwned(certs) = false;
+            return accessCertificates(certs).size();
+        }
+        else {
+            // Elevate lock.
+            m_lock->unlock();
+            m_lock->wrlock();
+            SharedLock locker(m_lock,false);
+            // Recheck cache.
+            i=m_cache.find(keyInfo);
+            if (i == m_cache.end()) {
+                i = m_cache.insert(make_pair(keyInfo,CacheEntry())).first;
+                _resolve(i->first, i->second);
+            }
+            accessCertificates(certs).assign(i->second.m_certs.begin(), i->second.m_certs.end());
+            accessOwned(certs) = false;
+            return accessCertificates(certs).size();
+        }
+    }
+    accessOwned(certs) = true;
+    return _resolveCertificates(keyInfo, accessCertificates(certs));
+}
+
+XSECCryptoKey* InlineKeyResolver::resolveKey(DSIGKeyInfoList* keyInfo) const
+{
+#ifdef _DEBUG
+    NDC ndc("resolveKey");
+#endif
+
+    if (!keyInfo)
+        return NULL;
+
+    // Default resolver handles RSA/DSAKeyValue and X509Certificate elements.
+    try {
+        XSECKeyInfoResolverDefault def;
+        return def.resolveKey(keyInfo);
+    }
+    catch(XSECException& e) {
+        auto_ptr_char temp(e.getMsg());
+        Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver").error("caught XML-Security exception loading certificate: %s", temp.get());
+    }
+    catch(XSECCryptoException& e) {
+        Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver").error("caught XML-Security exception loading certificate: %s", e.getMsg());
+    }
+    return NULL;
+}
+
+vector<XSECCryptoX509*>::size_type InlineKeyResolver::resolveCertificates(
+    DSIGKeyInfoList* keyInfo, ResolvedCertificates& certs
+    ) const
+{
+    accessCertificates(certs).clear();
+    accessOwned(certs) = false;
+
+    if (!keyInfo)
+        return 0;
+
+       DSIGKeyInfoList::size_type sz = keyInfo->getSize();
+    for (DSIGKeyInfoList::size_type i=0; accessCertificates(certs).empty() && i<sz; ++i) {
+        if (keyInfo->item(i)->getKeyInfoType()==DSIGKeyInfo::KEYINFO_X509) {
+            DSIGKeyInfoX509* x509 = static_cast<DSIGKeyInfoX509*>(keyInfo->item(i));
+            int count = x509->getCertificateListSize();
+            for (int j=0; j<count; ++j) {
+                accessCertificates(certs).push_back(x509->getCertificateCryptoItem(j));
+            }
+        }
+    }
+    return accessCertificates(certs).size();
+}
+
+XSECCryptoX509CRL* InlineKeyResolver::resolveCRL(DSIGKeyInfoList* keyInfo) const
+{
+#ifdef _DEBUG
+    NDC ndc("resolveCRL");
+#endif
+
+    if (!keyInfo)
+        return NULL;
+
+    DSIGKeyInfoList::size_type sz = keyInfo->getSize();
+    for (DSIGKeyInfoList::size_type i=0; i<sz; ++i) {
+        if (keyInfo->item(i)->getKeyInfoType()==DSIGKeyInfo::KEYINFO_X509) {
+            auto_ptr_char buf(static_cast<DSIGKeyInfoX509*>(keyInfo->item(i))->getX509CRL());
+            if (buf.get()) {
+                try {
+                    auto_ptr<XSECCryptoX509CRL> crlobj(XMLToolingConfig::getConfig().X509CRL());
+                    crlobj->loadX509CRLBase64Bin(buf.get(), strlen(buf.get()));
+                    return crlobj.release();
+                }
+                catch(XSECException& e) {
+                    auto_ptr_char temp(e.getMsg());
+                    Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver").error("caught XML-Security exception loading CRL: %s", temp.get());
+                }
+                catch(XSECCryptoException& e) {
+                    Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver").error("caught XML-Security exception loading CRL: %s", e.getMsg());
+                }
+            }
+        }
+    }
+    return NULL;
+}
index ac65a40..e1bb903 100644 (file)
@@ -1,64 +1,64 @@
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * SignatureValidator.cpp\r
- * \r
- * Validator for signatures based on an externally-supplied key \r
- */\r
\r
-#include "internal.h"\r
-#include "signature/SignatureValidator.h"\r
-\r
-#include <xsec/enc/XSECCryptoException.hpp>\r
-#include <xsec/framework/XSECException.hpp>\r
-\r
-using namespace xmlsignature;\r
-using namespace xmltooling;\r
-using namespace std;\r
-\r
-void SignatureValidator::validate(const XMLObject* xmlObject) const\r
-{\r
-    const Signature* sigObj=dynamic_cast<const Signature*>(xmlObject);\r
-    if (!sigObj)\r
-        throw ValidationException("Validator only applies to Signature objects.");\r
-    validate(sigObj);\r
-}\r
-\r
-void SignatureValidator::validate(const Signature* sigObj) const\r
-{\r
-    DSIGSignature* sig=sigObj->getXMLSignature();\r
-    if (!sig)\r
-        throw ValidationException("Signature does not exist yet.");\r
-    else if (!m_key && !m_resolver)\r
-        throw ValidationException("No KeyResolver or signing key set on Validator.");\r
-\r
-    try {\r
-        XSECCryptoKey* key = m_key ? m_key->clone() : m_resolver->resolveKey(sig->getKeyInfoList());\r
-        if (!key)\r
-            throw ValidationException("Unable to resolve signing key.");\r
-        sig->setSigningKey(key);\r
-        if (!sig->verify())\r
-            throw ValidationException("Digital signature does not validate with the given key.");\r
-    }\r
-    catch(XSECException& e) {\r
-        auto_ptr_char temp(e.getMsg());\r
-        throw ValidationException(string("Caught an XMLSecurity exception verifying signature: ") + temp.get());\r
-    }\r
-    catch(XSECCryptoException& e) {\r
-        throw ValidationException(string("Caught an XMLSecurity exception verifying signature: ") + e.getMsg());\r
-    }\r
-}\r
+/*
+ *  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.
+ */
+
+/**
+ * SignatureValidator.cpp
+ * 
+ * Validator for signatures based on an externally-supplied key 
+ */
+#include "internal.h"
+#include "signature/SignatureValidator.h"
+
+#include <xsec/enc/XSECCryptoException.hpp>
+#include <xsec/framework/XSECException.hpp>
+
+using namespace xmlsignature;
+using namespace xmltooling;
+using namespace std;
+
+void SignatureValidator::validate(const XMLObject* xmlObject) const
+{
+    const Signature* sigObj=dynamic_cast<const Signature*>(xmlObject);
+    if (!sigObj)
+        throw ValidationException("Validator only applies to Signature objects.");
+    validate(sigObj);
+}
+
+void SignatureValidator::validate(const Signature* sigObj) const
+{
+    DSIGSignature* sig=sigObj->getXMLSignature();
+    if (!sig)
+        throw ValidationException("Signature does not exist yet.");
+    else if (!m_key && !m_resolver)
+        throw ValidationException("No KeyResolver or signing key set on Validator.");
+
+    try {
+        XSECCryptoKey* key = m_key ? m_key->clone() : m_resolver->resolveKey(sig->getKeyInfoList());
+        if (!key)
+            throw ValidationException("Unable to resolve signing key.");
+        sig->setSigningKey(key);
+        if (!sig->verify())
+            throw ValidationException("Digital signature does not validate with the given key.");
+    }
+    catch(XSECException& e) {
+        auto_ptr_char temp(e.getMsg());
+        throw ValidationException(string("Caught an XMLSecurity exception verifying signature: ") + temp.get());
+    }
+    catch(XSECCryptoException& e) {
+        throw ValidationException(string("Caught an XMLSecurity exception verifying signature: ") + e.getMsg());
+    }
+}
index 31f5743..4168149 100644 (file)
-/*\r
-*  Copyright 2001-2006 Internet2\r
- * \r
-* Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * XMLSecSignatureImpl.cpp\r
- * \r
- * Signature class for XMLSec-based signature-handling\r
- */\r
-\r
-#include "internal.h"\r
-#include "exceptions.h"\r
-#include "impl/UnknownElement.h"\r
-#include "signature/KeyInfo.h"\r
-#include "signature/Signature.h"\r
-#include "util/NDC.h"\r
-#include "util/XMLConstants.h"\r
-#include "util/XMLHelper.h"\r
-\r
-#include <log4cpp/Category.hh>\r
-#include <xercesc/framework/MemBufInputSource.hpp>\r
-#include <xercesc/framework/Wrapper4InputSource.hpp>\r
-#include <xercesc/util/XMLUniDefs.hpp>\r
-#include <xsec/dsig/DSIGKeyInfoX509.hpp>\r
-#include <xsec/dsig/DSIGReference.hpp>\r
-#include <xsec/enc/XSECCryptoException.hpp>\r
-#include <xsec/framework/XSECException.hpp>\r
-\r
-using namespace xmlsignature;\r
-using namespace xmltooling;\r
-using namespace log4cpp;\r
-using namespace std;\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( push )\r
-    #pragma warning( disable : 4250 4251 )\r
-#endif\r
-\r
-namespace xmlsignature {\r
-    \r
-    class XMLTOOL_DLLLOCAL XMLSecSignatureImpl : public UnknownElementImpl, public virtual Signature\r
-    {\r
-    public:\r
-        XMLSecSignatureImpl() : UnknownElementImpl(XMLConstants::XMLSIG_NS, Signature::LOCAL_NAME, XMLConstants::XMLSIG_PREFIX),\r
-            m_signature(NULL), m_c14n(NULL), m_sm(NULL), m_key(NULL), m_keyInfo(NULL), m_reference(NULL) {}\r
-        virtual ~XMLSecSignatureImpl();\r
-        \r
-        void releaseDOM() const;\r
-        void releaseChildrenDOM(bool propagateRelease=true) const {\r
-            if (m_keyInfo) {\r
-                m_keyInfo->releaseDOM();\r
-                if (propagateRelease)\r
-                    m_keyInfo->releaseChildrenDOM();\r
-            }\r
-        }\r
-        XMLObject* clone() const;\r
-        Signature* cloneSignature() const;\r
-\r
-        DOMElement* marshall(DOMDocument* document=NULL, const vector<Signature*>* sigs=NULL) const;\r
-        DOMElement* marshall(DOMElement* parentElement, const vector<Signature*>* sigs=NULL) const;\r
-        XMLObject* unmarshall(DOMElement* element, bool bindDocument=false);\r
-        \r
-        // Getters\r
-        const XMLCh* getCanonicalizationMethod() const { return m_c14n ? m_c14n : DSIGConstants::s_unicodeStrURIEXC_C14N_NOC; }\r
-        const XMLCh* getSignatureAlgorithm() const { return m_sm ? m_sm : DSIGConstants::s_unicodeStrURIRSA_SHA1; }\r
-        KeyInfo* getKeyInfo() const { return m_keyInfo; }\r
-        ContentReference* getContentReference() const { return m_reference; }\r
-        DSIGSignature* getXMLSignature() const { return m_signature; }\r
-        \r
-        // Setters\r
-        void setCanonicalizationMethod(const XMLCh* c14n) { m_c14n = prepareForAssignment(m_c14n,c14n); }\r
-        void setSignatureAlgorithm(const XMLCh* sm) { m_sm = prepareForAssignment(m_sm,sm); }\r
-        void setSigningKey(XSECCryptoKey* signingKey) {\r
-            delete m_key;\r
-            m_key=signingKey;\r
-        }\r
-        void setKeyInfo(KeyInfo* keyInfo) {\r
-            prepareForAssignment(m_keyInfo, keyInfo);\r
-            m_keyInfo=keyInfo;\r
-        }\r
-        void setContentReference(ContentReference* reference) {\r
-            delete m_reference;\r
-            m_reference=reference;\r
-        }\r
-        \r
-        void sign();\r
-\r
-    private:\r
-        mutable DSIGSignature* m_signature;\r
-        XMLCh* m_c14n;\r
-        XMLCh* m_sm;\r
-        XSECCryptoKey* m_key;\r
-        KeyInfo* m_keyInfo;\r
-        ContentReference* m_reference;\r
-    };\r
-    \r
-};\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( pop )\r
-#endif\r
-\r
-XMLSecSignatureImpl::~XMLSecSignatureImpl()\r
-{\r
-    // Release the associated signature.\r
-    if (m_signature)\r
-        XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->releaseSignature(m_signature);\r
-\r
-    XMLString::release(&m_c14n);\r
-    XMLString::release(&m_sm);\r
-    delete m_key;\r
-    delete m_keyInfo;\r
-    delete m_reference;\r
-}\r
-\r
-void XMLSecSignatureImpl::releaseDOM() const\r
-{\r
-    if (getDOM()) {\r
-        // This should save off the DOM\r
-        UnknownElementImpl::releaseDOM();\r
-        \r
-        // Release the associated signature.\r
-        if (m_signature) {\r
-            XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->releaseSignature(m_signature);\r
-            m_signature=NULL;\r
-        }\r
-    }\r
-}\r
-\r
-XMLObject* XMLSecSignatureImpl::clone() const\r
-{\r
-    return cloneSignature();\r
-}\r
-\r
-Signature* XMLSecSignatureImpl::cloneSignature() const\r
-{\r
-    XMLSecSignatureImpl* ret=new XMLSecSignatureImpl();\r
-\r
-    ret->m_c14n=XMLString::replicate(m_c14n);\r
-    ret->m_sm=XMLString::replicate(m_sm);\r
-    if (m_key)\r
-        ret->m_key=m_key->clone();\r
-    if (m_keyInfo)\r
-        ret->m_keyInfo=m_keyInfo->cloneKeyInfo();\r
-\r
-    // If there's no XML locally, serialize this object into the new one, otherwise just copy it over.\r
-    if (m_xml.empty())\r
-        serialize(ret->m_xml);\r
-    else\r
-        ret->m_xml=m_xml;\r
-\r
-    return ret;\r
-}\r
-\r
-void XMLSecSignatureImpl::sign()\r
-{\r
-    Category& log=Category::getInstance(XMLTOOLING_LOGCAT".Signature");\r
-    log.debug("applying signature");\r
-\r
-    if (!m_signature)\r
-        throw SignatureException("Only a marshalled Signature object can be signed.");\r
-    else if (!m_key)\r
-        throw SignatureException("No signing key available for signature creation.");\r
-    else if (!m_reference)\r
-        throw SignatureException("No ContentReference object set for signature creation.");\r
-\r
-    try {\r
-        log.debug("creating signature reference(s)");\r
-        DSIGReferenceList* refs = m_signature->getReferenceList();\r
-        while (refs && refs->getSize())\r
-            delete refs->removeReference(0);\r
-        m_reference->createReferences(m_signature);\r
-        \r
-        log.debug("computing signature");\r
-        m_signature->setSigningKey(m_key->clone());\r
-        m_signature->sign();\r
-    }\r
-    catch(XSECException& e) {\r
-        auto_ptr_char temp(e.getMsg());\r
-        throw SignatureException(string("Caught an XMLSecurity exception while signing: ") + temp.get());\r
-    }\r
-    catch(XSECCryptoException& e) {\r
-        throw SignatureException(string("Caught an XMLSecurity exception while signing: ") + e.getMsg());\r
-    }\r
-}\r
-\r
-DOMElement* XMLSecSignatureImpl::marshall(DOMDocument* document, const vector<Signature*>* sigs) const\r
-{\r
-#ifdef _DEBUG\r
-    xmltooling::NDC ndc("marshall");\r
-#endif\r
-    \r
-    Category& log=Category::getInstance(XMLTOOLING_LOGCAT".Signature");\r
-    log.debug("marshalling ds:Signature");\r
-\r
-    DOMElement* cachedDOM=getDOM();\r
-    if (cachedDOM) {\r
-        if (!document || document==cachedDOM->getOwnerDocument()) {\r
-            log.debug("Signature has a usable cached DOM, reusing it");\r
-            if (document)\r
-                setDocumentElement(cachedDOM->getOwnerDocument(),cachedDOM);\r
-            releaseParentDOM(true);\r
-            return cachedDOM;\r
-        }\r
-        \r
-        // We have a DOM but it doesn't match the document we were given. This both sucks and blows.\r
-        // Without an adoptNode option to maintain the child pointers, we have to either import the\r
-        // DOM while somehow reassigning all the nested references (which amounts to a complete\r
-        // *unmarshall* operation), or we just release the existing DOM and hope that we can get\r
-        // it back. This depends on all objects being able to preserve their DOM at all costs.\r
-        releaseChildrenDOM(true);\r
-        releaseDOM();\r
-    }\r
-    \r
-    // If we get here, we didn't have a usable DOM.\r
-    bool bindDocument=false;\r
-    if (m_xml.empty()) {\r
-        // Fresh signature, so we just create an empty one.\r
-        log.debug("creating empty Signature element");\r
-        if (!document) {\r
-            document=DOMImplementationRegistry::getDOMImplementation(NULL)->createDocument();\r
-            bindDocument=true;\r
-        }\r
-        m_signature=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newSignature();\r
-        m_signature->setDSIGNSPrefix(XMLConstants::XMLSIG_PREFIX);\r
-        cachedDOM=m_signature->createBlankSignature(document, getCanonicalizationMethod(), getSignatureAlgorithm());\r
-    }\r
-    else {\r
-        // We need to reparse the XML we saved off into a new DOM.\r
-        MemBufInputSource src(reinterpret_cast<const XMLByte*>(m_xml.c_str()),m_xml.length(),"XMLSecSignatureImpl");\r
-        Wrapper4InputSource dsrc(&src,false);\r
-        log.debug("parsing Signature XML back into DOM tree");\r
-        DOMDocument* internalDoc=XMLToolingConfig::getConfig().getParser().parse(dsrc);\r
-        if (document) {\r
-            // The caller insists on using his own document, so we now have to import the thing\r
-            // into it. Then we're just dumping the one we built.\r
-            log.debug("reimporting new DOM into caller-supplied document");\r
-            cachedDOM=static_cast<DOMElement*>(document->importNode(internalDoc->getDocumentElement(), true));\r
-            internalDoc->release();\r
-        }\r
-        else {\r
-            // We just bind the document we built to the object as the result.\r
-            cachedDOM=static_cast<DOMElement*>(internalDoc->getDocumentElement());\r
-            document=internalDoc;\r
-            bindDocument=true;\r
-        }\r
-\r
-        // Now reload the signature from the DOM.\r
-        try {\r
-            m_signature=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newSignatureFromDOM(\r
-                document, cachedDOM\r
-                );\r
-            m_signature->load();\r
-        }\r
-        catch(XSECException& e) {\r
-            if (bindDocument)\r
-                document->release();\r
-            auto_ptr_char temp(e.getMsg());\r
-            throw MarshallingException(string("Caught an XMLSecurity exception while loading signature: ") + temp.get());\r
-        }\r
-        catch(XSECCryptoException& e) {\r
-            if (bindDocument)\r
-                document->release();\r
-            throw MarshallingException(string("Caught an XMLSecurity exception while loading signature: ") + e.getMsg());\r
-        }\r
-    }\r
-    \r
-    // Marshall KeyInfo data.\r
-    if (m_keyInfo && (!m_signature->getKeyInfoList() || m_signature->getKeyInfoList()->isEmpty())) {\r
-        m_keyInfo->marshall(cachedDOM);\r
-    }\r
-\r
-    // Recache the DOM and clear the serialized copy.\r
-    setDocumentElement(document, cachedDOM);\r
-    log.debug("caching DOM for Signature (document is %sbound)", bindDocument ? "" : "not ");\r
-    setDOM(cachedDOM, bindDocument);\r
-    releaseParentDOM(true);\r
-    m_xml.erase();\r
-    return cachedDOM;\r
-}\r
-\r
-DOMElement* XMLSecSignatureImpl::marshall(DOMElement* parentElement, const vector<Signature*>* sigs) const\r
-{\r
-#ifdef _DEBUG\r
-    xmltooling::NDC ndc("marshall");\r
-#endif\r
-    \r
-    Category& log=Category::getInstance(XMLTOOLING_LOGCAT".Signature");\r
-    log.debug("marshalling ds:Signature");\r
-\r
-    DOMElement* cachedDOM=getDOM();\r
-    if (cachedDOM) {\r
-        if (parentElement->getOwnerDocument()==cachedDOM->getOwnerDocument()) {\r
-            log.debug("Signature has a usable cached DOM, reusing it");\r
-            if (parentElement!=cachedDOM->getParentNode()) {\r
-                parentElement->appendChild(cachedDOM);\r
-                releaseParentDOM(true);\r
-            }\r
-            return cachedDOM;\r
-        }\r
-        \r
-        // We have a DOM but it doesn't match the document we were given. This both sucks and blows.\r
-        // Without an adoptNode option to maintain the child pointers, we have to either import the\r
-        // DOM while somehow reassigning all the nested references (which amounts to a complete\r
-        // *unmarshall* operation), or we just release the existing DOM and hope that we can get\r
-        // it back. This depends on all objects being able to preserve their DOM at all costs.\r
-        releaseChildrenDOM(true);\r
-        releaseDOM();\r
-    }\r
-    \r
-    // If we get here, we didn't have a usable DOM.\r
-    if (m_xml.empty()) {\r
-        // Fresh signature, so we just create an empty one.\r
-        log.debug("creating empty Signature element");\r
-        m_signature=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newSignature();\r
-        m_signature->setDSIGNSPrefix(XMLConstants::XMLSIG_PREFIX);\r
-        cachedDOM=m_signature->createBlankSignature(\r
-            parentElement->getOwnerDocument(), getCanonicalizationMethod(), getSignatureAlgorithm()\r
-            );\r
-    }\r
-    else {\r
-        MemBufInputSource src(reinterpret_cast<const XMLByte*>(m_xml.c_str()),m_xml.length(),"XMLSecSignatureImpl");\r
-        Wrapper4InputSource dsrc(&src,false);\r
-        log.debug("parsing XML back into DOM tree");\r
-        DOMDocument* internalDoc=XMLToolingConfig::getConfig().getParser().parse(dsrc);\r
-        \r
-        log.debug("reimporting new DOM into caller-supplied document");\r
-        cachedDOM=static_cast<DOMElement*>(parentElement->getOwnerDocument()->importNode(internalDoc->getDocumentElement(),true));\r
-        internalDoc->release();\r
-\r
-        // Now reload the signature from the DOM.\r
-        try {\r
-            m_signature=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newSignatureFromDOM(\r
-                parentElement->getOwnerDocument(), cachedDOM\r
-                );\r
-            m_signature->load();\r
-        }\r
-        catch(XSECException& e) {\r
-            auto_ptr_char temp(e.getMsg());\r
-            throw MarshallingException(string("Caught an XMLSecurity exception while loading signature: ") + temp.get());\r
-        }\r
-        catch(XSECCryptoException& e) {\r
-            throw MarshallingException(string("Caught an XMLSecurity exception while loading signature: ") + e.getMsg());\r
-        }\r
-    }\r
-\r
-    // Marshall KeyInfo data.\r
-    if (m_keyInfo && (!m_signature->getKeyInfoList() || m_signature->getKeyInfoList()->isEmpty())) {\r
-        m_keyInfo->marshall(cachedDOM);\r
-    }\r
-\r
-    // Recache the DOM and clear the serialized copy.\r
-    parentElement->appendChild(cachedDOM);\r
-    log.debug("caching DOM for Signature");\r
-    setDOM(cachedDOM, false);\r
-    releaseParentDOM(true);\r
-    m_xml.erase();\r
-    return cachedDOM;\r
-}\r
-\r
-XMLObject* XMLSecSignatureImpl::unmarshall(DOMElement* element, bool bindDocument)\r
-{\r
-    Category::getInstance(XMLTOOLING_LOGCAT".Signature").debug("unmarshalling ds:Signature");\r
-\r
-    try {\r
-        m_signature=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newSignatureFromDOM(\r
-            element->getOwnerDocument(), element\r
-            );\r
-        m_signature->load();\r
-    }\r
-    catch(XSECException& e) {\r
-        auto_ptr_char temp(e.getMsg());\r
-        throw UnmarshallingException(string("Caught an XMLSecurity exception while loading signature: ") + temp.get());\r
-    }\r
-    catch(XSECCryptoException& e) {\r
-        throw UnmarshallingException(string("Caught an XMLSecurity exception while loading signature: ") + e.getMsg());\r
-    }\r
-\r
-    setDOM(element, bindDocument);\r
-    return this;\r
-}\r
-\r
-Signature* SignatureBuilder::buildObject(\r
-    const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType\r
-    ) const\r
-{\r
-    if (!XMLString::equals(nsURI,XMLConstants::XMLSIG_NS) || !XMLString::equals(localName,Signature::LOCAL_NAME))\r
-        throw XMLObjectException("XMLSecSignatureBuilder requires standard Signature element name.");\r
-    return buildObject();\r
-}\r
-\r
-Signature* SignatureBuilder::buildObject() const\r
-{\r
-    return new XMLSecSignatureImpl();\r
-}\r
-\r
-const XMLCh Signature::LOCAL_NAME[] = UNICODE_LITERAL_9(S,i,g,n,a,t,u,r,e);\r
+/*
+*  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.
+ */
+
+/**
+ * XMLSecSignatureImpl.cpp
+ * 
+ * Signature class for XMLSec-based signature-handling
+ */
+
+#include "internal.h"
+#include "exceptions.h"
+#include "impl/UnknownElement.h"
+#include "signature/KeyInfo.h"
+#include "signature/Signature.h"
+#include "util/NDC.h"
+#include "util/XMLConstants.h"
+#include "util/XMLHelper.h"
+
+#include <log4cpp/Category.hh>
+#include <xercesc/framework/MemBufInputSource.hpp>
+#include <xercesc/framework/Wrapper4InputSource.hpp>
+#include <xercesc/util/XMLUniDefs.hpp>
+#include <xsec/dsig/DSIGKeyInfoX509.hpp>
+#include <xsec/dsig/DSIGReference.hpp>
+#include <xsec/enc/XSECCryptoException.hpp>
+#include <xsec/framework/XSECException.hpp>
+
+using namespace xmlsignature;
+using namespace xmltooling;
+using namespace log4cpp;
+using namespace std;
+
+#if defined (_MSC_VER)
+    #pragma warning( push )
+    #pragma warning( disable : 4250 4251 )
+#endif
+
+namespace xmlsignature {
+    
+    class XMLTOOL_DLLLOCAL XMLSecSignatureImpl : public UnknownElementImpl, public virtual Signature
+    {
+    public:
+        XMLSecSignatureImpl() : UnknownElementImpl(XMLConstants::XMLSIG_NS, Signature::LOCAL_NAME, XMLConstants::XMLSIG_PREFIX),
+            m_signature(NULL), m_c14n(NULL), m_sm(NULL), m_key(NULL), m_keyInfo(NULL), m_reference(NULL) {}
+        virtual ~XMLSecSignatureImpl();
+        
+        void releaseDOM() const;
+        void releaseChildrenDOM(bool propagateRelease=true) const {
+            if (m_keyInfo) {
+                m_keyInfo->releaseDOM();
+                if (propagateRelease)
+                    m_keyInfo->releaseChildrenDOM();
+            }
+        }
+        XMLObject* clone() const;
+        Signature* cloneSignature() const;
+
+        DOMElement* marshall(DOMDocument* document=NULL, const vector<Signature*>* sigs=NULL) const;
+        DOMElement* marshall(DOMElement* parentElement, const vector<Signature*>* sigs=NULL) const;
+        XMLObject* unmarshall(DOMElement* element, bool bindDocument=false);
+        
+        // Getters
+        const XMLCh* getCanonicalizationMethod() const { return m_c14n ? m_c14n : DSIGConstants::s_unicodeStrURIEXC_C14N_NOC; }
+        const XMLCh* getSignatureAlgorithm() const { return m_sm ? m_sm : DSIGConstants::s_unicodeStrURIRSA_SHA1; }
+        KeyInfo* getKeyInfo() const { return m_keyInfo; }
+        ContentReference* getContentReference() const { return m_reference; }
+        DSIGSignature* getXMLSignature() const { return m_signature; }
+        
+        // Setters
+        void setCanonicalizationMethod(const XMLCh* c14n) { m_c14n = prepareForAssignment(m_c14n,c14n); }
+        void setSignatureAlgorithm(const XMLCh* sm) { m_sm = prepareForAssignment(m_sm,sm); }
+        void setSigningKey(XSECCryptoKey* signingKey) {
+            delete m_key;
+            m_key=signingKey;
+        }
+        void setKeyInfo(KeyInfo* keyInfo) {
+            prepareForAssignment(m_keyInfo, keyInfo);
+            m_keyInfo=keyInfo;
+        }
+        void setContentReference(ContentReference* reference) {
+            delete m_reference;
+            m_reference=reference;
+        }
+        
+        void sign();
+
+    private:
+        mutable DSIGSignature* m_signature;
+        XMLCh* m_c14n;
+        XMLCh* m_sm;
+        XSECCryptoKey* m_key;
+        KeyInfo* m_keyInfo;
+        ContentReference* m_reference;
+    };
+    
+};
+
+#if defined (_MSC_VER)
+    #pragma warning( pop )
+#endif
+
+XMLSecSignatureImpl::~XMLSecSignatureImpl()
+{
+    // Release the associated signature.
+    if (m_signature)
+        XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->releaseSignature(m_signature);
+
+    XMLString::release(&m_c14n);
+    XMLString::release(&m_sm);
+    delete m_key;
+    delete m_keyInfo;
+    delete m_reference;
+}
+
+void XMLSecSignatureImpl::releaseDOM() const
+{
+    if (getDOM()) {
+        // This should save off the DOM
+        UnknownElementImpl::releaseDOM();
+        
+        // Release the associated signature.
+        if (m_signature) {
+            XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->releaseSignature(m_signature);
+            m_signature=NULL;
+        }
+    }
+}
+
+XMLObject* XMLSecSignatureImpl::clone() const
+{
+    return cloneSignature();
+}
+
+Signature* XMLSecSignatureImpl::cloneSignature() const
+{
+    XMLSecSignatureImpl* ret=new XMLSecSignatureImpl();
+
+    ret->m_c14n=XMLString::replicate(m_c14n);
+    ret->m_sm=XMLString::replicate(m_sm);
+    if (m_key)
+        ret->m_key=m_key->clone();
+    if (m_keyInfo)
+        ret->m_keyInfo=m_keyInfo->cloneKeyInfo();
+
+    // 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 XMLSecSignatureImpl::sign()
+{
+    Category& log=Category::getInstance(XMLTOOLING_LOGCAT".Signature");
+    log.debug("applying signature");
+
+    if (!m_signature)
+        throw SignatureException("Only a marshalled Signature object can be signed.");
+    else if (!m_key)
+        throw SignatureException("No signing key available for signature creation.");
+    else if (!m_reference)
+        throw SignatureException("No ContentReference object set for signature creation.");
+
+    try {
+        log.debug("creating signature reference(s)");
+        DSIGReferenceList* refs = m_signature->getReferenceList();
+        while (refs && refs->getSize())
+            delete refs->removeReference(0);
+        m_reference->createReferences(m_signature);
+        
+        log.debug("computing signature");
+        m_signature->setSigningKey(m_key->clone());
+        m_signature->sign();
+    }
+    catch(XSECException& e) {
+        auto_ptr_char temp(e.getMsg());
+        throw SignatureException(string("Caught an XMLSecurity exception while signing: ") + temp.get());
+    }
+    catch(XSECCryptoException& e) {
+        throw SignatureException(string("Caught an XMLSecurity exception while signing: ") + e.getMsg());
+    }
+}
+
+DOMElement* XMLSecSignatureImpl::marshall(DOMDocument* document, const vector<Signature*>* sigs) const
+{
+#ifdef _DEBUG
+    xmltooling::NDC ndc("marshall");
+#endif
+    
+    Category& log=Category::getInstance(XMLTOOLING_LOGCAT".Signature");
+    log.debug("marshalling ds:Signature");
+
+    DOMElement* cachedDOM=getDOM();
+    if (cachedDOM) {
+        if (!document || document==cachedDOM->getOwnerDocument()) {
+            log.debug("Signature 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. This both sucks and blows.
+        // Without an adoptNode option to maintain the child pointers, we have to either import the
+        // DOM while somehow reassigning all the nested references (which amounts to a complete
+        // *unmarshall* operation), or we just release the existing DOM and hope that we can get
+        // it back. This depends on all objects being able to preserve their DOM at all costs.
+        releaseChildrenDOM(true);
+        releaseDOM();
+    }
+    
+    // If we get here, we didn't have a usable DOM.
+    bool bindDocument=false;
+    if (m_xml.empty()) {
+        // Fresh signature, so we just create an empty one.
+        log.debug("creating empty Signature element");
+        if (!document) {
+            document=DOMImplementationRegistry::getDOMImplementation(NULL)->createDocument();
+            bindDocument=true;
+        }
+        m_signature=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newSignature();
+        m_signature->setDSIGNSPrefix(XMLConstants::XMLSIG_PREFIX);
+        cachedDOM=m_signature->createBlankSignature(document, getCanonicalizationMethod(), getSignatureAlgorithm());
+    }
+    else {
+        // We need to reparse the XML we saved off into a new DOM.
+        MemBufInputSource src(reinterpret_cast<const XMLByte*>(m_xml.c_str()),m_xml.length(),"XMLSecSignatureImpl");
+        Wrapper4InputSource dsrc(&src,false);
+        log.debug("parsing Signature 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");
+            cachedDOM=static_cast<DOMElement*>(document->importNode(internalDoc->getDocumentElement(), true));
+            internalDoc->release();
+        }
+        else {
+            // We just bind the document we built to the object as the result.
+            cachedDOM=static_cast<DOMElement*>(internalDoc->getDocumentElement());
+            document=internalDoc;
+            bindDocument=true;
+        }
+
+        // Now reload the signature from the DOM.
+        try {
+            m_signature=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newSignatureFromDOM(
+                document, cachedDOM
+                );
+            m_signature->load();
+        }
+        catch(XSECException& e) {
+            if (bindDocument)
+                document->release();
+            auto_ptr_char temp(e.getMsg());
+            throw MarshallingException(string("Caught an XMLSecurity exception while loading signature: ") + temp.get());
+        }
+        catch(XSECCryptoException& e) {
+            if (bindDocument)
+                document->release();
+            throw MarshallingException(string("Caught an XMLSecurity exception while loading signature: ") + e.getMsg());
+        }
+    }
+    
+    // Marshall KeyInfo data.
+    if (m_keyInfo && (!m_signature->getKeyInfoList() || m_signature->getKeyInfoList()->isEmpty())) {
+        m_keyInfo->marshall(cachedDOM);
+    }
+
+    // Recache the DOM and clear the serialized copy.
+    setDocumentElement(document, cachedDOM);
+    log.debug("caching DOM for Signature (document is %sbound)", bindDocument ? "" : "not ");
+    setDOM(cachedDOM, bindDocument);
+    releaseParentDOM(true);
+    m_xml.erase();
+    return cachedDOM;
+}
+
+DOMElement* XMLSecSignatureImpl::marshall(DOMElement* parentElement, const vector<Signature*>* sigs) const
+{
+#ifdef _DEBUG
+    xmltooling::NDC ndc("marshall");
+#endif
+    
+    Category& log=Category::getInstance(XMLTOOLING_LOGCAT".Signature");
+    log.debug("marshalling ds:Signature");
+
+    DOMElement* cachedDOM=getDOM();
+    if (cachedDOM) {
+        if (parentElement->getOwnerDocument()==cachedDOM->getOwnerDocument()) {
+            log.debug("Signature has a usable cached DOM, reusing it");
+            if (parentElement!=cachedDOM->getParentNode()) {
+                parentElement->appendChild(cachedDOM);
+                releaseParentDOM(true);
+            }
+            return cachedDOM;
+        }
+        
+        // We have a DOM but it doesn't match the document we were given. This both sucks and blows.
+        // Without an adoptNode option to maintain the child pointers, we have to either import the
+        // DOM while somehow reassigning all the nested references (which amounts to a complete
+        // *unmarshall* operation), or we just release the existing DOM and hope that we can get
+        // it back. This depends on all objects being able to preserve their DOM at all costs.
+        releaseChildrenDOM(true);
+        releaseDOM();
+    }
+    
+    // If we get here, we didn't have a usable DOM.
+    if (m_xml.empty()) {
+        // Fresh signature, so we just create an empty one.
+        log.debug("creating empty Signature element");
+        m_signature=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newSignature();
+        m_signature->setDSIGNSPrefix(XMLConstants::XMLSIG_PREFIX);
+        cachedDOM=m_signature->createBlankSignature(
+            parentElement->getOwnerDocument(), getCanonicalizationMethod(), getSignatureAlgorithm()
+            );
+    }
+    else {
+        MemBufInputSource src(reinterpret_cast<const XMLByte*>(m_xml.c_str()),m_xml.length(),"XMLSecSignatureImpl");
+        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");
+        cachedDOM=static_cast<DOMElement*>(parentElement->getOwnerDocument()->importNode(internalDoc->getDocumentElement(),true));
+        internalDoc->release();
+
+        // Now reload the signature from the DOM.
+        try {
+            m_signature=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newSignatureFromDOM(
+                parentElement->getOwnerDocument(), cachedDOM
+                );
+            m_signature->load();
+        }
+        catch(XSECException& e) {
+            auto_ptr_char temp(e.getMsg());
+            throw MarshallingException(string("Caught an XMLSecurity exception while loading signature: ") + temp.get());
+        }
+        catch(XSECCryptoException& e) {
+            throw MarshallingException(string("Caught an XMLSecurity exception while loading signature: ") + e.getMsg());
+        }
+    }
+
+    // Marshall KeyInfo data.
+    if (m_keyInfo && (!m_signature->getKeyInfoList() || m_signature->getKeyInfoList()->isEmpty())) {
+        m_keyInfo->marshall(cachedDOM);
+    }
+
+    // Recache the DOM and clear the serialized copy.
+    parentElement->appendChild(cachedDOM);
+    log.debug("caching DOM for Signature");
+    setDOM(cachedDOM, false);
+    releaseParentDOM(true);
+    m_xml.erase();
+    return cachedDOM;
+}
+
+XMLObject* XMLSecSignatureImpl::unmarshall(DOMElement* element, bool bindDocument)
+{
+    Category::getInstance(XMLTOOLING_LOGCAT".Signature").debug("unmarshalling ds:Signature");
+
+    try {
+        m_signature=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newSignatureFromDOM(
+            element->getOwnerDocument(), element
+            );
+        m_signature->load();
+    }
+    catch(XSECException& e) {
+        auto_ptr_char temp(e.getMsg());
+        throw UnmarshallingException(string("Caught an XMLSecurity exception while loading signature: ") + temp.get());
+    }
+    catch(XSECCryptoException& e) {
+        throw UnmarshallingException(string("Caught an XMLSecurity exception while loading signature: ") + e.getMsg());
+    }
+
+    setDOM(element, bindDocument);
+    return this;
+}
+
+Signature* SignatureBuilder::buildObject(
+    const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType
+    ) const
+{
+    if (!XMLString::equals(nsURI,XMLConstants::XMLSIG_NS) || !XMLString::equals(localName,Signature::LOCAL_NAME))
+        throw XMLObjectException("XMLSecSignatureBuilder requires standard Signature element name.");
+    return buildObject();
+}
+
+Signature* SignatureBuilder::buildObject() const
+{
+    return new XMLSecSignatureImpl();
+}
+
+const XMLCh Signature::LOCAL_NAME[] = UNICODE_LITERAL_9(S,i,g,n,a,t,u,r,e);
index eefa5a6..53d743f 100644 (file)
@@ -348,8 +348,8 @@ namespace {
         }
             
         EnvelopeImpl(const EnvelopeImpl& src)
-                : AbstractXMLObject(src), AbstractComplexElement(src),
-                    AbstractAttributeExtensibleXMLObject(src), AbstractDOMCachingXMLObject(src) {
+                : AbstractXMLObject(src), AbstractAttributeExtensibleXMLObject(src),
+                    AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
             init();
             if (src.getHeader())
                 setHeader(src.getHeader()->cloneHeader());
index 1d95fb7..dd8a45e 100644 (file)
@@ -1,59 +1,59 @@
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * unicode.cpp\r
- * \r
- * Helper classes and types for manipulating Unicode \r
- */\r
-\r
-#include "internal.h"\r
-#include "unicode.h"\r
-\r
-#include <xercesc/util/XMLUTF8Transcoder.hpp>\r
-#include <xercesc/util/XMLUniDefs.hpp>\r
-\r
-static const XMLCh UTF8[]={ chLatin_U, chLatin_T, chLatin_F, chDigit_8, chNull };\r
-\r
-char* xmltooling::toUTF8(const XMLCh* src)\r
-{\r
-    unsigned int eaten;\r
-    unsigned int srclen=XMLString::stringLen(src);\r
-    XMLUTF8Transcoder t(UTF8, srclen*4 + 1);\r
-    char* buf=new char[srclen*4 + 1];\r
-    memset(buf,0,srclen*4 + 1);\r
-    t.transcodeTo(\r
-        src,srclen,\r
-        reinterpret_cast<XMLByte*>(buf),srclen*4,\r
-        eaten,XMLTranscoder::UnRep_RepChar);\r
-    return buf;\r
-}\r
-\r
-XMLCh* xmltooling::fromUTF8(const char* src)\r
-{\r
-    unsigned int eaten;\r
-    unsigned int srclen=strlen(src);\r
-    XMLUTF8Transcoder t(UTF8, srclen + 1);\r
-    XMLCh* buf=new XMLCh[srclen + 1];\r
-    unsigned char* sizes=new unsigned char[srclen];\r
-    memset(buf,0,(srclen+1)*sizeof(XMLCh));\r
-    t.transcodeFrom(\r
-        reinterpret_cast<const XMLByte*>(src),srclen,\r
-        buf,srclen,\r
-        eaten,sizes);\r
-    delete[] sizes;\r
-    return buf;\r
-}\r
+/*
+ *  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.
+ */
+
+/**
+ * unicode.cpp
+ * 
+ * Helper classes and types for manipulating Unicode 
+ */
+
+#include "internal.h"
+#include "unicode.h"
+
+#include <xercesc/util/XMLUTF8Transcoder.hpp>
+#include <xercesc/util/XMLUniDefs.hpp>
+
+static const XMLCh UTF8[]={ chLatin_U, chLatin_T, chLatin_F, chDigit_8, chNull };
+
+char* xmltooling::toUTF8(const XMLCh* src)
+{
+    unsigned int eaten;
+    unsigned int srclen=XMLString::stringLen(src);
+    XMLUTF8Transcoder t(UTF8, srclen*4 + 1);
+    char* buf=new char[srclen*4 + 1];
+    memset(buf,0,srclen*4 + 1);
+    t.transcodeTo(
+        src,srclen,
+        reinterpret_cast<XMLByte*>(buf),srclen*4,
+        eaten,XMLTranscoder::UnRep_RepChar);
+    return buf;
+}
+
+XMLCh* xmltooling::fromUTF8(const char* src)
+{
+    unsigned int eaten;
+    unsigned int srclen=strlen(src);
+    XMLUTF8Transcoder t(UTF8, srclen + 1);
+    XMLCh* buf=new XMLCh[srclen + 1];
+    unsigned char* sizes=new unsigned char[srclen];
+    memset(buf,0,(srclen+1)*sizeof(XMLCh));
+    t.transcodeFrom(
+        reinterpret_cast<const XMLByte*>(src),srclen,
+        buf,srclen,
+        eaten,sizes);
+    delete[] sizes;
+    return buf;
+}
index 50e78f4..b4bd111 100644 (file)
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file unicode.h\r
- * \r
- * Helper classes and types for manipulating Unicode\r
- */\r
\r
-#if !defined(__xmltooling_unicode_h__)\r
-#define __xmltooling_unicode_h__\r
-\r
-#include <string>\r
-#include <xercesc/util/XMLString.hpp>\r
-#include <xmltooling/base.h>\r
-\r
-using namespace xercesc;\r
-\r
-namespace xmltooling {\r
-    \r
-    #ifdef HAVE_GOOD_STL\r
-        /**\r
-         * An STL string type that supports 16-bit Unicode.\r
-         * Most compilers support this, but various versions of gcc3 do not.\r
-         */\r
-        typedef std::basic_string<XMLCh> xstring;\r
-    #endif\r
-\r
-    /**\r
-     * Transcodes a 16-bit Unicode string into UTF-8.\r
-     * @param src   the 16-bit string to transcode\r
-     * @return      a UTF-8 string allocated by the Xerces memory manager \r
-     */\r
-    extern XMLTOOL_API char* toUTF8(const XMLCh* src);\r
-\r
-    /**\r
-     * Transcodes a UTF-8 string into 16-bit Unicode.\r
-     * @param src   the UTF-8 string to transcode\r
-     * @return      a 16-bit Unicode string allocated by the Xerces memory manager \r
-     */\r
-    extern XMLTOOL_API XMLCh* fromUTF8(const char* src);\r
-\r
-    /**\r
-     * A minimal auto_ptr-like class that can copy or transcode a buffer into\r
-     * the local code page and free the result automatically.\r
-     * \r
-     * Needed because a standard auto_ptr would use delete on the resulting\r
-     * pointer. \r
-     */\r
-    class XMLTOOL_API auto_ptr_char\r
-    {\r
-    public:\r
-        /**\r
-         * Constructor transcodes a 16-bit Unicode string into the local code page (NOT UTF-8) and wraps the result.\r
-         * @param src   the 16-bit string to transcode and wrap\r
-         * @param trim  trims leading/trailing whitespace from the result (defaults to true) \r
-         */\r
-        auto_ptr_char(const XMLCh* src, bool trim=true) : m_buf(XMLString::transcode(src)) {if (trim && m_buf) XMLString::trim(m_buf);}\r
-\r
-        /**\r
-         * Constructor copies a local code page (NOT UTF-8) string and wraps the result.\r
-         * @param src   the local string to copy and wrap\r
-         * @param trim  trims leading/trailing whitespace from the result (defaults to true) \r
-         */\r
-        auto_ptr_char(const char* src, bool trim=true) : m_buf(XMLString::replicate(src)) {if (trim && m_buf) XMLString::trim(m_buf);}\r
-\r
-        /**\r
-         * Destructor frees the wrapped buffer using the Xerces memory manager.\r
-         */\r
-        ~auto_ptr_char() { XMLString::release(&m_buf); }\r
-\r
-        /**\r
-         * Returns the wrapped buffer.\r
-         * @return a null-terminated local code page string\r
-         */\r
-        const char* get() const { return m_buf; }\r
-\r
-        /**\r
-         * Returns the wrapped buffer and transfers ownership of it to the caller.\r
-         * @return a null-terminated local code page string\r
-         */\r
-        char* release() { char* temp=m_buf; m_buf=NULL; return temp; }\r
-\r
-    private:    \r
-        char* m_buf;\r
-    MAKE_NONCOPYABLE(auto_ptr_char);\r
-    };\r
-\r
-    /**\r
-     * A minimal auto_ptr-like class that can copy or transcode a buffer into\r
-     * 16-bit Unicode and free the result automatically.\r
-     * \r
-     * Needed because a standard auto_ptr would use delete on the resulting\r
-     * pointer. \r
-     */\r
-    class XMLTOOL_API auto_ptr_XMLCh\r
-    {\r
-    public:\r
-        /**\r
-         * Constructor transcodes a local code page (NOT UTF-8) string into 16-bit Unicode and wraps the result.\r
-         * @param src   the local string to transcode and wrap\r
-         * @param trim  trims leading/trailing whitespace from the result (defaults to true) \r
-         */\r
-        auto_ptr_XMLCh(const char* src, bool trim=true) : m_buf(XMLString::transcode(src)) {if (trim && m_buf) XMLString::trim(m_buf);}\r
-\r
-        /**\r
-         * Constructor copies a 16-bit Unicode string and wraps the result.\r
-         * @param src   the Unicode string to copy and wrap\r
-         * @param trim  trims leading/trailing whitespace from the result (defaults to true) \r
-         */\r
-        auto_ptr_XMLCh(const XMLCh* src, bool trim=true) : m_buf(XMLString::replicate(src)) {if (trim && m_buf) XMLString::trim(m_buf);}\r
-\r
-        /**\r
-         * Destructor frees the wrapped buffer using the Xerces memory manager.\r
-         */\r
-        ~auto_ptr_XMLCh() { XMLString::release(&m_buf); }\r
-\r
-        /**\r
-         * Returns the wrapped buffer.\r
-         * @return a null-terminated Unicode string\r
-         */\r
-        const XMLCh* get() const { return m_buf; }\r
-        \r
-        /**\r
-         * Returns the wrapped buffer and transfers ownership of it to the caller.\r
-         * @return a null-terminated Unicode string\r
-         */\r
-        XMLCh* release() { XMLCh* temp=m_buf; m_buf=NULL; return temp; }\r
-\r
-    private:\r
-        XMLCh* m_buf;\r
-    MAKE_NONCOPYABLE(auto_ptr_XMLCh);\r
-    };\r
-\r
-};\r
-\r
-#endif /* __xmltooling_unicode_h__ */\r
+/*
+ *  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.
+ */
+
+/**
+ * @file unicode.h
+ * 
+ * Helper classes and types for manipulating Unicode
+ */
+#if !defined(__xmltooling_unicode_h__)
+#define __xmltooling_unicode_h__
+
+#include <string>
+#include <xercesc/util/XMLString.hpp>
+#include <xmltooling/base.h>
+
+using namespace xercesc;
+
+namespace xmltooling {
+    
+    #ifdef HAVE_GOOD_STL
+        /**
+         * An STL string type that supports 16-bit Unicode.
+         * Most compilers support this, but various versions of gcc3 do not.
+         */
+        typedef std::basic_string<XMLCh> xstring;
+    #endif
+
+    /**
+     * Transcodes a 16-bit Unicode string into UTF-8.
+     * @param src   the 16-bit string to transcode
+     * @return      a UTF-8 string allocated by the Xerces memory manager 
+     */
+    extern XMLTOOL_API char* toUTF8(const XMLCh* src);
+
+    /**
+     * Transcodes a UTF-8 string into 16-bit Unicode.
+     * @param src   the UTF-8 string to transcode
+     * @return      a 16-bit Unicode string allocated by the Xerces memory manager 
+     */
+    extern XMLTOOL_API XMLCh* fromUTF8(const char* src);
+
+    /**
+     * A minimal auto_ptr-like class that can copy or transcode a buffer into
+     * the local code page and free the result automatically.
+     * 
+     * Needed because a standard auto_ptr would use delete on the resulting
+     * pointer. 
+     */
+    class XMLTOOL_API auto_ptr_char
+    {
+    public:
+        /**
+         * Constructor transcodes a 16-bit Unicode string into the local code page (NOT UTF-8) and wraps the result.
+         * @param src   the 16-bit string to transcode and wrap
+         * @param trim  trims leading/trailing whitespace from the result (defaults to true) 
+         */
+        auto_ptr_char(const XMLCh* src, bool trim=true) : m_buf(XMLString::transcode(src)) {if (trim && m_buf) XMLString::trim(m_buf);}
+
+        /**
+         * Constructor copies a local code page (NOT UTF-8) string and wraps the result.
+         * @param src   the local string to copy and wrap
+         * @param trim  trims leading/trailing whitespace from the result (defaults to true) 
+         */
+        auto_ptr_char(const char* src, bool trim=true) : m_buf(XMLString::replicate(src)) {if (trim && m_buf) XMLString::trim(m_buf);}
+
+        /**
+         * Destructor frees the wrapped buffer using the Xerces memory manager.
+         */
+        ~auto_ptr_char() { XMLString::release(&m_buf); }
+
+        /**
+         * Returns the wrapped buffer.
+         * @return a null-terminated local code page string
+         */
+        const char* get() const { return m_buf; }
+
+        /**
+         * Returns the wrapped buffer and transfers ownership of it to the caller.
+         * @return a null-terminated local code page string
+         */
+        char* release() { char* temp=m_buf; m_buf=NULL; return temp; }
+
+    private:    
+        char* m_buf;
+    MAKE_NONCOPYABLE(auto_ptr_char);
+    };
+
+    /**
+     * A minimal auto_ptr-like class that can copy or transcode a buffer into
+     * 16-bit Unicode and free the result automatically.
+     * 
+     * Needed because a standard auto_ptr would use delete on the resulting
+     * pointer. 
+     */
+    class XMLTOOL_API auto_ptr_XMLCh
+    {
+    public:
+        /**
+         * Constructor transcodes a local code page (NOT UTF-8) string into 16-bit Unicode and wraps the result.
+         * @param src   the local string to transcode and wrap
+         * @param trim  trims leading/trailing whitespace from the result (defaults to true) 
+         */
+        auto_ptr_XMLCh(const char* src, bool trim=true) : m_buf(XMLString::transcode(src)) {if (trim && m_buf) XMLString::trim(m_buf);}
+
+        /**
+         * Constructor copies a 16-bit Unicode string and wraps the result.
+         * @param src   the Unicode string to copy and wrap
+         * @param trim  trims leading/trailing whitespace from the result (defaults to true) 
+         */
+        auto_ptr_XMLCh(const XMLCh* src, bool trim=true) : m_buf(XMLString::replicate(src)) {if (trim && m_buf) XMLString::trim(m_buf);}
+
+        /**
+         * Destructor frees the wrapped buffer using the Xerces memory manager.
+         */
+        ~auto_ptr_XMLCh() { XMLString::release(&m_buf); }
+
+        /**
+         * Returns the wrapped buffer.
+         * @return a null-terminated Unicode string
+         */
+        const XMLCh* get() const { return m_buf; }
+        
+        /**
+         * Returns the wrapped buffer and transfers ownership of it to the caller.
+         * @return a null-terminated Unicode string
+         */
+        XMLCh* release() { XMLCh* temp=m_buf; m_buf=NULL; return temp; }
+
+    private:
+        XMLCh* m_buf;
+    MAKE_NONCOPYABLE(auto_ptr_XMLCh);
+    };
+
+};
+
+#endif /* __xmltooling_unicode_h__ */
index 7877c50..6e27cb2 100644 (file)
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * DateTime.cpp\r
- * \r
- * Manipulation of XML date/time data. \r
- */\r
-\r
-/*\r
- * This is mostly copied from Xerces-C, but they don't seem inclined to produce a usable\r
- * class, so I had to incorporate my own version of it for now. I can't inherit it\r
- * since the fields I need are private.\r
- */\r
-\r
-#include "internal.h"\r
-#include "util/DateTime.h"\r
-\r
-#ifndef WIN32\r
-# include <errno.h>\r
-#endif\r
-\r
-#include <ctime>\r
-#include <xercesc/util/Janitor.hpp>\r
-#include <xercesc/util/NumberFormatException.hpp>\r
-\r
-using namespace xmltooling;\r
-using namespace std;\r
-\r
-//\r
-// constants used to process raw data (fBuffer)\r
-//\r
-// [-]{CCYY-MM-DD}'T'{HH:MM:SS.MS}['Z']\r
-//                                [{+|-}hh:mm']\r
-//\r
-\r
-static const XMLCh DURATION_STARTER     = chLatin_P;              // 'P'\r
-static const XMLCh DURATION_Y           = chLatin_Y;              // 'Y'\r
-static const XMLCh DURATION_M           = chLatin_M;              // 'M'\r
-static const XMLCh DURATION_D           = chLatin_D;              // 'D'\r
-static const XMLCh DURATION_H           = chLatin_H;              // 'H'\r
-static const XMLCh DURATION_S           = chLatin_S;              // 'S'\r
-\r
-static const XMLCh DATE_SEPARATOR       = chDash;                 // '-'\r
-static const XMLCh TIME_SEPARATOR       = chColon;                // ':'\r
-static const XMLCh TIMEZONE_SEPARATOR   = chColon;                // ':'\r
-static const XMLCh DATETIME_SEPARATOR   = chLatin_T;              // 'T'\r
-static const XMLCh MILISECOND_SEPARATOR = chPeriod;               // '.'\r
-\r
-static const XMLCh UTC_STD_CHAR         = chLatin_Z;              // 'Z'\r
-static const XMLCh UTC_POS_CHAR         = chPlus;                 // '+'\r
-static const XMLCh UTC_NEG_CHAR         = chDash;                 // '-'\r
-\r
-static const XMLCh UTC_SET[]            = {UTC_STD_CHAR           //"Z+-"\r
-                                         , UTC_POS_CHAR\r
-                                         , UTC_NEG_CHAR\r
-                                         , chNull};\r
-\r
-static const int YMD_MIN_SIZE    = 10;   // CCYY-MM-DD\r
-static const int YMONTH_MIN_SIZE = 7;    // CCYY_MM\r
-static const int TIME_MIN_SIZE   = 8;    // hh:mm:ss\r
-static const int TIMEZONE_SIZE   = 5;    // hh:mm\r
-static const int DAY_SIZE        = 5;    // ---DD\r
-//static const int MONTH_SIZE      = 6;    // --MM--\r
-static const int MONTHDAY_SIZE   = 7;    // --MM-DD\r
-static const int NOT_FOUND       = -1;\r
-\r
-//define constants to be used in assigning default values for\r
-//all date/time excluding duration\r
-static const int YEAR_DEFAULT  = 2000;\r
-static const int MONTH_DEFAULT = 01;\r
-static const int DAY_DEFAULT   = 15;\r
-\r
-// order-relation on duration is a partial order. The dates below are used to\r
-// for comparison of 2 durations, based on the fact that\r
-// duration x and y is x<=y iff s+x<=s+y\r
-// see 3.2.6 duration W3C schema datatype specs\r
-//\r
-// the dates are in format: {CCYY,MM,DD, H, S, M, MS, timezone}\r
-const int DateTime::DATETIMES[][TOTAL_SIZE] =\r
-{\r
-    {1696, 9, 1, 0, 0, 0, 0, UTC_STD},\r
-       {1697, 2, 1, 0, 0, 0, 0, UTC_STD},\r
-       {1903, 3, 1, 0, 0, 0, 0, UTC_STD},\r
-       {1903, 7, 1, 0, 0, 0, 0, UTC_STD}\r
-};\r
-\r
-// ---------------------------------------------------------------------------\r
-//  local methods\r
-// ---------------------------------------------------------------------------\r
-static inline int fQuotient(int a, int b)\r
-{\r
-    div_t div_result = div(a, b);\r
-    return div_result.quot;\r
-}\r
-\r
-static inline int fQuotient(int temp, int low, int high)\r
-{\r
-    return fQuotient(temp - low, high - low);\r
-}\r
-\r
-static inline int mod(int a, int b, int quotient)\r
-{\r
-       return (a - quotient*b) ;\r
-}\r
-\r
-static inline int modulo (int temp, int low, int high)\r
-{\r
-    //modulo(a - low, high - low) + low\r
-    int a = temp - low;\r
-    int b = high - low;\r
-    return (mod (a, b, fQuotient(a, b)) + low) ;\r
-}\r
-\r
-static inline bool isLeapYear(int year)\r
-{\r
-    return((year%4 == 0) && ((year%100 != 0) || (year%400 == 0)));\r
-}\r
-\r
-static int maxDayInMonthFor(int year, int month)\r
-{\r
-\r
-    if ( month == 4 || month == 6 || month == 9 || month == 11 )\r
-    {\r
-        return 30;\r
-    }\r
-    else if ( month==2 )\r
-    {\r
-        if ( isLeapYear(year) )\r
-            return 29;\r
-        else\r
-            return 28;\r
-    }\r
-    else\r
-    {\r
-        return 31;\r
-    }\r
-\r
-}\r
-\r
-// ---------------------------------------------------------------------------\r
-//  static methods : for duration\r
-// ---------------------------------------------------------------------------\r
-/**\r
- * Compares 2 given durations. (refer to W3C Schema Datatypes "3.2.6 duration")\r
- *\r
- * 3.2.6.2 Order relation on duration\r
- *\r
- *     In general, the order-relation on duration is a partial order since there is no\r
- *  determinate relationship between certain durations such as one month (P1M) and 30 days (P30D).\r
- *  The order-relation of two duration values x and y is x < y iff s+x < s+y for each qualified\r
- *  dateTime s in the list below.\r
- *\r
- *     These values for s cause the greatest deviations in the addition of dateTimes and durations\r
- *\r
- **/\r
-int DateTime::compare(const DateTime* const pDate1\r
-                       , const DateTime* const pDate2\r
-                       , bool  strict)\r
-{\r
-    //REVISIT: this is unoptimazed vs of comparing 2 durations\r
-    //         Algorithm is described in 3.2.6.2 W3C Schema Datatype specs\r
-    //\r
-\r
-    int resultA, resultB = XMLDateTime::INDETERMINATE;\r
-\r
-    //try and see if the objects are equal\r
-    if ( (resultA = compareOrder(pDate1, pDate2)) == XMLDateTime::EQUAL)\r
-        return XMLDateTime::EQUAL;\r
-\r
-    //long comparison algorithm is required\r
-    DateTime tempA, *pTempA = &tempA;\r
-    DateTime tempB, *pTempB = &tempB;\r
-\r
-    addDuration(pTempA, pDate1, 0);\r
-    addDuration(pTempB, pDate2, 0);\r
-    resultA = compareOrder(pTempA, pTempB);\r
-    if ( resultA == XMLDateTime::INDETERMINATE )\r
-        return XMLDateTime::INDETERMINATE;\r
-\r
-    addDuration(pTempA, pDate1, 1);\r
-    addDuration(pTempB, pDate2, 1);\r
-    resultB = compareOrder(pTempA, pTempB);\r
-    resultA = compareResult(resultA, resultB, strict);\r
-    if ( resultA == XMLDateTime::INDETERMINATE )\r
-        return XMLDateTime::INDETERMINATE;\r
-\r
-    addDuration(pTempA, pDate1, 2);\r
-    addDuration(pTempB, pDate2, 2);\r
-    resultB = compareOrder(pTempA, pTempB);\r
-    resultA = compareResult(resultA, resultB, strict);\r
-    if ( resultA == XMLDateTime::INDETERMINATE )\r
-        return XMLDateTime::INDETERMINATE;\r
-\r
-    addDuration(pTempA, pDate1, 3);\r
-    addDuration(pTempB, pDate2, 3);\r
-    resultB = compareOrder(pTempA, pTempB);\r
-    resultA = compareResult(resultA, resultB, strict);\r
-\r
-    return resultA;\r
-\r
-}\r
-\r
-//\r
-// Form a new DateTime with duration and baseDate array\r
-// Note: C++        Java\r
-//       fNewDate   duration\r
-//       fDuration  date\r
-//\r
-\r
-void DateTime::addDuration(DateTime*             fNewDate\r
-                            , const DateTime* const fDuration\r
-                            , int index)\r
-\r
-{\r
-\r
-    //REVISIT: some code could be shared between normalize() and this method,\r
-    //         however is it worth moving it? The structures are different...\r
-    //\r
-\r
-    fNewDate->reset();\r
-    //add months (may be modified additionaly below)\r
-    int temp = DATETIMES[index][Month] + fDuration->fValue[Month];\r
-    fNewDate->fValue[Month] = modulo(temp, 1, 13);\r
-    int carry = fQuotient(temp, 1, 13);\r
-\r
-    //add years (may be modified additionaly below)\r
-    fNewDate->fValue[CentYear] =\r
-        DATETIMES[index][CentYear] + fDuration->fValue[CentYear] + carry;\r
-\r
-    //add seconds\r
-    temp = DATETIMES[index][Second] + fDuration->fValue[Second];\r
-    carry = fQuotient (temp, 60);\r
-    fNewDate->fValue[Second] =  mod(temp, 60, carry);\r
-               \r
-    //add minutes\r
-    temp = DATETIMES[index][Minute] + fDuration->fValue[Minute] + carry;\r
-    carry = fQuotient(temp, 60);\r
-    fNewDate->fValue[Minute] = mod(temp, 60, carry);\r
-\r
-    //add hours\r
-    temp = DATETIMES[index][Hour] + fDuration->fValue[Hour] + carry;\r
-    carry = fQuotient(temp, 24);\r
-    fNewDate->fValue[Hour] = mod(temp, 24, carry);\r
-               \r
-    fNewDate->fValue[Day] =\r
-        DATETIMES[index][Day] + fDuration->fValue[Day] + carry;\r
-\r
-    while ( true )\r
-    {\r
-        temp = maxDayInMonthFor(fNewDate->fValue[CentYear], fNewDate->fValue[Month]);\r
-        if ( fNewDate->fValue[Day] < 1 )\r
-        { //original fNewDate was negative\r
-            fNewDate->fValue[Day] +=\r
-                maxDayInMonthFor(fNewDate->fValue[CentYear], fNewDate->fValue[Month]-1);\r
-            carry = -1;\r
-        }\r
-        else if ( fNewDate->fValue[Day] > temp )\r
-        {\r
-            fNewDate->fValue[Day] -= temp;\r
-            carry = 1;\r
-        }\r
-        else\r
-        {\r
-            break;\r
-        }\r
-\r
-        temp = fNewDate->fValue[Month] + carry;\r
-        fNewDate->fValue[Month] = modulo(temp, 1, 13);\r
-        fNewDate->fValue[CentYear] += fQuotient(temp, 1, 13);\r
-    }\r
-\r
-    //fNewDate->fValue[utc] = UTC_STD_CHAR;\r
-    fNewDate->fValue[utc] = UTC_STD;\r
-}\r
-\r
-int DateTime::compareResult(int resultA\r
-                             , int resultB\r
-                             , bool strict)\r
-{\r
-\r
-    if ( resultB == XMLDateTime::INDETERMINATE )\r
-    {\r
-        return XMLDateTime::INDETERMINATE;\r
-    }\r
-    else if ( (resultA != resultB) &&\r
-              strict                )\r
-    {\r
-        return XMLDateTime::INDETERMINATE;\r
-    }\r
-    else if ( (resultA != resultB) &&\r
-              !strict               )\r
-    {\r
-        if ( (resultA != XMLDateTime::EQUAL) &&\r
-             (resultB != XMLDateTime::EQUAL)  )\r
-        {\r
-            return XMLDateTime::INDETERMINATE;\r
-        }\r
-        else\r
-        {\r
-            return (resultA != XMLDateTime::EQUAL)? resultA : resultB;\r
-        }\r
-    }\r
-\r
-    return resultA;\r
-       \r
-}\r
-\r
-// ---------------------------------------------------------------------------\r
-//  static methods : for others\r
-// ---------------------------------------------------------------------------\r
-int DateTime::compare(const DateTime* const pDate1\r
-                       , const DateTime* const pDate2)\r
-{\r
-\r
-    if (pDate1->fValue[utc] == pDate2->fValue[utc])\r
-    {\r
-        return DateTime::compareOrder(pDate1, pDate2);\r
-    }\r
-\r
-    int c1, c2;\r
-\r
-    if ( pDate1->isNormalized())\r
-    {\r
-        c1 = compareResult(pDate1, pDate2, false, UTC_POS);\r
-        c2 = compareResult(pDate1, pDate2, false, UTC_NEG);\r
-        return getRetVal(c1, c2);\r
-    }\r
-    else if ( pDate2->isNormalized())\r
-    {\r
-        c1 = compareResult(pDate1, pDate2, true, UTC_POS);\r
-        c2 = compareResult(pDate1, pDate2, true, UTC_NEG);\r
-        return getRetVal(c1, c2);\r
-    }\r
-\r
-    return XMLDateTime::INDETERMINATE; \r
-}\r
-\r
-int DateTime::compareResult(const DateTime* const pDate1\r
-                             , const DateTime* const pDate2\r
-                             , bool  set2Left\r
-                             , int   utc_type)\r
-{\r
-    DateTime tmpDate = (set2Left ? *pDate1 : *pDate2);\r
-\r
-    tmpDate.fTimeZone[hh] = 14;\r
-    tmpDate.fTimeZone[mm] = 0;\r
-    tmpDate.fValue[utc] = utc_type;\r
-    tmpDate.normalize();\r
-\r
-    return (set2Left? DateTime::compareOrder(&tmpDate, pDate2) :\r
-                      DateTime::compareOrder(pDate1, &tmpDate));\r
-}\r
-\r
-int DateTime::compareOrder(const DateTime* const lValue\r
-                            , const DateTime* const rValue)\r
-                            //, MemoryManager* const memMgr)\r
-{\r
-    //\r
-    // If any of the them is not normalized() yet,\r
-    // we need to do something here.\r
-    //\r
-    DateTime lTemp = *lValue;\r
-    DateTime rTemp = *rValue;\r
-\r
-    lTemp.normalize();\r
-    rTemp.normalize();\r
-\r
-    for ( int i = 0 ; i < TOTAL_SIZE; i++ )\r
-    {\r
-        if ( lTemp.fValue[i] < rTemp.fValue[i] )\r
-        {\r
-            return XMLDateTime::LESS_THAN;\r
-        }\r
-        else if ( lTemp.fValue[i] > rTemp.fValue[i] )\r
-        {\r
-            return XMLDateTime::GREATER_THAN;\r
-        }\r
-    }\r
-\r
-    if ( lTemp.fHasTime)\r
-    {\r
-        if ( lTemp.fMiliSecond < rTemp.fMiliSecond )\r
-        {\r
-            return XMLDateTime::LESS_THAN;\r
-        }\r
-        else if ( lTemp.fMiliSecond > rTemp.fMiliSecond )\r
-        {\r
-            return XMLDateTime::GREATER_THAN;\r
-        }\r
-    }\r
-\r
-    return XMLDateTime::EQUAL;\r
-}\r
-\r
-// ---------------------------------------------------------------------------\r
-//  ctor and dtor\r
-// ---------------------------------------------------------------------------\r
-DateTime::~DateTime()\r
-{\r
-    delete[] fBuffer;\r
-}\r
-\r
-DateTime::DateTime()\r
-: fStart(0)\r
-, fEnd(0)\r
-, fBufferMaxLen(0)\r
-, fBuffer(0)\r
-, fMiliSecond(0)\r
-, fHasTime(false)\r
-{\r
-    reset();\r
-}\r
-\r
-DateTime::DateTime(const XMLCh* const aString)\r
-: fStart(0)\r
-, fEnd(0)\r
-, fBufferMaxLen(0)\r
-, fBuffer(0)\r
-, fMiliSecond(0)\r
-, fHasTime(false)\r
-{\r
-    setBuffer(aString);\r
-}\r
-\r
-DateTime::DateTime(time_t epoch)\r
-: fStart(0)\r
-, fEnd(0)\r
-, fBufferMaxLen(0)\r
-, fBuffer(0)\r
-, fMiliSecond(0)\r
-, fHasTime(false)\r
-{\r
-#ifndef HAVE_GMTIME_R\r
-    struct tm* ptime=gmtime(&epoch);\r
-#else\r
-    struct tm res;\r
-    struct tm* ptime=gmtime_r(&epoch,&res);\r
-#endif\r
-    char timebuf[32];\r
-    strftime(timebuf,32,"%Y-%m-%dT%H:%M:%SZ",ptime);\r
-    auto_ptr_XMLCh timeptr(timebuf);\r
-    setBuffer(timeptr.get());\r
-}\r
-\r
-// -----------------------------------------------------------------------\r
-// Copy ctor and Assignment operators\r
-// -----------------------------------------------------------------------\r
-\r
-DateTime::DateTime(const DateTime &toCopy)\r
-: fBufferMaxLen(0)\r
-, fBuffer(0)\r
-{\r
-    copy(toCopy);\r
-}\r
-\r
-DateTime& DateTime::operator=(const DateTime& rhs)\r
-{\r
-    if (this == &rhs)\r
-        return *this;\r
-\r
-    copy(rhs);\r
-    return *this;\r
-}\r
-\r
-// -----------------------------------------------------------------------\r
-// Implementation of Abstract Interface\r
-// -----------------------------------------------------------------------\r
-\r
-//\r
-// We may simply return the handle to fBuffer\r
-//\r
-const XMLCh*  DateTime::getRawData() const\r
-{\r
-    //assertBuffer();\r
-    return fBuffer;\r
-}\r
-\r
-\r
-const XMLCh*  DateTime::getFormattedString() const\r
-{\r
-    return getRawData();\r
-}\r
-\r
-int DateTime::getSign() const\r
-{\r
-    return 0;\r
-}\r
-\r
-time_t DateTime::getEpoch() const\r
-{\r
-    struct tm t;\r
-    t.tm_sec=getSecond();\r
-    t.tm_min=getMinute();\r
-    t.tm_hour=getHour();\r
-    t.tm_mday=getDay();\r
-    t.tm_mon=getMonth()-1;\r
-    t.tm_year=getYear()-1900;\r
-    t.tm_isdst=0;\r
-#if defined(HAVE_TIMEGM)\r
-    return timegm(&t);\r
-#else\r
-    // Windows, and hopefully most others...?\r
-    return mktime(&t) - timezone;\r
-#endif\r
-}\r
-\r
-// ---------------------------------------------------------------------------\r
-//  Parsers\r
-// ---------------------------------------------------------------------------\r
-\r
-//\r
-// [-]{CCYY-MM-DD}'T'{HH:MM:SS.MS}[TimeZone]\r
-//\r
-void DateTime::parseDateTime()\r
-{\r
-    initParser();\r
-    getDate();\r
-\r
-    //fStart is supposed to point to 'T'\r
-    if (fBuffer[fStart++] != DATETIME_SEPARATOR)\r
-        ThrowXML1(SchemaDateTimeException\r
-                , XMLExcepts::DateTime_gDay_invalid\r
-                , fBuffer);\r
-\r
-    getTime();\r
-    validateDateTime();\r
-    normalize();\r
-    fHasTime = true;\r
-}\r
-\r
-//\r
-// [-]{CCYY-MM-DD}[TimeZone]\r
-//\r
-void DateTime::parseDate()\r
-{\r
-    initParser();\r
-    getDate();\r
-    parseTimeZone();\r
-    validateDateTime();\r
-    normalize();\r
-}\r
-\r
-void DateTime::parseTime()\r
-{\r
-    initParser();\r
-\r
-    // time initialize to default values\r
-    fValue[CentYear]= YEAR_DEFAULT;\r
-    fValue[Month]   = MONTH_DEFAULT;\r
-    fValue[Day]     = DAY_DEFAULT;\r
-\r
-    getTime();\r
-\r
-    validateDateTime();\r
-    normalize();\r
-    fHasTime = true;\r
-}\r
-\r
-//\r
-// {---DD}[TimeZone]\r
-//  01234\r
-//\r
-void DateTime::parseDay()\r
-{\r
-    initParser();\r
-\r
-    if (fBuffer[0] != DATE_SEPARATOR ||\r
-        fBuffer[1] != DATE_SEPARATOR ||\r
-        fBuffer[2] != DATE_SEPARATOR  )\r
-    {\r
-        ThrowXML1(SchemaDateTimeException\r
-                , XMLExcepts::DateTime_gDay_invalid\r
-                , fBuffer);\r
-    }\r
-\r
-    //initialize values\r
-    fValue[CentYear] = YEAR_DEFAULT;\r
-    fValue[Month]    = MONTH_DEFAULT;\r
-    fValue[Day]      = parseInt(fStart+3, fStart+5);\r
-\r
-    if ( DAY_SIZE < fEnd )\r
-    {\r
-        int sign = findUTCSign(DAY_SIZE);\r
-        if ( sign < 0 )\r
-        {\r
-            ThrowXML1(SchemaDateTimeException\r
-                    , XMLExcepts::DateTime_gDay_invalid\r
-                    , fBuffer);\r
-        }\r
-        else\r
-        {\r
-            getTimeZone(sign);\r
-        }\r
-    }\r
-\r
-    validateDateTime();\r
-    normalize();\r
-}\r
-\r
-//\r
-// {--MM--}[TimeZone]\r
-// {--MM}[TimeZone]\r
-//  012345\r
-//\r
-void DateTime::parseMonth()\r
-{\r
-    initParser();\r
-\r
-    if (fBuffer[0] != DATE_SEPARATOR ||\r
-        fBuffer[1] != DATE_SEPARATOR  )\r
-    {\r
-        ThrowXML1(SchemaDateTimeException\r
-                , XMLExcepts::DateTime_gMth_invalid\r
-                , fBuffer);\r
-    }\r
-\r
-    //set constants\r
-    fValue[CentYear] = YEAR_DEFAULT;\r
-    fValue[Day]      = DAY_DEFAULT;\r
-    fValue[Month]    = parseInt(2, 4);\r
-\r
-    // REVISIT: allow both --MM and --MM-- now. \r
-    // need to remove the following lines to disallow --MM-- \r
-    // when the errata is officially in the rec. \r
-    fStart = 4;\r
-    if ( fEnd >= fStart+2 && fBuffer[fStart] == DATE_SEPARATOR && fBuffer[fStart+1] == DATE_SEPARATOR ) \r
-    { \r
-        fStart += 2; \r
-    } \r
-\r
-    //\r
-    // parse TimeZone if any\r
-    //\r
-    if ( fStart < fEnd )\r
-    {\r
-        int sign = findUTCSign(fStart);\r
-        if ( sign < 0 )\r
-        {\r
-            ThrowXML1(SchemaDateTimeException\r
-                    , XMLExcepts::DateTime_gMth_invalid\r
-                    , fBuffer);\r
-        }\r
-        else\r
-        {\r
-            getTimeZone(sign);\r
-        }\r
-    }\r
-\r
-    validateDateTime();\r
-    normalize();\r
-}\r
-\r
-//\r
-//[-]{CCYY}[TimeZone]\r
-// 0  1234\r
-//\r
-void DateTime::parseYear()\r
-{\r
-    initParser();\r
-\r
-    // skip the first '-' and search for timezone\r
-    //\r
-    int sign = findUTCSign((fBuffer[0] == chDash) ? 1 : 0);\r
-\r
-    if (sign == NOT_FOUND)\r
-    {\r
-        fValue[CentYear] = parseIntYear(fEnd);\r
-    }\r
-    else\r
-    {\r
-        fValue[CentYear] = parseIntYear(sign);\r
-        getTimeZone(sign);\r
-    }\r
-\r
-    //initialize values\r
-    fValue[Month] = MONTH_DEFAULT;\r
-    fValue[Day]   = DAY_DEFAULT;   //java is 1\r
-\r
-    validateDateTime();\r
-    normalize();\r
-}\r
-\r
-//\r
-//{--MM-DD}[TimeZone]\r
-// 0123456\r
-//\r
-void DateTime::parseMonthDay()\r
-{\r
-    initParser();\r
-\r
-    if (fBuffer[0] != DATE_SEPARATOR ||\r
-        fBuffer[1] != DATE_SEPARATOR ||\r
-        fBuffer[4] != DATE_SEPARATOR )\r
-    {\r
-        ThrowXML1(SchemaDateTimeException\r
-                , XMLExcepts::DateTime_gMthDay_invalid\r
-                , fBuffer);\r
-    }\r
-\r
-\r
-    //initialize\r
-    fValue[CentYear] = YEAR_DEFAULT;\r
-    fValue[Month]    = parseInt(2, 4); \r
-    fValue[Day]      = parseInt(5, 7);\r
-\r
-    if ( MONTHDAY_SIZE < fEnd )\r
-    {\r
-        int sign = findUTCSign(MONTHDAY_SIZE);\r
-        if ( sign<0 )\r
-        {\r
-            ThrowXML1(SchemaDateTimeException\r
-                    , XMLExcepts::DateTime_gMthDay_invalid\r
-                    , fBuffer);\r
-        }\r
-        else\r
-        {\r
-            getTimeZone(sign);\r
-        }\r
-    }\r
-\r
-    validateDateTime();\r
-    normalize();\r
-}\r
-\r
-void DateTime::parseYearMonth()\r
-{\r
-    initParser();\r
-\r
-    // get date\r
-    getYearMonth();\r
-    fValue[Day] = DAY_DEFAULT;\r
-    parseTimeZone();\r
-\r
-    validateDateTime();\r
-    normalize();\r
-}\r
-\r
-//\r
-//PnYn MnDTnH nMnS: -P1Y2M3DT10H30M\r
-//\r
-// [-]{'P'{[n'Y'][n'M'][n'D']['T'][n'H'][n'M'][n'S']}}\r
-//\r
-//  Note: the n above shall be >= 0\r
-//        if no time element found, 'T' shall be absent\r
-//\r
-void DateTime::parseDuration()\r
-{\r
-    initParser();\r
-\r
-    // must start with '-' or 'P'\r
-    //\r
-    XMLCh c = fBuffer[fStart++];\r
-    if ( (c != DURATION_STARTER) &&\r
-         (c != chDash)            )\r
-    {\r
-        ThrowXML1(SchemaDateTimeException\r
-                , XMLExcepts::DateTime_dur_Start_dashP\r
-                , fBuffer);\r
-    }\r
-\r
-    // 'P' must ALWAYS be present in either case\r
-    if ( (c == chDash) &&\r
-         (fBuffer[fStart++]!= DURATION_STARTER ))\r
-    {\r
-        ThrowXML1(SchemaDateTimeException\r
-                , XMLExcepts::DateTime_dur_noP\r
-                , fBuffer);\r
-    }\r
-\r
-    // java code\r
-    //date[utc]=(c=='-')?'-':0;\r
-    //fValue[utc] = UTC_STD;\r
-    fValue[utc] = (fBuffer[0] == chDash? UTC_NEG : UTC_STD);\r
-\r
-    int negate = ( fBuffer[0] == chDash ? -1 : 1);\r
-\r
-    //\r
-    // No negative value is allowed after 'P'\r
-    //\r
-    // eg P-1234, invalid\r
-    //\r
-    if (indexOf(fStart, fEnd, chDash) != NOT_FOUND)\r
-    {\r
-        ThrowXML1(SchemaDateTimeException\r
-                , XMLExcepts::DateTime_dur_DashNotFirst\r
-                , fBuffer);\r
-    }\r
-\r
-    //at least one number and designator must be seen after P\r
-    bool designator = false;\r
-\r
-    int endDate = indexOf(fStart, fEnd, DATETIME_SEPARATOR);\r
-    if ( endDate == NOT_FOUND )\r
-    {\r
-        endDate = fEnd;  // 'T' absent\r
-    }\r
-\r
-    //find 'Y'\r
-    int end = indexOf(fStart, endDate, DURATION_Y);\r
-    if ( end != NOT_FOUND )\r
-    {\r
-        //scan year\r
-        fValue[CentYear] = negate * parseInt(fStart, end);\r
-        fStart = end+1;\r
-        designator = true;\r
-    }\r
-\r
-    end = indexOf(fStart, endDate, DURATION_M);\r
-    if ( end != NOT_FOUND )\r
-    {\r
-        //scan month\r
-        fValue[Month] = negate * parseInt(fStart, end);\r
-        fStart = end+1;\r
-        designator = true;\r
-    }\r
-\r
-    end = indexOf(fStart, endDate, DURATION_D);\r
-    if ( end != NOT_FOUND )\r
-    {\r
-        //scan day\r
-        fValue[Day] = negate * parseInt(fStart,end);\r
-        fStart = end+1;\r
-        designator = true;\r
-    }\r
-\r
-    if ( (fEnd == endDate) &&   // 'T' absent\r
-         (fStart != fEnd)   )   // something after Day\r
-    {\r
-        ThrowXML1(SchemaDateTimeException\r
-                , XMLExcepts::DateTime_dur_inv_b4T\r
-                , fBuffer);\r
-    }\r
-\r
-    if ( fEnd != endDate ) // 'T' present\r
-    {\r
-        //scan hours, minutes, seconds\r
-        //\r
-\r
-        // skip 'T' first\r
-        end = indexOf(++fStart, fEnd, DURATION_H);\r
-        if ( end != NOT_FOUND )\r
-        {\r
-            //scan hours\r
-            fValue[Hour] = negate * parseInt(fStart, end);\r
-            fStart = end+1;\r
-            designator = true;\r
-        }\r
-\r
-        end = indexOf(fStart, fEnd, DURATION_M);\r
-        if ( end != NOT_FOUND )\r
-        {\r
-            //scan min\r
-            fValue[Minute] = negate * parseInt(fStart, end);\r
-            fStart = end+1;\r
-            designator = true;\r
-        }\r
-\r
-        end = indexOf(fStart, fEnd, DURATION_S);\r
-        if ( end != NOT_FOUND )\r
-        {\r
-            //scan seconds\r
-            int mlsec = indexOf (fStart, end, MILISECOND_SEPARATOR);\r
-\r
-            /***\r
-             * Schema Errata: E2-23\r
-             * at least one digit must follow the decimal point if it appears. \r
-             * That is, the value of the seconds component must conform \r
-             * to the following pattern: [0-9]+(.[0-9]+)? \r
-             */\r
-            if ( mlsec != NOT_FOUND )\r
-            {\r
-                /***\r
-                 * make usure there is something after the '.' and before the end.\r
-                 */\r
-                if ( mlsec+1 == end )\r
-                {\r
-                    ThrowXML1(SchemaDateTimeException\r
-                            , XMLExcepts::DateTime_dur_inv_seconds\r
-                            , fBuffer);\r
-                }\r
-\r
-                fValue[Second]     = negate * parseInt(fStart, mlsec);\r
-                fMiliSecond        = negate * parseMiliSecond(mlsec+1, end);\r
-            }\r
-            else\r
-            {\r
-                fValue[Second] = negate * parseInt(fStart,end);\r
-            }\r
-\r
-            fStart = end+1;\r
-            designator = true;\r
-        }\r
-\r
-        // no additional data should appear after last item\r
-        // P1Y1M1DT is illigal value as well\r
-        if ( (fStart != fEnd) ||\r
-              fBuffer[--fStart] == DATETIME_SEPARATOR )\r
-        {\r
-            ThrowXML1(SchemaDateTimeException\r
-                    , XMLExcepts::DateTime_dur_NoTimeAfterT\r
-                    , fBuffer);\r
-        }\r
-    }\r
-\r
-    if ( !designator )\r
-    {\r
-        ThrowXML1(SchemaDateTimeException\r
-                , XMLExcepts::DateTime_dur_NoElementAtAll\r
-                , fBuffer);\r
-    }\r
-\r
-}\r
-\r
-// ---------------------------------------------------------------------------\r
-//  Scanners\r
-// ---------------------------------------------------------------------------\r
-\r
-//\r
-// [-]{CCYY-MM-DD}\r
-//\r
-// Note: CCYY could be more than 4 digits\r
-//       Assuming fStart point to the beginning of the Date Section\r
-//       fStart updated to point to the position right AFTER the second 'D'\r
-//       Since the lenght of CCYY might be variable, we can't check format upfront\r
-//\r
-void DateTime::getDate()\r
-{\r
-\r
-    // Ensure enough chars in buffer\r
-    if ( (fStart+YMD_MIN_SIZE) > fEnd)\r
-        ThrowXML1(SchemaDateTimeException\r
-                , XMLExcepts::DateTime_date_incomplete\r
-                , fBuffer);\r
-\r
-    getYearMonth();    // Scan YearMonth and\r
-                       // fStart point to the next '-'\r
-\r
-    if (fBuffer[fStart++] != DATE_SEPARATOR)\r
-    {\r
-        ThrowXML1(SchemaDateTimeException\r
-                , XMLExcepts::DateTime_date_invalid\r
-                , fBuffer);\r
-        //("CCYY-MM must be followed by '-' sign");\r
-    }\r
-\r
-    fValue[Day] = parseInt(fStart, fStart+2);\r
-    fStart += 2 ;  //fStart points right after the Day\r
-\r
-    return;\r
-}\r
-\r
-//\r
-// hh:mm:ss[.msssss]['Z']\r
-// hh:mm:ss[.msssss][['+'|'-']hh:mm]\r
-// 012345678\r
-//\r
-// Note: Assuming fStart point to the beginning of the Time Section\r
-//       fStart updated to point to the position right AFTER the second 's'\r
-//                                                  or ms if any\r
-//\r
-void DateTime::getTime()\r
-{\r
-\r
-    // Ensure enough chars in buffer\r
-    if ( (fStart+TIME_MIN_SIZE) > fEnd)\r
-        ThrowXML1(SchemaDateTimeException\r
-                , XMLExcepts::DateTime_time_incomplete\r
-                , fBuffer);\r
-        //"Imcomplete Time Format"\r
-\r
-    // check (fixed) format first\r
-    if ((fBuffer[fStart + 2] != TIME_SEPARATOR) ||\r
-        (fBuffer[fStart + 5] != TIME_SEPARATOR)  )\r
-    {\r
-        ThrowXML1(SchemaDateTimeException\r
-                , XMLExcepts::DateTime_time_invalid\r
-                , fBuffer);\r
-        //("Error in parsing time" );\r
-    }\r
-\r
-    //\r
-    // get hours, minute and second\r
-    //\r
-    fValue[Hour]   = parseInt(fStart + 0, fStart + 2);\r
-    fValue[Minute] = parseInt(fStart + 3, fStart + 5);\r
-    fValue[Second] = parseInt(fStart + 6, fStart + 8);\r
-    fStart += 8;\r
-\r
-    // to see if any ms and/or utc part after that\r
-    if (fStart >= fEnd)\r
-        return;\r
-\r
-    //find UTC sign if any\r
-    int sign = findUTCSign(fStart);\r
-\r
-    //parse miliseconds\r
-    int milisec = (fBuffer[fStart] == MILISECOND_SEPARATOR)? fStart : NOT_FOUND;\r
-    if ( milisec != NOT_FOUND )\r
-    {\r
-        fStart++;   // skip the '.'\r
-        // make sure we have some thing between the '.' and fEnd\r
-        if (fStart >= fEnd)\r
-        {\r
-            ThrowXML1(SchemaDateTimeException\r
-                    , XMLExcepts::DateTime_ms_noDigit\r
-                    , fBuffer);\r
-            //("ms shall be present once '.' is present" );\r
-        }\r
-\r
-        if ( sign == NOT_FOUND )\r
-        {\r
-            fMiliSecond = parseMiliSecond(fStart, fEnd);  //get ms between '.' and fEnd\r
-            fStart = fEnd;\r
-        }\r
-        else\r
-        {\r
-            fMiliSecond = parseMiliSecond(fStart, sign);  //get ms between UTC sign and fEnd\r
-        }\r
-       }\r
-    else if(sign == 0 || sign != fStart)\r
-    {\r
-        // seconds has more than 2 digits\r
-        ThrowXML1(SchemaDateTimeException\r
-                , XMLExcepts::DateTime_min_invalid\r
-                , fBuffer);\r
-    }\r
-\r
-    //parse UTC time zone (hh:mm)\r
-    if ( sign > 0 ) {\r
-        getTimeZone(sign);\r
-    }\r
-\r
-}\r
-\r
-//\r
-// [-]{CCYY-MM}\r
-//\r
-// Note: CCYY could be more than 4 digits\r
-//       fStart updated to point AFTER the second 'M' (probably meet the fEnd)\r
-//\r
-void DateTime::getYearMonth()\r
-{\r
-\r
-    // Ensure enough chars in buffer\r
-    if ( (fStart+YMONTH_MIN_SIZE) > fEnd)\r
-        ThrowXML1(SchemaDateTimeException\r
-                , XMLExcepts::DateTime_ym_incomplete\r
-                , fBuffer);\r
-        //"Imcomplete YearMonth Format";\r
-\r
-    // skip the first leading '-'\r
-    int start = ( fBuffer[0] == chDash ) ? fStart + 1 : fStart;\r
-\r
-    //\r
-    // search for year separator '-'\r
-    //\r
-    int yearSeparator = indexOf(start, fEnd, DATE_SEPARATOR);\r
-    if ( yearSeparator == NOT_FOUND)\r
-        ThrowXML1(SchemaDateTimeException\r
-                , XMLExcepts::DateTime_ym_invalid\r
-                , fBuffer);\r
-        //("Year separator is missing or misplaced");\r
-\r
-    fValue[CentYear] = parseIntYear(yearSeparator);\r
-    fStart = yearSeparator + 1;  //skip the '-' and point to the first M\r
-\r
-    //\r
-    //gonna check we have enough byte for month\r
-    //\r
-    if ((fStart + 2) > fEnd )\r
-        ThrowXML1(SchemaDateTimeException\r
-                , XMLExcepts::DateTime_ym_noMonth\r
-                , fBuffer);\r
-        //"no month in buffer"\r
-\r
-    fValue[Month] = parseInt(fStart, yearSeparator + 3);\r
-    fStart += 2;  //fStart points right after the MONTH\r
-\r
-    return;\r
-}\r
-\r
-void DateTime::parseTimeZone()\r
-{\r
-    if ( fStart < fEnd )\r
-    {\r
-        int sign = findUTCSign(fStart);\r
-        if ( sign < 0 )\r
-        {\r
-            ThrowXML1(SchemaDateTimeException\r
-                    , XMLExcepts::DateTime_tz_noUTCsign\r
-                    , fBuffer);\r
-            //("Error in month parsing");\r
-        }\r
-        else\r
-        {\r
-            getTimeZone(sign);\r
-        }\r
-    }\r
-\r
-    return;\r
-}\r
-\r
-//\r
-// 'Z'\r
-// ['+'|'-']hh:mm\r
-//\r
-// Note: Assuming fStart points to the beginning of TimeZone section\r
-//       fStart updated to meet fEnd\r
-//\r
-void DateTime::getTimeZone(const int sign)\r
-{\r
-\r
-    if ( fBuffer[sign] == UTC_STD_CHAR )\r
-    {\r
-        if ((sign + 1) != fEnd )\r
-        {\r
-            ThrowXML1(SchemaDateTimeException\r
-                    , XMLExcepts::DateTime_tz_stuffAfterZ\r
-                    , fBuffer);\r
-            //"Error in parsing time zone");\r
-        }              \r
-\r
-        return;        \r
-    }\r
-\r
-    //\r
-    // otherwise, it has to be this format\r
-    // '[+|-]'hh:mm\r
-    //    1   23456 7\r
-    //   sign      fEnd\r
-    //\r
-    if ( ( ( sign + TIMEZONE_SIZE + 1) != fEnd )      ||\r
-         ( fBuffer[sign + 3] != TIMEZONE_SEPARATOR ) )\r
-    {\r
-        ThrowXML1(SchemaDateTimeException\r
-                , XMLExcepts::DateTime_tz_invalid\r
-                , fBuffer);\r
-        //("Error in parsing time zone");\r
-    }\r
-\r
-    fTimeZone[hh] = parseInt(sign+1, sign+3);          \r
-    fTimeZone[mm] = parseInt(sign+4, fEnd);\r
-                       \r
-    return;\r
-}\r
-\r
-// ---------------------------------------------------------------------------\r
-//  Validator and normalizer\r
-// ---------------------------------------------------------------------------\r
-\r
-/**\r
- * If timezone present - normalize dateTime  [E Adding durations to dateTimes]\r
- *\r
- * @param date   CCYY-MM-DDThh:mm:ss+03\r
- * @return CCYY-MM-DDThh:mm:ssZ\r
- */\r
-void DateTime::normalize()\r
-{\r
-\r
-    if ((fValue[utc] == UTC_UNKNOWN) ||\r
-        (fValue[utc] == UTC_STD)      )\r
-        return;\r
-\r
-    int negate = (fValue[utc] == UTC_POS)? -1: 1;\r
-\r
-    // add mins\r
-    int temp = fValue[Minute] + negate * fTimeZone[mm];\r
-    int carry = fQuotient(temp, 60);\r
-    fValue[Minute] = mod(temp, 60, carry);\r
-\r
-    //add hours\r
-    temp = fValue[Hour] + negate * fTimeZone[hh] + carry;\r
-    carry = fQuotient(temp, 24);\r
-    fValue[Hour] = mod(temp, 24, carry);\r
-\r
-    fValue[Day] += carry;\r
-\r
-    while (1)\r
-    {\r
-        temp = maxDayInMonthFor(fValue[CentYear], fValue[Month]);\r
-        if (fValue[Day] < 1)\r
-        {\r
-            fValue[Day] += maxDayInMonthFor(fValue[CentYear], fValue[Month] - 1);\r
-            carry = -1;\r
-        }\r
-        else if ( fValue[Day] > temp )\r
-        {\r
-            fValue[Day] -= temp;\r
-            carry = 1;\r
-        }\r
-        else\r
-        {\r
-            break;\r
-        }\r
-\r
-        temp = fValue[Month] + carry;\r
-        fValue[Month] = modulo(temp, 1, 13);\r
-        fValue[CentYear] += fQuotient(temp, 1, 13);\r
-    }\r
-\r
-    // set to normalized\r
-    fValue[utc] = UTC_STD;\r
-\r
-    return;\r
-}\r
-\r
-void DateTime::validateDateTime() const\r
-{\r
-\r
-    //REVISIT: should we throw an exception for not valid dates\r
-    //          or reporting an error message should be sufficient?\r
-    if ( fValue[CentYear] == 0 )\r
-    {\r
-        ThrowXML1(SchemaDateTimeException\r
-                , XMLExcepts::DateTime_year_zero\r
-                , fBuffer);\r
-        //"The year \"0000\" is an illegal year value");\r
-    }\r
-\r
-    if ( fValue[Month] < 1  ||\r
-         fValue[Month] > 12  )\r
-    {\r
-        ThrowXML1(SchemaDateTimeException\r
-                , XMLExcepts::DateTime_mth_invalid\r
-                , fBuffer);\r
-               //"The month must have values 1 to 12");\r
-    }\r
-\r
-    //validate days\r
-    if ( fValue[Day] > maxDayInMonthFor( fValue[CentYear], fValue[Month]) ||\r
-         fValue[Day] == 0 )\r
-    {\r
-        ThrowXML1(SchemaDateTimeException\r
-                , XMLExcepts::DateTime_day_invalid\r
-                , fBuffer);\r
-        //"The day must have values 1 to 31");\r
-    }\r
-\r
-    //validate hours\r
-    if ((fValue[Hour] < 0)  ||\r
-        (fValue[Hour] > 24) ||\r
-        ((fValue[Hour] == 24) && ((fValue[Minute] !=0) ||\r
-                                  (fValue[Second] !=0) ||\r
-                                  (fMiliSecond    !=0))))\r
-    {\r
-        ThrowXML1(SchemaDateTimeException\r
-                , XMLExcepts::DateTime_hour_invalid\r
-                , fBuffer);\r
-        //("Hour must have values 0-23");\r
-    }\r
-\r
-    //validate minutes\r
-    if ( fValue[Minute] < 0 ||\r
-         fValue[Minute] > 59 )\r
-    {\r
-        ThrowXML1(SchemaDateTimeException\r
-                , XMLExcepts::DateTime_min_invalid\r
-                , fBuffer);\r
-        //"Minute must have values 0-59");\r
-    }\r
-\r
-    //validate seconds\r
-    if ( fValue[Second] < 0 ||\r
-         fValue[Second] > 60 )\r
-    {\r
-        ThrowXML1(SchemaDateTimeException\r
-                , XMLExcepts::DateTime_second_invalid\r
-                , fBuffer);\r
-        //"Second must have values 0-60");\r
-    }\r
-\r
-    //validate time-zone hours\r
-    if ( (abs(fTimeZone[hh]) > 14) ||\r
-         ((abs(fTimeZone[hh]) == 14) && (fTimeZone[mm] != 0)) )\r
-    {\r
-        ThrowXML1(SchemaDateTimeException\r
-                , XMLExcepts::DateTime_tz_hh_invalid\r
-                , fBuffer);\r
-        //"Time zone should have range -14..+14");\r
-    }\r
-\r
-    //validate time-zone minutes\r
-    if ( abs(fTimeZone[mm]) > 59 )\r
-    {\r
-        ThrowXML1(SchemaDateTimeException\r
-                , XMLExcepts::DateTime_min_invalid\r
-                , fBuffer);\r
-        //("Minute must have values 0-59");\r
-    }\r
-       \r
-    return;\r
-}\r
-\r
-// -----------------------------------------------------------------------\r
-// locator and converter\r
-// -----------------------------------------------------------------------\r
-int DateTime::indexOf(const int start, const int end, const XMLCh ch) const\r
-{\r
-    for ( int i = start; i < end; i++ )\r
-        if ( fBuffer[i] == ch )\r
-            return i;\r
-\r
-    return NOT_FOUND;\r
-}\r
-\r
-int DateTime::findUTCSign (const int start)\r
-{\r
-    int  pos;\r
-    for ( int index = start; index < fEnd; index++ )\r
-    {\r
-        pos = XMLString::indexOf(UTC_SET, fBuffer[index]);\r
-        if ( pos != NOT_FOUND)\r
-        {\r
-            fValue[utc] = pos+1;   // refer to utcType, there is 1 diff\r
-            return index;\r
-        }\r
-    }\r
-\r
-    return NOT_FOUND;\r
-}\r
-\r
-//\r
-// Note:\r
-//    start: starting point in fBuffer\r
-//    end:   ending point in fBuffer (exclusive)\r
-//    fStart NOT updated\r
-//\r
-int DateTime::parseInt(const int start, const int end) const\r
-{\r
-    unsigned int retVal = 0;\r
-    for (int i=start; i < end; i++) {\r
-\r
-        if (fBuffer[i] < chDigit_0 || fBuffer[i] > chDigit_9)\r
-            ThrowXML(NumberFormatException, XMLExcepts::XMLNUM_Inv_chars);\r
-\r
-        retVal = (retVal * 10) + (unsigned int) (fBuffer[i] - chDigit_0);\r
-    }\r
-\r
-    return (int) retVal;\r
-}\r
-\r
-//\r
-// Note:\r
-//    start: pointing to the first digit after the '.'\r
-//    end:   pointing to one position after the last digit\r
-//    fStart NOT updated\r
-//\r
-double DateTime::parseMiliSecond(const int start, const int end) const\r
-{\r
-\r
-    unsigned int  miliSecLen = (end-1) - (start-1) + 1; //to include the '.'\r
-    XMLCh* miliSecData = new XMLCh[miliSecLen + 1];\r
-    ArrayJanitor<XMLCh> janMili(miliSecData);\r
-    XMLString::copyNString(miliSecData, &(fBuffer[start-1]), miliSecLen);\r
-    *(miliSecData + miliSecLen) = chNull;\r
-\r
-    char *nptr = XMLString::transcode(miliSecData);\r
-    ArrayJanitor<char> jan(nptr);\r
-    size_t   strLen = strlen(nptr);\r
-    char *endptr = 0;\r
-    errno = 0;\r
-\r
-    //printf("milisec=<%s>\n", nptr);\r
-\r
-    double retVal = strtod(nptr, &endptr);\r
-\r
-    // check if all chars are valid char\r
-    if ( (endptr - nptr) != strLen)\r
-        ThrowXML(NumberFormatException, XMLExcepts::XMLNUM_Inv_chars);\r
-\r
-    // we don't check underflow occurs since\r
-    // nothing we can do about it.\r
-    return retVal;\r
-}\r
-\r
-//\r
-// [-]CCYY\r
-//\r
-// Note: start from fStart\r
-//       end (exclusive)\r
-//       fStart NOT updated\r
-//\r
-int DateTime::parseIntYear(const int end) const\r
-{\r
-    // skip the first leading '-'\r
-    int start = ( fBuffer[0] == chDash ) ? fStart + 1 : fStart;\r
-\r
-    int length = end - start;\r
-    if (length < 4)\r
-    {\r
-        ThrowXML1(SchemaDateTimeException\r
-                , XMLExcepts::DateTime_year_tooShort\r
-                , fBuffer);\r
-        //"Year must have 'CCYY' format");\r
-    }\r
-    else if (length > 4 &&\r
-             fBuffer[start] == chDigit_0)\r
-    {\r
-        ThrowXML1(SchemaDateTimeException\r
-                , XMLExcepts::DateTime_year_leadingZero\r
-                , fBuffer);\r
-        //"Leading zeros are required if the year value would otherwise have fewer than four digits;\r
-        // otherwise they are forbidden");\r
-    }\r
-\r
-    bool negative = (fBuffer[0] == chDash);\r
-    int  yearVal = parseInt((negative ? 1 : 0), end);\r
-    return ( negative ? (-1) * yearVal : yearVal );\r
-}\r
-\r
-/***\r
- * E2-41\r
- *\r
- *  3.2.7.2 Canonical representation\r
- * \r
- *  Except for trailing fractional zero digits in the seconds representation, \r
- *  '24:00:00' time representations, and timezone (for timezoned values), \r
- *  the mapping from literals to values is one-to-one. Where there is more \r
- *  than one possible representation, the canonical representation is as follows: \r
- *  redundant trailing zero digits in fractional-second literals are prohibited. \r
- *  An hour representation of '24' is prohibited. Timezoned values are canonically\r
- *  represented by appending 'Z' to the nontimezoned representation. (All \r
- *  timezoned dateTime values are UTC.) \r
- *\r
- *  .'24:00:00' -> '00:00:00'\r
- *  .milisecond: trailing zeros removed\r
- *  .'Z'\r
- *\r
- ***/\r
-XMLCh* DateTime::getDateTimeCanonicalRepresentation() const\r
-{\r
-    XMLCh *miliStartPtr, *miliEndPtr;\r
-    searchMiliSeconds(miliStartPtr, miliEndPtr);\r
-    size_t miliSecondsLen = miliEndPtr - miliStartPtr;\r
-\r
-    XMLCh* retBuf = new XMLCh[21 + miliSecondsLen + 2];\r
-    XMLCh* retPtr = retBuf;\r
-\r
-    // (-?) cc+yy-mm-dd'T'hh:mm:ss'Z'    ('.'s+)?\r
-    //      2+  8       1      8   1\r
-    //\r
-    int additionalLen = fillYearString(retPtr, CentYear);\r
-    if(additionalLen != 0)\r
-    {\r
-        // very bad luck; have to resize the buffer...\r
-        XMLCh *tmpBuf = new XMLCh[additionalLen+21+miliSecondsLen +2];\r
-        XMLString::moveChars(tmpBuf, retBuf, 4+additionalLen);\r
-        retPtr = tmpBuf+(retPtr-retBuf);\r
-        delete[] retBuf;\r
-        retBuf = tmpBuf;\r
-    }\r
-    *retPtr++ = DATE_SEPARATOR;\r
-    fillString(retPtr, Month, 2);\r
-    *retPtr++ = DATE_SEPARATOR;\r
-    fillString(retPtr, Day, 2);\r
-    *retPtr++ = DATETIME_SEPARATOR;\r
-\r
-    fillString(retPtr, Hour, 2);\r
-    if (fValue[Hour] == 24)\r
-    {\r
-        *(retPtr - 2) = chDigit_0;\r
-        *(retPtr - 1) = chDigit_0;\r
-    }\r
-    *retPtr++ = TIME_SEPARATOR;\r
-    fillString(retPtr, Minute, 2);\r
-    *retPtr++ = TIME_SEPARATOR;\r
-    fillString(retPtr, Second, 2);\r
-\r
-    if (miliSecondsLen)\r
-    {\r
-        *retPtr++ = chPeriod;\r
-        XMLString::copyNString(retPtr, miliStartPtr, miliSecondsLen);\r
-        retPtr += miliSecondsLen;\r
-    }\r
-\r
-    *retPtr++ = UTC_STD_CHAR;\r
-    *retPtr = chNull;\r
-\r
-    return retBuf;\r
-}\r
-\r
-/***\r
- * 3.2.8 time\r
- *\r
- *  . either the time zone must be omitted or, \r
- *    if present, the time zone must be Coordinated Universal Time (UTC) indicated by a "Z".   \r
- *\r
- *  . Additionally, the canonical representation for midnight is 00:00:00.\r
- *\r
-***/\r
-XMLCh* DateTime::getTimeCanonicalRepresentation() const\r
-{\r
-    XMLCh *miliStartPtr, *miliEndPtr;\r
-    searchMiliSeconds(miliStartPtr, miliEndPtr);\r
-    size_t miliSecondsLen = miliEndPtr - miliStartPtr;\r
-\r
-    XMLCh* retBuf = new XMLCh[10 + miliSecondsLen + 2];\r
-    XMLCh* retPtr = retBuf;\r
-\r
-    // 'hh:mm:ss'Z'    ('.'s+)?\r
-    //      8    1\r
-    //\r
-\r
-    fillString(retPtr, Hour, 2);\r
-    if (fValue[Hour] == 24)\r
-    {\r
-        *(retPtr - 2) = chDigit_0;\r
-        *(retPtr - 1) = chDigit_0;\r
-    }\r
-    *retPtr++ = TIME_SEPARATOR;\r
-    fillString(retPtr, Minute, 2);\r
-    *retPtr++ = TIME_SEPARATOR;\r
-    fillString(retPtr, Second, 2);\r
-\r
-    if (miliSecondsLen)\r
-    {\r
-        *retPtr++ = chPeriod;\r
-        XMLString::copyNString(retPtr, miliStartPtr, miliSecondsLen);\r
-        retPtr += miliSecondsLen;\r
-    }\r
-\r
-    *retPtr++ = UTC_STD_CHAR;\r
-    *retPtr = chNull;\r
-\r
-    return retBuf;\r
-}\r
-\r
-void DateTime::fillString(XMLCh*& ptr, valueIndex ind, int expLen) const\r
-{\r
-    XMLCh strBuffer[16];\r
-    assert(expLen < 16);\r
-    XMLString::binToText(fValue[ind], strBuffer, expLen, 10);\r
-    int   actualLen = XMLString::stringLen(strBuffer);\r
-    int   i;\r
-    //append leading zeros\r
-    for (i = 0; i < expLen - actualLen; i++)\r
-    {\r
-        *ptr++ = chDigit_0;\r
-    }\r
-\r
-    for (i = 0; i < actualLen; i++)\r
-    {\r
-        *ptr++ = strBuffer[i];\r
-    }\r
-\r
-}\r
-\r
-int DateTime::fillYearString(XMLCh*& ptr, valueIndex ind) const\r
-{\r
-    XMLCh strBuffer[16];\r
-    // let's hope we get no years of 15 digits...\r
-    XMLString::binToText(fValue[ind], strBuffer, 15, 10);\r
-    int   actualLen = XMLString::stringLen(strBuffer);\r
-    // don't forget that years can be negative...\r
-    int negativeYear = 0;\r
-    if(strBuffer[0] == chDash)\r
-    {\r
-        *ptr++ = strBuffer[0];\r
-        negativeYear = 1;\r
-    }\r
-    int   i;\r
-    //append leading zeros\r
-    for (i = 0; i < 4 - actualLen+negativeYear; i++)\r
-    {\r
-        *ptr++ = chDigit_0;\r
-    }\r
-\r
-    for (i = negativeYear; i < actualLen; i++)\r
-    {\r
-        *ptr++ = strBuffer[i];\r
-    }\r
-    if(actualLen > 4)\r
-        return actualLen-4;\r
-    return 0;\r
-}\r
-\r
-/***\r
- *\r
- *   .check if the rawData has the mili second component\r
- *   .capture the substring\r
- *\r
- ***/\r
-void DateTime::searchMiliSeconds(XMLCh*& miliStartPtr, XMLCh*& miliEndPtr) const\r
-{\r
-    miliStartPtr = miliEndPtr = 0;\r
-\r
-    int milisec = XMLString::indexOf(fBuffer, MILISECOND_SEPARATOR);\r
-    if (milisec == -1)\r
-        return;\r
-\r
-    miliStartPtr = fBuffer + milisec + 1;\r
-    miliEndPtr   = miliStartPtr;\r
-    while (*miliEndPtr)\r
-    {\r
-        if ((*miliEndPtr < chDigit_0) || (*miliEndPtr > chDigit_9))\r
-            break;\r
-\r
-        miliEndPtr++;\r
-    }\r
-\r
-    //remove trailing zeros\r
-    while( *(miliEndPtr - 1) == chDigit_0)\r
-        miliEndPtr--;\r
-\r
-    return;\r
-}\r
-\r
+/*
+ *  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.
+ */
+
+/**
+ * DateTime.cpp
+ * 
+ * Manipulation of XML date/time data. 
+ */
+
+/*
+ * This is mostly copied from Xerces-C, but they don't seem inclined to produce a usable
+ * class, so I had to incorporate my own version of it for now. I can't inherit it
+ * since the fields I need are private.
+ */
+
+#include "internal.h"
+#include "util/DateTime.h"
+
+#ifndef WIN32
+# include <errno.h>
+#endif
+
+#include <ctime>
+#include <xercesc/util/Janitor.hpp>
+#include <xercesc/util/NumberFormatException.hpp>
+
+using namespace xmltooling;
+using namespace std;
+
+//
+// constants used to process raw data (fBuffer)
+//
+// [-]{CCYY-MM-DD}'T'{HH:MM:SS.MS}['Z']
+//                                [{+|-}hh:mm']
+//
+
+static const XMLCh DURATION_STARTER     = chLatin_P;              // 'P'
+static const XMLCh DURATION_Y           = chLatin_Y;              // 'Y'
+static const XMLCh DURATION_M           = chLatin_M;              // 'M'
+static const XMLCh DURATION_D           = chLatin_D;              // 'D'
+static const XMLCh DURATION_H           = chLatin_H;              // 'H'
+static const XMLCh DURATION_S           = chLatin_S;              // 'S'
+
+static const XMLCh DATE_SEPARATOR       = chDash;                 // '-'
+static const XMLCh TIME_SEPARATOR       = chColon;                // ':'
+static const XMLCh TIMEZONE_SEPARATOR   = chColon;                // ':'
+static const XMLCh DATETIME_SEPARATOR   = chLatin_T;              // 'T'
+static const XMLCh MILISECOND_SEPARATOR = chPeriod;               // '.'
+
+static const XMLCh UTC_STD_CHAR         = chLatin_Z;              // 'Z'
+static const XMLCh UTC_POS_CHAR         = chPlus;                 // '+'
+static const XMLCh UTC_NEG_CHAR         = chDash;                 // '-'
+
+static const XMLCh UTC_SET[]            = {UTC_STD_CHAR           //"Z+-"
+                                         , UTC_POS_CHAR
+                                         , UTC_NEG_CHAR
+                                         , chNull};
+
+static const int YMD_MIN_SIZE    = 10;   // CCYY-MM-DD
+static const int YMONTH_MIN_SIZE = 7;    // CCYY_MM
+static const int TIME_MIN_SIZE   = 8;    // hh:mm:ss
+static const int TIMEZONE_SIZE   = 5;    // hh:mm
+static const int DAY_SIZE        = 5;    // ---DD
+//static const int MONTH_SIZE      = 6;    // --MM--
+static const int MONTHDAY_SIZE   = 7;    // --MM-DD
+static const int NOT_FOUND       = -1;
+
+//define constants to be used in assigning default values for
+//all date/time excluding duration
+static const int YEAR_DEFAULT  = 2000;
+static const int MONTH_DEFAULT = 01;
+static const int DAY_DEFAULT   = 15;
+
+// order-relation on duration is a partial order. The dates below are used to
+// for comparison of 2 durations, based on the fact that
+// duration x and y is x<=y iff s+x<=s+y
+// see 3.2.6 duration W3C schema datatype specs
+//
+// the dates are in format: {CCYY,MM,DD, H, S, M, MS, timezone}
+const int DateTime::DATETIMES[][TOTAL_SIZE] =
+{
+    {1696, 9, 1, 0, 0, 0, 0, UTC_STD},
+       {1697, 2, 1, 0, 0, 0, 0, UTC_STD},
+       {1903, 3, 1, 0, 0, 0, 0, UTC_STD},
+       {1903, 7, 1, 0, 0, 0, 0, UTC_STD}
+};
+
+// ---------------------------------------------------------------------------
+//  local methods
+// ---------------------------------------------------------------------------
+static inline int fQuotient(int a, int b)
+{
+    div_t div_result = div(a, b);
+    return div_result.quot;
+}
+
+static inline int fQuotient(int temp, int low, int high)
+{
+    return fQuotient(temp - low, high - low);
+}
+
+static inline int mod(int a, int b, int quotient)
+{
+       return (a - quotient*b) ;
+}
+
+static inline int modulo (int temp, int low, int high)
+{
+    //modulo(a - low, high - low) + low
+    int a = temp - low;
+    int b = high - low;
+    return (mod (a, b, fQuotient(a, b)) + low) ;
+}
+
+static inline bool isLeapYear(int year)
+{
+    return((year%4 == 0) && ((year%100 != 0) || (year%400 == 0)));
+}
+
+static int maxDayInMonthFor(int year, int month)
+{
+
+    if ( month == 4 || month == 6 || month == 9 || month == 11 )
+    {
+        return 30;
+    }
+    else if ( month==2 )
+    {
+        if ( isLeapYear(year) )
+            return 29;
+        else
+            return 28;
+    }
+    else
+    {
+        return 31;
+    }
+
+}
+
+// ---------------------------------------------------------------------------
+//  static methods : for duration
+// ---------------------------------------------------------------------------
+/**
+ * Compares 2 given durations. (refer to W3C Schema Datatypes "3.2.6 duration")
+ *
+ * 3.2.6.2 Order relation on duration
+ *
+ *     In general, the order-relation on duration is a partial order since there is no
+ *  determinate relationship between certain durations such as one month (P1M) and 30 days (P30D).
+ *  The order-relation of two duration values x and y is x < y iff s+x < s+y for each qualified
+ *  dateTime s in the list below.
+ *
+ *     These values for s cause the greatest deviations in the addition of dateTimes and durations
+ *
+ **/
+int DateTime::compare(const DateTime* const pDate1
+                       , const DateTime* const pDate2
+                       , bool  strict)
+{
+    //REVISIT: this is unoptimazed vs of comparing 2 durations
+    //         Algorithm is described in 3.2.6.2 W3C Schema Datatype specs
+    //
+
+    int resultA, resultB = XMLDateTime::INDETERMINATE;
+
+    //try and see if the objects are equal
+    if ( (resultA = compareOrder(pDate1, pDate2)) == XMLDateTime::EQUAL)
+        return XMLDateTime::EQUAL;
+
+    //long comparison algorithm is required
+    DateTime tempA, *pTempA = &tempA;
+    DateTime tempB, *pTempB = &tempB;
+
+    addDuration(pTempA, pDate1, 0);
+    addDuration(pTempB, pDate2, 0);
+    resultA = compareOrder(pTempA, pTempB);
+    if ( resultA == XMLDateTime::INDETERMINATE )
+        return XMLDateTime::INDETERMINATE;
+
+    addDuration(pTempA, pDate1, 1);
+    addDuration(pTempB, pDate2, 1);
+    resultB = compareOrder(pTempA, pTempB);
+    resultA = compareResult(resultA, resultB, strict);
+    if ( resultA == XMLDateTime::INDETERMINATE )
+        return XMLDateTime::INDETERMINATE;
+
+    addDuration(pTempA, pDate1, 2);
+    addDuration(pTempB, pDate2, 2);
+    resultB = compareOrder(pTempA, pTempB);
+    resultA = compareResult(resultA, resultB, strict);
+    if ( resultA == XMLDateTime::INDETERMINATE )
+        return XMLDateTime::INDETERMINATE;
+
+    addDuration(pTempA, pDate1, 3);
+    addDuration(pTempB, pDate2, 3);
+    resultB = compareOrder(pTempA, pTempB);
+    resultA = compareResult(resultA, resultB, strict);
+
+    return resultA;
+
+}
+
+//
+// Form a new DateTime with duration and baseDate array
+// Note: C++        Java
+//       fNewDate   duration
+//       fDuration  date
+//
+
+void DateTime::addDuration(DateTime*             fNewDate
+                            , const DateTime* const fDuration
+                            , int index)
+
+{
+
+    //REVISIT: some code could be shared between normalize() and this method,
+    //         however is it worth moving it? The structures are different...
+    //
+
+    fNewDate->reset();
+    //add months (may be modified additionaly below)
+    int temp = DATETIMES[index][Month] + fDuration->fValue[Month];
+    fNewDate->fValue[Month] = modulo(temp, 1, 13);
+    int carry = fQuotient(temp, 1, 13);
+
+    //add years (may be modified additionaly below)
+    fNewDate->fValue[CentYear] =
+        DATETIMES[index][CentYear] + fDuration->fValue[CentYear] + carry;
+
+    //add seconds
+    temp = DATETIMES[index][Second] + fDuration->fValue[Second];
+    carry = fQuotient (temp, 60);
+    fNewDate->fValue[Second] =  mod(temp, 60, carry);
+               
+    //add minutes
+    temp = DATETIMES[index][Minute] + fDuration->fValue[Minute] + carry;
+    carry = fQuotient(temp, 60);
+    fNewDate->fValue[Minute] = mod(temp, 60, carry);
+
+    //add hours
+    temp = DATETIMES[index][Hour] + fDuration->fValue[Hour] + carry;
+    carry = fQuotient(temp, 24);
+    fNewDate->fValue[Hour] = mod(temp, 24, carry);
+               
+    fNewDate->fValue[Day] =
+        DATETIMES[index][Day] + fDuration->fValue[Day] + carry;
+
+    while ( true )
+    {
+        temp = maxDayInMonthFor(fNewDate->fValue[CentYear], fNewDate->fValue[Month]);
+        if ( fNewDate->fValue[Day] < 1 )
+        { //original fNewDate was negative
+            fNewDate->fValue[Day] +=
+                maxDayInMonthFor(fNewDate->fValue[CentYear], fNewDate->fValue[Month]-1);
+            carry = -1;
+        }
+        else if ( fNewDate->fValue[Day] > temp )
+        {
+            fNewDate->fValue[Day] -= temp;
+            carry = 1;
+        }
+        else
+        {
+            break;
+        }
+
+        temp = fNewDate->fValue[Month] + carry;
+        fNewDate->fValue[Month] = modulo(temp, 1, 13);
+        fNewDate->fValue[CentYear] += fQuotient(temp, 1, 13);
+    }
+
+    //fNewDate->fValue[utc] = UTC_STD_CHAR;
+    fNewDate->fValue[utc] = UTC_STD;
+}
+
+int DateTime::compareResult(int resultA
+                             , int resultB
+                             , bool strict)
+{
+
+    if ( resultB == XMLDateTime::INDETERMINATE )
+    {
+        return XMLDateTime::INDETERMINATE;
+    }
+    else if ( (resultA != resultB) &&
+              strict                )
+    {
+        return XMLDateTime::INDETERMINATE;
+    }
+    else if ( (resultA != resultB) &&
+              !strict               )
+    {
+        if ( (resultA != XMLDateTime::EQUAL) &&
+             (resultB != XMLDateTime::EQUAL)  )
+        {
+            return XMLDateTime::INDETERMINATE;
+        }
+        else
+        {
+            return (resultA != XMLDateTime::EQUAL)? resultA : resultB;
+        }
+    }
+
+    return resultA;
+       
+}
+
+// ---------------------------------------------------------------------------
+//  static methods : for others
+// ---------------------------------------------------------------------------
+int DateTime::compare(const DateTime* const pDate1
+                       , const DateTime* const pDate2)
+{
+
+    if (pDate1->fValue[utc] == pDate2->fValue[utc])
+    {
+        return DateTime::compareOrder(pDate1, pDate2);
+    }
+
+    int c1, c2;
+
+    if ( pDate1->isNormalized())
+    {
+        c1 = compareResult(pDate1, pDate2, false, UTC_POS);
+        c2 = compareResult(pDate1, pDate2, false, UTC_NEG);
+        return getRetVal(c1, c2);
+    }
+    else if ( pDate2->isNormalized())
+    {
+        c1 = compareResult(pDate1, pDate2, true, UTC_POS);
+        c2 = compareResult(pDate1, pDate2, true, UTC_NEG);
+        return getRetVal(c1, c2);
+    }
+
+    return XMLDateTime::INDETERMINATE; 
+}
+
+int DateTime::compareResult(const DateTime* const pDate1
+                             , const DateTime* const pDate2
+                             , bool  set2Left
+                             , int   utc_type)
+{
+    DateTime tmpDate = (set2Left ? *pDate1 : *pDate2);
+
+    tmpDate.fTimeZone[hh] = 14;
+    tmpDate.fTimeZone[mm] = 0;
+    tmpDate.fValue[utc] = utc_type;
+    tmpDate.normalize();
+
+    return (set2Left? DateTime::compareOrder(&tmpDate, pDate2) :
+                      DateTime::compareOrder(pDate1, &tmpDate));
+}
+
+int DateTime::compareOrder(const DateTime* const lValue
+                            , const DateTime* const rValue)
+                            //, MemoryManager* const memMgr)
+{
+    //
+    // If any of the them is not normalized() yet,
+    // we need to do something here.
+    //
+    DateTime lTemp = *lValue;
+    DateTime rTemp = *rValue;
+
+    lTemp.normalize();
+    rTemp.normalize();
+
+    for ( int i = 0 ; i < TOTAL_SIZE; i++ )
+    {
+        if ( lTemp.fValue[i] < rTemp.fValue[i] )
+        {
+            return XMLDateTime::LESS_THAN;
+        }
+        else if ( lTemp.fValue[i] > rTemp.fValue[i] )
+        {
+            return XMLDateTime::GREATER_THAN;
+        }
+    }
+
+    if ( lTemp.fHasTime)
+    {
+        if ( lTemp.fMiliSecond < rTemp.fMiliSecond )
+        {
+            return XMLDateTime::LESS_THAN;
+        }
+        else if ( lTemp.fMiliSecond > rTemp.fMiliSecond )
+        {
+            return XMLDateTime::GREATER_THAN;
+        }
+    }
+
+    return XMLDateTime::EQUAL;
+}
+
+// ---------------------------------------------------------------------------
+//  ctor and dtor
+// ---------------------------------------------------------------------------
+DateTime::~DateTime()
+{
+    delete[] fBuffer;
+}
+
+DateTime::DateTime()
+: fStart(0)
+, fEnd(0)
+, fBufferMaxLen(0)
+, fBuffer(0)
+, fMiliSecond(0)
+, fHasTime(false)
+{
+    reset();
+}
+
+DateTime::DateTime(const XMLCh* const aString)
+: fStart(0)
+, fEnd(0)
+, fBufferMaxLen(0)
+, fBuffer(0)
+, fMiliSecond(0)
+, fHasTime(false)
+{
+    setBuffer(aString);
+}
+
+DateTime::DateTime(time_t epoch)
+: fStart(0)
+, fEnd(0)
+, fBufferMaxLen(0)
+, fBuffer(0)
+, fMiliSecond(0)
+, fHasTime(false)
+{
+#ifndef HAVE_GMTIME_R
+    struct tm* ptime=gmtime(&epoch);
+#else
+    struct tm res;
+    struct tm* ptime=gmtime_r(&epoch,&res);
+#endif
+    char timebuf[32];
+    strftime(timebuf,32,"%Y-%m-%dT%H:%M:%SZ",ptime);
+    auto_ptr_XMLCh timeptr(timebuf);
+    setBuffer(timeptr.get());
+}
+
+// -----------------------------------------------------------------------
+// Copy ctor and Assignment operators
+// -----------------------------------------------------------------------
+
+DateTime::DateTime(const DateTime &toCopy)
+: fBufferMaxLen(0)
+, fBuffer(0)
+{
+    copy(toCopy);
+}
+
+DateTime& DateTime::operator=(const DateTime& rhs)
+{
+    if (this == &rhs)
+        return *this;
+
+    copy(rhs);
+    return *this;
+}
+
+// -----------------------------------------------------------------------
+// Implementation of Abstract Interface
+// -----------------------------------------------------------------------
+
+//
+// We may simply return the handle to fBuffer
+//
+const XMLCh*  DateTime::getRawData() const
+{
+    //assertBuffer();
+    return fBuffer;
+}
+
+
+const XMLCh*  DateTime::getFormattedString() const
+{
+    return getRawData();
+}
+
+int DateTime::getSign() const
+{
+    return 0;
+}
+
+time_t DateTime::getEpoch() const
+{
+    struct tm t;
+    t.tm_sec=getSecond();
+    t.tm_min=getMinute();
+    t.tm_hour=getHour();
+    t.tm_mday=getDay();
+    t.tm_mon=getMonth()-1;
+    t.tm_year=getYear()-1900;
+    t.tm_isdst=0;
+#if defined(HAVE_TIMEGM)
+    return timegm(&t);
+#else
+    // Windows, and hopefully most others...?
+    return mktime(&t) - timezone;
+#endif
+}
+
+// ---------------------------------------------------------------------------
+//  Parsers
+// ---------------------------------------------------------------------------
+
+//
+// [-]{CCYY-MM-DD}'T'{HH:MM:SS.MS}[TimeZone]
+//
+void DateTime::parseDateTime()
+{
+    initParser();
+    getDate();
+
+    //fStart is supposed to point to 'T'
+    if (fBuffer[fStart++] != DATETIME_SEPARATOR)
+        ThrowXML1(SchemaDateTimeException
+                , XMLExcepts::DateTime_gDay_invalid
+                , fBuffer);
+
+    getTime();
+    validateDateTime();
+    normalize();
+    fHasTime = true;
+}
+
+//
+// [-]{CCYY-MM-DD}[TimeZone]
+//
+void DateTime::parseDate()
+{
+    initParser();
+    getDate();
+    parseTimeZone();
+    validateDateTime();
+    normalize();
+}
+
+void DateTime::parseTime()
+{
+    initParser();
+
+    // time initialize to default values
+    fValue[CentYear]= YEAR_DEFAULT;
+    fValue[Month]   = MONTH_DEFAULT;
+    fValue[Day]     = DAY_DEFAULT;
+
+    getTime();
+
+    validateDateTime();
+    normalize();
+    fHasTime = true;
+}
+
+//
+// {---DD}[TimeZone]
+//  01234
+//
+void DateTime::parseDay()
+{
+    initParser();
+
+    if (fBuffer[0] != DATE_SEPARATOR ||
+        fBuffer[1] != DATE_SEPARATOR ||
+        fBuffer[2] != DATE_SEPARATOR  )
+    {
+        ThrowXML1(SchemaDateTimeException
+                , XMLExcepts::DateTime_gDay_invalid
+                , fBuffer);
+    }
+
+    //initialize values
+    fValue[CentYear] = YEAR_DEFAULT;
+    fValue[Month]    = MONTH_DEFAULT;
+    fValue[Day]      = parseInt(fStart+3, fStart+5);
+
+    if ( DAY_SIZE < fEnd )
+    {
+        int sign = findUTCSign(DAY_SIZE);
+        if ( sign < 0 )
+        {
+            ThrowXML1(SchemaDateTimeException
+                    , XMLExcepts::DateTime_gDay_invalid
+                    , fBuffer);
+        }
+        else
+        {
+            getTimeZone(sign);
+        }
+    }
+
+    validateDateTime();
+    normalize();
+}
+
+//
+// {--MM--}[TimeZone]
+// {--MM}[TimeZone]
+//  012345
+//
+void DateTime::parseMonth()
+{
+    initParser();
+
+    if (fBuffer[0] != DATE_SEPARATOR ||
+        fBuffer[1] != DATE_SEPARATOR  )
+    {
+        ThrowXML1(SchemaDateTimeException
+                , XMLExcepts::DateTime_gMth_invalid
+                , fBuffer);
+    }
+
+    //set constants
+    fValue[CentYear] = YEAR_DEFAULT;
+    fValue[Day]      = DAY_DEFAULT;
+    fValue[Month]    = parseInt(2, 4);
+
+    // REVISIT: allow both --MM and --MM-- now. 
+    // need to remove the following lines to disallow --MM-- 
+    // when the errata is officially in the rec. 
+    fStart = 4;
+    if ( fEnd >= fStart+2 && fBuffer[fStart] == DATE_SEPARATOR && fBuffer[fStart+1] == DATE_SEPARATOR ) 
+    { 
+        fStart += 2; 
+    } 
+
+    //
+    // parse TimeZone if any
+    //
+    if ( fStart < fEnd )
+    {
+        int sign = findUTCSign(fStart);
+        if ( sign < 0 )
+        {
+            ThrowXML1(SchemaDateTimeException
+                    , XMLExcepts::DateTime_gMth_invalid
+                    , fBuffer);
+        }
+        else
+        {
+            getTimeZone(sign);
+        }
+    }
+
+    validateDateTime();
+    normalize();
+}
+
+//
+//[-]{CCYY}[TimeZone]
+// 0  1234
+//
+void DateTime::parseYear()
+{
+    initParser();
+
+    // skip the first '-' and search for timezone
+    //
+    int sign = findUTCSign((fBuffer[0] == chDash) ? 1 : 0);
+
+    if (sign == NOT_FOUND)
+    {
+        fValue[CentYear] = parseIntYear(fEnd);
+    }
+    else
+    {
+        fValue[CentYear] = parseIntYear(sign);
+        getTimeZone(sign);
+    }
+
+    //initialize values
+    fValue[Month] = MONTH_DEFAULT;
+    fValue[Day]   = DAY_DEFAULT;   //java is 1
+
+    validateDateTime();
+    normalize();
+}
+
+//
+//{--MM-DD}[TimeZone]
+// 0123456
+//
+void DateTime::parseMonthDay()
+{
+    initParser();
+
+    if (fBuffer[0] != DATE_SEPARATOR ||
+        fBuffer[1] != DATE_SEPARATOR ||
+        fBuffer[4] != DATE_SEPARATOR )
+    {
+        ThrowXML1(SchemaDateTimeException
+                , XMLExcepts::DateTime_gMthDay_invalid
+                , fBuffer);
+    }
+
+
+    //initialize
+    fValue[CentYear] = YEAR_DEFAULT;
+    fValue[Month]    = parseInt(2, 4); 
+    fValue[Day]      = parseInt(5, 7);
+
+    if ( MONTHDAY_SIZE < fEnd )
+    {
+        int sign = findUTCSign(MONTHDAY_SIZE);
+        if ( sign<0 )
+        {
+            ThrowXML1(SchemaDateTimeException
+                    , XMLExcepts::DateTime_gMthDay_invalid
+                    , fBuffer);
+        }
+        else
+        {
+            getTimeZone(sign);
+        }
+    }
+
+    validateDateTime();
+    normalize();
+}
+
+void DateTime::parseYearMonth()
+{
+    initParser();
+
+    // get date
+    getYearMonth();
+    fValue[Day] = DAY_DEFAULT;
+    parseTimeZone();
+
+    validateDateTime();
+    normalize();
+}
+
+//
+//PnYn MnDTnH nMnS: -P1Y2M3DT10H30M
+//
+// [-]{'P'{[n'Y'][n'M'][n'D']['T'][n'H'][n'M'][n'S']}}
+//
+//  Note: the n above shall be >= 0
+//        if no time element found, 'T' shall be absent
+//
+void DateTime::parseDuration()
+{
+    initParser();
+
+    // must start with '-' or 'P'
+    //
+    XMLCh c = fBuffer[fStart++];
+    if ( (c != DURATION_STARTER) &&
+         (c != chDash)            )
+    {
+        ThrowXML1(SchemaDateTimeException
+                , XMLExcepts::DateTime_dur_Start_dashP
+                , fBuffer);
+    }
+
+    // 'P' must ALWAYS be present in either case
+    if ( (c == chDash) &&
+         (fBuffer[fStart++]!= DURATION_STARTER ))
+    {
+        ThrowXML1(SchemaDateTimeException
+                , XMLExcepts::DateTime_dur_noP
+                , fBuffer);
+    }
+
+    // java code
+    //date[utc]=(c=='-')?'-':0;
+    //fValue[utc] = UTC_STD;
+    fValue[utc] = (fBuffer[0] == chDash? UTC_NEG : UTC_STD);
+
+    int negate = ( fBuffer[0] == chDash ? -1 : 1);
+
+    //
+    // No negative value is allowed after 'P'
+    //
+    // eg P-1234, invalid
+    //
+    if (indexOf(fStart, fEnd, chDash) != NOT_FOUND)
+    {
+        ThrowXML1(SchemaDateTimeException
+                , XMLExcepts::DateTime_dur_DashNotFirst
+                , fBuffer);
+    }
+
+    //at least one number and designator must be seen after P
+    bool designator = false;
+
+    int endDate = indexOf(fStart, fEnd, DATETIME_SEPARATOR);
+    if ( endDate == NOT_FOUND )
+    {
+        endDate = fEnd;  // 'T' absent
+    }
+
+    //find 'Y'
+    int end = indexOf(fStart, endDate, DURATION_Y);
+    if ( end != NOT_FOUND )
+    {
+        //scan year
+        fValue[CentYear] = negate * parseInt(fStart, end);
+        fStart = end+1;
+        designator = true;
+    }
+
+    end = indexOf(fStart, endDate, DURATION_M);
+    if ( end != NOT_FOUND )
+    {
+        //scan month
+        fValue[Month] = negate * parseInt(fStart, end);
+        fStart = end+1;
+        designator = true;
+    }
+
+    end = indexOf(fStart, endDate, DURATION_D);
+    if ( end != NOT_FOUND )
+    {
+        //scan day
+        fValue[Day] = negate * parseInt(fStart,end);
+        fStart = end+1;
+        designator = true;
+    }
+
+    if ( (fEnd == endDate) &&   // 'T' absent
+         (fStart != fEnd)   )   // something after Day
+    {
+        ThrowXML1(SchemaDateTimeException
+                , XMLExcepts::DateTime_dur_inv_b4T
+                , fBuffer);
+    }
+
+    if ( fEnd != endDate ) // 'T' present
+    {
+        //scan hours, minutes, seconds
+        //
+
+        // skip 'T' first
+        end = indexOf(++fStart, fEnd, DURATION_H);
+        if ( end != NOT_FOUND )
+        {
+            //scan hours
+            fValue[Hour] = negate * parseInt(fStart, end);
+            fStart = end+1;
+            designator = true;
+        }
+
+        end = indexOf(fStart, fEnd, DURATION_M);
+        if ( end != NOT_FOUND )
+        {
+            //scan min
+            fValue[Minute] = negate * parseInt(fStart, end);
+            fStart = end+1;
+            designator = true;
+        }
+
+        end = indexOf(fStart, fEnd, DURATION_S);
+        if ( end != NOT_FOUND )
+        {
+            //scan seconds
+            int mlsec = indexOf (fStart, end, MILISECOND_SEPARATOR);
+
+            /***
+             * Schema Errata: E2-23
+             * at least one digit must follow the decimal point if it appears. 
+             * That is, the value of the seconds component must conform 
+             * to the following pattern: [0-9]+(.[0-9]+)? 
+             */
+            if ( mlsec != NOT_FOUND )
+            {
+                /***
+                 * make usure there is something after the '.' and before the end.
+                 */
+                if ( mlsec+1 == end )
+                {
+                    ThrowXML1(SchemaDateTimeException
+                            , XMLExcepts::DateTime_dur_inv_seconds
+                            , fBuffer);
+                }
+
+                fValue[Second]     = negate * parseInt(fStart, mlsec);
+                fMiliSecond        = negate * parseMiliSecond(mlsec+1, end);
+            }
+            else
+            {
+                fValue[Second] = negate * parseInt(fStart,end);
+            }
+
+            fStart = end+1;
+            designator = true;
+        }
+
+        // no additional data should appear after last item
+        // P1Y1M1DT is illigal value as well
+        if ( (fStart != fEnd) ||
+              fBuffer[--fStart] == DATETIME_SEPARATOR )
+        {
+            ThrowXML1(SchemaDateTimeException
+                    , XMLExcepts::DateTime_dur_NoTimeAfterT
+                    , fBuffer);
+        }
+    }
+
+    if ( !designator )
+    {
+        ThrowXML1(SchemaDateTimeException
+                , XMLExcepts::DateTime_dur_NoElementAtAll
+                , fBuffer);
+    }
+
+}
+
+// ---------------------------------------------------------------------------
+//  Scanners
+// ---------------------------------------------------------------------------
+
+//
+// [-]{CCYY-MM-DD}
+//
+// Note: CCYY could be more than 4 digits
+//       Assuming fStart point to the beginning of the Date Section
+//       fStart updated to point to the position right AFTER the second 'D'
+//       Since the lenght of CCYY might be variable, we can't check format upfront
+//
+void DateTime::getDate()
+{
+
+    // Ensure enough chars in buffer
+    if ( (fStart+YMD_MIN_SIZE) > fEnd)
+        ThrowXML1(SchemaDateTimeException
+                , XMLExcepts::DateTime_date_incomplete
+                , fBuffer);
+
+    getYearMonth();    // Scan YearMonth and
+                       // fStart point to the next '-'
+
+    if (fBuffer[fStart++] != DATE_SEPARATOR)
+    {
+        ThrowXML1(SchemaDateTimeException
+                , XMLExcepts::DateTime_date_invalid
+                , fBuffer);
+        //("CCYY-MM must be followed by '-' sign");
+    }
+
+    fValue[Day] = parseInt(fStart, fStart+2);
+    fStart += 2 ;  //fStart points right after the Day
+
+    return;
+}
+
+//
+// hh:mm:ss[.msssss]['Z']
+// hh:mm:ss[.msssss][['+'|'-']hh:mm]
+// 012345678
+//
+// Note: Assuming fStart point to the beginning of the Time Section
+//       fStart updated to point to the position right AFTER the second 's'
+//                                                  or ms if any
+//
+void DateTime::getTime()
+{
+
+    // Ensure enough chars in buffer
+    if ( (fStart+TIME_MIN_SIZE) > fEnd)
+        ThrowXML1(SchemaDateTimeException
+                , XMLExcepts::DateTime_time_incomplete
+                , fBuffer);
+        //"Imcomplete Time Format"
+
+    // check (fixed) format first
+    if ((fBuffer[fStart + 2] != TIME_SEPARATOR) ||
+        (fBuffer[fStart + 5] != TIME_SEPARATOR)  )
+    {
+        ThrowXML1(SchemaDateTimeException
+                , XMLExcepts::DateTime_time_invalid
+                , fBuffer);
+        //("Error in parsing time" );
+    }
+
+    //
+    // get hours, minute and second
+    //
+    fValue[Hour]   = parseInt(fStart + 0, fStart + 2);
+    fValue[Minute] = parseInt(fStart + 3, fStart + 5);
+    fValue[Second] = parseInt(fStart + 6, fStart + 8);
+    fStart += 8;
+
+    // to see if any ms and/or utc part after that
+    if (fStart >= fEnd)
+        return;
+
+    //find UTC sign if any
+    int sign = findUTCSign(fStart);
+
+    //parse miliseconds
+    int milisec = (fBuffer[fStart] == MILISECOND_SEPARATOR)? fStart : NOT_FOUND;
+    if ( milisec != NOT_FOUND )
+    {
+        fStart++;   // skip the '.'
+        // make sure we have some thing between the '.' and fEnd
+        if (fStart >= fEnd)
+        {
+            ThrowXML1(SchemaDateTimeException
+                    , XMLExcepts::DateTime_ms_noDigit
+                    , fBuffer);
+            //("ms shall be present once '.' is present" );
+        }
+
+        if ( sign == NOT_FOUND )
+        {
+            fMiliSecond = parseMiliSecond(fStart, fEnd);  //get ms between '.' and fEnd
+            fStart = fEnd;
+        }
+        else
+        {
+            fMiliSecond = parseMiliSecond(fStart, sign);  //get ms between UTC sign and fEnd
+        }
+       }
+    else if(sign == 0 || sign != fStart)
+    {
+        // seconds has more than 2 digits
+        ThrowXML1(SchemaDateTimeException
+                , XMLExcepts::DateTime_min_invalid
+                , fBuffer);
+    }
+
+    //parse UTC time zone (hh:mm)
+    if ( sign > 0 ) {
+        getTimeZone(sign);
+    }
+
+}
+
+//
+// [-]{CCYY-MM}
+//
+// Note: CCYY could be more than 4 digits
+//       fStart updated to point AFTER the second 'M' (probably meet the fEnd)
+//
+void DateTime::getYearMonth()
+{
+
+    // Ensure enough chars in buffer
+    if ( (fStart+YMONTH_MIN_SIZE) > fEnd)
+        ThrowXML1(SchemaDateTimeException
+                , XMLExcepts::DateTime_ym_incomplete
+                , fBuffer);
+        //"Imcomplete YearMonth Format";
+
+    // skip the first leading '-'
+    int start = ( fBuffer[0] == chDash ) ? fStart + 1 : fStart;
+
+    //
+    // search for year separator '-'
+    //
+    int yearSeparator = indexOf(start, fEnd, DATE_SEPARATOR);
+    if ( yearSeparator == NOT_FOUND)
+        ThrowXML1(SchemaDateTimeException
+                , XMLExcepts::DateTime_ym_invalid
+                , fBuffer);
+        //("Year separator is missing or misplaced");
+
+    fValue[CentYear] = parseIntYear(yearSeparator);
+    fStart = yearSeparator + 1;  //skip the '-' and point to the first M
+
+    //
+    //gonna check we have enough byte for month
+    //
+    if ((fStart + 2) > fEnd )
+        ThrowXML1(SchemaDateTimeException
+                , XMLExcepts::DateTime_ym_noMonth
+                , fBuffer);
+        //"no month in buffer"
+
+    fValue[Month] = parseInt(fStart, yearSeparator + 3);
+    fStart += 2;  //fStart points right after the MONTH
+
+    return;
+}
+
+void DateTime::parseTimeZone()
+{
+    if ( fStart < fEnd )
+    {
+        int sign = findUTCSign(fStart);
+        if ( sign < 0 )
+        {
+            ThrowXML1(SchemaDateTimeException
+                    , XMLExcepts::DateTime_tz_noUTCsign
+                    , fBuffer);
+            //("Error in month parsing");
+        }
+        else
+        {
+            getTimeZone(sign);
+        }
+    }
+
+    return;
+}
+
+//
+// 'Z'
+// ['+'|'-']hh:mm
+//
+// Note: Assuming fStart points to the beginning of TimeZone section
+//       fStart updated to meet fEnd
+//
+void DateTime::getTimeZone(const int sign)
+{
+
+    if ( fBuffer[sign] == UTC_STD_CHAR )
+    {
+        if ((sign + 1) != fEnd )
+        {
+            ThrowXML1(SchemaDateTimeException
+                    , XMLExcepts::DateTime_tz_stuffAfterZ
+                    , fBuffer);
+            //"Error in parsing time zone");
+        }              
+
+        return;        
+    }
+
+    //
+    // otherwise, it has to be this format
+    // '[+|-]'hh:mm
+    //    1   23456 7
+    //   sign      fEnd
+    //
+    if ( ( ( sign + TIMEZONE_SIZE + 1) != fEnd )      ||
+         ( fBuffer[sign + 3] != TIMEZONE_SEPARATOR ) )
+    {
+        ThrowXML1(SchemaDateTimeException
+                , XMLExcepts::DateTime_tz_invalid
+                , fBuffer);
+        //("Error in parsing time zone");
+    }
+
+    fTimeZone[hh] = parseInt(sign+1, sign+3);          
+    fTimeZone[mm] = parseInt(sign+4, fEnd);
+                       
+    return;
+}
+
+// ---------------------------------------------------------------------------
+//  Validator and normalizer
+// ---------------------------------------------------------------------------
+
+/**
+ * If timezone present - normalize dateTime  [E Adding durations to dateTimes]
+ *
+ * @param date   CCYY-MM-DDThh:mm:ss+03
+ * @return CCYY-MM-DDThh:mm:ssZ
+ */
+void DateTime::normalize()
+{
+
+    if ((fValue[utc] == UTC_UNKNOWN) ||
+        (fValue[utc] == UTC_STD)      )
+        return;
+
+    int negate = (fValue[utc] == UTC_POS)? -1: 1;
+
+    // add mins
+    int temp = fValue[Minute] + negate * fTimeZone[mm];
+    int carry = fQuotient(temp, 60);
+    fValue[Minute] = mod(temp, 60, carry);
+
+    //add hours
+    temp = fValue[Hour] + negate * fTimeZone[hh] + carry;
+    carry = fQuotient(temp, 24);
+    fValue[Hour] = mod(temp, 24, carry);
+
+    fValue[Day] += carry;
+
+    while (1)
+    {
+        temp = maxDayInMonthFor(fValue[CentYear], fValue[Month]);
+        if (fValue[Day] < 1)
+        {
+            fValue[Day] += maxDayInMonthFor(fValue[CentYear], fValue[Month] - 1);
+            carry = -1;
+        }
+        else if ( fValue[Day] > temp )
+        {
+            fValue[Day] -= temp;
+            carry = 1;
+        }
+        else
+        {
+            break;
+        }
+
+        temp = fValue[Month] + carry;
+        fValue[Month] = modulo(temp, 1, 13);
+        fValue[CentYear] += fQuotient(temp, 1, 13);
+    }
+
+    // set to normalized
+    fValue[utc] = UTC_STD;
+
+    return;
+}
+
+void DateTime::validateDateTime() const
+{
+
+    //REVISIT: should we throw an exception for not valid dates
+    //          or reporting an error message should be sufficient?
+    if ( fValue[CentYear] == 0 )
+    {
+        ThrowXML1(SchemaDateTimeException
+                , XMLExcepts::DateTime_year_zero
+                , fBuffer);
+        //"The year \"0000\" is an illegal year value");
+    }
+
+    if ( fValue[Month] < 1  ||
+         fValue[Month] > 12  )
+    {
+        ThrowXML1(SchemaDateTimeException
+                , XMLExcepts::DateTime_mth_invalid
+                , fBuffer);
+               //"The month must have values 1 to 12");
+    }
+
+    //validate days
+    if ( fValue[Day] > maxDayInMonthFor( fValue[CentYear], fValue[Month]) ||
+         fValue[Day] == 0 )
+    {
+        ThrowXML1(SchemaDateTimeException
+                , XMLExcepts::DateTime_day_invalid
+                , fBuffer);
+        //"The day must have values 1 to 31");
+    }
+
+    //validate hours
+    if ((fValue[Hour] < 0)  ||
+        (fValue[Hour] > 24) ||
+        ((fValue[Hour] == 24) && ((fValue[Minute] !=0) ||
+                                  (fValue[Second] !=0) ||
+                                  (fMiliSecond    !=0))))
+    {
+        ThrowXML1(SchemaDateTimeException
+                , XMLExcepts::DateTime_hour_invalid
+                , fBuffer);
+        //("Hour must have values 0-23");
+    }
+
+    //validate minutes
+    if ( fValue[Minute] < 0 ||
+         fValue[Minute] > 59 )
+    {
+        ThrowXML1(SchemaDateTimeException
+                , XMLExcepts::DateTime_min_invalid
+                , fBuffer);
+        //"Minute must have values 0-59");
+    }
+
+    //validate seconds
+    if ( fValue[Second] < 0 ||
+         fValue[Second] > 60 )
+    {
+        ThrowXML1(SchemaDateTimeException
+                , XMLExcepts::DateTime_second_invalid
+                , fBuffer);
+        //"Second must have values 0-60");
+    }
+
+    //validate time-zone hours
+    if ( (abs(fTimeZone[hh]) > 14) ||
+         ((abs(fTimeZone[hh]) == 14) && (fTimeZone[mm] != 0)) )
+    {
+        ThrowXML1(SchemaDateTimeException
+                , XMLExcepts::DateTime_tz_hh_invalid
+                , fBuffer);
+        //"Time zone should have range -14..+14");
+    }
+
+    //validate time-zone minutes
+    if ( abs(fTimeZone[mm]) > 59 )
+    {
+        ThrowXML1(SchemaDateTimeException
+                , XMLExcepts::DateTime_min_invalid
+                , fBuffer);
+        //("Minute must have values 0-59");
+    }
+       
+    return;
+}
+
+// -----------------------------------------------------------------------
+// locator and converter
+// -----------------------------------------------------------------------
+int DateTime::indexOf(const int start, const int end, const XMLCh ch) const
+{
+    for ( int i = start; i < end; i++ )
+        if ( fBuffer[i] == ch )
+            return i;
+
+    return NOT_FOUND;
+}
+
+int DateTime::findUTCSign (const int start)
+{
+    int  pos;
+    for ( int index = start; index < fEnd; index++ )
+    {
+        pos = XMLString::indexOf(UTC_SET, fBuffer[index]);
+        if ( pos != NOT_FOUND)
+        {
+            fValue[utc] = pos+1;   // refer to utcType, there is 1 diff
+            return index;
+        }
+    }
+
+    return NOT_FOUND;
+}
+
+//
+// Note:
+//    start: starting point in fBuffer
+//    end:   ending point in fBuffer (exclusive)
+//    fStart NOT updated
+//
+int DateTime::parseInt(const int start, const int end) const
+{
+    unsigned int retVal = 0;
+    for (int i=start; i < end; i++) {
+
+        if (fBuffer[i] < chDigit_0 || fBuffer[i] > chDigit_9)
+            ThrowXML(NumberFormatException, XMLExcepts::XMLNUM_Inv_chars);
+
+        retVal = (retVal * 10) + (unsigned int) (fBuffer[i] - chDigit_0);
+    }
+
+    return (int) retVal;
+}
+
+//
+// Note:
+//    start: pointing to the first digit after the '.'
+//    end:   pointing to one position after the last digit
+//    fStart NOT updated
+//
+double DateTime::parseMiliSecond(const int start, const int end) const
+{
+
+    unsigned int  miliSecLen = (end-1) - (start-1) + 1; //to include the '.'
+    XMLCh* miliSecData = new XMLCh[miliSecLen + 1];
+    ArrayJanitor<XMLCh> janMili(miliSecData);
+    XMLString::copyNString(miliSecData, &(fBuffer[start-1]), miliSecLen);
+    *(miliSecData + miliSecLen) = chNull;
+
+    char *nptr = XMLString::transcode(miliSecData);
+    ArrayJanitor<char> jan(nptr);
+    size_t   strLen = strlen(nptr);
+    char *endptr = 0;
+    errno = 0;
+
+    //printf("milisec=<%s>\n", nptr);
+
+    double retVal = strtod(nptr, &endptr);
+
+    // check if all chars are valid char
+    if ( (endptr - nptr) != strLen)
+        ThrowXML(NumberFormatException, XMLExcepts::XMLNUM_Inv_chars);
+
+    // we don't check underflow occurs since
+    // nothing we can do about it.
+    return retVal;
+}
+
+//
+// [-]CCYY
+//
+// Note: start from fStart
+//       end (exclusive)
+//       fStart NOT updated
+//
+int DateTime::parseIntYear(const int end) const
+{
+    // skip the first leading '-'
+    int start = ( fBuffer[0] == chDash ) ? fStart + 1 : fStart;
+
+    int length = end - start;
+    if (length < 4)
+    {
+        ThrowXML1(SchemaDateTimeException
+                , XMLExcepts::DateTime_year_tooShort
+                , fBuffer);
+        //"Year must have 'CCYY' format");
+    }
+    else if (length > 4 &&
+             fBuffer[start] == chDigit_0)
+    {
+        ThrowXML1(SchemaDateTimeException
+                , XMLExcepts::DateTime_year_leadingZero
+                , fBuffer);
+        //"Leading zeros are required if the year value would otherwise have fewer than four digits;
+        // otherwise they are forbidden");
+    }
+
+    bool negative = (fBuffer[0] == chDash);
+    int  yearVal = parseInt((negative ? 1 : 0), end);
+    return ( negative ? (-1) * yearVal : yearVal );
+}
+
+/***
+ * E2-41
+ *
+ *  3.2.7.2 Canonical representation
+ * 
+ *  Except for trailing fractional zero digits in the seconds representation, 
+ *  '24:00:00' time representations, and timezone (for timezoned values), 
+ *  the mapping from literals to values is one-to-one. Where there is more 
+ *  than one possible representation, the canonical representation is as follows: 
+ *  redundant trailing zero digits in fractional-second literals are prohibited. 
+ *  An hour representation of '24' is prohibited. Timezoned values are canonically
+ *  represented by appending 'Z' to the nontimezoned representation. (All 
+ *  timezoned dateTime values are UTC.) 
+ *
+ *  .'24:00:00' -> '00:00:00'
+ *  .milisecond: trailing zeros removed
+ *  .'Z'
+ *
+ ***/
+XMLCh* DateTime::getDateTimeCanonicalRepresentation() const
+{
+    XMLCh *miliStartPtr, *miliEndPtr;
+    searchMiliSeconds(miliStartPtr, miliEndPtr);
+    size_t miliSecondsLen = miliEndPtr - miliStartPtr;
+
+    XMLCh* retBuf = new XMLCh[21 + miliSecondsLen + 2];
+    XMLCh* retPtr = retBuf;
+
+    // (-?) cc+yy-mm-dd'T'hh:mm:ss'Z'    ('.'s+)?
+    //      2+  8       1      8   1
+    //
+    int additionalLen = fillYearString(retPtr, CentYear);
+    if(additionalLen != 0)
+    {
+        // very bad luck; have to resize the buffer...
+        XMLCh *tmpBuf = new XMLCh[additionalLen+21+miliSecondsLen +2];
+        XMLString::moveChars(tmpBuf, retBuf, 4+additionalLen);
+        retPtr = tmpBuf+(retPtr-retBuf);
+        delete[] retBuf;
+        retBuf = tmpBuf;
+    }
+    *retPtr++ = DATE_SEPARATOR;
+    fillString(retPtr, Month, 2);
+    *retPtr++ = DATE_SEPARATOR;
+    fillString(retPtr, Day, 2);
+    *retPtr++ = DATETIME_SEPARATOR;
+
+    fillString(retPtr, Hour, 2);
+    if (fValue[Hour] == 24)
+    {
+        *(retPtr - 2) = chDigit_0;
+        *(retPtr - 1) = chDigit_0;
+    }
+    *retPtr++ = TIME_SEPARATOR;
+    fillString(retPtr, Minute, 2);
+    *retPtr++ = TIME_SEPARATOR;
+    fillString(retPtr, Second, 2);
+
+    if (miliSecondsLen)
+    {
+        *retPtr++ = chPeriod;
+        XMLString::copyNString(retPtr, miliStartPtr, miliSecondsLen);
+        retPtr += miliSecondsLen;
+    }
+
+    *retPtr++ = UTC_STD_CHAR;
+    *retPtr = chNull;
+
+    return retBuf;
+}
+
+/***
+ * 3.2.8 time
+ *
+ *  . either the time zone must be omitted or, 
+ *    if present, the time zone must be Coordinated Universal Time (UTC) indicated by a "Z".   
+ *
+ *  . Additionally, the canonical representation for midnight is 00:00:00.
+ *
+***/
+XMLCh* DateTime::getTimeCanonicalRepresentation() const
+{
+    XMLCh *miliStartPtr, *miliEndPtr;
+    searchMiliSeconds(miliStartPtr, miliEndPtr);
+    size_t miliSecondsLen = miliEndPtr - miliStartPtr;
+
+    XMLCh* retBuf = new XMLCh[10 + miliSecondsLen + 2];
+    XMLCh* retPtr = retBuf;
+
+    // 'hh:mm:ss'Z'    ('.'s+)?
+    //      8    1
+    //
+
+    fillString(retPtr, Hour, 2);
+    if (fValue[Hour] == 24)
+    {
+        *(retPtr - 2) = chDigit_0;
+        *(retPtr - 1) = chDigit_0;
+    }
+    *retPtr++ = TIME_SEPARATOR;
+    fillString(retPtr, Minute, 2);
+    *retPtr++ = TIME_SEPARATOR;
+    fillString(retPtr, Second, 2);
+
+    if (miliSecondsLen)
+    {
+        *retPtr++ = chPeriod;
+        XMLString::copyNString(retPtr, miliStartPtr, miliSecondsLen);
+        retPtr += miliSecondsLen;
+    }
+
+    *retPtr++ = UTC_STD_CHAR;
+    *retPtr = chNull;
+
+    return retBuf;
+}
+
+void DateTime::fillString(XMLCh*& ptr, valueIndex ind, int expLen) const
+{
+    XMLCh strBuffer[16];
+    assert(expLen < 16);
+    XMLString::binToText(fValue[ind], strBuffer, expLen, 10);
+    int   actualLen = XMLString::stringLen(strBuffer);
+    int   i;
+    //append leading zeros
+    for (i = 0; i < expLen - actualLen; i++)
+    {
+        *ptr++ = chDigit_0;
+    }
+
+    for (i = 0; i < actualLen; i++)
+    {
+        *ptr++ = strBuffer[i];
+    }
+
+}
+
+int DateTime::fillYearString(XMLCh*& ptr, valueIndex ind) const
+{
+    XMLCh strBuffer[16];
+    // let's hope we get no years of 15 digits...
+    XMLString::binToText(fValue[ind], strBuffer, 15, 10);
+    int   actualLen = XMLString::stringLen(strBuffer);
+    // don't forget that years can be negative...
+    int negativeYear = 0;
+    if(strBuffer[0] == chDash)
+    {
+        *ptr++ = strBuffer[0];
+        negativeYear = 1;
+    }
+    int   i;
+    //append leading zeros
+    for (i = 0; i < 4 - actualLen+negativeYear; i++)
+    {
+        *ptr++ = chDigit_0;
+    }
+
+    for (i = negativeYear; i < actualLen; i++)
+    {
+        *ptr++ = strBuffer[i];
+    }
+    if(actualLen > 4)
+        return actualLen-4;
+    return 0;
+}
+
+/***
+ *
+ *   .check if the rawData has the mili second component
+ *   .capture the substring
+ *
+ ***/
+void DateTime::searchMiliSeconds(XMLCh*& miliStartPtr, XMLCh*& miliEndPtr) const
+{
+    miliStartPtr = miliEndPtr = 0;
+
+    int milisec = XMLString::indexOf(fBuffer, MILISECOND_SEPARATOR);
+    if (milisec == -1)
+        return;
+
+    miliStartPtr = fBuffer + milisec + 1;
+    miliEndPtr   = miliStartPtr;
+    while (*miliEndPtr)
+    {
+        if ((*miliEndPtr < chDigit_0) || (*miliEndPtr > chDigit_9))
+            break;
+
+        miliEndPtr++;
+    }
+
+    //remove trailing zeros
+    while( *(miliEndPtr - 1) == chDigit_0)
+        miliEndPtr--;
+
+    return;
+}
+
index aceaf22..44ce374 100644 (file)
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file DateTime.h\r
- * \r
- * Manipulation of XML date/time data. \r
- */\r
-\r
-#ifndef _XML_DATETIME_H\r
-#define _XML_DATETIME_H\r
-\r
-#include <xmltooling/base.h>\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( push )\r
-    #pragma warning( disable : 4244 )\r
-#endif\r
-\r
-#include <xercesc/util/XMLDateTime.hpp>\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( pop )\r
-#endif\r
-\r
-namespace xmltooling\r
-{\r
-    /**\r
-     * Class for manipulating XML date/time information.\r
-     * \r
-     * This is mostly copied from Xerces-C, but they haven't produced a usable date/time\r
-     * class, so we had to incorporate a version of it for now. It can't be inherited\r
-     * since the fields needed are private.\r
-     */\r
-    class XMLTOOL_API DateTime\r
-    {\r
-    public:\r
-        /// @cond OFF\r
-        DateTime();\r
-        DateTime(const XMLCh* const);\r
-        DateTime(time_t epoch);\r
-        DateTime(const DateTime&);\r
-        DateTime& operator=(const DateTime&);\r
-        ~DateTime();\r
-    \r
-        inline void setBuffer(const XMLCh* const);\r
-    \r
-        const XMLCh* getRawData() const;\r
-        const XMLCh* getFormattedString() const;\r
-        int getSign() const;\r
-    \r
-        XMLCh* getDateTimeCanonicalRepresentation() const;\r
-        XMLCh* getTimeCanonicalRepresentation() const;\r
-    \r
-        void parseDateTime();\r
-        void parseDate();\r
-        void parseTime();\r
-        void parseDay();\r
-        void parseMonth();\r
-        void parseYear();\r
-        void parseMonthDay();\r
-        void parseYearMonth();\r
-        void parseDuration();\r
-    \r
-        static int compare(const DateTime* const, const DateTime* const);\r
-        static int compare(const DateTime* const, const DateTime* const, bool);\r
-        static int compareOrder(const DateTime* const, const DateTime* const);                                    \r
-    \r
-        int getYear() const {return fValue[CentYear];}\r
-        int getMonth() const {return fValue[Month];}\r
-        int getDay() const {return fValue[Day];}\r
-        int getHour() const {return fValue[Hour];}\r
-        int getMinute() const {return fValue[Minute];}\r
-        int getSecond() const {return fValue[Second];}\r
-        time_t getEpoch() const;\r
-    \r
-        /// @endcond\r
-    private:\r
-        enum valueIndex {\r
-            CentYear   = 0,\r
-            Month      ,\r
-            Day        ,\r
-            Hour       ,\r
-            Minute     ,\r
-            Second     ,\r
-            MiliSecond ,  //not to be used directly\r
-            utc        ,\r
-            TOTAL_SIZE\r
-        };\r
-    \r
-        enum utcType {\r
-            UTC_UNKNOWN = 0,\r
-            UTC_STD        ,          // set in parse() or normalize()\r
-            UTC_POS        ,          // set in parse()\r
-            UTC_NEG                   // set in parse()\r
-        };\r
-    \r
-        enum timezoneIndex {\r
-            hh = 0,\r
-            mm ,\r
-            TIMEZONE_ARRAYSIZE\r
-        };\r
-    \r
-        static int compareResult(int, int, bool);\r
-        static void addDuration(DateTime* pDuration, const DateTime* const pBaseDate, int index);\r
-        static int compareResult(const DateTime* const, const DateTime* const, bool, int);\r
-        static inline int getRetVal(int, int);\r
-    \r
-        inline void reset();\r
-        //inline void assertBuffer() const;\r
-        inline void copy(const DateTime&);\r
-        \r
-        inline void initParser();\r
-        inline bool isNormalized() const;\r
-    \r
-        void getDate();\r
-        void getTime();\r
-        void getYearMonth();\r
-        void getTimeZone(const int);\r
-        void parseTimeZone();\r
-    \r
-        int findUTCSign(const int start);\r
-        int indexOf(const int start, const int end, const XMLCh ch) const;\r
-        int parseInt(const int start, const int end) const;\r
-        int parseIntYear(const int end) const;\r
-        double parseMiliSecond(const int start, const int end) const;\r
-    \r
-        void validateDateTime() const;\r
-        void normalize();\r
-        void fillString(XMLCh*& ptr, valueIndex ind, int expLen) const;\r
-        int  fillYearString(XMLCh*& ptr, valueIndex ind) const;\r
-        void searchMiliSeconds(XMLCh*& miliStartPtr, XMLCh*& miliEndPtr) const;\r
-    \r
-       bool operator==(const DateTime& toCompare) const;\r
-    \r
-        static const int DATETIMES[][TOTAL_SIZE];\r
-        int fValue[TOTAL_SIZE];\r
-        int fTimeZone[TIMEZONE_ARRAYSIZE];\r
-        int fStart;\r
-        int fEnd;\r
-        int fBufferMaxLen;\r
-        XMLCh* fBuffer;\r
-    \r
-        double fMiliSecond;\r
-        bool fHasTime;\r
-    };\r
-\r
-    inline void DateTime::setBuffer(const XMLCh* const aString)\r
-    {\r
-        reset();\r
-        fEnd = XMLString::stringLen(aString);\r
-        if (fEnd > 0) {\r
-            if (fEnd > fBufferMaxLen) {\r
-                delete[] fBuffer;\r
-                fBufferMaxLen = fEnd + 8;\r
-                fBuffer = new XMLCh[fBufferMaxLen+1];\r
-            }\r
-            memcpy(fBuffer, aString, (fEnd+1) * sizeof(XMLCh));\r
-        }\r
-    }\r
-    \r
-    inline void DateTime::reset()\r
-    {\r
-        for ( int i=0; i < XMLDateTime::TOTAL_SIZE; i++ )\r
-            fValue[i] = 0;\r
-    \r
-        fMiliSecond   = 0;\r
-        fHasTime      = false;\r
-        fTimeZone[hh] = fTimeZone[mm] = 0;\r
-        fStart = fEnd = 0;\r
-    \r
-        if (fBuffer)\r
-            *fBuffer = 0;\r
-    }\r
-    \r
-    inline void DateTime::copy(const DateTime& rhs)\r
-    {\r
-        for ( int i = 0; i < XMLDateTime::TOTAL_SIZE; i++ )\r
-            fValue[i] = rhs.fValue[i];\r
-    \r
-        fMiliSecond   = rhs.fMiliSecond;\r
-        fHasTime      = rhs.fHasTime;\r
-        fTimeZone[hh] = rhs.fTimeZone[hh];\r
-        fTimeZone[mm] = rhs.fTimeZone[mm];\r
-        fStart = rhs.fStart;\r
-        fEnd   = rhs.fEnd;\r
-    \r
-        if (fEnd > 0) {\r
-            if (fEnd > fBufferMaxLen) {\r
-                delete[] fBuffer;\r
-                fBufferMaxLen = rhs.fBufferMaxLen;\r
-                fBuffer = new XMLCh[fBufferMaxLen+1];\r
-            }\r
-            memcpy(fBuffer, rhs.fBuffer, (fEnd+1) * sizeof(XMLCh));\r
-        }\r
-    }\r
-    \r
-    inline void DateTime::initParser()\r
-    {\r
-        fStart = 0;   // to ensure scan from the very first beginning\r
-                      // in case the pointer is updated accidentally by someone else.\r
-    }\r
-    \r
-    inline bool DateTime::isNormalized() const\r
-    {\r
-        return (fValue[XMLDateTime::utc] == XMLDateTime::UTC_STD ? true : false);\r
-    }\r
-    \r
-    inline int DateTime::getRetVal(int c1, int c2)\r
-    {\r
-        if ((c1 == XMLDateTime::LESS_THAN && c2 == XMLDateTime::GREATER_THAN) ||\r
-            (c1 == XMLDateTime::GREATER_THAN && c2 == XMLDateTime::LESS_THAN))\r
-            return XMLDateTime::INDETERMINATE;\r
-    \r
-        return (c1 != XMLDateTime::INDETERMINATE) ? c1 : c2;\r
-    }\r
-\r
-}\r
-\r
-#endif\r
+/*
+ *  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.
+ */
+
+/**
+ * @file DateTime.h
+ * 
+ * Manipulation of XML date/time data. 
+ */
+
+#ifndef _XML_DATETIME_H
+#define _XML_DATETIME_H
+
+#include <xmltooling/base.h>
+
+#if defined (_MSC_VER)
+    #pragma warning( push )
+    #pragma warning( disable : 4244 )
+#endif
+
+#include <xercesc/util/XMLDateTime.hpp>
+
+#if defined (_MSC_VER)
+    #pragma warning( pop )
+#endif
+
+namespace xmltooling
+{
+    /**
+     * Class for manipulating XML date/time information.
+     * 
+     * This is mostly copied from Xerces-C, but they haven't produced a usable date/time
+     * class, so we had to incorporate a version of it for now. It can't be inherited
+     * since the fields needed are private.
+     */
+    class XMLTOOL_API DateTime
+    {
+    public:
+        /// @cond OFF
+        DateTime();
+        DateTime(const XMLCh* const);
+        DateTime(time_t epoch);
+        DateTime(const DateTime&);
+        DateTime& operator=(const DateTime&);
+        ~DateTime();
+    
+        inline void setBuffer(const XMLCh* const);
+    
+        const XMLCh* getRawData() const;
+        const XMLCh* getFormattedString() const;
+        int getSign() const;
+    
+        XMLCh* getDateTimeCanonicalRepresentation() const;
+        XMLCh* getTimeCanonicalRepresentation() const;
+    
+        void parseDateTime();
+        void parseDate();
+        void parseTime();
+        void parseDay();
+        void parseMonth();
+        void parseYear();
+        void parseMonthDay();
+        void parseYearMonth();
+        void parseDuration();
+    
+        static int compare(const DateTime* const, const DateTime* const);
+        static int compare(const DateTime* const, const DateTime* const, bool);
+        static int compareOrder(const DateTime* const, const DateTime* const);                                    
+    
+        int getYear() const {return fValue[CentYear];}
+        int getMonth() const {return fValue[Month];}
+        int getDay() const {return fValue[Day];}
+        int getHour() const {return fValue[Hour];}
+        int getMinute() const {return fValue[Minute];}
+        int getSecond() const {return fValue[Second];}
+        time_t getEpoch() const;
+    
+        /// @endcond
+    private:
+        enum valueIndex {
+            CentYear   = 0,
+            Month      ,
+            Day        ,
+            Hour       ,
+            Minute     ,
+            Second     ,
+            MiliSecond ,  //not to be used directly
+            utc        ,
+            TOTAL_SIZE
+        };
+    
+        enum utcType {
+            UTC_UNKNOWN = 0,
+            UTC_STD        ,          // set in parse() or normalize()
+            UTC_POS        ,          // set in parse()
+            UTC_NEG                   // set in parse()
+        };
+    
+        enum timezoneIndex {
+            hh = 0,
+            mm ,
+            TIMEZONE_ARRAYSIZE
+        };
+    
+        static int compareResult(int, int, bool);
+        static void addDuration(DateTime* pDuration, const DateTime* const pBaseDate, int index);
+        static int compareResult(const DateTime* const, const DateTime* const, bool, int);
+        static inline int getRetVal(int, int);
+    
+        inline void reset();
+        //inline void assertBuffer() const;
+        inline void copy(const DateTime&);
+        
+        inline void initParser();
+        inline bool isNormalized() const;
+    
+        void getDate();
+        void getTime();
+        void getYearMonth();
+        void getTimeZone(const int);
+        void parseTimeZone();
+    
+        int findUTCSign(const int start);
+        int indexOf(const int start, const int end, const XMLCh ch) const;
+        int parseInt(const int start, const int end) const;
+        int parseIntYear(const int end) const;
+        double parseMiliSecond(const int start, const int end) const;
+    
+        void validateDateTime() const;
+        void normalize();
+        void fillString(XMLCh*& ptr, valueIndex ind, int expLen) const;
+        int  fillYearString(XMLCh*& ptr, valueIndex ind) const;
+        void searchMiliSeconds(XMLCh*& miliStartPtr, XMLCh*& miliEndPtr) const;
+    
+       bool operator==(const DateTime& toCompare) const;
+    
+        static const int DATETIMES[][TOTAL_SIZE];
+        int fValue[TOTAL_SIZE];
+        int fTimeZone[TIMEZONE_ARRAYSIZE];
+        int fStart;
+        int fEnd;
+        int fBufferMaxLen;
+        XMLCh* fBuffer;
+    
+        double fMiliSecond;
+        bool fHasTime;
+    };
+
+    inline void DateTime::setBuffer(const XMLCh* const aString)
+    {
+        reset();
+        fEnd = XMLString::stringLen(aString);
+        if (fEnd > 0) {
+            if (fEnd > fBufferMaxLen) {
+                delete[] fBuffer;
+                fBufferMaxLen = fEnd + 8;
+                fBuffer = new XMLCh[fBufferMaxLen+1];
+            }
+            memcpy(fBuffer, aString, (fEnd+1) * sizeof(XMLCh));
+        }
+    }
+    
+    inline void DateTime::reset()
+    {
+        for ( int i=0; i < XMLDateTime::TOTAL_SIZE; i++ )
+            fValue[i] = 0;
+    
+        fMiliSecond   = 0;
+        fHasTime      = false;
+        fTimeZone[hh] = fTimeZone[mm] = 0;
+        fStart = fEnd = 0;
+    
+        if (fBuffer)
+            *fBuffer = 0;
+    }
+    
+    inline void DateTime::copy(const DateTime& rhs)
+    {
+        for ( int i = 0; i < XMLDateTime::TOTAL_SIZE; i++ )
+            fValue[i] = rhs.fValue[i];
+    
+        fMiliSecond   = rhs.fMiliSecond;
+        fHasTime      = rhs.fHasTime;
+        fTimeZone[hh] = rhs.fTimeZone[hh];
+        fTimeZone[mm] = rhs.fTimeZone[mm];
+        fStart = rhs.fStart;
+        fEnd   = rhs.fEnd;
+    
+        if (fEnd > 0) {
+            if (fEnd > fBufferMaxLen) {
+                delete[] fBuffer;
+                fBufferMaxLen = rhs.fBufferMaxLen;
+                fBuffer = new XMLCh[fBufferMaxLen+1];
+            }
+            memcpy(fBuffer, rhs.fBuffer, (fEnd+1) * sizeof(XMLCh));
+        }
+    }
+    
+    inline void DateTime::initParser()
+    {
+        fStart = 0;   // to ensure scan from the very first beginning
+                      // in case the pointer is updated accidentally by someone else.
+    }
+    
+    inline bool DateTime::isNormalized() const
+    {
+        return (fValue[XMLDateTime::utc] == XMLDateTime::UTC_STD ? true : false);
+    }
+    
+    inline int DateTime::getRetVal(int c1, int c2)
+    {
+        if ((c1 == XMLDateTime::LESS_THAN && c2 == XMLDateTime::GREATER_THAN) ||
+            (c1 == XMLDateTime::GREATER_THAN && c2 == XMLDateTime::LESS_THAN))
+            return XMLDateTime::INDETERMINATE;
+    
+        return (c1 != XMLDateTime::INDETERMINATE) ? c1 : c2;
+    }
+
+}
+
+#endif
index 966fb30..2867a4c 100644 (file)
@@ -1,43 +1,43 @@
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * NDC.cpp\r
- * \r
- * Diagnostic context for logging \r
- */\r
-\r
-#include "internal.h"\r
-#include "util/NDC.h"\r
-\r
-#include <log4cpp/NDC.hh>\r
-\r
-using namespace xmltooling;\r
-\r
-NDC::NDC(const char* context)\r
-{\r
-    log4cpp::NDC::push(context);\r
-}\r
-\r
-NDC::NDC(const std::string& context)\r
-{\r
-    log4cpp::NDC::push(context);\r
-}\r
-\r
-NDC::~NDC()\r
-{\r
-    log4cpp::NDC::pop();\r
-}\r
+/*
+ *  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.
+ */
+
+/**
+ * NDC.cpp
+ * 
+ * Diagnostic context for logging 
+ */
+
+#include "internal.h"
+#include "util/NDC.h"
+
+#include <log4cpp/NDC.hh>
+
+using namespace xmltooling;
+
+NDC::NDC(const char* context)
+{
+    log4cpp::NDC::push(context);
+}
+
+NDC::NDC(const std::string& context)
+{
+    log4cpp::NDC::push(context);
+}
+
+NDC::~NDC()
+{
+    log4cpp::NDC::pop();
+}
index 9d5714c..eb5de13 100644 (file)
@@ -1,59 +1,59 @@
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file NDC.h\r
- * \r
- * Diagnostic context for logging \r
- */\r
-\r
-#if !defined(__xmltooling_ndc_h__)\r
-#define __xmltooling_ndc_h__\r
-\r
-#include <string>\r
-#include <xmltooling/base.h>\r
-\r
-namespace xmltooling {\r
-    \r
-    /**\r
-     * A portable stack-based context for diagnostic logging \r
-     */\r
-    class XMLTOOL_API NDC\r
-    {\r
-    public:\r
-        /**\r
-         * Constructor pushes logging context onto diagnostic stack\r
-         * @param context   null-terminated label for context\r
-         */\r
-        NDC(const char* context);\r
-\r
-        /**\r
-         * Constructor pushes logging context onto diagnostic stack\r
-         * @param context   string label for context\r
-         */\r
-        NDC(const std::string& context);\r
-        \r
-        /**\r
-         * Destructor pops context off of diagnostic stack\r
-         */\r
-        ~NDC();\r
-        \r
-    MAKE_NONCOPYABLE(NDC);\r
-    };\r
-\r
-};\r
-\r
-#endif /* __xmltooling_ndc_h__ */\r
+/*
+ *  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.
+ */
+
+/**
+ * @file NDC.h
+ * 
+ * Diagnostic context for logging 
+ */
+
+#if !defined(__xmltooling_ndc_h__)
+#define __xmltooling_ndc_h__
+
+#include <string>
+#include <xmltooling/base.h>
+
+namespace xmltooling {
+    
+    /**
+     * A portable stack-based context for diagnostic logging 
+     */
+    class XMLTOOL_API NDC
+    {
+    public:
+        /**
+         * Constructor pushes logging context onto diagnostic stack
+         * @param context   null-terminated label for context
+         */
+        NDC(const char* context);
+
+        /**
+         * Constructor pushes logging context onto diagnostic stack
+         * @param context   string label for context
+         */
+        NDC(const std::string& context);
+        
+        /**
+         * Destructor pops context off of diagnostic stack
+         */
+        ~NDC();
+        
+    MAKE_NONCOPYABLE(NDC);
+    };
+
+};
+
+#endif /* __xmltooling_ndc_h__ */
index 64910df..f4f9a8f 100644 (file)
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file ParserPool.h\r
- * \r
- * XML parsing\r
- */\r
-\r
-#if !defined(__xmltooling_pool_h__)\r
-#define __xmltooling_pool_h__\r
-\r
-#include <xmltooling/unicode.h>\r
-#include <xmltooling/util/Threads.h>\r
-\r
-#include <map>\r
-#include <stack>\r
-#include <istream>\r
-#include <xercesc/dom/DOM.hpp>\r
-#include <xercesc/sax/InputSource.hpp>\r
-#include <xercesc/util/BinInputStream.hpp>\r
-\r
-using namespace xercesc;\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( push )\r
-    #pragma warning( disable : 4250 4251 )\r
-#endif\r
-\r
-namespace xmltooling {\r
-\r
-    /**\r
-     * A thread-safe pool of DOMBuilders that share characteristics\r
-     */\r
-    class XMLTOOL_API ParserPool : public DOMEntityResolver, DOMErrorHandler\r
-    {\r
-        MAKE_NONCOPYABLE(ParserPool);\r
-    public:\r
-        /**\r
-         * Constructs a new pool\r
-         * \r
-         * @param namespaceAware    indicates whether parsers should be namespace-aware or not\r
-         * @param schemaAware       indicates whether parsers should be schema-validating or not\r
-         */\r
-        ParserPool(bool namespaceAware=true, bool schemaAware=false);\r
-        ~ParserPool();\r
-\r
-        /**\r
-         * Creates a new document using a parser from this pool.\r
-         * \r
-         * @return new XML document\r
-         * \r
-         */\r
-        DOMDocument* newDocument();\r
-\r
-        /**\r
-         * Parses a document using a pooled parser with the proper settings\r
-         * \r
-         * @param domsrc A DOM source containing the content to be parsed\r
-         * @return The DOM document resulting from the parse\r
-         * @throws XMLParserException thrown if there was a problem reading, parsing, or validating the XML\r
-         */\r
-        DOMDocument* parse(DOMInputSource& domsrc);\r
-\r
-        /**\r
-         * Parses a document using a pooled parser with the proper settings\r
-         * \r
-         * @param is An input stream containing the content to be parsed\r
-         * @return The DOM document resulting from the parse\r
-         * @throws XMLParserException thrown if there was a problem reading, parsing, or validating the XML\r
-         */\r
-        DOMDocument* parse(std::istream& is);\r
-\r
-        /**\r
-         * Load an OASIS catalog file to map schema namespace URIs to filenames.\r
-         * \r
-         * This does not provide real catalog support; only the &lt;uri&gt; element\r
-         * is supported to map from a namespace URI to a relative path or file:// URI.\r
-         * \r
-         * @param pathname  path to a catalog file\r
-         * @return true iff the catalog was successfully processed\r
-         */\r
-        bool loadCatalog(const XMLCh* pathname);\r
-        \r
-        /**\r
-         * Load a schema explicitly from a local file.\r
-         * \r
-         * Note that "successful processing" does not imply that the schema is valid,\r
-         * only that a reference to it was successfully registered with the pool.\r
-         * \r
-         * @param nsURI     XML namespace to load\r
-         * @param pathname  path to schema file\r
-         * @return true iff the schema was successfully processed\r
-         */\r
-        bool loadSchema(const XMLCh* nsURI, const XMLCh* pathname);\r
-\r
-        /**\r
-         * Supplies all external entities (primarily schemas) to the parser\r
-         */\r
-        DOMInputSource* resolveEntity(const XMLCh* const publicId, const XMLCh* const systemId, const XMLCh* const baseURI);\r
-\r
-        /**\r
-         * Handles parsing errors\r
-         */\r
-        bool handleError(const DOMError& e);\r
-\r
-    private:\r
-        DOMBuilder* createBuilder();\r
-        DOMBuilder* checkoutBuilder();\r
-        void checkinBuilder(DOMBuilder* builder);\r
-\r
-#ifdef HAVE_GOOD_STL\r
-        xstring m_schemaLocations;\r
-        std::map<xstring,xstring> m_schemaLocMap;\r
-#else\r
-        std::string m_schemaLocations;\r
-        std::map<std::string,std::string> m_schemaLocMap;\r
-#endif\r
-        bool m_namespaceAware,m_schemaAware;\r
-        std::stack<DOMBuilder*> m_pool;\r
-        Mutex* m_lock;\r
-    };\r
-\r
-    /**\r
-     * A parser source that wraps a C++ input stream\r
-     */\r
-    class XMLTOOL_API StreamInputSource : public InputSource\r
-    {\r
-    MAKE_NONCOPYABLE(StreamInputSource);\r
-    public:\r
-        /**\r
-         * Constructs an input source around an input stream reference.\r
-         * \r
-         * @param is        reference to an input stream\r
-         * @param systemId  optional system identifier to attach to the stream\r
-         */\r
-        StreamInputSource(std::istream& is, const char* systemId=NULL) : InputSource(systemId), m_is(is) {}\r
-        /// @cond off\r
-        virtual BinInputStream* makeStream() const { return new StreamBinInputStream(m_is); }\r
-        /// @endcond\r
-\r
-        /**\r
-         * A Xerces input stream that wraps a C++ input stream\r
-         */\r
-        class XMLTOOL_API StreamBinInputStream : public BinInputStream\r
-        {\r
-        public:\r
-            /**\r
-             * Constructs a Xerces input stream around a C++ input stream reference.\r
-             * \r
-             * @param is        reference to an input stream\r
-             */\r
-            StreamBinInputStream(std::istream& is) : m_is(is), m_pos(0) {}\r
-            /// @cond off\r
-            virtual unsigned int curPos() const { return m_pos; }\r
-            virtual unsigned int readBytes(XMLByte* const toFill, const unsigned int maxToRead);\r
-            /// @endcond\r
-        private:\r
-            std::istream& m_is;\r
-            unsigned int m_pos;\r
-        };\r
-\r
-    private:\r
-        std::istream& m_is;\r
-    };\r
-};\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( pop )\r
-#endif\r
-\r
-#endif /* __xmltooling_pool_h__ */\r
+/*
+ *  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.
+ */
+
+/**
+ * @file ParserPool.h
+ * 
+ * XML parsing
+ */
+
+#if !defined(__xmltooling_pool_h__)
+#define __xmltooling_pool_h__
+
+#include <xmltooling/unicode.h>
+#include <xmltooling/util/Threads.h>
+
+#include <map>
+#include <stack>
+#include <istream>
+#include <xercesc/dom/DOM.hpp>
+#include <xercesc/sax/InputSource.hpp>
+#include <xercesc/util/BinInputStream.hpp>
+
+using namespace xercesc;
+
+#if defined (_MSC_VER)
+    #pragma warning( push )
+    #pragma warning( disable : 4250 4251 )
+#endif
+
+namespace xmltooling {
+
+    /**
+     * A thread-safe pool of DOMBuilders that share characteristics
+     */
+    class XMLTOOL_API ParserPool : public DOMEntityResolver, DOMErrorHandler
+    {
+        MAKE_NONCOPYABLE(ParserPool);
+    public:
+        /**
+         * Constructs a new pool
+         * 
+         * @param namespaceAware    indicates whether parsers should be namespace-aware or not
+         * @param schemaAware       indicates whether parsers should be schema-validating or not
+         */
+        ParserPool(bool namespaceAware=true, bool schemaAware=false);
+        ~ParserPool();
+
+        /**
+         * Creates a new document using a parser from this pool.
+         * 
+         * @return new XML document
+         * 
+         */
+        DOMDocument* newDocument();
+
+        /**
+         * Parses a document using a pooled parser with the proper settings
+         * 
+         * @param domsrc A DOM source containing the content to be parsed
+         * @return The DOM document resulting from the parse
+         * @throws XMLParserException thrown if there was a problem reading, parsing, or validating the XML
+         */
+        DOMDocument* parse(DOMInputSource& domsrc);
+
+        /**
+         * Parses a document using a pooled parser with the proper settings
+         * 
+         * @param is An input stream containing the content to be parsed
+         * @return The DOM document resulting from the parse
+         * @throws XMLParserException thrown if there was a problem reading, parsing, or validating the XML
+         */
+        DOMDocument* parse(std::istream& is);
+
+        /**
+         * Load an OASIS catalog file to map schema namespace URIs to filenames.
+         * 
+         * This does not provide real catalog support; only the &lt;uri&gt; element
+         * is supported to map from a namespace URI to a relative path or file:// URI.
+         * 
+         * @param pathname  path to a catalog file
+         * @return true iff the catalog was successfully processed
+         */
+        bool loadCatalog(const XMLCh* pathname);
+        
+        /**
+         * Load a schema explicitly from a local file.
+         * 
+         * Note that "successful processing" does not imply that the schema is valid,
+         * only that a reference to it was successfully registered with the pool.
+         * 
+         * @param nsURI     XML namespace to load
+         * @param pathname  path to schema file
+         * @return true iff the schema was successfully processed
+         */
+        bool loadSchema(const XMLCh* nsURI, const XMLCh* pathname);
+
+        /**
+         * Supplies all external entities (primarily schemas) to the parser
+         */
+        DOMInputSource* resolveEntity(const XMLCh* const publicId, const XMLCh* const systemId, const XMLCh* const baseURI);
+
+        /**
+         * Handles parsing errors
+         */
+        bool handleError(const DOMError& e);
+
+    private:
+        DOMBuilder* createBuilder();
+        DOMBuilder* checkoutBuilder();
+        void checkinBuilder(DOMBuilder* builder);
+
+#ifdef HAVE_GOOD_STL
+        xstring m_schemaLocations;
+        std::map<xstring,xstring> m_schemaLocMap;
+#else
+        std::string m_schemaLocations;
+        std::map<std::string,std::string> m_schemaLocMap;
+#endif
+        bool m_namespaceAware,m_schemaAware;
+        std::stack<DOMBuilder*> m_pool;
+        Mutex* m_lock;
+    };
+
+    /**
+     * A parser source that wraps a C++ input stream
+     */
+    class XMLTOOL_API StreamInputSource : public InputSource
+    {
+    MAKE_NONCOPYABLE(StreamInputSource);
+    public:
+        /**
+         * Constructs an input source around an input stream reference.
+         * 
+         * @param is        reference to an input stream
+         * @param systemId  optional system identifier to attach to the stream
+         */
+        StreamInputSource(std::istream& is, const char* systemId=NULL) : InputSource(systemId), m_is(is) {}
+        /// @cond off
+        virtual BinInputStream* makeStream() const { return new StreamBinInputStream(m_is); }
+        /// @endcond
+
+        /**
+         * A Xerces input stream that wraps a C++ input stream
+         */
+        class XMLTOOL_API StreamBinInputStream : public BinInputStream
+        {
+        public:
+            /**
+             * Constructs a Xerces input stream around a C++ input stream reference.
+             * 
+             * @param is        reference to an input stream
+             */
+            StreamBinInputStream(std::istream& is) : m_is(is), m_pos(0) {}
+            /// @cond off
+            virtual unsigned int curPos() const { return m_pos; }
+            virtual unsigned int readBytes(XMLByte* const toFill, const unsigned int maxToRead);
+            /// @endcond
+        private:
+            std::istream& m_is;
+            unsigned int m_pos;
+        };
+
+    private:
+        std::istream& m_is;
+    };
+};
+
+#if defined (_MSC_VER)
+    #pragma warning( pop )
+#endif
+
+#endif /* __xmltooling_pool_h__ */
index 94fd22d..1300d89 100644 (file)
@@ -1,66 +1,66 @@
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file xmltooling/util/ReplayCache.h\r
- * \r
- * Helper class on top of StorageService for detecting message replay.\r
- */\r
-\r
-#ifndef __xmltooling_replay_h__\r
-#define __xmltooling_replay_h__\r
-\r
-#include <xmltooling/util/StorageService.h>\r
-\r
-namespace xmltooling {\r
-\r
-    /**\r
-     * Helper class on top of StorageService for detecting message replay.\r
-     */\r
-    class XMLTOOL_API ReplayCache\r
-    {\r
-        MAKE_NONCOPYABLE(ReplayCache);\r
-    public:\r
-        \r
-        /**\r
-         * Creates a replay cache on top of a particular StorageService.\r
-         * \r
-         * @param storage       pointer to a StorageService, or NULL to keep cache in memory\r
-         */\r
-        ReplayCache(StorageService* storage=NULL);\r
-\r
-        virtual ~ReplayCache();\r
-        \r
-        /**\r
-         * Returns true iff the check value is not found in the cache, and stores it.\r
-         * \r
-         * @param context   a context label to subdivide the cache\r
-         * @param s         value to check\r
-         * @param expires   time for disposal of value from cache\r
-         */\r
-        virtual bool check(const char* context, const char* s, time_t expires);\r
-    \r
-        bool check(const char* context, const XMLCh* str, time_t expires) {\r
-            auto_ptr_char temp(str);\r
-            return check(context, temp.get(), expires);\r
-        }\r
-        \r
-    private:\r
-        StorageService* m_storage;\r
-    };\r
-};\r
-\r
-#endif /* __xmltooling_replay_h__ */\r
+/*
+ *  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.
+ */
+
+/**
+ * @file xmltooling/util/ReplayCache.h
+ * 
+ * Helper class on top of StorageService for detecting message replay.
+ */
+
+#ifndef __xmltooling_replay_h__
+#define __xmltooling_replay_h__
+
+#include <xmltooling/util/StorageService.h>
+
+namespace xmltooling {
+
+    /**
+     * Helper class on top of StorageService for detecting message replay.
+     */
+    class XMLTOOL_API ReplayCache
+    {
+        MAKE_NONCOPYABLE(ReplayCache);
+    public:
+        
+        /**
+         * Creates a replay cache on top of a particular StorageService.
+         * 
+         * @param storage       pointer to a StorageService, or NULL to keep cache in memory
+         */
+        ReplayCache(StorageService* storage=NULL);
+
+        virtual ~ReplayCache();
+        
+        /**
+         * Returns true iff the check value is not found in the cache, and stores it.
+         * 
+         * @param context   a context label to subdivide the cache
+         * @param s         value to check
+         * @param expires   time for disposal of value from cache
+         */
+        virtual bool check(const char* context, const char* s, time_t expires);
+    
+        bool check(const char* context, const XMLCh* str, time_t expires) {
+            auto_ptr_char temp(str);
+            return check(context, temp.get(), expires);
+        }
+        
+    private:
+        StorageService* m_storage;
+    };
+};
+
+#endif /* __xmltooling_replay_h__ */
index 571b86d..c96021b 100644 (file)
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file xmltooling/util/StorageService.h\r
- * \r
- * Generic data storage interface\r
- */\r
-\r
-#ifndef __xmltooling_storage_h__\r
-#define __xmltooling_storage_h__\r
-\r
-#include <xmltooling/XMLObject.h>\r
-\r
-#include <ctime>\r
-\r
-namespace xmltooling {\r
-\r
-    /**\r
-     * Generic data storage facility for use by services that require\r
-     * some degree of persistence. Implementations will vary in how much\r
-     * persistence they can supply.\r
-     * \r
-     * <p>Storage is divided into "contexts" identified by a string label.\r
-     * Keys need to be unique only within a given context, so multiple\r
-     * components can share a single storage service safely as long as they\r
-     * use different labels.\r
-     */\r
-    class XMLTOOL_API StorageService\r
-    {\r
-        MAKE_NONCOPYABLE(StorageService);\r
-    public:\r
-        virtual ~StorageService() {}\r
-        \r
-        /**\r
-         * Creates a new "short" record in the storage service.\r
-         * \r
-         * @param context       a storage context label\r
-         * @param key           null-terminated unique key of up to 255 bytes\r
-         * @param value         null-terminated value of up to 255 bytes to store\r
-         * @param expiration    an expiration timestamp, after which the record can be purged\r
-         * \r
-         * @throws IOException  raised if errors occur in the insertion process \r
-         */\r
-        virtual void createString(const char* context, const char* key, const char* value, time_t expiration)=0;\r
-        \r
-        /**\r
-         * Returns an existing "short" record from the storage service.\r
-         * \r
-         * @param context       a storage context label\r
-         * @param key           null-terminated unique key of up to 255 bytes\r
-         * @param pvalue        location in which to return the record value\r
-         * @param pexpiration   location in which to return the expiration timestamp\r
-         * @return  true iff a valid record exists and was returned   \r
-         * \r
-         * @throws IOException  raised if errors occur in the read process \r
-         */\r
-        virtual bool readString(const char* context, const char* key, std::string* pvalue=NULL, time_t* pexpiration=NULL)=0;\r
-\r
-        /**\r
-         * Updates an existing "short" record in the storage service.\r
-         * \r
-         * @param context       a storage context label\r
-         * @param key           null-terminated unique key of up to 255 bytes\r
-         * @param value         null-terminated value of up to 255 bytes to store, or NULL to leave alone\r
-         * @param expiration    a new expiration timestamp, or 0 to leave alone\r
-         * @return true iff the record exists and was updated\r
-         *    \r
-         * @throws IOException  raised if errors occur in the update process \r
-         */\r
-        virtual bool updateString(const char* context, const char* key, const char* value=NULL, time_t expiration=0)=0;\r
-        \r
-        /**\r
-         * Deletes an existing "short" record from the storage service.\r
-         * \r
-         * @param context       a storage context label\r
-         * @param key           null-terminated unique key of up to 255 bytes\r
-         * @return true iff the record existed and was deleted\r
-         *    \r
-         * @throws IOException  raised if errors occur in the deletion process \r
-         */\r
-        virtual bool deleteString(const char* context, const char* key)=0;\r
-        \r
-        /**\r
-         * Creates a new "long" record in the storage service.\r
-         * \r
-         * @param context       a storage context label\r
-         * @param key           null-terminated unique key of up to 255 bytes\r
-         * @param value         null-terminated value of arbitrary length\r
-         * @param expiration    an expiration timestamp, after which the record can be purged\r
-         * \r
-         * @throws IOException  raised if errors occur in the insertion process \r
-         */\r
-        virtual void createText(const char* context, const char* key, const char* value, time_t expiration)=0;\r
-        \r
-        /**\r
-         * Returns an existing "long" record from the storage service.\r
-         * \r
-         * @param context       a storage context label\r
-         * @param key           null-terminated unique key of up to 255 bytes\r
-         * @param pvalue        location in which to return the record value\r
-         * @param pexpiration   location in which to return the expiration timestamp\r
-         * @return  true iff a valid record exists and was returned   \r
-         * \r
-         * @throws IOException  raised if errors occur in the read process \r
-         */\r
-        virtual bool readText(const char* context, const char* key, std::string* pvalue=NULL, time_t* pexpiration=NULL)=0;\r
-\r
-        /**\r
-         * Updates an existing "long" record in the storage service.\r
-         * \r
-         * @param context       a storage context label\r
-         * @param key           null-terminated unique key of up to 255 bytes\r
-         * @param value         null-terminated value of arbitrary length to store, or NULL to leave alone\r
-         * @param expiration    a new expiration timestamp, or 0 to leave alone\r
-         * @return true iff the record exists and was updated\r
-         *    \r
-         * @throws IOException  raised if errors occur in the update process \r
-         */\r
-        virtual bool updateText(const char* context, const char* key, const char* value=NULL, time_t expiration=0)=0;\r
-        \r
-        /**\r
-         * Deletes an existing "long" record from the storage service.\r
-         * \r
-         * @param context       a storage context label\r
-         * @param key           null-terminated unique key of up to 255 bytes\r
-         * @return true iff the record existed and was deleted\r
-         *    \r
-         * @throws IOException  raised if errors occur in the deletion process \r
-         */\r
-        virtual bool deleteText(const char* context, const char* key)=0;\r
-        \r
-        /**\r
-         * Manually trigger a cleanup of expired records.\r
-         * The method <strong>MAY</strong> return without guaranteeing that\r
-         * cleanup has already occurred.\r
-         * \r
-         * @param context       a storage context label\r
-         */\r
-        virtual void reap(const char* context)=0;\r
-        \r
-        /**\r
-         * Forcibly removes all records in a given context along with any\r
-         * associated resources devoted to maintaining the context.\r
-         * \r
-         * @param context       a storage context label\r
-         */\r
-        virtual void deleteContext(const char* context)=0;\r
-\r
-    protected:\r
-        StorageService() {}\r
-    };\r
-\r
-    /**\r
-     * Registers StorageService classes into the runtime.\r
-     */\r
-    void XMLTOOL_API registerStorageServices();\r
-\r
-    /** StorageService based on in-memory caching. */\r
-    #define MEMORY_STORAGE_SERVICE  "org.opensaml.xmlooling.MemoryStorageService"\r
-};\r
-\r
-#endif /* __xmltooling_storage_h__ */\r
+/*
+ *  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.
+ */
+
+/**
+ * @file xmltooling/util/StorageService.h
+ * 
+ * Generic data storage interface
+ */
+
+#ifndef __xmltooling_storage_h__
+#define __xmltooling_storage_h__
+
+#include <xmltooling/XMLObject.h>
+
+#include <ctime>
+
+namespace xmltooling {
+
+    /**
+     * Generic data storage facility for use by services that require
+     * some degree of persistence. Implementations will vary in how much
+     * persistence they can supply.
+     * 
+     * <p>Storage is divided into "contexts" identified by a string label.
+     * Keys need to be unique only within a given context, so multiple
+     * components can share a single storage service safely as long as they
+     * use different labels.
+     */
+    class XMLTOOL_API StorageService
+    {
+        MAKE_NONCOPYABLE(StorageService);
+    public:
+        virtual ~StorageService() {}
+        
+        /**
+         * Creates a new "short" record in the storage service.
+         * 
+         * @param context       a storage context label
+         * @param key           null-terminated unique key of up to 255 bytes
+         * @param value         null-terminated value of up to 255 bytes to store
+         * @param expiration    an expiration timestamp, after which the record can be purged
+         * 
+         * @throws IOException  raised if errors occur in the insertion process 
+         */
+        virtual void createString(const char* context, const char* key, const char* value, time_t expiration)=0;
+        
+        /**
+         * Returns an existing "short" record from the storage service.
+         * 
+         * @param context       a storage context label
+         * @param key           null-terminated unique key of up to 255 bytes
+         * @param pvalue        location in which to return the record value
+         * @param pexpiration   location in which to return the expiration timestamp
+         * @return  true iff a valid record exists and was returned   
+         * 
+         * @throws IOException  raised if errors occur in the read process 
+         */
+        virtual bool readString(const char* context, const char* key, std::string* pvalue=NULL, time_t* pexpiration=NULL)=0;
+
+        /**
+         * Updates an existing "short" record in the storage service.
+         * 
+         * @param context       a storage context label
+         * @param key           null-terminated unique key of up to 255 bytes
+         * @param value         null-terminated value of up to 255 bytes to store, or NULL to leave alone
+         * @param expiration    a new expiration timestamp, or 0 to leave alone
+         * @return true iff the record exists and was updated
+         *    
+         * @throws IOException  raised if errors occur in the update process 
+         */
+        virtual bool updateString(const char* context, const char* key, const char* value=NULL, time_t expiration=0)=0;
+        
+        /**
+         * Deletes an existing "short" record from the storage service.
+         * 
+         * @param context       a storage context label
+         * @param key           null-terminated unique key of up to 255 bytes
+         * @return true iff the record existed and was deleted
+         *    
+         * @throws IOException  raised if errors occur in the deletion process 
+         */
+        virtual bool deleteString(const char* context, const char* key)=0;
+        
+        /**
+         * Creates a new "long" record in the storage service.
+         * 
+         * @param context       a storage context label
+         * @param key           null-terminated unique key of up to 255 bytes
+         * @param value         null-terminated value of arbitrary length
+         * @param expiration    an expiration timestamp, after which the record can be purged
+         * 
+         * @throws IOException  raised if errors occur in the insertion process 
+         */
+        virtual void createText(const char* context, const char* key, const char* value, time_t expiration)=0;
+        
+        /**
+         * Returns an existing "long" record from the storage service.
+         * 
+         * @param context       a storage context label
+         * @param key           null-terminated unique key of up to 255 bytes
+         * @param pvalue        location in which to return the record value
+         * @param pexpiration   location in which to return the expiration timestamp
+         * @return  true iff a valid record exists and was returned   
+         * 
+         * @throws IOException  raised if errors occur in the read process 
+         */
+        virtual bool readText(const char* context, const char* key, std::string* pvalue=NULL, time_t* pexpiration=NULL)=0;
+
+        /**
+         * Updates an existing "long" record in the storage service.
+         * 
+         * @param context       a storage context label
+         * @param key           null-terminated unique key of up to 255 bytes
+         * @param value         null-terminated value of arbitrary length to store, or NULL to leave alone
+         * @param expiration    a new expiration timestamp, or 0 to leave alone
+         * @return true iff the record exists and was updated
+         *    
+         * @throws IOException  raised if errors occur in the update process 
+         */
+        virtual bool updateText(const char* context, const char* key, const char* value=NULL, time_t expiration=0)=0;
+        
+        /**
+         * Deletes an existing "long" record from the storage service.
+         * 
+         * @param context       a storage context label
+         * @param key           null-terminated unique key of up to 255 bytes
+         * @return true iff the record existed and was deleted
+         *    
+         * @throws IOException  raised if errors occur in the deletion process 
+         */
+        virtual bool deleteText(const char* context, const char* key)=0;
+        
+        /**
+         * Manually trigger a cleanup of expired records.
+         * The method <strong>MAY</strong> return without guaranteeing that
+         * cleanup has already occurred.
+         * 
+         * @param context       a storage context label
+         */
+        virtual void reap(const char* context)=0;
+        
+        /**
+         * Forcibly removes all records in a given context along with any
+         * associated resources devoted to maintaining the context.
+         * 
+         * @param context       a storage context label
+         */
+        virtual void deleteContext(const char* context)=0;
+
+    protected:
+        StorageService() {}
+    };
+
+    /**
+     * Registers StorageService classes into the runtime.
+     */
+    void XMLTOOL_API registerStorageServices();
+
+    /** StorageService based on in-memory caching. */
+    #define MEMORY_STORAGE_SERVICE  "org.opensaml.xmlooling.MemoryStorageService"
+};
+
+#endif /* __xmltooling_storage_h__ */
index 8e5cdc0..1111f4d 100644 (file)
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * Win32Threads.cpp\r
- * \r
- * Thread and locking wrappers for Win32 platforms\r
- */\r
-\r
-#include "internal.h"\r
-#include "util/Threads.h"\r
-\r
-#include <log4cpp/Category.hh>\r
-\r
-#ifndef WIN32\r
-# error "This implementation is for WIN32 platforms."\r
-#endif\r
-\r
-using namespace xmltooling;\r
-using namespace log4cpp;\r
-using namespace std;\r
-\r
-// base error code for a routine to return on failure\r
-#define THREAD_ERROR_TIMEOUT   (1)\r
-#define THREAD_ERROR_WAKE_OTHER (2)\r
-#define THREAD_ERROR               (3)\r
-\r
-// windows returns non zero for success pthreads returns zero\r
-static int XMLTOOL_DLLLOCAL map_windows_error_status_to_pthreads(int rc=0) {\r
-    if(rc!=0)  // success?\r
-        return 0;\r
-    Category::getInstance(XMLTOOLING_LOGCAT".Threads").error("error from thread operation (%d)", GetLastError());\r
-    return THREAD_ERROR;\r
-}\r
-\r
-namespace xmltooling {\r
-\r
-    // two levels of classes are needed here\r
-    // in case InitializeCriticalSection\r
-    // throws an exception we can keep from\r
-    // calling the critical_section destructor\r
-    // on unitilized data, or it could be done with a flag\r
-    struct XMLTOOL_DLLLOCAL critical_section_data {\r
-        CRITICAL_SECTION cs;\r
-        critical_section_data(){\r
-            InitializeCriticalSection(&cs);    \r
-        }\r
-    };\r
-    \r
-    class XMLTOOL_DLLLOCAL critical_section {\r
-    private:\r
-        critical_section_data  cse;\r
-    public:\r
-        critical_section(){}\r
-        ~critical_section(){\r
-            DeleteCriticalSection (&cse.cs);\r
-        }\r
-        void enter(void) {\r
-            EnterCriticalSection(&cse.cs);\r
-        }\r
-        void leave(void) {\r
-            LeaveCriticalSection(&cse.cs);\r
-        }\r
-    };\r
-    \r
-    // hold a critical section over the lifetime of this object\r
-    // used to make a stack variable that unlocks automaticly\r
-    // on return/throw\r
-    class XMLTOOL_DLLLOCAL with_crit_section {\r
-    private:\r
-        critical_section& cs;\r
-    public:\r
-        with_crit_section(critical_section& acs):cs(acs){\r
-            cs.enter();\r
-        }\r
-        ~with_crit_section(){\r
-            cs.leave();\r
-        }\r
-    };\r
-    \r
-    class XMLTOOL_DLLLOCAL ThreadImpl : public Thread {\r
-    private:\r
-        HANDLE thread_id;\r
-    public:\r
-        ThreadImpl(void* (*start_routine)(void*), void* arg) : thread_id(0) {\r
-            thread_id=CreateThread(\r
-                0, // security attributes\r
-                0, // use default stack size, maybe this should be setable\r
-                (LPTHREAD_START_ROUTINE ) start_routine,\r
-                arg,\r
-                0, // flags, default is ignore stacksize and don't create suspended which is what we want\r
-                0);\r
-            if (thread_id==0) {\r
-                map_windows_error_status_to_pthreads();\r
-                throw ThreadingException("Thread creation failed.");\r
-            }\r
-        }\r
-\r
-        ~ThreadImpl() {\r
-            (void)detach();\r
-        }\r
-    \r
-        int detach() {\r
-            if (thread_id==0)\r
-                return THREAD_ERROR;\r
-            int rc=map_windows_error_status_to_pthreads(CloseHandle(thread_id));\r
-            thread_id=0;\r
-            return rc;\r
-        }\r
-\r
-        int join(void** thread_return) {\r
-            if (thread_id==0)\r
-                return THREAD_ERROR;\r
-            if (thread_return!=0)\r
-                *thread_return=0;\r
-            int rc=WaitForSingleObject(thread_id,INFINITE);\r
-            switch(rc) {\r
-                case WAIT_OBJECT_0:\r
-                    if (thread_return)\r
-                        map_windows_error_status_to_pthreads(GetExitCodeThread(thread_id,(unsigned long*)thread_return));\r
-                default:\r
-                    return THREAD_ERROR;\r
-            }\r
-            return 0;\r
-        }\r
-      \r
-        int kill(int signo) {\r
-            if (thread_id==0)\r
-                return THREAD_ERROR;\r
-            return map_windows_error_status_to_pthreads(TerminateThread(thread_id,signo));\r
-        }\r
-    };\r
-    \r
-    class XMLTOOL_DLLLOCAL MutexImpl : public Mutex {\r
-    private:\r
-        HANDLE mhandle;\r
-    public:\r
-        MutexImpl() : mhandle(CreateMutex(0,false,0)) {\r
-            if (mhandle==0) {\r
-                map_windows_error_status_to_pthreads();\r
-                throw ThreadingException("Mutex creation failed.");\r
-            }\r
-        }\r
-        \r
-        ~MutexImpl() {\r
-            if((mhandle!=0) && (!CloseHandle(mhandle))) \r
-                map_windows_error_status_to_pthreads();\r
-        }\r
-        \r
-        int lock() {\r
-            int rc=WaitForSingleObject(mhandle,INFINITE);\r
-            switch(rc) {\r
-                case WAIT_ABANDONED:\r
-                case WAIT_OBJECT_0:\r
-                    return 0;\r
-                default:\r
-                    return map_windows_error_status_to_pthreads();\r
-            }\r
-        }\r
-        \r
-        int unlock() {\r
-            return map_windows_error_status_to_pthreads(ReleaseMutex(mhandle));\r
-        }\r
-    };\r
-    \r
-    class XMLTOOL_DLLLOCAL CondWaitImpl : public CondWait {\r
-    private:\r
-        HANDLE cond;\r
-    \r
-    public:\r
-        CondWaitImpl() : cond(CreateEvent(0,false,false,0)) {\r
-            if(cond==0) {\r
-                map_windows_error_status_to_pthreads();\r
-               throw ThreadingException("Event creation failed.");\r
-            }\r
-        };\r
-    \r
-        ~CondWaitImpl() {\r
-            if((cond!=0) && (!CloseHandle(cond))) \r
-                map_windows_error_status_to_pthreads();\r
-        }\r
-    \r
-        int wait(Mutex* mutex) {\r
-            return timedwait(mutex,INFINITE);\r
-        }\r
-    \r
-        int signal() {\r
-            if(!SetEvent(cond))\r
-                return map_windows_error_status_to_pthreads();\r
-            return 0;\r
-        }\r
-      \r
-        int broadcast() {\r
-            throw ThreadingException("Broadcast not implemented on Win32 platforms.");\r
-        }\r
-    \r
-        // wait for myself to signal and this mutex or the timeout\r
-        int timedwait(Mutex* mutex, int delay_seconds) {\r
-            int rc=mutex->unlock();\r
-            if(rc!=0)\r
-                return rc;\r
-        \r
-            int delay_ms=delay_seconds;\r
-            if(delay_seconds!=INFINITE)\r
-                delay_ms*=1000;\r
-            rc=WaitForSingleObject(cond,delay_ms);\r
-            int rc2=mutex->lock();\r
-            if(rc2!=0)\r
-                return rc2;\r
-            switch(rc) {\r
-                case WAIT_ABANDONED:\r
-                case WAIT_OBJECT_0:\r
-                case WAIT_TIMEOUT:\r
-                    return 0;\r
-                default:\r
-                    return map_windows_error_status_to_pthreads();\r
-            }\r
-            return 0;\r
-        }\r
-    };\r
-    \r
-    class XMLTOOL_DLLLOCAL RWLockImpl : public RWLock {\r
-    private:\r
-        // used to protect read or write to the data below\r
-        critical_section cs;\r
-        // event handle threads wait on when the lock they want is busy\r
-        // normally set to signaled all the time, if some thread can't get what\r
-        // they want they reset it and sleep.  on releasing a lock set it to\r
-        // signaled if someone may have wanted what you just released\r
-        HANDLE wake_waiters;\r
-        // number of threads holding a read lock\r
-        int num_readers;\r
-        // true iff there a writer has our lock\r
-        bool have_writer;\r
-    \r
-    public:\r
-        RWLockImpl() : wake_waiters(0), num_readers(0), have_writer(true) {\r
-            with_crit_section acs(cs);\r
-            wake_waiters=CreateEvent(0,true,true,0);\r
-            have_writer=false;\r
-            if (wake_waiters==0) {\r
-                map_windows_error_status_to_pthreads();\r
-                throw ThreadingException("Event creation for shared lock failed.");\r
-            }\r
-        }\r
-        \r
-        ~RWLockImpl() { \r
-            with_crit_section acs(cs);\r
-            if ((wake_waiters!=0) && (!CloseHandle(wake_waiters))) \r
-                map_windows_error_status_to_pthreads();\r
-        }\r
-    \r
-        int rdlock() {\r
-            while(1) {\r
-                // wait for the lock maybe being availible\r
-                // we will find out for sure inside the critical section\r
-                if (WaitForSingleObject(wake_waiters,INFINITE)!=WAIT_OBJECT_0) \r
-                    return map_windows_error_status_to_pthreads();\r
-         \r
-                with_crit_section alock(cs);\r
-                // invariant not locked for reading and writing\r
-                if ((num_readers!=0) && (have_writer))\r
-                    return THREAD_ERROR;\r
-                // if no writer we can join any existing readers\r
-                if (!have_writer) {\r
-                    num_readers++;\r
-                    return 0;\r
-                }\r
-           \r
-                // have a writer, mark the synchronization object\r
-                // so everyone waits, when the writer unlocks it will wake us\r
-                if (!ResetEvent(wake_waiters))\r
-                    return map_windows_error_status_to_pthreads();\r
-            }\r
-            return THREAD_ERROR;\r
-        }\r
-    \r
-        int wrlock() {\r
-            while(1) {\r
-                // wait for the lock maybe being availible\r
-                // we will find out for sure inside the critical section\r
-                if (WaitForSingleObject(wake_waiters,INFINITE)!=WAIT_OBJECT_0) \r
-                    return map_windows_error_status_to_pthreads();\r
-\r
-                with_crit_section bla(cs);\r
-                // invariant not locked for reading and writing\r
-                if ((num_readers!=0) && (have_writer))\r
-                      return THREAD_ERROR;\r
-\r
-                // if no writer and no readers we can become the writer\r
-                if ((num_readers==0) && (!have_writer)) {\r
-                    have_writer=true;\r
-                    return 0;\r
-                }\r
-             \r
-                // lock is busy, the unlocker will wake us\r
-                if (!ResetEvent(wake_waiters))\r
-                    return map_windows_error_status_to_pthreads();\r
-            }\r
-            return THREAD_ERROR;\r
-        }\r
-    \r
-        int unlock() {\r
-            with_crit_section mumble(cs);\r
-            // invariant not locked for reading and writing\r
-            if ((num_readers!=0) && (have_writer))\r
-                return THREAD_ERROR;\r
-            \r
-            // error if nothing locked\r
-            if ((num_readers==0) && (!have_writer))\r
-                return THREAD_ERROR;\r
-            \r
-            // if there was a writer it has to be us so unlock write lock \r
-            have_writer=false;\r
-            \r
-            // if there where any reades there is one less now\r
-            if(num_readers>0)\r
-                num_readers--;\r
-            \r
-            // if no readers left wake up any readers/writers waiting\r
-            // to have a go at it\r
-            if (num_readers==0)\r
-                if (!SetEvent(wake_waiters))\r
-                    return map_windows_error_status_to_pthreads();\r
-            return 0;\r
-        }\r
-    };\r
-    \r
-    typedef void (*destroy_hook_type)(void*);\r
-    \r
-    class XMLTOOL_DLLLOCAL ThreadKeyImpl : public ThreadKey {\r
-    private:\r
-        destroy_hook_type destroy_hook;\r
-        DWORD key;\r
-    \r
-    public:\r
-        ThreadKeyImpl(void (*destroy_fcn)(void*)) : destroy_hook(destroy_fcn) {\r
-            key=TlsAlloc();\r
-        };\r
-        \r
-        virtual ~ThreadKeyImpl() {\r
-            if (destroy_hook)\r
-                destroy_hook(TlsGetValue(key));\r
-            TlsFree(key);\r
-        }\r
-    \r
-        int setData(void* data) {\r
-            TlsSetValue(key,data);\r
-            return 0;\r
-        }\r
-        \r
-        void* getData() const {\r
-            return TlsGetValue(key);\r
-        }\r
-    };\r
-\r
-};\r
-\r
-//\r
-// public "static" creation functions\r
-//\r
-\r
-Thread* Thread::create(void* (*start_routine)(void*), void* arg)\r
-{\r
-    return new ThreadImpl(start_routine, arg);\r
-}\r
-\r
-void Thread::exit(void* return_val)\r
-{\r
-    ExitThread((DWORD)return_val);\r
-}\r
-\r
-void Thread::sleep(int seconds)\r
-{\r
-    Sleep(seconds * 1000);\r
-}\r
-\r
-Mutex * Mutex::create()\r
-{\r
-    return new MutexImpl();\r
-}\r
-\r
-CondWait * CondWait::create()\r
-{\r
-    return new CondWaitImpl();\r
-}\r
-\r
-RWLock * RWLock::create()\r
-{\r
-    return new RWLockImpl();\r
-}\r
-\r
-ThreadKey* ThreadKey::create (void (*destroy_fcn)(void*))\r
-{\r
-    return new ThreadKeyImpl(destroy_fcn);\r
-}\r
+/*
+ *  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.
+ */
+
+/**
+ * Win32Threads.cpp
+ * 
+ * Thread and locking wrappers for Win32 platforms
+ */
+
+#include "internal.h"
+#include "util/Threads.h"
+
+#include <log4cpp/Category.hh>
+
+#ifndef WIN32
+# error "This implementation is for WIN32 platforms."
+#endif
+
+using namespace xmltooling;
+using namespace log4cpp;
+using namespace std;
+
+// base error code for a routine to return on failure
+#define THREAD_ERROR_TIMEOUT   (1)
+#define THREAD_ERROR_WAKE_OTHER (2)
+#define THREAD_ERROR               (3)
+
+// windows returns non zero for success pthreads returns zero
+static int XMLTOOL_DLLLOCAL map_windows_error_status_to_pthreads(int rc=0) {
+    if(rc!=0)  // success?
+        return 0;
+    Category::getInstance(XMLTOOLING_LOGCAT".Threads").error("error from thread operation (%d)", GetLastError());
+    return THREAD_ERROR;
+}
+
+namespace xmltooling {
+
+    // two levels of classes are needed here
+    // in case InitializeCriticalSection
+    // throws an exception we can keep from
+    // calling the critical_section destructor
+    // on unitilized data, or it could be done with a flag
+    struct XMLTOOL_DLLLOCAL critical_section_data {
+        CRITICAL_SECTION cs;
+        critical_section_data(){
+            InitializeCriticalSection(&cs);    
+        }
+    };
+    
+    class XMLTOOL_DLLLOCAL critical_section {
+    private:
+        critical_section_data  cse;
+    public:
+        critical_section(){}
+        ~critical_section(){
+            DeleteCriticalSection (&cse.cs);
+        }
+        void enter(void) {
+            EnterCriticalSection(&cse.cs);
+        }
+        void leave(void) {
+            LeaveCriticalSection(&cse.cs);
+        }
+    };
+    
+    // hold a critical section over the lifetime of this object
+    // used to make a stack variable that unlocks automaticly
+    // on return/throw
+    class XMLTOOL_DLLLOCAL with_crit_section {
+    private:
+        critical_section& cs;
+    public:
+        with_crit_section(critical_section& acs):cs(acs){
+            cs.enter();
+        }
+        ~with_crit_section(){
+            cs.leave();
+        }
+    };
+    
+    class XMLTOOL_DLLLOCAL ThreadImpl : public Thread {
+    private:
+        HANDLE thread_id;
+    public:
+        ThreadImpl(void* (*start_routine)(void*), void* arg) : thread_id(0) {
+            thread_id=CreateThread(
+                0, // security attributes
+                0, // use default stack size, maybe this should be setable
+                (LPTHREAD_START_ROUTINE ) start_routine,
+                arg,
+                0, // flags, default is ignore stacksize and don't create suspended which is what we want
+                0);
+            if (thread_id==0) {
+                map_windows_error_status_to_pthreads();
+                throw ThreadingException("Thread creation failed.");
+            }
+        }
+
+        ~ThreadImpl() {
+            (void)detach();
+        }
+    
+        int detach() {
+            if (thread_id==0)
+                return THREAD_ERROR;
+            int rc=map_windows_error_status_to_pthreads(CloseHandle(thread_id));
+            thread_id=0;
+            return rc;
+        }
+
+        int join(void** thread_return) {
+            if (thread_id==0)
+                return THREAD_ERROR;
+            if (thread_return!=0)
+                *thread_return=0;
+            int rc=WaitForSingleObject(thread_id,INFINITE);
+            switch(rc) {
+                case WAIT_OBJECT_0:
+                    if (thread_return)
+                        map_windows_error_status_to_pthreads(GetExitCodeThread(thread_id,(unsigned long*)thread_return));
+                default:
+                    return THREAD_ERROR;
+            }
+            return 0;
+        }
+      
+        int kill(int signo) {
+            if (thread_id==0)
+                return THREAD_ERROR;
+            return map_windows_error_status_to_pthreads(TerminateThread(thread_id,signo));
+        }
+    };
+    
+    class XMLTOOL_DLLLOCAL MutexImpl : public Mutex {
+    private:
+        HANDLE mhandle;
+    public:
+        MutexImpl() : mhandle(CreateMutex(0,false,0)) {
+            if (mhandle==0) {
+                map_windows_error_status_to_pthreads();
+                throw ThreadingException("Mutex creation failed.");
+            }
+        }
+        
+        ~MutexImpl() {
+            if((mhandle!=0) && (!CloseHandle(mhandle))) 
+                map_windows_error_status_to_pthreads();
+        }
+        
+        int lock() {
+            int rc=WaitForSingleObject(mhandle,INFINITE);
+            switch(rc) {
+                case WAIT_ABANDONED:
+                case WAIT_OBJECT_0:
+                    return 0;
+                default:
+                    return map_windows_error_status_to_pthreads();
+            }
+        }
+        
+        int unlock() {
+            return map_windows_error_status_to_pthreads(ReleaseMutex(mhandle));
+        }
+    };
+    
+    class XMLTOOL_DLLLOCAL CondWaitImpl : public CondWait {
+    private:
+        HANDLE cond;
+    
+    public:
+        CondWaitImpl() : cond(CreateEvent(0,false,false,0)) {
+            if(cond==0) {
+                map_windows_error_status_to_pthreads();
+               throw ThreadingException("Event creation failed.");
+            }
+        };
+    
+        ~CondWaitImpl() {
+            if((cond!=0) && (!CloseHandle(cond))) 
+                map_windows_error_status_to_pthreads();
+        }
+    
+        int wait(Mutex* mutex) {
+            return timedwait(mutex,INFINITE);
+        }
+    
+        int signal() {
+            if(!SetEvent(cond))
+                return map_windows_error_status_to_pthreads();
+            return 0;
+        }
+      
+        int broadcast() {
+            throw ThreadingException("Broadcast not implemented on Win32 platforms.");
+        }
+    
+        // wait for myself to signal and this mutex or the timeout
+        int timedwait(Mutex* mutex, int delay_seconds) {
+            int rc=mutex->unlock();
+            if(rc!=0)
+                return rc;
+        
+            int delay_ms=delay_seconds;
+            if(delay_seconds!=INFINITE)
+                delay_ms*=1000;
+            rc=WaitForSingleObject(cond,delay_ms);
+            int rc2=mutex->lock();
+            if(rc2!=0)
+                return rc2;
+            switch(rc) {
+                case WAIT_ABANDONED:
+                case WAIT_OBJECT_0:
+                case WAIT_TIMEOUT:
+                    return 0;
+                default:
+                    return map_windows_error_status_to_pthreads();
+            }
+            return 0;
+        }
+    };
+    
+    class XMLTOOL_DLLLOCAL RWLockImpl : public RWLock {
+    private:
+        // used to protect read or write to the data below
+        critical_section cs;
+        // event handle threads wait on when the lock they want is busy
+        // normally set to signaled all the time, if some thread can't get what
+        // they want they reset it and sleep.  on releasing a lock set it to
+        // signaled if someone may have wanted what you just released
+        HANDLE wake_waiters;
+        // number of threads holding a read lock
+        int num_readers;
+        // true iff there a writer has our lock
+        bool have_writer;
+    
+    public:
+        RWLockImpl() : wake_waiters(0), num_readers(0), have_writer(true) {
+            with_crit_section acs(cs);
+            wake_waiters=CreateEvent(0,true,true,0);
+            have_writer=false;
+            if (wake_waiters==0) {
+                map_windows_error_status_to_pthreads();
+                throw ThreadingException("Event creation for shared lock failed.");
+            }
+        }
+        
+        ~RWLockImpl() { 
+            with_crit_section acs(cs);
+            if ((wake_waiters!=0) && (!CloseHandle(wake_waiters))) 
+                map_windows_error_status_to_pthreads();
+        }
+    
+        int rdlock() {
+            while(1) {
+                // wait for the lock maybe being availible
+                // we will find out for sure inside the critical section
+                if (WaitForSingleObject(wake_waiters,INFINITE)!=WAIT_OBJECT_0) 
+                    return map_windows_error_status_to_pthreads();
+         
+                with_crit_section alock(cs);
+                // invariant not locked for reading and writing
+                if ((num_readers!=0) && (have_writer))
+                    return THREAD_ERROR;
+                // if no writer we can join any existing readers
+                if (!have_writer) {
+                    num_readers++;
+                    return 0;
+                }
+           
+                // have a writer, mark the synchronization object
+                // so everyone waits, when the writer unlocks it will wake us
+                if (!ResetEvent(wake_waiters))
+                    return map_windows_error_status_to_pthreads();
+            }
+            return THREAD_ERROR;
+        }
+    
+        int wrlock() {
+            while(1) {
+                // wait for the lock maybe being availible
+                // we will find out for sure inside the critical section
+                if (WaitForSingleObject(wake_waiters,INFINITE)!=WAIT_OBJECT_0) 
+                    return map_windows_error_status_to_pthreads();
+
+                with_crit_section bla(cs);
+                // invariant not locked for reading and writing
+                if ((num_readers!=0) && (have_writer))
+                      return THREAD_ERROR;
+
+                // if no writer and no readers we can become the writer
+                if ((num_readers==0) && (!have_writer)) {
+                    have_writer=true;
+                    return 0;
+                }
+             
+                // lock is busy, the unlocker will wake us
+                if (!ResetEvent(wake_waiters))
+                    return map_windows_error_status_to_pthreads();
+            }
+            return THREAD_ERROR;
+        }
+    
+        int unlock() {
+            with_crit_section mumble(cs);
+            // invariant not locked for reading and writing
+            if ((num_readers!=0) && (have_writer))
+                return THREAD_ERROR;
+            
+            // error if nothing locked
+            if ((num_readers==0) && (!have_writer))
+                return THREAD_ERROR;
+            
+            // if there was a writer it has to be us so unlock write lock 
+            have_writer=false;
+            
+            // if there where any reades there is one less now
+            if(num_readers>0)
+                num_readers--;
+            
+            // if no readers left wake up any readers/writers waiting
+            // to have a go at it
+            if (num_readers==0)
+                if (!SetEvent(wake_waiters))
+                    return map_windows_error_status_to_pthreads();
+            return 0;
+        }
+    };
+    
+    typedef void (*destroy_hook_type)(void*);
+    
+    class XMLTOOL_DLLLOCAL ThreadKeyImpl : public ThreadKey {
+    private:
+        destroy_hook_type destroy_hook;
+        DWORD key;
+    
+    public:
+        ThreadKeyImpl(void (*destroy_fcn)(void*)) : destroy_hook(destroy_fcn) {
+            key=TlsAlloc();
+        };
+        
+        virtual ~ThreadKeyImpl() {
+            if (destroy_hook)
+                destroy_hook(TlsGetValue(key));
+            TlsFree(key);
+        }
+    
+        int setData(void* data) {
+            TlsSetValue(key,data);
+            return 0;
+        }
+        
+        void* getData() const {
+            return TlsGetValue(key);
+        }
+    };
+
+};
+
+//
+// public "static" creation functions
+//
+
+Thread* Thread::create(void* (*start_routine)(void*), void* arg)
+{
+    return new ThreadImpl(start_routine, arg);
+}
+
+void Thread::exit(void* return_val)
+{
+    ExitThread((DWORD)return_val);
+}
+
+void Thread::sleep(int seconds)
+{
+    Sleep(seconds * 1000);
+}
+
+Mutex * Mutex::create()
+{
+    return new MutexImpl();
+}
+
+CondWait * CondWait::create()
+{
+    return new CondWaitImpl();
+}
+
+RWLock * RWLock::create()
+{
+    return new RWLockImpl();
+}
+
+ThreadKey* ThreadKey::create (void (*destroy_fcn)(void*))
+{
+    return new ThreadKeyImpl(destroy_fcn);
+}
index 232c8d5..a45f7c5 100644 (file)
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * XMLConstants.cpp\r
- * \r
- * Fundamental XML namespace constants \r
- */\r
-\r
-\r
-#include "internal.h"\r
-#include "util/XMLConstants.h"\r
-#include <xercesc/util/XMLUniDefs.hpp>\r
-\r
-using namespace xmltooling;\r
-    \r
-const XMLCh XMLConstants::XML_NS[] = // http://www.w3.org/XML/1998/namespace\r
-{ chLatin_h, chLatin_t, chLatin_t, chLatin_p, chColon, chForwardSlash, chForwardSlash,\r
-  chLatin_w, chLatin_w, chLatin_w, chPeriod, chLatin_w, chDigit_3, chPeriod, chLatin_o, chLatin_r, chLatin_g, chForwardSlash,\r
-  chLatin_X, chLatin_M, chLatin_L, chForwardSlash, chDigit_1, chDigit_9, chDigit_9, chDigit_8, chForwardSlash,\r
-  chLatin_n, chLatin_a, chLatin_m, chLatin_e, chLatin_s, chLatin_p, chLatin_a, chLatin_c, chLatin_e, chNull\r
-};\r
-\r
-const XMLCh XMLConstants::XMLNS_NS[] = // http://www.w3.org/2000/xmlns/\r
-{ chLatin_h, chLatin_t, chLatin_t, chLatin_p, chColon, chForwardSlash, chForwardSlash,\r
-  chLatin_w, chLatin_w, chLatin_w, chPeriod, chLatin_w, chDigit_3, chPeriod, chLatin_o, chLatin_r, chLatin_g, chForwardSlash,\r
-  chDigit_2, chDigit_0, chDigit_0, chDigit_0, chForwardSlash,\r
-  chLatin_x, chLatin_m, chLatin_l, chLatin_n, chLatin_s, chForwardSlash, chNull\r
-};\r
-\r
-const XMLCh XMLConstants::XMLNS_PREFIX[] = { chLatin_x, chLatin_m, chLatin_l, chLatin_n, chLatin_s, chNull };\r
-\r
-const XMLCh XMLConstants::XML_PREFIX[] = { chLatin_x, chLatin_m, chLatin_l, chNull };\r
-\r
-const XMLCh XMLConstants::XSD_NS[] = // http://www.w3.org/2001/XMLSchema\r
-{ chLatin_h, chLatin_t, chLatin_t, chLatin_p, chColon, chForwardSlash, chForwardSlash,\r
-  chLatin_w, chLatin_w, chLatin_w, chPeriod, chLatin_w, chDigit_3, chPeriod, chLatin_o, chLatin_r, chLatin_g, chForwardSlash,\r
-  chDigit_2, chDigit_0, chDigit_0, chDigit_1, chForwardSlash,\r
-  chLatin_X, chLatin_M, chLatin_L, chLatin_S, chLatin_c, chLatin_h, chLatin_e, chLatin_m, chLatin_a, chNull\r
-};\r
-\r
-const XMLCh XMLConstants::XSD_PREFIX[] = { chLatin_x, chLatin_s, chNull };\r
-\r
-const XMLCh XMLConstants::XSI_NS[] = // http://www.w3.org/2001/XMLSchema-instance\r
-{ chLatin_h, chLatin_t, chLatin_t, chLatin_p, chColon, chForwardSlash, chForwardSlash,\r
-  chLatin_w, chLatin_w, chLatin_w, chPeriod, chLatin_w, chDigit_3, chPeriod, chLatin_o, chLatin_r, chLatin_g, chForwardSlash,\r
-  chDigit_2, chDigit_0, chDigit_0, chDigit_1, chForwardSlash,\r
-  chLatin_X, chLatin_M, chLatin_L, chLatin_S, chLatin_c, chLatin_h, chLatin_e, chLatin_m, chLatin_a, chDash,\r
-  chLatin_i, chLatin_n, chLatin_s, chLatin_t, chLatin_a, chLatin_n, chLatin_c, chLatin_e, chNull\r
-};\r
-\r
-const XMLCh XMLConstants::XSI_PREFIX[] = { chLatin_x, chLatin_s, chLatin_i, chNull };\r
-\r
-const XMLCh XMLConstants::XMLSIG_NS[] = // http://www.w3.org/2000/09/xmldsig#\r
-{ chLatin_h, chLatin_t, chLatin_t, chLatin_p, chColon, chForwardSlash, chForwardSlash,\r
-  chLatin_w, chLatin_w, chLatin_w, chPeriod, chLatin_w, chDigit_3, chPeriod, chLatin_o, chLatin_r, chLatin_g, chForwardSlash,\r
-  chDigit_2, chDigit_0, chDigit_0, chDigit_0, chForwardSlash, chDigit_0, chDigit_9, chForwardSlash,\r
-  chLatin_x, chLatin_m, chLatin_l, chLatin_d, chLatin_s, chLatin_i, chLatin_g, chPound, chNull\r
-};\r
-\r
-const XMLCh XMLConstants::XMLSIG_PREFIX[] = { chLatin_d, chLatin_s, chNull };\r
-\r
-const XMLCh XMLConstants::XMLENC_NS[] = // http://www.w3.org/2001/04/xmlenc#\r
-{ chLatin_h, chLatin_t, chLatin_t, chLatin_p, chColon, chForwardSlash, chForwardSlash,\r
-  chLatin_w, chLatin_w, chLatin_w, chPeriod, chLatin_w, chDigit_3, chPeriod, chLatin_o, chLatin_r, chLatin_g, chForwardSlash,\r
-  chDigit_2, chDigit_0, chDigit_0, chDigit_1, chForwardSlash, chDigit_0, chDigit_4, chForwardSlash,\r
-  chLatin_x, chLatin_m, chLatin_l, chLatin_e, chLatin_n, chLatin_c, chPound, chNull\r
-};\r
-\r
-const XMLCh XMLConstants::XMLENC_PREFIX[] = { chLatin_x, chLatin_e, chLatin_n, chLatin_c, chNull };\r
-\r
-const XMLCh XMLConstants::SOAP11ENV_NS[] = // http://schemas.xmlsoap.org/soap/envelope/\r
-{ chLatin_h, chLatin_t, chLatin_t, chLatin_p, chColon, chForwardSlash, chForwardSlash,\r
-  chLatin_s, chLatin_c, chLatin_h, chLatin_e, chLatin_m, chLatin_a, chLatin_s, chPeriod,\r
-      chLatin_x, chLatin_m, chLatin_l, chLatin_s, chLatin_o, chLatin_a, chLatin_p, chPeriod,\r
-      chLatin_o, chLatin_r, chLatin_g, chForwardSlash,\r
-  chLatin_s, chLatin_o, chLatin_a, chLatin_p, chForwardSlash,\r
-  chLatin_e, chLatin_n, chLatin_v, chLatin_e, chLatin_l, chLatin_o, chLatin_p, chLatin_e, chForwardSlash, chNull\r
-};\r
-\r
-const XMLCh XMLConstants::SOAP11ENV_PREFIX[] = UNICODE_LITERAL_1(S);\r
-\r
-const XMLCh XMLConstants::XMLTOOLING_NS[] = // http://www.opensaml.org/xmltooling\r
-{ chLatin_h, chLatin_t, chLatin_t, chLatin_p, chColon, chForwardSlash, chForwardSlash,\r
-  chLatin_w, chLatin_w, chLatin_w, chPeriod,\r
-  chLatin_o, chLatin_p, chLatin_e, chLatin_n, chLatin_s, chLatin_a, chLatin_m, chLatin_l, chPeriod,\r
-  chLatin_o, chLatin_r, chLatin_g, chForwardSlash,\r
-  chLatin_x, chLatin_m, chLatin_l, chLatin_t, chLatin_o, chLatin_o, chLatin_l, chLatin_i, chLatin_n, chLatin_g, chNull\r
-};\r
-\r
-const XMLCh XMLConstants::XML_TRUE[] = { chLatin_t, chLatin_r, chLatin_u, chLatin_e, chNull };\r
-\r
-const XMLCh XMLConstants::XML_FALSE[] = { chLatin_f, chLatin_a, chLatin_l, chLatin_s, chLatin_e, chNull };\r
-\r
-const XMLCh XMLConstants::XML_ONE[] = { chDigit_1, chNull };\r
-\r
-const XMLCh XMLConstants::XML_ZERO[] = { chDigit_0, chNull };\r
+/*
+ *  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.
+ */
+
+/**
+ * XMLConstants.cpp
+ * 
+ * Fundamental XML namespace constants 
+ */
+
+
+#include "internal.h"
+#include "util/XMLConstants.h"
+#include <xercesc/util/XMLUniDefs.hpp>
+
+using namespace xmltooling;
+    
+const XMLCh XMLConstants::XML_NS[] = // http://www.w3.org/XML/1998/namespace
+{ chLatin_h, chLatin_t, chLatin_t, chLatin_p, chColon, chForwardSlash, chForwardSlash,
+  chLatin_w, chLatin_w, chLatin_w, chPeriod, chLatin_w, chDigit_3, chPeriod, chLatin_o, chLatin_r, chLatin_g, chForwardSlash,
+  chLatin_X, chLatin_M, chLatin_L, chForwardSlash, chDigit_1, chDigit_9, chDigit_9, chDigit_8, chForwardSlash,
+  chLatin_n, chLatin_a, chLatin_m, chLatin_e, chLatin_s, chLatin_p, chLatin_a, chLatin_c, chLatin_e, chNull
+};
+
+const XMLCh XMLConstants::XMLNS_NS[] = // http://www.w3.org/2000/xmlns/
+{ chLatin_h, chLatin_t, chLatin_t, chLatin_p, chColon, chForwardSlash, chForwardSlash,
+  chLatin_w, chLatin_w, chLatin_w, chPeriod, chLatin_w, chDigit_3, chPeriod, chLatin_o, chLatin_r, chLatin_g, chForwardSlash,
+  chDigit_2, chDigit_0, chDigit_0, chDigit_0, chForwardSlash,
+  chLatin_x, chLatin_m, chLatin_l, chLatin_n, chLatin_s, chForwardSlash, chNull
+};
+
+const XMLCh XMLConstants::XMLNS_PREFIX[] = { chLatin_x, chLatin_m, chLatin_l, chLatin_n, chLatin_s, chNull };
+
+const XMLCh XMLConstants::XML_PREFIX[] = { chLatin_x, chLatin_m, chLatin_l, chNull };
+
+const XMLCh XMLConstants::XSD_NS[] = // http://www.w3.org/2001/XMLSchema
+{ chLatin_h, chLatin_t, chLatin_t, chLatin_p, chColon, chForwardSlash, chForwardSlash,
+  chLatin_w, chLatin_w, chLatin_w, chPeriod, chLatin_w, chDigit_3, chPeriod, chLatin_o, chLatin_r, chLatin_g, chForwardSlash,
+  chDigit_2, chDigit_0, chDigit_0, chDigit_1, chForwardSlash,
+  chLatin_X, chLatin_M, chLatin_L, chLatin_S, chLatin_c, chLatin_h, chLatin_e, chLatin_m, chLatin_a, chNull
+};
+
+const XMLCh XMLConstants::XSD_PREFIX[] = { chLatin_x, chLatin_s, chNull };
+
+const XMLCh XMLConstants::XSI_NS[] = // http://www.w3.org/2001/XMLSchema-instance
+{ chLatin_h, chLatin_t, chLatin_t, chLatin_p, chColon, chForwardSlash, chForwardSlash,
+  chLatin_w, chLatin_w, chLatin_w, chPeriod, chLatin_w, chDigit_3, chPeriod, chLatin_o, chLatin_r, chLatin_g, chForwardSlash,
+  chDigit_2, chDigit_0, chDigit_0, chDigit_1, chForwardSlash,
+  chLatin_X, chLatin_M, chLatin_L, chLatin_S, chLatin_c, chLatin_h, chLatin_e, chLatin_m, chLatin_a, chDash,
+  chLatin_i, chLatin_n, chLatin_s, chLatin_t, chLatin_a, chLatin_n, chLatin_c, chLatin_e, chNull
+};
+
+const XMLCh XMLConstants::XSI_PREFIX[] = { chLatin_x, chLatin_s, chLatin_i, chNull };
+
+const XMLCh XMLConstants::XMLSIG_NS[] = // http://www.w3.org/2000/09/xmldsig#
+{ chLatin_h, chLatin_t, chLatin_t, chLatin_p, chColon, chForwardSlash, chForwardSlash,
+  chLatin_w, chLatin_w, chLatin_w, chPeriod, chLatin_w, chDigit_3, chPeriod, chLatin_o, chLatin_r, chLatin_g, chForwardSlash,
+  chDigit_2, chDigit_0, chDigit_0, chDigit_0, chForwardSlash, chDigit_0, chDigit_9, chForwardSlash,
+  chLatin_x, chLatin_m, chLatin_l, chLatin_d, chLatin_s, chLatin_i, chLatin_g, chPound, chNull
+};
+
+const XMLCh XMLConstants::XMLSIG_PREFIX[] = { chLatin_d, chLatin_s, chNull };
+
+const XMLCh XMLConstants::XMLENC_NS[] = // http://www.w3.org/2001/04/xmlenc#
+{ chLatin_h, chLatin_t, chLatin_t, chLatin_p, chColon, chForwardSlash, chForwardSlash,
+  chLatin_w, chLatin_w, chLatin_w, chPeriod, chLatin_w, chDigit_3, chPeriod, chLatin_o, chLatin_r, chLatin_g, chForwardSlash,
+  chDigit_2, chDigit_0, chDigit_0, chDigit_1, chForwardSlash, chDigit_0, chDigit_4, chForwardSlash,
+  chLatin_x, chLatin_m, chLatin_l, chLatin_e, chLatin_n, chLatin_c, chPound, chNull
+};
+
+const XMLCh XMLConstants::XMLENC_PREFIX[] = { chLatin_x, chLatin_e, chLatin_n, chLatin_c, chNull };
+
+const XMLCh XMLConstants::SOAP11ENV_NS[] = // http://schemas.xmlsoap.org/soap/envelope/
+{ chLatin_h, chLatin_t, chLatin_t, chLatin_p, chColon, chForwardSlash, chForwardSlash,
+  chLatin_s, chLatin_c, chLatin_h, chLatin_e, chLatin_m, chLatin_a, chLatin_s, chPeriod,
+      chLatin_x, chLatin_m, chLatin_l, chLatin_s, chLatin_o, chLatin_a, chLatin_p, chPeriod,
+      chLatin_o, chLatin_r, chLatin_g, chForwardSlash,
+  chLatin_s, chLatin_o, chLatin_a, chLatin_p, chForwardSlash,
+  chLatin_e, chLatin_n, chLatin_v, chLatin_e, chLatin_l, chLatin_o, chLatin_p, chLatin_e, chForwardSlash, chNull
+};
+
+const XMLCh XMLConstants::SOAP11ENV_PREFIX[] = UNICODE_LITERAL_1(S);
+
+const XMLCh XMLConstants::XMLTOOLING_NS[] = // http://www.opensaml.org/xmltooling
+{ chLatin_h, chLatin_t, chLatin_t, chLatin_p, chColon, chForwardSlash, chForwardSlash,
+  chLatin_w, chLatin_w, chLatin_w, chPeriod,
+  chLatin_o, chLatin_p, chLatin_e, chLatin_n, chLatin_s, chLatin_a, chLatin_m, chLatin_l, chPeriod,
+  chLatin_o, chLatin_r, chLatin_g, chForwardSlash,
+  chLatin_x, chLatin_m, chLatin_l, chLatin_t, chLatin_o, chLatin_o, chLatin_l, chLatin_i, chLatin_n, chLatin_g, chNull
+};
+
+const XMLCh XMLConstants::XML_TRUE[] = { chLatin_t, chLatin_r, chLatin_u, chLatin_e, chNull };
+
+const XMLCh XMLConstants::XML_FALSE[] = { chLatin_f, chLatin_a, chLatin_l, chLatin_s, chLatin_e, chNull };
+
+const XMLCh XMLConstants::XML_ONE[] = { chDigit_1, chNull };
+
+const XMLCh XMLConstants::XML_ZERO[] = { chDigit_0, chNull };
index 355ec39..093688d 100644 (file)
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file XMLConstants.h\r
- * \r
- * Fundamental XML namespace constants \r
- */\r
-\r
-#if !defined(__xmltooling_xmlconstants_h__)\r
-#define __xmltooling_xmlconstants_h__\r
-\r
-#include <xmltooling/unicode.h>\r
-\r
-namespace xmltooling {\r
-    \r
-    /**\r
-     * XML related constants.\r
-     */\r
-    struct XMLTOOL_API XMLConstants\r
-    {\r
-        /**  XML core namespace ("http://www.w3.org/XML/1998/namespace") */\r
-        static const XMLCh XML_NS[]; \r
-\r
-        /** XML namespace prefix for special xml attributes ("xml") */\r
-        static const XMLCh XML_PREFIX[];\r
-    \r
-        /**  XML namespace for xmlns attributes ("http://www.w3.org/2000/xmlns/") */\r
-        static const XMLCh XMLNS_NS[];\r
-        \r
-        /** XML namespace prefix for xmlns attributes ("xmlns") */\r
-        static const XMLCh XMLNS_PREFIX[];\r
-    \r
-        /**  XML Schema namespace ("http://www.w3.org/2001/XMLSchema") */\r
-        static const XMLCh XSD_NS[];\r
-        \r
-        /**  XML Schema QName prefix ("xs") */\r
-        static const XMLCh XSD_PREFIX[];\r
-    \r
-        /**  XML Schema Instance namespace ("http://www.w3.org/2001/XMLSchema-instance") */\r
-        static const XMLCh XSI_NS[];\r
-        \r
-        /**  XML Schema Instance QName prefix ("xsi") */\r
-        static const XMLCh XSI_PREFIX[];\r
-        \r
-        /**  XML Signature namespace ("http://www.w3.org/2000/09/xmldsig#") */\r
-        static const XMLCh XMLSIG_NS[];\r
-        \r
-        /**  XML Signature QName prefix ("ds") */\r
-        static const XMLCh XMLSIG_PREFIX[];\r
-        \r
-        /**  XML Encryption namespace ("http://www.w3.org/2001/04/xmlenc#") */\r
-        static const XMLCh XMLENC_NS[];\r
-        \r
-        /**  XML Encryption QName prefix ("xenc") */\r
-        static const XMLCh XMLENC_PREFIX[];\r
-        \r
-        /**  SOAP 1.1 Envelope XML namespace ("http://schemas.xmlsoap.org/soap/envelope/") */\r
-        static const XMLCh SOAP11ENV_NS[]; \r
-\r
-        /**  SOAP 1.1 Envelope QName prefix ("S") */\r
-        static const XMLCh SOAP11ENV_PREFIX[];\r
-    \r
-        /**  XML Tooling namespace ("http://www.opensaml.org/xmltooling") */\r
-        static const XMLCh XMLTOOLING_NS[];\r
-\r
-        /**  XML "true" boolean constant */\r
-        static const XMLCh XML_TRUE[];\r
-\r
-        /**  XML "false" boolean constant */\r
-        static const XMLCh XML_FALSE[];\r
-\r
-        /**  XML "1" boolean constant */\r
-        static const XMLCh XML_ONE[];\r
-\r
-        /**  XML "0" boolean constant */\r
-        static const XMLCh XML_ZERO[];\r
-        \r
-        /** Enumerations of the different values of a boolean attribute or element */\r
-        enum xmltooling_bool_t {\r
-            XML_BOOL_NULL,\r
-            XML_BOOL_TRUE,\r
-            XML_BOOL_FALSE,\r
-            XML_BOOL_ONE,\r
-            XML_BOOL_ZERO\r
-        };\r
-    };\r
-\r
-};\r
-\r
-#endif /* __xmltooling_xmlconstants_h__ */\r
+/*
+ *  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.
+ */
+
+/**
+ * @file XMLConstants.h
+ * 
+ * Fundamental XML namespace constants 
+ */
+
+#if !defined(__xmltooling_xmlconstants_h__)
+#define __xmltooling_xmlconstants_h__
+
+#include <xmltooling/unicode.h>
+
+namespace xmltooling {
+    
+    /**
+     * XML related constants.
+     */
+    struct XMLTOOL_API XMLConstants
+    {
+        /**  XML core namespace ("http://www.w3.org/XML/1998/namespace") */
+        static const XMLCh XML_NS[]; 
+
+        /** XML namespace prefix for special xml attributes ("xml") */
+        static const XMLCh XML_PREFIX[];
+    
+        /**  XML namespace for xmlns attributes ("http://www.w3.org/2000/xmlns/") */
+        static const XMLCh XMLNS_NS[];
+        
+        /** XML namespace prefix for xmlns attributes ("xmlns") */
+        static const XMLCh XMLNS_PREFIX[];
+    
+        /**  XML Schema namespace ("http://www.w3.org/2001/XMLSchema") */
+        static const XMLCh XSD_NS[];
+        
+        /**  XML Schema QName prefix ("xs") */
+        static const XMLCh XSD_PREFIX[];
+    
+        /**  XML Schema Instance namespace ("http://www.w3.org/2001/XMLSchema-instance") */
+        static const XMLCh XSI_NS[];
+        
+        /**  XML Schema Instance QName prefix ("xsi") */
+        static const XMLCh XSI_PREFIX[];
+        
+        /**  XML Signature namespace ("http://www.w3.org/2000/09/xmldsig#") */
+        static const XMLCh XMLSIG_NS[];
+        
+        /**  XML Signature QName prefix ("ds") */
+        static const XMLCh XMLSIG_PREFIX[];
+        
+        /**  XML Encryption namespace ("http://www.w3.org/2001/04/xmlenc#") */
+        static const XMLCh XMLENC_NS[];
+        
+        /**  XML Encryption QName prefix ("xenc") */
+        static const XMLCh XMLENC_PREFIX[];
+        
+        /**  SOAP 1.1 Envelope XML namespace ("http://schemas.xmlsoap.org/soap/envelope/") */
+        static const XMLCh SOAP11ENV_NS[]; 
+
+        /**  SOAP 1.1 Envelope QName prefix ("S") */
+        static const XMLCh SOAP11ENV_PREFIX[];
+    
+        /**  XML Tooling namespace ("http://www.opensaml.org/xmltooling") */
+        static const XMLCh XMLTOOLING_NS[];
+
+        /**  XML "true" boolean constant */
+        static const XMLCh XML_TRUE[];
+
+        /**  XML "false" boolean constant */
+        static const XMLCh XML_FALSE[];
+
+        /**  XML "1" boolean constant */
+        static const XMLCh XML_ONE[];
+
+        /**  XML "0" boolean constant */
+        static const XMLCh XML_ZERO[];
+        
+        /** Enumerations of the different values of a boolean attribute or element */
+        enum xmltooling_bool_t {
+            XML_BOOL_NULL,
+            XML_BOOL_TRUE,
+            XML_BOOL_FALSE,
+            XML_BOOL_ONE,
+            XML_BOOL_ZERO
+        };
+    };
+
+};
+
+#endif /* __xmltooling_xmlconstants_h__ */
index 1bf8d5d..9411daa 100644 (file)
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * XMLHelper.cpp\r
- * \r
- * A helper class for working with W3C DOM objects. \r
- */\r
-\r
-#include "internal.h"\r
-#include "exceptions.h"\r
-#include "util/XMLHelper.h"\r
-#include "util/XMLConstants.h"\r
-\r
-#include <xercesc/framework/MemBufFormatTarget.hpp>\r
-#include <xercesc/util/XMLUniDefs.hpp>\r
-\r
-using namespace xmltooling;\r
-\r
-static const XMLCh type[]={chLatin_t, chLatin_y, chLatin_p, chLatin_e, chNull };\r
-    \r
-bool XMLHelper::hasXSIType(const DOMElement* e)\r
-{\r
-    if (e) {\r
-        if (e->hasAttributeNS(XMLConstants::XSI_NS, type)) {\r
-            return true;\r
-        }\r
-    }\r
-\r
-    return false;\r
-}\r
-\r
-QName* XMLHelper::getXSIType(const DOMElement* e)\r
-{\r
-    DOMAttr* attribute = e->getAttributeNodeNS(XMLConstants::XSI_NS, type);\r
-    if (attribute) {\r
-        const XMLCh* attributeValue = attribute->getTextContent();\r
-        if (attributeValue && *attributeValue) {\r
-            int i;\r
-            if ((i=XMLString::indexOf(attributeValue,chColon))>0) {\r
-                XMLCh* prefix=new XMLCh[i+1];\r
-                XMLString::subString(prefix,attributeValue,0,i);\r
-                prefix[i]=chNull;\r
-                QName* ret=new QName(e->lookupNamespaceURI(prefix), attributeValue + i + 1, prefix);\r
-                delete[] prefix;\r
-                return ret;\r
-            }\r
-            else {\r
-                return new QName(e->lookupNamespaceURI(&chNull), attributeValue);\r
-            }\r
-        }\r
-    }\r
-\r
-    return NULL;\r
-}\r
-\r
-DOMAttr* XMLHelper::getIdAttribute(const DOMElement* domElement)\r
-{\r
-    if(!domElement->hasAttributes()) {\r
-        return NULL;\r
-    }\r
-    \r
-    DOMNamedNodeMap* attributes = domElement->getAttributes();\r
-    DOMAttr* attribute;\r
-    for(XMLSize_t i = 0; i < attributes->getLength(); i++) {\r
-        attribute = static_cast<DOMAttr*>(attributes->item(i));\r
-        if(attribute->isId()) {\r
-            return attribute;\r
-        }\r
-    }\r
-    \r
-    return NULL;\r
-}\r
-\r
-QName* XMLHelper::getNodeQName(const DOMNode* domNode)\r
-{\r
-    if (domNode)\r
-        return new QName(domNode->getNamespaceURI(), domNode->getLocalName(), domNode->getPrefix());\r
-    return NULL; \r
-}\r
-\r
-QName* XMLHelper::getAttributeValueAsQName(const DOMAttr* attribute)\r
-{\r
-    if (!attribute)\r
-        return NULL;\r
-    \r
-    int i;\r
-    const XMLCh* attributeValue=attribute->getTextContent();\r
-    if (attributeValue && (i=XMLString::indexOf(attributeValue,chColon))>0) {\r
-        XMLCh* prefix=new XMLCh[i+1];\r
-        XMLString::subString(prefix,attributeValue,0,i);\r
-        prefix[i]=chNull;\r
-        QName* ret=new QName(attribute->lookupNamespaceURI(prefix), attributeValue + i + 1, prefix);\r
-        delete[] prefix;\r
-        return ret;\r
-    }\r
-    \r
-    return new QName(attribute->lookupNamespaceURI(NULL), attributeValue);\r
-}\r
-\r
-DOMElement* XMLHelper::appendChildElement(DOMElement* parentElement, DOMElement* childElement)\r
-{\r
-    DOMDocument* parentDocument = parentElement->getOwnerDocument();\r
-    if (childElement->getOwnerDocument() != parentDocument) {\r
-        childElement = static_cast<DOMElement*>(parentDocument->importNode(childElement, true));\r
-    }\r
-\r
-    parentElement->appendChild(childElement);\r
-    return childElement;\r
-}\r
-\r
-const XMLCh* XMLHelper::getTextContent(const DOMElement* e)\r
-{\r
-    DOMNode* child=e->getFirstChild();\r
-    while (child) {\r
-        if (child->getNodeType()==DOMNode::TEXT_NODE)\r
-            return child->getNodeValue();\r
-        child=child->getNextSibling();\r
-    }\r
-    return NULL;\r
-}\r
-\r
-DOMElement* XMLHelper::getFirstChildElement(const DOMNode* n, const XMLCh* localName)\r
-{\r
-    DOMNode* child = n->getFirstChild();\r
-    while (child && child->getNodeType() != DOMNode::ELEMENT_NODE)\r
-        child = child->getNextSibling();\r
-    if (child && localName) {\r
-        if (!XMLString::equals(localName,child->getLocalName()))\r
-            return getNextSiblingElement(child, localName);\r
-    }\r
-    return static_cast<DOMElement*>(child);\r
-}    \r
-\r
-DOMElement* XMLHelper::getLastChildElement(const DOMNode* n, const XMLCh* localName)\r
-{\r
-    DOMNode* child = n->getLastChild();\r
-    while (child && child->getNodeType() != DOMNode::ELEMENT_NODE)\r
-        child = child->getPreviousSibling();\r
-    if (child && localName) {\r
-        if (!XMLString::equals(localName,child->getLocalName()))\r
-            return getPreviousSiblingElement(child, localName);\r
-    }\r
-    return static_cast<DOMElement*>(child);\r
-}    \r
-\r
-DOMElement* XMLHelper::getFirstChildElement(const DOMNode* n, const XMLCh* ns, const XMLCh* localName)\r
-{\r
-    DOMElement* e = getFirstChildElement(n, localName);\r
-    while (e && !XMLString::equals(e->getNamespaceURI(),ns))\r
-        e = getNextSiblingElement(e, localName);\r
-    return e;\r
-}\r
-\r
-DOMElement* XMLHelper::getLastChildElement(const DOMNode* n, const XMLCh* ns, const XMLCh* localName)\r
-{\r
-    DOMElement* e = getLastChildElement(n, localName);\r
-    while (e && !XMLString::equals(e->getNamespaceURI(),ns))\r
-        e = getPreviousSiblingElement(e, localName);\r
-    return e;\r
-}\r
-\r
-DOMElement* XMLHelper::getNextSiblingElement(const DOMNode* n, const XMLCh* localName)\r
-{\r
-    DOMNode* sib = n->getNextSibling();\r
-    while (sib && sib->getNodeType() != DOMNode::ELEMENT_NODE)\r
-        sib = sib->getNextSibling();\r
-    if (sib && localName) {\r
-        if (!XMLString::equals(localName,sib->getLocalName()))\r
-            return getNextSiblingElement(sib, localName);\r
-    }   \r
-    return static_cast<DOMElement*>(sib);\r
-}\r
-\r
-DOMElement* XMLHelper::getPreviousSiblingElement(const DOMNode* n, const XMLCh* localName)\r
-{\r
-    DOMNode* sib = n->getPreviousSibling();\r
-    while (sib && sib->getNodeType() != DOMNode::ELEMENT_NODE)\r
-        sib = sib->getPreviousSibling();\r
-    if (sib && localName) {\r
-        if (!XMLString::equals(localName,sib->getLocalName()))\r
-            return getPreviousSiblingElement(sib, localName);\r
-    }   \r
-    return static_cast<DOMElement*>(sib);\r
-}\r
-\r
-DOMElement* XMLHelper::getNextSiblingElement(const DOMNode* n, const XMLCh* ns, const XMLCh* localName)\r
-{\r
-    DOMElement* e = getNextSiblingElement(n, localName);\r
-    while (e && !XMLString::equals(e->getNamespaceURI(),ns))\r
-        e = getNextSiblingElement(e, localName);\r
-    return e;\r
-}\r
-\r
-DOMElement* XMLHelper::getPreviousSiblingElement(const DOMNode* n, const XMLCh* ns, const XMLCh* localName)\r
-{\r
-    DOMElement* e = getPreviousSiblingElement(n, localName);\r
-    while (e && !XMLString::equals(e->getNamespaceURI(),ns))\r
-        e = getPreviousSiblingElement(e, localName);\r
-    return e;\r
-}\r
-\r
-void XMLHelper::serialize(const DOMElement* e, std::string& buf)\r
-{\r
-    static const XMLCh impltype[] = { chLatin_L, chLatin_S, chNull };\r
-    static const XMLCh UTF8[]={ chLatin_U, chLatin_T, chLatin_F, chDigit_8, chNull };\r
-    DOMImplementation* impl=DOMImplementationRegistry::getDOMImplementation(impltype);\r
-    DOMWriter* serializer=(static_cast<DOMImplementationLS*>(impl))->createDOMWriter();\r
-    XercesJanitor<DOMWriter> janitor(serializer);\r
-    serializer->setEncoding(UTF8);\r
-    MemBufFormatTarget target;\r
-    if (!serializer->writeNode(&target,*e))\r
-        throw XMLParserException("unable to serialize XML");\r
-    buf.erase();\r
-    buf.append(reinterpret_cast<const char*>(target.getRawBuffer()),target.getLen());\r
-}\r
+/*
+ *  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.
+ */
+
+/**
+ * XMLHelper.cpp
+ * 
+ * A helper class for working with W3C DOM objects. 
+ */
+
+#include "internal.h"
+#include "exceptions.h"
+#include "util/XMLHelper.h"
+#include "util/XMLConstants.h"
+
+#include <xercesc/framework/MemBufFormatTarget.hpp>
+#include <xercesc/util/XMLUniDefs.hpp>
+
+using namespace xmltooling;
+
+static const XMLCh type[]={chLatin_t, chLatin_y, chLatin_p, chLatin_e, chNull };
+    
+bool XMLHelper::hasXSIType(const DOMElement* e)
+{
+    if (e) {
+        if (e->hasAttributeNS(XMLConstants::XSI_NS, type)) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+QName* XMLHelper::getXSIType(const DOMElement* e)
+{
+    DOMAttr* attribute = e->getAttributeNodeNS(XMLConstants::XSI_NS, type);
+    if (attribute) {
+        const XMLCh* attributeValue = attribute->getTextContent();
+        if (attributeValue && *attributeValue) {
+            int i;
+            if ((i=XMLString::indexOf(attributeValue,chColon))>0) {
+                XMLCh* prefix=new XMLCh[i+1];
+                XMLString::subString(prefix,attributeValue,0,i);
+                prefix[i]=chNull;
+                QName* ret=new QName(e->lookupNamespaceURI(prefix), attributeValue + i + 1, prefix);
+                delete[] prefix;
+                return ret;
+            }
+            else {
+                return new QName(e->lookupNamespaceURI(&chNull), attributeValue);
+            }
+        }
+    }
+
+    return NULL;
+}
+
+DOMAttr* XMLHelper::getIdAttribute(const DOMElement* domElement)
+{
+    if(!domElement->hasAttributes()) {
+        return NULL;
+    }
+    
+    DOMNamedNodeMap* attributes = domElement->getAttributes();
+    DOMAttr* attribute;
+    for(XMLSize_t i = 0; i < attributes->getLength(); i++) {
+        attribute = static_cast<DOMAttr*>(attributes->item(i));
+        if(attribute->isId()) {
+            return attribute;
+        }
+    }
+    
+    return NULL;
+}
+
+QName* XMLHelper::getNodeQName(const DOMNode* domNode)
+{
+    if (domNode)
+        return new QName(domNode->getNamespaceURI(), domNode->getLocalName(), domNode->getPrefix());
+    return NULL; 
+}
+
+QName* XMLHelper::getAttributeValueAsQName(const DOMAttr* attribute)
+{
+    if (!attribute)
+        return NULL;
+    
+    int i;
+    const XMLCh* attributeValue=attribute->getTextContent();
+    if (attributeValue && (i=XMLString::indexOf(attributeValue,chColon))>0) {
+        XMLCh* prefix=new XMLCh[i+1];
+        XMLString::subString(prefix,attributeValue,0,i);
+        prefix[i]=chNull;
+        QName* ret=new QName(attribute->lookupNamespaceURI(prefix), attributeValue + i + 1, prefix);
+        delete[] prefix;
+        return ret;
+    }
+    
+    return new QName(attribute->lookupNamespaceURI(NULL), attributeValue);
+}
+
+DOMElement* XMLHelper::appendChildElement(DOMElement* parentElement, DOMElement* childElement)
+{
+    DOMDocument* parentDocument = parentElement->getOwnerDocument();
+    if (childElement->getOwnerDocument() != parentDocument) {
+        childElement = static_cast<DOMElement*>(parentDocument->importNode(childElement, true));
+    }
+
+    parentElement->appendChild(childElement);
+    return childElement;
+}
+
+const XMLCh* XMLHelper::getTextContent(const DOMElement* e)
+{
+    DOMNode* child=e->getFirstChild();
+    while (child) {
+        if (child->getNodeType()==DOMNode::TEXT_NODE)
+            return child->getNodeValue();
+        child=child->getNextSibling();
+    }
+    return NULL;
+}
+
+DOMElement* XMLHelper::getFirstChildElement(const DOMNode* n, const XMLCh* localName)
+{
+    DOMNode* child = n->getFirstChild();
+    while (child && child->getNodeType() != DOMNode::ELEMENT_NODE)
+        child = child->getNextSibling();
+    if (child && localName) {
+        if (!XMLString::equals(localName,child->getLocalName()))
+            return getNextSiblingElement(child, localName);
+    }
+    return static_cast<DOMElement*>(child);
+}    
+
+DOMElement* XMLHelper::getLastChildElement(const DOMNode* n, const XMLCh* localName)
+{
+    DOMNode* child = n->getLastChild();
+    while (child && child->getNodeType() != DOMNode::ELEMENT_NODE)
+        child = child->getPreviousSibling();
+    if (child && localName) {
+        if (!XMLString::equals(localName,child->getLocalName()))
+            return getPreviousSiblingElement(child, localName);
+    }
+    return static_cast<DOMElement*>(child);
+}    
+
+DOMElement* XMLHelper::getFirstChildElement(const DOMNode* n, const XMLCh* ns, const XMLCh* localName)
+{
+    DOMElement* e = getFirstChildElement(n, localName);
+    while (e && !XMLString::equals(e->getNamespaceURI(),ns))
+        e = getNextSiblingElement(e, localName);
+    return e;
+}
+
+DOMElement* XMLHelper::getLastChildElement(const DOMNode* n, const XMLCh* ns, const XMLCh* localName)
+{
+    DOMElement* e = getLastChildElement(n, localName);
+    while (e && !XMLString::equals(e->getNamespaceURI(),ns))
+        e = getPreviousSiblingElement(e, localName);
+    return e;
+}
+
+DOMElement* XMLHelper::getNextSiblingElement(const DOMNode* n, const XMLCh* localName)
+{
+    DOMNode* sib = n->getNextSibling();
+    while (sib && sib->getNodeType() != DOMNode::ELEMENT_NODE)
+        sib = sib->getNextSibling();
+    if (sib && localName) {
+        if (!XMLString::equals(localName,sib->getLocalName()))
+            return getNextSiblingElement(sib, localName);
+    }   
+    return static_cast<DOMElement*>(sib);
+}
+
+DOMElement* XMLHelper::getPreviousSiblingElement(const DOMNode* n, const XMLCh* localName)
+{
+    DOMNode* sib = n->getPreviousSibling();
+    while (sib && sib->getNodeType() != DOMNode::ELEMENT_NODE)
+        sib = sib->getPreviousSibling();
+    if (sib && localName) {
+        if (!XMLString::equals(localName,sib->getLocalName()))
+            return getPreviousSiblingElement(sib, localName);
+    }   
+    return static_cast<DOMElement*>(sib);
+}
+
+DOMElement* XMLHelper::getNextSiblingElement(const DOMNode* n, const XMLCh* ns, const XMLCh* localName)
+{
+    DOMElement* e = getNextSiblingElement(n, localName);
+    while (e && !XMLString::equals(e->getNamespaceURI(),ns))
+        e = getNextSiblingElement(e, localName);
+    return e;
+}
+
+DOMElement* XMLHelper::getPreviousSiblingElement(const DOMNode* n, const XMLCh* ns, const XMLCh* localName)
+{
+    DOMElement* e = getPreviousSiblingElement(n, localName);
+    while (e && !XMLString::equals(e->getNamespaceURI(),ns))
+        e = getPreviousSiblingElement(e, localName);
+    return e;
+}
+
+void XMLHelper::serialize(const DOMElement* e, std::string& buf)
+{
+    static const XMLCh impltype[] = { chLatin_L, chLatin_S, chNull };
+    static const XMLCh UTF8[]={ chLatin_U, chLatin_T, chLatin_F, chDigit_8, chNull };
+    DOMImplementation* impl=DOMImplementationRegistry::getDOMImplementation(impltype);
+    DOMWriter* serializer=(static_cast<DOMImplementationLS*>(impl))->createDOMWriter();
+    XercesJanitor<DOMWriter> janitor(serializer);
+    serializer->setEncoding(UTF8);
+    MemBufFormatTarget target;
+    if (!serializer->writeNode(&target,*e))
+        throw XMLParserException("unable to serialize XML");
+    buf.erase();
+    buf.append(reinterpret_cast<const char*>(target.getRawBuffer()),target.getLen());
+}
index df33c63..868d00f 100644 (file)
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file XMLHelper.h\r
- * \r
- * A helper class for working with W3C DOM objects. \r
- */\r
-\r
-#ifndef __xmltooling_xmlhelper_h__\r
-#define __xmltooling_xmlhelper_h__\r
-\r
-#include <xmltooling/QName.h>\r
-#include <xercesc/dom/DOM.hpp>\r
-\r
-using namespace xercesc;\r
-\r
-namespace xmltooling {\r
-    \r
-    /**\r
-     * RAII wrapper for Xerces resources.\r
-     */\r
-    template<class T> class XercesJanitor\r
-    {\r
-        MAKE_NONCOPYABLE(XercesJanitor);\r
-        T* m_held;\r
-    public:\r
-        XercesJanitor(T* resource) : m_held(resource) {}\r
-        \r
-        ~XercesJanitor() {\r
-            if (m_held)\r
-                m_held->release();\r
-        }\r
-        \r
-        /**\r
-         * Returns resource held by this object and releases it to the caller.\r
-         * \r
-         * @return  the resource held or NULL\r
-         */\r
-        T* release() {\r
-            T* ret=m_held;\r
-            m_held=NULL;\r
-            return ret;\r
-        }\r
-    };\r
-    \r
-    /**\r
-     * A helper class for working with W3C DOM objects. \r
-     */\r
-    class XMLTOOL_API XMLHelper\r
-    {\r
-    public:\r
-        /**\r
-         * Checks if the given element has an xsi:type defined for it\r
-         * \r
-         * @param e the DOM element\r
-         * @return true if there is a type, false if not\r
-         */\r
-        static bool hasXSIType(const DOMElement* e);\r
-\r
-        /**\r
-         * Gets the XSI type for a given element if it has one.\r
-         * \r
-         * @param e the element\r
-         * @return the type or null\r
-         */\r
-        static QName* getXSIType(const DOMElement* e);\r
-\r
-        /**\r
-         * Gets the ID attribute of a DOM element.\r
-         * \r
-         * @param domElement the DOM element\r
-         * @return the ID attribute or null if there isn't one\r
-         */\r
-        static DOMAttr* getIdAttribute(const DOMElement* domElement);\r
-\r
-        /**\r
-         * Gets the QName for the given DOM node.\r
-         * \r
-         * @param domNode the DOM node\r
-         * @return the QName for the element or null if the element was null\r
-         */\r
-        static QName* getNodeQName(const DOMNode* domNode);\r
-\r
-        /**\r
-         * Constructs a QName from an attribute's value.\r
-         * \r
-         * @param attribute the attribute with a QName value\r
-         * @return a QName from an attribute's value, or null if the given attribute is null\r
-         */\r
-        static QName* getAttributeValueAsQName(const DOMAttr* attribute);\r
-\r
-        /**\r
-         * Appends the child Element to the parent Element,\r
-         * importing the child Element into the parent's Document if needed.\r
-         * \r
-         * @param parentElement the parent Element\r
-         * @param childElement the child Element\r
-         * @return the child Element that was added (may be an imported copy)\r
-         */\r
-        static DOMElement* appendChildElement(DOMElement* parentElement, DOMElement* childElement);\r
-        \r
-        /**\r
-         * Checks the qualified name of a node.\r
-         * \r
-         * @param n     node to check\r
-         * @param ns    namespace to compare with\r
-         * @param local local name to compare with\r
-         * @return  true iff the node's qualified name matches the other parameters\r
-         */\r
-        static bool isNodeNamed(const DOMNode* n, const XMLCh* ns, const XMLCh* local) {\r
-            return (n && XMLString::equals(local,n->getLocalName()) && XMLString::equals(ns,n->getNamespaceURI()));\r
-        }\r
-\r
-        /**\r
-         * Returns the first matching child element of the node if any.\r
-         * \r
-         * @param n         node to check\r
-         * @param localName local name to compare with or NULL for any match\r
-         * @return  the first matching child node of type Element, or NULL\r
-         */\r
-        static DOMElement* getFirstChildElement(const DOMNode* n, const XMLCh* localName=NULL);\r
-        \r
-        /**\r
-         * Returns the last matching child element of the node if any.\r
-         * \r
-         * @param n     node to check\r
-         * @param localName local name to compare with or NULL for any match\r
-         * @return  the last matching child node of type Element, or NULL\r
-         */\r
-        static DOMElement* getLastChildElement(const DOMNode* n, const XMLCh* localName=NULL);\r
-        \r
-        /**\r
-         * Returns the next matching sibling element of the node if any.\r
-         * \r
-         * @param n     node to check\r
-         * @param localName local name to compare with or NULL for any match\r
-         * @return  the next matching sibling node of type Element, or NULL\r
-         */\r
-        static DOMElement* getNextSiblingElement(const DOMNode* n, const XMLCh* localName=NULL);\r
-        \r
-        /**\r
-         * Returns the previous matching sibling element of the node if any.\r
-         * \r
-         * @param n     node to check\r
-         * @param localName local name to compare with or NULL for any match\r
-         * @return  the previous matching sibling node of type Element, or NULL\r
-         */\r
-        static DOMElement* getPreviousSiblingElement(const DOMNode* n, const XMLCh* localName=NULL);\r
-        \r
-        /**\r
-         * Returns the first matching child element of the node if any.\r
-         * \r
-         * @param n         node to check\r
-         * @param ns        namespace to compare with\r
-         * @param localName local name to compare with\r
-         * @return  the first matching child node of type Element, or NULL\r
-         */\r
-        static DOMElement* getFirstChildElement(const DOMNode* n, const XMLCh* ns, const XMLCh* localName);\r
-        \r
-        /**\r
-         * Returns the last matching child element of the node if any.\r
-         * \r
-         * @param n         node to check\r
-         * @param ns        namespace to compare with\r
-         * @param localName local name to compare with\r
-         * @return  the last matching child node of type Element, or NULL\r
-         */\r
-        static DOMElement* getLastChildElement(const DOMNode* n, const XMLCh* ns, const XMLCh* localName);\r
-        \r
-        /**\r
-         * Returns the next matching sibling element of the node if any.\r
-         * \r
-         * @param n         node to check\r
-         * @param ns        namespace to compare with\r
-         * @param localName local name to compare with\r
-         * @return  the next matching sibling node of type Element, or NULL\r
-         */\r
-        static DOMElement* getNextSiblingElement(const DOMNode* n, const XMLCh* ns, const XMLCh* localName);\r
-        \r
-        /**\r
-         * Returns the previous matching sibling element of the node if any.\r
-         * \r
-         * @param n         node to check\r
-         * @param ns        namespace to compare with\r
-         * @param localName local name to compare with\r
-         * @return  the previous matching sibling node of type Element, or NULL\r
-         */\r
-        static DOMElement* getPreviousSiblingElement(const DOMNode* n, const XMLCh* ns, const XMLCh* localName);\r
-\r
-        /**\r
-         * Returns the content of the first Text node found in the element, if any.\r
-         * This is roughly similar to the DOM getTextContent function, but only\r
-         * examples the immediate children of the element.\r
-         *\r
-         * @param e     element to examine\r
-         * @return the content of the first Text node found, or NULL\r
-         */\r
-        static const XMLCh* getTextContent(const DOMElement* e);\r
-\r
-        /**\r
-         * Serializes the DOM Element provided into a buffer using UTF-8 encoding and\r
-         * the default XML serializer available. No manipulation or formatting is applied.\r
-         * \r
-         * @param e     element to serialize\r
-         * @param buf   buffer to serialize element into\r
-         */\r
-        static void serialize(const DOMElement* e, std::string& buf);\r
-    };\r
-\r
-};\r
-\r
-#endif /* __xmltooling_xmlhelper_h__ */\r
+/*
+ *  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.
+ */
+
+/**
+ * @file XMLHelper.h
+ * 
+ * A helper class for working with W3C DOM objects. 
+ */
+
+#ifndef __xmltooling_xmlhelper_h__
+#define __xmltooling_xmlhelper_h__
+
+#include <xmltooling/QName.h>
+#include <xercesc/dom/DOM.hpp>
+
+using namespace xercesc;
+
+namespace xmltooling {
+    
+    /**
+     * RAII wrapper for Xerces resources.
+     */
+    template<class T> class XercesJanitor
+    {
+        MAKE_NONCOPYABLE(XercesJanitor);
+        T* m_held;
+    public:
+        XercesJanitor(T* resource) : m_held(resource) {}
+        
+        ~XercesJanitor() {
+            if (m_held)
+                m_held->release();
+        }
+        
+        /**
+         * Returns resource held by this object and releases it to the caller.
+         * 
+         * @return  the resource held or NULL
+         */
+        T* release() {
+            T* ret=m_held;
+            m_held=NULL;
+            return ret;
+        }
+    };
+    
+    /**
+     * A helper class for working with W3C DOM objects. 
+     */
+    class XMLTOOL_API XMLHelper
+    {
+    public:
+        /**
+         * Checks if the given element has an xsi:type defined for it
+         * 
+         * @param e the DOM element
+         * @return true if there is a type, false if not
+         */
+        static bool hasXSIType(const DOMElement* e);
+
+        /**
+         * Gets the XSI type for a given element if it has one.
+         * 
+         * @param e the element
+         * @return the type or null
+         */
+        static QName* getXSIType(const DOMElement* e);
+
+        /**
+         * Gets the ID attribute of a DOM element.
+         * 
+         * @param domElement the DOM element
+         * @return the ID attribute or null if there isn't one
+         */
+        static DOMAttr* getIdAttribute(const DOMElement* domElement);
+
+        /**
+         * Gets the QName for the given DOM node.
+         * 
+         * @param domNode the DOM node
+         * @return the QName for the element or null if the element was null
+         */
+        static QName* getNodeQName(const DOMNode* domNode);
+
+        /**
+         * Constructs a QName from an attribute's value.
+         * 
+         * @param attribute the attribute with a QName value
+         * @return a QName from an attribute's value, or null if the given attribute is null
+         */
+        static QName* getAttributeValueAsQName(const DOMAttr* attribute);
+
+        /**
+         * Appends the child Element to the parent Element,
+         * importing the child Element into the parent's Document if needed.
+         * 
+         * @param parentElement the parent Element
+         * @param childElement the child Element
+         * @return the child Element that was added (may be an imported copy)
+         */
+        static DOMElement* appendChildElement(DOMElement* parentElement, DOMElement* childElement);
+        
+        /**
+         * Checks the qualified name of a node.
+         * 
+         * @param n     node to check
+         * @param ns    namespace to compare with
+         * @param local local name to compare with
+         * @return  true iff the node's qualified name matches the other parameters
+         */
+        static bool isNodeNamed(const DOMNode* n, const XMLCh* ns, const XMLCh* local) {
+            return (n && XMLString::equals(local,n->getLocalName()) && XMLString::equals(ns,n->getNamespaceURI()));
+        }
+
+        /**
+         * Returns the first matching child element of the node if any.
+         * 
+         * @param n         node to check
+         * @param localName local name to compare with or NULL for any match
+         * @return  the first matching child node of type Element, or NULL
+         */
+        static DOMElement* getFirstChildElement(const DOMNode* n, const XMLCh* localName=NULL);
+        
+        /**
+         * Returns the last matching child element of the node if any.
+         * 
+         * @param n     node to check
+         * @param localName local name to compare with or NULL for any match
+         * @return  the last matching child node of type Element, or NULL
+         */
+        static DOMElement* getLastChildElement(const DOMNode* n, const XMLCh* localName=NULL);
+        
+        /**
+         * Returns the next matching sibling element of the node if any.
+         * 
+         * @param n     node to check
+         * @param localName local name to compare with or NULL for any match
+         * @return  the next matching sibling node of type Element, or NULL
+         */
+        static DOMElement* getNextSiblingElement(const DOMNode* n, const XMLCh* localName=NULL);
+        
+        /**
+         * Returns the previous matching sibling element of the node if any.
+         * 
+         * @param n     node to check
+         * @param localName local name to compare with or NULL for any match
+         * @return  the previous matching sibling node of type Element, or NULL
+         */
+        static DOMElement* getPreviousSiblingElement(const DOMNode* n, const XMLCh* localName=NULL);
+        
+        /**
+         * Returns the first matching child element of the node if any.
+         * 
+         * @param n         node to check
+         * @param ns        namespace to compare with
+         * @param localName local name to compare with
+         * @return  the first matching child node of type Element, or NULL
+         */
+        static DOMElement* getFirstChildElement(const DOMNode* n, const XMLCh* ns, const XMLCh* localName);
+        
+        /**
+         * Returns the last matching child element of the node if any.
+         * 
+         * @param n         node to check
+         * @param ns        namespace to compare with
+         * @param localName local name to compare with
+         * @return  the last matching child node of type Element, or NULL
+         */
+        static DOMElement* getLastChildElement(const DOMNode* n, const XMLCh* ns, const XMLCh* localName);
+        
+        /**
+         * Returns the next matching sibling element of the node if any.
+         * 
+         * @param n         node to check
+         * @param ns        namespace to compare with
+         * @param localName local name to compare with
+         * @return  the next matching sibling node of type Element, or NULL
+         */
+        static DOMElement* getNextSiblingElement(const DOMNode* n, const XMLCh* ns, const XMLCh* localName);
+        
+        /**
+         * Returns the previous matching sibling element of the node if any.
+         * 
+         * @param n         node to check
+         * @param ns        namespace to compare with
+         * @param localName local name to compare with
+         * @return  the previous matching sibling node of type Element, or NULL
+         */
+        static DOMElement* getPreviousSiblingElement(const DOMNode* n, const XMLCh* ns, const XMLCh* localName);
+
+        /**
+         * Returns the content of the first Text node found in the element, if any.
+         * This is roughly similar to the DOM getTextContent function, but only
+         * examples the immediate children of the element.
+         *
+         * @param e     element to examine
+         * @return the content of the first Text node found, or NULL
+         */
+        static const XMLCh* getTextContent(const DOMElement* e);
+
+        /**
+         * Serializes the DOM Element provided into a buffer using UTF-8 encoding and
+         * the default XML serializer available. No manipulation or formatting is applied.
+         * 
+         * @param e     element to serialize
+         * @param buf   buffer to serialize element into
+         */
+        static void serialize(const DOMElement* e, std::string& buf);
+    };
+
+};
+
+#endif /* __xmltooling_xmlhelper_h__ */
index 58256bf..b56f6a7 100644 (file)
@@ -1,55 +1,55 @@
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file Validator.h\r
- * \r
- * Rules checking of XMLObjects \r
- */\r
-\r
-#ifndef __xmltooling_validator_h__\r
-#define __xmltooling_validator_h__\r
-\r
-#include <xmltooling/XMLObject.h>\r
-\r
-namespace xmltooling {\r
-\r
-    /**\r
-     * An interface for classes that implement rules for checking the \r
-     * validity of XMLObjects.\r
-     */\r
-    class XMLTOOL_API Validator\r
-    {\r
-    MAKE_NONCOPYABLE(Validator);\r
-    public:\r
-        virtual ~Validator() {}\r
-        \r
-        /**\r
-         * Checks to see if an XMLObject is valid.\r
-         * \r
-         * @param xmlObject the XMLObject to validate\r
-\r
-         * @throws ValidationException thrown if the element is not valid\r
-         */\r
-        virtual void validate(const XMLObject* xmlObject) const=0;\r
-\r
-    protected:\r
-        Validator() {}\r
-    };\r
-\r
-};\r
-\r
-#endif /* __xmltooling_validator_h__ */\r
+/*
+ *  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.
+ */
+
+/**
+ * @file Validator.h
+ * 
+ * Rules checking of XMLObjects 
+ */
+
+#ifndef __xmltooling_validator_h__
+#define __xmltooling_validator_h__
+
+#include <xmltooling/XMLObject.h>
+
+namespace xmltooling {
+
+    /**
+     * An interface for classes that implement rules for checking the 
+     * validity of XMLObjects.
+     */
+    class XMLTOOL_API Validator
+    {
+    MAKE_NONCOPYABLE(Validator);
+    public:
+        virtual ~Validator() {}
+        
+        /**
+         * Checks to see if an XMLObject is valid.
+         * 
+         * @param xmlObject the XMLObject to validate
+
+         * @throws ValidationException thrown if the element is not valid
+         */
+        virtual void validate(const XMLObject* xmlObject) const=0;
+
+    protected:
+        Validator() {}
+    };
+
+};
+
+#endif /* __xmltooling_validator_h__ */
index 742e4bd..1fb65d9 100644 (file)
@@ -1,67 +1,67 @@
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * ValidatorSuite.cpp\r
- * \r
- * Groups of rule checkers of XMLObjects based on type or element name. \r
- */\r
-\r
-#include "internal.h"\r
-#include "validation/ValidatorSuite.h"\r
-#include "util/XMLHelper.h"\r
-\r
-using namespace xmltooling;\r
-using namespace std;\r
-\r
-ValidatorSuite xmltooling::SchemaValidators("SchemaValidators");\r
-\r
-void ValidatorSuite::deregisterValidators(const QName& key)\r
-{\r
-    pair<multimap<QName,Validator*>::iterator,multimap<QName,Validator*>::iterator> range=m_map.equal_range(key);\r
-    for_each(range.first, range.second, xmltooling::cleanup_pair<QName,Validator>());\r
-    m_map.erase(range.first, range.second);\r
-}\r
-\r
-void ValidatorSuite::destroyValidators()\r
-{\r
-    for_each(m_map.begin(),m_map.end(),xmltooling::cleanup_pair<QName,Validator>());\r
-    m_map.clear();\r
-}\r
-\r
-void ValidatorSuite::validate(const XMLObject* xmlObject) const\r
-{\r
-    if (!xmlObject)\r
-        return;\r
-\r
-    pair<multimap<QName,Validator*>::const_iterator,multimap<QName,Validator*>::const_iterator> range;\r
-    if (xmlObject->getSchemaType()) {\r
-        range=m_map.equal_range(*(xmlObject->getSchemaType()));\r
-        while (range.first!=range.second) {\r
-            range.first->second->validate(xmlObject);\r
-            ++range.first;\r
-        }\r
-    }\r
-    range=m_map.equal_range(xmlObject->getElementQName());\r
-    while (range.first!=range.second) {\r
-        range.first->second->validate(xmlObject);\r
-        ++range.first;\r
-    }\r
-\r
-    const list<XMLObject*>& kids=xmlObject->getOrderedChildren();\r
-    for (list<XMLObject*>::const_iterator j=kids.begin(); j!=kids.end(); j++)\r
-        validate(*j);\r
-}\r
+/*
+ *  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.
+ */
+
+/**
+ * ValidatorSuite.cpp
+ * 
+ * Groups of rule checkers of XMLObjects based on type or element name. 
+ */
+
+#include "internal.h"
+#include "validation/ValidatorSuite.h"
+#include "util/XMLHelper.h"
+
+using namespace xmltooling;
+using namespace std;
+
+ValidatorSuite xmltooling::SchemaValidators("SchemaValidators");
+
+void ValidatorSuite::deregisterValidators(const QName& key)
+{
+    pair<multimap<QName,Validator*>::iterator,multimap<QName,Validator*>::iterator> range=m_map.equal_range(key);
+    for_each(range.first, range.second, xmltooling::cleanup_pair<QName,Validator>());
+    m_map.erase(range.first, range.second);
+}
+
+void ValidatorSuite::destroyValidators()
+{
+    for_each(m_map.begin(),m_map.end(),xmltooling::cleanup_pair<QName,Validator>());
+    m_map.clear();
+}
+
+void ValidatorSuite::validate(const XMLObject* xmlObject) const
+{
+    if (!xmlObject)
+        return;
+
+    pair<multimap<QName,Validator*>::const_iterator,multimap<QName,Validator*>::const_iterator> range;
+    if (xmlObject->getSchemaType()) {
+        range=m_map.equal_range(*(xmlObject->getSchemaType()));
+        while (range.first!=range.second) {
+            range.first->second->validate(xmlObject);
+            ++range.first;
+        }
+    }
+    range=m_map.equal_range(xmlObject->getElementQName());
+    while (range.first!=range.second) {
+        range.first->second->validate(xmlObject);
+        ++range.first;
+    }
+
+    const list<XMLObject*>& kids=xmlObject->getOrderedChildren();
+    for (list<XMLObject*>::const_iterator j=kids.begin(); j!=kids.end(); j++)
+        validate(*j);
+}
index cea0693..9fc63a6 100644 (file)
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file ValidatorSuite.h\r
- * \r
- * Groups of rule checkers of XMLObjects based on type or element name. \r
- */\r
-\r
-#ifndef __xmltooling_valsuite_h__\r
-#define __xmltooling_valsuite_h__\r
-\r
-#include <xmltooling/QName.h>\r
-#include <xmltooling/validation/Validator.h>\r
-\r
-#include <map>\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( push )\r
-    #pragma warning( disable : 4250 4251 )\r
-#endif\r
-\r
-namespace xmltooling {\r
-\r
-    /**\r
-     * A collection of validators that can be applied to an XMLObject and its children. These collections can represent\r
-     * usage specific checks, such as those outlined in schemas or profiles of specific XML specifications.\r
-     * \r
-     * Registered Validators must be stateless. Validators are fetched based on schema type and\r
-     * element name, in that order.\r
-     */\r
-    class XMLTOOL_API ValidatorSuite\r
-    {\r
-    MAKE_NONCOPYABLE(ValidatorSuite);\r
-    public:\r
-        /**\r
-         * Creates a new suite.\r
-         * \r
-         * @param id    an identifier for the suite\r
-         */\r
-        ValidatorSuite(const char* id) : m_id(id) {}\r
-        \r
-        ~ValidatorSuite() {\r
-            destroyValidators();\r
-        }\r
-\r
-        /**\r
-         * Gets a unique ID for this suite.\r
-         * \r
-         * @return a unique ID for this suite\r
-         */\r
-        const char* getId() {\r
-            return m_id.c_str();\r
-        }\r
-\r
-        /**\r
-         * Evaluates the registered validators against the given XMLObject and it's children.\r
-         * \r
-         * @param xmlObject the XMLObject tree to validate\r
-         * \r
-         * @throws ValidationException thrown if the element tree is not valid\r
-         */\r
-        void validate(const XMLObject* xmlObject) const;\r
-\r
-        /**\r
-         * Registers a new validator for the given key.\r
-         * \r
-         * @param key       the key used to retrieve the validator\r
-         * @param validator the validator\r
-         */\r
-        void registerValidator(const QName& key, Validator* validator) {\r
-            m_map.insert(std::make_pair(key,validator));\r
-        }\r
-\r
-        /**\r
-         * Deregisters validators.\r
-         * \r
-         * @param key       the key for the validators to be deregistered\r
-         */\r
-        void deregisterValidators(const QName& key);\r
-\r
-        /**\r
-         * Unregisters and destroys all registered validators. \r
-         */\r
-        void destroyValidators();\r
-\r
-    private:\r
-        std::string m_id;\r
-        std::multimap<QName,Validator*> m_map;\r
-    };\r
-\r
-    /**\r
-     * Validator suite for schema-style structural validation.\r
-     * \r
-     * This is <strong>NOT</strong> a comprehensive replacement for real\r
-     * schema validation, but it does basic structural checking of overall\r
-     * element relationships and some basic attribute presence checking.\r
-     */\r
-    extern XMLTOOL_API xmltooling::ValidatorSuite SchemaValidators;\r
-    \r
-};\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( pop )\r
-#endif\r
-\r
-#endif /* __xmltooling_valsuite_h__ */\r
+/*
+ *  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.
+ */
+
+/**
+ * @file ValidatorSuite.h
+ * 
+ * Groups of rule checkers of XMLObjects based on type or element name. 
+ */
+
+#ifndef __xmltooling_valsuite_h__
+#define __xmltooling_valsuite_h__
+
+#include <xmltooling/QName.h>
+#include <xmltooling/validation/Validator.h>
+
+#include <map>
+
+#if defined (_MSC_VER)
+    #pragma warning( push )
+    #pragma warning( disable : 4250 4251 )
+#endif
+
+namespace xmltooling {
+
+    /**
+     * A collection of validators that can be applied to an XMLObject and its children. These collections can represent
+     * usage specific checks, such as those outlined in schemas or profiles of specific XML specifications.
+     * 
+     * Registered Validators must be stateless. Validators are fetched based on schema type and
+     * element name, in that order.
+     */
+    class XMLTOOL_API ValidatorSuite
+    {
+    MAKE_NONCOPYABLE(ValidatorSuite);
+    public:
+        /**
+         * Creates a new suite.
+         * 
+         * @param id    an identifier for the suite
+         */
+        ValidatorSuite(const char* id) : m_id(id) {}
+        
+        ~ValidatorSuite() {
+            destroyValidators();
+        }
+
+        /**
+         * Gets a unique ID for this suite.
+         * 
+         * @return a unique ID for this suite
+         */
+        const char* getId() {
+            return m_id.c_str();
+        }
+
+        /**
+         * Evaluates the registered validators against the given XMLObject and it's children.
+         * 
+         * @param xmlObject the XMLObject tree to validate
+         * 
+         * @throws ValidationException thrown if the element tree is not valid
+         */
+        void validate(const XMLObject* xmlObject) const;
+
+        /**
+         * Registers a new validator for the given key.
+         * 
+         * @param key       the key used to retrieve the validator
+         * @param validator the validator
+         */
+        void registerValidator(const QName& key, Validator* validator) {
+            m_map.insert(std::make_pair(key,validator));
+        }
+
+        /**
+         * Deregisters validators.
+         * 
+         * @param key       the key for the validators to be deregistered
+         */
+        void deregisterValidators(const QName& key);
+
+        /**
+         * Unregisters and destroys all registered validators. 
+         */
+        void destroyValidators();
+
+    private:
+        std::string m_id;
+        std::multimap<QName,Validator*> m_map;
+    };
+
+    /**
+     * Validator suite for schema-style structural validation.
+     * 
+     * This is <strong>NOT</strong> a comprehensive replacement for real
+     * schema validation, but it does basic structural checking of overall
+     * element relationships and some basic attribute presence checking.
+     */
+    extern XMLTOOL_API xmltooling::ValidatorSuite SchemaValidators;
+    
+};
+
+#if defined (_MSC_VER)
+    #pragma warning( pop )
+#endif
+
+#endif /* __xmltooling_valsuite_h__ */
index 21bc63b..a399a24 100644 (file)
@@ -1,74 +1,74 @@
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * version.h\r
- * \r
- * Library version macros and constants \r
- */\r
-\r
-#if !defined(__xmltooling_version_h__)\r
-#define __xmltooling_version_h__\r
-\r
-// This is all based on Xerces, on the theory it might be useful to\r
-// support this kind of stuff in the future. If they ever yank some\r
-// of this stuff, it can be copied into here.\r
-\r
-#include <xercesc/util/XercesVersion.hpp>\r
-\r
-// ---------------------------------------------------------------------------\r
-// V E R S I O N   S P E C I F I C A T I O N\r
-\r
-/**\r
- * MODIFY THESE NUMERIC VALUES TO COINCIDE WITH XMLTOOLING VERSION\r
- * AND DO NOT MODIFY ANYTHING ELSE IN THIS VERSION HEADER FILE\r
- */\r
-\r
-#define XMLTOOLING_VERSION_MAJOR 1\r
-#define XMLTOOLING_VERSION_MINOR 0\r
-#define XMLTOOLING_VERSION_REVISION 0\r
-\r
-/** DO NOT MODIFY BELOW THIS LINE */\r
-\r
-/**\r
- * MAGIC THAT AUTOMATICALLY GENERATES THE FOLLOWING:\r
- *\r
- *     gXMLToolingVersionStr, gXMLToolingFullVersionStr, gXMLToolingMajVersion, gXMLToolingMinVersion, gXMLToolingRevision\r
- */\r
-\r
-// ---------------------------------------------------------------------------\r
-// V E R S I O N   I N F O R M A T I O N\r
-\r
-// XMLTooling version strings; these particular macros cannot be used for\r
-// conditional compilation as they are not numeric constants\r
-\r
-#define XMLTOOLING_FULLVERSIONSTR INVK_CAT3_SEP_UNDERSCORE(XMLTOOLING_VERSION_MAJOR,XMLTOOLING_VERSION_MINOR,XMLTOOLING_VERSION_REVISION)\r
-#define XMLTOOLING_FULLVERSIONDOT INVK_CAT3_SEP_PERIOD(XMLTOOLING_VERSION_MAJOR,XMLTOOLING_VERSION_MINOR,XMLTOOLING_VERSION_REVISION)\r
-#define XMLTOOLING_FULLVERSIONNUM INVK_CAT3_SEP_NIL(XMLTOOLING_VERSION_MAJOR,XMLTOOLING_VERSION_MINOR,XMLTOOLING_VERSION_REVISION)\r
-#define XMLTOOLING_VERSIONSTR     INVK_CAT2_SEP_UNDERSCORE(XMLTOOLING_VERSION_MAJOR,XMLTOOLING_VERSION_MINOR)\r
-\r
-const char* const    gXMLToolingVersionStr = XMLTOOLING_VERSIONSTR;\r
-const char* const    gXMLToolingFullVersionStr = XMLTOOLING_FULLVERSIONSTR;\r
-const unsigned int   gXMLToolingMajVersion = XMLTOOLING_VERSION_MAJOR;\r
-const unsigned int   gXMLToolingMinVersion = XMLTOOLING_VERSION_MINOR;\r
-const unsigned int   gXMLToolingRevision   = XMLTOOLING_VERSION_REVISION;\r
-\r
-// XMLTooling version numeric constants that can be used for conditional\r
-// compilation purposes.\r
-\r
-#define _XMLTOOLING_VERSION CALC_EXPANDED_FORM (XMLTOOLING_VERSION_MAJOR,XMLTOOLING_VERSION_MINOR,XMLTOOLING_VERSION_REVISION)\r
-\r
-#endif // __xmltooling_version_h__\r
+/*
+ *  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.
+ */
+
+/**
+ * version.h
+ * 
+ * Library version macros and constants 
+ */
+
+#if !defined(__xmltooling_version_h__)
+#define __xmltooling_version_h__
+
+// This is all based on Xerces, on the theory it might be useful to
+// support this kind of stuff in the future. If they ever yank some
+// of this stuff, it can be copied into here.
+
+#include <xercesc/util/XercesVersion.hpp>
+
+// ---------------------------------------------------------------------------
+// V E R S I O N   S P E C I F I C A T I O N
+
+/**
+ * MODIFY THESE NUMERIC VALUES TO COINCIDE WITH XMLTOOLING VERSION
+ * AND DO NOT MODIFY ANYTHING ELSE IN THIS VERSION HEADER FILE
+ */
+
+#define XMLTOOLING_VERSION_MAJOR 1
+#define XMLTOOLING_VERSION_MINOR 0
+#define XMLTOOLING_VERSION_REVISION 0
+
+/** DO NOT MODIFY BELOW THIS LINE */
+
+/**
+ * MAGIC THAT AUTOMATICALLY GENERATES THE FOLLOWING:
+ *
+ *     gXMLToolingVersionStr, gXMLToolingFullVersionStr, gXMLToolingMajVersion, gXMLToolingMinVersion, gXMLToolingRevision
+ */
+
+// ---------------------------------------------------------------------------
+// V E R S I O N   I N F O R M A T I O N
+
+// XMLTooling version strings; these particular macros cannot be used for
+// conditional compilation as they are not numeric constants
+
+#define XMLTOOLING_FULLVERSIONSTR INVK_CAT3_SEP_UNDERSCORE(XMLTOOLING_VERSION_MAJOR,XMLTOOLING_VERSION_MINOR,XMLTOOLING_VERSION_REVISION)
+#define XMLTOOLING_FULLVERSIONDOT INVK_CAT3_SEP_PERIOD(XMLTOOLING_VERSION_MAJOR,XMLTOOLING_VERSION_MINOR,XMLTOOLING_VERSION_REVISION)
+#define XMLTOOLING_FULLVERSIONNUM INVK_CAT3_SEP_NIL(XMLTOOLING_VERSION_MAJOR,XMLTOOLING_VERSION_MINOR,XMLTOOLING_VERSION_REVISION)
+#define XMLTOOLING_VERSIONSTR     INVK_CAT2_SEP_UNDERSCORE(XMLTOOLING_VERSION_MAJOR,XMLTOOLING_VERSION_MINOR)
+
+const char* const    gXMLToolingVersionStr = XMLTOOLING_VERSIONSTR;
+const char* const    gXMLToolingFullVersionStr = XMLTOOLING_FULLVERSIONSTR;
+const unsigned int   gXMLToolingMajVersion = XMLTOOLING_VERSION_MAJOR;
+const unsigned int   gXMLToolingMinVersion = XMLTOOLING_VERSION_MINOR;
+const unsigned int   gXMLToolingRevision   = XMLTOOLING_VERSION_REVISION;
+
+// XMLTooling version numeric constants that can be used for conditional
+// compilation purposes.
+
+#define _XMLTOOLING_VERSION CALC_EXPANDED_FORM (XMLTOOLING_VERSION_MAJOR,XMLTOOLING_VERSION_MINOR,XMLTOOLING_VERSION_REVISION)
+
+#endif // __xmltooling_version_h__
index 908e4d4..0633ada 100644 (file)
@@ -1,69 +1,69 @@
-/*\r
- *  Copyright 2001-2005 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#include "XMLObjectBaseTestCase.h"\r
-\r
-#include <fstream>\r
-#include <xercesc/util/XMLUniDefs.hpp>\r
-\r
-class ComplexXMLObjectTest : public CxxTest::TestSuite {\r
-public:\r
-    ComplexXMLObjectTest() {}\r
-\r
-    void setUp() {\r
-        XMLObjectBuilder::registerDefaultBuilder(new AnyElementBuilder());\r
-    }\r
-\r
-    void tearDown() {\r
-        XMLObjectBuilder::deregisterDefaultBuilder();\r
-    }\r
-\r
-    void testComplexUnmarshalling() {\r
-        string path=data_path + "ComplexXMLObject.xml";\r
-        ifstream fs(path.c_str());\r
-        DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(fs);\r
-        TS_ASSERT(doc!=NULL);\r
-        XercesJanitor<DOMDocument> janitor(doc);\r
-\r
-        const XMLObjectBuilder* b = XMLObjectBuilder::getBuilder(doc->getDocumentElement());\r
-        TS_ASSERT(b!=NULL);\r
-\r
-        auto_ptr<ElementProxy> wcObject(\r
-            dynamic_cast<ElementProxy*>(b->buildFromDocument(doc, false))\r
-            );\r
-        TS_ASSERT(wcObject.get()!=NULL);\r
-        \r
-        ListOf(XMLObject) kids=wcObject->getXMLObjects();\r
-        TSM_ASSERT_EQUALS("Number of child elements was not expected value", 2, kids.size());\r
-        \r
-        ElementProxy* wc1=dynamic_cast<ElementProxy*>(*(++kids.begin()));\r
-        ElementProxy* wc2=dynamic_cast<ElementProxy*>(*(++(wc1->getXMLObjects().begin())));\r
-        TSM_ASSERT_EQUALS("Number of child elements was not expected value", 3, wc2->getXMLObjects().size());\r
-\r
-        static const XMLCh html[] = {chLatin_h, chLatin_t, chLatin_m, chLatin_l, chNull};\r
-        static const XMLCh div[] = {chLatin_d, chLatin_i, chLatin_v, chNull};\r
-        auto_ptr_XMLCh htmlns("http://www.w3.org/1999/xhtml");\r
-        QName q(htmlns.get(),div,html);\r
-        ListOf(XMLObject)::const_iterator it=wc2->getXMLObjects().begin();\r
-        ++it; ++it;\r
-        TSM_ASSERT_EQUALS("Element QName unexpected", it->getElementQName(),q);\r
-\r
-        DOMElement* rebuilt = wcObject->marshall(XMLToolingConfig::getConfig().getParser().newDocument());\r
-        wcObject->setDocument(rebuilt->getOwnerDocument());\r
-        TS_ASSERT(rebuilt->isEqualNode(doc->getDocumentElement()));\r
-    }\r
-\r
-};\r
+/*
+ *  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 <fstream>
+#include <xercesc/util/XMLUniDefs.hpp>
+
+class ComplexXMLObjectTest : public CxxTest::TestSuite {
+public:
+    ComplexXMLObjectTest() {}
+
+    void setUp() {
+        XMLObjectBuilder::registerDefaultBuilder(new AnyElementBuilder());
+    }
+
+    void tearDown() {
+        XMLObjectBuilder::deregisterDefaultBuilder();
+    }
+
+    void testComplexUnmarshalling() {
+        string path=data_path + "ComplexXMLObject.xml";
+        ifstream fs(path.c_str());
+        DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(fs);
+        TS_ASSERT(doc!=NULL);
+        XercesJanitor<DOMDocument> janitor(doc);
+
+        const XMLObjectBuilder* b = XMLObjectBuilder::getBuilder(doc->getDocumentElement());
+        TS_ASSERT(b!=NULL);
+
+        auto_ptr<ElementProxy> wcObject(
+            dynamic_cast<ElementProxy*>(b->buildFromDocument(doc, false))
+            );
+        TS_ASSERT(wcObject.get()!=NULL);
+        
+        ListOf(XMLObject) kids=wcObject->getXMLObjects();
+        TSM_ASSERT_EQUALS("Number of child elements was not expected value", 2, kids.size());
+        
+        ElementProxy* wc1=dynamic_cast<ElementProxy*>(*(++kids.begin()));
+        ElementProxy* wc2=dynamic_cast<ElementProxy*>(*(++(wc1->getXMLObjects().begin())));
+        TSM_ASSERT_EQUALS("Number of child elements was not expected value", 3, wc2->getXMLObjects().size());
+
+        static const XMLCh html[] = {chLatin_h, chLatin_t, chLatin_m, chLatin_l, chNull};
+        static const XMLCh div[] = {chLatin_d, chLatin_i, chLatin_v, chNull};
+        auto_ptr_XMLCh htmlns("http://www.w3.org/1999/xhtml");
+        QName q(htmlns.get(),div,html);
+        ListOf(XMLObject)::const_iterator it=wc2->getXMLObjects().begin();
+        ++it; ++it;
+        TSM_ASSERT_EQUALS("Element QName unexpected", it->getElementQName(),q);
+
+        DOMElement* rebuilt = wcObject->marshall(XMLToolingConfig::getConfig().getParser().newDocument());
+        wcObject->setDocument(rebuilt->getOwnerDocument());
+        TS_ASSERT(rebuilt->isEqualNode(doc->getDocumentElement()));
+    }
+
+};
index 3f88890..8f9e4c7 100644 (file)
@@ -1,93 +1,93 @@
-/*\r
- *  Copyright 2001-2005 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#include "XMLObjectBaseTestCase.h"\r
-\r
-#include <xmltooling/encryption/Decrypter.h>\r
-#include <xmltooling/encryption/Encrypter.h>\r
-#include <xmltooling/signature/CredentialResolver.h>\r
-\r
-#include <fstream>\r
-#include <xercesc/util/XMLUniDefs.hpp>\r
-#include <xsec/dsig/DSIGReference.hpp>\r
-\r
-using namespace xmlencryption;\r
-\r
-class _addcert : public std::binary_function<X509Data*,XSECCryptoX509*,void> {\r
-public:\r
-    void operator()(X509Data* bag, XSECCryptoX509* cert) const {\r
-        safeBuffer& buf=cert->getDEREncodingSB();\r
-        X509Certificate* x=X509CertificateBuilder::buildX509Certificate();\r
-        x->setValue(buf.sbStrToXMLCh());\r
-        bag->getX509Certificates().push_back(x);\r
-    }\r
-};\r
-\r
-class EncryptionTest : public CxxTest::TestSuite {\r
-    CredentialResolver* m_resolver;\r
-public:\r
-    void setUp() {\r
-        m_resolver=NULL;\r
-        string config = data_path + "FilesystemCredentialResolver.xml";\r
-        ifstream in(config.c_str());\r
-        DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(in);\r
-        XercesJanitor<DOMDocument> janitor(doc);\r
-        m_resolver = XMLToolingConfig::getConfig().CredentialResolverManager.newPlugin(\r
-            FILESYSTEM_CREDENTIAL_RESOLVER,doc->getDocumentElement()\r
-            );\r
-    }\r
-\r
-    void tearDown() {\r
-        delete m_resolver;\r
-    }\r
-\r
-    void testEncryption() {\r
-        string path=data_path + "ComplexXMLObject.xml";\r
-        ifstream fs(path.c_str());\r
-        DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(fs);\r
-        TS_ASSERT(doc!=NULL);\r
-\r
-        try {\r
-            Locker locker(m_resolver);\r
-            Encrypter encrypter;\r
-            Encrypter::EncryptionParams ep;\r
-            Encrypter::KeyEncryptionParams kep(DSIGConstants::s_unicodeStrURIRSA_1_5,m_resolver->getKey());\r
-            auto_ptr<EncryptedData> encData(encrypter.encryptElement(doc->getDocumentElement(),ep,&kep));\r
-\r
-            string buf;\r
-            XMLHelper::serialize(encData->marshall(), buf);\r
-            istringstream is(buf);\r
-            DOMDocument* doc2=XMLToolingConfig::getConfig().getValidatingParser().parse(is);\r
-            auto_ptr<EncryptedData> encData2(\r
-                dynamic_cast<EncryptedData*>(XMLObjectBuilder::buildOneFromElement(doc2->getDocumentElement(),true))\r
-                );\r
-\r
-            Decrypter decrypter(new KeyResolver(m_resolver->getKey()));\r
-            DOMDocumentFragment* frag = decrypter.decryptData(encData2.get());\r
-            XMLHelper::serialize(static_cast<DOMElement*>(frag->getFirstChild()), buf);\r
-            //TS_TRACE(buf.c_str());\r
-            TS_ASSERT(doc->getDocumentElement()->isEqualNode(frag->getFirstChild()));\r
-            frag->release();\r
-            doc->release();\r
-        }\r
-        catch (XMLToolingException& e) {\r
-            TS_TRACE(e.what());\r
-            doc->release();\r
-            throw;\r
-        }\r
-    }\r
-\r
-};\r
+/*
+ *  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 <xmltooling/encryption/Decrypter.h>
+#include <xmltooling/encryption/Encrypter.h>
+#include <xmltooling/signature/CredentialResolver.h>
+
+#include <fstream>
+#include <xercesc/util/XMLUniDefs.hpp>
+#include <xsec/dsig/DSIGReference.hpp>
+
+using namespace xmlencryption;
+
+class _addcert : public std::binary_function<X509Data*,XSECCryptoX509*,void> {
+public:
+    void operator()(X509Data* bag, XSECCryptoX509* cert) const {
+        safeBuffer& buf=cert->getDEREncodingSB();
+        X509Certificate* x=X509CertificateBuilder::buildX509Certificate();
+        x->setValue(buf.sbStrToXMLCh());
+        bag->getX509Certificates().push_back(x);
+    }
+};
+
+class EncryptionTest : public CxxTest::TestSuite {
+    CredentialResolver* m_resolver;
+public:
+    void setUp() {
+        m_resolver=NULL;
+        string config = data_path + "FilesystemCredentialResolver.xml";
+        ifstream in(config.c_str());
+        DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(in);
+        XercesJanitor<DOMDocument> janitor(doc);
+        m_resolver = XMLToolingConfig::getConfig().CredentialResolverManager.newPlugin(
+            FILESYSTEM_CREDENTIAL_RESOLVER,doc->getDocumentElement()
+            );
+    }
+
+    void tearDown() {
+        delete m_resolver;
+    }
+
+    void testEncryption() {
+        string path=data_path + "ComplexXMLObject.xml";
+        ifstream fs(path.c_str());
+        DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(fs);
+        TS_ASSERT(doc!=NULL);
+
+        try {
+            Locker locker(m_resolver);
+            Encrypter encrypter;
+            Encrypter::EncryptionParams ep;
+            Encrypter::KeyEncryptionParams kep(DSIGConstants::s_unicodeStrURIRSA_1_5,m_resolver->getKey());
+            auto_ptr<EncryptedData> encData(encrypter.encryptElement(doc->getDocumentElement(),ep,&kep));
+
+            string buf;
+            XMLHelper::serialize(encData->marshall(), buf);
+            istringstream is(buf);
+            DOMDocument* doc2=XMLToolingConfig::getConfig().getValidatingParser().parse(is);
+            auto_ptr<EncryptedData> encData2(
+                dynamic_cast<EncryptedData*>(XMLObjectBuilder::buildOneFromElement(doc2->getDocumentElement(),true))
+                );
+
+            Decrypter decrypter(new KeyResolver(m_resolver->getKey()));
+            DOMDocumentFragment* frag = decrypter.decryptData(encData2.get());
+            XMLHelper::serialize(static_cast<DOMElement*>(frag->getFirstChild()), buf);
+            //TS_TRACE(buf.c_str());
+            TS_ASSERT(doc->getDocumentElement()->isEqualNode(frag->getFirstChild()));
+            frag->release();
+            doc->release();
+        }
+        catch (XMLToolingException& e) {
+            TS_TRACE(e.what());
+            doc->release();
+            throw;
+        }
+    }
+
+};
index d290fbe..f7a67b7 100644 (file)
@@ -1,49 +1,49 @@
-/*\r
- *  Copyright 2001-2005 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#include "XMLObjectBaseTestCase.h"\r
-\r
-#include <xmltooling/exceptions.h>\r
-\r
-\r
-class ExceptionTest : public CxxTest::TestSuite {\r
-public:\r
-\r
-    void testException(void) {\r
-#define TEST(n,b,a) XMLToolingException e##n(b); \\r
-                TS_ASSERT(!strcmp(a,e##n.what()))\r
-\r
-#define TESTP(n,b,a,p) MarshallingException e##n(b,p); \\r
-                TS_ASSERT(!strcmp(a,e##n.what()))\r
-\r
-\r
-        TESTP(1,"This is a test.",          "This is a test.",      params(2,"Foo","bar"));\r
-        TESTP(2,"This is a test.$",         "This is a test.",      params(2,"Foo","bar"));\r
-        TESTP(3,"This is a $ test.",        "This is a  test.",     params(2,"Foo","bar"));\r
-        TESTP(4,"$$This is a test.$",       "$This is a test.",     params(2,"Foo","bar"));\r
-        TESTP(5,"$This is a $test.",        "This is a test.",      params(2,"Foo","bar"));\r
-        TESTP(6,"$1 is a $2",               "Foo is a bar",         params(2,"Foo","bar"));\r
-        TESTP(7,"$This is a $test.",        "Foo is a bar.",        namedparams(2,"This","Foo","test","bar"));\r
-        TESTP(8,"Unable to generate random data: $1",\r
-                "Unable to generate random data: OpenSSLCryptoProvider::getRandom - OpenSSL random not properly initialised",\r
-                params(1,"OpenSSLCryptoProvider::getRandom - OpenSSL random not properly initialised"));\r
-\r
-        string buf=e7.toString();\r
-        auto_ptr<XMLToolingException> ptr(XMLToolingException::fromString(buf.c_str()));\r
-        TS_ASSERT(typeid(*ptr)==typeid(MarshallingException));\r
-        TS_ASSERT(!strcmp(ptr->what(),"Foo is a bar."));\r
-    }\r
-};\r
+/*
+ *  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 <xmltooling/exceptions.h>
+
+
+class ExceptionTest : public CxxTest::TestSuite {
+public:
+
+    void testException(void) {
+#define TEST(n,b,a) XMLToolingException e##n(b); \
+                TS_ASSERT(!strcmp(a,e##n.what()))
+
+#define TESTP(n,b,a,p) MarshallingException e##n(b,p); \
+                TS_ASSERT(!strcmp(a,e##n.what()))
+
+
+        TESTP(1,"This is a test.",          "This is a test.",      params(2,"Foo","bar"));
+        TESTP(2,"This is a test.$",         "This is a test.",      params(2,"Foo","bar"));
+        TESTP(3,"This is a $ test.",        "This is a  test.",     params(2,"Foo","bar"));
+        TESTP(4,"$$This is a test.$",       "$This is a test.",     params(2,"Foo","bar"));
+        TESTP(5,"$This is a $test.",        "This is a test.",      params(2,"Foo","bar"));
+        TESTP(6,"$1 is a $2",               "Foo is a bar",         params(2,"Foo","bar"));
+        TESTP(7,"$This is a $test.",        "Foo is a bar.",        namedparams(2,"This","Foo","test","bar"));
+        TESTP(8,"Unable to generate random data: $1",
+                "Unable to generate random data: OpenSSLCryptoProvider::getRandom - OpenSSL random not properly initialised",
+                params(1,"OpenSSLCryptoProvider::getRandom - OpenSSL random not properly initialised"));
+
+        string buf=e7.toString();
+        auto_ptr<XMLToolingException> ptr(XMLToolingException::fromString(buf.c_str()));
+        TS_ASSERT(typeid(*ptr)==typeid(MarshallingException));
+        TS_ASSERT(!strcmp(ptr->what(),"Foo is a bar."));
+    }
+};
index 92e720a..7f2816b 100644 (file)
@@ -1,48 +1,48 @@
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#include "XMLObjectBaseTestCase.h"\r
-\r
-#include <xmltooling/signature/CredentialResolver.h>\r
-\r
-#include <fstream>\r
-\r
-class FilesystemCredentialResolverTest : public CxxTest::TestSuite {\r
-public:\r
-    void setUp() {\r
-    }\r
-    \r
-    void tearDown() {\r
-    }\r
-\r
-    void testFilesystemProvider() {\r
-        string config = data_path + "FilesystemCredentialResolver.xml";\r
-        ifstream in(config.c_str());\r
-        DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(in);\r
-        XercesJanitor<DOMDocument> janitor(doc);\r
-\r
-        auto_ptr<CredentialResolver> credResolver(\r
-            XMLToolingConfig::getConfig().CredentialResolverManager.newPlugin(\r
-                FILESYSTEM_CREDENTIAL_RESOLVER,doc->getDocumentElement()\r
-                )\r
-            );\r
-\r
-        Locker locker(credResolver.get());\r
-        auto_ptr<XSECCryptoKey> key(credResolver->getKey());\r
-        TSM_ASSERT("Retrieved key was null", key.get()!=NULL);\r
-        TSM_ASSERT_EQUALS("Unexpected number of certificates", 1, credResolver->getCertificates().size());\r
-    }\r
-};\r
+/*
+ *  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.
+ */
+
+#include "XMLObjectBaseTestCase.h"
+
+#include <xmltooling/signature/CredentialResolver.h>
+
+#include <fstream>
+
+class FilesystemCredentialResolverTest : public CxxTest::TestSuite {
+public:
+    void setUp() {
+    }
+    
+    void tearDown() {
+    }
+
+    void testFilesystemProvider() {
+        string config = data_path + "FilesystemCredentialResolver.xml";
+        ifstream in(config.c_str());
+        DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(in);
+        XercesJanitor<DOMDocument> janitor(doc);
+
+        auto_ptr<CredentialResolver> credResolver(
+            XMLToolingConfig::getConfig().CredentialResolverManager.newPlugin(
+                FILESYSTEM_CREDENTIAL_RESOLVER,doc->getDocumentElement()
+                )
+            );
+
+        Locker locker(credResolver.get());
+        auto_ptr<XSECCryptoKey> key(credResolver->getKey());
+        TSM_ASSERT("Retrieved key was null", key.get()!=NULL);
+        TSM_ASSERT_EQUALS("Unexpected number of certificates", 1, credResolver->getCertificates().size());
+    }
+};
index 0a23779..a8e4ef8 100644 (file)
@@ -1,63 +1,63 @@
-/*\r
- *  Copyright 2001-2005 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#include "XMLObjectBaseTestCase.h"\r
-\r
-#include <fstream>\r
-#include <xmltooling/signature/KeyInfo.h>\r
-#include <xmltooling/signature/KeyResolver.h>\r
-\r
-using namespace xmlsignature;\r
-\r
-class InlineKeyResolverTest : public CxxTest::TestSuite {\r
-    KeyResolver* m_resolver;\r
-public:\r
-    InlineKeyResolverTest() : m_resolver(NULL) {}\r
-\r
-    void setUp() {\r
-        string config = data_path + "InlineKeyResolver.xml";\r
-        ifstream in(config.c_str());\r
-        DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(in);\r
-        XercesJanitor<DOMDocument> janitor(doc);\r
-        m_resolver=XMLToolingConfig::getConfig().KeyResolverManager.newPlugin(INLINE_KEY_RESOLVER,doc->getDocumentElement());\r
-    }\r
-\r
-    void tearDown() {\r
-        delete m_resolver;\r
-        m_resolver=NULL;\r
-    }\r
-\r
-    void testResolver() {\r
-        string path=data_path + "KeyInfo1.xml";\r
-        ifstream fs(path.c_str());\r
-        DOMDocument* doc=XMLToolingConfig::getConfig().getValidatingParser().parse(fs);\r
-        TS_ASSERT(doc!=NULL);\r
-        const XMLObjectBuilder* b = XMLObjectBuilder::getBuilder(doc->getDocumentElement());\r
-        TS_ASSERT(b!=NULL);\r
-        auto_ptr<KeyInfo> kiObject(dynamic_cast<KeyInfo*>(b->buildFromDocument(doc)));\r
-        TS_ASSERT(kiObject.get()!=NULL);\r
-\r
-        auto_ptr<XSECCryptoKey> key(m_resolver->resolveKey(kiObject.get()));\r
-        TSM_ASSERT("Unable to resolve public key.", key.get()!=NULL);\r
-        TSM_ASSERT_EQUALS("Unexpected key type.", key->getKeyType(), XSECCryptoKey::KEY_RSA_PUBLIC);\r
-\r
-        auto_ptr<XSECCryptoX509CRL> crl(m_resolver->resolveCRL(kiObject.get()));\r
-        TSM_ASSERT("Unable to resolve CRL.", crl.get()!=NULL);\r
-\r
-        KeyResolver::ResolvedCertificates certs;\r
-        TSM_ASSERT_EQUALS("Wrong certificate count.", m_resolver->resolveCertificates(kiObject.get(), certs), 1);\r
-    }\r
-};\r
+/*
+ *  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 <fstream>
+#include <xmltooling/signature/KeyInfo.h>
+#include <xmltooling/signature/KeyResolver.h>
+
+using namespace xmlsignature;
+
+class InlineKeyResolverTest : public CxxTest::TestSuite {
+    KeyResolver* m_resolver;
+public:
+    InlineKeyResolverTest() : m_resolver(NULL) {}
+
+    void setUp() {
+        string config = data_path + "InlineKeyResolver.xml";
+        ifstream in(config.c_str());
+        DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(in);
+        XercesJanitor<DOMDocument> janitor(doc);
+        m_resolver=XMLToolingConfig::getConfig().KeyResolverManager.newPlugin(INLINE_KEY_RESOLVER,doc->getDocumentElement());
+    }
+
+    void tearDown() {
+        delete m_resolver;
+        m_resolver=NULL;
+    }
+
+    void testResolver() {
+        string path=data_path + "KeyInfo1.xml";
+        ifstream fs(path.c_str());
+        DOMDocument* doc=XMLToolingConfig::getConfig().getValidatingParser().parse(fs);
+        TS_ASSERT(doc!=NULL);
+        const XMLObjectBuilder* b = XMLObjectBuilder::getBuilder(doc->getDocumentElement());
+        TS_ASSERT(b!=NULL);
+        auto_ptr<KeyInfo> kiObject(dynamic_cast<KeyInfo*>(b->buildFromDocument(doc)));
+        TS_ASSERT(kiObject.get()!=NULL);
+
+        auto_ptr<XSECCryptoKey> key(m_resolver->resolveKey(kiObject.get()));
+        TSM_ASSERT("Unable to resolve public key.", key.get()!=NULL);
+        TSM_ASSERT_EQUALS("Unexpected key type.", key->getKeyType(), XSECCryptoKey::KEY_RSA_PUBLIC);
+
+        auto_ptr<XSECCryptoX509CRL> crl(m_resolver->resolveCRL(kiObject.get()));
+        TSM_ASSERT("Unable to resolve CRL.", crl.get()!=NULL);
+
+        KeyResolver::ResolvedCertificates certs;
+        TSM_ASSERT_EQUALS("Wrong certificate count.", m_resolver->resolveCertificates(kiObject.get(), certs), 1);
+    }
+};
index 0379cae..5f23612 100644 (file)
@@ -1,95 +1,95 @@
-/*\r
- *  Copyright 2001-2005 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#include "XMLObjectBaseTestCase.h"\r
-\r
-#include <fstream>\r
-#include <xmltooling/signature/KeyInfo.h>\r
-#include <xmltooling/validation/ValidatorSuite.h>\r
-\r
-using namespace xmlsignature;\r
-\r
-class KeyInfoTest : public CxxTest::TestSuite {\r
-public:\r
-    KeyInfoTest() {}\r
-\r
-    void setUp() {\r
-        XMLObjectBuilder::registerDefaultBuilder(new AnyElementBuilder());\r
-    }\r
-\r
-    void tearDown() {\r
-        XMLObjectBuilder::deregisterDefaultBuilder();\r
-    }\r
-\r
-    void testKeyInfo1() {\r
-        string path=data_path + "KeyInfo1.xml";\r
-        ifstream fs(path.c_str());\r
-        DOMDocument* doc=XMLToolingConfig::getConfig().getValidatingParser().parse(fs);\r
-        TS_ASSERT(doc!=NULL);\r
-\r
-        const XMLObjectBuilder* b = XMLObjectBuilder::getBuilder(doc->getDocumentElement());\r
-        TS_ASSERT(b!=NULL);\r
-\r
-        auto_ptr<KeyInfo> kiObject(dynamic_cast<KeyInfo*>(b->buildFromDocument(doc)));\r
-        TS_ASSERT(kiObject.get()!=NULL);\r
-        TSM_ASSERT_EQUALS("Number of child elements was not expected value",\r
-            3, kiObject->getOrderedChildren().size());\r
-        TSM_ASSERT_EQUALS("Number of child elements was not expected value",\r
-            1, kiObject->getKeyValues().size());\r
-        TSM_ASSERT_EQUALS("Number of child elements was not expected value",\r
-            1, kiObject->getX509Datas().front()->getX509Certificates().size());\r
-\r
-        auto_ptr_XMLCh expected("Public Key for CN=xmldap.org, OU=Domain Control Validated, O=xmldap.org");\r
-        TSM_ASSERT("KeyName was not expected value", XMLString::equals(expected.get(), kiObject->getKeyNames().front()->getName()));\r
-\r
-        SchemaValidators.validate(kiObject.get());\r
-    }\r
-\r
-    void testKeyInfo2() {\r
-        string path=data_path + "KeyInfo2.xml";\r
-        ifstream fs(path.c_str());\r
-        DOMDocument* doc=XMLToolingConfig::getConfig().getValidatingParser().parse(fs);\r
-        TS_ASSERT(doc!=NULL);\r
-\r
-        const XMLObjectBuilder* b = XMLObjectBuilder::getBuilder(doc->getDocumentElement());\r
-        TS_ASSERT(b!=NULL);\r
-\r
-        auto_ptr<KeyInfo> kiObject(dynamic_cast<KeyInfo*>(b->buildFromDocument(doc)));\r
-        TS_ASSERT(kiObject.get()!=NULL);\r
-        TSM_ASSERT_EQUALS("Number of child elements was not expected value",\r
-            2, kiObject->getOrderedChildren().size());\r
-        TSM_ASSERT_EQUALS("Number of child elements was not expected value",\r
-            1, kiObject->getRetrievalMethods().size());\r
-        TSM_ASSERT_EQUALS("Number of child elements was not expected value",\r
-            2, kiObject->getSPKIDatas().front()->getSPKISexps().size());\r
-\r
-        SchemaValidators.validate(kiObject.get());\r
-    }\r
-\r
-    void testKeyInfo3() {\r
-        string path=data_path + "KeyInfo3.xml";\r
-        ifstream fs(path.c_str());\r
-        DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(fs);\r
-        TS_ASSERT(doc!=NULL);\r
-\r
-        const XMLObjectBuilder* b = XMLObjectBuilder::getBuilder(doc->getDocumentElement());\r
-        TS_ASSERT(b!=NULL);\r
-\r
-        auto_ptr<KeyInfo> kiObject(dynamic_cast<KeyInfo*>(b->buildFromDocument(doc)));\r
-        TS_ASSERT(kiObject.get()!=NULL);\r
-        TS_ASSERT_THROWS(SchemaValidators.validate(kiObject.get()),ValidationException);\r
-    }\r
-};\r
+/*
+ *  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 <fstream>
+#include <xmltooling/signature/KeyInfo.h>
+#include <xmltooling/validation/ValidatorSuite.h>
+
+using namespace xmlsignature;
+
+class KeyInfoTest : public CxxTest::TestSuite {
+public:
+    KeyInfoTest() {}
+
+    void setUp() {
+        XMLObjectBuilder::registerDefaultBuilder(new AnyElementBuilder());
+    }
+
+    void tearDown() {
+        XMLObjectBuilder::deregisterDefaultBuilder();
+    }
+
+    void testKeyInfo1() {
+        string path=data_path + "KeyInfo1.xml";
+        ifstream fs(path.c_str());
+        DOMDocument* doc=XMLToolingConfig::getConfig().getValidatingParser().parse(fs);
+        TS_ASSERT(doc!=NULL);
+
+        const XMLObjectBuilder* b = XMLObjectBuilder::getBuilder(doc->getDocumentElement());
+        TS_ASSERT(b!=NULL);
+
+        auto_ptr<KeyInfo> kiObject(dynamic_cast<KeyInfo*>(b->buildFromDocument(doc)));
+        TS_ASSERT(kiObject.get()!=NULL);
+        TSM_ASSERT_EQUALS("Number of child elements was not expected value",
+            3, kiObject->getOrderedChildren().size());
+        TSM_ASSERT_EQUALS("Number of child elements was not expected value",
+            1, kiObject->getKeyValues().size());
+        TSM_ASSERT_EQUALS("Number of child elements was not expected value",
+            1, kiObject->getX509Datas().front()->getX509Certificates().size());
+
+        auto_ptr_XMLCh expected("Public Key for CN=xmldap.org, OU=Domain Control Validated, O=xmldap.org");
+        TSM_ASSERT("KeyName was not expected value", XMLString::equals(expected.get(), kiObject->getKeyNames().front()->getName()));
+
+        SchemaValidators.validate(kiObject.get());
+    }
+
+    void testKeyInfo2() {
+        string path=data_path + "KeyInfo2.xml";
+        ifstream fs(path.c_str());
+        DOMDocument* doc=XMLToolingConfig::getConfig().getValidatingParser().parse(fs);
+        TS_ASSERT(doc!=NULL);
+
+        const XMLObjectBuilder* b = XMLObjectBuilder::getBuilder(doc->getDocumentElement());
+        TS_ASSERT(b!=NULL);
+
+        auto_ptr<KeyInfo> kiObject(dynamic_cast<KeyInfo*>(b->buildFromDocument(doc)));
+        TS_ASSERT(kiObject.get()!=NULL);
+        TSM_ASSERT_EQUALS("Number of child elements was not expected value",
+            2, kiObject->getOrderedChildren().size());
+        TSM_ASSERT_EQUALS("Number of child elements was not expected value",
+            1, kiObject->getRetrievalMethods().size());
+        TSM_ASSERT_EQUALS("Number of child elements was not expected value",
+            2, kiObject->getSPKIDatas().front()->getSPKISexps().size());
+
+        SchemaValidators.validate(kiObject.get());
+    }
+
+    void testKeyInfo3() {
+        string path=data_path + "KeyInfo3.xml";
+        ifstream fs(path.c_str());
+        DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(fs);
+        TS_ASSERT(doc!=NULL);
+
+        const XMLObjectBuilder* b = XMLObjectBuilder::getBuilder(doc->getDocumentElement());
+        TS_ASSERT(b!=NULL);
+
+        auto_ptr<KeyInfo> kiObject(dynamic_cast<KeyInfo*>(b->buildFromDocument(doc)));
+        TS_ASSERT(kiObject.get()!=NULL);
+        TS_ASSERT_THROWS(SchemaValidators.validate(kiObject.get()),ValidationException);
+    }
+};
index 1a5c53a..0414185 100644 (file)
-/*\r
- *  Copyright 2001-2005 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#include "XMLObjectBaseTestCase.h"\r
-\r
-#include <fstream>\r
-\r
-class MarshallingTest : public CxxTest::TestSuite {\r
-public:\r
-    void setUp() {\r
-        QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);\r
-        QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);\r
-        XMLObjectBuilder::registerBuilder(qname, new SimpleXMLObjectBuilder());\r
-        XMLObjectBuilder::registerBuilder(qtype, new SimpleXMLObjectBuilder());\r
-    }\r
-\r
-    void tearDown() {\r
-        QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);\r
-        QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);\r
-        XMLObjectBuilder::deregisterBuilder(qname);\r
-        XMLObjectBuilder::deregisterBuilder(qtype);\r
-    }\r
-\r
-    void testMarshallingWithAttributes() {\r
-        QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);\r
-        auto_ptr<SimpleXMLObject> sxObject(SimpleXMLObjectBuilder::newSimpleXMLObject());\r
-        TS_ASSERT(sxObject.get()!=NULL);\r
-        auto_ptr_XMLCh expected("Firefly");\r
-        sxObject->setId(expected.get());\r
-        \r
-        DOMElement* rootElement = sxObject->marshall();\r
-\r
-        string path=data_path + "SimpleXMLObjectWithAttribute.xml";\r
-        ifstream fs(path.c_str());\r
-        DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(fs);\r
-        TS_ASSERT(doc!=NULL);\r
-\r
-        TS_ASSERT(rootElement->isEqualNode(doc->getDocumentElement()));\r
-        doc->release();\r
-    }\r
-\r
-    void testMarshallingWithElementContent() {\r
-        QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);\r
-        auto_ptr<SimpleXMLObject> sxObject(SimpleXMLObjectBuilder::newSimpleXMLObject());\r
-        TS_ASSERT(sxObject.get()!=NULL);\r
-        auto_ptr_XMLCh expected("Sample Content");\r
-        sxObject->setValue(expected.get());\r
-        \r
-        DOMElement* rootElement = sxObject->marshall();\r
-\r
-        string path=data_path + "SimpleXMLObjectWithContent.xml";\r
-        ifstream fs(path.c_str());\r
-        DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(fs);\r
-        TS_ASSERT(doc!=NULL);\r
-\r
-        TS_ASSERT(rootElement->isEqualNode(doc->getDocumentElement()));\r
-        doc->release();\r
-    }\r
-\r
-    void testMarshallingWithChildElements() {\r
-        QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);\r
-        const SimpleXMLObjectBuilder* b=dynamic_cast<const SimpleXMLObjectBuilder*>(XMLObjectBuilder::getBuilder(qname));\r
-        TS_ASSERT(b!=NULL);\r
-        \r
-        auto_ptr<SimpleXMLObject> sxObject(b->buildObject());\r
-        TS_ASSERT(sxObject.get()!=NULL);\r
-        VectorOf(SimpleXMLObject) kids=sxObject->getSimpleXMLObjects();\r
-        kids.push_back(b->buildObject());\r
-        kids.push_back(b->buildObject());\r
-        kids.push_back(b->buildObject());\r
-        \r
-        // Test some collection stuff\r
-        auto_ptr_XMLCh foo("Foo");\r
-        auto_ptr_XMLCh bar("Bar");\r
-        auto_ptr_XMLCh baz("Baz");\r
-        kids.begin()->setId(foo.get());\r
-        kids.at(2)->setValue(bar.get());\r
-        kids.erase(kids.begin()+1);\r
-        TS_ASSERT(XMLString::equals(kids.back()->getValue(), bar.get()));\r
-        \r
-        QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME,SimpleXMLObject::NAMESPACE_PREFIX);\r
-        kids.push_back(\r
-            b->buildObject(SimpleXMLObject::NAMESPACE,SimpleXMLObject::DERIVED_NAME,SimpleXMLObject::NAMESPACE_PREFIX,&qtype)\r
-            );\r
-        kids.back()->setValue(baz.get());\r
-        \r
-        DOMElement* rootElement = sxObject->marshall();\r
-\r
-        string path=data_path + "SimpleXMLObjectWithChildren.xml";\r
-        ifstream fs(path.c_str());\r
-        DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(fs);\r
-        TS_ASSERT(doc!=NULL);\r
-\r
-        TS_ASSERT(rootElement->isEqualNode(doc->getDocumentElement()));\r
-        doc->release();\r
-    }\r
-\r
-};\r
+/*
+ *  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 <fstream>
+
+class MarshallingTest : public CxxTest::TestSuite {
+public:
+    void setUp() {
+        QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);
+        QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);
+        XMLObjectBuilder::registerBuilder(qname, new SimpleXMLObjectBuilder());
+        XMLObjectBuilder::registerBuilder(qtype, new SimpleXMLObjectBuilder());
+    }
+
+    void tearDown() {
+        QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);
+        QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);
+        XMLObjectBuilder::deregisterBuilder(qname);
+        XMLObjectBuilder::deregisterBuilder(qtype);
+    }
+
+    void testMarshallingWithAttributes() {
+        QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);
+        auto_ptr<SimpleXMLObject> sxObject(SimpleXMLObjectBuilder::newSimpleXMLObject());
+        TS_ASSERT(sxObject.get()!=NULL);
+        auto_ptr_XMLCh expected("Firefly");
+        sxObject->setId(expected.get());
+        
+        DOMElement* rootElement = sxObject->marshall();
+
+        string path=data_path + "SimpleXMLObjectWithAttribute.xml";
+        ifstream fs(path.c_str());
+        DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(fs);
+        TS_ASSERT(doc!=NULL);
+
+        TS_ASSERT(rootElement->isEqualNode(doc->getDocumentElement()));
+        doc->release();
+    }
+
+    void testMarshallingWithElementContent() {
+        QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);
+        auto_ptr<SimpleXMLObject> sxObject(SimpleXMLObjectBuilder::newSimpleXMLObject());
+        TS_ASSERT(sxObject.get()!=NULL);
+        auto_ptr_XMLCh expected("Sample Content");
+        sxObject->setValue(expected.get());
+        
+        DOMElement* rootElement = sxObject->marshall();
+
+        string path=data_path + "SimpleXMLObjectWithContent.xml";
+        ifstream fs(path.c_str());
+        DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(fs);
+        TS_ASSERT(doc!=NULL);
+
+        TS_ASSERT(rootElement->isEqualNode(doc->getDocumentElement()));
+        doc->release();
+    }
+
+    void testMarshallingWithChildElements() {
+        QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);
+        const SimpleXMLObjectBuilder* b=dynamic_cast<const SimpleXMLObjectBuilder*>(XMLObjectBuilder::getBuilder(qname));
+        TS_ASSERT(b!=NULL);
+        
+        auto_ptr<SimpleXMLObject> sxObject(b->buildObject());
+        TS_ASSERT(sxObject.get()!=NULL);
+        VectorOf(SimpleXMLObject) kids=sxObject->getSimpleXMLObjects();
+        kids.push_back(b->buildObject());
+        kids.push_back(b->buildObject());
+        kids.push_back(b->buildObject());
+        
+        // Test some collection stuff
+        auto_ptr_XMLCh foo("Foo");
+        auto_ptr_XMLCh bar("Bar");
+        auto_ptr_XMLCh baz("Baz");
+        kids.begin()->setId(foo.get());
+        kids.at(2)->setValue(bar.get());
+        kids.erase(kids.begin()+1);
+        TS_ASSERT(XMLString::equals(kids.back()->getValue(), bar.get()));
+        
+        QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME,SimpleXMLObject::NAMESPACE_PREFIX);
+        kids.push_back(
+            b->buildObject(SimpleXMLObject::NAMESPACE,SimpleXMLObject::DERIVED_NAME,SimpleXMLObject::NAMESPACE_PREFIX,&qtype)
+            );
+        kids.back()->setValue(baz.get());
+        
+        DOMElement* rootElement = sxObject->marshall();
+
+        string path=data_path + "SimpleXMLObjectWithChildren.xml";
+        ifstream fs(path.c_str());
+        DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(fs);
+        TS_ASSERT(doc!=NULL);
+
+        TS_ASSERT(rootElement->isEqualNode(doc->getDocumentElement()));
+        doc->release();
+    }
+
+};
index c8f02ee..830e17b 100644 (file)
@@ -1,46 +1,46 @@
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#include "XMLObjectBaseTestCase.h"\r
-\r
-#include <xmltooling/util/StorageService.h>\r
-\r
-class MemoryStorageServiceTest : public CxxTest::TestSuite {\r
-public:\r
-    void setUp() {\r
-    }\r
-    \r
-    void tearDown() {\r
-    }\r
-\r
-    void testMemoryService() {\r
-        auto_ptr<StorageService> storage(\r
-            XMLToolingConfig::getConfig().StorageServiceManager.newPlugin(MEMORY_STORAGE_SERVICE,NULL)\r
-            );\r
-\r
-        string data;\r
-        TSM_ASSERT("Record found in storage.", !storage->readString("context", "foo1", &data));\r
-        storage->createString("context", "foo1", "bar1", time(NULL) + 60);\r
-        storage->createString("context", "foo2", "bar2", time(NULL) + 60);\r
-        TSM_ASSERT("Record not found in storage.", storage->readString("context", "foo1", &data));\r
-        TSM_ASSERT_EQUALS("Record value doesn't match.", data, "bar1");\r
-        TSM_ASSERT("Update failed.", storage->updateString("context", "foo2", "bar1"));\r
-        TSM_ASSERT("Record not found in storage.", storage->readString("context", "foo2", &data));\r
-        TSM_ASSERT_EQUALS("Record value doesn't match.", data, "bar1");\r
-        TSM_ASSERT("Delete failed.", storage->deleteString("context", "foo2"));\r
-        storage->reap("context");\r
-    }\r
-};\r
+/*
+ *  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.
+ */
+
+#include "XMLObjectBaseTestCase.h"
+
+#include <xmltooling/util/StorageService.h>
+
+class MemoryStorageServiceTest : public CxxTest::TestSuite {
+public:
+    void setUp() {
+    }
+    
+    void tearDown() {
+    }
+
+    void testMemoryService() {
+        auto_ptr<StorageService> storage(
+            XMLToolingConfig::getConfig().StorageServiceManager.newPlugin(MEMORY_STORAGE_SERVICE,NULL)
+            );
+
+        string data;
+        TSM_ASSERT("Record found in storage.", !storage->readString("context", "foo1", &data));
+        storage->createString("context", "foo1", "bar1", time(NULL) + 60);
+        storage->createString("context", "foo2", "bar2", time(NULL) + 60);
+        TSM_ASSERT("Record not found in storage.", storage->readString("context", "foo1", &data));
+        TSM_ASSERT_EQUALS("Record value doesn't match.", data, "bar1");
+        TSM_ASSERT("Update failed.", storage->updateString("context", "foo2", "bar1"));
+        TSM_ASSERT("Record not found in storage.", storage->readString("context", "foo2", &data));
+        TSM_ASSERT_EQUALS("Record value doesn't match.", data, "bar1");
+        TSM_ASSERT("Delete failed.", storage->deleteString("context", "foo2"));
+        storage->reap("context");
+    }
+};
index c1ca7ec..a733767 100644 (file)
-/*\r
- *  Copyright 2001-2005 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#include "XMLObjectBaseTestCase.h"\r
-\r
-#include <xmltooling/signature/CredentialResolver.h>\r
-#include <xmltooling/signature/KeyInfo.h>\r
-#include <xmltooling/signature/SignatureValidator.h>\r
-\r
-#include <fstream>\r
-#include <xercesc/util/XMLUniDefs.hpp>\r
-#include <xsec/dsig/DSIGReference.hpp>\r
-\r
-class TestContext : public ContentReference\r
-{\r
-    XMLCh* m_uri;\r
-    \r
-public:\r
-    TestContext(const XMLCh* uri) {\r
-        m_uri=XMLString::replicate(uri);\r
-    }\r
-    \r
-    virtual ~TestContext() {\r
-        XMLString::release(&m_uri);\r
-    }\r
-\r
-    void createReferences(DSIGSignature* sig) {\r
-        DSIGReference* ref=sig->createReference(m_uri);\r
-        ref->appendEnvelopedSignatureTransform();\r
-        ref->appendCanonicalizationTransform(CANON_C14NE_NOC);\r
-    }\r
-};\r
-\r
-class TestValidator : public SignatureValidator\r
-{\r
-    XMLCh* m_uri;\r
-    \r
-public:\r
-    TestValidator(const XMLCh* uri) : SignatureValidator(XMLToolingConfig::getConfig().KeyResolverManager.newPlugin(INLINE_KEY_RESOLVER,NULL)) {\r
-        m_uri=XMLString::replicate(uri);\r
-    }\r
-    \r
-    virtual ~TestValidator() {\r
-        XMLString::release(&m_uri);\r
-    }\r
-\r
-    void validate(const Signature* sigObj) const {\r
-        DSIGSignature* sig=sigObj->getXMLSignature();\r
-        if (!sig)\r
-            throw SignatureException("Only a marshalled Signature object can be verified.");\r
-        const XMLCh* uri=sig->getReferenceList()->item(0)->getURI();\r
-        TSM_ASSERT_SAME_DATA("Reference URI does not match.",uri,m_uri,XMLString::stringLen(uri));\r
-        SignatureValidator::validate(sigObj);\r
-    }\r
-};\r
-\r
-class _addcert : public std::binary_function<X509Data*,XSECCryptoX509*,void> {\r
-public:\r
-    void operator()(X509Data* bag, XSECCryptoX509* cert) const {\r
-        safeBuffer& buf=cert->getDEREncodingSB();\r
-        X509Certificate* x=X509CertificateBuilder::buildX509Certificate();\r
-        x->setValue(buf.sbStrToXMLCh());\r
-        bag->getX509Certificates().push_back(x);\r
-    }\r
-};\r
-\r
-class SignatureTest : public CxxTest::TestSuite {\r
-    CredentialResolver* m_resolver;\r
-public:\r
-    void setUp() {\r
-        m_resolver=NULL;\r
-        QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);\r
-        QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);\r
-        XMLObjectBuilder::registerBuilder(qname, new SimpleXMLObjectBuilder());\r
-        XMLObjectBuilder::registerBuilder(qtype, new SimpleXMLObjectBuilder());\r
-\r
-        string config = data_path + "FilesystemCredentialResolver.xml";\r
-        ifstream in(config.c_str());\r
-        DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(in);\r
-        XercesJanitor<DOMDocument> janitor(doc);\r
-        m_resolver = XMLToolingConfig::getConfig().CredentialResolverManager.newPlugin(\r
-            FILESYSTEM_CREDENTIAL_RESOLVER,doc->getDocumentElement()\r
-            );\r
-    }\r
-\r
-    void tearDown() {\r
-        QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);\r
-        QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);\r
-        XMLObjectBuilder::deregisterBuilder(qname);\r
-        XMLObjectBuilder::deregisterBuilder(qtype);\r
-        delete m_resolver;\r
-    }\r
-\r
-    void testSignature() {\r
-        QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);\r
-        const SimpleXMLObjectBuilder* b=dynamic_cast<const SimpleXMLObjectBuilder*>(XMLObjectBuilder::getBuilder(qname));\r
-        TS_ASSERT(b!=NULL);\r
-        \r
-        auto_ptr<SimpleXMLObject> sxObject(b->buildObject());\r
-        TS_ASSERT(sxObject.get()!=NULL);\r
-        VectorOf(SimpleXMLObject) kids=sxObject->getSimpleXMLObjects();\r
-        kids.push_back(b->buildObject());\r
-        kids.push_back(b->buildObject());\r
-        \r
-        // Test some collection stuff\r
-        auto_ptr_XMLCh foo("Foo");\r
-        auto_ptr_XMLCh bar("Bar");\r
-        kids.begin()->setId(foo.get());\r
-        kids[1]->setValue(bar.get());\r
-        \r
-        // Append a Signature.\r
-        Signature* sig=SignatureBuilder::buildSignature();\r
-        sxObject->setSignature(sig);\r
-        sig->setContentReference(new TestContext(&chNull));\r
-\r
-        Locker locker(m_resolver);\r
-        sig->setSigningKey(m_resolver->getKey());\r
-        \r
-        // Build KeyInfo.\r
-        KeyInfo* keyInfo=KeyInfoBuilder::buildKeyInfo();\r
-        X509Data* x509Data=X509DataBuilder::buildX509Data();\r
-        keyInfo->getX509Datas().push_back(x509Data);\r
-        for_each(m_resolver->getCertificates().begin(),m_resolver->getCertificates().end(),bind1st(_addcert(),x509Data));\r
-        sig->setKeyInfo(keyInfo);\r
-        \r
-        DOMElement* rootElement = NULL;\r
-        try {\r
-            rootElement=sxObject->marshall((DOMDocument*)NULL);\r
-            sig->sign();\r
-        }\r
-        catch (XMLToolingException& e) {\r
-            TS_TRACE(e.what());\r
-            throw;\r
-        }\r
-        \r
-        string buf;\r
-        XMLHelper::serialize(rootElement, buf);\r
-        //TS_TRACE(buf.c_str());\r
-\r
-        istringstream in(buf);\r
-        DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(in);\r
-        auto_ptr<SimpleXMLObject> sxObject2(dynamic_cast<SimpleXMLObject*>(b->buildFromDocument(doc)));\r
-        TS_ASSERT(sxObject2.get()!=NULL);\r
-        TS_ASSERT(sxObject2->getSignature()!=NULL);\r
-        \r
-        try {\r
-            TestValidator tv(&chNull);\r
-            tv.validate(sxObject2->getSignature());\r
-        }\r
-        catch (XMLToolingException& e) {\r
-            TS_TRACE(e.what());\r
-            throw;\r
-        }\r
-    }\r
-\r
-};\r
+/*
+ *  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 <xmltooling/signature/CredentialResolver.h>
+#include <xmltooling/signature/KeyInfo.h>
+#include <xmltooling/signature/SignatureValidator.h>
+
+#include <fstream>
+#include <xercesc/util/XMLUniDefs.hpp>
+#include <xsec/dsig/DSIGReference.hpp>
+
+class TestContext : public ContentReference
+{
+    XMLCh* m_uri;
+    
+public:
+    TestContext(const XMLCh* uri) {
+        m_uri=XMLString::replicate(uri);
+    }
+    
+    virtual ~TestContext() {
+        XMLString::release(&m_uri);
+    }
+
+    void createReferences(DSIGSignature* sig) {
+        DSIGReference* ref=sig->createReference(m_uri);
+        ref->appendEnvelopedSignatureTransform();
+        ref->appendCanonicalizationTransform(CANON_C14NE_NOC);
+    }
+};
+
+class TestValidator : public SignatureValidator
+{
+    XMLCh* m_uri;
+    
+public:
+    TestValidator(const XMLCh* uri) : SignatureValidator(XMLToolingConfig::getConfig().KeyResolverManager.newPlugin(INLINE_KEY_RESOLVER,NULL)) {
+        m_uri=XMLString::replicate(uri);
+    }
+    
+    virtual ~TestValidator() {
+        XMLString::release(&m_uri);
+    }
+
+    void validate(const Signature* sigObj) const {
+        DSIGSignature* sig=sigObj->getXMLSignature();
+        if (!sig)
+            throw SignatureException("Only a marshalled Signature object can be verified.");
+        const XMLCh* uri=sig->getReferenceList()->item(0)->getURI();
+        TSM_ASSERT_SAME_DATA("Reference URI does not match.",uri,m_uri,XMLString::stringLen(uri));
+        SignatureValidator::validate(sigObj);
+    }
+};
+
+class _addcert : public std::binary_function<X509Data*,XSECCryptoX509*,void> {
+public:
+    void operator()(X509Data* bag, XSECCryptoX509* cert) const {
+        safeBuffer& buf=cert->getDEREncodingSB();
+        X509Certificate* x=X509CertificateBuilder::buildX509Certificate();
+        x->setValue(buf.sbStrToXMLCh());
+        bag->getX509Certificates().push_back(x);
+    }
+};
+
+class SignatureTest : public CxxTest::TestSuite {
+    CredentialResolver* m_resolver;
+public:
+    void setUp() {
+        m_resolver=NULL;
+        QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);
+        QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);
+        XMLObjectBuilder::registerBuilder(qname, new SimpleXMLObjectBuilder());
+        XMLObjectBuilder::registerBuilder(qtype, new SimpleXMLObjectBuilder());
+
+        string config = data_path + "FilesystemCredentialResolver.xml";
+        ifstream in(config.c_str());
+        DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(in);
+        XercesJanitor<DOMDocument> janitor(doc);
+        m_resolver = XMLToolingConfig::getConfig().CredentialResolverManager.newPlugin(
+            FILESYSTEM_CREDENTIAL_RESOLVER,doc->getDocumentElement()
+            );
+    }
+
+    void tearDown() {
+        QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);
+        QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);
+        XMLObjectBuilder::deregisterBuilder(qname);
+        XMLObjectBuilder::deregisterBuilder(qtype);
+        delete m_resolver;
+    }
+
+    void testSignature() {
+        QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);
+        const SimpleXMLObjectBuilder* b=dynamic_cast<const SimpleXMLObjectBuilder*>(XMLObjectBuilder::getBuilder(qname));
+        TS_ASSERT(b!=NULL);
+        
+        auto_ptr<SimpleXMLObject> sxObject(b->buildObject());
+        TS_ASSERT(sxObject.get()!=NULL);
+        VectorOf(SimpleXMLObject) kids=sxObject->getSimpleXMLObjects();
+        kids.push_back(b->buildObject());
+        kids.push_back(b->buildObject());
+        
+        // Test some collection stuff
+        auto_ptr_XMLCh foo("Foo");
+        auto_ptr_XMLCh bar("Bar");
+        kids.begin()->setId(foo.get());
+        kids[1]->setValue(bar.get());
+        
+        // Append a Signature.
+        Signature* sig=SignatureBuilder::buildSignature();
+        sxObject->setSignature(sig);
+        sig->setContentReference(new TestContext(&chNull));
+
+        Locker locker(m_resolver);
+        sig->setSigningKey(m_resolver->getKey());
+        
+        // Build KeyInfo.
+        KeyInfo* keyInfo=KeyInfoBuilder::buildKeyInfo();
+        X509Data* x509Data=X509DataBuilder::buildX509Data();
+        keyInfo->getX509Datas().push_back(x509Data);
+        for_each(m_resolver->getCertificates().begin(),m_resolver->getCertificates().end(),bind1st(_addcert(),x509Data));
+        sig->setKeyInfo(keyInfo);
+        
+        DOMElement* rootElement = NULL;
+        try {
+            rootElement=sxObject->marshall((DOMDocument*)NULL);
+            sig->sign();
+        }
+        catch (XMLToolingException& e) {
+            TS_TRACE(e.what());
+            throw;
+        }
+        
+        string buf;
+        XMLHelper::serialize(rootElement, buf);
+        //TS_TRACE(buf.c_str());
+
+        istringstream in(buf);
+        DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(in);
+        auto_ptr<SimpleXMLObject> sxObject2(dynamic_cast<SimpleXMLObject*>(b->buildFromDocument(doc)));
+        TS_ASSERT(sxObject2.get()!=NULL);
+        TS_ASSERT(sxObject2->getSignature()!=NULL);
+        
+        try {
+            TestValidator tv(&chNull);
+            tv.validate(sxObject2->getSignature());
+        }
+        catch (XMLToolingException& e) {
+            TS_TRACE(e.what());
+            throw;
+        }
+    }
+
+};
index b645f11..255168c 100644 (file)
-/*\r
- *  Copyright 2001-2005 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#include "XMLObjectBaseTestCase.h"\r
-\r
-#include <fstream>\r
-#include <xercesc/util/XMLUniDefs.hpp>\r
-\r
-const XMLCh SimpleXMLObject::NAMESPACE[] = {\r
-    chLatin_h, chLatin_t, chLatin_t, chLatin_p, chColon, chForwardSlash, chForwardSlash,\r
-    chLatin_w, chLatin_w, chLatin_w, chPeriod,\r
-    chLatin_e, chLatin_x, chLatin_a, chLatin_m, chLatin_p, chLatin_l, chLatin_e, chPeriod,\r
-    chLatin_o, chLatin_r, chLatin_g, chForwardSlash,\r
-    chLatin_t, chLatin_e, chLatin_s, chLatin_t,\r
-    chLatin_O, chLatin_b, chLatin_j, chLatin_e, chLatin_c, chLatin_t, chLatin_s, chNull\r
-};\r
-\r
-const XMLCh SimpleXMLObject::NAMESPACE_PREFIX[] = {\r
-    chLatin_t, chLatin_e, chLatin_s, chLatin_t, chNull\r
-};\r
-\r
-const XMLCh SimpleXMLObject::LOCAL_NAME[] = {\r
-    chLatin_S, chLatin_i, chLatin_m, chLatin_p, chLatin_l, chLatin_e,\r
-    chLatin_E, chLatin_l, chLatin_e, chLatin_m, chLatin_e, chLatin_n, chLatin_t, chNull\r
-};\r
-\r
-const XMLCh SimpleXMLObject::DERIVED_NAME[] = {\r
-    chLatin_D, chLatin_e, chLatin_r, chLatin_i, chLatin_v, chLatin_e, chLatin_d,\r
-    chLatin_E, chLatin_l, chLatin_e, chLatin_m, chLatin_e, chLatin_n, chLatin_t, chNull\r
-};\r
-\r
-const XMLCh SimpleXMLObject::TYPE_NAME[] = {\r
-    chLatin_S, chLatin_i, chLatin_m, chLatin_p, chLatin_l, chLatin_e,\r
-    chLatin_E, chLatin_l, chLatin_e, chLatin_m, chLatin_e, chLatin_n, chLatin_t, \r
-    chLatin_T, chLatin_y, chLatin_p, chLatin_e, chNull\r
-};\r
-\r
-const XMLCh SimpleXMLObject::ID_ATTRIB_NAME[] = {\r
-    chLatin_I, chLatin_d, chNull\r
-};\r
-\r
-class UnmarshallingTest : public CxxTest::TestSuite {\r
-public:\r
-    void setUp() {\r
-        QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);\r
-        QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);\r
-        XMLObjectBuilder::registerBuilder(qname, new SimpleXMLObjectBuilder());\r
-        XMLObjectBuilder::registerBuilder(qtype, new SimpleXMLObjectBuilder());\r
-    }\r
-\r
-    void tearDown() {\r
-        QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);\r
-        QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);\r
-        XMLObjectBuilder::deregisterBuilder(qname);\r
-        XMLObjectBuilder::deregisterBuilder(qtype);\r
-    }\r
-\r
-    void testUnmarshallingWithAttributes() {\r
-        string path=data_path + "SimpleXMLObjectWithAttribute.xml";\r
-        ifstream fs(path.c_str());\r
-        DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(fs);\r
-        TS_ASSERT(doc!=NULL);\r
-\r
-        const XMLObjectBuilder* b = XMLObjectBuilder::getBuilder(doc->getDocumentElement());\r
-        TS_ASSERT(b!=NULL);\r
-\r
-        auto_ptr<SimpleXMLObject> sxObject(\r
-            dynamic_cast<SimpleXMLObject*>(b->buildFromDocument(doc))\r
-            );\r
-        TS_ASSERT(sxObject.get()!=NULL);\r
-\r
-        auto_ptr_XMLCh expected("Firefly");\r
-        TSM_ASSERT("ID was not expected value", XMLString::equals(expected.get(), sxObject->getId()));\r
-    }\r
-\r
-    void testUnmarshallingWithElementContent() {\r
-        string path=data_path + "SimpleXMLObjectWithContent.xml";\r
-        ifstream fs(path.c_str());\r
-        DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(fs);\r
-        TS_ASSERT(doc!=NULL);\r
-\r
-        const XMLObjectBuilder* b = XMLObjectBuilder::getBuilder(doc->getDocumentElement());\r
-        TS_ASSERT(b!=NULL);\r
-\r
-        auto_ptr<SimpleXMLObject> sxObject(\r
-            dynamic_cast<SimpleXMLObject*>(b->buildFromDocument(doc))\r
-            );\r
-        TS_ASSERT(sxObject.get()!=NULL);\r
-\r
-        auto_ptr_XMLCh expected("Sample Content");\r
-        TSM_ASSERT("Element content was not expected value", XMLString::equals(expected.get(), sxObject->getValue()));\r
-    }\r
-\r
-    void testUnmarshallingWithChildElements() {\r
-        string path=data_path + "SimpleXMLObjectWithChildren.xml";\r
-        ifstream fs(path.c_str());\r
-        DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(fs);\r
-        TS_ASSERT(doc!=NULL);\r
-\r
-        const XMLObjectBuilder* b = XMLObjectBuilder::getBuilder(doc->getDocumentElement());\r
-        TS_ASSERT(b!=NULL);\r
-\r
-        auto_ptr<SimpleXMLObject> sxObject(\r
-            dynamic_cast<SimpleXMLObject*>(b->buildFromDocument(doc))\r
-            );\r
-        TS_ASSERT(sxObject.get()!=NULL);\r
-\r
-        VectorOf(SimpleXMLObject) kids=sxObject->getSimpleXMLObjects();\r
-        TSM_ASSERT_EQUALS("Number of child elements was not expected value", 3, kids.size());\r
-        QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);\r
-        TSM_ASSERT_EQUALS("Child's schema type was not expected value", qtype, *(kids.back()->getSchemaType()));\r
-    }\r
-\r
-    void testUnmarshallingWithClone() {\r
-        string path=data_path + "SimpleXMLObjectWithChildren.xml";\r
-        ifstream fs(path.c_str());\r
-        DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(fs);\r
-        TS_ASSERT(doc!=NULL);\r
-\r
-        const XMLObjectBuilder* b = XMLObjectBuilder::getBuilder(doc->getDocumentElement());\r
-        TS_ASSERT(b!=NULL);\r
-\r
-        auto_ptr<SimpleXMLObject> sxObject(\r
-            dynamic_cast<SimpleXMLObject*>(b->buildFromDocument(doc))\r
-            );\r
-        TS_ASSERT(sxObject.get()!=NULL);\r
-\r
-        sxObject->releaseThisAndChildrenDOM();\r
-        auto_ptr<SimpleXMLObject> clonedObject(sxObject->clone());\r
-\r
-        VectorOf(SimpleXMLObject) kids=clonedObject->getSimpleXMLObjects();\r
-        TSM_ASSERT_EQUALS("Number of child elements was not expected value", 3, kids.size());\r
-        QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);\r
-        TSM_ASSERT_EQUALS("Child's schema type was not expected value", qtype, *(kids.back()->getSchemaType()));\r
-    }\r
-\r
-    void testUnmarshallingWithUnknownChild() {\r
-        string path=data_path + "SimpleXMLObjectWithUnknownChild.xml";\r
-        ifstream fs(path.c_str());\r
-        DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(fs);\r
-        TS_ASSERT(doc!=NULL);\r
-\r
-        const XMLObjectBuilder* b = XMLObjectBuilder::getBuilder(doc->getDocumentElement());\r
-        TS_ASSERT(b!=NULL);\r
-\r
-        TS_ASSERT_THROWS(b->buildFromDocument(doc),UnmarshallingException);\r
-        doc->release();\r
-    }\r
-};\r
+/*
+ *  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 <fstream>
+#include <xercesc/util/XMLUniDefs.hpp>
+
+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::DERIVED_NAME[] = {
+    chLatin_D, chLatin_e, chLatin_r, chLatin_i, chLatin_v, chLatin_e, chLatin_d,
+    chLatin_E, chLatin_l, chLatin_e, chLatin_m, chLatin_e, chLatin_n, chLatin_t, chNull
+};
+
+const XMLCh SimpleXMLObject::TYPE_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, 
+    chLatin_T, chLatin_y, chLatin_p, chLatin_e, chNull
+};
+
+const XMLCh SimpleXMLObject::ID_ATTRIB_NAME[] = {
+    chLatin_I, chLatin_d, chNull
+};
+
+class UnmarshallingTest : public CxxTest::TestSuite {
+public:
+    void setUp() {
+        QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);
+        QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);
+        XMLObjectBuilder::registerBuilder(qname, new SimpleXMLObjectBuilder());
+        XMLObjectBuilder::registerBuilder(qtype, new SimpleXMLObjectBuilder());
+    }
+
+    void tearDown() {
+        QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);
+        QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);
+        XMLObjectBuilder::deregisterBuilder(qname);
+        XMLObjectBuilder::deregisterBuilder(qtype);
+    }
+
+    void testUnmarshallingWithAttributes() {
+        string path=data_path + "SimpleXMLObjectWithAttribute.xml";
+        ifstream fs(path.c_str());
+        DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(fs);
+        TS_ASSERT(doc!=NULL);
+
+        const XMLObjectBuilder* b = XMLObjectBuilder::getBuilder(doc->getDocumentElement());
+        TS_ASSERT(b!=NULL);
+
+        auto_ptr<SimpleXMLObject> sxObject(
+            dynamic_cast<SimpleXMLObject*>(b->buildFromDocument(doc))
+            );
+        TS_ASSERT(sxObject.get()!=NULL);
+
+        auto_ptr_XMLCh expected("Firefly");
+        TSM_ASSERT("ID was not expected value", XMLString::equals(expected.get(), sxObject->getId()));
+    }
+
+    void testUnmarshallingWithElementContent() {
+        string path=data_path + "SimpleXMLObjectWithContent.xml";
+        ifstream fs(path.c_str());
+        DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(fs);
+        TS_ASSERT(doc!=NULL);
+
+        const XMLObjectBuilder* b = XMLObjectBuilder::getBuilder(doc->getDocumentElement());
+        TS_ASSERT(b!=NULL);
+
+        auto_ptr<SimpleXMLObject> sxObject(
+            dynamic_cast<SimpleXMLObject*>(b->buildFromDocument(doc))
+            );
+        TS_ASSERT(sxObject.get()!=NULL);
+
+        auto_ptr_XMLCh expected("Sample Content");
+        TSM_ASSERT("Element content was not expected value", XMLString::equals(expected.get(), sxObject->getValue()));
+    }
+
+    void testUnmarshallingWithChildElements() {
+        string path=data_path + "SimpleXMLObjectWithChildren.xml";
+        ifstream fs(path.c_str());
+        DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(fs);
+        TS_ASSERT(doc!=NULL);
+
+        const XMLObjectBuilder* b = XMLObjectBuilder::getBuilder(doc->getDocumentElement());
+        TS_ASSERT(b!=NULL);
+
+        auto_ptr<SimpleXMLObject> sxObject(
+            dynamic_cast<SimpleXMLObject*>(b->buildFromDocument(doc))
+            );
+        TS_ASSERT(sxObject.get()!=NULL);
+
+        VectorOf(SimpleXMLObject) kids=sxObject->getSimpleXMLObjects();
+        TSM_ASSERT_EQUALS("Number of child elements was not expected value", 3, kids.size());
+        QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);
+        TSM_ASSERT_EQUALS("Child's schema type was not expected value", qtype, *(kids.back()->getSchemaType()));
+    }
+
+    void testUnmarshallingWithClone() {
+        string path=data_path + "SimpleXMLObjectWithChildren.xml";
+        ifstream fs(path.c_str());
+        DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(fs);
+        TS_ASSERT(doc!=NULL);
+
+        const XMLObjectBuilder* b = XMLObjectBuilder::getBuilder(doc->getDocumentElement());
+        TS_ASSERT(b!=NULL);
+
+        auto_ptr<SimpleXMLObject> sxObject(
+            dynamic_cast<SimpleXMLObject*>(b->buildFromDocument(doc))
+            );
+        TS_ASSERT(sxObject.get()!=NULL);
+
+        sxObject->releaseThisAndChildrenDOM();
+        auto_ptr<SimpleXMLObject> clonedObject(sxObject->clone());
+
+        VectorOf(SimpleXMLObject) kids=clonedObject->getSimpleXMLObjects();
+        TSM_ASSERT_EQUALS("Number of child elements was not expected value", 3, kids.size());
+        QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);
+        TSM_ASSERT_EQUALS("Child's schema type was not expected value", qtype, *(kids.back()->getSchemaType()));
+    }
+
+    void testUnmarshallingWithUnknownChild() {
+        string path=data_path + "SimpleXMLObjectWithUnknownChild.xml";
+        ifstream fs(path.c_str());
+        DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(fs);
+        TS_ASSERT(doc!=NULL);
+
+        const XMLObjectBuilder* b = XMLObjectBuilder::getBuilder(doc->getDocumentElement());
+        TS_ASSERT(b!=NULL);
+
+        TS_ASSERT_THROWS(b->buildFromDocument(doc),UnmarshallingException);
+        doc->release();
+    }
+};
index 6507143..dc76d97 100644 (file)
-/*\r
- *  Copyright 2001-2005 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#include "XMLObjectBaseTestCase.h"\r
-\r
-#include <fstream>\r
-#include <cxxtest/GlobalFixture.h>\r
-#include <xmltooling/XMLToolingConfig.h>\r
-#include <xmltooling/util/ParserPool.h>\r
-\r
-//#define XMLTOOLINGTEST_LEAKCHECK\r
-\r
-std::string data_path = "../xmltoolingtest/data/";\r
-\r
-class ToolingFixture : public CxxTest::GlobalFixture\r
-{\r
-public:\r
-    bool setUpWorld() {\r
-        XMLToolingConfig::getConfig().log_config();\r
-\r
-        if (getenv("XMLTOOLINGTEST_DATA"))\r
-            data_path=std::string(getenv("XMLTOOLINGTEST_DATA")) + "/";\r
-        XMLToolingConfig::getConfig().catalog_path = data_path + "catalog.xml";\r
-\r
-        if (!XMLToolingConfig::getConfig().init())\r
-            return false;\r
-        \r
-        return true;\r
-    }\r
-    bool tearDownWorld() {\r
-        XMLToolingConfig::getConfig().term();\r
-#if defined(_MSC_VER ) && defined(XMLTOOLINGTEST_LEAKCHECK)\r
-       _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );\r
-       _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT );\r
-       _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );\r
-       _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT );\r
-       _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );\r
-       _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDOUT );\r
-       _CrtDumpMemoryLeaks();\r
-#endif\r
-        return true;\r
-    }\r
-    //bool setUp() { printf( "</test>" ); return true; }\r
-    //bool tearDown() { printf( "</test>" ); return true; }\r
-};\r
-\r
-static ToolingFixture globalFixture;\r
-\r
-class GlobalTest : public CxxTest::TestSuite\r
-{\r
-public:\r
-    void setUp() {\r
-        XMLObjectBuilder::registerDefaultBuilder(new UnknownElementBuilder());\r
-    }\r
-\r
-    void tearDown() {\r
-        XMLObjectBuilder::deregisterDefaultBuilder();\r
-    }\r
-\r
-    void testUnknown() {\r
-        ifstream fs("../xmltoolingtest/data/SimpleXMLObjectWithChildren.xml");\r
-        DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(fs);\r
-        TS_ASSERT(doc!=NULL);\r
-\r
-        string buf1;\r
-        XMLHelper::serialize(doc->getDocumentElement(), buf1);\r
-\r
-        const XMLObjectBuilder* b=XMLObjectBuilder::getBuilder(doc->getDocumentElement());\r
-        TS_ASSERT(b!=NULL);\r
-\r
-        auto_ptr<XMLObject> xmlObject(b->buildFromDocument(doc)); // bind document\r
-        TS_ASSERT(xmlObject.get()!=NULL);\r
-\r
-        auto_ptr<XMLObject> clonedObject(xmlObject->clone());\r
-        TS_ASSERT(clonedObject.get()!=NULL);\r
-\r
-        DOMElement* rootElement=clonedObject->marshall();\r
-        TS_ASSERT(rootElement!=NULL);\r
-\r
-        // should reuse DOM\r
-        TS_ASSERT(rootElement==clonedObject->marshall());\r
-\r
-        string buf2;\r
-        XMLHelper::serialize(rootElement, buf2);\r
-        TS_ASSERT_EQUALS(buf1,buf2);\r
-    }\r
-\r
-    void testUnknownWithDocChange() {\r
-        ifstream fs("../xmltoolingtest/data/SimpleXMLObjectWithChildren.xml");\r
-        DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(fs);\r
-        TS_ASSERT(doc!=NULL);\r
-\r
-        string buf1;\r
-        XMLHelper::serialize(doc->getDocumentElement(), buf1);\r
-\r
-        const XMLObjectBuilder* b=XMLObjectBuilder::getBuilder(doc->getDocumentElement());\r
-        TS_ASSERT(b!=NULL);\r
-\r
-        auto_ptr<XMLObject> xmlObject(b->buildFromDocument(doc)); // bind document\r
-        TS_ASSERT(xmlObject.get()!=NULL);\r
-\r
-        DOMDocument* newDoc=XMLToolingConfig::getConfig().getParser().newDocument();\r
-        DOMElement* rootElement=xmlObject->marshall(newDoc);\r
-        TS_ASSERT(rootElement!=NULL);\r
-\r
-        string buf2;\r
-        XMLHelper::serialize(rootElement, buf2);\r
-        TS_ASSERT_EQUALS(buf1,buf2);\r
-\r
-        newDoc->release();\r
-    }\r
-};\r
-\r
+/*
+ *  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 <fstream>
+#include <cxxtest/GlobalFixture.h>
+#include <xmltooling/XMLToolingConfig.h>
+#include <xmltooling/util/ParserPool.h>
+
+//#define XMLTOOLINGTEST_LEAKCHECK
+
+std::string data_path = "../xmltoolingtest/data/";
+
+class ToolingFixture : public CxxTest::GlobalFixture
+{
+public:
+    bool setUpWorld() {
+        XMLToolingConfig::getConfig().log_config();
+
+        if (getenv("XMLTOOLINGTEST_DATA"))
+            data_path=std::string(getenv("XMLTOOLINGTEST_DATA")) + "/";
+        XMLToolingConfig::getConfig().catalog_path = data_path + "catalog.xml";
+
+        if (!XMLToolingConfig::getConfig().init())
+            return false;
+        
+        return true;
+    }
+    bool tearDownWorld() {
+        XMLToolingConfig::getConfig().term();
+#if defined(_MSC_VER ) && defined(XMLTOOLINGTEST_LEAKCHECK)
+       _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
+       _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT );
+       _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
+       _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT );
+       _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
+       _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDOUT );
+       _CrtDumpMemoryLeaks();
+#endif
+        return true;
+    }
+    //bool setUp() { printf( "</test>" ); return true; }
+    //bool tearDown() { printf( "</test>" ); return true; }
+};
+
+static ToolingFixture globalFixture;
+
+class GlobalTest : public CxxTest::TestSuite
+{
+public:
+    void setUp() {
+        XMLObjectBuilder::registerDefaultBuilder(new UnknownElementBuilder());
+    }
+
+    void tearDown() {
+        XMLObjectBuilder::deregisterDefaultBuilder();
+    }
+
+    void testUnknown() {
+        ifstream fs("../xmltoolingtest/data/SimpleXMLObjectWithChildren.xml");
+        DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(fs);
+        TS_ASSERT(doc!=NULL);
+
+        string buf1;
+        XMLHelper::serialize(doc->getDocumentElement(), buf1);
+
+        const XMLObjectBuilder* b=XMLObjectBuilder::getBuilder(doc->getDocumentElement());
+        TS_ASSERT(b!=NULL);
+
+        auto_ptr<XMLObject> xmlObject(b->buildFromDocument(doc)); // bind document
+        TS_ASSERT(xmlObject.get()!=NULL);
+
+        auto_ptr<XMLObject> clonedObject(xmlObject->clone());
+        TS_ASSERT(clonedObject.get()!=NULL);
+
+        DOMElement* rootElement=clonedObject->marshall();
+        TS_ASSERT(rootElement!=NULL);
+
+        // should reuse DOM
+        TS_ASSERT(rootElement==clonedObject->marshall());
+
+        string buf2;
+        XMLHelper::serialize(rootElement, buf2);
+        TS_ASSERT_EQUALS(buf1,buf2);
+    }
+
+    void testUnknownWithDocChange() {
+        ifstream fs("../xmltoolingtest/data/SimpleXMLObjectWithChildren.xml");
+        DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(fs);
+        TS_ASSERT(doc!=NULL);
+
+        string buf1;
+        XMLHelper::serialize(doc->getDocumentElement(), buf1);
+
+        const XMLObjectBuilder* b=XMLObjectBuilder::getBuilder(doc->getDocumentElement());
+        TS_ASSERT(b!=NULL);
+
+        auto_ptr<XMLObject> xmlObject(b->buildFromDocument(doc)); // bind document
+        TS_ASSERT(xmlObject.get()!=NULL);
+
+        DOMDocument* newDoc=XMLToolingConfig::getConfig().getParser().newDocument();
+        DOMElement* rootElement=xmlObject->marshall(newDoc);
+        TS_ASSERT(rootElement!=NULL);
+
+        string buf2;
+        XMLHelper::serialize(rootElement, buf2);
+        TS_ASSERT_EQUALS(buf1,buf2);
+
+        newDoc->release();
+    }
+};
+