2 * Copyright (C) 2004-2008 Geometer Plus <contact@geometerplus.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 #include <ZLXMLReader.h>
24 #include <ZLResource.h>
26 #include "ProgramCollection.h"
27 #include "../options/FBOptions.h"
29 class ProgramCollectionBuilder
: public ZLXMLReader
{
32 ProgramCollectionBuilder(ProgramCollectionMap
&collectionMap
);
33 ~ProgramCollectionBuilder();
36 void startElementHandler(const char *tag
, const char **attributes
);
37 void endElementHandler(const char *tag
);
40 ProgramCollectionMap
&myCollectionMap
;
41 shared_ptr
<ProgramCollection
> myCurrentCollection
;
42 shared_ptr
<Program
> myCurrentProgram
;
45 static const std::string SECTION
= "section";
46 static const std::string PROGRAM
= "program";
47 static const std::string ACTION
= "action";
48 static const std::string OPTION
= "option";
50 ProgramCollectionBuilder::ProgramCollectionBuilder(ProgramCollectionMap
&collectionMap
) : myCollectionMap(collectionMap
) {
53 ProgramCollectionBuilder::~ProgramCollectionBuilder() {
56 void ProgramCollectionBuilder::startElementHandler(const char *tag
, const char **attributes
) {
58 const char *name
= attributeValue(attributes
, "name");
60 myCurrentCollection
= myCollectionMap
.myMap
[name
];
61 if (myCurrentCollection
.isNull()) {
62 myCurrentCollection
= new ProgramCollection(name
);
63 myCollectionMap
.myMap
[name
] = myCurrentCollection
;
66 } else if (!myCurrentCollection
.isNull() && (PROGRAM
== tag
)) {
67 const char *name
= attributeValue(attributes
, "name");
68 const char *protocol
= attributeValue(attributes
, "protocol");
69 const char *testFile
= attributeValue(attributes
, "testFile");
70 if ((name
!= 0) && (protocol
!= 0)) {
71 shared_ptr
<ZLMessageOutputChannel
> channel
=
72 ZLCommunicationManager::instance().createMessageOutputChannel(protocol
, (testFile
!= 0) ? testFile
: "");
73 if (!channel
.isNull()) {
74 std::string sName
= name
;
76 if (sName
[0] == '%') {
77 sName
= ZLResource::resource("external")[sName
.substr(1)].value();
79 myCurrentProgram
= new Program(sName
, channel
);
80 myCurrentCollection
->myNames
.push_back(sName
);
81 myCurrentCollection
->myPrograms
[sName
] = myCurrentProgram
;
85 } else if (!myCurrentProgram
.isNull() && (ACTION
== tag
)) {
86 const char *name
= attributeValue(attributes
, "name");
88 static const std::string NAME
= "name";
89 ZLCommunicationManager::Data
&data
= myCurrentProgram
->myCommandData
[name
];
90 for (const char **it
= attributes
; (*it
!= 0) && (*(it
+ 1) != 0); it
+= 2) {
92 data
[*it
] = *(it
+ 1);
96 } else if (!myCurrentProgram
.isNull() && (OPTION
== tag
)) {
97 const char *name
= attributeValue(attributes
, "name");
99 const char *defaultValue
= attributeValue(attributes
, "defaultValue");
100 const std::string sName
= name
;
101 const std::string sDefaultValue
= (defaultValue
!= 0) ? defaultValue
: std::string();
102 myCurrentProgram
->myOptions
.push_back(Program::OptionDescription(sName
, sDefaultValue
));
103 myCurrentProgram
->myDefaultValues
[sName
] = sDefaultValue
;
108 void ProgramCollectionBuilder::endElementHandler(const char *tag
) {
109 if (SECTION
== tag
) {
110 if (!myCurrentCollection
.isNull()) {
111 const std::vector
<std::string
> &names
= myCurrentCollection
->names();
112 ZLStringOption
&nameOption
= myCurrentCollection
->CurrentNameOption
;
113 if (!names
.empty() && (std::find(names
.begin(), names
.end(), nameOption
.value()) == names
.end())) {
114 nameOption
.setValue(names
.front());
117 myCurrentCollection
= 0;
118 myCurrentProgram
= 0;
119 } else if (PROGRAM
== tag
) {
120 myCurrentProgram
= 0;
124 ProgramCollectionMap::ProgramCollectionMap() {
125 ProgramCollectionBuilder
builder(*this);
126 builder
.readDocument(ZLibrary::DefaultFilesPathPrefix() + "external.xml");
129 shared_ptr
<ProgramCollection
> ProgramCollectionMap::collection(const std::string
&name
) const {
130 std::map
<std::string
,shared_ptr
<ProgramCollection
> >::const_iterator it
= myMap
.find(name
);
131 return (it
!= myMap
.end()) ? it
->second
: 0;
134 ProgramCollection::ProgramCollection(const std::string
&name
) :
135 EnableCollectionOption(ZLCategoryKey::CONFIG
, name
, "Enabled", true),
136 CurrentNameOption(ZLCategoryKey::CONFIG
, name
, "Name", "") {
139 const std::vector
<std::string
> &ProgramCollection::names() const {
143 shared_ptr
<Program
> ProgramCollection::program(const std::string
&name
) const {
144 std::map
<std::string
,shared_ptr
<Program
> >::const_iterator it
= myPrograms
.find(name
);
145 return (it
!= myPrograms
.end()) ? it
->second
: 0;
148 shared_ptr
<Program
> ProgramCollection::currentProgram() const {
149 if (!EnableCollectionOption
.value()) {
152 return program(CurrentNameOption
.value());
155 Program::Program(const std::string
&name
, shared_ptr
<ZLMessageOutputChannel
> channel
) : myName(name
), myChannel(channel
) {
158 void Program::run(const std::string
&command
, const std::string
¶meter
) const {
159 if (!myChannel
.isNull()) {
160 std::map
<std::string
,ZLCommunicationManager::Data
>::const_iterator it
= myCommandData
.find(command
);
161 if (it
!= myCommandData
.end()) {
162 ZLCommunicationManager::Data data
= it
->second
;
163 for (ZLCommunicationManager::Data::iterator jt
= data
.begin(); jt
!= data
.end(); ++jt
) {
164 if (!jt
->second
.empty() && jt
->second
[0] == '%') {
165 const std::string optionName
= jt
->second
.substr(1);
166 std::map
<std::string
,std::string
>::const_iterator st
= myDefaultValues
.find(optionName
);
167 jt
->second
= ZLStringOption(
168 FBCategoryKey::EXTERNAL
,
171 (st
!= myDefaultValues
.end()) ? st
->second
: "").value();
174 shared_ptr
<ZLMessageSender
> sender
= myChannel
->createSender(data
);
175 if (!sender
.isNull()) {
176 sender
->sendStringMessage(parameter
);
182 const std::vector
<Program::OptionDescription
> &Program::options() const {
186 Program::OptionDescription::OptionDescription(const std::string
&name
, const std::string
&defaultValue
) : OptionName(name
), DefaultValue(defaultValue
) {