-/*\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);
+ }
+}
-/*\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__ */
-/*\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__ */
-/*\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();
+}
-/*\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__ */
-/*\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__ */
-/*\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.");
+}
-/*\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__ */
-/*\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;
+}
-/*\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__ */
-/*\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__ */
-/*\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__ */
-/*\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__ */
-/*\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;
+}
-/*\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__ */
-/*\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__ */
-/*\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();
+}
-/*\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__ */
-/*\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__ */
-/*\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();
+}
-/*\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__ */
-/* 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 */
-/*\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__ */
-/*\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;
+}
-/*\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);
+}
+
-/*\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__ */
-/*\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));
+}
-/*\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__ */
-/*\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__ */
-/*\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__ */
+
-/*\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><KeyResolver> 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><KeyResolver> 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__ */
-/*\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><KeyResolver> 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><KeyResolver> 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__ */
-/*\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__ */
+
+
-/*\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;
+}
-/*\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);
+
+}
-/*\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);
+
+}
+
-/*\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__ */
-/*\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__ */
-/*\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__ */
-/*\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__ */
-/*\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__ */
-/*\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__ */
-/*\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__ */
-/*\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;
+}
-/*\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;
+}
-/*\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());
+ }
+}
-/*\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);
}
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());
-/*\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;
+}
-/*\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__ */
-/*\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;
+}
+
-/*\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
-/*\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();
+}
-/*\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__ */
-/*\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 <uri> 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 <uri> 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__ */
-/*\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__ */
-/*\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__ */
-/*\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);
+}
-/*\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 };
-/*\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__ */
-/*\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());
+}
-/*\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__ */
-/*\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__ */
-/*\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);
+}
-/*\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__ */
-/*\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__
-/*\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()));
+ }
+
+};
-/*\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;
+ }
+ }
+
+};
-/*\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."));
+ }
+};
-/*\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());
+ }
+};
-/*\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);
+ }
+};
-/*\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);
+ }
+};
-/*\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();
+ }
+
+};
-/*\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");
+ }
+};
-/*\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;
+ }
+ }
+
+};
-/*\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();
+ }
+};
-/*\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();
+ }
+};
+