/*\r
- * Copyright 2001-2007 Internet2\r
- * \r
+ * Copyright 2001-2009 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
/**\r
* @file ReloadableXMLFile.cpp\r
- * \r
+ *\r
* Base class for file-based XML configuration.\r
*/\r
\r
#include "internal.h"\r
#include "util/NDC.h"\r
+#include "util/PathResolver.h"\r
#include "util/ReloadableXMLFile.h"\r
#include "util/XMLConstants.h"\r
#include "util/XMLHelper.h"\r
\r
#include <xercesc/framework/LocalFileInputSource.hpp>\r
#include <xercesc/framework/Wrapper4InputSource.hpp>\r
-#include <xercesc/framework/URLInputSource.hpp>\r
#include <xercesc/util/XMLUniDefs.hpp>\r
\r
using namespace xmltooling::logging;\r
using namespace xmltooling;\r
+using namespace xercesc;\r
using namespace std;\r
\r
static const XMLCh uri[] = UNICODE_LITERAL_3(u,r,i);\r
static const XMLCh reloadInterval[] = UNICODE_LITERAL_14(r,e,l,o,a,d,I,n,t,e,r,v,a,l);\r
static const XMLCh backingFilePath[] = UNICODE_LITERAL_15(b,a,c,k,i,n,g,F,i,l,e,P,a,t,h);\r
\r
+
+ReloadableXMLFile::~ReloadableXMLFile()
+{
+ delete m_lock;
+}
+\r
ReloadableXMLFile::ReloadableXMLFile(const DOMElement* e, Category& log)\r
: m_root(e), m_local(true), m_validate(false), m_filestamp(0), m_reloadInterval(0), m_lock(NULL), m_log(log)\r
{\r
}\r
else\r
m_local=false;\r
- \r
+\r
if (source && *source) {\r
const XMLCh* flag=e->getAttributeNS(NULL,validate);\r
m_validate=(XMLString::equals(flag,xmlconstants::XML_TRUE) || XMLString::equals(flag,xmlconstants::XML_ONE));\r
\r
auto_ptr_char temp(source);\r
m_source=temp.get();\r
- \r
+\r
if (!m_local && !strstr(m_source.c_str(),"://")) {\r
log.warn("deprecated usage of uri/url attribute for a local resource, use path instead");\r
m_local=true;\r
}\r
\r
if (m_local) {\r
+ XMLToolingConfig::getConfig().getPathResolver()->resolve(m_source, PathResolver::XMLTOOLING_CFG_FILE);\r
+\r
flag=e->getAttributeNS(NULL,reloadChanges);\r
if (!XMLString::equals(flag,xmlconstants::XML_FALSE) && !XMLString::equals(flag,xmlconstants::XML_ZERO)) {\r
#ifdef WIN32\r
if (source && *source) {\r
auto_ptr_char temp2(source);\r
m_backing=temp2.get();\r
+ XMLToolingConfig::getConfig().getPathResolver()->resolve(m_backing, PathResolver::XMLTOOLING_RUN_FILE);\r
log.debug("backup remote resource with (%s)", m_backing.c_str());\r
}\r
source = e->getAttributeNS(NULL,reloadInterval);\r
m_log.debug("loading configuration from external resource...");\r
\r
DOMDocument* doc=NULL;\r
- auto_ptr_XMLCh widenit(backup ? m_backing.c_str() : m_source.c_str());\r
if (m_local || backup) {\r
+ auto_ptr_XMLCh widenit(backup ? m_backing.c_str() : m_source.c_str());\r
LocalFileInputSource src(widenit.get());\r
Wrapper4InputSource dsrc(&src,false);\r
if (m_validate)\r
doc=XMLToolingConfig::getConfig().getParser().parse(dsrc);\r
}\r
else {\r
- URLInputSource src(widenit.get());\r
+ URLInputSource src(m_root);\r
Wrapper4InputSource dsrc(&src,false);\r
if (m_validate)\r
doc=XMLToolingConfig::getConfig().getValidatingParser().parse(dsrc);\r
m_log.debug("backing up remote resource to (%s)", m_backing.c_str());\r
try {\r
ofstream backer(m_backing.c_str());\r
- backer << *(doc->getDocumentElement());\r
+ backer << *doc;\r
}\r
catch (exception& ex) {\r
m_log.crit("exception while backing up resource: %s", ex.what());\r
{\r
if (!m_lock)\r
return this;\r
- \r
+\r
m_lock->rdlock();\r
\r
// Check if we need to refresh.\r
#endif\r
if (m_filestamp>=stat_buf.st_mtime)\r
return this;\r
- \r
+\r
// Elevate lock and recheck.\r
m_log.debug("timestamp of local resource changed, elevating to a write lock");\r
m_lock->unlock();\r
m_filestamp = now;\r
m_log.info("reloading remote resource...");\r
}\r
- \r
+\r
// Do this once...\r
try {\r
// At this point we're holding the write lock, so make sure we pop it.\r
} catch (exception& ex) {\r
m_log.crit("maintaining existing configuration, error reloading resource (%s): %s", m_source.c_str(), ex.what());\r
}\r
- \r
+\r
// If we made it here, the swap may or may not have worked, but we need to relock.\r
m_log.debug("attempt to update resource complete, relocking");\r
m_lock->rdlock();\r
return this;\r
}\r
+\r
+void ReloadableXMLFile::unlock()
+{
+ if (m_lock)
+ m_lock->unlock();
+}
+\r
+pair<bool,DOMElement*> ReloadableXMLFile::load()
+{
+ return load(false);
+}