-/*\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() {\r
- delete m_typeQname;\r
- std::for_each(m_children.begin(), m_children.end(), cleanup<XMLObject>());\r
-}\r
-\r
-AbstractXMLObject::AbstractXMLObject(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)\r
- : m_elementQname(nsURI, localName, prefix), m_typeQname(NULL), m_parent(NULL),\r
- m_log(&log4cpp::Category::getInstance(XMLTOOLING_LOGCAT".XMLObject"))\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_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
-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
- return newValue;\r
- }\r
- else {\r
- return NULL;\r
- }\r
- }\r
-\r
- if (oldValue != newValue) {\r
- delete oldValue;\r
- releaseThisandParentDOM();\r
- newValue->setParent(this);\r
- }\r
-\r
- return newValue;\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() {
+ delete m_typeQname;
+ std::for_each(m_children.begin(), m_children.end(), cleanup<XMLObject>());
+}
+
+AbstractXMLObject::AbstractXMLObject(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+ : m_log(&log4cpp::Category::getInstance(XMLTOOLING_LOGCAT".XMLObject")),
+ 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_parent(NULL), m_elementQname(src.m_elementQname), m_typeQname(NULL)
+{
+ if (src.m_typeQname)
+ m_typeQname=new QName(*src.m_typeQname);
+}
+
+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;
+ }
+ else {
+ return NULL;
+ }
+ }
+
+ if (oldValue != newValue) {
+ delete oldValue;
+ releaseThisandParentDOM();
+ newValue->setParent(this);
+ }
+
+ return newValue;
+}
AbstractAttributeExtensibleXMLObject.h \
AbstractDOMCachingXMLObject.h \
AbstractElementProxy.h \
- AbstractValidatingXMLObject.h \
AbstractXMLObject.h \
AttributeExtensibleXMLObject.h \
base.h \
Namespace.h \
QName.h \
unicode.h \
- ValidatingXMLObject.h \
version.h \
XMLObject.h \
XMLObjectBuilder.h \
util/XMLObjectChildrenList.h
valinclude_HEADERS = \
+ validation/AbstractValidatingXMLObject.h \
+ validation/ValidatingXMLObject.h \
validation/Validator.h
noinst_HEADERS = \
if BUILD_XMLSEC
xmlsec_sources = \
- signature/impl/KeyInfoImpl.cpp \
signature/impl/XMLSecSignatureImpl.cpp
else
xmlsec_sources =
impl/UnknownElement.cpp \
io/AbstractXMLObjectMarshaller.cpp \
io/AbstractXMLObjectUnmarshaller.cpp \
+ signature/impl/KeyInfoImpl.cpp \
util/NDC.cpp \
util/ParserPool.cpp \
util/XMLConstants.cpp \
#define NULL 0
#endif
+#ifdef _MSC_VER
+ #define XMLTOOLING_DOXYGEN(desc) /##** desc */
+#else
+ #define XMLTOOLING_DOXYGEN(desc)
+#endif
+
/**
* Blocks copy c'tor and assignment operator for a class.
*/
cname() {} \
public: \
virtual ~cname() {} \
- /##** Type-specific clone method. */ \
+ XMLTOOLING_DOXYGEN(Type-specific clone method.) \
virtual cname* clone##cname() const=0; \
- /##** Element prefix */ \
+ XMLTOOLING_DOXYGEN(Element prefix) \
static const XMLCh PREFIX[]; \
- /##** Element local name */ \
+ XMLTOOLING_DOXYGEN(Element local name) \
static const XMLCh LOCAL_NAME[]
/**
* @param upcased the upcased name of the attribute
*/
#define DECL_XMLOBJECT_ATTRIB(proper,upcased) \
- /##** proper attribute name */ \
+ XMLTOOLING_DOXYGEN(proper attribute name) \
static const XMLCh upcased##_ATTRIB_NAME[]; \
- /##** Returns the proper attribute. */ \
+ XMLTOOLING_DOXYGEN(Returns the proper attribute.) \
virtual const XMLCh* get##proper() const=0; \
- /##** Sets the proper attribute. */ \
+ XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
virtual void set##proper(const XMLCh* proper)=0
/**
* @param cname the name of the XMLObject specialization
*/
#define BEGIN_XMLOBJECTBUILDER(cname) \
- /##** Builder for cname objects. */ \
+ XMLTOOLING_DOXYGEN(Builder for cname objects.) \
class XMLTOOL_API cname##Builder : public xmltooling::XMLObjectBuilder { \
public: \
virtual ~cname##Builder() {} \
- /##** Default builder. */ \
+ XMLTOOLING_DOXYGEN(Default builder.) \
virtual cname* buildObject() const=0
/**
-/*\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
- * exceptions.cpp\r
- * \r
- * Exception classes\r
- */\r
- \r
-#include "internal.h"\r
-#include "exceptions.h"\r
-#include "XMLToolingConfig.h"\r
-#include "util/XMLConstants.h"\r
-#include "util/XMLHelper.h"\r
-\r
-#include <sstream>\r
-#include <xercesc/util/XMLUniDefs.hpp>\r
-\r
-using namespace xmltooling;\r
-using namespace std;\r
-\r
-params::params(int count,...)\r
-{\r
- va_list args;\r
- va_start(args,count);\r
- while (count--)\r
- v.push_back(va_arg(args,char*));\r
- va_end(args);\r
-}\r
-\r
-namedparams::namedparams(int count,...)\r
-{\r
- count*=2;\r
- va_list args;\r
- va_start(args,count);\r
- while (count--)\r
- v.push_back(va_arg(args,char*));\r
- va_end(args);\r
-}\r
-\r
-XMLToolingException::ExceptionFactoryMap XMLToolingException::m_factoryMap;\r
-\r
-XMLToolingException* XMLToolingException::getInstance(const char* exceptionClass)\r
-{\r
- if (exceptionClass) {\r
- ExceptionFactoryMap::const_iterator i=m_factoryMap.find(exceptionClass);\r
- if (i!=m_factoryMap.end())\r
- return (i->second)();\r
- }\r
- return new XMLToolingException();\r
-}\r
-\r
-XMLToolingException::XMLToolingException(const char* msg, const params& p)\r
-{\r
- if (msg)\r
- m_msg=msg;\r
- addProperties(p);\r
-}\r
-\r
-XMLToolingException::XMLToolingException(const char* msg, const namedparams& p)\r
-{\r
- if (msg)\r
- m_msg=msg;\r
- addProperties(p);\r
-}\r
-\r
-XMLToolingException::XMLToolingException(const std::string& msg, const params& p) : m_msg(msg)\r
-{\r
- addProperties(p);\r
-}\r
-\r
-XMLToolingException::XMLToolingException(const std::string& msg, const namedparams& p) : m_msg(msg)\r
-{\r
- addProperties(p);\r
-}\r
-\r
-void XMLToolingException::setMessage(const char* msg)\r
-{\r
- if (msg)\r
- m_msg=msg;\r
- else\r
- m_msg.erase();\r
- m_processedmsg.erase();\r
-}\r
-\r
-inline const char* get_digit_character()\r
-{\r
- static const char s_characters[19] = \r
- {\r
- '9'\r
- , '8'\r
- , '7'\r
- , '6'\r
- , '5'\r
- , '4'\r
- , '3'\r
- , '2'\r
- , '1'\r
- , '0'\r
- , '1'\r
- , '2'\r
- , '3'\r
- , '4'\r
- , '5'\r
- , '6'\r
- , '7'\r
- , '8'\r
- , '9'\r
- };\r
- static const char *s_mid = s_characters + 9;\r
-\r
- return s_mid;\r
-}\r
-\r
-inline const char* unsigned_integer_to_string(char* buf, size_t cchBuf, int i)\r
-{\r
- char* psz=buf + cchBuf - 1; // Set psz to last char\r
- *psz = 0; // Set terminating null\r
-\r
- do {\r
- unsigned int lsd = i % 10; // Get least significant\r
- // digit\r
-\r
- i /= 10; // Prepare for next most\r
- // significant digit\r
-\r
- --psz; // Move back\r
-\r
- *psz = get_digit_character()[lsd]; // Place the digit\r
-\r
- } while(i!=0 && psz>buf);\r
-\r
- return psz;\r
-}\r
-\r
-void XMLToolingException::addProperties(const params& p)\r
-{\r
- m_processedmsg.erase();\r
- int i=m_params.size()+1;\r
- char buf[20];\r
- const vector<const char*>& v=p.get();\r
- for (vector<const char*>::const_iterator ci=v.begin(); ci!=v.end(); ci++) {\r
- m_params[unsigned_integer_to_string(buf,sizeof(buf),i++)] = *ci;\r
- }\r
-}\r
- \r
-void XMLToolingException::addProperties(const namedparams& p)\r
-{\r
- m_processedmsg.erase();\r
- const vector<const char*>& v=p.get();\r
- for (vector<const char*>::const_iterator ci=v.begin(); ci!=v.end(); ci++) {\r
- m_params.erase(*ci);\r
- m_params[*ci] = *(ci+1);\r
- ci++; // advance past name to value, then loop will advance it again\r
- }\r
-}\r
-\r
-const char* XMLToolingException::getProperty(unsigned int index) const\r
-{\r
- char buf[20];\r
- map<string,string>::const_iterator i=m_params.find(unsigned_integer_to_string(buf,sizeof(buf),index));\r
- return (i==m_params.end()) ? NULL : i->second.c_str();\r
-}\r
-\r
-const char* XMLToolingException::getProperty(const char* name) const\r
-{\r
- map<string,string>::const_iterator i=m_params.find(name);\r
- return (i==m_params.end()) ? NULL : i->second.c_str();\r
-}\r
-\r
-const char* XMLToolingException::getMessage() const\r
-{\r
- if (!m_processedmsg.empty())\r
- return m_processedmsg.c_str();\r
- else if (m_params.empty())\r
- return m_msg.c_str();\r
-\r
- static const char* legal="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890_";\r
-\r
- // Replace any parameters in the message.\r
- string::size_type i=0,start=0;\r
- while (start!=string::npos && start<m_msg.length() && (i=m_msg.find("$",start))!=string::npos) {\r
- if (i>start)\r
- m_processedmsg += m_msg.substr(start,i-start); // append everything in between\r
- start=i+1; // move start to the beginning of the token name\r
- i=m_msg.find_first_not_of(legal,start); // find token delimiter\r
- if (i==start) { // append a non legal character\r
- m_processedmsg+=m_msg[start++];\r
- continue;\r
- }\r
- \r
- // search for token in map\r
- map<string,string>::const_iterator param=m_params.find(m_msg.substr(start,(i==string::npos) ? i : i-start));\r
- if (param!=m_params.end()) {\r
- m_processedmsg+=param->second;\r
- start=i;\r
- }\r
- }\r
- if (start!=string::npos && start<m_msg.length())\r
- m_processedmsg += m_msg.substr(start,i); // append rest of string\r
- return m_processedmsg.c_str();\r
-}\r
-\r
-string XMLToolingException::toString() const\r
-{\r
- string xml=string("<exception xmlns=\"http://www.opensaml.org/xmltooling\" type=\"") + getClassName() + "\">";\r
- const char* msg=getMessage();\r
- if (msg)\r
- xml=xml + "<message>" + msg + "</message>";\r
- for (map<string,string>::const_iterator i=m_params.begin(); i!=m_params.end(); i++) {\r
- xml=xml + "<param name=\"" + i->first + "\">" + i->second + "</param>";\r
- }\r
- xml+="</exception>";\r
- return xml;\r
-}\r
-\r
-XMLToolingException* XMLToolingException::fromStream(std::istream& in)\r
-{\r
- static const XMLCh exception[] = { chLatin_e, chLatin_x, chLatin_c, chLatin_e, chLatin_p, chLatin_t, chLatin_i, chLatin_o, chLatin_n, chNull };\r
- static const XMLCh message[] = { chLatin_m, chLatin_e, chLatin_s, chLatin_s, chLatin_a, chLatin_g, chLatin_e, chNull };\r
- static const XMLCh name[] = { chLatin_n, chLatin_a, chLatin_m, chLatin_e, chNull };\r
- static const XMLCh param[] = { chLatin_p, chLatin_a, chLatin_r, chLatin_a, chLatin_m, chNull };\r
- static const XMLCh type[] = { chLatin_t, chLatin_y, chLatin_p, chLatin_e, chNull };\r
-\r
- DOMDocument* doc=XMLToolingInternalConfig::getInternalConfig().m_parserPool->parse(in);\r
- \r
- // Check root element.\r
- const DOMElement* root=doc->getDocumentElement();\r
- if (!XMLHelper::isNodeNamed(root,XMLConstants::XMLTOOLING_NS,exception)) {\r
- doc->release();\r
- throw XMLToolingException("Invalid root element on serialized exception.");\r
- }\r
- \r
- auto_ptr_char classname(root->getAttributeNS(NULL,type));\r
- auto_ptr<XMLToolingException> excep(XMLToolingException::getInstance(classname.get()));\r
- \r
- DOMElement* child=XMLHelper::getFirstChildElement(root,XMLConstants::XMLTOOLING_NS,message);\r
- if (child && child->hasChildNodes()) {\r
- auto_ptr_char m(child->getFirstChild()->getNodeValue());\r
- excep->setMessage(m.get());\r
- }\r
- \r
- child=XMLHelper::getFirstChildElement(root,XMLConstants::XMLTOOLING_NS,param);\r
- while (child && child->hasChildNodes()) {\r
- auto_ptr_char n(child->getAttributeNS(NULL,name));\r
- char* v=toUTF8(child->getFirstChild()->getNodeValue());\r
- if (n.get() && v)\r
- excep->addProperty(n.get(), v);\r
- XMLString::release(&v);\r
- child=XMLHelper::getNextSiblingElement(root,XMLConstants::XMLTOOLING_NS,param);\r
- }\r
-\r
- doc->release();\r
- return excep.release();\r
-}\r
- \r
-XMLToolingException* XMLToolingException::fromString(const char* s)\r
-{\r
- istringstream in(s);\r
- return fromStream(in);\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.
+ */
+
+/**
+ * exceptions.cpp
+ *
+ * Exception classes
+ */
+
+#include "internal.h"
+#include "exceptions.h"
+#include "XMLToolingConfig.h"
+#include "util/XMLConstants.h"
+#include "util/XMLHelper.h"
+
+#include <stdarg.h>
+#include <sstream>
+#include <xercesc/util/XMLUniDefs.hpp>
+
+using namespace xmltooling;
+using namespace std;
+
+params::params(int count,...)
+{
+ va_list args;
+ va_start(args,count);
+ while (count--)
+ v.push_back(va_arg(args,char*));
+ va_end(args);
+}
+
+namedparams::namedparams(int count,...)
+{
+ count*=2;
+ va_list args;
+ va_start(args,count);
+ while (count--)
+ v.push_back(va_arg(args,char*));
+ va_end(args);
+}
+
+XMLToolingException::ExceptionFactoryMap XMLToolingException::m_factoryMap;
+
+XMLToolingException* XMLToolingException::getInstance(const char* exceptionClass)
+{
+ if (exceptionClass) {
+ ExceptionFactoryMap::const_iterator i=m_factoryMap.find(exceptionClass);
+ if (i!=m_factoryMap.end())
+ return (i->second)();
+ }
+ return new XMLToolingException();
+}
+
+XMLToolingException::XMLToolingException(const char* msg, const params& p)
+{
+ if (msg)
+ m_msg=msg;
+ addProperties(p);
+}
+
+XMLToolingException::XMLToolingException(const char* msg, const namedparams& p)
+{
+ if (msg)
+ m_msg=msg;
+ addProperties(p);
+}
+
+XMLToolingException::XMLToolingException(const std::string& msg, const params& p) : m_msg(msg)
+{
+ addProperties(p);
+}
+
+XMLToolingException::XMLToolingException(const std::string& msg, const namedparams& p) : m_msg(msg)
+{
+ addProperties(p);
+}
+
+void XMLToolingException::setMessage(const char* msg)
+{
+ if (msg)
+ m_msg=msg;
+ else
+ m_msg.erase();
+ m_processedmsg.erase();
+}
+
+inline const char* get_digit_character()
+{
+ static const char s_characters[19] =
+ {
+ '9'
+ , '8'
+ , '7'
+ , '6'
+ , '5'
+ , '4'
+ , '3'
+ , '2'
+ , '1'
+ , '0'
+ , '1'
+ , '2'
+ , '3'
+ , '4'
+ , '5'
+ , '6'
+ , '7'
+ , '8'
+ , '9'
+ };
+ static const char *s_mid = s_characters + 9;
+
+ return s_mid;
+}
+
+inline const char* unsigned_integer_to_string(char* buf, size_t cchBuf, int i)
+{
+ char* psz=buf + cchBuf - 1; // Set psz to last char
+ *psz = 0; // Set terminating null
+
+ do {
+ unsigned int lsd = i % 10; // Get least significant
+ // digit
+
+ i /= 10; // Prepare for next most
+ // significant digit
+
+ --psz; // Move back
+
+ *psz = get_digit_character()[lsd]; // Place the digit
+
+ } while(i!=0 && psz>buf);
+
+ return psz;
+}
+
+void XMLToolingException::addProperties(const params& p)
+{
+ m_processedmsg.erase();
+ int i=m_params.size()+1;
+ char buf[20];
+ const vector<const char*>& v=p.get();
+ for (vector<const char*>::const_iterator ci=v.begin(); ci!=v.end(); ci++) {
+ m_params[unsigned_integer_to_string(buf,sizeof(buf),i++)] = *ci;
+ }
+}
+
+void XMLToolingException::addProperties(const namedparams& p)
+{
+ m_processedmsg.erase();
+ const vector<const char*>& v=p.get();
+ for (vector<const char*>::const_iterator ci=v.begin(); ci!=v.end(); ci++) {
+ m_params.erase(*ci);
+ m_params[*ci] = *(ci+1);
+ ci++; // advance past name to value, then loop will advance it again
+ }
+}
+
+const char* XMLToolingException::getProperty(unsigned int index) const
+{
+ char buf[20];
+ map<string,string>::const_iterator i=m_params.find(unsigned_integer_to_string(buf,sizeof(buf),index));
+ return (i==m_params.end()) ? NULL : i->second.c_str();
+}
+
+const char* XMLToolingException::getProperty(const char* name) const
+{
+ map<string,string>::const_iterator i=m_params.find(name);
+ return (i==m_params.end()) ? NULL : i->second.c_str();
+}
+
+const char* XMLToolingException::getMessage() const
+{
+ if (!m_processedmsg.empty())
+ return m_processedmsg.c_str();
+ else if (m_params.empty())
+ return m_msg.c_str();
+
+ static const char* legal="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890_";
+
+ // Replace any parameters in the message.
+ string::size_type i=0,start=0;
+ while (start!=string::npos && start<m_msg.length() && (i=m_msg.find("$",start))!=string::npos) {
+ if (i>start)
+ m_processedmsg += m_msg.substr(start,i-start); // append everything in between
+ start=i+1; // move start to the beginning of the token name
+ i=m_msg.find_first_not_of(legal,start); // find token delimiter
+ if (i==start) { // append a non legal character
+ m_processedmsg+=m_msg[start++];
+ continue;
+ }
+
+ // search for token in map
+ map<string,string>::const_iterator param=m_params.find(m_msg.substr(start,(i==string::npos) ? i : i-start));
+ if (param!=m_params.end()) {
+ m_processedmsg+=param->second;
+ start=i;
+ }
+ }
+ if (start!=string::npos && start<m_msg.length())
+ m_processedmsg += m_msg.substr(start,i); // append rest of string
+ return m_processedmsg.c_str();
+}
+
+string XMLToolingException::toString() const
+{
+ string xml=string("<exception xmlns=\"http://www.opensaml.org/xmltooling\" type=\"") + getClassName() + "\">";
+ const char* msg=getMessage();
+ if (msg)
+ xml=xml + "<message>" + msg + "</message>";
+ for (map<string,string>::const_iterator i=m_params.begin(); i!=m_params.end(); i++) {
+ xml=xml + "<param name=\"" + i->first + "\">" + i->second + "</param>";
+ }
+ xml+="</exception>";
+ return xml;
+}
+
+XMLToolingException* XMLToolingException::fromStream(std::istream& in)
+{
+ static const XMLCh exception[] = { chLatin_e, chLatin_x, chLatin_c, chLatin_e, chLatin_p, chLatin_t, chLatin_i, chLatin_o, chLatin_n, chNull };
+ static const XMLCh message[] = { chLatin_m, chLatin_e, chLatin_s, chLatin_s, chLatin_a, chLatin_g, chLatin_e, chNull };
+ static const XMLCh name[] = { chLatin_n, chLatin_a, chLatin_m, chLatin_e, chNull };
+ static const XMLCh param[] = { chLatin_p, chLatin_a, chLatin_r, chLatin_a, chLatin_m, chNull };
+ static const XMLCh type[] = { chLatin_t, chLatin_y, chLatin_p, chLatin_e, chNull };
+
+ DOMDocument* doc=XMLToolingInternalConfig::getInternalConfig().m_parserPool->parse(in);
+
+ // Check root element.
+ const DOMElement* root=doc->getDocumentElement();
+ if (!XMLHelper::isNodeNamed(root,XMLConstants::XMLTOOLING_NS,exception)) {
+ doc->release();
+ throw XMLToolingException("Invalid root element on serialized exception.");
+ }
+
+ auto_ptr_char classname(root->getAttributeNS(NULL,type));
+ auto_ptr<XMLToolingException> excep(XMLToolingException::getInstance(classname.get()));
+
+ DOMElement* child=XMLHelper::getFirstChildElement(root,XMLConstants::XMLTOOLING_NS,message);
+ if (child && child->hasChildNodes()) {
+ auto_ptr_char m(child->getFirstChild()->getNodeValue());
+ excep->setMessage(m.get());
+ }
+
+ child=XMLHelper::getFirstChildElement(root,XMLConstants::XMLTOOLING_NS,param);
+ while (child && child->hasChildNodes()) {
+ auto_ptr_char n(child->getAttributeNS(NULL,name));
+ char* v=toUTF8(child->getFirstChild()->getNodeValue());
+ if (n.get() && v)
+ excep->addProperty(n.get(), v);
+ XMLString::release(&v);
+ child=XMLHelper::getNextSiblingElement(root,XMLConstants::XMLTOOLING_NS,param);
+ }
+
+ doc->release();
+ return excep.release();
+}
+
+XMLToolingException* XMLToolingException::fromString(const char* s)
+{
+ istringstream in(s);
+ return fromStream(in);
+}
-/*\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 exceptions.h\r
- * \r
- * Exception classes\r
- */\r
- \r
-#ifndef __xmltooling_exceptions_h__\r
-#define __xmltooling_exceptions_h__\r
-\r
-#include <map>\r
-#include <string>\r
-#include <vector>\r
-#include <iostream>\r
-#include <xmltooling/base.h>\r
-\r
-/**\r
- * Declares a derived exception class\r
- * \r
- * @param name the exception class\r
- * @param base the base class\r
- * @param desc\r
- */\r
-#define DECL_XMLTOOLING_EXCEPTION(name,base,desc) \\r
- /##** desc */ \\r
- class XMLTOOL_EXCEPTIONAPI(XMLTOOL_API) name : public xmltooling::base { \\r
- public: \\r
- /##** base##::##base(const char*,const xmltooling::params&) */ \\r
- name(const char* msg=NULL, const xmltooling::params& p=xmltooling::params()) \\r
- : xmltooling::base(msg,p) {} \\r
- /##** base##::##base(const char*,const xmltooling::namedparams&) */ \\r
- name(const char* msg, const xmltooling::namedparams& p) \\r
- : xmltooling::base(msg,p) {} \\r
- /##** base##::##base(const std::string&,const xmltooling::params&) */ \\r
- name(const std::string& msg, const xmltooling::params& p=xmltooling::params()) \\r
- : xmltooling::base(msg,p) {} \\r
- /##** base##::##base(const std::string&,const xmltooling::namedparams&) */ \\r
- name(const std::string& msg, const xmltooling::namedparams& p) \\r
- : xmltooling::base(msg,p) {} \\r
- virtual ~name() {} \\r
- virtual const char* getClassName() const { return "xmltooling::"#name; } \\r
- void raise() const {throw *this;} \\r
- }\r
-\r
-/**\r
- * Declares a factory function for an exception class.\r
- * \r
- * @param name the exception class name\r
- */\r
-#define DECL_EXCEPTION_FACTORY(name) \\r
- xmltooling::XMLToolingException* name##Factory() \\r
- { \\r
- return new xmltooling::name(); \\r
- }\r
-\r
-/**\r
- * Registers a factory for an exception class.\r
- * \r
- * @param name the exception class name\r
- */\r
-#define REGISTER_EXCEPTION_FACTORY(name) XMLToolingException::registerFactory("xmltooling::"#name,name##Factory)\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
- * Wrapper around a variable number of arguments.\r
- */\r
- class XMLTOOL_API params\r
- {\r
- public:\r
- /**\r
- * Initializes with zero parameters.\r
- */\r
- params() {}\r
- \r
- /**\r
- * Initializes the parameter set.\r
- * \r
- * @param count the number of parameters that follow\r
- */\r
- params(int count,...);\r
- \r
- /**\r
- * Returns an immutable reference to the set of parameters.\r
- * \r
- * @return the parameter set\r
- */\r
- const std::vector<const char*>& get() const {return v;}\r
- \r
- protected:\r
- /** Contains the parameters being passed. */\r
- std::vector<const char*> v;\r
- };\r
- \r
- /**\r
- * Wrapper around a variable number of name/value pairs.\r
- */\r
- class XMLTOOL_API namedparams : public params\r
- {\r
- public:\r
- /**\r
- * Initializes with zero parameters.\r
- */\r
- namedparams() {}\r
-\r
- /**\r
- * Initializes the named parameter set.\r
- * \r
- * @param count the number of name/value pairs that follow (must be even)\r
- */\r
- namedparams(int count,...);\r
- };\r
-\r
- class XMLTOOL_EXCEPTIONAPI(XMLTOOL_API) XMLToolingException;\r
- \r
- /** A factory function that returns an empty exception object of a given type. */\r
- typedef XMLToolingException* ExceptionFactory();\r
- \r
- /**\r
- * Base exception class, supports parametrized messages and XML serialization.\r
- * Parameters are prefixed with a dollar sign ($) and can be positional ($1)\r
- * or named ($info).\r
- */\r
- class XMLTOOL_EXCEPTIONAPI(XMLTOOL_API) XMLToolingException\r
- {\r
- public:\r
- virtual ~XMLToolingException() {}\r
-\r
- /**\r
- * Constructs an exception using a message and positional parameters.\r
- * \r
- * @param msg error message\r
- * @param p an ordered set of positional parameter strings\r
- */\r
- XMLToolingException(const char* msg=NULL, const params& p=params());\r
-\r
- /**\r
- * Constructs an exception using a message and named parameters.\r
- * \r
- * @param msg error message\r
- * @param p a set of named parameter strings\r
- */\r
- XMLToolingException(const char* msg, const namedparams& p);\r
-\r
- /**\r
- * Constructs an exception using a message and positional parameters.\r
- * \r
- * @param msg error message\r
- * @param p an ordered set of positional parameter strings\r
- */\r
- XMLToolingException(const std::string& msg, const params& p=params());\r
-\r
- /**\r
- * Constructs an exception using a message and named parameters.\r
- * \r
- * @param msg error message\r
- * @param p a set of named parameter strings\r
- */\r
- XMLToolingException(const std::string& msg, const namedparams& p);\r
-\r
- /**\r
- * Returns the error message, after processing any parameter references.\r
- * \r
- * @return the processed message\r
- */\r
- const char* getMessage() const;\r
-\r
- /**\r
- * Returns the error message, after processing any parameter references.\r
- * \r
- * @return the processed message\r
- */\r
- const char* what() const {return getMessage();}\r
-\r
- /**\r
- * Sets the error message.\r
- * \r
- * @param msg the error message\r
- */\r
- void setMessage(const char* msg);\r
-\r
- /**\r
- * Sets the error message.\r
- * \r
- * @param msg the error message\r
- */\r
- void setMessage(const std::string& msg) {\r
- setMessage(msg.c_str());\r
- }\r
-\r
- /**\r
- * Attach a set of positional parameters to the exception.\r
- * \r
- * @param p an ordered set of named parameter strings\r
- */\r
- void addProperties(const params& p);\r
- \r
- /**\r
- * Attach a set of named parameters to the exception.\r
- * \r
- * @param p a set of named parameter strings\r
- */\r
- void addProperties(const namedparams& p);\r
-\r
- /**\r
- * Attach a single positional parameter at the next available position.\r
- * \r
- * @param value the parameter value\r
- */\r
- void addProperty(const char* value) {\r
- addProperties(params(1,value));\r
- }\r
-\r
- /**\r
- * Attach a single named parameter.\r
- * \r
- * @param name the parameter name\r
- * @param value the parameter value\r
- */\r
- void addProperty(const char* name, const char* value) {\r
- addProperties(namedparams(1,name,value));\r
- }\r
-\r
- /**\r
- * Returns the parameter property with the designated position (based from one).\r
- * \r
- * @param index position to access\r
- * @return the parameter property or NULL\r
- */\r
- const char* getProperty(unsigned int index) const;\r
-\r
- /**\r
- * Returns the parameter property with the designated name.\r
- * \r
- * @param name named parameter to access\r
- * @return the parameter property or NULL\r
- */\r
- const char* getProperty(const char* name) const;\r
-\r
- /**\r
- * Raises an exception using itself.\r
- * Used to raise an exception of a derived type.\r
- */\r
- virtual void raise() const {\r
- throw *this;\r
- }\r
-\r
- /**\r
- * Returns a unique name for the exception class.\r
- * \r
- * @return class name\r
- */\r
- virtual const char* getClassName() const {\r
- return "xmltooling::XMLToolingException";\r
- }\r
- \r
- /**\r
- * Returns a string containing a serialized representation of the exception.\r
- * \r
- * @return the serialization\r
- */\r
- std::string toString() const;\r
-\r
- private:\r
- std::string m_msg;\r
- mutable std::string m_processedmsg;\r
- std::map<std::string,std::string> m_params;\r
-\r
- public:\r
- /**\r
- * Builds an empty exception of the given type.\r
- * \r
- * @param exceptionClass the name of the exception type to build\r
- * @return an empty exception object\r
- */\r
- static XMLToolingException* getInstance(const char* exceptionClass);\r
-\r
- /**\r
- * Builds an exception from a serialized input stream.\r
- * \r
- * @param in input stream\r
- * @return the exception object found in the stream\r
- */\r
- static XMLToolingException* fromStream(std::istream& in);\r
- \r
- /**\r
- * Builds an exception from a serialized input buffer.\r
- * \r
- * @param s input buffer\r
- * @return the exception object found in the buffer\r
- */\r
- static XMLToolingException* fromString(const char* s);\r
- \r
- /**\r
- * Registers a factory to create exceptions of a given class name.\r
- * \r
- * @param exceptionClass name of exception type\r
- * @param factory factory function to build exceptions with\r
- */\r
- static void registerFactory(const char* exceptionClass, ExceptionFactory* factory) {\r
- m_factoryMap[exceptionClass] = factory;\r
- }\r
- \r
- /**\r
- * Unregisters the factory for a given class name.\r
- * \r
- * @param exceptionClass name of exception type\r
- */\r
- static void deregisterFactory(const char* exceptionClass) {\r
- m_factoryMap.erase(exceptionClass);\r
- }\r
-\r
- private:\r
- typedef std::map<std::string,ExceptionFactory*> ExceptionFactoryMap;\r
- static ExceptionFactoryMap m_factoryMap;\r
- };\r
-\r
- DECL_XMLTOOLING_EXCEPTION(XMLParserException,XMLToolingException,Exceptions related to XML parsing);\r
- DECL_XMLTOOLING_EXCEPTION(XMLObjectException,XMLToolingException,Exceptions in basic object usage);\r
- DECL_XMLTOOLING_EXCEPTION(MarshallingException,XMLToolingException,Exceptions during object marshalling);\r
- DECL_XMLTOOLING_EXCEPTION(UnmarshallingException,XMLToolingException,Exceptions during object unmarshalling);\r
- DECL_XMLTOOLING_EXCEPTION(UnknownElementException,XMLToolingException,Exceptions due to processing of unknown element content);\r
- DECL_XMLTOOLING_EXCEPTION(UnknownAttributeException,XMLToolingException,Exceptions due to processing of unknown attributes);\r
- DECL_XMLTOOLING_EXCEPTION(ValidationException,XMLToolingException,Exceptions during object validation);\r
- DECL_XMLTOOLING_EXCEPTION(SignatureException,XMLToolingException,Exceptions in signature processing);\r
-\r
-};\r
-\r
-#if defined (_MSC_VER)\r
- #pragma warning( pop )\r
-#endif\r
-\r
-#endif /* __xmltooling_exceptions_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 exceptions.h
+ *
+ * Exception classes
+ */
+
+#ifndef __xmltooling_exceptions_h__
+#define __xmltooling_exceptions_h__
+
+#include <map>
+#include <string>
+#include <vector>
+#include <iostream>
+#include <xmltooling/base.h>
+
+/**
+ * Declares a derived exception class
+ *
+ * @param name the exception class
+ * @param base the base class
+ * @param desc
+ */
+#define DECL_XMLTOOLING_EXCEPTION(name,base,desc) \
+ XMLTOOLING_DOXYGEN(desc) \
+ class XMLTOOL_EXCEPTIONAPI(XMLTOOL_API) name : public xmltooling::base { \
+ public: \
+ XMLTOOLING_DOXYGEN(Constructor) \
+ name(const char* msg=NULL, const xmltooling::params& p=xmltooling::params()) \
+ : xmltooling::base(msg,p) {} \
+ XMLTOOLING_DOXYGEN(Constructor) \
+ name(const char* msg, const xmltooling::namedparams& p) \
+ : xmltooling::base(msg,p) {} \
+ XMLTOOLING_DOXYGEN(Constructor) \
+ name(const std::string& msg, const xmltooling::params& p=xmltooling::params()) \
+ : xmltooling::base(msg,p) {} \
+ XMLTOOLING_DOXYGEN(Constructor) \
+ name(const std::string& msg, const xmltooling::namedparams& p) \
+ : xmltooling::base(msg,p) {} \
+ virtual ~name() {} \
+ virtual const char* getClassName() const { return "xmltooling::"#name; } \
+ void raise() const {throw *this;} \
+ }
+
+/**
+ * Declares a factory function for an exception class.
+ *
+ * @param name the exception class name
+ */
+#define DECL_EXCEPTION_FACTORY(name) \
+ xmltooling::XMLToolingException* name##Factory() \
+ { \
+ return new xmltooling::name(); \
+ }
+
+/**
+ * Registers a factory for an exception class.
+ *
+ * @param name the exception class name
+ */
+#define REGISTER_EXCEPTION_FACTORY(name) XMLToolingException::registerFactory("xmltooling::"#name,name##Factory)
+
+#if defined (_MSC_VER)
+ #pragma warning( push )
+ #pragma warning( disable : 4250 4251 )
+#endif
+
+namespace xmltooling {
+
+ /**
+ * Wrapper around a variable number of arguments.
+ */
+ class XMLTOOL_API params
+ {
+ public:
+ /**
+ * Initializes with zero parameters.
+ */
+ params() {}
+
+ /**
+ * Initializes the parameter set.
+ *
+ * @param count the number of parameters that follow
+ */
+ params(int count,...);
+
+ /**
+ * Returns an immutable reference to the set of parameters.
+ *
+ * @return the parameter set
+ */
+ const std::vector<const char*>& get() const {return v;}
+
+ protected:
+ /** Contains the parameters being passed. */
+ std::vector<const char*> v;
+ };
+
+ /**
+ * Wrapper around a variable number of name/value pairs.
+ */
+ class XMLTOOL_API namedparams : public params
+ {
+ public:
+ /**
+ * Initializes with zero parameters.
+ */
+ namedparams() {}
+
+ /**
+ * Initializes the named parameter set.
+ *
+ * @param count the number of name/value pairs that follow (must be even)
+ */
+ namedparams(int count,...);
+ };
+
+ class XMLTOOL_EXCEPTIONAPI(XMLTOOL_API) XMLToolingException;
+
+ /** A factory function that returns an empty exception object of a given type. */
+ typedef XMLToolingException* ExceptionFactory();
+
+ /**
+ * Base exception class, supports parametrized messages and XML serialization.
+ * Parameters are prefixed with a dollar sign ($) and can be positional ($1)
+ * or named ($info).
+ */
+ class XMLTOOL_EXCEPTIONAPI(XMLTOOL_API) XMLToolingException
+ {
+ public:
+ virtual ~XMLToolingException() {}
+
+ /**
+ * Constructs an exception using a message and positional parameters.
+ *
+ * @param msg error message
+ * @param p an ordered set of positional parameter strings
+ */
+ XMLToolingException(const char* msg=NULL, const params& p=params());
+
+ /**
+ * Constructs an exception using a message and named parameters.
+ *
+ * @param msg error message
+ * @param p a set of named parameter strings
+ */
+ XMLToolingException(const char* msg, const namedparams& p);
+
+ /**
+ * Constructs an exception using a message and positional parameters.
+ *
+ * @param msg error message
+ * @param p an ordered set of positional parameter strings
+ */
+ XMLToolingException(const std::string& msg, const params& p=params());
+
+ /**
+ * Constructs an exception using a message and named parameters.
+ *
+ * @param msg error message
+ * @param p a set of named parameter strings
+ */
+ XMLToolingException(const std::string& msg, const namedparams& p);
+
+ /**
+ * Returns the error message, after processing any parameter references.
+ *
+ * @return the processed message
+ */
+ const char* getMessage() const;
+
+ /**
+ * Returns the error message, after processing any parameter references.
+ *
+ * @return the processed message
+ */
+ const char* what() const {return getMessage();}
+
+ /**
+ * Sets the error message.
+ *
+ * @param msg the error message
+ */
+ void setMessage(const char* msg);
+
+ /**
+ * Sets the error message.
+ *
+ * @param msg the error message
+ */
+ void setMessage(const std::string& msg) {
+ setMessage(msg.c_str());
+ }
+
+ /**
+ * Attach a set of positional parameters to the exception.
+ *
+ * @param p an ordered set of named parameter strings
+ */
+ void addProperties(const params& p);
+
+ /**
+ * Attach a set of named parameters to the exception.
+ *
+ * @param p a set of named parameter strings
+ */
+ void addProperties(const namedparams& p);
+
+ /**
+ * Attach a single positional parameter at the next available position.
+ *
+ * @param value the parameter value
+ */
+ void addProperty(const char* value) {
+ addProperties(params(1,value));
+ }
+
+ /**
+ * Attach a single named parameter.
+ *
+ * @param name the parameter name
+ * @param value the parameter value
+ */
+ void addProperty(const char* name, const char* value) {
+ addProperties(namedparams(1,name,value));
+ }
+
+ /**
+ * Returns the parameter property with the designated position (based from one).
+ *
+ * @param index position to access
+ * @return the parameter property or NULL
+ */
+ const char* getProperty(unsigned int index) const;
+
+ /**
+ * Returns the parameter property with the designated name.
+ *
+ * @param name named parameter to access
+ * @return the parameter property or NULL
+ */
+ const char* getProperty(const char* name) const;
+
+ /**
+ * Raises an exception using itself.
+ * Used to raise an exception of a derived type.
+ */
+ virtual void raise() const {
+ throw *this;
+ }
+
+ /**
+ * Returns a unique name for the exception class.
+ *
+ * @return class name
+ */
+ virtual const char* getClassName() const {
+ return "xmltooling::XMLToolingException";
+ }
+
+ /**
+ * Returns a string containing a serialized representation of the exception.
+ *
+ * @return the serialization
+ */
+ std::string toString() const;
+
+ private:
+ std::string m_msg;
+ mutable std::string m_processedmsg;
+ std::map<std::string,std::string> m_params;
+
+ public:
+ /**
+ * Builds an empty exception of the given type.
+ *
+ * @param exceptionClass the name of the exception type to build
+ * @return an empty exception object
+ */
+ static XMLToolingException* getInstance(const char* exceptionClass);
+
+ /**
+ * Builds an exception from a serialized input stream.
+ *
+ * @param in input stream
+ * @return the exception object found in the stream
+ */
+ static XMLToolingException* fromStream(std::istream& in);
+
+ /**
+ * Builds an exception from a serialized input buffer.
+ *
+ * @param s input buffer
+ * @return the exception object found in the buffer
+ */
+ static XMLToolingException* fromString(const char* s);
+
+ /**
+ * Registers a factory to create exceptions of a given class name.
+ *
+ * @param exceptionClass name of exception type
+ * @param factory factory function to build exceptions with
+ */
+ static void registerFactory(const char* exceptionClass, ExceptionFactory* factory) {
+ m_factoryMap[exceptionClass] = factory;
+ }
+
+ /**
+ * Unregisters the factory for a given class name.
+ *
+ * @param exceptionClass name of exception type
+ */
+ static void deregisterFactory(const char* exceptionClass) {
+ m_factoryMap.erase(exceptionClass);
+ }
+
+ private:
+ typedef std::map<std::string,ExceptionFactory*> ExceptionFactoryMap;
+ static ExceptionFactoryMap m_factoryMap;
+ };
+
+ DECL_XMLTOOLING_EXCEPTION(XMLParserException,XMLToolingException,Exceptions related to XML parsing);
+ DECL_XMLTOOLING_EXCEPTION(XMLObjectException,XMLToolingException,Exceptions in basic object usage);
+ DECL_XMLTOOLING_EXCEPTION(MarshallingException,XMLToolingException,Exceptions during object marshalling);
+ DECL_XMLTOOLING_EXCEPTION(UnmarshallingException,XMLToolingException,Exceptions during object unmarshalling);
+ DECL_XMLTOOLING_EXCEPTION(UnknownElementException,XMLToolingException,Exceptions due to processing of unknown element content);
+ DECL_XMLTOOLING_EXCEPTION(UnknownAttributeException,XMLToolingException,Exceptions due to processing of unknown attributes);
+ DECL_XMLTOOLING_EXCEPTION(ValidationException,XMLToolingException,Exceptions during object validation);
+ DECL_XMLTOOLING_EXCEPTION(SignatureException,XMLToolingException,Exceptions in signature processing);
+
+};
+
+#if defined (_MSC_VER)
+ #pragma warning( pop )
+#endif
+
+#endif /* __xmltooling_exceptions_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
- * AbstractXMLObjectUnmarshaller.cpp\r
- * \r
- * A thread-safe abstract unmarshaller.\r
- */\r
-\r
-#include "internal.h"\r
-#include "exceptions.h"\r
-#include "XMLObjectBuilder.h"\r
-#include "io/AbstractXMLObjectUnmarshaller.h"\r
-#include "util/NDC.h"\r
-#include "util/XMLConstants.h"\r
-#include "util/XMLHelper.h"\r
-\r
-#include <xercesc/util/XMLUniDefs.hpp>\r
-#include <log4cpp/Category.hh>\r
-\r
-using namespace xmltooling;\r
-using namespace log4cpp;\r
-using namespace std;\r
-\r
-#define XT_log (*static_cast<Category*>(m_log))\r
-\r
-XMLObject* AbstractXMLObjectUnmarshaller::unmarshall(DOMElement* element, bool bindDocument)\r
-{\r
-#ifdef _DEBUG\r
- xmltooling::NDC ndc("unmarshall");\r
-#endif\r
-\r
- if (getDOM() || hasParent())\r
- throw UnmarshallingException("Object already contains data, it cannot be unmarshalled at this stage.");\r
-\r
- if (!XMLString::equals(element->getNamespaceURI(),getElementQName().getNamespaceURI()) ||\r
- !XMLString::equals(element->getLocalName(),getElementQName().getLocalPart())) {\r
- throw UnmarshallingException("Unrecognized element supplied to implementation for unmarshalling.");\r
- }\r
-\r
- if (XT_log.isDebugEnabled()) {\r
- auto_ptr_char dname(element->getNodeName());\r
- XT_log.debug("unmarshalling DOM element (%s)", dname.get());\r
- }\r
-\r
- if (element->hasAttributes()) {\r
- unmarshallAttributes(element);\r
- }\r
-\r
- unmarshallChildElements(element);\r
-\r
- /* TODO: Signing\r
- if (xmlObject instanceof SignableXMLObject) {\r
- verifySignature(domElement, xmlObject);\r
- }\r
- */\r
-\r
- setDOM(element,bindDocument);\r
- return this;\r
-}\r
-\r
-void AbstractXMLObjectUnmarshaller::unmarshallAttributes(const DOMElement* domElement)\r
-{\r
-#ifdef _DEBUG\r
- xmltooling::NDC ndc("unmarshallAttributes");\r
-#endif\r
- static const XMLCh type[]={chLatin_t, chLatin_y, chLatin_p, chLatin_e, chNull};\r
-\r
- if (XT_log.isDebugEnabled()) {\r
- auto_ptr_char dname(domElement->getNodeName());\r
- XT_log.debug("unmarshalling attributes for DOM element (%s)", dname.get());\r
- }\r
-\r
- DOMNamedNodeMap* attributes = domElement->getAttributes();\r
- if (!attributes) {\r
- XT_log.debug("no attributes to unmarshall");\r
- return;\r
- }\r
-\r
- DOMNode* childNode;\r
- DOMAttr* attribute;\r
- for (XMLSize_t i=0; i<attributes->getLength(); i++) {\r
- childNode = attributes->item(i);\r
-\r
- // The child node should always be an attribute, but just in case\r
- if (childNode->getNodeType() != DOMNode::ATTRIBUTE_NODE) {\r
- XT_log.debug("encountered child node of type %d in attribute list, ignoring it", childNode->getNodeType());\r
- continue;\r
- }\r
-\r
- attribute = static_cast<DOMAttr*>(childNode);\r
- \r
- const XMLCh* nsuri=attribute->getNamespaceURI();\r
- if (XMLString::equals(nsuri,XMLConstants::XMLNS_NS)) {\r
- if (XMLString::equals(attribute->getLocalName(),XMLConstants::XMLNS_PREFIX)) {\r
- XT_log.debug("found default namespace declaration, adding it to the list of namespaces on the XMLObject");\r
- addNamespace(Namespace(attribute->getValue(), NULL, true));\r
- continue;\r
- }\r
- else {\r
- XT_log.debug("found namespace declaration, adding it to the list of namespaces on the XMLObject");\r
- addNamespace(Namespace(attribute->getValue(), attribute->getLocalName(), true));\r
- continue;\r
- }\r
- }\r
- else if (XMLString::equals(nsuri,XMLConstants::XSI_NS) && XMLString::equals(attribute->getLocalName(),type)) {\r
- XT_log.debug("skipping xsi:type declaration");\r
- continue;\r
- }\r
- else if (nsuri && !XMLString::equals(nsuri,XMLConstants::XML_NS)) {\r
- XT_log.debug("found namespace-qualified attribute, adding prefix to the list of namespaces on the XMLObject");\r
- addNamespace(Namespace(nsuri, attribute->getPrefix()));\r
- }\r
-\r
- XT_log.debug("processing generic attribute");\r
- processAttribute(attribute);\r
- }\r
-}\r
-\r
-void AbstractXMLObjectUnmarshaller::unmarshallChildElements(const DOMElement* domElement)\r
-{\r
-#ifdef _DEBUG\r
- xmltooling::NDC ndc("unmarshallChildElements");\r
-#endif\r
-\r
- if (XT_log.isDebugEnabled()) {\r
- auto_ptr_char dname(domElement->getNodeName());\r
- XT_log.debug("unmarshalling child elements of DOM element (%s)", dname.get());\r
- }\r
-\r
- DOMNodeList* childNodes = domElement->getChildNodes();\r
- DOMNode* childNode;\r
- if (!childNodes || childNodes->getLength()==0) {\r
- XT_log.debug("element had no children");\r
- return;\r
- }\r
-\r
- XMLToolingConfig& config=XMLToolingConfig::getConfig();\r
- for (XMLSize_t i = 0; i < childNodes->getLength(); i++) {\r
- childNode = childNodes->item(i);\r
- if (childNode->getNodeType() == DOMNode::ELEMENT_NODE) {\r
- const XMLObjectBuilder* builder = XMLObjectBuilder::getBuilder(static_cast<DOMElement*>(childNode));\r
- if (!builder) {\r
- auto_ptr<QName> cname(XMLHelper::getNodeQName(childNode));\r
- XT_log.error("no default builder installed, found unknown child element (%s)", cname->toString().c_str());\r
- throw UnmarshallingException("Unmarshaller found unknown child element, but no default builder was found.");\r
- }\r
-\r
- if (XT_log.isDebugEnabled()) {\r
- auto_ptr<QName> cname(XMLHelper::getNodeQName(childNode));\r
- XT_log.debug("unmarshalling child element (%s)", cname->toString().c_str());\r
- }\r
-\r
- // Retain ownership of the unmarshalled child until it's processed by the parent.\r
- auto_ptr<XMLObject> childObject(builder->buildFromElement(static_cast<DOMElement*>(childNode)));\r
- processChildElement(childObject.get(), static_cast<DOMElement*>(childNode));\r
- childObject.release();\r
- }\r
- else if (childNode->getNodeType() == DOMNode::TEXT_NODE) {\r
- XT_log.debug("processing element content");\r
- processElementContent(childNode->getNodeValue());\r
- }\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.
+ */
+
+/**
+ * AbstractXMLObjectUnmarshaller.cpp
+ *
+ * A thread-safe abstract unmarshaller.
+ */
+
+#include "internal.h"
+#include "exceptions.h"
+#include "XMLObjectBuilder.h"
+#include "io/AbstractXMLObjectUnmarshaller.h"
+#include "util/NDC.h"
+#include "util/XMLConstants.h"
+#include "util/XMLHelper.h"
+
+#include <xercesc/util/XMLUniDefs.hpp>
+#include <log4cpp/Category.hh>
+
+using namespace xmltooling;
+using namespace log4cpp;
+using namespace std;
+
+#define XT_log (*static_cast<Category*>(m_log))
+
+XMLObject* AbstractXMLObjectUnmarshaller::unmarshall(DOMElement* element, bool bindDocument)
+{
+#ifdef _DEBUG
+ xmltooling::NDC ndc("unmarshall");
+#endif
+
+ if (getDOM() || hasParent())
+ throw UnmarshallingException("Object already contains data, it cannot be unmarshalled at this stage.");
+
+ if (!XMLString::equals(element->getNamespaceURI(),getElementQName().getNamespaceURI()) ||
+ !XMLString::equals(element->getLocalName(),getElementQName().getLocalPart())) {
+ throw UnmarshallingException("Unrecognized element supplied to implementation for unmarshalling.");
+ }
+
+ if (XT_log.isDebugEnabled()) {
+ auto_ptr_char dname(element->getNodeName());
+ XT_log.debug("unmarshalling DOM element (%s)", dname.get());
+ }
+
+ if (element->hasAttributes()) {
+ unmarshallAttributes(element);
+ }
+
+ unmarshallChildElements(element);
+
+ /* TODO: Signing
+ if (xmlObject instanceof SignableXMLObject) {
+ verifySignature(domElement, xmlObject);
+ }
+ */
+
+ setDOM(element,bindDocument);
+ return this;
+}
+
+void AbstractXMLObjectUnmarshaller::unmarshallAttributes(const DOMElement* domElement)
+{
+#ifdef _DEBUG
+ xmltooling::NDC ndc("unmarshallAttributes");
+#endif
+ static const XMLCh type[]={chLatin_t, chLatin_y, chLatin_p, chLatin_e, chNull};
+
+ if (XT_log.isDebugEnabled()) {
+ auto_ptr_char dname(domElement->getNodeName());
+ XT_log.debug("unmarshalling attributes for DOM element (%s)", dname.get());
+ }
+
+ DOMNamedNodeMap* attributes = domElement->getAttributes();
+ if (!attributes) {
+ XT_log.debug("no attributes to unmarshall");
+ return;
+ }
+
+ DOMNode* childNode;
+ DOMAttr* attribute;
+ for (XMLSize_t i=0; i<attributes->getLength(); i++) {
+ childNode = attributes->item(i);
+
+ // The child node should always be an attribute, but just in case
+ if (childNode->getNodeType() != DOMNode::ATTRIBUTE_NODE) {
+ XT_log.debug("encountered child node of type %d in attribute list, ignoring it", childNode->getNodeType());
+ continue;
+ }
+
+ attribute = static_cast<DOMAttr*>(childNode);
+
+ const XMLCh* nsuri=attribute->getNamespaceURI();
+ if (XMLString::equals(nsuri,XMLConstants::XMLNS_NS)) {
+ if (XMLString::equals(attribute->getLocalName(),XMLConstants::XMLNS_PREFIX)) {
+ XT_log.debug("found default namespace declaration, adding it to the list of namespaces on the XMLObject");
+ addNamespace(Namespace(attribute->getValue(), NULL, true));
+ continue;
+ }
+ else {
+ XT_log.debug("found namespace declaration, adding it to the list of namespaces on the XMLObject");
+ addNamespace(Namespace(attribute->getValue(), attribute->getLocalName(), true));
+ continue;
+ }
+ }
+ else if (XMLString::equals(nsuri,XMLConstants::XSI_NS) && XMLString::equals(attribute->getLocalName(),type)) {
+ XT_log.debug("skipping xsi:type declaration");
+ continue;
+ }
+ else if (nsuri && !XMLString::equals(nsuri,XMLConstants::XML_NS)) {
+ XT_log.debug("found namespace-qualified attribute, adding prefix to the list of namespaces on the XMLObject");
+ addNamespace(Namespace(nsuri, attribute->getPrefix()));
+ }
+
+ XT_log.debug("processing generic attribute");
+ processAttribute(attribute);
+ }
+}
+
+void AbstractXMLObjectUnmarshaller::unmarshallChildElements(const DOMElement* domElement)
+{
+#ifdef _DEBUG
+ xmltooling::NDC ndc("unmarshallChildElements");
+#endif
+
+ if (XT_log.isDebugEnabled()) {
+ auto_ptr_char dname(domElement->getNodeName());
+ XT_log.debug("unmarshalling child elements of DOM element (%s)", dname.get());
+ }
+
+ DOMNodeList* childNodes = domElement->getChildNodes();
+ DOMNode* childNode;
+ if (!childNodes || childNodes->getLength()==0) {
+ XT_log.debug("element had no children");
+ return;
+ }
+
+ for (XMLSize_t i = 0; i < childNodes->getLength(); i++) {
+ childNode = childNodes->item(i);
+ if (childNode->getNodeType() == DOMNode::ELEMENT_NODE) {
+ const XMLObjectBuilder* builder = XMLObjectBuilder::getBuilder(static_cast<DOMElement*>(childNode));
+ if (!builder) {
+ auto_ptr<QName> cname(XMLHelper::getNodeQName(childNode));
+ XT_log.error("no default builder installed, found unknown child element (%s)", cname->toString().c_str());
+ throw UnmarshallingException("Unmarshaller found unknown child element, but no default builder was found.");
+ }
+
+ if (XT_log.isDebugEnabled()) {
+ auto_ptr<QName> cname(XMLHelper::getNodeQName(childNode));
+ XT_log.debug("unmarshalling child element (%s)", cname->toString().c_str());
+ }
+
+ // Retain ownership of the unmarshalled child until it's processed by the parent.
+ auto_ptr<XMLObject> childObject(builder->buildFromElement(static_cast<DOMElement*>(childNode)));
+ processChildElement(childObject.get(), static_cast<DOMElement*>(childNode));
+ childObject.release();
+ }
+ else if (childNode->getNodeType() == DOMNode::TEXT_NODE) {
+ XT_log.debug("processing element content");
+ processElementContent(childNode->getNodeValue());
+ }
+ }
+}
-/*\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
- * ParserPool.cpp\r
- * \r
- * XML parsing\r
- */\r
-\r
-#include "internal.h"\r
-#include "exceptions.h"\r
-#include "util/NDC.h"\r
-#include "util/ParserPool.h"\r
-#include "util/XMLHelper.h"\r
-\r
-#include <algorithm>\r
-#include <functional>\r
-#include <sys/types.h>\r
-#include <sys/stat.h>\r
-#include <log4cpp/Category.hh>\r
-#include <xercesc/util/PlatformUtils.hpp>\r
-#include <xercesc/util/XMLUniDefs.hpp>\r
-#include <xercesc/sax/SAXException.hpp>\r
-#include <xercesc/framework/MemBufInputSource.hpp>\r
-#include <xercesc/framework/LocalFileInputSource.hpp>\r
-#include <xercesc/framework/Wrapper4InputSource.hpp>\r
-\r
-using namespace xmltooling;\r
-using namespace std;\r
-using namespace log4cpp;\r
-\r
-ParserPool::ParserPool(bool namespaceAware, bool schemaAware)\r
- : m_namespaceAware(namespaceAware), m_schemaAware(schemaAware), m_lock(XMLPlatformUtils::makeMutex()) {}\r
-\r
-ParserPool::~ParserPool()\r
-{\r
- while(!m_pool.empty()) {\r
- m_pool.top()->release();\r
- m_pool.pop();\r
- }\r
- XMLPlatformUtils::closeMutex(m_lock);\r
-}\r
-\r
-DOMDocument* ParserPool::newDocument()\r
-{\r
- return DOMImplementationRegistry::getDOMImplementation(NULL)->createDocument();\r
-}\r
-\r
-DOMDocument* ParserPool::parse(DOMInputSource& domsrc)\r
-{\r
- DOMBuilder* parser=checkoutBuilder();\r
- try {\r
- DOMDocument* doc=parser->parse(domsrc);\r
- parser->setFeature(XMLUni::fgXercesUserAdoptsDOMDocument,true);\r
- checkinBuilder(parser);\r
- return doc;\r
- }\r
- catch (...) {\r
- checkinBuilder(parser);\r
- throw;\r
- }\r
-}\r
-\r
-DOMDocument* ParserPool::parse(istream& is)\r
-{\r
- StreamInputSource src(is);\r
- Wrapper4InputSource domsrc(&src,false);\r
- return parse(domsrc);\r
-}\r
-\r
-// Functor to double its argument separated by a character and append to a buffer\r
-template <class T> class doubleit\r
-{\r
-public:\r
- doubleit(T& t, const typename T::value_type& s) : temp(t), sep(s) {}\r
- void operator() (const pair<T,T>& s) { temp += s.first + sep + s.first + sep; }\r
- T& temp;\r
- const typename T::value_type& sep;\r
-};\r
-\r
-bool ParserPool::loadSchema(const XMLCh* nsURI, const XMLCh* pathname)\r
-{\r
- // Just check the pathname and then directly register the pair into the map.\r
- \r
- auto_ptr_char p(pathname);\r
-#ifdef WIN32\r
- struct _stat stat_buf;\r
- if (_stat(p.get(), &stat_buf) != 0)\r
-#else\r
- struct stat stat_buf;\r
- if (stat(p.get(), &stat_buf) != 0)\r
-#endif\r
- {\r
-#if _DEBUG\r
- xmltooling::NDC ndc("loadSchema");\r
-#endif\r
- Category& log=Category::getInstance(XMLTOOLING_LOGCAT".ParserPool");\r
- auto_ptr_char n(nsURI);\r
- log.error("failed to load schema for (%s), file not found (%s)",n.get(),p.get());\r
- return false;\r
- }\r
-\r
- XMLPlatformUtils::lockMutex(m_lock);\r
-#ifdef HAVE_GOOD_STL\r
- m_schemaLocMap[nsURI]=pathname;\r
- m_schemaLocations.erase();\r
- for_each(m_schemaLocMap.begin(),m_schemaLocMap.end(),doubleit<xstring>(m_schemaLocations,chSpace));\r
-#else\r
- auto_ptr_char n(nsURI);\r
- m_schemaLocMap[n.get()]=p.get();\r
- m_schemaLocations.erase();\r
- for_each(m_schemaLocMap.begin(),m_schemaLocMap.end(),doubleit<string>(m_schemaLocations,' '));\r
-#endif\r
- XMLPlatformUtils::unlockMutex(m_lock);\r
-\r
- return true;\r
-}\r
-\r
-bool ParserPool::loadCatalog(const XMLCh* pathname)\r
-{\r
-#if _DEBUG\r
- xmltooling::NDC ndc("loadCatalog");\r
-#endif\r
- Category& log=Category::getInstance(XMLTOOLING_LOGCAT".ParserPool");\r
-\r
- // XML constants\r
- static const XMLCh impltype[] = { chLatin_L, chLatin_S, chNull };\r
- static const XMLCh catalog[] = { chLatin_c, chLatin_a, chLatin_t, chLatin_a, chLatin_l, chLatin_o, chLatin_g, chNull };\r
- static const XMLCh uri[] = { chLatin_u, chLatin_r, chLatin_i, chNull };\r
- static const XMLCh name[] = { chLatin_n, chLatin_a, chLatin_m, chLatin_e, chNull };\r
- static const XMLCh CATALOG_NS[] = {\r
- chLatin_u, chLatin_r, chLatin_n, chColon,\r
- chLatin_o, chLatin_a, chLatin_s, chLatin_i, chLatin_s, chColon,\r
- chLatin_n, chLatin_a, chLatin_m, chLatin_e, chLatin_s, chColon,\r
- chLatin_t, chLatin_c, chColon,\r
- chLatin_e, chLatin_n, chLatin_t, chLatin_i, chLatin_t, chLatin_y, chColon,\r
- chLatin_x, chLatin_m, chLatin_l, chLatin_n, chLatin_s, chColon,\r
- chLatin_x, chLatin_m, chLatin_l, chColon,\r
- chLatin_c, chLatin_a, chLatin_t, chLatin_a, chLatin_l, chLatin_o, chLatin_g, chNull\r
- };\r
-\r
- // Parse the catalog with the internal parser pool.\r
-\r
- if (log.isDebugEnabled()) {\r
- auto_ptr_char temp(pathname);\r
- log.debug("loading XML catalog from %s", temp.get());\r
- }\r
-\r
- LocalFileInputSource fsrc(NULL,pathname);\r
- Wrapper4InputSource domsrc(&fsrc,false);\r
- try {\r
- DOMDocument* doc=XMLToolingInternalConfig::getInternalConfig().m_parserPool->parse(domsrc);\r
- \r
- // Check root element.\r
- const DOMElement* root=doc->getDocumentElement();\r
- if (!XMLHelper::isNodeNamed(root,CATALOG_NS,catalog)) {\r
- auto_ptr_char temp(pathname);\r
- log.error("unknown root element, failed to load XML catalog from %s", temp.get());\r
- doc->release();\r
- return false;\r
- }\r
- \r
- // Fetch all the <uri> elements.\r
- DOMNodeList* mappings=root->getElementsByTagNameNS(CATALOG_NS,uri);\r
- XMLPlatformUtils::lockMutex(m_lock);\r
- for (XMLSize_t i=0; i<mappings->getLength(); i++) {\r
- root=static_cast<DOMElement*>(mappings->item(i));\r
- const XMLCh* from=root->getAttributeNS(NULL,name);\r
- const XMLCh* to=root->getAttributeNS(NULL,uri);\r
-#ifdef HAVE_GOOD_STL\r
- m_schemaLocMap[from]=to;\r
-#else\r
- auto_ptr_char f(from);\r
- auto_ptr_char t(to);\r
- m_schemaLocMap[f.get()]=t.get();\r
-#endif\r
- }\r
- m_schemaLocations.erase();\r
-#ifdef HAVE_GOOD_STL\r
- for_each(m_schemaLocMap.begin(),m_schemaLocMap.end(),doubleit<xstring>(m_schemaLocations,chSpace));\r
-#else\r
- for_each(m_schemaLocMap.begin(),m_schemaLocMap.end(),doubleit<string>(m_schemaLocations,' '));\r
-#endif\r
- XMLPlatformUtils::unlockMutex(m_lock);\r
- doc->release();\r
- }\r
- catch (XMLParserException& e) {\r
- log.error("catalog loader caught XMLParserException: %s", e.what());\r
- return false;\r
- }\r
-\r
- return true;\r
-}\r
-\r
-DOMInputSource* ParserPool::resolveEntity(const XMLCh* const publicId, const XMLCh* const systemId, const XMLCh* const baseURI)\r
-{\r
-#if _DEBUG\r
- xmltooling::NDC ndc("resolveEntity");\r
-#endif\r
- if (!systemId)\r
- return NULL;\r
-\r
- Category& log=Category::getInstance(XMLTOOLING_LOGCAT".ParserPool");\r
- if (log.isDebugEnabled()) {\r
- auto_ptr_char sysId(systemId);\r
- auto_ptr_char base(baseURI);\r
- log.debug("asked to resolve %s with baseURI %s",sysId.get(),base.get() ? base.get() : "(null)");\r
- }\r
-\r
- // Find well-known schemas in the specified location.\r
-#ifdef HAVE_GOOD_STL\r
- map<xstring,xstring>::const_iterator i=m_schemaLocMap.find(systemId);\r
- if (i!=m_schemaLocMap.end())\r
- return new Wrapper4InputSource(new LocalFileInputSource(NULL,i->second.c_str()));\r
-#else\r
- auto_ptr_char temp(systemId);\r
- map<string,string>::const_iterator i=m_schemaLocMap.find(temp.get());\r
- auto_ptr_XMLCh temp2(i->second.c_str());\r
- if (i!=m_schemaLocMap.end())\r
- return new Wrapper4InputSource(new LocalFileInputSource(NULL,temp2.get()));\r
-#endif \r
-\r
- // Shortcircuit the request.\r
- log.warn("unauthorized entity request, blocking it");\r
- static const XMLByte nullbuf[] = {0};\r
- return new Wrapper4InputSource(new MemBufInputSource(nullbuf,0,systemId));\r
-}\r
-\r
-bool ParserPool::handleError(const DOMError& e)\r
-{\r
-#ifdef _DEBUG\r
- xmltooling::NDC ndc("handleError");\r
-#endif\r
- Category& log=Category::getInstance(XMLTOOLING_LOGCAT".ParserPool");\r
- DOMLocator* locator=e.getLocation();\r
- auto_ptr_char temp(e.getMessage());\r
-\r
- switch (e.getSeverity()) {\r
- case DOMError::DOM_SEVERITY_WARNING:\r
- log.warnStream() << "warning on line " << locator->getLineNumber()\r
- << ", column " << locator->getColumnNumber()\r
- << ", message: " << temp.get() << CategoryStream::ENDLINE;\r
- return true;\r
-\r
- case DOMError::DOM_SEVERITY_ERROR:\r
- log.errorStream() << "error on line " << locator->getLineNumber()\r
- << ", column " << locator->getColumnNumber()\r
- << ", message: " << temp.get() << CategoryStream::ENDLINE;\r
- throw XMLParserException(string("error during XML parsing: ") + (temp.get() ? temp.get() : "no message"));\r
-\r
- case DOMError::DOM_SEVERITY_FATAL_ERROR:\r
- log.critStream() << "fatal error on line " << locator->getLineNumber()\r
- << ", column " << locator->getColumnNumber()\r
- << ", message: " << temp.get() << CategoryStream::ENDLINE;\r
- throw XMLParserException(string("fatal error during XML parsing: ") + (temp.get() ? temp.get() : "no message"));\r
- }\r
- throw XMLParserException(string("unclassified error during XML parsing: ") + (temp.get() ? temp.get() : "no message"));\r
-}\r
-\r
-DOMBuilder* ParserPool::createBuilder()\r
-{\r
- static const XMLCh impltype[] = { chLatin_L, chLatin_S, chNull };\r
- DOMImplementation* impl=DOMImplementationRegistry::getDOMImplementation(impltype);\r
- DOMBuilder* parser=static_cast<DOMImplementationLS*>(impl)->createDOMBuilder(DOMImplementationLS::MODE_SYNCHRONOUS,0);\r
- if (m_namespaceAware)\r
- parser->setFeature(XMLUni::fgDOMNamespaces,true);\r
- if (m_schemaAware) {\r
- parser->setFeature(XMLUni::fgXercesSchema,true);\r
- parser->setFeature(XMLUni::fgDOMValidation,true);\r
- parser->setFeature(XMLUni::fgXercesCacheGrammarFromParse,true);\r
- parser->setFeature(XMLUni::fgXercesValidationErrorAsFatal,true);\r
- \r
- // We build a "fake" schema location hint that binds each namespace to itself.\r
- // This ensures the entity resolver will be given the namespace as a systemId it can check. \r
-#ifdef HAVE_GOOD_STL\r
- parser->setProperty(XMLUni::fgXercesSchemaExternalSchemaLocation,const_cast<XMLCh*>(m_schemaLocations.c_str()));\r
-#else\r
- auto_ptr_XMLCh temp(m_schemaLocations.c_str());\r
- parser->setProperty(XMLUni::fgXercesSchemaExternalSchemaLocation,const_cast<XMLCh*>(temp.get()));\r
-#endif\r
- }\r
- parser->setFeature(XMLUni::fgXercesUserAdoptsDOMDocument,true);\r
- parser->setEntityResolver(this);\r
- parser->setErrorHandler(this);\r
- return parser;\r
-}\r
-\r
-DOMBuilder* ParserPool::checkoutBuilder()\r
-{\r
- XMLPlatformUtils::lockMutex(m_lock);\r
- try {\r
- if (m_pool.empty()) {\r
- DOMBuilder* builder=createBuilder();\r
- XMLPlatformUtils::unlockMutex(m_lock);\r
- return builder;\r
- }\r
- DOMBuilder* p=m_pool.top();\r
- m_pool.pop();\r
- if (m_schemaAware) {\r
-#ifdef HAVE_GOOD_STL\r
- p->setProperty(XMLUni::fgXercesSchemaExternalSchemaLocation,const_cast<XMLCh*>(m_schemaLocations.c_str()));\r
-#else\r
- auto_ptr_XMLCh temp2(m_schemaLocations.c_str());\r
- p->setProperty(XMLUni::fgXercesSchemaExternalSchemaLocation,const_cast<XMLCh*>(temp2.get()));\r
-#endif\r
- }\r
- XMLPlatformUtils::unlockMutex(m_lock);\r
- return p;\r
- }\r
- catch(...) {\r
- XMLPlatformUtils::unlockMutex(m_lock);\r
- throw;\r
- }\r
-}\r
-\r
-void ParserPool::checkinBuilder(DOMBuilder* builder)\r
-{\r
- if (builder) {\r
- XMLPlatformUtils::lockMutex(m_lock);\r
- m_pool.push(builder);\r
- XMLPlatformUtils::unlockMutex(m_lock);\r
- }\r
-}\r
-\r
-unsigned int StreamInputSource::StreamBinInputStream::readBytes(XMLByte* const toFill, const unsigned int maxToRead)\r
-{\r
- XMLByte* target=toFill;\r
- unsigned int bytes_read=0,request=maxToRead;\r
-\r
- // Fulfill the rest by reading from the stream.\r
- if (request && !m_is.eof()) {\r
- try {\r
- m_is.read(reinterpret_cast<char* const>(target),request);\r
- m_pos+=m_is.gcount();\r
- bytes_read+=m_is.gcount();\r
- }\r
- catch(...) {\r
- Category::getInstance(XMLTOOLING_LOGCAT".StreamInputSource").critStream() <<\r
- "XML::StreamInputSource::StreamBinInputStream::readBytes caught an exception" << CategoryStream::ENDLINE;\r
- *toFill=0;\r
- return 0;\r
- }\r
- }\r
- return bytes_read;\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.
+ */
+
+/**
+ * ParserPool.cpp
+ *
+ * XML parsing
+ */
+
+#include "internal.h"
+#include "exceptions.h"
+#include "util/NDC.h"
+#include "util/ParserPool.h"
+#include "util/XMLHelper.h"
+
+#include <algorithm>
+#include <functional>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <log4cpp/Category.hh>
+#include <xercesc/util/PlatformUtils.hpp>
+#include <xercesc/util/XMLUniDefs.hpp>
+#include <xercesc/sax/SAXException.hpp>
+#include <xercesc/framework/MemBufInputSource.hpp>
+#include <xercesc/framework/LocalFileInputSource.hpp>
+#include <xercesc/framework/Wrapper4InputSource.hpp>
+
+using namespace xmltooling;
+using namespace std;
+using namespace log4cpp;
+
+ParserPool::ParserPool(bool namespaceAware, bool schemaAware)
+ : m_namespaceAware(namespaceAware), m_schemaAware(schemaAware), m_lock(XMLPlatformUtils::makeMutex()) {}
+
+ParserPool::~ParserPool()
+{
+ while(!m_pool.empty()) {
+ m_pool.top()->release();
+ m_pool.pop();
+ }
+ XMLPlatformUtils::closeMutex(m_lock);
+}
+
+DOMDocument* ParserPool::newDocument()
+{
+ return DOMImplementationRegistry::getDOMImplementation(NULL)->createDocument();
+}
+
+DOMDocument* ParserPool::parse(DOMInputSource& domsrc)
+{
+ DOMBuilder* parser=checkoutBuilder();
+ try {
+ DOMDocument* doc=parser->parse(domsrc);
+ parser->setFeature(XMLUni::fgXercesUserAdoptsDOMDocument,true);
+ checkinBuilder(parser);
+ return doc;
+ }
+ catch (...) {
+ checkinBuilder(parser);
+ throw;
+ }
+}
+
+DOMDocument* ParserPool::parse(istream& is)
+{
+ StreamInputSource src(is);
+ Wrapper4InputSource domsrc(&src,false);
+ return parse(domsrc);
+}
+
+// Functor to double its argument separated by a character and append to a buffer
+template <class T> class doubleit
+{
+public:
+ doubleit(T& t, const typename T::value_type& s) : temp(t), sep(s) {}
+ void operator() (const pair<T,T>& s) { temp += s.first + sep + s.first + sep; }
+ T& temp;
+ const typename T::value_type& sep;
+};
+
+bool ParserPool::loadSchema(const XMLCh* nsURI, const XMLCh* pathname)
+{
+ // Just check the pathname and then directly register the pair into the map.
+
+ auto_ptr_char p(pathname);
+#ifdef WIN32
+ struct _stat stat_buf;
+ if (_stat(p.get(), &stat_buf) != 0)
+#else
+ struct stat stat_buf;
+ if (stat(p.get(), &stat_buf) != 0)
+#endif
+ {
+#if _DEBUG
+ xmltooling::NDC ndc("loadSchema");
+#endif
+ Category& log=Category::getInstance(XMLTOOLING_LOGCAT".ParserPool");
+ auto_ptr_char n(nsURI);
+ log.error("failed to load schema for (%s), file not found (%s)",n.get(),p.get());
+ return false;
+ }
+
+ XMLPlatformUtils::lockMutex(m_lock);
+#ifdef HAVE_GOOD_STL
+ m_schemaLocMap[nsURI]=pathname;
+ m_schemaLocations.erase();
+ for_each(m_schemaLocMap.begin(),m_schemaLocMap.end(),doubleit<xstring>(m_schemaLocations,chSpace));
+#else
+ auto_ptr_char n(nsURI);
+ m_schemaLocMap[n.get()]=p.get();
+ m_schemaLocations.erase();
+ for_each(m_schemaLocMap.begin(),m_schemaLocMap.end(),doubleit<string>(m_schemaLocations,' '));
+#endif
+ XMLPlatformUtils::unlockMutex(m_lock);
+
+ return true;
+}
+
+bool ParserPool::loadCatalog(const XMLCh* pathname)
+{
+#if _DEBUG
+ xmltooling::NDC ndc("loadCatalog");
+#endif
+ Category& log=Category::getInstance(XMLTOOLING_LOGCAT".ParserPool");
+
+ // XML constants
+ static const XMLCh catalog[] = { chLatin_c, chLatin_a, chLatin_t, chLatin_a, chLatin_l, chLatin_o, chLatin_g, chNull };
+ static const XMLCh uri[] = { chLatin_u, chLatin_r, chLatin_i, chNull };
+ static const XMLCh name[] = { chLatin_n, chLatin_a, chLatin_m, chLatin_e, chNull };
+ static const XMLCh CATALOG_NS[] = {
+ chLatin_u, chLatin_r, chLatin_n, chColon,
+ chLatin_o, chLatin_a, chLatin_s, chLatin_i, chLatin_s, chColon,
+ chLatin_n, chLatin_a, chLatin_m, chLatin_e, chLatin_s, chColon,
+ chLatin_t, chLatin_c, chColon,
+ chLatin_e, chLatin_n, chLatin_t, chLatin_i, chLatin_t, chLatin_y, chColon,
+ chLatin_x, chLatin_m, chLatin_l, chLatin_n, chLatin_s, chColon,
+ chLatin_x, chLatin_m, chLatin_l, chColon,
+ chLatin_c, chLatin_a, chLatin_t, chLatin_a, chLatin_l, chLatin_o, chLatin_g, chNull
+ };
+
+ // Parse the catalog with the internal parser pool.
+
+ if (log.isDebugEnabled()) {
+ auto_ptr_char temp(pathname);
+ log.debug("loading XML catalog from %s", temp.get());
+ }
+
+ LocalFileInputSource fsrc(NULL,pathname);
+ Wrapper4InputSource domsrc(&fsrc,false);
+ try {
+ DOMDocument* doc=XMLToolingInternalConfig::getInternalConfig().m_parserPool->parse(domsrc);
+
+ // Check root element.
+ const DOMElement* root=doc->getDocumentElement();
+ if (!XMLHelper::isNodeNamed(root,CATALOG_NS,catalog)) {
+ auto_ptr_char temp(pathname);
+ log.error("unknown root element, failed to load XML catalog from %s", temp.get());
+ doc->release();
+ return false;
+ }
+
+ // Fetch all the <uri> elements.
+ DOMNodeList* mappings=root->getElementsByTagNameNS(CATALOG_NS,uri);
+ XMLPlatformUtils::lockMutex(m_lock);
+ for (XMLSize_t i=0; i<mappings->getLength(); i++) {
+ root=static_cast<DOMElement*>(mappings->item(i));
+ const XMLCh* from=root->getAttributeNS(NULL,name);
+ const XMLCh* to=root->getAttributeNS(NULL,uri);
+#ifdef HAVE_GOOD_STL
+ m_schemaLocMap[from]=to;
+#else
+ auto_ptr_char f(from);
+ auto_ptr_char t(to);
+ m_schemaLocMap[f.get()]=t.get();
+#endif
+ }
+ m_schemaLocations.erase();
+#ifdef HAVE_GOOD_STL
+ for_each(m_schemaLocMap.begin(),m_schemaLocMap.end(),doubleit<xstring>(m_schemaLocations,chSpace));
+#else
+ for_each(m_schemaLocMap.begin(),m_schemaLocMap.end(),doubleit<string>(m_schemaLocations,' '));
+#endif
+ XMLPlatformUtils::unlockMutex(m_lock);
+ doc->release();
+ }
+ catch (XMLParserException& e) {
+ log.error("catalog loader caught XMLParserException: %s", e.what());
+ return false;
+ }
+
+ return true;
+}
+
+DOMInputSource* ParserPool::resolveEntity(const XMLCh* const publicId, const XMLCh* const systemId, const XMLCh* const baseURI)
+{
+#if _DEBUG
+ xmltooling::NDC ndc("resolveEntity");
+#endif
+ if (!systemId)
+ return NULL;
+
+ Category& log=Category::getInstance(XMLTOOLING_LOGCAT".ParserPool");
+ if (log.isDebugEnabled()) {
+ auto_ptr_char sysId(systemId);
+ auto_ptr_char base(baseURI);
+ log.debug("asked to resolve %s with baseURI %s",sysId.get(),base.get() ? base.get() : "(null)");
+ }
+
+ // Find well-known schemas in the specified location.
+#ifdef HAVE_GOOD_STL
+ map<xstring,xstring>::const_iterator i=m_schemaLocMap.find(systemId);
+ if (i!=m_schemaLocMap.end())
+ return new Wrapper4InputSource(new LocalFileInputSource(NULL,i->second.c_str()));
+#else
+ auto_ptr_char temp(systemId);
+ map<string,string>::const_iterator i=m_schemaLocMap.find(temp.get());
+ auto_ptr_XMLCh temp2(i->second.c_str());
+ if (i!=m_schemaLocMap.end())
+ return new Wrapper4InputSource(new LocalFileInputSource(NULL,temp2.get()));
+#endif
+
+ // Shortcircuit the request.
+ log.warn("unauthorized entity request, blocking it");
+ static const XMLByte nullbuf[] = {0};
+ return new Wrapper4InputSource(new MemBufInputSource(nullbuf,0,systemId));
+}
+
+bool ParserPool::handleError(const DOMError& e)
+{
+#ifdef _DEBUG
+ xmltooling::NDC ndc("handleError");
+#endif
+ Category& log=Category::getInstance(XMLTOOLING_LOGCAT".ParserPool");
+ DOMLocator* locator=e.getLocation();
+ auto_ptr_char temp(e.getMessage());
+
+ switch (e.getSeverity()) {
+ case DOMError::DOM_SEVERITY_WARNING:
+ log.warnStream() << "warning on line " << locator->getLineNumber()
+ << ", column " << locator->getColumnNumber()
+ << ", message: " << temp.get() << CategoryStream::ENDLINE;
+ return true;
+
+ case DOMError::DOM_SEVERITY_ERROR:
+ log.errorStream() << "error on line " << locator->getLineNumber()
+ << ", column " << locator->getColumnNumber()
+ << ", message: " << temp.get() << CategoryStream::ENDLINE;
+ throw XMLParserException(string("error during XML parsing: ") + (temp.get() ? temp.get() : "no message"));
+
+ case DOMError::DOM_SEVERITY_FATAL_ERROR:
+ log.critStream() << "fatal error on line " << locator->getLineNumber()
+ << ", column " << locator->getColumnNumber()
+ << ", message: " << temp.get() << CategoryStream::ENDLINE;
+ throw XMLParserException(string("fatal error during XML parsing: ") + (temp.get() ? temp.get() : "no message"));
+ }
+ throw XMLParserException(string("unclassified error during XML parsing: ") + (temp.get() ? temp.get() : "no message"));
+}
+
+DOMBuilder* ParserPool::createBuilder()
+{
+ static const XMLCh impltype[] = { chLatin_L, chLatin_S, chNull };
+ DOMImplementation* impl=DOMImplementationRegistry::getDOMImplementation(impltype);
+ DOMBuilder* parser=static_cast<DOMImplementationLS*>(impl)->createDOMBuilder(DOMImplementationLS::MODE_SYNCHRONOUS,0);
+ if (m_namespaceAware)
+ parser->setFeature(XMLUni::fgDOMNamespaces,true);
+ if (m_schemaAware) {
+ parser->setFeature(XMLUni::fgXercesSchema,true);
+ parser->setFeature(XMLUni::fgDOMValidation,true);
+ parser->setFeature(XMLUni::fgXercesCacheGrammarFromParse,true);
+ parser->setFeature(XMLUni::fgXercesValidationErrorAsFatal,true);
+
+ // We build a "fake" schema location hint that binds each namespace to itself.
+ // This ensures the entity resolver will be given the namespace as a systemId it can check.
+#ifdef HAVE_GOOD_STL
+ parser->setProperty(XMLUni::fgXercesSchemaExternalSchemaLocation,const_cast<XMLCh*>(m_schemaLocations.c_str()));
+#else
+ auto_ptr_XMLCh temp(m_schemaLocations.c_str());
+ parser->setProperty(XMLUni::fgXercesSchemaExternalSchemaLocation,const_cast<XMLCh*>(temp.get()));
+#endif
+ }
+ parser->setFeature(XMLUni::fgXercesUserAdoptsDOMDocument,true);
+ parser->setEntityResolver(this);
+ parser->setErrorHandler(this);
+ return parser;
+}
+
+DOMBuilder* ParserPool::checkoutBuilder()
+{
+ XMLPlatformUtils::lockMutex(m_lock);
+ try {
+ if (m_pool.empty()) {
+ DOMBuilder* builder=createBuilder();
+ XMLPlatformUtils::unlockMutex(m_lock);
+ return builder;
+ }
+ DOMBuilder* p=m_pool.top();
+ m_pool.pop();
+ if (m_schemaAware) {
+#ifdef HAVE_GOOD_STL
+ p->setProperty(XMLUni::fgXercesSchemaExternalSchemaLocation,const_cast<XMLCh*>(m_schemaLocations.c_str()));
+#else
+ auto_ptr_XMLCh temp2(m_schemaLocations.c_str());
+ p->setProperty(XMLUni::fgXercesSchemaExternalSchemaLocation,const_cast<XMLCh*>(temp2.get()));
+#endif
+ }
+ XMLPlatformUtils::unlockMutex(m_lock);
+ return p;
+ }
+ catch(...) {
+ XMLPlatformUtils::unlockMutex(m_lock);
+ throw;
+ }
+}
+
+void ParserPool::checkinBuilder(DOMBuilder* builder)
+{
+ if (builder) {
+ XMLPlatformUtils::lockMutex(m_lock);
+ m_pool.push(builder);
+ XMLPlatformUtils::unlockMutex(m_lock);
+ }
+}
+
+unsigned int StreamInputSource::StreamBinInputStream::readBytes(XMLByte* const toFill, const unsigned int maxToRead)
+{
+ XMLByte* target=toFill;
+ unsigned int bytes_read=0,request=maxToRead;
+
+ // Fulfill the rest by reading from the stream.
+ if (request && !m_is.eof()) {
+ try {
+ m_is.read(reinterpret_cast<char* const>(target),request);
+ m_pos+=m_is.gcount();
+ bytes_read+=m_is.gcount();
+ }
+ catch(...) {
+ Category::getInstance(XMLTOOLING_LOGCAT".StreamInputSource").critStream() <<
+ "XML::StreamInputSource::StreamBinInputStream::readBytes caught an exception" << CategoryStream::ENDLINE;
+ *toFill=0;
+ return 0;
+ }
+ }
+ return bytes_read;
+}
Container& sublist,
typename std::list<_Ty*>* backing,
typename std::list<_Ty*>::iterator ins_fence
- ) : m_parent(parent), m_container(sublist), m_list(backing), m_fence(ins_fence) {
+ ) : m_container(sublist), m_list(backing), m_fence(ins_fence), m_parent(parent) {
}
/// @cond OFF
xmltoolingtest_h = \
ComplexXMLObjectTest.h \
- ExceptionText.h \
+ ExceptionTest.h \
MarshallingTest.h \
UnmarshallingTest.h \
xmltoolingtest.h \