plugin code
[lbook_fbreader.git] / fbreader / src / external / ProgramCollection.cpp
blob113fd9a9ed5935a866c21b344f1da947a9b0358e
1 /*
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
17 * 02110-1301, USA.
20 #include <algorithm>
22 #include <ZLXMLReader.h>
23 #include <ZLibrary.h>
24 #include <ZLResource.h>
26 #include "ProgramCollection.h"
27 #include "../options/FBOptions.h"
29 class ProgramCollectionBuilder : public ZLXMLReader {
31 public:
32 ProgramCollectionBuilder(ProgramCollectionMap &collectionMap);
33 ~ProgramCollectionBuilder();
35 private:
36 void startElementHandler(const char *tag, const char **attributes);
37 void endElementHandler(const char *tag);
39 private:
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) {
57 if (SECTION == tag) {
58 const char *name = attributeValue(attributes, "name");
59 if (name != 0) {
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;
75 if (!sName.empty()) {
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");
87 if (name != 0) {
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) {
91 if (NAME != *it) {
92 data[*it] = *(it + 1);
96 } else if (!myCurrentProgram.isNull() && (OPTION == tag)) {
97 const char *name = attributeValue(attributes, "name");
98 if (name != 0) {
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 {
140 return myNames;
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()) {
150 return 0;
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 &parameter) 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,
169 myName,
170 optionName,
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 {
183 return myOptions;
186 Program::OptionDescription::OptionDescription(const std::string &name, const std::string &defaultValue) : OptionName(name), DefaultValue(defaultValue) {