summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrandomdan <randomdan@localhost>2011-12-14 21:42:31 +0000
committerrandomdan <randomdan@localhost>2011-12-14 21:42:31 +0000
commit8a7980bff41ccb8dc42b18eb1edd4b3938977fc3 (patch)
tree4b0a3414ba881a3118630c41ca24129d23f996df
parentDon't write JSON numbers in scientific notation, use native C++ boolalpha for... (diff)
downloadproject2-8a7980bff41ccb8dc42b18eb1edd4b3938977fc3.tar.bz2
project2-8a7980bff41ccb8dc42b18eb1edd4b3938977fc3.tar.xz
project2-8a7980bff41ccb8dc42b18eb1edd4b3938977fc3.zip
Pluggable script engines
XML script parser moved to XML module Script parsing object multiple instantiation bug fix Scripts changed to match new standardized format and layout
-rw-r--r--project2/cgi/Jamfile.jam11
-rw-r--r--project2/cgi/cgiAppEngine.cpp8
-rw-r--r--project2/cgi/cgiAppEngine.h12
-rw-r--r--project2/cgi/cgiOutputOptions.cpp17
-rw-r--r--project2/cgi/cgiOutputOptions.h4
-rw-r--r--project2/cgi/cgiStageCustomError.cpp8
-rw-r--r--project2/cgi/cgiStageCustomNotFound.cpp8
-rw-r--r--project2/cgi/cgiStageDefaultNotFound.cpp2
-rw-r--r--project2/cgi/cgiStageFail.cpp6
-rw-r--r--project2/cgi/cgiStageInitial.cpp6
-rw-r--r--project2/cgi/cgiStagePresent.cpp10
-rw-r--r--project2/cgi/cgiStageRedirect.cpp4
-rw-r--r--project2/cgi/cgiStageRequest.cpp14
-rw-r--r--project2/common/Jamfile.jam11
-rw-r--r--project2/common/cache.cpp4
-rw-r--r--project2/common/cache.h2
-rw-r--r--project2/common/checkHost.cpp8
-rw-r--r--project2/common/checkHost.h6
-rw-r--r--project2/common/columns.cpp9
-rw-r--r--project2/common/columns.h5
-rw-r--r--project2/common/commonObjects.cpp30
-rw-r--r--project2/common/commonObjects.h8
-rw-r--r--project2/common/dataSource.cpp2
-rw-r--r--project2/common/dataSource.h2
-rw-r--r--project2/common/definedColumns.cpp10
-rw-r--r--project2/common/definedColumns.h5
-rw-r--r--project2/common/environment.cpp25
-rw-r--r--project2/common/environment.h3
-rw-r--r--project2/common/exceptions.cpp23
-rw-r--r--project2/common/exceptions.h15
-rw-r--r--project2/common/functions/dates.cpp8
-rw-r--r--project2/common/functions/strings.cpp2
-rw-r--r--project2/common/iHaveParameters.cpp8
-rw-r--r--project2/common/iHaveParameters.h3
-rw-r--r--project2/common/iHaveSubTasks.cpp2
-rw-r--r--project2/common/iHaveSubTasks.h2
-rw-r--r--project2/common/if.cpp18
-rw-r--r--project2/common/if.h5
-rw-r--r--project2/common/iterate.cpp6
-rw-r--r--project2/common/iterate.h3
-rw-r--r--project2/common/library.cpp3
-rw-r--r--project2/common/library.h2
-rw-r--r--project2/common/memoryCache.cpp2
-rw-r--r--project2/common/noOutputExecute.cpp2
-rw-r--r--project2/common/noOutputExecute.h2
-rw-r--r--project2/common/paramChecker.cpp8
-rw-r--r--project2/common/paramChecker.h3
-rw-r--r--project2/common/pch.hpp4
-rw-r--r--project2/common/presenter.h4
-rw-r--r--project2/common/rowProcessor.cpp14
-rw-r--r--project2/common/rowProcessor.h2
-rw-r--r--project2/common/rowSet.cpp2
-rw-r--r--project2/common/rowSet.h2
-rw-r--r--project2/common/rowView.cpp13
-rw-r--r--project2/common/rowView.h3
-rw-r--r--project2/common/scripts.cpp29
-rw-r--r--project2/common/scripts.h64
-rw-r--r--project2/common/sessionClearTask.cpp4
-rw-r--r--project2/common/sessionClearTask.h3
-rw-r--r--project2/common/sessionSetTask.cpp4
-rw-r--r--project2/common/sessionSetTask.h3
-rw-r--r--project2/common/singleton.cpp13
-rw-r--r--project2/common/sourceObject.cpp4
-rw-r--r--project2/common/sourceObject.h6
-rw-r--r--project2/common/structExceptHandling.cpp38
-rw-r--r--project2/common/structExceptHandling.h2
-rw-r--r--project2/common/task.cpp2
-rw-r--r--project2/common/task.h3
-rw-r--r--project2/common/taskHost.cpp20
-rw-r--r--project2/common/taskHost.h6
-rw-r--r--project2/common/transform.cpp2
-rw-r--r--project2/common/transform.h4
-rw-r--r--project2/common/validDateCheck.cpp5
-rw-r--r--project2/common/variableConvert.cpp10
-rw-r--r--project2/common/variables-modconfig.cpp4
-rw-r--r--project2/common/variables-modfixed.cpp13
-rw-r--r--project2/common/variables-modfixed.h17
-rw-r--r--project2/common/variables-modliteral.cpp78
-rw-r--r--project2/common/variables-modliteral.h40
-rw-r--r--project2/common/variables-modlocalparam.cpp4
-rw-r--r--project2/common/variables-modlookup.cpp8
-rw-r--r--project2/common/variables-modparam.cpp4
-rw-r--r--project2/common/variables-modsession.cpp4
-rw-r--r--project2/common/variables-moduri.cpp4
-rw-r--r--project2/common/variables.cpp197
-rw-r--r--project2/common/variables.h27
-rw-r--r--project2/common/view.cpp2
-rw-r--r--project2/common/view.h2
-rw-r--r--project2/common/viewHost.cpp21
-rw-r--r--project2/common/viewHost.h9
-rw-r--r--project2/common/xmlObjectLoader.cpp95
-rw-r--r--project2/common/xmlObjectLoader.h108
-rw-r--r--project2/common/xmlScriptParser.cpp47
-rw-r--r--project2/common/xmlScriptParser.h35
-rw-r--r--project2/common/xmlStorage.h37
-rw-r--r--project2/console/Jamfile.jam10
-rw-r--r--project2/console/claOptions.cpp14
-rw-r--r--project2/console/consoleAppEngine.cpp12
-rw-r--r--project2/console/consoleAppEngine.h2
-rw-r--r--project2/console/consoleEnvironment.h5
-rw-r--r--project2/console/consolePresenter.cpp3
-rw-r--r--project2/console/consolePresenter.h2
-rw-r--r--project2/console/p2consoleMain.cpp6
-rw-r--r--project2/files/Jamfile.jam9
-rw-r--r--project2/files/fileRows.cpp2
-rw-r--r--project2/files/fileRows.h2
-rw-r--r--project2/files/fsRows.cpp2
-rw-r--r--project2/files/fsRows.h3
-rw-r--r--project2/files/streamRows.cpp18
-rw-r--r--project2/files/streamRows.h2
-rw-r--r--project2/json/Jamfile.jam11
-rw-r--r--project2/json/presenter.cpp2
-rw-r--r--project2/mail/Jamfile.jam9
-rw-r--r--project2/mail/sendmailTask.cpp8
-rw-r--r--project2/mail/sendmailTask.h4
-rw-r--r--project2/processes/Jamfile.jam10
-rw-r--r--project2/processes/procRows.cpp3
-rw-r--r--project2/processes/procRows.h2
-rw-r--r--project2/regex/Jamfile.jam10
-rw-r--r--project2/regex/regexCheck.cpp2
-rw-r--r--project2/regex/regexCheck.h2
-rw-r--r--project2/regex/regexRows.cpp4
-rw-r--r--project2/regex/regexRows.h2
-rw-r--r--project2/sql/Jamfile.jam16
-rw-r--r--project2/sql/pch.hpp2
-rw-r--r--project2/sql/rdbmsDataSource.cpp22
-rw-r--r--project2/sql/rdbmsDataSource.h5
-rw-r--r--project2/sql/sqlCache.cpp2
-rw-r--r--project2/sql/sqlCheck.cpp8
-rw-r--r--project2/sql/sqlCheck.h4
-rw-r--r--project2/sql/sqlMergeTask.cpp51
-rw-r--r--project2/sql/sqlMergeTask.h5
-rw-r--r--project2/sql/sqlRows.cpp5
-rw-r--r--project2/sql/sqlRows.h3
-rw-r--r--project2/sql/sqlTask.cpp21
-rw-r--r--project2/sql/sqlTask.h3
-rw-r--r--project2/sql/sqlWriter.cpp67
-rw-r--r--project2/sql/sqlWriter.h9
-rw-r--r--project2/url/Jamfile.jam9
-rw-r--r--project2/url/curlHelper.cpp19
-rw-r--r--project2/url/curlHelper.h3
-rw-r--r--project2/url/urlRows.cpp2
-rw-r--r--project2/url/urlRows.h3
-rw-r--r--project2/xml/Jamfile.jam3
-rw-r--r--project2/xml/rawView.cpp5
-rw-r--r--project2/xml/rawView.h2
-rw-r--r--project2/xml/xmlCache.cpp2
-rw-r--r--project2/xml/xmlDocumentPrefetch.cpp8
-rw-r--r--project2/xml/xmlDocumentPrefetch.h2
-rw-r--r--project2/xml/xmlPresenter.cpp6
-rw-r--r--project2/xml/xmlPresenter.h4
-rw-r--r--project2/xml/xmlRawRows.cpp4
-rw-r--r--project2/xml/xmlRawRows.h4
-rw-r--r--project2/xml/xmlRows.cpp25
-rw-r--r--project2/xml/xmlRows.h2
-rw-r--r--project2/xml/xmlScriptParser.cpp191
-rw-r--r--project2/xml/xmlScriptParser.h48
-rw-r--r--project2/xml/xpathRows.cpp34
-rw-r--r--project2/xml/xpathRows.h8
159 files changed, 1219 insertions, 928 deletions
diff --git a/project2/cgi/Jamfile.jam b/project2/cgi/Jamfile.jam
index 48225cb..017dd11 100644
--- a/project2/cgi/Jamfile.jam
+++ b/project2/cgi/Jamfile.jam
@@ -1,6 +1,7 @@
-alias libxmlpp : : : :
- <cflags>"`pkg-config --cflags libxml++-2.6`"
- <linkflags>"`pkg-config --libs libxml++-2.6`" ;
+alias glibmm : : : :
+ <cflags>"`pkg-config --cflags glibmm-2.4`"
+ <linkflags>"`pkg-config --libs glibmm-2.4`"
+ ;
lib boost_filesystem : : <name>boost_filesystem ;
lib cgicc : : <name>cgicc ;
lib fcgi : : <name>fcgi ;
@@ -9,7 +10,7 @@ lib fcgi++ : : <name>fcgi++ ;
cpp-pch pch : pch.hpp :
<include>../../libmisc
<library>cgicc
- <library>libxmlpp
+ <library>glibmm
<library>../common//p2common
<library>boost_filesystem
<library>../xml//p2xml
@@ -20,7 +21,7 @@ lib p2web :
:
<include>../libmisc
<library>cgicc
- <library>libxmlpp
+ <library>glibmm
<library>../common//p2common
<library>boost_filesystem
<library>../xml//p2xml
diff --git a/project2/cgi/cgiAppEngine.cpp b/project2/cgi/cgiAppEngine.cpp
index 7fd7c33..4d91069 100644
--- a/project2/cgi/cgiAppEngine.cpp
+++ b/project2/cgi/cgiAppEngine.cpp
@@ -56,15 +56,15 @@ CgiApplicationEngine::process() const
currentStage = currentStage.get<0>()->run();
}
catch (const CheckHost::CheckFailure & cf) {
- currentStage = NextStage(new PresentStage(_env, _env->resolveScript(_env->presentRoot, cf.failedCheck->present())));
+ currentStage = NextStage(new PresentStage(_env, _env->resolveScript(_env->presentRoot, cf.failedCheck->present(), false)));
}
- catch (const XmlScriptParser::NotFound & nf) {
+ catch (const ScriptNotFound & nf) {
if (_env->notFoundPresent.empty() || triedNotFound) {
currentStage = NextStage(new DefaultNotFoundStage(_env, nf));
}
else {
triedNotFound = true;
- currentStage = NextStage(new CustomNotFoundStage(_env, nf));
+ currentStage = NextStage(new CustomNotFoundStage(_env, nf, _env->resolveScript(_env->errorPresentRoot, _env->notFoundPresent, false)));
}
}
catch (const std::exception & ex) {
@@ -73,7 +73,7 @@ CgiApplicationEngine::process() const
}
else {
triedNotFound = true;
- currentStage = NextStage(new CustomErrorStage(_env, ex));
+ currentStage = NextStage(new CustomErrorStage(_env, ex, _env->resolveScript(_env->errorPresentRoot, _env->onErrorPresent, false)));
}
}
} while (currentStage.get<0>());
diff --git a/project2/cgi/cgiAppEngine.h b/project2/cgi/cgiAppEngine.h
index 25d3b93..f4b3896 100644
--- a/project2/cgi/cgiAppEngine.h
+++ b/project2/cgi/cgiAppEngine.h
@@ -88,7 +88,7 @@ class CgiApplicationEngine : public ApplicationEngine, public TransformChainLink
/// Stage to process POST requests
class RequestStage : public ResponseStage, TaskHost {
public:
- RequestStage(const CgiEnvironment *, const boost::filesystem::path & path);
+ RequestStage(const CgiEnvironment *, ScriptReaderPtr);
virtual NextStage run();
virtual HttpHeaderPtr getHeader() const;
@@ -99,7 +99,7 @@ class CgiApplicationEngine : public ApplicationEngine, public TransformChainLink
/// Stage to process GET requests and follow up RequestStages
class PresentStage : public virtual ResponseStage, ViewHost {
public:
- PresentStage(const CgiEnvironment * e, const boost::filesystem::path & path);
+ PresentStage(const CgiEnvironment * e, ScriptReaderPtr);
virtual NextStage run();
virtual HttpHeaderPtr getHeader() const;
@@ -108,19 +108,19 @@ class CgiApplicationEngine : public ApplicationEngine, public TransformChainLink
/// The built-in fail-safe not found stage
class DefaultNotFoundStage : public virtual ResponseStage {
public:
- DefaultNotFoundStage(const CgiEnvironment *, const XmlScriptParser::NotFound &);
+ DefaultNotFoundStage(const CgiEnvironment *, const ScriptNotFound &);
virtual NextStage run();
virtual HttpHeaderPtr getHeader() const;
private:
- const XmlScriptParser::NotFound nf;
+ const ScriptNotFound nf;
XmlPresenterPtr pres;
};
/// Custom not found handling stage
class CustomNotFoundStage : public DefaultNotFoundStage, public PresentStage {
public:
- CustomNotFoundStage(const CgiEnvironment *, const ::XmlScriptParser::NotFound &);
+ CustomNotFoundStage(const CgiEnvironment *, const ScriptNotFound &, ScriptReaderPtr);
virtual NextStage run();
virtual HttpHeaderPtr getHeader() const;
};
@@ -142,7 +142,7 @@ class CgiApplicationEngine : public ApplicationEngine, public TransformChainLink
/// Custom unhandled error handling stage
class CustomErrorStage : public DefaultErrorStage, public PresentStage {
public:
- CustomErrorStage(const CgiEnvironment *, const std::exception &);
+ CustomErrorStage(const CgiEnvironment *, const std::exception &, ScriptReaderPtr);
virtual NextStage run();
virtual HttpHeaderPtr getHeader() const;
};
diff --git a/project2/cgi/cgiOutputOptions.cpp b/project2/cgi/cgiOutputOptions.cpp
index add1671..f9a6d86 100644
--- a/project2/cgi/cgiOutputOptions.cpp
+++ b/project2/cgi/cgiOutputOptions.cpp
@@ -1,4 +1,5 @@
#include "cgiOutputOptions.h"
+#include "scripts.h"
bool OutputOptions::core;
bool OutputOptions::session;
@@ -7,13 +8,13 @@ bool OutputOptions::environment;
bool OutputOptions::url;
bool OutputOptions::parameters;
-OutputOptions::OutputOptions(const xmlpp::Element * p) :
- Core(p, "core", false, core),
- Session(p, "session", false, session),
- Timing(p, "timing", false, timing),
- Environment(p, "environment", false, environment),
- URL(p, "url", false, url),
- Parameters(p, "parameters", false, parameters)
+OutputOptions::OutputOptions(ScriptNodePtr p) :
+ Core(p, "core", core),
+ Session(p, "session", session),
+ Timing(p, "timing", timing),
+ Environment(p, "environment", environment),
+ URL(p, "url", url),
+ Parameters(p, "parameters", parameters)
{
}
@@ -31,7 +32,7 @@ OutputOptionsLoader::OutputOptionsLoader() :
}
OutputOptionsPtr
-OutputOptionsLoader::createFrom(const xmlpp::Element * e) const {
+OutputOptionsLoader::createFrom(ScriptNodePtr e) const {
return new OutputOptions(e);
}
diff --git a/project2/cgi/cgiOutputOptions.h b/project2/cgi/cgiOutputOptions.h
index a1ff62d..07b7598 100644
--- a/project2/cgi/cgiOutputOptions.h
+++ b/project2/cgi/cgiOutputOptions.h
@@ -11,7 +11,7 @@ namespace xmlpp {
class OutputOptions : public IntrusivePtrBase {
public:
- OutputOptions(const xmlpp::Element *);
+ OutputOptions(ScriptNodePtr);
const Variable Core;
const Variable Session;
@@ -35,7 +35,7 @@ typedef boost::intrusive_ptr<OutputOptions> OutputOptionsPtr;
class OutputOptionsLoader : public ComponentLoader {
public:
OutputOptionsLoader();
- OutputOptionsPtr createFrom(const xmlpp::Element * e) const;
+ OutputOptionsPtr createFrom(ScriptNodePtr e) const;
const Options * options() const;
private:
diff --git a/project2/cgi/cgiStageCustomError.cpp b/project2/cgi/cgiStageCustomError.cpp
index 8b4b347..82fc6a1 100644
--- a/project2/cgi/cgiStageCustomError.cpp
+++ b/project2/cgi/cgiStageCustomError.cpp
@@ -4,12 +4,12 @@
#include "cgiHttpHeader.h"
#include "logger.h"
-CgiApplicationEngine::CustomErrorStage::CustomErrorStage(const CgiEnvironment * env, const std::exception & ex) :
+CgiApplicationEngine::CustomErrorStage::CustomErrorStage(const CgiEnvironment * env, const std::exception & ex, ScriptReaderPtr s) :
CgiApplicationEngine::ResponseStage(env),
- ::XmlScriptParser(e->resolveScript(env->errorPresentRoot, env->onErrorPresent), false),
- ::CheckHost(e->resolveScript(env->errorPresentRoot, env->onErrorPresent)),
+ ::CommonObjects(s),
+ ::CheckHost(s),
CgiApplicationEngine::DefaultErrorStage(env, ex),
- CgiApplicationEngine::PresentStage(env, e->resolveScript(env->errorPresentRoot, env->onErrorPresent))
+ CgiApplicationEngine::PresentStage(env, s)
{
}
diff --git a/project2/cgi/cgiStageCustomNotFound.cpp b/project2/cgi/cgiStageCustomNotFound.cpp
index fc49804..8a224fa 100644
--- a/project2/cgi/cgiStageCustomNotFound.cpp
+++ b/project2/cgi/cgiStageCustomNotFound.cpp
@@ -4,12 +4,12 @@
#include "cgiHttpHeader.h"
#include "logger.h"
-CgiApplicationEngine::CustomNotFoundStage::CustomNotFoundStage(const CgiEnvironment * env, const ::XmlScriptParser::NotFound & notfound) :
+CgiApplicationEngine::CustomNotFoundStage::CustomNotFoundStage(const CgiEnvironment * env, const ScriptNotFound & notfound, ScriptReaderPtr s) :
CgiApplicationEngine::ResponseStage(env),
- ::XmlScriptParser(e->resolveScript(env->errorPresentRoot, env->notFoundPresent), false),
- ::CheckHost(e->resolveScript(env->errorPresentRoot, env->notFoundPresent)),
+ ::CommonObjects(s),
+ ::CheckHost(s),
CgiApplicationEngine::DefaultNotFoundStage(env, notfound),
- CgiApplicationEngine::PresentStage(env, e->resolveScript(env->errorPresentRoot, env->notFoundPresent))
+ CgiApplicationEngine::PresentStage(env, s)
{
}
diff --git a/project2/cgi/cgiStageDefaultNotFound.cpp b/project2/cgi/cgiStageDefaultNotFound.cpp
index 38cc395..d05c92b 100644
--- a/project2/cgi/cgiStageDefaultNotFound.cpp
+++ b/project2/cgi/cgiStageDefaultNotFound.cpp
@@ -6,7 +6,7 @@
static const Glib::ustring DefaultNotFoundStageResp("notfound");
-CgiApplicationEngine::DefaultNotFoundStage::DefaultNotFoundStage(const CgiEnvironment * env, const XmlScriptParser::NotFound & notfound) :
+CgiApplicationEngine::DefaultNotFoundStage::DefaultNotFoundStage(const CgiEnvironment * env, const ScriptNotFound & notfound) :
CgiApplicationEngine::ResponseStage(env),
nf(notfound),
pres(new XmlPresenter(DefaultNotFoundStageResp, e->errorTransformStyle, e->errorContentType))
diff --git a/project2/cgi/cgiStageFail.cpp b/project2/cgi/cgiStageFail.cpp
index 87aba66..62de295 100644
--- a/project2/cgi/cgiStageFail.cpp
+++ b/project2/cgi/cgiStageFail.cpp
@@ -31,11 +31,11 @@ namespace CgiApplicationExtras {
class CgiFail : public View {
public:
- CgiFail(const xmlpp::Element * e) :
+ CgiFail(ScriptNodePtr e) :
SourceObject(e),
View(e),
- code(e, "code", false, 500),
- message(e, "message", false, "Application error") {
+ code(e, "code", 500),
+ message(e, "message", "Application error") {
}
void execute(const MultiRowSetPresenter *) const {
throw CgiApplicationEngine::ResponseStagePtr(
diff --git a/project2/cgi/cgiStageInitial.cpp b/project2/cgi/cgiStageInitial.cpp
index b263110..0fe81d4 100644
--- a/project2/cgi/cgiStageInitial.cpp
+++ b/project2/cgi/cgiStageInitial.cpp
@@ -17,12 +17,10 @@ CgiApplicationEngine::InitialStage::run()
if (e->elems.empty()) {
throw EmptyRequestURL();
}
- return NextStage(new RequestStage(e, e->resolveScript(e->requestRoot,
- e->getRedirectURL())));
+ return NextStage(new RequestStage(e, e->resolveScript(e->requestRoot, e->getRedirectURL(), false)));
}
else {
- return NextStage(new PresentStage(e, e->resolveScript(e->presentRoot,
- e->elems.empty() ? e->defaultPresent : e->getRedirectURL())));
+ return NextStage(new PresentStage(e, e->resolveScript(e->presentRoot, e->elems.empty() ? e->defaultPresent : e->getRedirectURL(), false)));
}
}
diff --git a/project2/cgi/cgiStagePresent.cpp b/project2/cgi/cgiStagePresent.cpp
index 54b0e02..8eb0487 100644
--- a/project2/cgi/cgiStagePresent.cpp
+++ b/project2/cgi/cgiStagePresent.cpp
@@ -5,13 +5,13 @@
#include <boost/foreach.hpp>
#include <boost/bind.hpp>
-CgiApplicationEngine::PresentStage::PresentStage(const CgiEnvironment * e, const boost::filesystem::path & path) :
+CgiApplicationEngine::PresentStage::PresentStage(const CgiEnvironment * e, ScriptReaderPtr s) :
CgiApplicationEngine::ResponseStage(e),
- XmlScriptParser(path, false),
- CheckHost(path),
- ViewHost(path)
+ CommonObjects(s),
+ CheckHost(s),
+ ViewHost(s)
{
- loader.supportedStorers.insert(Storer::into<OutputOptionsLoader>(&outputOptions));
+ s->loader.addLoadTarget(s->root(), Storer::into<OutputOptionsLoader>(&outputOptions));
}
CgiApplicationEngine::NextStage
diff --git a/project2/cgi/cgiStageRedirect.cpp b/project2/cgi/cgiStageRedirect.cpp
index f72e986..8c918f1 100644
--- a/project2/cgi/cgiStageRedirect.cpp
+++ b/project2/cgi/cgiStageRedirect.cpp
@@ -29,10 +29,10 @@ namespace CgiApplicationExtras {
class CgiRedirect : public View {
public:
- CgiRedirect(const xmlpp::Element * e) :
+ CgiRedirect(ScriptNodePtr e) :
SourceObject(e),
View(e),
- url(e, "url", true) {
+ url(e, "url") {
}
void execute(const MultiRowSetPresenter *) const {
throw CgiApplicationEngine::ResponseStagePtr(
diff --git a/project2/cgi/cgiStageRequest.cpp b/project2/cgi/cgiStageRequest.cpp
index 4831a71..99ca956 100644
--- a/project2/cgi/cgiStageRequest.cpp
+++ b/project2/cgi/cgiStageRequest.cpp
@@ -5,13 +5,13 @@
#include "xmlObjectLoader.h"
#include <boost/foreach.hpp>
-CgiApplicationEngine::RequestStage::RequestStage(const CgiEnvironment * e, const boost::filesystem::path & path) :
- XmlScriptParser(path, false),
- SourceObject(get_document()->get_root_node()),
- ::CheckHost(path),
+CgiApplicationEngine::RequestStage::RequestStage(const CgiEnvironment * e, ScriptReaderPtr s) :
+ SourceObject(s->root()),
+ CommonObjects(s),
+ ::CheckHost(s),
CgiApplicationEngine::ResponseStage(e),
- ::TaskHost(path),
- present(get_document()->get_root_node()->get_attribute_value("present"))
+ ::TaskHost(s),
+ present(s->root()->value("present","").as<std::string>())
{
}
@@ -20,7 +20,7 @@ CgiApplicationEngine::RequestStage::run()
{
runChecks();
execute();
- return NextStage(present.empty() ? NULL : new PresentStage(e, e->resolveScript(e->presentRoot, present)), this);
+ return NextStage(present.empty() ? NULL : new PresentStage(e, e->resolveScript(e->presentRoot, present, false)), this);
}
const std::string contentType = "text/plain";
diff --git a/project2/common/Jamfile.jam b/project2/common/Jamfile.jam
index 4964ea1..5c6cfc7 100644
--- a/project2/common/Jamfile.jam
+++ b/project2/common/Jamfile.jam
@@ -1,6 +1,7 @@
-alias libxmlpp : : : :
- <cflags>"`pkg-config --cflags libxml++-2.6`"
- <linkflags>"`pkg-config --libs libxml++-2.6`" ;
+alias glibmm : : : :
+ <cflags>"`pkg-config --cflags glibmm-2.4`"
+ <linkflags>"`pkg-config --libs glibmm-2.4`"
+ ;
lib dl : : <name>dl ;
lib boost_system : : <name>boost_system ;
lib boost_filesystem : : <name>boost_filesystem ;
@@ -8,7 +9,7 @@ lib boost_date_time : : <name>boost_date_time ;
cpp-pch pch : pch.hpp :
<include>../../libmisc
- <library>libxmlpp
+ <library>glibmm
;
lib p2common :
pch
@@ -18,7 +19,7 @@ lib p2common :
../../libmisc/misc.cpp
:
<include>../../libmisc
- <library>libxmlpp
+ <library>glibmm
<library>dl
<library>boost_system
<library>boost_filesystem
diff --git a/project2/common/cache.cpp b/project2/common/cache.cpp
index 7ad4053..f5edc43 100644
--- a/project2/common/cache.cpp
+++ b/project2/common/cache.cpp
@@ -5,10 +5,10 @@
#include "logger.h"
#include <boost/foreach.hpp>
-Cache::Cache(const xmlpp::Element * p) :
+Cache::Cache(ScriptNodePtr p) :
IHaveParameters(p),
SourceObject(p),
- inherit(p->get_attribute_value("inherit") != "false")
+ inherit(p->value("inherit", true).as<bool>())
{
}
diff --git a/project2/common/cache.h b/project2/common/cache.h
index eff24b0..2c438b8 100644
--- a/project2/common/cache.h
+++ b/project2/common/cache.h
@@ -12,7 +12,7 @@ typedef boost::intrusive_ptr<const RowSet> RowSetCPtr;
class Cache : public IHaveParameters, public SourceObject {
public:
- Cache(const xmlpp::Element * p);
+ Cache(ScriptNodePtr p);
bool checkAndExecute(const Glib::ustring &, const Glib::ustring &, const RowProcessor *);
virtual RowSetPresenterPtr openFor(const Glib::ustring &, const Glib::ustring &, const IHaveParameters *) = 0;
diff --git a/project2/common/checkHost.cpp b/project2/common/checkHost.cpp
index 343b255..4f2ab44 100644
--- a/project2/common/checkHost.cpp
+++ b/project2/common/checkHost.cpp
@@ -3,10 +3,10 @@
#include "appEngine.h"
#include <boost/foreach.hpp>
-CheckHost::CheckHost(const boost::filesystem::path & file) :
- XmlScriptParser(file, false)
+CheckHost::CheckHost(ScriptReaderPtr s) :
+ CommonObjects(s)
{
- loader.supportedStorers.insert(Storer::into<ElementLoader>(&parameterChecks));
+ s->loader.addLoadTarget(s->root(), Storer::into<ElementLoader>(&parameterChecks));
}
CheckHost::~CheckHost()
@@ -16,7 +16,7 @@ CheckHost::~CheckHost()
void
CheckHost::runChecks() const
{
- parseDocument();
+ loadScriptComponents();
BOOST_FOREACH(const ParamCheckers::value_type & pc, parameterChecks) {
if (!pc->performCheck()) {
ApplicationEngine::getCurrent()->logMessage(false, pc->group(), pc->message());
diff --git a/project2/common/checkHost.h b/project2/common/checkHost.h
index 54fc96d..9a87aea 100644
--- a/project2/common/checkHost.h
+++ b/project2/common/checkHost.h
@@ -1,13 +1,13 @@
#ifndef CHECKHOST_H
#define CHECKHOST_H
-#include "xmlScriptParser.h"
#include "paramChecker.h"
#include "xmlStorage.h"
#include <set>
#include <boost/function.hpp>
+#include "commonObjects.h"
-class CheckHost : public virtual XmlScriptParser {
+class CheckHost : virtual public CommonObjects {
public:
class CheckFailure : std::exception {
public:
@@ -15,7 +15,7 @@ class CheckHost : public virtual XmlScriptParser {
~CheckFailure() throw();
const ParamCheckerCPtr failedCheck;
};
- CheckHost(const boost::filesystem::path & file);
+ CheckHost(ScriptReaderPtr script);
~CheckHost();
void runChecks() const;
diff --git a/project2/common/columns.cpp b/project2/common/columns.cpp
index e64a9f8..268a59d 100644
--- a/project2/common/columns.cpp
+++ b/project2/common/columns.cpp
@@ -1,11 +1,10 @@
#include <pch.hpp>
#include "columns.h"
-#include <libxml++/nodes/textnode.h>
-Column::Column(unsigned int i, const xmlpp::Element * p) :
+Column::Column(unsigned int i, ScriptNodePtr p) :
idx(i),
- name(p->get_attribute("name") ? p->get_attribute_value("name") : p->get_child_text()->get_content()),
- defValue(p, "default", false)
+ name(p->get_name()),
+ defValue(p, "default", Null())
{
}
@@ -17,7 +16,7 @@ Column::Column(unsigned int i, const Glib::ustring & n, const Variable & v) :
}
Column *
-Column::make(unsigned int idx, const xmlpp::Element * p)
+Column::make(unsigned int idx, ScriptNodePtr p)
{
return new Column(idx, p);
}
diff --git a/project2/common/columns.h b/project2/common/columns.h
index 8b9b9b3..d0b62d9 100644
--- a/project2/common/columns.h
+++ b/project2/common/columns.h
@@ -1,7 +1,6 @@
#ifndef COLUMNS_H
#define COLUMNS_H
-#include <libxml++/nodes/element.h>
#include "variables.h"
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
@@ -9,10 +8,10 @@
class Column : public IntrusivePtrBase {
public:
- Column(unsigned int idx, const xmlpp::Element * p);
+ Column(unsigned int idx, ScriptNodePtr p);
Column(unsigned int i, const Glib::ustring & n, const Variable & v = Variable(Null()));
- static Column * make(unsigned int idx, const xmlpp::Element * p);
+ static Column * make(unsigned int idx, ScriptNodePtr p);
const unsigned int idx;
const Glib::ustring name;
diff --git a/project2/common/commonObjects.cpp b/project2/common/commonObjects.cpp
index 4ce8c82..5bfe6bc 100644
--- a/project2/common/commonObjects.cpp
+++ b/project2/common/commonObjects.cpp
@@ -3,7 +3,16 @@
#include "safeMapFind.h"
#include "appEngine.h"
#include "xmlObjectLoader.h"
-#include "xmlScriptParser.h"
+
+CommonObjects::CommonObjects()
+{
+}
+
+CommonObjects::CommonObjects(ScriptReaderPtr s) :
+ script(s)
+{
+ s->loader.addLoadTarget(s->root(), Storer::into<ElementLoader>(&rowSets));
+}
CommonObjects::~CommonObjects()
{
@@ -18,13 +27,18 @@ CommonObjects::getSource(const std::string & name) const
CommonObjects::DataSources::const_iterator
CommonObjects::loadDataSource(const std::string & name) const
{
- XmlScriptParser xml(Environment::getCurrent()->resolveScript(
- Environment::getCurrent()->datasourceRoot, name), true);
-
- LoaderBase loader(true);
- loader.supportedStorers.insert(Storer::into<ElementLoader>(&datasources));
- loader.collectAll(xml.get_document()->get_root_node(), false);
-
+ ScriptReaderPtr dbs = Environment::getCurrent()->resolveScript(Environment::getCurrent()->datasourceRoot, name, true);
+ dbs->loader.addLoadTarget(dbs->root(), Storer::into<ElementLoader>(&datasources));
+ dbs->loader.collectAll(NULL, false, dbs->root());
return safeMapFind<DataSourceNotFound>(datasources, name);
}
+void
+CommonObjects::loadScriptComponents() const
+{
+ if (script) {
+ script->loader.collectAll(this, true, script->root());
+ script.reset();
+ }
+}
+
diff --git a/project2/common/commonObjects.h b/project2/common/commonObjects.h
index fe6bd5c..2e00442 100644
--- a/project2/common/commonObjects.h
+++ b/project2/common/commonObjects.h
@@ -13,7 +13,9 @@ class CommonObjects : public virtual IntrusivePtrBase {
SimpleMessageException(DataSourceNotFound);
SimpleMessageException(DataSourceNotCompatible);
- virtual ~CommonObjects();
+ CommonObjects();
+ CommonObjects(ScriptReaderPtr script);
+ ~CommonObjects();
RowSetPtr getSource(const std::string &) const;
template <class DataSourceType>
@@ -29,9 +31,13 @@ class CommonObjects : public virtual IntrusivePtrBase {
}
return s;
}
+ void loadScriptComponents() const;
+
protected:
RowSets rowSets;
mutable DataSources datasources;
+ mutable ScriptReaderPtr script;
+
private:
DataSources::const_iterator loadDataSource(const std::string & name) const;
};
diff --git a/project2/common/dataSource.cpp b/project2/common/dataSource.cpp
index 3fedbd8..cd03300 100644
--- a/project2/common/dataSource.cpp
+++ b/project2/common/dataSource.cpp
@@ -1,7 +1,7 @@
#include <pch.hpp>
#include "dataSource.h"
-DataSource::DataSource(const xmlpp::Element * p) :
+DataSource::DataSource(ScriptNodePtr p) :
SourceObject(p)
{
}
diff --git a/project2/common/dataSource.h b/project2/common/dataSource.h
index d8a5a9a..1f557dd 100644
--- a/project2/common/dataSource.h
+++ b/project2/common/dataSource.h
@@ -10,7 +10,7 @@ typedef boost::intrusive_ptr<DataSource> DataSourcePtr;
/// Base class for data sources providing transaction support
class DataSource : public SourceObject {
public:
- DataSource(const xmlpp::Element * p);
+ DataSource(ScriptNodePtr p);
virtual ~DataSource();
virtual void commit() { };
diff --git a/project2/common/definedColumns.cpp b/project2/common/definedColumns.cpp
index 2db8f24..cc88939 100644
--- a/project2/common/definedColumns.cpp
+++ b/project2/common/definedColumns.cpp
@@ -1,16 +1,12 @@
#include <pch.hpp>
#include "definedColumns.h"
#include <boost/function.hpp>
-#include <libxml++/nodes/textnode.h>
-DefinedColumns::DefinedColumns(const xmlpp::Element * p, const Glib::ustring & colPath, const ColCreator & func)
+DefinedColumns::DefinedColumns(ScriptNodePtr p, const Glib::ustring & colPath, const ColCreator & func)
{
unsigned int colNo = 0;
- BOOST_FOREACH(const xmlpp::Node * node, p->find(colPath)) {
- const xmlpp::Element * elem = dynamic_cast<const xmlpp::Element *>(node);
- if (elem) {
- columns.insert(func(colNo++, elem));
- }
+ BOOST_FOREACH(ScriptNodePtr node, p->childrenIn(colPath)) {
+ columns.insert(func(colNo++, node));
}
}
diff --git a/project2/common/definedColumns.h b/project2/common/definedColumns.h
index 2fc6bbd..89d42be 100644
--- a/project2/common/definedColumns.h
+++ b/project2/common/definedColumns.h
@@ -1,7 +1,6 @@
#ifndef DEFINEDCOLUMNS_H
#define DEFINEDCOLUMNS_H
-#include <libxml++/nodes/element.h>
#include <boost/foreach.hpp>
#include "variables.h"
#include "rowSet.h"
@@ -9,8 +8,8 @@
class DefinedColumns {
public:
- typedef boost::function2<Column *, unsigned int, const xmlpp::Element *> ColCreator;
- DefinedColumns(const xmlpp::Element * p, const Glib::ustring & colPath, const ColCreator & func);
+ typedef boost::function2<Column *, unsigned int, ScriptNodePtr> ColCreator;
+ DefinedColumns(ScriptNodePtr p, const Glib::ustring & colPath, const ColCreator & func);
Columns columns;
};
diff --git a/project2/common/environment.cpp b/project2/common/environment.cpp
index 18d60a0..e99be54 100644
--- a/project2/common/environment.cpp
+++ b/project2/common/environment.cpp
@@ -90,20 +90,21 @@ Environment::getCurrent()
return currentEnv;
}
-boost::filesystem::path
-Environment::resolveScript(const std::string & group, const std::string & name) const
+ScriptReaderPtr
+Environment::resolveScript(const std::string & group, const std::string & name, bool ii) const
{
- boost::filesystem::path script(boost::filesystem::current_path() / group);
- BOOST_FOREACH(const boost::filesystem::path & e, boost::filesystem::path(name)) {
- if (boost::filesystem::is_directory(script / e)) {
- script /= e;
- }
- else {
- if (boost::filesystem::is_regular_file((script / e).replace_extension(".xml"))) {
- return ((script / e).replace_extension(".xml"));
- }
+ typedef std::map<std::string, boost::shared_ptr<ScriptReaderLoader> > ReaderLoaders;
+ BOOST_FOREACH(const ReaderLoaders::value_type & rl, *LoaderBase::objLoaders<ScriptReaderLoader>()) {
+ ScriptReaderPtr rs = rl.second->resolveScript(group, name);
+ if (rs) {
+ return rs;
}
}
- return script;
+ if (ii) {
+ throw DependencyNotFound(group, name);
+ }
+ else {
+ throw ScriptNotFound(group, name);
+ }
}
diff --git a/project2/common/environment.h b/project2/common/environment.h
index 6185178..c2b9474 100644
--- a/project2/common/environment.h
+++ b/project2/common/environment.h
@@ -7,6 +7,7 @@
#include <boost/filesystem/path.hpp>
#include "options.h"
#include "exceptions.h"
+#include "scripts.h"
SimpleMessageException(NoSuchPlatform);
@@ -26,7 +27,7 @@ class Environment {
virtual std::string getScriptName() const = 0;
virtual const Glib::ustring & platform() const = 0;
- boost::filesystem::path resolveScript(const std::string & group, const std::string & name) const;
+ ScriptReaderPtr resolveScript(const std::string & group, const std::string & name, bool ii) const;
private:
Options commonOptions;
diff --git a/project2/common/exceptions.cpp b/project2/common/exceptions.cpp
index d347f5f..2fa5509 100644
--- a/project2/common/exceptions.cpp
+++ b/project2/common/exceptions.cpp
@@ -25,3 +25,26 @@ numeric_error::what() const throw()
return buf;
}
+two_part_error::two_part_error(const std::string & w1, const std::string & w2) :
+ what1(w1),
+ what2(w2),
+ buf(NULL)
+{
+}
+
+two_part_error::~two_part_error() throw()
+{
+ free(buf);
+}
+
+const char *
+two_part_error::what() const throw()
+{
+ if (!buf) {
+ if (asprintf(&buf, "%s, %s", what1.c_str(), what2.c_str()) < 1) {
+ throw std::bad_alloc();
+ }
+ }
+ return buf;
+}
+
diff --git a/project2/common/exceptions.h b/project2/common/exceptions.h
index a9d4952..a45e53d 100644
--- a/project2/common/exceptions.h
+++ b/project2/common/exceptions.h
@@ -12,6 +12,16 @@ class numeric_error : public std::exception {
int err;
mutable char * buf;
};
+class two_part_error : public std::exception {
+ public:
+ two_part_error(const std::string & what1, const std::string & what2);
+ ~two_part_error() throw();
+ const char * what() const throw();
+ private:
+ const std::string what1;
+ const std::string what2;
+ mutable char * buf;
+};
#define StaticMessageException(Name, Text) \
class Name : public std::runtime_error { \
public: \
@@ -22,6 +32,11 @@ class Name : public std::runtime_error { \
public: \
Name(const std::string & what) : std::runtime_error(what) { } \
}
+#define SimpleMessage2Exception(Name) \
+class Name : public two_part_error { \
+ public: \
+ Name(const std::string & what1, const std::string & what2) : two_part_error(what1, what2) { } \
+}
#define SimpleMessageExceptionBase(Name, Base) \
class Name : public Base { \
public: \
diff --git a/project2/common/functions/dates.cpp b/project2/common/functions/dates.cpp
index da169cf..8028789 100644
--- a/project2/common/functions/dates.cpp
+++ b/project2/common/functions/dates.cpp
@@ -11,7 +11,7 @@ class ParseError { };
/// Variable implementation to access platform configuration values
class ParseDate : public VariableImplDyn {
public:
- ParseDate(const xmlpp::Element * e) :
+ ParseDate(ScriptNodePtr e) :
VariableImplDyn(e),
string(e, "string"),
format(e, "format")
@@ -41,7 +41,7 @@ DECLARE_COMPONENT_LOADER("parsedate", ParseDate, VariableLoader);
class FormatDate : public VariableImplDyn {
public:
- FormatDate(const xmlpp::Element * e) :
+ FormatDate(ScriptNodePtr e) :
VariableImplDyn(e),
date(e, "date"),
format(e, "format")
@@ -64,7 +64,7 @@ DECLARE_COMPONENT_LOADER("formatdate", FormatDate, VariableLoader);
class AdjustDate : public VariableImplDyn {
public:
- AdjustDate(const xmlpp::Element * e) :
+ AdjustDate(ScriptNodePtr e) :
VariableImplDyn(e),
date(e, "date"),
offset(e, "offset")
@@ -82,7 +82,7 @@ DECLARE_COMPONENT_LOADER("adjustdate", AdjustDate, VariableLoader);
class CurrentDate : public VariableImplDyn {
public:
- CurrentDate(const xmlpp::Element * e) :
+ CurrentDate(ScriptNodePtr e) :
VariableImplDyn(e)
{
}
diff --git a/project2/common/functions/strings.cpp b/project2/common/functions/strings.cpp
index 1272c6c..d2967d2 100644
--- a/project2/common/functions/strings.cpp
+++ b/project2/common/functions/strings.cpp
@@ -6,7 +6,7 @@
/// Variable implementation to access platform configuration values
class Trim : public VariableImplDyn {
public:
- Trim(const xmlpp::Element * e) :
+ Trim(ScriptNodePtr e) :
VariableImplDyn(e),
string(e, "string")
{
diff --git a/project2/common/iHaveParameters.cpp b/project2/common/iHaveParameters.cpp
index cded7e1..5272e5f 100644
--- a/project2/common/iHaveParameters.cpp
+++ b/project2/common/iHaveParameters.cpp
@@ -7,12 +7,10 @@
IHaveParameters::Stack IHaveParameters::scope;
-IHaveParameters::IHaveParameters(const xmlpp::Element * p)
+IHaveParameters::IHaveParameters(ScriptNodePtr p)
{
- BOOST_FOREACH(xmlpp::Node * node, p->find("parameters/*")) {
- if (const xmlpp::Element * pelem = dynamic_cast<const xmlpp::Element *>(node)) {
- parameters.insert(Parameters::value_type(pelem->get_name(), Variable(pelem, boost::optional<Glib::ustring>())));
- }
+ BOOST_FOREACH(ScriptNodePtr node, p->childrenIn("parameters")) {
+ parameters.insert(Parameters::value_type(node->get_name(), Variable(node)));
}
}
diff --git a/project2/common/iHaveParameters.h b/project2/common/iHaveParameters.h
index 08c8d00..2b7ed2a 100644
--- a/project2/common/iHaveParameters.h
+++ b/project2/common/iHaveParameters.h
@@ -1,7 +1,6 @@
#ifndef IHAVEPARAMETERS
#define IHAVEPARAMETERS
-#include <libxml++/nodes/element.h>
#include <boost/intrusive_ptr.hpp>
#include <vector>
#include "variables.h"
@@ -12,7 +11,7 @@ class IHaveParameters {
public:
typedef std::map<Glib::ustring, Variable> Parameters;
- IHaveParameters(const xmlpp::Element * p);
+ IHaveParameters(ScriptNodePtr p);
virtual ~IHaveParameters() = 0;
const Parameters & allParameters() const;
diff --git a/project2/common/iHaveSubTasks.cpp b/project2/common/iHaveSubTasks.cpp
index 586dff8..78868aa 100644
--- a/project2/common/iHaveSubTasks.cpp
+++ b/project2/common/iHaveSubTasks.cpp
@@ -2,7 +2,7 @@
#include "iHaveSubTasks.h"
#include <boost/foreach.hpp>
-IHaveSubTasks::IHaveSubTasks(const xmlpp::Element * e) :
+IHaveSubTasks::IHaveSubTasks(ScriptNodePtr e) :
SourceObject(e),
NoOutputExecute(e)
{
diff --git a/project2/common/iHaveSubTasks.h b/project2/common/iHaveSubTasks.h
index c2d2022..e52a9be 100644
--- a/project2/common/iHaveSubTasks.h
+++ b/project2/common/iHaveSubTasks.h
@@ -8,7 +8,7 @@ class IHaveSubTasks : public NoOutputExecute {
public:
typedef ANONORDEREDSTORAGEOF(NoOutputExecute) Tasks;
- IHaveSubTasks(const xmlpp::Element * p);
+ IHaveSubTasks(ScriptNodePtr p);
IHaveSubTasks(const std::string & n);
virtual ~IHaveSubTasks();
diff --git a/project2/common/if.cpp b/project2/common/if.cpp
index a810146..0f982ec 100644
--- a/project2/common/if.cpp
+++ b/project2/common/if.cpp
@@ -10,12 +10,10 @@ DECLARE_LOADER("if", If);
SimpleMessageException(IfModeIsNonsense);
-IfSet::IfSet(const xmlpp::Element * e) :
- mode(e->get_attribute_value("mode") == "or" ? Or : And)
+IfSet::IfSet(ScriptNodePtr e) :
+ mode(e->value("mode", "and").as<Glib::ustring>() == "or" ? Or : And)
{
- LoaderBase loader(true);
- loader.supportedStorers.insert(Storer::into<ElementLoader>(&checks));
- loader.collectAll(e, true, IgnoreUnsupported);
+ e->script->loader.addLoadTarget(e, Storer::into<ElementLoader>(&checks));
}
template <class Range, class Pred>
@@ -41,23 +39,21 @@ IfSet::passes() const
throw IfModeIsNonsense(getName());
}
-If::If(const xmlpp::Element * e) :
+If::If(ScriptNodePtr e) :
SourceObject(e),
IHaveSubTasks(e),
View(e),
IfSet(e)
{
- LoaderBase loader(true);
- loader.supportedStorers.insert(Storer::into<ElementLoader>(&normal));
- loader.supportedStorers.insert(Storer::into<ElementLoader>(&subViews));
- loader.collectAll(e, true, IgnoreUnsupported);
+ e->script->loader.addLoadTarget(e, Storer::into<ElementLoader>(&normal));
+ e->script->loader.addLoadTarget(e, Storer::into<ElementLoader>(&subViews));
}
void
If::execute(const MultiRowSetPresenter * presenter) const
{
if (passes()) {
- Logger()->messagef(LOG_DEBUG, "IfSet passed, showing %zu views", subViews.size());
+ Logger()->messagef(LOG_DEBUG, "IfSet passed %zu checks, showing %zu views", checks.size(), subViews.size());
BOOST_FOREACH(const SubViews::value_type & sq, subViews) {
sq->execute(presenter);
}
diff --git a/project2/common/if.h b/project2/common/if.h
index 28299ba..e27003d 100644
--- a/project2/common/if.h
+++ b/project2/common/if.h
@@ -7,7 +7,7 @@
class IfSet : public virtual IntrusivePtrBase {
public:
- IfSet(const xmlpp::Element *);
+ IfSet(ScriptNodePtr);
bool passes() const;
private:
@@ -15,13 +15,14 @@ class IfSet : public virtual IntrusivePtrBase {
enum Mode { And, Or };
Mode mode;
typedef ANONORDEREDSTORAGEOF(ParamChecker) ParamCheckers;
+ protected:
ParamCheckers checks;
};
/// Project2 component to conditionally execute its children
class If : public IHaveSubTasks, public View, public IfSet {
public:
- If(const xmlpp::Element *);
+ If(ScriptNodePtr);
virtual void execute(const MultiRowSetPresenter*) const;
virtual void execute() const;
diff --git a/project2/common/iterate.cpp b/project2/common/iterate.cpp
index ba8a4b9..9c7592e 100644
--- a/project2/common/iterate.cpp
+++ b/project2/common/iterate.cpp
@@ -8,14 +8,12 @@
DECLARE_LOADER("iterate", Iterate);
-Iterate::Iterate(const xmlpp::Element * p) :
+Iterate::Iterate(ScriptNodePtr p) :
SourceObject(p),
IHaveSubTasks(p),
RowProcessor(p)
{
- LoaderBase loader(true);
- loader.supportedStorers.insert(Storer::into<ElementLoader>(&normal));
- loader.collectAll(p, true, IgnoreUnsupported);
+ p->script->loader.addLoadTarget(p, Storer::into<ElementLoader>(&normal));
}
Iterate::~Iterate()
diff --git a/project2/common/iterate.h b/project2/common/iterate.h
index 50fd879..aa0b0e8 100644
--- a/project2/common/iterate.h
+++ b/project2/common/iterate.h
@@ -1,7 +1,6 @@
#ifndef ITERATE_H
#define ITERATE_H
-#include <libxml++/nodes/element.h>
#include "rowProcessor.h"
#include "iHaveSubTasks.h"
#include "xmlStorage.h"
@@ -12,7 +11,7 @@ typedef boost::intrusive_ptr<Iterate> IteratePtr;
/// Project2 component to iterate over a row set, executing its children for each record
class Iterate : public IHaveSubTasks, public RowProcessor {
public:
- Iterate(const xmlpp::Element * p);
+ Iterate(ScriptNodePtr p);
virtual ~Iterate();
void loadComplete(const CommonObjects *);
diff --git a/project2/common/library.cpp b/project2/common/library.cpp
index 711e14f..0c4fa7b 100644
--- a/project2/common/library.cpp
+++ b/project2/common/library.cpp
@@ -2,12 +2,13 @@
#include <dlfcn.h>
#include "xmlStorage.h"
#include "exceptions.h"
+#include "scripts.h"
#include "library.h"
SimpleMessageException(LoadLibraryFailed);
SimpleMessageException(UnloadLibraryFailed);
-Library::Library(const xmlpp::Element * p) :
+Library::Library(ScriptNodePtr p) :
SourceObject(p),
handle(dlopen(Variable(p, "path")(), RTLD_NOW))
{
diff --git a/project2/common/library.h b/project2/common/library.h
index 523dcf4..892c075 100644
--- a/project2/common/library.h
+++ b/project2/common/library.h
@@ -5,7 +5,7 @@
class Library : public SourceObject {
public:
- Library(const xmlpp::Element * p);
+ Library(ScriptNodePtr p);
~Library();
private:
diff --git a/project2/common/memoryCache.cpp b/project2/common/memoryCache.cpp
index 5942cb8..ea7fb84 100644
--- a/project2/common/memoryCache.cpp
+++ b/project2/common/memoryCache.cpp
@@ -94,7 +94,7 @@ class MemoryCache : public Cache {
boost::multi_index::tag<IndexByTime>, BOOST_MULTI_INDEX_MEMBER(CachedRowSet, const time_t, createdAt)>
> > CacheStore;
- MemoryCache(const xmlpp::Element * p) :
+ MemoryCache(ScriptNodePtr p) :
Cache(p)
{
}
diff --git a/project2/common/noOutputExecute.cpp b/project2/common/noOutputExecute.cpp
index 5b1cb36..02c8f71 100644
--- a/project2/common/noOutputExecute.cpp
+++ b/project2/common/noOutputExecute.cpp
@@ -2,7 +2,7 @@
#include "noOutputExecute.h"
#include <boost/foreach.hpp>
-NoOutputExecute::NoOutputExecute(const xmlpp::Element * p) :
+NoOutputExecute::NoOutputExecute(ScriptNodePtr p) :
SourceObject(p)
{
}
diff --git a/project2/common/noOutputExecute.h b/project2/common/noOutputExecute.h
index 1047f38..fffea9c 100644
--- a/project2/common/noOutputExecute.h
+++ b/project2/common/noOutputExecute.h
@@ -10,7 +10,7 @@ typedef boost::intrusive_ptr<NoOutputExecute> NoOutputExecutePtr;
/// Base class for Project2 compoments that perform actions, but product no output
class NoOutputExecute : public virtual SourceObject {
public:
- NoOutputExecute(const xmlpp::Element * p);
+ NoOutputExecute(ScriptNodePtr p);
NoOutputExecute(const std::string & n);
virtual ~NoOutputExecute();
diff --git a/project2/common/paramChecker.cpp b/project2/common/paramChecker.cpp
index ad61b3a..fe49fa3 100644
--- a/project2/common/paramChecker.cpp
+++ b/project2/common/paramChecker.cpp
@@ -2,11 +2,11 @@
#include "paramChecker.h"
#include "xmlObjectLoader.h"
-ParamChecker::ParamChecker(const xmlpp::Element * p) :
+ParamChecker::ParamChecker(ScriptNodePtr p) :
SourceObject(p),
- message(p, "message", false, "Check failed"),
- group(p, "group", false, "default"),
- present(p, "present", false, "")
+ message(p, "message", "Check failed"),
+ group(p, "group", "default"),
+ present(p, "present", "")
{
}
diff --git a/project2/common/paramChecker.h b/project2/common/paramChecker.h
index b0940c9..db3d8de 100644
--- a/project2/common/paramChecker.h
+++ b/project2/common/paramChecker.h
@@ -1,14 +1,13 @@
#ifndef PARAMCHECKER_H
#define PARAMCHECKER_H
-#include <libxml/tree.h>
#include "sourceObject.h"
#include "variables.h"
/// Base class for Project2 compoments that perform tests/checks
class ParamChecker : public SourceObject {
public:
- ParamChecker(const xmlpp::Element * p);
+ ParamChecker(ScriptNodePtr p);
virtual ~ParamChecker();
virtual bool performCheck() const = 0;
diff --git a/project2/common/pch.hpp b/project2/common/pch.hpp
index 536dc5a..54637e0 100644
--- a/project2/common/pch.hpp
+++ b/project2/common/pch.hpp
@@ -14,9 +14,6 @@
#include <glibmm/ustring.h>
#include <intrusivePtrBase.h>
#include <iostream>
-#include <libxml++/attribute.h>
-#include <libxml++/nodes/element.h>
-#include <libxml++/nodes/textnode.h>
#include <list>
#include <map>
#include <set>
@@ -29,6 +26,7 @@
#include "xmlObjectLoader.h"
#include "variables.h"
#include "sourceObject.h"
+#include "scripts.h"
#endif
#endif
diff --git a/project2/common/presenter.h b/project2/common/presenter.h
index 6a72495..c0cc700 100644
--- a/project2/common/presenter.h
+++ b/project2/common/presenter.h
@@ -77,14 +77,14 @@ typedef boost::intrusive_ptr<NameValuePairPresenter> NameValuePairPresenterPtr;
/// Base class to implement presenter modules
class PresenterLoader : public ComponentLoader {
public:
- virtual MultiRowSetPresenterPtr createFrom(const xmlpp::Element * e) const = 0;
+ virtual MultiRowSetPresenterPtr createFrom(ScriptNodePtr e) const = 0;
};
/// Helper implemention for specific presenters
template <class PresenterType>
class PresenterLoaderImpl : public PresenterLoader {
public:
- virtual MultiRowSetPresenterPtr createFrom(const xmlpp::Element * e) const
+ virtual MultiRowSetPresenterPtr createFrom(ScriptNodePtr e) const
{
return new PresenterType(e);
}
diff --git a/project2/common/rowProcessor.cpp b/project2/common/rowProcessor.cpp
index e186c43..e2ce6ba 100644
--- a/project2/common/rowProcessor.cpp
+++ b/project2/common/rowProcessor.cpp
@@ -5,16 +5,14 @@
#include "scopeObject.h"
#include <boost/foreach.hpp>
-RowProcessor::RowProcessor(const xmlpp::Element * p) :
+RowProcessor::RowProcessor(ScriptNodePtr p) :
IHaveParameters(p),
- recordSource(p->get_attribute_value("source")),
- filter(p->get_attribute_value("filter")),
- CROE(Variable(p, "cacheRowsOnError", false, false)()),
- IRSE(Variable(p, "ignoreRowSourceError", false, false)())
+ recordSource(p->value("source").as<std::string>()),
+ filter(p->value("filter", "").as<Glib::ustring>()),
+ CROE(p->value("cacheRowsOnError", false)),
+ IRSE(p->value("ignoreRowSourceError", false))
{
- LoaderBase loader(true);
- loader.supportedStorers.insert(Storer::into<ElementLoader>(&caches));
- loader.collectAll(p, true, IgnoreUnsupported);
+ p->script->loader.addLoadTarget(p, Storer::into<ElementLoader>(&caches));
}
void
diff --git a/project2/common/rowProcessor.h b/project2/common/rowProcessor.h
index e435bf4..18beac7 100644
--- a/project2/common/rowProcessor.h
+++ b/project2/common/rowProcessor.h
@@ -13,7 +13,7 @@ class Presenter;
/// Base class for Project2 components that work with row sets
class RowProcessor : public IHaveParameters {
public:
- RowProcessor(const xmlpp::Element *);
+ RowProcessor(ScriptNodePtr);
void loadComplete(const CommonObjects *);
const std::string recordSource;
diff --git a/project2/common/rowSet.cpp b/project2/common/rowSet.cpp
index 77d2a2d..cc397d1 100644
--- a/project2/common/rowSet.cpp
+++ b/project2/common/rowSet.cpp
@@ -10,7 +10,7 @@
RowState::RowValuesStack RowState::stack;
-RowSet::RowSet(const xmlpp::Element * p) :
+RowSet::RowSet(ScriptNodePtr p) :
SourceObject(p)
{
}
diff --git a/project2/common/rowSet.h b/project2/common/rowSet.h
index a181059..2845983 100644
--- a/project2/common/rowSet.h
+++ b/project2/common/rowSet.h
@@ -23,7 +23,7 @@ class RowSet : public SourceObject {
SimpleMessageException(FieldDoesNotExist);
SimpleNumericException(FieldOutOfRange);
- RowSet(const xmlpp::Element *);
+ RowSet(ScriptNodePtr);
virtual ~RowSet() = 0;
virtual void execute(const Glib::ustring &, const RowProcessor *) const = 0;
diff --git a/project2/common/rowView.cpp b/project2/common/rowView.cpp
index 5e01061..35b410d 100644
--- a/project2/common/rowView.cpp
+++ b/project2/common/rowView.cpp
@@ -6,25 +6,20 @@
#include "scopeObject.h"
#include <boost/foreach.hpp>
#include <boost/bind.hpp>
-#include <libxml++/nodes/textnode.h>
DECLARE_LOADER("view", RowView);
-RowView::RowView(const xmlpp::Element * p) :
+RowView::RowView(ScriptNodePtr p) :
SourceObject(p),
View(p),
RowProcessor(p),
rootName(p, "rootname"),
recordName(p, "recordname")
{
- BOOST_FOREACH(xmlpp::Node * node, p->find("columns/*")) {
- if (const xmlpp::Element * elem = dynamic_cast<const xmlpp::Element *>(node)) {
- viewColumns.insert(Columns::value_type(elem->get_name(), Variable(elem, boost::optional<Glib::ustring>())));
- }
+ BOOST_FOREACH(ScriptNodePtr node, p->childrenIn("columns")) {
+ viewColumns.insert(Columns::value_type(node->get_name(), Variable(node)));
}
- LoaderBase loader(true);
- loader.supportedStorers.insert(Storer::into<ElementLoader>(&subViews));
- loader.collectAll(p, true, IgnoreUnsupported);
+ p->script->loader.addLoadTarget(p, Storer::into<ElementLoader>(&subViews));
}
RowView::~RowView()
diff --git a/project2/common/rowView.h b/project2/common/rowView.h
index 558284c..4b90884 100644
--- a/project2/common/rowView.h
+++ b/project2/common/rowView.h
@@ -1,7 +1,6 @@
#ifndef ROWVIEW_H
#define ROWVIEW_H
-#include <libxml++/nodes/element.h>
#include <boost/intrusive_ptr.hpp>
#include "rowProcessor.h"
#include "view.h"
@@ -9,7 +8,7 @@
/// Project2 component to create output based on a records in a row set
class RowView : public View, public RowProcessor {
public:
- RowView(const xmlpp::Element *);
+ RowView(ScriptNodePtr);
virtual ~RowView();
void loadComplete(const CommonObjects *);
diff --git a/project2/common/scripts.cpp b/project2/common/scripts.cpp
new file mode 100644
index 0000000..4d15cfe
--- /dev/null
+++ b/project2/common/scripts.cpp
@@ -0,0 +1,29 @@
+#include "scripts.h"
+#include "variables-modfixed.h"
+
+ScriptNode::ScriptNode(ScriptReaderPtr s) :
+ script(s)
+{
+}
+
+VariableImpl *
+ScriptNode::variable(const Glib::ustring & n, const VariableType & def) const
+{
+ try {
+ return variable(n);
+ }
+ catch (const ValueNotFound &) {
+ return new VariableFixed(def);
+ }
+}
+
+VariableType
+ScriptNode::value(const Glib::ustring & n, const VariableType & def) const
+{
+ try {
+ return value(n);
+ }
+ catch (const ValueNotFound &) {
+ return def;
+ }
+}
diff --git a/project2/common/scripts.h b/project2/common/scripts.h
new file mode 100644
index 0000000..2db4bad
--- /dev/null
+++ b/project2/common/scripts.h
@@ -0,0 +1,64 @@
+#ifndef SCRIPTS_H
+#define SCRIPTS_H
+
+#include "intrusivePtrBase.h"
+#include <boost/intrusive_ptr.hpp>
+#include <boost/function.hpp>
+#include <boost/optional.hpp>
+#include "xmlObjectLoader.h"
+#include "exceptions.h"
+#include "variables.h"
+#include <vector>
+
+SimpleMessageException(ValueNotFound);
+SimpleMessage2Exception(ScriptNotFound);
+SimpleMessage2Exception(DependencyNotFound);
+
+class ScriptNode;
+class ScriptReader;
+typedef boost::intrusive_ptr<const ScriptNode> ScriptNodePtr;
+typedef boost::intrusive_ptr<ScriptReader> ScriptReaderPtr;
+
+class ScriptNode : public IntrusivePtrBase {
+ public:
+ ScriptNode(ScriptReaderPtr);
+
+ typedef std::vector<ScriptNodePtr> ScriptNodes;
+ typedef boost::function1<void, const VariableType &> LiteralCallback;
+ typedef boost::function1<void, ScriptNodePtr> NodeCallback;
+
+ virtual bool componentNamespace() const = 0;
+ virtual std::string get_name() const = 0;
+
+ // Child called name
+ virtual ScriptNodePtr child(const Glib::ustring & name) const = 0;
+ // All children
+ virtual ScriptNodes children() const = 0;
+ // All children in sub
+ virtual ScriptNodes childrenIn(const Glib::ustring & sub) const = 0;
+
+ virtual bool valueExists(const Glib::ustring & name) const = 0;
+ virtual VariableImpl * variable(const boost::optional<Glib::ustring> & defaultSource = boost::optional<Glib::ustring>()) const = 0;
+ virtual VariableImpl * variable(const Glib::ustring & name) const = 0;
+ VariableImpl * variable(const Glib::ustring & name, const VariableType & def) const;
+ virtual VariableType value(const Glib::ustring & name) const = 0;
+ VariableType value(const Glib::ustring & name, const VariableType & def) const;
+ virtual void composeWithCallbacks(const LiteralCallback &, const NodeCallback &) const = 0;
+
+ const ScriptReaderPtr script;
+};
+
+class ScriptReader : public virtual IntrusivePtrBase {
+ public:
+ virtual ScriptNodePtr root() = 0;
+ LoaderBase loader;
+};
+
+/// Base class to implement script reader modules
+class ScriptReaderLoader : public ComponentLoader {
+ public:
+ virtual ScriptReaderPtr resolveScript(const std::string & group, const std::string & name) const = 0;
+};
+
+#endif
+
diff --git a/project2/common/sessionClearTask.cpp b/project2/common/sessionClearTask.cpp
index 17dcf8f..9fba697 100644
--- a/project2/common/sessionClearTask.cpp
+++ b/project2/common/sessionClearTask.cpp
@@ -7,10 +7,10 @@
DECLARE_LOADER("sessionclear", SessionClearTask);
-SessionClearTask::SessionClearTask(const xmlpp::Element * p) :
+SessionClearTask::SessionClearTask(ScriptNodePtr p) :
SourceObject(p),
Task(p),
- key(p->get_attribute_value("key"))
+ key(p->value("key").as<Glib::ustring>())
{
}
diff --git a/project2/common/sessionClearTask.h b/project2/common/sessionClearTask.h
index 5df0aa5..224c951 100644
--- a/project2/common/sessionClearTask.h
+++ b/project2/common/sessionClearTask.h
@@ -1,7 +1,6 @@
#ifndef SESSIONCLEARTASK_H
#define SESSIONCLEARTASK_H
-#include <libxml++/nodes/element.h>
#include <boost/intrusive_ptr.hpp>
#include <map>
#include "sourceObject.h"
@@ -13,7 +12,7 @@ class CommonObjects;
/// Project2 component to remove a variable from the session
class SessionClearTask : public Task {
public:
- SessionClearTask(const xmlpp::Element * p);
+ SessionClearTask(ScriptNodePtr p);
virtual ~SessionClearTask();
void execute() const;
diff --git a/project2/common/sessionSetTask.cpp b/project2/common/sessionSetTask.cpp
index 69e05c5..8cf0788 100644
--- a/project2/common/sessionSetTask.cpp
+++ b/project2/common/sessionSetTask.cpp
@@ -7,10 +7,10 @@
DECLARE_LOADER("sessionset", SessionSetTask);
-SessionSetTask::SessionSetTask(const xmlpp::Element * p) :
+SessionSetTask::SessionSetTask(ScriptNodePtr p) :
SourceObject(p),
Task(p),
- key(p->get_attribute_value("key")),
+ key(p->value("key").as<Glib::ustring>()),
value(p, "value")
{
}
diff --git a/project2/common/sessionSetTask.h b/project2/common/sessionSetTask.h
index 1fddbba..c9b22e5 100644
--- a/project2/common/sessionSetTask.h
+++ b/project2/common/sessionSetTask.h
@@ -1,7 +1,6 @@
#ifndef SESSIONSETTASK_H
#define SESSIONSETTASK_H
-#include <libxml++/nodes/element.h>
#include <boost/intrusive_ptr.hpp>
#include <map>
#include "sourceObject.h"
@@ -14,7 +13,7 @@ class CommonObjects;
/// Project2 component to add/update a variable in the session
class SessionSetTask : public Task {
public:
- SessionSetTask(const xmlpp::Element * p);
+ SessionSetTask(ScriptNodePtr p);
virtual ~SessionSetTask();
void execute() const;
diff --git a/project2/common/singleton.cpp b/project2/common/singleton.cpp
index eb78a48..91c80ff 100644
--- a/project2/common/singleton.cpp
+++ b/project2/common/singleton.cpp
@@ -1,5 +1,4 @@
#include <pch.hpp>
-#include <libxml++/nodes/element.h>
#include "view.h"
#include "iHaveParameters.h"
#include "presenter.h"
@@ -7,18 +6,14 @@
class Singleton : public View {
public:
- Singleton(const xmlpp::Element * p) :
+ Singleton(ScriptNodePtr p) :
SourceObject(p),
View(p),
rootName(p, "rootname") {
- BOOST_FOREACH(xmlpp::Node * node, p->find("columns/*")) {
- if (const xmlpp::Element * elem = dynamic_cast<const xmlpp::Element *>(node)) {
- viewColumns.insert(Columns::value_type(elem->get_name(), Variable(elem, boost::optional<Glib::ustring>())));
- }
+ BOOST_FOREACH(ScriptNodePtr node, p->childrenIn("columns")) {
+ viewColumns.insert(Columns::value_type(node->get_name(), Variable(node)));
}
- LoaderBase loader(true);
- loader.supportedStorers.insert(Storer::into<ElementLoader>(&subViews));
- loader.collectAll(p, true, IgnoreUnsupported);
+ p->script->loader.addLoadTarget(p, Storer::into<ElementLoader>(&subViews));
}
void execute(const MultiRowSetPresenter * p) const
{
diff --git a/project2/common/sourceObject.cpp b/project2/common/sourceObject.cpp
index f0423cb..ccc1034 100644
--- a/project2/common/sourceObject.cpp
+++ b/project2/common/sourceObject.cpp
@@ -3,8 +3,8 @@
unsigned int SourceObject::loadOrder = 1;
-SourceObject::SourceObject(const xmlpp::Element * p) :
- name(p ? p->get_attribute_value("name") : "anon"),
+SourceObject::SourceObject(ScriptNodePtr p) :
+ name(p ? p->value("name", "anon").as<std::string>() : "anon"),
order(loadOrder++)
{
}
diff --git a/project2/common/sourceObject.h b/project2/common/sourceObject.h
index 6a6df55..4d10dd4 100644
--- a/project2/common/sourceObject.h
+++ b/project2/common/sourceObject.h
@@ -1,17 +1,19 @@
#ifndef SOURCEOBJECT_H
#define SOURCEOBJECT_H
-#include <libxml++/nodes/element.h>
#include <boost/intrusive_ptr.hpp>
+#include <string>
#include "intrusivePtrBase.h"
class CommonObjects;
class SourceObject;
+class ScriptNode;
typedef boost::intrusive_ptr<SourceObject> SourceObjectPtr;
+typedef boost::intrusive_ptr<const ScriptNode> ScriptNodePtr;
/// Base class for all Project2 components that can be placed in a Project2 script
class SourceObject : public virtual IntrusivePtrBase {
public:
- SourceObject(const xmlpp::Element * p);
+ SourceObject(ScriptNodePtr p);
SourceObject(const std::string & name);
virtual ~SourceObject() = 0;
diff --git a/project2/common/structExceptHandling.cpp b/project2/common/structExceptHandling.cpp
index 0f176c9..bfd2f2b 100644
--- a/project2/common/structExceptHandling.cpp
+++ b/project2/common/structExceptHandling.cpp
@@ -2,30 +2,44 @@
#include "structExceptHandling.h"
#include "xmlObjectLoader.h"
#include "xmlStorage.h"
+#include "scripts.h"
#include <boost/foreach.hpp>
DECLARE_LOADER("handler", StructuredExceptionHandler);
-static void
-loadHelper(const char * name, const xmlpp::Element * root, ANONORDEREDSTORAGEOF(NoOutputExecute) * noes)
+static
+ScriptNodePtr
+loadHelperSub(const char * name, bool required, ScriptNodePtr root)
{
- LoaderBase loader(true);
- loader.supportedStorers.insert(Storer::into<ElementLoader>(noes));
- BOOST_FOREACH(const xmlpp::Node * node, root->find(name)) {
- const xmlpp::Element * elem = dynamic_cast<const xmlpp::Element *>(node);
- if (elem) {
- loader.collectAll(elem, true, ErrorOnUnsupported);
+ if (required) {
+ return root->child(name);
+ }
+ else {
+ try {
+ return root->child(name);
}
+ catch (const ValueNotFound &) {
+ return NULL;
+ }
+ }
+}
+static
+void
+loadHelper(const char * name, bool required, ScriptNodePtr root, ANONORDEREDSTORAGEOF(NoOutputExecute) * noes)
+{
+ ScriptNodePtr c = loadHelperSub(name, required, root);
+ if (c) {
+ root->script->loader.addLoadTarget(c, Storer::into<ElementLoader>(noes));
}
}
-StructuredExceptionHandler::StructuredExceptionHandler(const xmlpp::Element * e) :
+StructuredExceptionHandler::StructuredExceptionHandler(ScriptNodePtr e) :
SourceObject(e),
IHaveSubTasks(e)
{
- loadHelper("try", e, &normal);
- loadHelper("catch", e, &catches);
- loadHelper("finally", e, &finallies);
+ loadHelper("try", true, e, &normal);
+ loadHelper("catch", false, e, &catches);
+ loadHelper("finally", false, e, &finallies);
}
void
diff --git a/project2/common/structExceptHandling.h b/project2/common/structExceptHandling.h
index eabd384..067c389 100644
--- a/project2/common/structExceptHandling.h
+++ b/project2/common/structExceptHandling.h
@@ -5,7 +5,7 @@
class StructuredExceptionHandler : public IHaveSubTasks {
public:
- StructuredExceptionHandler(const xmlpp::Element *);
+ StructuredExceptionHandler(ScriptNodePtr);
void loadComplete(const CommonObjects*);
void execute() const;
diff --git a/project2/common/task.cpp b/project2/common/task.cpp
index 823382b..c4275f8 100644
--- a/project2/common/task.cpp
+++ b/project2/common/task.cpp
@@ -2,7 +2,7 @@
#include "task.h"
#include <boost/foreach.hpp>
-Task::Task(const xmlpp::Element * p) :
+Task::Task(ScriptNodePtr p) :
SourceObject(p),
NoOutputExecute(p)
{
diff --git a/project2/common/task.h b/project2/common/task.h
index 57697e2..5303f15 100644
--- a/project2/common/task.h
+++ b/project2/common/task.h
@@ -1,14 +1,13 @@
#ifndef TASK_H
#define TASK_H
-#include <libxml++/nodes/element.h>
#include "sourceObject.h"
#include "noOutputExecute.h"
/// Base class for Project2 components that perform some specific task
class Task : public NoOutputExecute {
public:
- Task(const xmlpp::Element * p);
+ Task(ScriptNodePtr p);
virtual ~Task();
virtual void execute() const = 0;
};
diff --git a/project2/common/taskHost.cpp b/project2/common/taskHost.cpp
index 98a1fa5..9ee0304 100644
--- a/project2/common/taskHost.cpp
+++ b/project2/common/taskHost.cpp
@@ -3,15 +3,17 @@
#include "noOutputExecute.h"
#include "dataSource.h"
#include "scopeObject.h"
+#include "xmlObjectLoader.h"
+#include "commonObjects.h"
#include <boost/foreach.hpp>
-TaskHost::TaskHost(const boost::filesystem::path & file) :
- XmlScriptParser(file, false),
- SourceObject(get_document()->get_root_node()),
- CheckHost(file),
- IHaveSubTasks(get_document()->get_root_node())
+TaskHost::TaskHost(ScriptReaderPtr s) :
+ SourceObject(s->root()),
+ CommonObjects(s),
+ CheckHost(s),
+ IHaveSubTasks(s->root())
{
- loader.supportedStorers.insert(Storer::into<ElementLoader>(&tasks));
+ s->loader.addLoadTarget(s->root(), Storer::into<ElementLoader>(&tasks));
}
TaskHost::~TaskHost()
@@ -27,7 +29,7 @@ TaskHost::loadComplete(const CommonObjects * co)
void
TaskHost::execute() const
{
- parseDocument();
+ loadScriptComponents();
ScopeObject txHandler(boost::bind(&TaskHost::commitAll, this), boost::bind(&TaskHost::rollbackAll, this));
run(tasks);
}
@@ -35,7 +37,7 @@ TaskHost::execute() const
void
TaskHost::commitAll() const
{
- BOOST_FOREACH(const DataSources::value_type & ds, datasources) {
+ BOOST_FOREACH(const CommonObjects::DataSources::value_type & ds, CommonObjects::datasources) {
ds.second->commit();
}
}
@@ -43,7 +45,7 @@ TaskHost::commitAll() const
void
TaskHost::rollbackAll() const
{
- BOOST_FOREACH(const DataSources::value_type & ds, datasources) {
+ BOOST_FOREACH(const CommonObjects::DataSources::value_type & ds, CommonObjects::datasources) {
ds.second->rollback();
}
}
diff --git a/project2/common/taskHost.h b/project2/common/taskHost.h
index ca8275c..9f9a1c5 100644
--- a/project2/common/taskHost.h
+++ b/project2/common/taskHost.h
@@ -2,16 +2,16 @@
#define TASKHOST_H
#include "xmlStorage.h"
-#include "xmlScriptParser.h"
#include "checkHost.h"
#include "iHaveSubTasks.h"
+#include "commonObjects.h"
class NoOutputExecute;
class DataSource;
-class TaskHost : virtual public XmlScriptParser, public IHaveSubTasks, virtual public CheckHost {
+class TaskHost : public IHaveSubTasks, virtual public CheckHost, virtual public CommonObjects {
protected:
- TaskHost(const boost::filesystem::path & file);
+ TaskHost(ScriptReaderPtr script);
virtual ~TaskHost();
void loadComplete(const CommonObjects *);
diff --git a/project2/common/transform.cpp b/project2/common/transform.cpp
index d109c19..0dafcd5 100644
--- a/project2/common/transform.cpp
+++ b/project2/common/transform.cpp
@@ -9,7 +9,7 @@ TransformChainLink::~TransformChainLink()
typedef std::map<std::string, boost::shared_ptr<TransformLoader> > TransformLoaderMap;
void
-TransformSource::addTarget(TransformChainLinkPtr tcl, const xmlpp::Element * e)
+TransformSource::addTarget(TransformChainLinkPtr tcl, ScriptNodePtr e)
{
BOOST_FOREACH(const TransformLoaderMap::value_type & tl, *LoaderBase::objLoaders<TransformLoader>()) {
TransformPtr t = tl.second->create();
diff --git a/project2/common/transform.h b/project2/common/transform.h
index ded356b..06db2c7 100644
--- a/project2/common/transform.h
+++ b/project2/common/transform.h
@@ -17,7 +17,7 @@ typedef boost::intrusive_ptr<Transform> TransformPtr;
class TransformSource : public TransformChainLink {
public:
- void addTarget(TransformChainLinkPtr, const xmlpp::Element * e = NULL);
+ void addTarget(TransformChainLinkPtr, ScriptNodePtr e = NULL);
void doTransforms() const;
private:
virtual const TransformChainLink * object() const { return this; }
@@ -35,7 +35,7 @@ class Transform : public virtual IntrusivePtrBase {
public:
virtual void transform(const TransformSource * src, TransformChainLink * dest) const = 0;
virtual bool canTransform(const TransformSource * src, TransformChainLink * dest) const = 0;
- virtual void configure(const xmlpp::Element *) { };
+ virtual void configure(ScriptNodePtr) { };
};
class TransformLoader : public ComponentLoader {
diff --git a/project2/common/validDateCheck.cpp b/project2/common/validDateCheck.cpp
index 6f731bb..987fa87 100644
--- a/project2/common/validDateCheck.cpp
+++ b/project2/common/validDateCheck.cpp
@@ -4,14 +4,15 @@
#include "commonObjects.h"
#include "paramChecker.h"
#include "variables.h"
+#include "scripts.h"
class ValidDateCheck : public ParamChecker {
public:
- ValidDateCheck(const xmlpp::Element * p) :
+ ValidDateCheck(ScriptNodePtr p) :
ParamChecker(p),
applyTo(p, "apply-to"),
format(p, "format"),
- warnLev(p->get_attribute_value("warn") == "no" ? LOG_INFO : LOG_WARNING)
+ warnLev(p->value("warn", true).as<bool>() ? LOG_WARNING : LOG_INFO)
{
}
diff --git a/project2/common/variableConvert.cpp b/project2/common/variableConvert.cpp
index 7eb16cf..a7ddca4 100644
--- a/project2/common/variableConvert.cpp
+++ b/project2/common/variableConvert.cpp
@@ -28,7 +28,7 @@ set(const VariableType * var, const T * t)
return ::set(var, t, deleter<T>);
}
-SimpleMessageException(InvalidConversionTo);
+SimpleMessage2Exception(InvalidConversionTo);
class NullVariable : std::runtime_error {
public:
@@ -131,7 +131,7 @@ class ConvertVisitor : public boost::static_visitor<DestType> {
return boost::lexical_cast<DestType>(r);
}
DestType operator()(const boost::posix_time::ptime &) const {
- throw InvalidConversionTo(typeid(DestType).name());
+ throw InvalidConversionTo(typeid(DestType).name(), "<Date Time>");
}
DestType operator()(const Null &) const {
throw NullVariable();
@@ -162,7 +162,7 @@ class ConvertVisitorDateTime : public boost::static_visitor<const boost::posix_t
}
template <typename T>
const boost::posix_time::ptime & operator()(const T &) const {
- throw InvalidConversionTo("DateTime");
+ throw InvalidConversionTo("DateTime", typeid(T).name());
}
private:
const VariableType * var;
@@ -176,10 +176,10 @@ class ConvertVisitorBool : public boost::static_visitor<bool> {
const char * str = s.c_str();
if (strcasecmp(str, "true") == 0 || strcasecmp(str, "yes") == 0 || strcasecmp(str, "on") == 0) return true;
if (strcasecmp(str, "false") == 0 || strcasecmp(str, "no") == 0 || strcasecmp(str, "off") == 0) return false;
- throw InvalidConversionTo("bool");
+ throw InvalidConversionTo("bool", s);
}
bool operator()(const boost::posix_time::ptime &) const {
- throw InvalidConversionTo("bool");
+ throw InvalidConversionTo("bool", "<Date time>");
}
bool operator()(const Null &) const {
throw NullVariable();
diff --git a/project2/common/variables-modconfig.cpp b/project2/common/variables-modconfig.cpp
index c44daf2..5a031be 100644
--- a/project2/common/variables-modconfig.cpp
+++ b/project2/common/variables-modconfig.cpp
@@ -13,9 +13,9 @@ SimpleMessageException(NoSuchConfigurationValue);
/// Variable implementation to access platform configuration values
class VariableConfig : public VariableImplDyn {
public:
- VariableConfig(const xmlpp::Element * e) :
+ VariableConfig(ScriptNodePtr e) :
VariableImplDyn(e),
- name(e->get_attribute_value("name"))
+ name(e->value("name").as<Glib::ustring>())
{
}
VariableType value() const
diff --git a/project2/common/variables-modfixed.cpp b/project2/common/variables-modfixed.cpp
new file mode 100644
index 0000000..45fa74e
--- /dev/null
+++ b/project2/common/variables-modfixed.cpp
@@ -0,0 +1,13 @@
+#include "variables-modfixed.h"
+
+VariableFixed::VariableFixed(VariableType v) :
+ var(v)
+{
+}
+
+VariableType
+VariableFixed::value() const
+{
+ return var;
+}
+
diff --git a/project2/common/variables-modfixed.h b/project2/common/variables-modfixed.h
new file mode 100644
index 0000000..eceb548
--- /dev/null
+++ b/project2/common/variables-modfixed.h
@@ -0,0 +1,17 @@
+#ifndef VARIABLES_MODFIXED_H
+#define VARIABLES_MODFIXED_H
+
+#include "variables.h"
+
+/// Variable implementation which has some fixed value
+class VariableFixed : public VariableImpl {
+ public:
+ VariableFixed(VariableType v);
+ VariableType value() const;
+
+ private:
+ VariableType var;
+};
+
+#endif
+
diff --git a/project2/common/variables-modliteral.cpp b/project2/common/variables-modliteral.cpp
new file mode 100644
index 0000000..8c165ee
--- /dev/null
+++ b/project2/common/variables-modliteral.cpp
@@ -0,0 +1,78 @@
+#include "variables-modliteral.h"
+#include "scripts.h"
+#include <stdio.h>
+#include <boost/foreach.hpp>
+#include <boost/bind.hpp>
+
+/// Variable implementation whose value is a literal value of some known type
+VariableLiteral::VariableLiteral(const Glib::ustring & src, const VT_typeID format) :
+ val(VariableType::make(src, format))
+{
+}
+
+template <typename X, typename Y>
+static
+void
+append(VariableLiteral::Vals * vals, const Y & y)
+{
+ vals->push_back(new X(y));
+}
+
+VariableLiteral::VariableLiteral(ScriptNodePtr s) {
+ try {
+ val = VariableType::make(s->value("value"), VariableType::getTypeFromName(s->value("type", "")));
+ }
+ catch (const ValueNotFound &) {
+ s->composeWithCallbacks(
+ boost::bind(&append<TextPart, Glib::ustring>, &vals, _1),
+ boost::bind(&append<VarPart, ScriptNodePtr>, &vals, _1));
+ }
+}
+
+VariableType
+VariableLiteral::value() const
+{
+ if (vals.empty()) {
+ return val;
+ }
+ if (vals.size() == 1) {
+ return *vals.front();
+ }
+ Glib::ustring v;
+ BOOST_FOREACH(PartCPtr p, vals) {
+ p->appendTo(v);
+ }
+ return v;
+}
+
+VariableLiteral::TextPart::TextPart(const Glib::ustring & e) :
+ txt(e)
+{
+}
+void
+VariableLiteral::TextPart::appendTo(Glib::ustring & str) const
+{
+ str += txt;
+}
+VariableLiteral::TextPart::operator VariableType() const
+{
+ return txt;
+}
+
+VariableLiteral::VarPart::VarPart(ScriptNodePtr e) : Variable(e)
+{
+}
+void
+VariableLiteral::VarPart::appendTo(Glib::ustring & str) const
+{
+ str += (*this)().operator const Glib::ustring &();
+}
+VariableLiteral::VarPart::operator VariableType() const
+{
+ return (*this)();
+}
+
+DECLARE_COMPONENT_LOADER("literal", VariableLiteral, VariableLoader);
+DECLARE_CUSTOM_COMPONENT_LOADER("", VariableLiteralDef, VariableLoaderImpl<VariableLiteral>, VariableLoader);
+
+
diff --git a/project2/common/variables-modliteral.h b/project2/common/variables-modliteral.h
new file mode 100644
index 0000000..77a43cc
--- /dev/null
+++ b/project2/common/variables-modliteral.h
@@ -0,0 +1,40 @@
+#ifndef VARIABLES_MODLITERAL_H
+#define VARIABLES_MODLITERAL_H
+
+#include "variables.h"
+#include <list>
+
+class VariableLiteral : public VariableImpl {
+ public:
+ VariableLiteral(const Glib::ustring & src, const VT_typeID format = DefaultType);
+ VariableLiteral(ScriptNodePtr);
+ virtual VariableType value() const;
+ class Part;
+ typedef boost::intrusive_ptr<Part> PartCPtr;
+ typedef std::list<PartCPtr> Vals;
+
+ class Part : public IntrusivePtrBase {
+ public:
+ virtual void appendTo(Glib::ustring & str) const = 0;
+ virtual operator VariableType() const = 0;
+ };
+ class TextPart : public Part {
+ public:
+ TextPart(const Glib::ustring & e);
+ void appendTo(Glib::ustring & str) const;
+ operator VariableType() const;
+ const Glib::ustring txt;
+ };
+ class VarPart : public Part, public Variable {
+ public:
+ VarPart(ScriptNodePtr e);
+ void appendTo(Glib::ustring & str) const;
+ operator VariableType() const;
+ };
+ private:
+ VariableType val;
+ Vals vals;
+};
+
+#endif
+
diff --git a/project2/common/variables-modlocalparam.cpp b/project2/common/variables-modlocalparam.cpp
index 957f76a..f6fd31c 100644
--- a/project2/common/variables-modlocalparam.cpp
+++ b/project2/common/variables-modlocalparam.cpp
@@ -8,9 +8,9 @@
/// Variable implementation to access call parameters
class VariableLocalParam : public VariableImplDyn {
public:
- VariableLocalParam(const xmlpp::Element * e) :
+ VariableLocalParam(ScriptNodePtr e) :
VariableImplDyn(e),
- name(e->get_attribute_value("name"))
+ name(e->value("name").as<Glib::ustring>())
{
}
VariableType value() const
diff --git a/project2/common/variables-modlookup.cpp b/project2/common/variables-modlookup.cpp
index 82c3539..c5a2a2e 100644
--- a/project2/common/variables-modlookup.cpp
+++ b/project2/common/variables-modlookup.cpp
@@ -30,14 +30,12 @@ class VariableLookup : public VariableImplDyn, public RowProcessor {
return l;
}
};
- VariableLookup(const xmlpp::Element * e) :
+ VariableLookup(ScriptNodePtr e) :
VariableImplDyn(e),
RowProcessor(e),
- name(e->get_attribute_value("name"))
+ name(e->value("name").as<Glib::ustring>())
{
- LoaderBase loader(true);
- loader.supportedStorers.insert(Storer::into<ElementLoader>(&rowSets));
- loader.collectAll(e, false);
+ e->script->loader.addLoadTarget(e, Storer::into<ElementLoader>(&rowSets));
}
VariableType value() const
{
diff --git a/project2/common/variables-modparam.cpp b/project2/common/variables-modparam.cpp
index 4908a89..f17cae5 100644
--- a/project2/common/variables-modparam.cpp
+++ b/project2/common/variables-modparam.cpp
@@ -7,9 +7,9 @@
/// Variable implementation to access call parameters
class VariableParam : public VariableImplDyn {
public:
- VariableParam(const xmlpp::Element * e) :
+ VariableParam(ScriptNodePtr e) :
VariableImplDyn(e),
- name(e->get_attribute_value("name"))
+ name(e->value("name").as<Glib::ustring>())
{
}
VariableType value() const
diff --git a/project2/common/variables-modsession.cpp b/project2/common/variables-modsession.cpp
index 27f1db2..68d0e56 100644
--- a/project2/common/variables-modsession.cpp
+++ b/project2/common/variables-modsession.cpp
@@ -7,9 +7,9 @@
/// Variable implementation to access session contents
class VariableSession : public VariableImplDyn {
public:
- VariableSession(const xmlpp::Element * e) :
+ VariableSession(ScriptNodePtr e) :
VariableImplDyn(e),
- name(e->get_attribute_value("name"))
+ name(e->value("name").as<Glib::ustring>())
{
}
VariableType value() const
diff --git a/project2/common/variables-moduri.cpp b/project2/common/variables-moduri.cpp
index f91423a..8096203 100644
--- a/project2/common/variables-moduri.cpp
+++ b/project2/common/variables-moduri.cpp
@@ -7,9 +7,9 @@
/// Variable implementation to access URI path fragments
class VariableUri : public VariableImplDyn {
public:
- VariableUri(const xmlpp::Element * e) :
+ VariableUri(ScriptNodePtr e) :
VariableImplDyn(e),
- index(atoi(e->get_attribute_value("index").c_str()))
+ index(e->value("index").as<int32_t>())
{
}
VariableType value() const
diff --git a/project2/common/variables.cpp b/project2/common/variables.cpp
index a3669aa..8df00e2 100644
--- a/project2/common/variables.cpp
+++ b/project2/common/variables.cpp
@@ -1,12 +1,12 @@
#include <pch.hpp>
#include "variables.h"
+#include "variables-modfixed.h"
#include "iHaveParameters.h"
#include "xmlObjectLoader.h"
#include "exceptions.h"
#include "appEngine.h"
#include "session.h"
#include "rowSet.h"
-#include <libxml++/nodes/textnode.h>
#include <stdexcept>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/foreach.hpp>
@@ -16,8 +16,6 @@
#include <boost/date_time/posix_time/posix_time.hpp>
SimpleMessageException(UnknownVariableType);
-SimpleMessageException(UnknownVariableSource);
-SimpleMessageException(NoVariableDefinition);
bool
Null::operator<(const Null &) const
@@ -54,41 +52,20 @@ operator<<(std::basic_ostream<unsigned char> & os, const Boolean & b)
return os;
}
-enum VT_typeID {
- DefaultType,
- String,
- Int,
- UInt,
- LInt,
- LUInt,
- LLInt,
- LLUInt,
- Float,
- Double,
- DateTime,
-};
-
-static
VT_typeID
-getVariableTypeFromName(const std::string & src)
+VariableType::getTypeFromName(const std::string & src)
{
if (src.empty()) return String;
if (src == "string") return String;
if (src == "int") return Int;
- if (src == "uint") return UInt;
- if (src == "lint") return LInt;
- if (src == "luint") return LUInt;
- if (src == "llint") return LLInt;
- if (src == "lluint") return LLUInt;
if (src == "float") return Float;
- if (src == "double") return Double;
if (src == "datetime") return DateTime;
+ if (src == "null") return Nul;
throw UnknownVariableType(src);
}
-static
VariableType
-makeVariableType(const Glib::ustring & src, const VT_typeID format = DefaultType)
+VariableType::make(const Glib::ustring & src, const VT_typeID format)
{
switch (format) {
default:
@@ -96,23 +73,13 @@ makeVariableType(const Glib::ustring & src, const VT_typeID format = DefaultType
case String:
return src;
case Int:
- return boost::lexical_cast<int>(src);
- case UInt:
- return boost::lexical_cast<unsigned int>(src);
- case LInt:
- return boost::lexical_cast<long int>(src);
- case LUInt:
- return boost::lexical_cast<long unsigned int>(src);
- case LLInt:
- return boost::lexical_cast<long long int>(src);
- case LLUInt:
- return boost::lexical_cast<long long unsigned int>(src);
+ return boost::lexical_cast<int64_t>(src);
case Float:
- return boost::lexical_cast<float>(src);
- case Double:
return boost::lexical_cast<double>(src);
case DateTime:
return boost::posix_time::time_from_string(src);
+ case Nul:
+ return Null();
}
}
@@ -241,88 +208,7 @@ VariableType::operator<(const VariableType & b) const
return false;
}
-/// Variable implementation whose value is a literal value of some known type
-class VariableLiteral : public VariableImpl {
- public:
- VariableLiteral(const Glib::ustring & src, const VT_typeID format = DefaultType) :
- val(makeVariableType(src, format))
- {
- }
- VariableLiteral(const xmlpp::Element * c)
- {
- if (const xmlpp::Attribute * la = c->get_attribute("value")) {
- val = makeVariableType(la->get_value(), getVariableTypeFromName(c->get_attribute_value("type")));
- }
- else {
- BOOST_FOREACH(const xmlpp::Node * n, c->get_children()) {
- if (const xmlpp::Element * e = dynamic_cast<const xmlpp::Element *>(n)) {
- vals.push_back(new VarPart(e));
- }
- else if (const xmlpp::TextNode * t = dynamic_cast<const xmlpp::TextNode *>(n)) {
- vals.push_back(new TextPart(t));
- }
- }
- }
- }
-
- virtual VariableType value() const
- {
- if (vals.empty()) {
- return val;
- }
- if (vals.size() == 1) {
- return *vals.front();
- }
- Glib::ustring v;
- BOOST_FOREACH(PartCPtr p, vals) {
- p->appendTo(v);
- }
- return v;
- }
- private:
- VariableType val;
- class Part : public IntrusivePtrBase {
- public:
- virtual void appendTo(Glib::ustring & str) const = 0;
- virtual operator VariableType() const = 0;
- };
- class TextPart : public Part {
- public:
- TextPart(const xmlpp::TextNode * e) :
- txt(e->get_content())
- {
- }
- void appendTo(Glib::ustring & str) const
- {
- str += txt;
- }
- operator VariableType() const
- {
- return txt;
- }
- const Glib::ustring txt;
- };
- class VarPart : public Part, public Variable {
- public:
- VarPart(const xmlpp::Element * e) : Variable(e, boost::optional<Glib::ustring>())
- {
- }
- void appendTo(Glib::ustring & str) const
- {
- str += (*this)().operator const Glib::ustring &();
- }
- operator VariableType() const
- {
- return (*this)();
- }
- };
- typedef boost::intrusive_ptr<Part> PartCPtr;
- std::list<PartCPtr> vals;
-};
-DECLARE_COMPONENT_LOADER("literal", VariableLiteral, VariableLoader);
-DECLARE_CUSTOM_COMPONENT_LOADER("", VariableLiteralDef, VariableLoaderImpl<VariableLiteral>, VariableLoader);
-
-VariableImplDyn::VariableImplDyn(const xmlpp::Element * e)
+VariableImplDyn::VariableImplDyn(ScriptNodePtr e)
{
if (e) {
defaultValue = Variable(e, "default", false);
@@ -332,11 +218,11 @@ VariableImplDyn::VariableImplDyn(const xmlpp::Element * e)
/// Variable implementation to access fields in row sets
class VariableParent : public VariableImplDyn {
public:
- VariableParent(const xmlpp::Element * e) :
+ VariableParent(ScriptNodePtr e) :
VariableImplDyn(e),
- depth(e->get_attribute("depth") ? atoi(e->get_attribute_value("depth").c_str()) : 1),
- attr(e->get_attribute("attribute")),
- name(attr ? e->get_attribute_value("attribute") : e->get_attribute_value("name"))
+ depth(e->value("depth", 1).as<int32_t>()),
+ attr(e->valueExists("attribute")),
+ name((attr ? e->value("attribute") : e->value("name")).as<Glib::ustring>())
{
}
VariableParent(const Glib::ustring & n, bool a, unsigned int d) :
@@ -387,66 +273,23 @@ class VariableParent : public VariableImplDyn {
};
DECLARE_COMPONENT_LOADER("parent", VariableParent, VariableLoader);
-/// Variable implementation which has some fixed value
-class VariableFixed : public VariableImpl {
- public:
- VariableFixed(VariableType v) :
- var(v)
- {
- }
- VariableType value() const
- {
- return var;
- }
- private:
- VariableType var;
-};
Variable::Variable(VariableType def) :
var(new VariableFixed(def))
{
}
-Variable::Variable(const xmlpp::Element * e, const Glib::ustring & n, bool required, VariableType def)
+Variable::Variable(ScriptNodePtr s, const boost::optional<Glib::ustring> & defaultSource) :
+ var(s->variable(defaultSource))
{
- xmlpp::Attribute * a = e->get_attribute(n);
- if (a) {
- var = new VariableLiteral(a->get_value());
- return;
- }
- xmlpp::Element::NodeList cs = e->get_children(n);
- if (cs.size() == 1) {
- const xmlpp::Element * c = dynamic_cast<const xmlpp::Element *>(cs.front());
- if (c) {
- xmlpp::Attribute * source = c->get_attribute("source");
- if (source) {
- var = LoaderBase::getLoader<VariableLoader, UnknownVariableSource>(source->get_value())->create(c);
- }
- else {
- var = new VariableLiteral(c);
- }
- return;
- }
- }
- if (!required) {
- var = new VariableFixed(def);
- return;
- }
- throw NoVariableDefinition(n);
}
-
-Variable::Variable(const xmlpp::Element * c, const boost::optional<Glib::ustring> & defaultSource)
+Variable::Variable(ScriptNodePtr s, const Glib::ustring & n) :
+ var(s->variable(n))
+{
+}
+Variable::Variable(ScriptNodePtr s, const Glib::ustring & n, const VariableType & d) :
+ var(s->variable(n, d))
{
- xmlpp::Attribute * source = c->get_attribute("source");
- if (source) {
- var = LoaderBase::getLoader<VariableLoader, UnknownVariableSource>(source->get_value())->create(c);
- }
- else if (defaultSource) {
- var = LoaderBase::getLoader<VariableLoader, UnknownVariableSource>(defaultSource.get())->create(c);
- }
- else {
- var = new VariableLiteral(c);
- }
}
Variable::Variable(VariableImpl * v) :
diff --git a/project2/common/variables.h b/project2/common/variables.h
index e42de0c..05b7855 100644
--- a/project2/common/variables.h
+++ b/project2/common/variables.h
@@ -6,13 +6,22 @@
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <stdint.h>
#include <glibmm/ustring.h>
-#include <libxml++/nodes/element.h>
-#include <libxml++/attribute.h>
#include "intrusivePtrBase.h"
#include "xmlObjectLoader.h"
#include <boost/variant.hpp>
#include <boost/shared_ptr.hpp>
+SimpleMessageException(UnknownVariableSource);
+
+enum VT_typeID {
+ DefaultType,
+ Nul,
+ String,
+ Int,
+ Float,
+ DateTime,
+};
+
class Null {
public:
bool operator<(const Null &) const;
@@ -64,6 +73,9 @@ class VariableType : public _VT {
VariableType();
VariableType(const VariableType &);
~VariableType();
+ static VariableType make(const Glib::ustring & src, const VT_typeID format = DefaultType);
+ static VT_typeID getTypeFromName(const std::string & src);
+
void operator=(const VariableType &);
bool operator<(const VariableType &) const;
@@ -98,8 +110,9 @@ class Variable {
public:
typedef boost::intrusive_ptr<VariableImpl> VariableImplPtr;
- Variable(const xmlpp::Element *, const Glib::ustring & n, bool required = true, VariableType def = VariableType());
- Variable(const xmlpp::Element *, const boost::optional<Glib::ustring> &);
+ Variable(ScriptNodePtr, const boost::optional<Glib::ustring> & = boost::optional<Glib::ustring>());
+ Variable(ScriptNodePtr, const Glib::ustring & n);
+ Variable(ScriptNodePtr, const Glib::ustring & n, const VariableType & def);
Variable(VariableType def);
static Variable makeParent(const Glib::ustring & name, bool attr, unsigned int depth);
@@ -116,7 +129,7 @@ class Variable {
/// Base class for variables whose content is dynamic
class VariableImplDyn : public VariableImpl {
public:
- VariableImplDyn(const xmlpp::Element * e);
+ VariableImplDyn(ScriptNodePtr e);
virtual VariableType value() const = 0;
protected:
@@ -126,13 +139,13 @@ class VariableImplDyn : public VariableImpl {
/// Base class to create variables
class VariableLoader : public ComponentLoader {
public:
- virtual VariableImpl * create(const xmlpp::Element *) const = 0;
+ virtual VariableImpl * create(ScriptNodePtr) const = 0;
};
/// Helper implementation of VariableLoader for specific variable types
template <class VarType>
class VariableLoaderImpl : public VariableLoader {
public:
- virtual VariableImpl * create(const xmlpp::Element * e) const
+ virtual VariableImpl * create(ScriptNodePtr e) const
{
return new VarType(e);
}
diff --git a/project2/common/view.cpp b/project2/common/view.cpp
index 34ff3d4..30a6491 100644
--- a/project2/common/view.cpp
+++ b/project2/common/view.cpp
@@ -1,7 +1,7 @@
#include <pch.hpp>
#include "view.h"
-View::View(const xmlpp::Element * p) :
+View::View(ScriptNodePtr p) :
SourceObject(p)
{
}
diff --git a/project2/common/view.h b/project2/common/view.h
index 5a4b751..23c292f 100644
--- a/project2/common/view.h
+++ b/project2/common/view.h
@@ -9,7 +9,7 @@ class MultiRowSetPresenter;
/// Base class for Project2 components that output data
class View : public virtual SourceObject {
public:
- View(const xmlpp::Element *);
+ View(ScriptNodePtr);
virtual ~View();
virtual void execute(const MultiRowSetPresenter *) const = 0;
diff --git a/project2/common/viewHost.cpp b/project2/common/viewHost.cpp
index 9d3c14b..4c19370 100644
--- a/project2/common/viewHost.cpp
+++ b/project2/common/viewHost.cpp
@@ -1,17 +1,17 @@
#include <pch.hpp>
#include "viewHost.h"
+#include "commonObjects.h"
#include "transform.h"
#include <boost/foreach.hpp>
#include <iostream>
-#define FOREACH_PRESENTER BOOST_FOREACH (const PresenterPtr & p, presenters)
-
-ViewHost::ViewHost(const boost::filesystem::path & file) :
- XmlScriptParser(file, false),
- CheckHost(file)
+ViewHost::ViewHost(ScriptReaderPtr s) :
+ CommonObjects(s),
+ CheckHost(s),
+ root(s->root())
{
- loader.supportedStorers.insert(Storer::into<ElementLoader>(&views));
- loader.supportedStorers.insert(Storer::into<PresenterLoader>(&presenter));
+ s->loader.addLoadTarget(root, Storer::into<ElementLoader>(&views));
+ s->loader.addLoadTarget(root, Storer::into<PresenterLoader>(&presenter));
}
ViewHost::~ViewHost()
@@ -21,16 +21,17 @@ ViewHost::~ViewHost()
void
ViewHost::executeViews(const DefaultPresenterProvider & dpp) const
{
- parseDocument();
+ loadScriptComponents();
if (!presenter) {
- presenter = dpp(get_document()->get_root_node());
+ presenter = dpp(root);
+ root.reset();
}
BOOST_FOREACH(const Views::value_type & s, views) {
s->execute(presenter.get());
}
// Caches might open transactions
- BOOST_FOREACH(const DataSources::value_type & ds, datasources) {
+ BOOST_FOREACH(const CommonObjects::DataSources::value_type & ds, CommonObjects::datasources) {
ds.second->commit();
}
}
diff --git a/project2/common/viewHost.h b/project2/common/viewHost.h
index 409f195..589e2b1 100644
--- a/project2/common/viewHost.h
+++ b/project2/common/viewHost.h
@@ -1,19 +1,19 @@
#ifndef VIEWHOST_H
#define VIEWHOST_H
-#include "xmlScriptParser.h"
#include "paramChecker.h"
#include "xmlStorage.h"
#include "presenter.h"
#include "checkHost.h"
#include <set>
#include <boost/filesystem/path.hpp>
+#include "commonObjects.h"
-class ViewHost : virtual public XmlScriptParser, virtual public CheckHost {
+class ViewHost : virtual public CheckHost, virtual public CommonObjects {
public:
- typedef boost::function1<MultiRowSetPresenterPtr, const xmlpp::Element *> DefaultPresenterProvider;
+ typedef boost::function1<MultiRowSetPresenterPtr, ScriptNodePtr> DefaultPresenterProvider;
- ViewHost(const boost::filesystem::path & file);
+ ViewHost(ScriptReaderPtr script);
~ViewHost();
void executeViews(const DefaultPresenterProvider &) const;
@@ -23,6 +23,7 @@ class ViewHost : virtual public XmlScriptParser, virtual public CheckHost {
private:
typedef ANONORDEREDSTORAGEOF(View) Views;
Views views;
+ mutable ScriptNodePtr root;
};
typedef boost::intrusive_ptr<ViewHost> ViewHostPtr;
diff --git a/project2/common/xmlObjectLoader.cpp b/project2/common/xmlObjectLoader.cpp
index d430194..f25ba6b 100644
--- a/project2/common/xmlObjectLoader.cpp
+++ b/project2/common/xmlObjectLoader.cpp
@@ -6,7 +6,8 @@
#include "appEngine.h"
#include <boost/shared_ptr.hpp>
#include <boost/foreach.hpp>
-#include <libxml++/nodes/textnode.h>
+#include <boost/function.hpp>
+#include <boost/function_equal.hpp>
unsigned int LoaderBase::depth = 0;
std::set<SourceObjectPtr> LoaderBase::loadedObjects;
@@ -26,25 +27,21 @@ class DepthCounter {
typedef std::map<std::string, boost::shared_ptr<ElementLoader> > ElementLoaderMap;
typedef std::set<boost::shared_ptr<ComponentLoader> > ComponentLoaderSet;
-LoaderBase::LoaderBase(bool r) :
- recursive(r),
- ns(Environment::getCurrent()->xmlNamespace)
+LoaderBase::LoaderBase() :
+ recursive(true)
{
- supportedStorers.insert(Storer::into<ElementLoader>(&libraries));
}
-LoaderBase::LoaderBase(const Glib::ustring & n, bool r) :
- recursive(r),
- ns(n)
+LoaderBase::~LoaderBase()
{
- supportedStorers.insert(Storer::into<ElementLoader>(&libraries));
}
-LoaderBase::~LoaderBase()
-{
+void
+LoaderBase::addLoadTarget(ScriptNodePtr src, boost::intrusive_ptr<Storer> target) {
+ targets[src].push_back(target);
}
-std::set<boost::shared_ptr<ComponentLoader> > * &
+ std::set<boost::shared_ptr<ComponentLoader> > * &
LoaderBase::componentLoaders()
{
static std::set<boost::shared_ptr<ComponentLoader> > * _compLoaders = NULL;
@@ -55,54 +52,62 @@ LoaderBase::componentLoaders()
}
void
-LoaderBase::collectAll(const xmlpp::Element * node, bool childrenOnly, UnsupportedHandling uh) const
+LoaderBase::collectAll(ScriptNodePtr node, bool childrenOnly, const StorerPtrs & sts) const
{
- if (!node) {
- return;
- }
DepthCounter dc(depth);
unsigned int created = 0;
- if (!childrenOnly && node->get_namespace_uri() == ns) {
+ if (!childrenOnly && node->componentNamespace()) {
Glib::ustring name = node->get_name();
unsigned int stored = 0;
created += 1;
- BOOST_FOREACH(std::set<boost::intrusive_ptr<Storer> >::value_type s, supportedStorers) {
- boost::intrusive_ptr<IntrusivePtrBase> o = s->save(node);
- if (boost::intrusive_ptr<SourceObject> t = boost::dynamic_pointer_cast<SourceObject>(o)) {
- loadedObjects.insert(t);
+ boost::intrusive_ptr<IntrusivePtrBase> o;
+ BOOST_FOREACH(const StorerPtr & s, sts) {
+ try {
+ o = s->create(node);
+ break;
}
- if (o) {
+ catch (const NotSupported &) {
+ }
+ }
+ if (!o) {
+ throw NotSupported(name);
+ }
+ BOOST_FOREACH(const StorerPtr & s, sts) {
+ if (s->save(o, node)) {
stored += 1;
+ break;
}
}
if (stored < 1) {
- if (uh == ErrorOnUnsupported) {
- throw NotSupported(name);
- }
- else if (uh == WarnOnUnsupported) {
- Logger()->messagef(LOG_WARNING, "'%s' unsupported in this location", name.c_str());
- }
+ throw NotSupported(name);
}
}
if (created == 0 && (recursive || childrenOnly)) {
- BOOST_FOREACH(const xmlpp::Node * child, node->get_children()) {
- collectAll(dynamic_cast<const xmlpp::Element *>(child), false, uh);
+ BOOST_FOREACH(ScriptNodePtr child, node->children()) {
+ collectAll(child, false, sts);
}
}
}
void
-LoaderBase::collectAll(const CommonObjects * co, const xmlpp::Element * node, bool childrenOnly, UnsupportedHandling uh) const
+LoaderBase::collectAll(const CommonObjects * co, bool childrenOnly, ScriptNodePtr node)
{
- if (depth != 0) {
+ (void)co;
+ addLoadTarget(node, Storer::into<ElementLoader>(&libraries));
+ if (depth != 0 && co) {
throw std::logic_error("Cannot set CommonObjects in subloader");
}
- loadedObjects.clear();
- collectAll(node, childrenOnly, uh);
- BOOST_FOREACH(SourceObjectPtr o, loadedObjects) {
- o->loadComplete(co);
+ Targets::iterator i;
+ while ((i = targets.begin()) != targets.end()) {
+ collectAll(i->first, childrenOnly, i->second);
+ targets.erase(i);
+ }
+ if (co) {
+ BOOST_FOREACH(SourceObjectPtr o, loadedObjects) {
+ o->loadComplete(co);
+ }
+ loadedObjects.clear();
}
- loadedObjects.clear();
}
void
@@ -117,22 +122,6 @@ LoaderBase::onAllComponents(const boost::function1<void, ComponentLoader *> & fu
}
}
-Glib::ustring
-xmlChildText(const xmlpp::Node * p, const Glib::ustring & t)
-{
- Glib::ustring rtn;
- BOOST_FOREACH(const xmlpp::Node * child, p->get_children(t)) {
- const xmlpp::Element * e = dynamic_cast<const xmlpp::Element *>(child);
- if (e) {
- const xmlpp::ContentNode * cn = e->get_child_text();
- if (cn) {
- rtn += cn->get_content();
- }
- }
- }
- return rtn;
-}
-
void
ComponentLoader::onBegin()
{
diff --git a/project2/common/xmlObjectLoader.h b/project2/common/xmlObjectLoader.h
index 3c6fa34..3dd12a4 100644
--- a/project2/common/xmlObjectLoader.h
+++ b/project2/common/xmlObjectLoader.h
@@ -9,84 +9,86 @@
#include "intrusivePtrBase.h"
#include "sourceObject.h"
#include "exceptions.h"
-
-namespace xmlpp {
- class Element;
-}
-Glib::ustring xmlChildText(const xmlpp::Node * p, const Glib::ustring & n);
+#include <glibmm/ustring.h>
+#include <map>
+#include <vector>
enum UnsupportedHandling { ErrorOnUnsupported, WarnOnUnsupported, IgnoreUnsupported };
class ElementLoader;
class ComponentLoader;
class CommonObjects;
class Storer;
+class ScriptReader;
class LoaderBase {
public:
- LoaderBase(bool recursive);
- LoaderBase(const Glib::ustring & ns, bool recursive);
+ typedef boost::intrusive_ptr<Storer> StorerPtr;
+ typedef std::vector<StorerPtr> StorerPtrs;
+ typedef std::map<ScriptNodePtr, StorerPtrs> Targets;
+
+ LoaderBase();
virtual ~LoaderBase();
- void collectAll(const CommonObjects * co, const xmlpp::Element * node, bool childrenOnly,
- UnsupportedHandling uh = ErrorOnUnsupported) const;
- void collectAll(const xmlpp::Element * node, bool childrenOnly,
- UnsupportedHandling uh = ErrorOnUnsupported) const;
+ void collectAll(const CommonObjects * co, bool childrenOnly, ScriptNodePtr script);
- std::set<boost::intrusive_ptr<Storer> > supportedStorers;
+ void addLoadTarget(ScriptNodePtr src, boost::intrusive_ptr<Storer> target);
static void onAllComponents(const boost::function1<void, ComponentLoader *> &);
static std::set<boost::shared_ptr<ComponentLoader> > * & componentLoaders();
template <class T>
- static std::map<std::string, boost::shared_ptr<T> > * & objLoaders()
- {
- static std::map<std::string, boost::shared_ptr<T> > * _objLoaders = NULL;
- if (!_objLoaders) {
- _objLoaders = new std::map<std::string, boost::shared_ptr<T> >();
+ static std::map<std::string, boost::shared_ptr<T> > * & objLoaders()
+ {
+ static std::map<std::string, boost::shared_ptr<T> > * _objLoaders = NULL;
+ if (!_objLoaders) {
+ _objLoaders = new std::map<std::string, boost::shared_ptr<T> >();
+ }
+ return _objLoaders;
}
- return _objLoaders;
- }
template <class T>
- static void newLoader(const std::string & n, T * l)
- {
- boost::shared_ptr<T> p = boost::shared_ptr<T>(l);
- objLoaders<T>()->insert(std::pair<std::string, boost::shared_ptr<T> >(n, p));
- componentLoaders()->insert(boost::shared_ptr<T>(p));
- }
+ static void newLoader(const std::string & n, T * l)
+ {
+ boost::shared_ptr<T> p = boost::shared_ptr<T>(l);
+ objLoaders<T>()->insert(std::pair<std::string, boost::shared_ptr<T> >(n, p));
+ componentLoaders()->insert(boost::shared_ptr<T>(p));
+ }
template <class T>
- static void removeLoader(const std::string & n)
- {
- std::map<std::string, boost::shared_ptr<T> > * & o = objLoaders<T>();
- std::set<boost::shared_ptr<ComponentLoader> > * & c = componentLoaders();
- typename std::map<std::string, boost::shared_ptr<T> >::iterator i = o->find(n);
- c->erase(i->second);
- o->erase(i);
- if (o->empty()) {
- delete o;
- o = NULL;
- }
- if (c->empty()) {
- delete c;
- c = NULL;
+ static void removeLoader(const std::string & n)
+ {
+ std::map<std::string, boost::shared_ptr<T> > * & o = objLoaders<T>();
+ std::set<boost::shared_ptr<ComponentLoader> > * & c = componentLoaders();
+ typename std::map<std::string, boost::shared_ptr<T> >::iterator i = o->find(n);
+ c->erase(i->second);
+ o->erase(i);
+ if (o->empty()) {
+ delete o;
+ o = NULL;
+ }
+ if (c->empty()) {
+ delete c;
+ c = NULL;
+ }
}
- }
template <class L, class E>
- static boost::shared_ptr<L> getLoader(const std::string & n)
- {
- typename std::map<std::string, boost::shared_ptr<L> >::const_iterator i = objLoaders<L>()->find(n);
- if (i != objLoaders<L>()->end()) {
- return i->second;
- }
- else {
- throw E(n);
+ static boost::shared_ptr<L> getLoader(const std::string & n)
+ {
+ typename std::map<std::string, boost::shared_ptr<L> >::const_iterator i = objLoaders<L>()->find(n);
+ if (i != objLoaders<L>()->end()) {
+ return i->second;
+ }
+ else {
+ throw E(n);
+ }
}
- }
private:
+ void collectAll(ScriptNodePtr script, bool childrenOnly, const StorerPtrs & sts) const;
+ Targets targets;
static unsigned int depth;
+ template <class X> friend class ElementLoaderImpl;
static std::set<SourceObjectPtr> loadedObjects;
const bool recursive;
@@ -121,16 +123,18 @@ class ComponentLoader {
/// Helper for loading and maintaining Project2 script components
class ElementLoader : public ComponentLoader {
public:
- virtual SourceObjectPtr createFrom(const xmlpp::Element * xml) const = 0;
+ virtual SourceObjectPtr createFrom(ScriptNodePtr) const = 0;
};
/// Helper for loading and maintaining Project2 script components (typed implementation)
template <class X>
class ElementLoaderImpl : public ElementLoader {
public:
- SourceObjectPtr createFrom(const xmlpp::Element * xml) const
+ SourceObjectPtr createFrom(ScriptNodePtr sn) const
{
- return new X(xml);
+ SourceObjectPtr sop = new X(sn);
+ LoaderBase::loadedObjects.insert(sop);
+ return sop;
}
};
#endif
diff --git a/project2/common/xmlScriptParser.cpp b/project2/common/xmlScriptParser.cpp
deleted file mode 100644
index 1db1841..0000000
--- a/project2/common/xmlScriptParser.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-#include <pch.hpp>
-#include "xmlScriptParser.h"
-#include <libxml/xinclude.h>
-#include <boost/filesystem/convenience.hpp>
-
-XmlScriptParser::XmlScriptParser(const boost::filesystem::path & file, bool ii) :
- IsInclusion(ii),
- loader(true),
- documentParsed(false)
-{
- loadDocument(file);
-}
-
-void
-XmlScriptParser::loadDocument(const boost::filesystem::path & file)
-{
- if (!boost::filesystem::exists(file)) {
- if (IsInclusion) {
- throw DependencyNotFound(file.string());
- }
- else {
- throw NotFound(file.string());
- }
- }
- try {
- parse_file(file.string());
- }
- catch (const xmlpp::internal_error &) {
- throw NotReadable(file.string());
- }
- for (int x; (x = xmlXIncludeProcessFlags(get_document()->cobj(), XML_PARSE_NOXINCNODE)); ) {
- if (x < 0) {
- throw IncludesError(file.string());
- }
- }
- loader.supportedStorers.insert(Storer::into<ElementLoader>(&rowSets));
-}
-
-void
-XmlScriptParser::parseDocument() const
-{
- if (!documentParsed) {
- loader.collectAll(this, get_document()->get_root_node(), true, ErrorOnUnsupported);
- documentParsed = true;
- }
-}
-
diff --git a/project2/common/xmlScriptParser.h b/project2/common/xmlScriptParser.h
deleted file mode 100644
index 9f1406d..0000000
--- a/project2/common/xmlScriptParser.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef XMLSCRIPTPARSER_H
-#define XMLSCRIPTPARSER_H
-
-#include <libxml++/parsers/domparser.h>
-#include <boost/function.hpp>
-#include "exceptions.h"
-#include "xmlObjectLoader.h"
-#include <intrusivePtrBase.h>
-#include "commonObjects.h"
-#include <boost/filesystem/path.hpp>
-
-class XmlScriptParser : public xmlpp::DomParser, virtual public CommonObjects, virtual public IntrusivePtrBase {
- public:
- SimpleMessageException(ParseError);
- SimpleMessageExceptionBase(NotFound, ParseError);
- SimpleMessageExceptionBase(DependencyNotFound, ParseError);
- SimpleMessageExceptionBase(NotReadable, ParseError);
- SimpleMessageExceptionBase(IncludesError, ParseError);
-
- XmlScriptParser(const boost::filesystem::path & file, bool isInclusion);
-
- const bool IsInclusion;
-
- protected:
- LoaderBase loader;
- mutable bool documentParsed;
- void parseDocument() const;
-
- private:
- void loadDocument(const boost::filesystem::path & file);
-};
-
-
-#endif
-
diff --git a/project2/common/xmlStorage.h b/project2/common/xmlStorage.h
index ceae899..267343f 100644
--- a/project2/common/xmlStorage.h
+++ b/project2/common/xmlStorage.h
@@ -4,6 +4,7 @@
#include "sourceObject.h"
#include "xmlObjectLoader.h"
#include "exceptions.h"
+#include "scripts.h"
#include <set>
#include <list>
#include <map>
@@ -33,36 +34,34 @@ class Storer : public virtual IntrusivePtrBase {
template <class L, class X>
static StorerPtr into(ANONORDEREDSTORAGEOF(X) * list);
- virtual boost::intrusive_ptr<IntrusivePtrBase> save(const xmlpp::Element *) = 0;
+ virtual boost::intrusive_ptr<IntrusivePtrBase> create(ScriptNodePtr) const = 0;
+ virtual bool save(boost::intrusive_ptr<IntrusivePtrBase>, ScriptNodePtr) = 0;
};
template <class X, class M, class L>
class StorerBase : public Storer {
public:
typedef M * Map;
- boost::intrusive_ptr<IntrusivePtrBase> save(const xmlpp::Element * p) {
- try {
- boost::intrusive_ptr<X> O = boost::dynamic_pointer_cast<X>(
- LoaderBase::getLoader<L, NotSupported>(p->get_name())->createFrom(p));
- if (O) {
- if (!insert(p, O)) {
- throw StoreFailed(p->get_attribute_value("name"));
- }
+ boost::intrusive_ptr<IntrusivePtrBase> create(ScriptNodePtr p) const {
+ return LoaderBase::getLoader<L, NotSupported>(p->get_name())->createFrom(p);
+ }
+ bool save(boost::intrusive_ptr<IntrusivePtrBase> o, ScriptNodePtr p) {
+ boost::intrusive_ptr<X> O = boost::dynamic_pointer_cast<X>(o);
+ if (O) {
+ if (!insert(p, O)) {
+ throw StoreFailed(p->get_name());
}
- return O;
- }
- catch (NotSupported) {
- return NULL;
}
+ return O;
}
- virtual bool insert(const xmlpp::Element *, boost::intrusive_ptr<X>) = 0;
+ virtual bool insert(ScriptNodePtr, boost::intrusive_ptr<X>) = 0;
};
template <class X, class M, class L>
class StorerImpl : public StorerBase<X, M, L> {
public:
StorerImpl(M * m);
- bool insert(const xmlpp::Element *, boost::intrusive_ptr<X> O);
+ bool insert(ScriptNodePtr, boost::intrusive_ptr<X> O);
};
template <class X, class L>
class StorerImpl<X, SINGLE(X), L> : public StorerBase<X, SINGLE(X), L> {
@@ -71,7 +70,7 @@ class StorerImpl<X, SINGLE(X), L> : public StorerBase<X, SINGLE(X), L> {
StorerImpl(SINGLE(X) * o) : obj(o)
{
}
- bool insert(const xmlpp::Element *, boost::intrusive_ptr<X> O)
+ bool insert(ScriptNodePtr, boost::intrusive_ptr<X> O)
{
*obj = O;
return true;
@@ -85,7 +84,7 @@ class StorerImpl<X, STORAGEOF(X), L> : public StorerBase<X, STORAGEOF(X), L> {
StorerImpl(STORAGEOF(X) * m) : map(m)
{
}
- bool insert(const xmlpp::Element *, boost::intrusive_ptr<X> O)
+ bool insert(ScriptNodePtr, boost::intrusive_ptr<X> O)
{
return map->insert(typename Map::value_type(O->name, O)).second;
}
@@ -98,7 +97,7 @@ class StorerImpl<X, ANONSTORAGEOF(X), L> : public StorerBase<X, ANONSTORAGEOF(X)
StorerImpl(ANONSTORAGEOF(X) * m) : map(m)
{
}
- bool insert(const xmlpp::Element *, boost::intrusive_ptr<X> O)
+ bool insert(ScriptNodePtr, boost::intrusive_ptr<X> O)
{
map->insert(O);
return true;
@@ -112,7 +111,7 @@ class StorerImpl<X, ANONORDEREDSTORAGEOF(X), L> : public StorerBase<X, ANONORDER
StorerImpl(ANONORDEREDSTORAGEOF(X) * m) : map(m)
{
}
- bool insert(const xmlpp::Element *, boost::intrusive_ptr<X> O)
+ bool insert(ScriptNodePtr, boost::intrusive_ptr<X> O)
{
map->push_back(O);
return true;
diff --git a/project2/console/Jamfile.jam b/project2/console/Jamfile.jam
index 3a95bd6..b3b60a1 100644
--- a/project2/console/Jamfile.jam
+++ b/project2/console/Jamfile.jam
@@ -1,10 +1,10 @@
-alias libxmlpp : : : :
- <cflags>"`pkg-config --cflags libxml++-2.6`"
- <linkflags>"`pkg-config --libs libxml++-2.6`" ;
-
+alias glibmm : : : :
+ <cflags>"`pkg-config --cflags glibmm-2.4`"
+ <linkflags>"`pkg-config --libs glibmm-2.4`"
+ ;
cpp-pch pch : pch.hpp :
<include>../../libmisc
- <library>libxmlpp
+ <library>glibmm
<library>..//p2parts
;
exe p2console :
diff --git a/project2/console/claOptions.cpp b/project2/console/claOptions.cpp
index 135eebc..d3f7745 100644
--- a/project2/console/claOptions.cpp
+++ b/project2/console/claOptions.cpp
@@ -1,8 +1,11 @@
#include <pch.hpp>
#include <boost/foreach.hpp>
#include "../common/optionsSource.h"
+#include "../common/exceptions.h"
#include "consoleEnvironment.h"
+StaticMessageException(InvalidScriptName, "Script name should be group/name");
+
class CommandLineArguments : public OptionsSource {
public:
typedef std::list<Glib::ustring> optionList;
@@ -51,7 +54,16 @@ class CommandLineArguments : public OptionsSource {
}
BOOST_FOREACH (const optionList::value_type & i, values) {
- ConsoleEnvironment::todolist.push_back(i.raw());
+ Glib::ustring group, name;
+ Glib::ustring::size_type sl = i.find('/');
+ if (sl != (Glib::ustring::size_type)-1) {
+ group = i.substr(0, sl);
+ name = i.substr(sl + 1);
+ }
+ else {
+ throw InvalidScriptName();
+ }
+ ConsoleEnvironment::todolist.push_back(ConsoleEnvironment::ToDo(group, name));
}
}
};
diff --git a/project2/console/consoleAppEngine.cpp b/project2/console/consoleAppEngine.cpp
index 40d369e..7229c36 100644
--- a/project2/console/consoleAppEngine.cpp
+++ b/project2/console/consoleAppEngine.cpp
@@ -12,12 +12,12 @@
SimpleMessageException(UnknownPlatformAlias);
-ConsoleApplicationEngine::ConsoleApplicationEngine(const ConsoleEnvironment * env, const boost::filesystem::path & f) :
- XmlScriptParser(f, false),
- SourceObject(get_document()->get_root_node()),
- CheckHost(f),
- TaskHost(f),
- ViewHost(f),
+ConsoleApplicationEngine::ConsoleApplicationEngine(const ConsoleEnvironment * env, ScriptReaderPtr script) :
+ SourceObject(script->root()),
+ CommonObjects(script),
+ CheckHost(script),
+ TaskHost(script),
+ ViewHost(script),
_env(env),
runtime(new Session(UUID::generate_random()))
{
diff --git a/project2/console/consoleAppEngine.h b/project2/console/consoleAppEngine.h
index f2a0519..d53574f 100644
--- a/project2/console/consoleAppEngine.h
+++ b/project2/console/consoleAppEngine.h
@@ -16,7 +16,7 @@ class ConsoleEnvironment;
class ConsoleApplicationEngine : public ApplicationEngine, TaskHost, ViewHost {
public:
- ConsoleApplicationEngine(const ConsoleEnvironment *, const boost::filesystem::path &);
+ ConsoleApplicationEngine(const ConsoleEnvironment *, ScriptReaderPtr);
virtual ~ConsoleApplicationEngine();
void process() const;
diff --git a/project2/console/consoleEnvironment.h b/project2/console/consoleEnvironment.h
index 5f4545c..a5530a9 100644
--- a/project2/console/consoleEnvironment.h
+++ b/project2/console/consoleEnvironment.h
@@ -3,12 +3,13 @@
#include <string>
#include <vector>
-#include <boost/filesystem/path.hpp>
+#include <boost/tuple/tuple.hpp>
#include "environment.h"
class ConsoleEnvironment : public Environment {
public:
- typedef std::vector<boost::filesystem::path> ToDoList;
+ typedef boost::tuple<Glib::ustring, Glib::ustring> ToDo;
+ typedef std::vector<ToDo> ToDoList;
typedef std::vector<std::string> UriParams;
typedef std::vector<std::pair<std::string, std::string> > QueryParams;
diff --git a/project2/console/consolePresenter.cpp b/project2/console/consolePresenter.cpp
index 47c846a..33a7af9 100644
--- a/project2/console/consolePresenter.cpp
+++ b/project2/console/consolePresenter.cpp
@@ -1,9 +1,10 @@
#include <pch.hpp>
+#include <stdio.h>
#include "consolePresenter.h"
DECLARE_COMPONENT_LOADER("console", ConsolePresenter, PresenterLoader)
-ConsolePresenter::ConsolePresenter(const xmlpp::Element *) :
+ConsolePresenter::ConsolePresenter(ScriptNodePtr) :
indent(0),
out(stdout, true)
{
diff --git a/project2/console/consolePresenter.h b/project2/console/consolePresenter.h
index a411765..6122f7f 100644
--- a/project2/console/consolePresenter.h
+++ b/project2/console/consolePresenter.h
@@ -6,7 +6,7 @@
class ConsolePresenter : public Presenter {
public:
- ConsolePresenter(const xmlpp::Element *);
+ ConsolePresenter(ScriptNodePtr);
void pushSub(const Glib::ustring & ns, const Glib::ustring & name) const;
void addAttribute(const Glib::ustring & name, const Glib::ustring & ns, const VariableType & value) const;
void addNamedValue(const Glib::ustring & name, const Glib::ustring & ns, const VariableType & value) const;
diff --git a/project2/console/p2consoleMain.cpp b/project2/console/p2consoleMain.cpp
index c194510..c560bfd 100644
--- a/project2/console/p2consoleMain.cpp
+++ b/project2/console/p2consoleMain.cpp
@@ -13,10 +13,10 @@ main(int argc, char ** argv)
ConsoleEnvironment env(argc, argv);
LoaderBase::onAllComponents(boost::bind(&ComponentLoader::onBegin, _1));
env.init();
- BOOST_FOREACH(const boost::filesystem::path & file, env.todoList()) {
+ BOOST_FOREACH(const ConsoleEnvironment::ToDo & todo, env.todoList()) {
LoaderBase::onAllComponents(boost::bind(&ComponentLoader::onBefore, _1));
- Logger()->messagef(LOG_DEBUG, "%s: Beginning file '%s'", __FUNCTION__, file.string().c_str());
- ConsoleApplicationEngine app(&env, file);
+ Logger()->messagef(LOG_DEBUG, "%s: Beginning script '%s/%s'", __FUNCTION__, todo.get<0>().c_str(), todo.get<1>().c_str());
+ ConsoleApplicationEngine app(&env, env.resolveScript(todo.get<0>(), todo.get<1>(), false));
Logger()->messagef(LOG_DEBUG, "%s: Processing file", __FUNCTION__);
app.process();
diff --git a/project2/files/Jamfile.jam b/project2/files/Jamfile.jam
index 1b34e3c..dd818b3 100644
--- a/project2/files/Jamfile.jam
+++ b/project2/files/Jamfile.jam
@@ -1,6 +1,7 @@
-alias libxmlpp : : : :
- <cflags>"`pkg-config --cflags libxml++-2.6`"
- <linkflags>"`pkg-config --libs libxml++-2.6`" ;
+alias glibmm : : : :
+ <cflags>"`pkg-config --cflags glibmm-2.4`"
+ <linkflags>"`pkg-config --libs glibmm-2.4`"
+ ;
lib boost_system : : <name>boost_system ;
lib boost_filesystem : : <name>boost_filesystem ;
@@ -8,7 +9,7 @@ lib p2files :
[ glob *.cpp ]
:
<include>../libmisc
- <library>libxmlpp
+ <library>glibmm
<library>boost_filesystem
<library>boost_system
<library>../common//p2common
diff --git a/project2/files/fileRows.cpp b/project2/files/fileRows.cpp
index 8ba5c0c..af11f55 100644
--- a/project2/files/fileRows.cpp
+++ b/project2/files/fileRows.cpp
@@ -7,7 +7,7 @@
DECLARE_LOADER("filerows", FileRows);
-FileRows::FileRows(const xmlpp::Element * p) :
+FileRows::FileRows(ScriptNodePtr p) :
StreamRows(p),
path(p, "path")
{
diff --git a/project2/files/fileRows.h b/project2/files/fileRows.h
index 7d92d20..fccbd08 100644
--- a/project2/files/fileRows.h
+++ b/project2/files/fileRows.h
@@ -9,7 +9,7 @@ class CommonObjects;
/// Project2 component to create a row set from the contents of a file on the local filesystem
class FileRows : public StreamRows {
public:
- FileRows(const xmlpp::Element * p);
+ FileRows(ScriptNodePtr p);
~FileRows();
void execute(const Glib::ustring &, const RowProcessor *) const;
diff --git a/project2/files/fsRows.cpp b/project2/files/fsRows.cpp
index a76cc02..41ec4b6 100644
--- a/project2/files/fsRows.cpp
+++ b/project2/files/fsRows.cpp
@@ -127,7 +127,7 @@ class FsRowSpecMaxDepth : public FsRows::SpecBase {
const unsigned int maxDepth;
};
-FsRows::FsRows(const xmlpp::Element * p) :
+FsRows::FsRows(ScriptNodePtr p) :
RowSet(p)
{
}
diff --git a/project2/files/fsRows.h b/project2/files/fsRows.h
index 6ef6b31..a6b9c8c 100644
--- a/project2/files/fsRows.h
+++ b/project2/files/fsRows.h
@@ -1,7 +1,6 @@
#ifndef FSROWS_H
#define FSROWS_H
-#include <libxml++/nodes/element.h>
#include <boost/intrusive_ptr.hpp>
#include <boost/filesystem/path.hpp>
#include <sys/stat.h>
@@ -28,7 +27,7 @@ class FsRows : public RowSet {
typedef std::list<Glib::ustring> SpecSpec;
typedef boost::filesystem::path Path;
- FsRows(const xmlpp::Element * p);
+ FsRows(ScriptNodePtr p);
~FsRows();
void execute(const Glib::ustring &, const RowProcessor *) const;
diff --git a/project2/files/streamRows.cpp b/project2/files/streamRows.cpp
index 0be76cd..fc2572d 100644
--- a/project2/files/streamRows.cpp
+++ b/project2/files/streamRows.cpp
@@ -1,17 +1,17 @@
#include "streamRows.h"
#include "rowProcessor.h"
-StreamRows::StreamRows(const xmlpp::Element * p) :
- DefinedColumns(p, "columns/column", boost::bind(&Column::make, _1, _2)),
+StreamRows::StreamRows(ScriptNodePtr p) :
+ DefinedColumns(p, "columns", boost::bind(&Column::make, _1, _2)),
RowSet(p),
- fieldSep(p->get_attribute_value("fieldSep")[0]),
- quoteChar(p->get_attribute_value("quoteChar")[0]),
- keepBlankRows(p->get_attribute_value("keepBlankRows") == "true"),
- countBlankRows(p->get_attribute_value("keepBlankRows") == "count"),
- newline(p->get_attribute_value("newline")),
+ fieldSep(p->value("fieldSep", ",").as<Glib::ustring>()[0]),
+ quoteChar(p->value("quoteChar", "\"").as<Glib::ustring>()[0]),
+ keepBlankRows(p->value("keepBlankRows", false)),
+ countBlankRows(p->value("countBlankRows", false)),
+ newline(p->value("newline", "\n").as<Glib::ustring>()),
newlin(newline, 0, newline.length() - 1),
- encoding(p->get_attribute_value("encoding")),
- skipheader(atoi(p->get_attribute_value("skipheader").c_str()))
+ encoding(p->value("encoding", "utf-8").as<std::string>()),
+ skipheader(p->value("skipheader", 0).as<int64_t>())
{
}
diff --git a/project2/files/streamRows.h b/project2/files/streamRows.h
index 2d10116..95d8131 100644
--- a/project2/files/streamRows.h
+++ b/project2/files/streamRows.h
@@ -9,7 +9,7 @@ class RowProcessor;
/// Base class for Project2 components that create a row set based on the contents of a byte stream
class StreamRows : public DefinedColumns, public RowSet {
public:
- StreamRows(const xmlpp::Element * p);
+ StreamRows(ScriptNodePtr p);
~StreamRows();
protected:
diff --git a/project2/json/Jamfile.jam b/project2/json/Jamfile.jam
index 92a6e28..323e4fe 100644
--- a/project2/json/Jamfile.jam
+++ b/project2/json/Jamfile.jam
@@ -1,19 +1,20 @@
-alias libxmlpp : : : :
- <cflags>"`pkg-config --cflags libxml++-2.6`"
- <linkflags>"`pkg-config --libs libxml++-2.6`" ;
+alias glibmm : : : :
+ <cflags>"`pkg-config --cflags glibmm-2.4`"
+ <linkflags>"`pkg-config --libs glibmm-2.4`"
+ ;
lib boost_filesystem : : <name>boost_filesystem ;
lib boost_date_time : : <name>boost_date_time ;
cpp-pch pch : pch.hpp :
<include>../../libmisc
- <library>libxmlpp
+ <library>glibmm
<library>../common//p2common
;
lib p2json :
pch [ glob *.cpp ]
:
<include>../libmisc
- <library>libxmlpp
+ <library>glibmm
<library>../common//p2common
<library>../uuid//p2uuid
<library>../url//p2url
diff --git a/project2/json/presenter.cpp b/project2/json/presenter.cpp
index 4afd1a0..3b069a4 100644
--- a/project2/json/presenter.cpp
+++ b/project2/json/presenter.cpp
@@ -7,7 +7,7 @@
class JsonPresenter : public MultiRowSetPresenter, public ContentPresenter, public SourceOf<json::Object> {
public:
- JsonPresenter(const xmlpp::Element *) :
+ JsonPresenter(ScriptNodePtr) :
ContentPresenter("application/json; charset=UTF-8") {
curRowSet.push(&object);
}
diff --git a/project2/mail/Jamfile.jam b/project2/mail/Jamfile.jam
index 8c8f189..91e507d 100644
--- a/project2/mail/Jamfile.jam
+++ b/project2/mail/Jamfile.jam
@@ -1,13 +1,14 @@
-alias libxmlpp : : : :
- <cflags>"`pkg-config --cflags libxml++-2.6`"
- <linkflags>"`pkg-config --libs libxml++-2.6`" ;
+alias glibmm : : : :
+ <cflags>"`pkg-config --cflags glibmm-2.4`"
+ <linkflags>"`pkg-config --libs glibmm-2.4`"
+ ;
lib esmtp : : <name>esmtp ;
lib p2mail :
sendmailTask.cpp
:
<include>../../libmisc
- <library>libxmlpp
+ <library>glibmm
<library>esmtp
<library>../common//p2common
<library>../xml//p2xml
diff --git a/project2/mail/sendmailTask.cpp b/project2/mail/sendmailTask.cpp
index e2ca703..e8b354f 100644
--- a/project2/mail/sendmailTask.cpp
+++ b/project2/mail/sendmailTask.cpp
@@ -43,13 +43,13 @@ class SendEmailFailed : public std::runtime_error {
typedef boost::shared_ptr<xmlDoc> XmlDocumentPtr;
-SendMailTask::SendMailTask(const xmlpp::Element * p) :
+SendMailTask::SendMailTask(ScriptNodePtr p) :
SourceObject(p),
Task(p),
to(p, "to"),
subject(p, "subject"),
from(p, "from"),
- server(p, "server", defaultMailServer.empty(), defaultMailServer),
+ server(p, "server", defaultMailServer),
present(p, "present")
{
}
@@ -189,7 +189,7 @@ class TransformTextToEmail : public TransformImpl<TextDocument, SendMailTask::Pa
DECLARE_TRANSFORM(TransformTextToEmail);
PresenterPtr
-SendMailTask::createDefaultPresenter(const xmlpp::Element * n) const
+SendMailTask::createDefaultPresenter(ScriptNodePtr n) const
{
Logger()->message(LOG_DEBUG, "Building default email transform chain");
XmlPresenterPtr xpp = new XmlPresenter(n);
@@ -215,7 +215,7 @@ SendMailTask::execute() const
parts->parts.insert(new Header("Content-Transfer-Encoding", "binary"));
parts->parts.insert(new BoundaryEnd());
- ViewHostPtr vsp = new ViewHost(Environment::getCurrent()->resolveScript("emails", present()));
+ ViewHostPtr vsp = new ViewHost(Environment::getCurrent()->resolveScript("emails", present(), false));
vsp->executeViews(boost::bind(&SendMailTask::createDefaultPresenter, this, _1));
vsp->doTransforms();
part = parts->parts.begin();
diff --git a/project2/mail/sendmailTask.h b/project2/mail/sendmailTask.h
index 5b10d44..6e2a10b 100644
--- a/project2/mail/sendmailTask.h
+++ b/project2/mail/sendmailTask.h
@@ -31,7 +31,7 @@ class SendMailTask : public Task {
PartList parts;
};
- SendMailTask(const xmlpp::Element * p);
+ SendMailTask(ScriptNodePtr p);
virtual ~SendMailTask();
virtual void execute() const;
@@ -45,7 +45,7 @@ class SendMailTask : public Task {
private:
static const char * writeMailWrapper(void ** buf, int * len, void * arg);
const char * writeMail(void ** buf, int * len) const;
- PresenterPtr createDefaultPresenter(const xmlpp::Element * n) const;
+ PresenterPtr createDefaultPresenter(ScriptNodePtr n) const;
mutable boost::intrusive_ptr<Parts> parts;
mutable PartList::iterator part;
diff --git a/project2/processes/Jamfile.jam b/project2/processes/Jamfile.jam
index 4c0c2b4..aef9251 100644
--- a/project2/processes/Jamfile.jam
+++ b/project2/processes/Jamfile.jam
@@ -1,12 +1,12 @@
-alias libxmlpp : : : :
- <cflags>"`pkg-config --cflags libxml++-2.6`"
- <linkflags>"`pkg-config --libs libxml++-2.6`" ;
-
+alias glibmm : : : :
+ <cflags>"`pkg-config --cflags glibmm-2.4`"
+ <linkflags>"`pkg-config --libs glibmm-2.4`"
+ ;
lib p2processes :
procRows.cpp
:
<include>../../libmisc
- <library>libxmlpp
+ <library>glibmm
<library>../common//p2common
<library>../files//p2files
;
diff --git a/project2/processes/procRows.cpp b/project2/processes/procRows.cpp
index c868323..a8b6829 100644
--- a/project2/processes/procRows.cpp
+++ b/project2/processes/procRows.cpp
@@ -1,5 +1,6 @@
#include "procRows.h"
#include "xmlObjectLoader.h"
+#include "scripts.h"
#include <exception>
DECLARE_LOADER("procrows", ProcRows);
@@ -7,7 +8,7 @@ DECLARE_LOADER("procrows", ProcRows);
SimpleMessageException(SubProcessFailedToStart);
SimpleNumericException(SubProcessFailed);
-ProcRows::ProcRows(const xmlpp::Element * p) :
+ProcRows::ProcRows(ScriptNodePtr p) :
FileRows(p)
{
}
diff --git a/project2/processes/procRows.h b/project2/processes/procRows.h
index 09b6f04..f39749d 100644
--- a/project2/processes/procRows.h
+++ b/project2/processes/procRows.h
@@ -6,7 +6,7 @@
/// Project2 component to create a row set from the output of a locally executed program
class ProcRows : public FileRows {
public:
- ProcRows(const xmlpp::Element * p);
+ ProcRows(ScriptNodePtr p);
~ProcRows();
virtual FileStarChannel doOpen() const;
diff --git a/project2/regex/Jamfile.jam b/project2/regex/Jamfile.jam
index a83697f..7bb9d16 100644
--- a/project2/regex/Jamfile.jam
+++ b/project2/regex/Jamfile.jam
@@ -1,12 +1,12 @@
-alias libxmlpp : : : :
- <cflags>"`pkg-config --cflags libxml++-2.6`"
- <linkflags>"`pkg-config --libs libxml++-2.6`" ;
-
+alias glibmm : : : :
+ <cflags>"`pkg-config --cflags glibmm-2.4`"
+ <linkflags>"`pkg-config --libs glibmm-2.4`"
+ ;
lib p2regex :
regexCheck.cpp regexRows.cpp
:
<include>../../libmisc
- <library>libxmlpp
+ <library>glibmm
<library>../common//p2common
;
diff --git a/project2/regex/regexCheck.cpp b/project2/regex/regexCheck.cpp
index 1a1add3..e58e8f1 100644
--- a/project2/regex/regexCheck.cpp
+++ b/project2/regex/regexCheck.cpp
@@ -5,7 +5,7 @@
DECLARE_LOADER("regexcheck", RegexCheck);
-RegexCheck::RegexCheck(const xmlpp::Element * p) :
+RegexCheck::RegexCheck(ScriptNodePtr p) :
ParamChecker(p),
applyTo(p, "apply-to"),
regex(p, "regex")
diff --git a/project2/regex/regexCheck.h b/project2/regex/regexCheck.h
index c4f6e02..2ddc545 100644
--- a/project2/regex/regexCheck.h
+++ b/project2/regex/regexCheck.h
@@ -7,7 +7,7 @@
/// Project2 component to test the value of a variable against a regular expression
class RegexCheck : public ParamChecker {
public:
- RegexCheck(const xmlpp::Element * p);
+ RegexCheck(ScriptNodePtr p);
virtual ~RegexCheck();
bool performCheck() const;
diff --git a/project2/regex/regexRows.cpp b/project2/regex/regexRows.cpp
index a822cf1..1238eb5 100644
--- a/project2/regex/regexRows.cpp
+++ b/project2/regex/regexRows.cpp
@@ -6,8 +6,8 @@
DECLARE_LOADER("regexrows", RegexRows);
-RegexRows::RegexRows(const xmlpp::Element * p) :
- DefinedColumns(p, "columns/column", boost::bind(&Column::make, _1, _2)),
+RegexRows::RegexRows(ScriptNodePtr p) :
+ DefinedColumns(p, "columns", boost::bind(&Column::make, _1, _2)),
RowSet(p),
sourceText(p, "sourceText"),
regex(p, "regex")
diff --git a/project2/regex/regexRows.h b/project2/regex/regexRows.h
index 21d9dfa..4d94f52 100644
--- a/project2/regex/regexRows.h
+++ b/project2/regex/regexRows.h
@@ -7,7 +7,7 @@
/// Base class for Project2 components that create a row set based on the contents of a byte stream
class RegexRows : public DefinedColumns, public RowSet {
public:
- RegexRows(const xmlpp::Element * p);
+ RegexRows(ScriptNodePtr p);
~RegexRows();
void execute(const Glib::ustring&, const RowProcessor*) const;
diff --git a/project2/sql/Jamfile.jam b/project2/sql/Jamfile.jam
index 779aba3..068394f 100644
--- a/project2/sql/Jamfile.jam
+++ b/project2/sql/Jamfile.jam
@@ -1,12 +1,12 @@
-alias libxmlpp : : : :
- <cflags>"`pkg-config --cflags libxml++-2.6`"
- <linkflags>"`pkg-config --libs libxml++-2.6`" ;
-
+alias glibmm : : : :
+ <cflags>"`pkg-config --cflags glibmm-2.4`"
+ <linkflags>"`pkg-config --libs glibmm-2.4`"
+ ;
explicit object sql-modODBC ;
obj sql-modODBC :
sql-modODBC.cpp :
<library>../../libodbcpp//odbcpp
- <library>libxmlpp
+ <library>glibmm
<include>../../libmisc
<include>../common
: :
@@ -17,7 +17,7 @@ explicit object sql-modPQ ;
obj sql-modPQ :
sql-modPQ.cpp :
<library>../../libpqpp//pqpp
- <library>libxmlpp
+ <library>glibmm
<include>../../libmisc
<include>../common
: :
@@ -27,7 +27,7 @@ obj sql-modPQ :
cpp-pch pch : pch.hpp :
<include>../../libmisc
<include>../../libdbpp
- <library>libxmlpp
+ <library>glibmm
<library>../common//p2common
;
lib p2sql :
@@ -38,7 +38,7 @@ lib p2sql :
:
<odbc>yes:<library>sql-modODBC
<pq>yes:<library>sql-modPQ
- <library>libxmlpp
+ <library>glibmm
<library>../common//p2common
<include>../../libmisc
;
diff --git a/project2/sql/pch.hpp b/project2/sql/pch.hpp
index a212245..01c68d4 100644
--- a/project2/sql/pch.hpp
+++ b/project2/sql/pch.hpp
@@ -21,13 +21,13 @@
#include "sqlWriter.h"
#include "variables.h"
#include "xmlObjectLoader.h"
+#include "scripts.h"
#include <boost/bind.hpp>
#include <boost/foreach.hpp>
#include "options.h"
#include <buffer.h>
#include <column.h>
#include <errno.h>
-#include <libxml++/nodes/textnode.h>
#include <stdexcept>
#endif
diff --git a/project2/sql/rdbmsDataSource.cpp b/project2/sql/rdbmsDataSource.cpp
index 20ccaec..4c6ae17 100644
--- a/project2/sql/rdbmsDataSource.cpp
+++ b/project2/sql/rdbmsDataSource.cpp
@@ -1,7 +1,6 @@
#include <pch.hpp>
#include "rdbmsDataSource.h"
#include "connectionLoader.h"
-#include <libxml++/nodes/textnode.h>
#include <sys/utsname.h>
#include "logger.h"
#include <errno.h>
@@ -40,16 +39,13 @@ RdbmsDataSource::DBHosts RdbmsDataSource::dbhosts;
RdbmsDataSource::FailedHosts RdbmsDataSource::failedhosts;
RdbmsDataSource::DSNSet RdbmsDataSource::changedDSNs;
-RdbmsDataSource::RdbmsDataSource(const xmlpp::Element * p) :
+RdbmsDataSource::RdbmsDataSource(ScriptNodePtr p) :
DataSource(p),
- masterDsn(dynamic_cast<const xmlpp::Element *>(p->find("masterdsn").front())),
- preferLocal(p->get_attribute_value("preferlocal") != "false")
+ masterDsn(p->child("masterdsn")),
+ preferLocal(p->value("preferlocal", true))
{
- BOOST_FOREACH(const xmlpp::Node * node, p->find("readonly/dsn")) {
- const xmlpp::Element * elem = dynamic_cast<const xmlpp::Element *>(node);
- if (elem) {
- roDSNs.insert(ReadonlyDSNs::value_type(elem->get_attribute_value("host"), elem));
- }
+ BOOST_FOREACH(ScriptNodePtr node, p->childrenIn("readonly")) {
+ roDSNs.insert(ReadonlyDSNs::value_type(node->value("host"), node));
}
}
@@ -194,12 +190,10 @@ RdbmsDataSource::RdbmsConnection::isExpired() const
return (time(NULL) > lastUsedTime + keepAliveTime);
}
-RdbmsDataSource::ConnectionInfo::ConnectionInfo(const xmlpp::Element * n)
+RdbmsDataSource::ConnectionInfo::ConnectionInfo(ScriptNodePtr node)
{
- BOOST_FOREACH(const xmlpp::Node * node, n->get_children()) {
- typeId = LoaderBase::getLoader<ConnectionLoader, UnknownConnectionProvider>(node->get_name());
- dsn = dynamic_cast<const xmlpp::Element *>(node)->get_child_text()->get_content();
- }
+ typeId = LoaderBase::getLoader<ConnectionLoader, UnknownConnectionProvider>(node->value("provider"));
+ dsn = node->value("dsn").as<std::string>();
}
DB::Connection *
diff --git a/project2/sql/rdbmsDataSource.h b/project2/sql/rdbmsDataSource.h
index 60206ff..bc72b05 100644
--- a/project2/sql/rdbmsDataSource.h
+++ b/project2/sql/rdbmsDataSource.h
@@ -1,7 +1,6 @@
#ifndef RDBMSDATASOURCE_H
#define RDBMSDATASOURCE_H
-#include <libxml/tree.h>
#include <boost/shared_ptr.hpp>
#include <map>
#include <set>
@@ -32,7 +31,7 @@ class RdbmsDataSource : public DataSource {
class ConnectionInfo {
public:
- ConnectionInfo(const xmlpp::Element *);
+ ConnectionInfo(ScriptNodePtr);
DB::Connection * connect() const;
@@ -48,7 +47,7 @@ class RdbmsDataSource : public DataSource {
typedef std::map<ConnectionInfo, ConnectionPtr> DBHosts; // Map DSN strings to connections
typedef std::map<ConnectionInfo, const DB::ConnectionError> FailedHosts; // Map DSN strings to failures
- RdbmsDataSource(const xmlpp::Element * p);
+ RdbmsDataSource(ScriptNodePtr p);
~RdbmsDataSource();
const DB::Connection & getReadonly() const;
diff --git a/project2/sql/sqlCache.cpp b/project2/sql/sqlCache.cpp
index d1ae930..7ed4ae1 100644
--- a/project2/sql/sqlCache.cpp
+++ b/project2/sql/sqlCache.cpp
@@ -21,7 +21,7 @@ typedef boost::shared_ptr<DB::ModifyCommand> ModifyPtr;
class SqlCache : public Cache {
public:
- SqlCache(const xmlpp::Element * p) :
+ SqlCache(ScriptNodePtr p) :
Cache(p)
{
}
diff --git a/project2/sql/sqlCheck.cpp b/project2/sql/sqlCheck.cpp
index d6e0651..879cbca 100644
--- a/project2/sql/sqlCheck.cpp
+++ b/project2/sql/sqlCheck.cpp
@@ -13,13 +13,13 @@ DECLARE_LOADER("sqlcheck", SqlCheck);
class CantCompareNulls : public std::exception { };
-SqlCheck::SqlCheck(const xmlpp::Element * p) :
+SqlCheck::SqlCheck(ScriptNodePtr p) :
ParamChecker(p),
dataSource(p, "datasource"),
- filter(p, "filter", false, ""),
- testOp(p, "testOp", false, "=="),
+ filter(p, "filter", ""),
+ testOp(p, "testOp", "=="),
testValue(p, "testValue"),
- sqlCommand(dynamic_cast<xmlpp::Element *>(p->get_children("sql").front()))
+ sqlCommand(p->child("sql"))
{
}
diff --git a/project2/sql/sqlCheck.h b/project2/sql/sqlCheck.h
index c9933d7..86492dc 100644
--- a/project2/sql/sqlCheck.h
+++ b/project2/sql/sqlCheck.h
@@ -10,7 +10,7 @@ class RdbmsDataSource;
/// Project2 component to check the value of a variable against an RDBMS data source
class SqlCheck : public ParamChecker {
public:
- SqlCheck(const xmlpp::Element * p);
+ SqlCheck(ScriptNodePtr p);
virtual ~SqlCheck();
virtual void loadComplete(const CommonObjects *);
@@ -22,7 +22,7 @@ class SqlCheck : public ParamChecker {
const Variable testValue;
private:
- const DynamicSql::SqlCommand sqlCommand;
+ DynamicSql::SqlCommand sqlCommand;
const RdbmsDataSource * db;
};
diff --git a/project2/sql/sqlMergeTask.cpp b/project2/sql/sqlMergeTask.cpp
index 96a895a..972b299 100644
--- a/project2/sql/sqlMergeTask.cpp
+++ b/project2/sql/sqlMergeTask.cpp
@@ -12,7 +12,6 @@
#include <boost/algorithm/string/join.hpp>
#include <boost/foreach.hpp>
#include <boost/bind.hpp>
-#include <libxml++/nodes/textnode.h>
bool SqlMergeTask::defaultUseTempTable = true;
static void attach(boost::intrusive_ptr<IHaveSubTasks> i, DB::ModifyCommand * insert);
@@ -22,7 +21,7 @@ typedef boost::intrusive_ptr<SqlMergeInsert> SqlMergeInsertPtr;
/// Project2 component insert custom constructed records during an SQL Merge task
class SqlMergeInsert : IHaveParameters, public Task {
public:
- SqlMergeInsert(const xmlpp::Element * p) :
+ SqlMergeInsert(ScriptNodePtr p) :
SourceObject(p),
IHaveParameters(p),
Task(p) {
@@ -43,51 +42,51 @@ DECLARE_LOADER("sqlmerge", SqlMergeTask);
DECLARE_LOADER("sqlmergeinsert", SqlMergeInsert);
// Conversion logic
-SqlMergeTask::SqlMergeTask(const xmlpp::Element * p) :
+SqlMergeTask::SqlMergeTask(ScriptNodePtr p) :
SourceObject(p),
Task(p),
- updateWhere(p, "updatewhere", false),
- patchOrder(p, "patchorder", false),
- earlyKeys(p, "earlykeys", false, false),
- useView(p, "useview", false, false),
+ updateWhere(p, "updatewhere", Null()),
+ patchOrder(p, "patchorder", Null()),
+ earlyKeys(p, "earlykeys", false),
+ useView(p, "useview", false),
tempTableCreated(false),
+ sqlCommand(NULL),
insCmd(NULL),
destdb(NULL),
dataSource(p, "datasource"),
- dtable(p->get_attribute_value("targettable")),
+ dtable(p->value("targettable").as<std::string>()),
dtablet(stringf("tmp_%s_%d", dtable.c_str(), getpid()))
{
- LoaderBase loader(true);
- loader.supportedStorers.insert(Storer::into<ElementLoader>(&sources));
- loader.collectAll(p, true);
+ p->script->loader.addLoadTarget(p, Storer::into<ElementLoader>(&sources));
if (!sources.empty() && useView()) {
throw NotSupported("useview not supported with iterate fillers");
}
- BOOST_FOREACH(xmlpp::Node * psi, p->find("columns/column")) {
- xmlpp::Element * e = static_cast<xmlpp::Element *>(psi);
- TargetColumnPtr tcp(new TargetColumn(e->get_child_text()->get_content()));
- tcp->maptable = e->get_attribute_value("maptable");
+ BOOST_FOREACH(ScriptNodePtr e, p->childrenIn("columns")) {
+ TargetColumnPtr tcp(new TargetColumn(e->get_name()));
+ tcp->maptable = e->value("maptable", "").as<std::string>();
if (!tcp->maptable.empty()) {
if (useView()) {
throw NotSupported("useview not supported with mapped columns");
}
- tcp->mapcolumn = e->get_attribute_value("mapcolumn");
+ tcp->mapcolumn = e->value("mapcolumn").as<std::string>();
}
cols.insert(tcp);
+ tcp->isKey = e->value("key", false);
+ if (tcp->isKey) {
+ keys.insert(tcp->column);
+ }
}
- BOOST_FOREACH(xmlpp::Node * psi, p->find("columns/column[@key='true']")) {
- keys.insert(static_cast<xmlpp::Element *>(psi)->get_child_text()->get_content());
- }
- BOOST_FOREACH(xmlpp::Node * psi, p->find("sql")) {
- sqls.push_back(static_cast<xmlpp::Element *>(psi)->get_child_text()->get_content());
+ if (p->valueExists("sql")) {
+ sqlCommand = new DynamicSql::SqlCommand(p->child("sql"));
}
}
SqlMergeTask::~SqlMergeTask()
{
delete insCmd;
+ delete sqlCommand;
}
void
@@ -143,7 +142,7 @@ SqlMergeTask::createTempTable() const
DB::ModifyCommand * cv = destdb->newModifyCommand(stringf(
"CREATE VIEW %s AS %s",
dtablet.c_str(),
- boost::algorithm::join(sqls, " UNION ").c_str()));
+ sqlCommand->getSqlFor("").c_str()));
cv->execute();
delete cv;
}
@@ -280,11 +279,13 @@ attach(boost::intrusive_ptr<IHaveSubTasks> i, DB::ModifyCommand * insert)
void
SqlMergeTask::copyToTempTable() const
{
- if (useView()) return;
+ if (useView()) {
+ return;
+ }
BOOST_FOREACH(const Sources::value_type & i, sources) {
i->execute();
}
- BOOST_FOREACH(const std::string & sql, sqls) {
+ if (sqlCommand) {
Buffer ins;
ins.appendf("INSERT INTO %s(", dtablet.c_str());
foreach(Columns::const_iterator, cols, c) {
@@ -300,7 +301,7 @@ SqlMergeTask::copyToTempTable() const
}
ins.append((*c)->column);
}
- ins.appendf(" FROM (%s) tmp_src", sql.c_str());
+ ins.appendf(" FROM (%s) tmp_src", sqlCommand->getSqlFor("").c_str());
DB::ModifyCommand * cttt = destdb->newModifyCommand(ins);
cttt->execute();
delete cttt;
diff --git a/project2/sql/sqlMergeTask.h b/project2/sql/sqlMergeTask.h
index 41d1269..dc23936 100644
--- a/project2/sql/sqlMergeTask.h
+++ b/project2/sql/sqlMergeTask.h
@@ -32,13 +32,14 @@ class SqlMergeTask : public Task {
Column column;
Column mapcolumn;
Table maptable;
+ bool isKey;
};
typedef std::set<TargetColumnPtr, TargetColumn::Sort> Columns;
typedef std::set<Column> Keys;
- SqlMergeTask(const xmlpp::Element * p);
+ SqlMergeTask(ScriptNodePtr p);
virtual ~SqlMergeTask();
virtual void loadComplete(const CommonObjects *);
@@ -60,7 +61,7 @@ class SqlMergeTask : public Task {
mutable bool tempTableCreated;
typedef ANONSTORAGEOF(Iterate) Sources;
Sources sources;
- std::list<std::string> sqls;
+ DynamicSql::SqlCommand * sqlCommand;
protected:
DB::ModifyCommand * insertCommand() const;
DB::ModifyCommand * insCmd;
diff --git a/project2/sql/sqlRows.cpp b/project2/sql/sqlRows.cpp
index ed2d71b..dbcc7be 100644
--- a/project2/sql/sqlRows.cpp
+++ b/project2/sql/sqlRows.cpp
@@ -2,7 +2,6 @@
#include "sqlRows.h"
#include "sqlHandleAsVariableType.h"
#include "rowProcessor.h"
-#include "xml.h"
#include "selectcommand.h"
#include "rdbmsDataSource.h"
#include "column.h"
@@ -14,10 +13,10 @@
DECLARE_LOADER("sqlrows", SqlRows);
-SqlRows::SqlRows(const xmlpp::Element * p) :
+SqlRows::SqlRows(ScriptNodePtr p) :
RowSet(p),
dataSource(p, "datasource"),
- sqlCommand(dynamic_cast<xmlpp::Element *>(p->get_children("sql").front())),
+ sqlCommand(p->child("sql")),
db(NULL)
{
}
diff --git a/project2/sql/sqlRows.h b/project2/sql/sqlRows.h
index 5614fa1..7ed5d3f 100644
--- a/project2/sql/sqlRows.h
+++ b/project2/sql/sqlRows.h
@@ -1,7 +1,6 @@
#ifndef SQLROWS_H
#define SQLROWS_H
-#include <libxml++/nodes/element.h>
#include <boost/intrusive_ptr.hpp>
#include <map>
#include "selectcommand.h"
@@ -14,7 +13,7 @@ class RdbmsDataSource;
/// Project2 component to create a row set based on an SQL SELECT statement issued against an RDBMS data source
class SqlRows : public RowSet {
public:
- SqlRows(const xmlpp::Element * p);
+ SqlRows(ScriptNodePtr p);
~SqlRows();
void execute(const Glib::ustring &, const RowProcessor *) const;
diff --git a/project2/sql/sqlTask.cpp b/project2/sql/sqlTask.cpp
index 9f881de..6ff05af 100644
--- a/project2/sql/sqlTask.cpp
+++ b/project2/sql/sqlTask.cpp
@@ -17,27 +17,26 @@ class SqlIfChangesStorer : public StorerBase<NoOutputExecute, ANONORDEREDSTORAGE
noChanges(nc)
{
}
- bool insert(const xmlpp::Element * p, NoOutputExecutePtr O) {
- xmlpp::Attribute * runon = p->get_attribute("runon");
- if (!runon) {
+ bool insert(ScriptNodePtr p, NoOutputExecutePtr O) {
+ try {
+ ((p->value("runon").as<std::string>() == "changes") ? changes : noChanges)->push_back(O);
+ return true;
+ }
+ catch (const ValueNotFound &) {
throw RunOnNotSpecified();
}
- ((runon->get_value() == "changes") ? changes : noChanges)->push_back(O);
- return true;
}
Map changes, noChanges;
};
-SqlTask::SqlTask(const xmlpp::Element * p) :
+SqlTask::SqlTask(ScriptNodePtr p) :
SourceObject(p),
Task(p),
dataSource(p, "datasource"),
- filter(p, "filter", false, ""),
- sqlCommand(dynamic_cast<xmlpp::Element *>(p->get_children("sql").front()))
+ filter(p, "filter", ""),
+ sqlCommand(p->child("sql"))
{
- LoaderBase loader(true);
- loader.supportedStorers.insert(new SqlIfChangesStorer(&changesNOEs, &noChangesNOEs));
- loader.collectAll(p, true, IgnoreUnsupported);
+ p->script->loader.addLoadTarget(p, new SqlIfChangesStorer(&changesNOEs, &noChangesNOEs));
}
SqlTask::~SqlTask()
diff --git a/project2/sql/sqlTask.h b/project2/sql/sqlTask.h
index 384b000..b0d0d27 100644
--- a/project2/sql/sqlTask.h
+++ b/project2/sql/sqlTask.h
@@ -1,7 +1,6 @@
#ifndef SQLTASK_H
#define SQLTASK_H
-#include <libxml++/nodes/element.h>
#include <boost/intrusive_ptr.hpp>
#include <map>
#include "task.h"
@@ -14,7 +13,7 @@ class RdbmsDataSource;
/// Project2 component to execute a modifying SQL statement against an RDBMS data source
class SqlTask : public Task {
public:
- SqlTask(const xmlpp::Element * p);
+ SqlTask(ScriptNodePtr p);
virtual ~SqlTask();
virtual void loadComplete(const CommonObjects *);
virtual void execute() const;
diff --git a/project2/sql/sqlWriter.cpp b/project2/sql/sqlWriter.cpp
index 90de82f..867e1bd 100644
--- a/project2/sql/sqlWriter.cpp
+++ b/project2/sql/sqlWriter.cpp
@@ -11,25 +11,33 @@ DynamicSql::SqlWriter::~SqlWriter()
{
}
-DynamicSql::SqlCommand::SqlCommand(const xmlpp::Element * N)
+template <typename Type, typename Cons>
+static
+void
+appendNew(DynamicSql::Writers * w, const Cons & cons)
{
- BOOST_FOREACH(xmlpp::Node * n, N->get_children()) {
- const xmlpp::TextNode * t = dynamic_cast<const xmlpp::TextNode *>(n);
- if (t) {
- writers.push_back(new SqlText(t));
- }
- const xmlpp::Element * e = dynamic_cast<const xmlpp::Element *>(n);
- if (e) {
- if (e->get_name() == "filter") {
- SqlFilterPtr f = new SqlFilter(e);
- writers.push_back(f);
- filters.insert(Filters::value_type(f->name, f));
- }
- else if (e->get_name() == "param") {
- writers.push_back(new SqlParameter(e));
- }
- }
+ w->push_back(new Type(cons));
+}
+
+static
+void
+appendNewFromNode(DynamicSql::Writers * w, DynamicSql::SqlCommand::Filters * fs, ScriptNodePtr p)
+{
+ if (fs && p->get_name() == "filter") {
+ DynamicSql::SqlFilterPtr f = new DynamicSql::SqlFilter(p);
+ w->push_back(f);
+ fs->insert(DynamicSql::SqlCommand::Filters::value_type(f->name, f));
}
+ else if (p->get_name() == "param") {
+ w->push_back(new DynamicSql::SqlParameter(p));
+ }
+}
+
+DynamicSql::SqlCommand::SqlCommand(ScriptNodePtr s)
+{
+ s->composeWithCallbacks(
+ boost::bind(&appendNew<SqlText, Glib::ustring>, &writers, _1),
+ boost::bind(&appendNewFromNode, &writers, &filters, _1));
}
Glib::ustring
@@ -59,22 +67,13 @@ DynamicSql::SqlCommand::bindParams(DB::Command * cmd, unsigned int & offset) con
}
}
-DynamicSql::SqlFilter::SqlFilter(const xmlpp::Element * N) :
- name(N->get_attribute_value("name")),
+DynamicSql::SqlFilter::SqlFilter(ScriptNodePtr p) :
+ name(p->value("name").as<Glib::ustring>()),
active(false)
{
- BOOST_FOREACH(xmlpp::Node * n, N->get_children()) {
- const xmlpp::TextNode * t = dynamic_cast<const xmlpp::TextNode *>(n);
- if (t) {
- writers.push_back(new SqlText(t));
- }
- const xmlpp::Element * e = dynamic_cast<const xmlpp::Element *>(n);
- if (e) {
- if (e->get_name() == "param") {
- writers.push_back(new SqlParameter(e));
- }
- }
- }
+ p->composeWithCallbacks(
+ boost::bind(&appendNew<SqlText, Glib::ustring>, &writers, _1),
+ boost::bind(&appendNewFromNode, &writers, (DynamicSql::SqlCommand::Filters *)NULL, _1));
}
void
@@ -97,7 +96,7 @@ DynamicSql::SqlFilter::bindParams(DB::Command * cmd, unsigned int & offset) cons
}
}
-DynamicSql::SqlParameter::SqlParameter(const xmlpp::Element * n) :
+DynamicSql::SqlParameter::SqlParameter(ScriptNodePtr n) :
Variable(n, boost::optional<Glib::ustring>("local"))
{
}
@@ -114,8 +113,8 @@ DynamicSql::SqlParameter::bindParams(DB::Command * cmd, unsigned int & offset) c
boost::apply_visitor<const SqlVariableBinder, const VariableType>(SqlVariableBinder(cmd, offset++), (*this));
}
-DynamicSql::SqlText::SqlText(const xmlpp::TextNode * n) :
- text(n->get_content())
+DynamicSql::SqlText::SqlText(const Glib::ustring & n) :
+ text(n)
{
}
diff --git a/project2/sql/sqlWriter.h b/project2/sql/sqlWriter.h
index 7693e19..4b57fa9 100644
--- a/project2/sql/sqlWriter.h
+++ b/project2/sql/sqlWriter.h
@@ -2,7 +2,6 @@
#define SQLWRITER_H
#include <intrusivePtrBase.h>
-#include <libxml++/nodes/textnode.h>
#include <command.h>
#include <glibmm/ustring.h>
#include <list>
@@ -22,7 +21,7 @@ namespace DynamicSql {
};
class SqlText : public SqlWriter {
public:
- SqlText(const xmlpp::TextNode *);
+ SqlText(const Glib::ustring &);
virtual void writeSql(Glib::ustring & sql) const;
virtual void bindParams(DB::Command *, unsigned int & offset) const;
@@ -30,13 +29,13 @@ namespace DynamicSql {
};
class SqlParameter : public SqlWriter, Variable {
public:
- SqlParameter(const xmlpp::Element *);
+ SqlParameter(ScriptNodePtr);
virtual void writeSql(Glib::ustring & sql) const;
virtual void bindParams(DB::Command *, unsigned int & offset) const;
};
class SqlFilter : public SqlWriter {
public:
- SqlFilter(const xmlpp::Element *);
+ SqlFilter(ScriptNodePtr);
virtual void writeSql(Glib::ustring & sql) const;
virtual void bindParams(DB::Command *, unsigned int & offset) const;
@@ -48,7 +47,7 @@ namespace DynamicSql {
typedef boost::intrusive_ptr<SqlFilter> SqlFilterPtr;
class SqlCommand : public SqlWriter {
public:
- SqlCommand(const xmlpp::Element *);
+ SqlCommand(ScriptNodePtr);
virtual void writeSql(Glib::ustring & sql) const;
virtual void bindParams(DB::Command *, unsigned int & offset) const;
typedef std::multimap<Glib::ustring, SqlFilterPtr> Filters;
diff --git a/project2/url/Jamfile.jam b/project2/url/Jamfile.jam
index 6e6dc36..1710e17 100644
--- a/project2/url/Jamfile.jam
+++ b/project2/url/Jamfile.jam
@@ -1,6 +1,7 @@
-alias libxmlpp : : : :
- <cflags>"`pkg-config --cflags libxml++-2.6`"
- <linkflags>"`pkg-config --libs libxml++-2.6`" ;
+alias glibmm : : : :
+ <cflags>"`pkg-config --cflags glibmm-2.4`"
+ <linkflags>"`pkg-config --libs glibmm-2.4`"
+ ;
lib curl : : <name>curl ;
lib p2url :
@@ -11,7 +12,7 @@ lib p2url :
<library>../common//p2common
<library>../files//p2files
<include>../../libmisc
- <library>libxmlpp
+ <library>glibmm
<library>curl
: :
<include>.
diff --git a/project2/url/curlHelper.cpp b/project2/url/curlHelper.cpp
index 1b98d3b..7f698cb 100644
--- a/project2/url/curlHelper.cpp
+++ b/project2/url/curlHelper.cpp
@@ -1,15 +1,16 @@
#include "curlHelper.h"
+#include "scripts.h"
-VariableCurlHelper::VariableCurlHelper(const xmlpp::Element * p) :
+VariableCurlHelper::VariableCurlHelper(ScriptNodePtr p) :
url(p, "url"),
- userAgent(p, "useragent", false, "project2/0.3"),
- cookieJar(p, "cookiejar", false),
- proxy(p, "proxy", false),
- referer(p, "referer", false),
- method(p, "method", false),
- userName(p, "username", false),
- password(p, "password", false),
- timeout(p, "timeout", false, Variable(6000))
+ userAgent(p, "useragent", "project2/0.3"),
+ cookieJar(p, "cookiejar", Null()),
+ proxy(p, "proxy", Null()),
+ referer(p, "referer", Null()),
+ method(p, "method", Null()),
+ userName(p, "username", Null()),
+ password(p, "password", Null()),
+ timeout(p, "timeout", 6000)
{
}
diff --git a/project2/url/curlHelper.h b/project2/url/curlHelper.h
index 28395e5..e3e4484 100644
--- a/project2/url/curlHelper.h
+++ b/project2/url/curlHelper.h
@@ -1,7 +1,6 @@
#ifndef CURLHELPER_H
#define CURLHELPER_H
-#include <libxml++/nodes/element.h>
#include "variables.h"
#include "../libmisc/curlsup.h"
@@ -35,7 +34,7 @@ class CurlHelper {
/// Project2 helper component to configure CurlHelper from variables
class VariableCurlHelper : public CurlHelper {
public:
- VariableCurlHelper(const xmlpp::Element * p);
+ VariableCurlHelper(ScriptNodePtr p);
~VariableCurlHelper();
const Variable url;
diff --git a/project2/url/urlRows.cpp b/project2/url/urlRows.cpp
index b3abddd..a634126 100644
--- a/project2/url/urlRows.cpp
+++ b/project2/url/urlRows.cpp
@@ -8,7 +8,7 @@
DECLARE_LOADER("urlrows", UrlRows);
-UrlRows::UrlRows(const xmlpp::Element * p) :
+UrlRows::UrlRows(ScriptNodePtr p) :
StreamRows(p),
VariableCurlHelper(p),
convertRequired(encoding != "utf-8")
diff --git a/project2/url/urlRows.h b/project2/url/urlRows.h
index 9bd4302..77c85ab 100644
--- a/project2/url/urlRows.h
+++ b/project2/url/urlRows.h
@@ -1,7 +1,6 @@
#ifndef URLROWS_H
#define URLROWS_H
-#include <libxml++/nodes/element.h>
#include <boost/intrusive_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include <map>
@@ -11,7 +10,7 @@
/// Project2 component to create a row set from the contents of a file accessible via libcurl
class UrlRows : public StreamRows, VariableCurlHelper {
public:
- UrlRows(const xmlpp::Element * p);
+ UrlRows(ScriptNodePtr p);
~UrlRows();
void execute(const Glib::ustring &, const RowProcessor *) const;
diff --git a/project2/xml/Jamfile.jam b/project2/xml/Jamfile.jam
index 6078290..1e8fcf7 100644
--- a/project2/xml/Jamfile.jam
+++ b/project2/xml/Jamfile.jam
@@ -14,8 +14,7 @@ cpp-pch pch : pch.hpp :
;
lib p2xml :
pch
- rawView.cpp xmlPresenter.cpp transformXml.cpp transformHtml.cpp transformText.cpp xmlRows.cpp
- xmlRawRows.cpp xpathRows.cpp xmlDocumentCache.cpp xmlDocumentPrefetch.cpp xmlCache.cpp sessionXml.cpp
+ [ glob *.cpp ]
:
<include>../libmisc
<library>libxmlpp
diff --git a/project2/xml/rawView.cpp b/project2/xml/rawView.cpp
index 151d594..8feceb3 100644
--- a/project2/xml/rawView.cpp
+++ b/project2/xml/rawView.cpp
@@ -6,15 +6,16 @@
#include "xmlObjectLoader.h"
#include "environment.h"
#include "appEngine.h"
+#include "xmlScriptParser.h"
#include <boost/foreach.hpp>
#include <libxml++/nodes/textnode.h>
DECLARE_LOADER("rawview", RawView);
-RawView::RawView(const xmlpp::Element * p) :
+RawView::RawView(ScriptNodePtr p) :
SourceObject(p),
View(p),
- copyRoot(p)
+ copyRoot(boost::dynamic_pointer_cast<const XmlScriptNode>(p)->xmlElement())
{
}
diff --git a/project2/xml/rawView.h b/project2/xml/rawView.h
index 54f7b2e..67d5628 100644
--- a/project2/xml/rawView.h
+++ b/project2/xml/rawView.h
@@ -9,7 +9,7 @@
/// Project2 component to create output based on its own XML tree node
class RawView : public View {
public:
- RawView(const xmlpp::Element * p);
+ RawView(ScriptNodePtr p);
void execute(const MultiRowSetPresenter *) const;
private:
diff --git a/project2/xml/xmlCache.cpp b/project2/xml/xmlCache.cpp
index 8c0dd00..96cf914 100644
--- a/project2/xml/xmlCache.cpp
+++ b/project2/xml/xmlCache.cpp
@@ -14,7 +14,7 @@
class XmlCache : public Cache {
public:
- XmlCache(const xmlpp::Element * p) :
+ XmlCache(ScriptNodePtr p) :
Cache(p)
{
}
diff --git a/project2/xml/xmlDocumentPrefetch.cpp b/project2/xml/xmlDocumentPrefetch.cpp
index e5565e6..2be3eea 100644
--- a/project2/xml/xmlDocumentPrefetch.cpp
+++ b/project2/xml/xmlDocumentPrefetch.cpp
@@ -4,14 +4,14 @@
DECLARE_LOADER("xmldocumentprefetch", XmlDocumentPrefetch);
-XmlDocumentPrefetch::XmlDocumentPrefetch(const xmlpp::Element * p) :
+XmlDocumentPrefetch::XmlDocumentPrefetch(ScriptNodePtr p) :
SourceObject(p),
View(p),
Task(p),
VariableCurlHelper(p),
- html(p, "html", false, false),
- warnings(p, "warnings", false, true),
- encoding(p, "encoding", false)
+ html(p, "html", false),
+ warnings(p, "warnings", true),
+ encoding(p, "encoding", Null())
{
}
diff --git a/project2/xml/xmlDocumentPrefetch.h b/project2/xml/xmlDocumentPrefetch.h
index f75fabe..454492a 100644
--- a/project2/xml/xmlDocumentPrefetch.h
+++ b/project2/xml/xmlDocumentPrefetch.h
@@ -10,7 +10,7 @@
/// Project2 component to queue up CURL objects to be downloaded
class XmlDocumentPrefetch : public View, public Task, XmlDocumentCache, VariableCurlHelper {
public:
- XmlDocumentPrefetch(const xmlpp::Element * p);
+ XmlDocumentPrefetch(ScriptNodePtr p);
~XmlDocumentPrefetch();
void execute(const MultiRowSetPresenter*) const;
diff --git a/project2/xml/xmlPresenter.cpp b/project2/xml/xmlPresenter.cpp
index 249e4f4..86ec831 100644
--- a/project2/xml/xmlPresenter.cpp
+++ b/project2/xml/xmlPresenter.cpp
@@ -16,11 +16,11 @@ XmlPresenter::XmlPresenter(const Glib::ustring & responseRootNodeName, const Gli
createDoc(responseRootNodeName, responseStyle);
}
-XmlPresenter::XmlPresenter(const xmlpp::Element * e) :
- ContentPresenter(e->get_attribute_value("contenttype")),
+XmlPresenter::XmlPresenter(ScriptNodePtr e) :
+ ContentPresenter(e->value("contenttype", "")),
responseDoc(XmlDocumentPtr(new xmlpp::Document("1.0")))
{
- createDoc(e->get_attribute_value("root"), e->get_attribute_value("style"));
+ createDoc(e->value("root", ""), e->value("style", ""));
}
XmlPresenter::~XmlPresenter()
diff --git a/project2/xml/xmlPresenter.h b/project2/xml/xmlPresenter.h
index 4f3fdbb..38244be 100644
--- a/project2/xml/xmlPresenter.h
+++ b/project2/xml/xmlPresenter.h
@@ -3,16 +3,18 @@
#include "presenter.h"
#include "transform.h"
+#include <libxml/tree.h>
namespace xmlpp {
class Document;
+ class Element;
}
class XmlPresenter : public Presenter, public ContentPresenter, public SourceOf<xmlpp::Document>, public SourceOf<xmlDoc>, public SourceOf<boost::shared_ptr<xmlpp::Document> > {
public:
typedef boost::shared_ptr<xmlpp::Document> XmlDocumentPtr;
XmlPresenter(const Glib::ustring & responseRootNodeName, const Glib::ustring & responseStyle, const Glib::ustring & contentType);
- XmlPresenter(const xmlpp::Element * e);
+ XmlPresenter(ScriptNodePtr e);
~XmlPresenter();
void declareNamespace(const Glib::ustring & prefix, const Glib::ustring & ns) const;
diff --git a/project2/xml/xmlRawRows.cpp b/project2/xml/xmlRawRows.cpp
index 73685aa..faca679 100644
--- a/project2/xml/xmlRawRows.cpp
+++ b/project2/xml/xmlRawRows.cpp
@@ -42,7 +42,7 @@ class XmlRowState : public RowState {
};
-XmlRawRowsBase::XmlRawRowsBase(const xmlpp::Element * p) :
+XmlRawRowsBase::XmlRawRowsBase(ScriptNodePtr p) :
RowSet(p)
{
}
@@ -81,7 +81,7 @@ void XmlRawRowsBase::execute(const xmlpp::Document * doc, const RowProcessor * r
}
}
-XmlRawRows::XmlRawRows(const xmlpp::Element * p) :
+XmlRawRows::XmlRawRows(ScriptNodePtr p) :
XmlRawRowsBase(p),
path(p, "path")
{
diff --git a/project2/xml/xmlRawRows.h b/project2/xml/xmlRawRows.h
index 81c04a5..15dad48 100644
--- a/project2/xml/xmlRawRows.h
+++ b/project2/xml/xmlRawRows.h
@@ -6,7 +6,7 @@ namespace xmlpp {
class XmlRawRowsBase : public RowSet {
public:
- XmlRawRowsBase(const xmlpp::Element * p);
+ XmlRawRowsBase(ScriptNodePtr p);
XmlRawRowsBase();
protected:
@@ -15,7 +15,7 @@ class XmlRawRowsBase : public RowSet {
class XmlRawRows : public XmlRawRowsBase {
public:
- XmlRawRows(const xmlpp::Element * p);
+ XmlRawRows(ScriptNodePtr p);
XmlRawRows(const Glib::ustring & p);
void execute(const Glib::ustring&, const RowProcessor * rp) const;
diff --git a/project2/xml/xmlRows.cpp b/project2/xml/xmlRows.cpp
index d648b10..9ec7be0 100644
--- a/project2/xml/xmlRows.cpp
+++ b/project2/xml/xmlRows.cpp
@@ -14,7 +14,7 @@
DECLARE_LOADER("xmlrows", XmlRows);
-XmlRows::XmlRows(const xmlpp::Element * p) :
+XmlRows::XmlRows(ScriptNodePtr p) :
RowSet(p),
recordRoot(p, "recordroot"),
recordTrigger(p, "recordtrigger"),
@@ -29,22 +29,19 @@ XmlRows::XmlRows(const xmlpp::Element * p) :
boost::split(trigger, rT, boost::is_any_of("/"));
unsigned int col = 0;
- BOOST_FOREACH(const xmlpp::Node * node, p->find("fields/field")) {
- const xmlpp::Element * elem = dynamic_cast<const xmlpp::Element *>(node);
- if (elem) {
- Path p(root);
- Glib::ustring path(elem->get_child_text()->get_content());
+ BOOST_FOREACH(ScriptNodePtr node, p->childrenIn("fields")) {
+ Path p(root);
+ Glib::ustring path = node->value("path");
- for(ssi It = make_split_iterator(path, first_finder("/", boost::is_equal())); It!=ssi(); ++It) {
- if (It->front() == '@') {
- anyInterestingAttributes = true;
- }
- p.push_back(Glib::ustring(It->begin(), It->end()));
+ for(ssi It = make_split_iterator(path, first_finder("/", boost::is_equal())); It!=ssi(); ++It) {
+ if (It->front() == '@') {
+ anyInterestingAttributes = true;
}
-
- fields[p] = col;
- fieldNames.insert(new Column(col++, elem->get_attribute_value("name")));
+ p.push_back(Glib::ustring(It->begin(), It->end()));
}
+
+ fields[p] = col;
+ fieldNames.insert(new Column(col++, node->get_name()));
}
}
diff --git a/project2/xml/xmlRows.h b/project2/xml/xmlRows.h
index d9971bc..975e290 100644
--- a/project2/xml/xmlRows.h
+++ b/project2/xml/xmlRows.h
@@ -12,7 +12,7 @@ class XmlRows : public RowSet {
typedef std::vector<std::string> Path;
typedef std::map<Path, unsigned int> Interests;
- XmlRows(const xmlpp::Element * p);
+ XmlRows(ScriptNodePtr p);
~XmlRows();
void execute(const Glib::ustring &, const RowProcessor *) const;
diff --git a/project2/xml/xmlScriptParser.cpp b/project2/xml/xmlScriptParser.cpp
new file mode 100644
index 0000000..4963b8f
--- /dev/null
+++ b/project2/xml/xmlScriptParser.cpp
@@ -0,0 +1,191 @@
+#include <pch.hpp>
+#include "xmlScriptParser.h"
+#include "scripts.h"
+#include "commonObjects.h"
+#include "variables-modliteral.h"
+#include <libxml/xinclude.h>
+#include <boost/filesystem/convenience.hpp>
+
+XmlScriptParser::XmlScriptParser(const boost::filesystem::path & file)
+{
+ try {
+ parse_file(file.string());
+ }
+ catch (const xmlpp::internal_error &) {
+ throw NotReadable(file.string());
+ }
+ for (int x; (x = xmlXIncludeProcessFlags(get_document()->cobj(), XML_PARSE_NOXINCNODE)); ) {
+ if (x < 0) {
+ throw IncludesError(file.string());
+ }
+ }
+}
+
+ScriptNodePtr
+XmlScriptParser::root() {
+ if (!_root) {
+ _root = new XmlScriptNode(get_document()->get_root_node(), this);
+ }
+ return _root;
+}
+
+class XmlScriptReaderLoader : public ScriptReaderLoader {
+ public:
+ ScriptReaderPtr resolveScript(const std::string & group, const std::string & name) const {
+ boost::filesystem::path script(boost::filesystem::current_path() / group);
+ BOOST_FOREACH(const boost::filesystem::path & e, boost::filesystem::path(name)) {
+ if (boost::filesystem::is_directory(script / e)) {
+ script /= e;
+ }
+ else {
+ boost::filesystem::path path = (script / e).string() + ".xml";
+ if (boost::filesystem::is_regular_file(path)) {
+ return new XmlScriptParser(path);
+ }
+ }
+ }
+ return NULL;
+ }
+};
+
+
+XmlScriptNode::XmlScriptNode(const xmlpp::Element * e, ScriptReaderPtr p) :
+ ScriptNode(p),
+ element(e)
+{
+}
+
+const xmlpp::Element *
+XmlScriptNode::xmlElement() const
+{
+ return element;
+}
+
+bool
+XmlScriptNode::componentNamespace() const
+{
+ return element->get_namespace_uri () == Environment::getCurrent()->xmlNamespace;
+}
+
+std::string
+XmlScriptNode::get_name() const
+{
+ return element->get_name();
+}
+
+bool
+XmlScriptNode::valueExists(const Glib::ustring & n) const
+{
+ return (element->get_attribute(n) || !element->get_children(n).empty());
+}
+
+ScriptNode::ScriptNodes
+XmlScriptNode::children() const
+{
+ ScriptNodes sns;
+ BOOST_FOREACH(const xmlpp::Node * n, element->get_children()) {
+ if (const xmlpp::Element * e = dynamic_cast<const xmlpp::Element *>(n)) {
+ sns.push_back(new XmlScriptNode(e, script));
+ }
+ }
+ return sns;
+}
+
+ScriptNodePtr
+XmlScriptNode::child(const Glib::ustring & n) const
+{
+ const xmlpp::Element::NodeList cs = element->get_children(n);
+ if (cs.size() == 1) {
+ if (const xmlpp::Element * c = dynamic_cast<const xmlpp::Element *>(cs.front())) {
+ return new XmlScriptNode(c, script);
+ }
+ }
+ throw ValueNotFound(n);
+}
+
+ScriptNode::ScriptNodes
+XmlScriptNode::childrenIn(const Glib::ustring & c) const
+{
+ ScriptNodes sns;
+ BOOST_FOREACH(const xmlpp::Node * n, element->get_children(c)) {
+ if (const xmlpp::Element * e = dynamic_cast<const xmlpp::Element *>(n)) {
+ BOOST_FOREACH(const xmlpp::Node * n1, e->get_children()) {
+ if (const xmlpp::Element * e1 = dynamic_cast<const xmlpp::Element *>(n1)) {
+ sns.push_back(new XmlScriptNode(e1, script));
+ }
+ }
+ }
+ }
+ return sns;
+}
+
+VariableImpl *
+XmlScriptNode::variable(const Glib::ustring & n) const
+{
+ if (const xmlpp::Attribute * a = element->get_attribute(n)) {
+ return new VariableLiteral(a->get_value());
+ }
+ const xmlpp::Element::NodeList cs = element->get_children(n);
+ if (cs.size() == 1) {
+ if (const xmlpp::Element * c = dynamic_cast<const xmlpp::Element *>(cs.front())) {
+ if (const xmlpp::Attribute * source = c->get_attribute("source")) {
+ return LoaderBase::getLoader<VariableLoader, UnknownVariableSource>(source->get_value())->create(new XmlScriptNode(c, script));
+ }
+ else {
+ return new VariableLiteral(new XmlScriptNode(c, script));
+ }
+ }
+ }
+ throw ValueNotFound(n);
+}
+
+VariableImpl *
+XmlScriptNode::variable(const boost::optional<Glib::ustring> & defaultSource) const
+{
+ if (const xmlpp::Attribute * source = element->get_attribute("source")) {
+ return LoaderBase::getLoader<VariableLoader, UnknownVariableSource>(source->get_value())->create(new XmlScriptNode(element, script));
+ }
+ else if (defaultSource) {
+ return LoaderBase::getLoader<VariableLoader, UnknownVariableSource>(defaultSource.get())->create(new XmlScriptNode(element, script));
+ }
+ else {
+ return new VariableLiteral(new XmlScriptNode(element, script));
+ }
+}
+
+VariableType
+XmlScriptNode::value(const Glib::ustring & n) const
+{
+ if (const xmlpp::Attribute * a = element->get_attribute(n)) {
+ return a->get_value();
+ }
+ const xmlpp::Element::NodeList cs = element->get_children(n);
+ if (cs.size() == 1) {
+ if (const xmlpp::Element * c = dynamic_cast<const xmlpp::Element *>(cs.front())) {
+ boost::intrusive_ptr<VariableImpl> v;
+ if (const xmlpp::Attribute * source = c->get_attribute("source")) {
+ v = LoaderBase::getLoader<VariableLoader, UnknownVariableSource>(source->get_value())->create(new XmlScriptNode(c, script));
+ }
+ else {
+ v = new VariableLiteral(new XmlScriptNode(c, script));
+ }
+ return v->value();
+ }
+ }
+ throw ValueNotFound(n);
+}
+
+void
+XmlScriptNode::composeWithCallbacks(const LiteralCallback & lcb, const NodeCallback & ncb) const
+{
+ BOOST_FOREACH(const xmlpp::Node * n, element->get_children()) {
+ if (const xmlpp::TextNode * t = dynamic_cast<const xmlpp::TextNode *>(n)) {
+ lcb(t->get_content());
+ }
+ else if (const xmlpp::Element * e = dynamic_cast<const xmlpp::Element *>(n)) {
+ ncb(new XmlScriptNode(e, script));
+ }
+ }
+}
+
+DECLARE_CUSTOM_COMPONENT_LOADER("xmlScriptReader", XmlScriptReaderLoader, XmlScriptReaderLoader, ScriptReaderLoader);
diff --git a/project2/xml/xmlScriptParser.h b/project2/xml/xmlScriptParser.h
new file mode 100644
index 0000000..ad0b1bf
--- /dev/null
+++ b/project2/xml/xmlScriptParser.h
@@ -0,0 +1,48 @@
+#ifndef XMLSCRIPTPARSER_H
+#define XMLSCRIPTPARSER_H
+
+#include <boost/function.hpp>
+#include "exceptions.h"
+#include "xmlObjectLoader.h"
+#include "scripts.h"
+#include <intrusivePtrBase.h>
+#include <boost/filesystem/path.hpp>
+#include <libxml++/document.h>
+#include <libxml++/nodes/element.h>
+#include <libxml++/parsers/domparser.h>
+
+class XmlScriptNode : public ScriptNode {
+ public:
+ XmlScriptNode(const xmlpp::Element * xmlElement, ScriptReaderPtr p);
+
+ const xmlpp::Element * xmlElement() const;
+ bool componentNamespace() const;
+ std::string get_name() const;
+ ScriptNodePtr child(const Glib::ustring&) const;
+ ScriptNodes children() const;
+ ScriptNodes childrenIn(const Glib::ustring&) const;
+ bool valueExists(const Glib::ustring&) const;
+ VariableImpl * variable(const boost::optional<Glib::ustring> & defaultSource) const;
+ VariableImpl * variable(const Glib::ustring&) const;
+ VariableType value(const Glib::ustring&) const;
+ void composeWithCallbacks(const ScriptNode::LiteralCallback&, const ScriptNode::NodeCallback&) const;
+
+ private:
+ const xmlpp::Element * element;
+};
+
+class XmlScriptParser : public xmlpp::DomParser, public ScriptReader {
+ public:
+ SimpleMessageException(ParseError);
+ SimpleMessageExceptionBase(NotReadable, ParseError);
+ SimpleMessageExceptionBase(IncludesError, ParseError);
+
+ XmlScriptParser(const boost::filesystem::path & file);
+ ScriptNodePtr root();
+ private:
+ ScriptNodePtr _root;
+};
+
+
+#endif
+
diff --git a/project2/xml/xpathRows.cpp b/project2/xml/xpathRows.cpp
index e65104d..bc9481a 100644
--- a/project2/xml/xpathRows.cpp
+++ b/project2/xml/xpathRows.cpp
@@ -17,25 +17,19 @@ DECLARE_LOADER("xpathrows", XPathRows);
SimpleMessageException(XpathInitError);
SimpleMessageException(XpathEvalError);
-XPathRows::XPathRows(const xmlpp::Element * p) :
+XPathRows::XPathRows(ScriptNodePtr p) :
RowSet(p),
VariableCurlHelper(p),
- html(p, "html", false, false),
- warnings(p, "warnings", false, true),
- encoding(p, "encoding", false)
+ html(p, "html", false),
+ warnings(p, "warnings", true),
+ encoding(p, "encoding", Null())
{
- BOOST_FOREACH(const xmlpp::Node * node, p->find("filterview")) {
- const xmlpp::Element * elem = dynamic_cast<const xmlpp::Element *>(node);
- if (elem) {
- FilterViewPtr fv = new FilterView(elem);
- fvs[fv->name] = fv;
- }
+ BOOST_FOREACH(ScriptNodePtr node, p->childrenIn("filterviews")) {
+ FilterViewPtr fv = new FilterView(node);
+ fvs[fv->name] = fv;
}
- BOOST_FOREACH(const xmlpp::Node * node, p->find("namespace")) {
- const xmlpp::Element * elem = dynamic_cast<const xmlpp::Element *>(node);
- if (elem) {
- namespaces[elem->get_attribute_value("prefix")] = elem->get_attribute_value("url");
- }
+ BOOST_FOREACH(ScriptNodePtr node, p->childrenIn("namespaces")) {
+ namespaces[node->value("prefix")] = node->value("url").as<Glib::ustring>();
}
}
@@ -122,21 +116,21 @@ XPathRows::execute(const Glib::ustring & filter, const RowProcessor * rp) const
}
}
-XPathRows::FilterView::FilterView(const xmlpp::Element * p) :
- DefinedColumns(p, "field", boost::bind(XPathRows::FilterViewColumn::make, _1, _2)),
- name(p->get_attribute_value("name")),
+XPathRows::FilterView::FilterView(ScriptNodePtr p) :
+ DefinedColumns(p, "fields", boost::bind(XPathRows::FilterViewColumn::make, _1, _2)),
+ name(p->get_name()),
root(p, "root")
{
}
-XPathRows::FilterViewColumn::FilterViewColumn(unsigned int idx, const xmlpp::Element * p) :
+XPathRows::FilterViewColumn::FilterViewColumn(unsigned int idx, ScriptNodePtr p) :
Column(idx, p),
path(p, "xpath")
{
}
XPathRows::FilterViewColumn *
-XPathRows::FilterViewColumn::make(unsigned int idx, const xmlpp::Element * p)
+XPathRows::FilterViewColumn::make(unsigned int idx, ScriptNodePtr p)
{
return new FilterViewColumn(idx, p);
}
diff --git a/project2/xml/xpathRows.h b/project2/xml/xpathRows.h
index e2c6327..47d34eb 100644
--- a/project2/xml/xpathRows.h
+++ b/project2/xml/xpathRows.h
@@ -14,7 +14,7 @@
/// Project2 component to create a row set based on the contents of an XML resource and specific XPaths with its hierarchy
class XPathRows : public RowSet, XmlDocumentCache, VariableCurlHelper {
public:
- XPathRows(const xmlpp::Element * p);
+ XPathRows(ScriptNodePtr p);
~XPathRows();
void execute(const Glib::ustring &, const RowProcessor *) const;
@@ -22,15 +22,15 @@ class XPathRows : public RowSet, XmlDocumentCache, VariableCurlHelper {
private:
class FilterViewColumn : public Column {
public:
- FilterViewColumn(unsigned int, const xmlpp::Element *);
- static FilterViewColumn * make(unsigned int, const xmlpp::Element *);
+ FilterViewColumn(unsigned int, ScriptNodePtr);
+ static FilterViewColumn * make(unsigned int, ScriptNodePtr);
const Variable path;
};
class FilterView : public DefinedColumns, public virtual IntrusivePtrBase {
public:
typedef std::map<const Glib::ustring, Variable> XPaths;
- FilterView(const xmlpp::Element * p);
+ FilterView(ScriptNodePtr p);
const Glib::ustring name;
const Variable root;