+#else
+ XMLToolingConfig::getConfig().term();
+#endif
+ log.info("%s library shutdown complete", PACKAGE_STRING);
+}
+
+bool SPConfig::instantiate(const char* config, bool rethrow)
+{
+#ifdef _DEBUG
+ NDC ndc("instantiate");
+#endif
+ if (!config)
+ config = getenv("SHIBSP_CONFIG");
+ if (!config)
+ config = SHIBSP_CONFIG;
+ try {
+ xercesc::DOMDocument* dummydoc;
+ if (*config == '"' || *config == '\'') {
+ throw ConfigurationException("The value of SHIBSP_CONFIG started with a quote.");
+ }
+ else if (*config != '<') {
+
+ // Mock up some XML.
+ string resolved(config);
+ stringstream snippet;
+ snippet
+ << "<Dummy path='"
+ << XMLToolingConfig::getConfig().getPathResolver()->resolve(resolved, PathResolver::XMLTOOLING_CFG_FILE)
+ << "' validate='1'/>";
+ dummydoc = XMLToolingConfig::getConfig().getParser().parse(snippet);
+ XercesJanitor<xercesc::DOMDocument> docjanitor(dummydoc);
+ setServiceProvider(ServiceProviderManager.newPlugin(XML_SERVICE_PROVIDER, dummydoc->getDocumentElement()));
+ if (m_configDoc)
+ m_configDoc->release();
+ m_configDoc = docjanitor.release();
+ }
+ else {
+ stringstream snippet(config);
+ dummydoc = XMLToolingConfig::getConfig().getParser().parse(snippet);
+ XercesJanitor<xercesc::DOMDocument> docjanitor(dummydoc);
+ static const XMLCh _type[] = UNICODE_LITERAL_4(t,y,p,e);
+ auto_ptr_char type(dummydoc->getDocumentElement()->getAttributeNS(nullptr,_type));
+ if (type.get() && *type.get())
+ setServiceProvider(ServiceProviderManager.newPlugin(type.get(), dummydoc->getDocumentElement()));
+ else
+ throw ConfigurationException("The supplied XML bootstrapping configuration did not include a type attribute.");
+ if (m_configDoc)
+ m_configDoc->release();
+ m_configDoc = docjanitor.release();
+ }
+
+ getServiceProvider()->init();
+ return true;
+ }
+ catch (exception& ex) {
+ if (rethrow)
+ throw;
+ Category::getInstance(SHIBSP_LOGCAT".Config").fatal("caught exception while loading configuration: %s", ex.what());
+ }
+ return false;
+}
+
+TransactionLog::TransactionLog() : log(logging::Category::getInstance(SHIBSP_TX_LOGCAT)), m_lock(Mutex::create())
+{
+}
+
+TransactionLog::~TransactionLog()
+{
+ delete m_lock;
+}
+
+Lockable* TransactionLog::lock()
+{
+ m_lock->lock();
+ return this;
+}
+
+void TransactionLog::unlock()
+{
+ m_lock->unlock();