From 1ccaafc90bd7e241228e8ea8248445d8c63fb796 Mon Sep 17 00:00:00 2001 From: cantor Date: Fri, 17 Feb 2006 07:50:03 +0000 Subject: [PATCH] Some root interfaces and configuration machinery git-svn-id: https://svn.middleware.georgetown.edu/cpp-xmltooling/trunk@4 de75baf8-a10c-0410-a50a-987c0e22f00f --- xmltooling/ILockable.h | 81 +++++++++++++ xmltooling/Namespace.cpp | 15 +-- xmltooling/Namespace.h | 16 +-- xmltooling/QName.cpp | 121 +++++++++++++++++++ xmltooling/QName.h | 149 ++++++++++++++++++++++++ xmltooling/XMLObject.h | 150 ++++++++++++++++++++++++ xmltooling/XMLObjectBuilder.h | 50 ++++++++ xmltooling/XMLToolingConfig.cpp | 251 ++++++++++++++++++++++++++++++++++++++++ xmltooling/XMLToolingConfig.h | 94 +++++++++++++++ xmltooling/base.h | 10 ++ xmltooling/internal.h | 31 +++++ xmltooling/unicode.h | 10 +- xmltooling/xmltooling.vcproj | 50 +++++++- 13 files changed, 995 insertions(+), 33 deletions(-) create mode 100644 xmltooling/ILockable.h create mode 100644 xmltooling/QName.cpp create mode 100644 xmltooling/QName.h create mode 100644 xmltooling/XMLObject.h create mode 100644 xmltooling/XMLObjectBuilder.h create mode 100644 xmltooling/XMLToolingConfig.cpp create mode 100644 xmltooling/XMLToolingConfig.h diff --git a/xmltooling/ILockable.h b/xmltooling/ILockable.h new file mode 100644 index 0000000..500e41e --- /dev/null +++ b/xmltooling/ILockable.h @@ -0,0 +1,81 @@ +/* + * 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 ILockable.h + * + * Locking abstraction + */ + +#if !defined(__xmltooling_lockable_h__) +#define __xmltooling_lockable_h__ + +#include + +namespace xmltooling { + + /** + * Singleton object that manages library startup/shutdown.configuration. + */ + struct XMLTOOL_API ILockable + { + virtual ~ILockable() {} + + /** + * Lock the associated object for exclusive access. + * + * @return a reference to the object being locked + */ + virtual ILockable& 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: + /** + * Locks an object and stores it for later release. + * + * @param lockee Pointer to an object to lock and hold + */ + Locker(ILockable* lockee) : m_lockee(lockee->lock()) {} + + /** + * Locks an object and stores it for later release. + * + * @param lockee Reference to an object to lock and hold + */ + Locker(ILockable& lockee) : m_lockee(lockee.lock()) {} + + /** + * Releases lock on held pointer, if any. + */ + ~Locker() {m_lockee.unlock();} + private: + ILockable& m_lockee; + }; + +}; + +#endif /* __xmltooling_lockable_h__ */ diff --git a/xmltooling/Namespace.cpp b/xmltooling/Namespace.cpp index 0d7a3f2..06bb82e 100644 --- a/xmltooling/Namespace.cpp +++ b/xmltooling/Namespace.cpp @@ -14,29 +14,22 @@ * limitations under the License. */ -/* Namespace.cpp +/** + * @file Namespace.cpp * - * Data structure for representing XML namespace attributes - * - * $Id:$ + * Representing XML namespace attributes */ #include "internal.h" -#include "unicode.h" #include "Namespace.h" -using namespace std; using namespace xmltooling; -Namespace::Namespace() +Namespace::Namespace(const XMLCh* uri, const XMLCh* prefix) { #ifndef HAVE_GOOD_STL m_uri=m_prefix=NULL; #endif -} - -Namespace::Namespace(const XMLCh* uri, const XMLCh* prefix) -{ setNamespaceURI(uri); setNamespacePrefix(prefix); } diff --git a/xmltooling/Namespace.h b/xmltooling/Namespace.h index d94c845..984df21 100644 --- a/xmltooling/Namespace.h +++ b/xmltooling/Namespace.h @@ -23,8 +23,7 @@ #if !defined(__xmltooling_namespace_h__) #define __xmltooling_namespace_h__ -#include -#include +#include namespace xmltooling { @@ -35,28 +34,23 @@ namespace xmltooling { { public: /** - * Default constructor - */ - Namespace(); - - /** - * Constructor that takes an existing declaration + * Constructor * @param uri namespace URI * @param prefix namespace prefix (without the colon) */ - Namespace(const XMLCh* uri, const XMLCh* prefix); + Namespace(const XMLCh* uri=NULL, const XMLCh* prefix=NULL); ~Namespace(); #ifndef HAVE_GOOD_STL /** * Deep copy constructor */ - Namespace(const Namespace&); + Namespace(const Namespace& src); /** * Deep assignment operator */ - Namespace& operator=(const Namespace&); + Namespace& operator=(const Namespace& src); #endif #ifdef HAVE_GOOD_STL diff --git a/xmltooling/QName.cpp b/xmltooling/QName.cpp new file mode 100644 index 0000000..abf3c87 --- /dev/null +++ b/xmltooling/QName.cpp @@ -0,0 +1,121 @@ +/* + * 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.cpp + * + * Representing XML QNames + */ + +#include "internal.h" +#include "QName.h" + +using namespace xmltooling; + +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; +} + +bool xmltooling::operator==(const QName& op1, const QName& op2) +{ + return (!XMLString::compareString(op1.getNamespaceURI(),op2.getNamespaceURI()) && + !XMLString::compareString(op1.getLocalPart(),op2.getLocalPart())); +} +#endif + +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; +} diff --git a/xmltooling/QName.h b/xmltooling/QName.h new file mode 100644 index 0000000..8836d6c --- /dev/null +++ b/xmltooling/QName.h @@ -0,0 +1,149 @@ +/* + * 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 +#include + +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 + /** + * 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 + /** + * 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); + + 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); + +#ifndef HAVE_GOOD_STL + /** + * Returns true iff op1's components are equal to op2's components. + * @param op1 First qname to compare + * @param op2 Second qname to compare + */ + extern XMLTOOL_API bool operator==(const QName& op1, const QName& op2); +#endif + +}; + +#endif /* __xmltooling_qname_h__ */ diff --git a/xmltooling/XMLObject.h b/xmltooling/XMLObject.h new file mode 100644 index 0000000..a16b325 --- /dev/null +++ b/xmltooling/XMLObject.h @@ -0,0 +1,150 @@ +/* + * 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. + */ + +#if !defined(__xmltooling_xmlobj_h__) +#define __xmltooling_xmlobj_h__ + +#include +#include +#include +#include + +namespace xmltooling { + + /** + * Object that represents an XML Element that has been unmarshalled into this C++ object. + */ + class XMLTOOL_API XMLObject + { + MAKE_NONCOPYABLE(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; + + /** + * Gets the QName for this element. This QName MUST + * 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; + + /** + * Sets the namespace prefix for this element. + * + * @param prefix the prefix for this element + */ + virtual void setElementNamespacePrefix(const XMLCh* prefix)=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& 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)=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; + + /** + * Sets the XML schema type of this element. This translates to contents the xsi:type + * attribute for the element. + * + * @param type XML schema type of this element + */ + virtual void setSchemaType(const QName* type)=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; + + /** + * Stores an unmodifiable list of child objects in the order that they + * will appear in the serialized representation. + * + * The validity of the returned objects is not maintained if any non-const + * operations are performed on the parent object. + * + * @param v vector in which to store pointers to child objects + * @return the number of children + */ + virtual size_t getOrderedChildren(std::vector& v)=0; + }; + +}; + +#endif /* __xmltooling_xmlobj_h__ */ diff --git a/xmltooling/XMLObjectBuilder.h b/xmltooling/XMLObjectBuilder.h new file mode 100644 index 0000000..e2d023c --- /dev/null +++ b/xmltooling/XMLObjectBuilder.h @@ -0,0 +1,50 @@ +/* + * 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 XMLObjectBuilder.h + * + * Factory interface for XMLObjects + */ + +#if !defined(__xmltooling_xmlobjbuilder_h__) +#define __xmltooling_xmlobjbuilder_h__ + +#include + +namespace xmltooling { + + /** + * A factory interface for obtaining XMLObjects. + * Subclasses MAY supply additional factory methods. + */ + class XMLTOOL_API XMLObjectBuilder + { + MAKE_NON_COPYABLE(XMLObjectBuilder); + public: + virtual ~XMLObjectBuilder() {} + + /** + * Creates an empty XMLObject. + * + * @return the empty XMLObject + */ + public XMLObject* buildObject(); + }; + +}; + +#endif /* __xmltooling_xmlobjbuilder_h__ */ diff --git a/xmltooling/XMLToolingConfig.cpp b/xmltooling/XMLToolingConfig.cpp new file mode 100644 index 0000000..a81a222 --- /dev/null +++ b/xmltooling/XMLToolingConfig.cpp @@ -0,0 +1,251 @@ +/* + * 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.cpp + * + * Library configuration + */ + +#include "internal.h" +#include "XMLToolingConfig.h" +#include "util/NDC.h" + +#ifdef HAVE_DLFCN_H +# include +#endif + +#include +#include +#include +#include +#include + +#include + +using namespace log4cpp; +using namespace xmltooling; +using namespace std; + +namespace { + XMLToolingInternalConfig g_config; +} + +XMLToolingConfig& XMLToolingConfig::getConfig() +{ + return g_config; +} + +bool XMLToolingInternalConfig::log_config(const char* config) +{ + try { + if (!config && !*config) + config=getenv("XMLTOOLING_LOG_CONFIG"); + if (!config && !*config) + config="WARN"; + + bool level=false; + Category& root = Category::getRoot(); + if (!strcmp(config,"DEBUG")) { + root.setPriority(Priority::DEBUG); + level=true; + } + else if (!strcmp(config,"INFO")) { + root.setPriority(Priority::INFO); + level=true; + } + else if (!strcmp(config,"NOTICE")) { + root.setPriority(Priority::NOTICE); + level=true; + } + else if (!strcmp(config,"WARN")) { + root.setPriority(Priority::WARN); + level=true; + } + else if (!strcmp(config,"ERROR")) { + root.setPriority(Priority::ERROR); + level=true; + } + else if (!strcmp(config,"CRIT")) { + root.setPriority(Priority::CRIT); + level=true; + } + else if (!strcmp(config,"ALERT")) { + root.setPriority(Priority::ALERT); + level=true; + } + else if (!strcmp(config,"EMERG")) { + root.setPriority(Priority::EMERG); + level=true; + } + else if (!strcmp(config,"FATAL")) { + root.setPriority(Priority::FATAL); + level=true; + } + if (level) + root.setAppender(new OstreamAppender("default",&cerr)); + else + PropertyConfigurator::configure(config); + } + catch (const ConfigureFailure& e) { + Category::getInstance(XMLTOOLING_LOGCAT".Logging").crit("failed to initialize log4cpp: %s", e.what()); + return false; + } + + return true; +} + +bool XMLToolingInternalConfig::init() +{ +#ifdef _DEBUG + xmltooling::NDC ndc("init"); +#endif + Category& log=Category::getInstance(XMLTOOLING_LOGCAT".XMLToolingConfig"); + try { + log.debug("library initialization started"); + + xercesc::XMLPlatformUtils::Initialize(); + log.debug("Xerces initialization complete"); + + XSECPlatformUtils::Initialise(); + //m_xsec=new XSECProvider(); + log.debug("XMLSec initialization complete"); + + m_lock=xercesc::XMLPlatformUtils::makeMutex(); + } + catch (const xercesc::XMLException&) { + log.fatal("caught exception while initializing Xerces"); + return false; + } + + log.info("library initialization complete"); + return true; +} + +void XMLToolingInternalConfig::term() +{ + for (vector::reverse_iterator i=m_libhandles.rbegin(); i!=m_libhandles.rend(); i++) { +#if defined(WIN32) + FARPROC fn=GetProcAddress(static_cast(*i),"xmltooling_extension_term"); + if (fn) + fn(); + FreeLibrary(static_cast(*i)); +#elif defined(HAVE_DLFCN_H) + void (*fn)()=(void (*)())dlsym(*i,"xmltooling_extension_term"); + if (fn) + fn(); + dlclose(*i); +#else +# error "Don't know about dynamic loading on this platform!" +#endif + } + m_libhandles.clear(); + + //delete m_xsec; m_xsec=NULL; + XSECPlatformUtils::Terminate(); + xercesc::XMLPlatformUtils::closeMutex(m_lock); + xercesc::XMLPlatformUtils::Terminate(); + + #ifdef _DEBUG + xmltooling::NDC ndc("term"); +#endif + Category::getInstance(XMLTOOLING_LOGCAT".XMLToolingConfig").info("library shutdown complete"); +} + +ILockable& XMLToolingInternalConfig::lock() +{ + xercesc::XMLPlatformUtils::lockMutex(m_lock); + return *this; +} + +void XMLToolingInternalConfig::unlock() +{ + xercesc::XMLPlatformUtils::unlockMutex(m_lock); +} + +bool XMLToolingInternalConfig::load_library(const char* path, void* context) +{ +#ifdef _DEBUG + xmltooling::NDC ndc("LoadLibrary"); +#endif + Category& log=Category::getInstance(XMLTOOLING_LOGCAT".XMLToolingConfig"); + log.info("loading extension: %s", path); + +#if defined(WIN32) + HMODULE handle=NULL; + char* fixed=const_cast(path); + if (strchr(fixed,'/')) { + fixed=strdup(path); + char* p=fixed; + while (p=strchr(p,'/')) + *p='\\'; + } + + UINT em=SetErrorMode(SEM_FAILCRITICALERRORS); + try { + handle=LoadLibraryEx(fixed,NULL,LOAD_WITH_ALTERED_SEARCH_PATH); + if (!handle) + handle=LoadLibraryEx(fixed,NULL,0); + if (!handle) + throw runtime_error(string("unable to load extension library: ") + fixed); + FARPROC fn=GetProcAddress(handle,"xmltooling_extension_init"); + if (!fn) + throw runtime_error(string("unable to locate xmltooling_extension_init entry point: ") + fixed); + if (reinterpret_cast(fn)(context)!=0) + throw runtime_error(string("detected error in xmltooling_extension_init: ") + fixed); + if (fixed!=path) + free(fixed); + SetErrorMode(em); + } + catch(runtime_error& e) { + log.error(e.what()); + if (handle) + FreeLibrary(handle); + SetErrorMode(em); + if (fixed!=path) + free(fixed); + return false; + } + +#elif defined(HAVE_DLFCN_H) + void* handle=dlopen(path,RTLD_LAZY); + if (!handle) + throw runtime_error(string("unable to load extension library '") + path + "': " + dlerror()); + int (*fn)(void*)=(int (*)(void*))(dlsym(handle,"xmltooling_extension_init")); + if (!fn) { + dlclose(handle); + throw runtime_error( + string("unable to locate xmltooling_extension_init entry point in '") + path + "': " + + (dlerror() ? dlerror() : "unknown error") + ); + } + try { + if (fn(context)!=0) + throw runtime_error(string("detected error in xmltooling_extension_init in ") + path); + } + catch(runtime_error& e) { + log.error(e.what()); + if (handle) + dlclose(handle); + return false; + } +#else +# error "Don't know about dynamic loading on this platform!" +#endif + m_libhandles.push_back(handle); + log.info("loaded extension: %s", path); + return true; +} diff --git a/xmltooling/XMLToolingConfig.h b/xmltooling/XMLToolingConfig.h new file mode 100644 index 0000000..6b80eb1 --- /dev/null +++ b/xmltooling/XMLToolingConfig.h @@ -0,0 +1,94 @@ +/* + * 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 + */ + +#if !defined(__xmltooling_config_h__) +#define __xmltooling_config_h__ + +#include + +namespace xmltooling { + + /** + * Singleton object that manages library startup/shutdown.configuration. + */ + class XMLTOOL_API XMLToolingConfig : public ILockable + { + MAKE_NONCOPYABLE(XMLToolingConfig); + 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:
+ * extern "C" int xmltooling_extension_init(void* context);
+ * extern "C" void xmltooling_extension_term(); + * + * @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. + * + * @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; + + protected: + XMLToolingConfig() {} + }; + +}; + +#endif /* __xmltooling_config_h__ */ diff --git a/xmltooling/base.h b/xmltooling/base.h index 3fe0221..4fc9d51 100644 --- a/xmltooling/base.h +++ b/xmltooling/base.h @@ -71,4 +71,14 @@ #define XMLTOOL_EXCEPTIONAPI(api) #endif +// Macro to block copy c'tor and assignment operator for a class +#define MAKE_NONCOPYABLE(type) \ + private: \ + type(const type&); \ + type& operator=(const type&) + +#ifndef NULL +#define NULL 0 +#endif + #endif /* __xmltooling_base_h__ */ diff --git a/xmltooling/internal.h b/xmltooling/internal.h index 03f6d3d..5e6a0f8 100644 --- a/xmltooling/internal.h +++ b/xmltooling/internal.h @@ -34,7 +34,38 @@ #endif #include "base.h" +#include "XMLToolingConfig.h" + +#include #define XMLTOOLING_LOGCAT "XMLTooling" +namespace { + + class XMLToolingInternalConfig : public xmltooling::XMLToolingConfig + { + public: + XMLToolingInternalConfig() : m_lock(NULL) {} + + // global per-process setup and shutdown of runtime + bool init(); + void term(); + + // global mutex available to library applications + xmltooling::ILockable& lock(); + void unlock(); + + // configuration + bool load_library(const char* path, void* context=NULL); + bool log_config(const char* config=NULL); + + private: + std::vector m_libhandles; + void* m_lock; + //XSECProvider* m_xsec; + //PlugManager m_plugMgr; + }; + +}; + #endif /* __xmltooling_internal_h__ */ diff --git a/xmltooling/unicode.h b/xmltooling/unicode.h index 311ffb7..50e78f4 100644 --- a/xmltooling/unicode.h +++ b/xmltooling/unicode.h @@ -94,11 +94,9 @@ namespace xmltooling { */ char* release() { char* temp=m_buf; m_buf=NULL; return temp; } - private: - auto_ptr_char(const auto_ptr_char&); - auto_ptr_char& operator=(const auto_ptr_char&); - + private: char* m_buf; + MAKE_NONCOPYABLE(auto_ptr_char); }; /** @@ -143,10 +141,8 @@ namespace xmltooling { XMLCh* release() { XMLCh* temp=m_buf; m_buf=NULL; return temp; } private: - auto_ptr_XMLCh(const auto_ptr_XMLCh&); - auto_ptr_XMLCh& operator=(const auto_ptr_XMLCh&); - XMLCh* m_buf; + MAKE_NONCOPYABLE(auto_ptr_XMLCh); }; }; diff --git a/xmltooling/xmltooling.vcproj b/xmltooling/xmltooling.vcproj index e65b61e..7a9b44e 100644 --- a/xmltooling/xmltooling.vcproj +++ b/xmltooling/xmltooling.vcproj @@ -45,7 +45,6 @@ MinimalRebuild="true" BasicRuntimeChecks="3" RuntimeLibrary="3" - DisableLanguageExtensions="true" UsePrecompiledHeader="0" BrowseInformation="1" WarningLevel="3" @@ -63,7 +62,7 @@ /> + + + + @@ -194,6 +200,14 @@ RelativePath=".\util\NDC.cpp" > + + + + + + @@ -218,6 +236,10 @@ > + + @@ -225,6 +247,18 @@ RelativePath=".\version.h" > + + + + + + @@ -232,6 +266,14 @@ RelativePath=".\util\NDC.h" > + + + +