00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <pion/platform/ConfigManager.hpp>
00021 #include <pion/platform/ReactionEngine.hpp>
00022 #include "TransformReactor.hpp"
00023
00024 using namespace pion::platform;
00025
00026
00027 namespace pion {
00028 namespace plugins {
00029
00030
00031
00032
00033 const std::string TransformReactor::OUTGOING_EVENT_ELEMENT_NAME = "OutgoingEvent";
00034 const std::string TransformReactor::DELIVER_ORIGINAL_NAME = "DeliverOriginal";
00035 const std::string TransformReactor::COPY_ORIGINAL_ELEMENT_NAME = "CopyOriginal";
00036 const std::string TransformReactor::TRANSFORMATION_ELEMENT_NAME = "Transformation";
00037 const std::string TransformReactor::TERM_ELEMENT_NAME = "Term";
00038 const std::string TransformReactor::TYPE_ELEMENT_NAME = "Type";
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 void TransformReactor::setConfig(const Vocabulary& v, const xmlNodePtr config_ptr)
00106 {
00107
00108 ConfigWriteLock cfg_lock(*this);
00109 Reactor::setConfig(v, config_ptr);
00110
00111
00112 m_transforms.clear();
00113
00114
00115
00116
00117 m_event_type = Vocabulary::UNDEFINED_TERM_REF;
00118 std::string event_type_str;
00119 if (ConfigManager::getConfigOption(OUTGOING_EVENT_ELEMENT_NAME, event_type_str, config_ptr))
00120 {
00121 if (!event_type_str.empty())
00122 m_event_type = v.findTerm(event_type_str);
00123 }
00124
00125
00126
00127
00128 m_deliver_original = DO_NEVER;
00129 std::string deliver_original_str;
00130 if (ConfigManager::getConfigOption(DELIVER_ORIGINAL_NAME, deliver_original_str, config_ptr))
00131 {
00132 if (deliver_original_str == "true" || deliver_original_str == "always")
00133 m_deliver_original = DO_ALWAYS;
00134 else if (deliver_original_str == "if-not-changed")
00135 m_deliver_original = DO_SOMETIMES;
00136
00137 }
00138
00139
00140
00141 m_copy_original = COPY_UNCHANGED;
00142 std::string copy_original_str;
00143 if (ConfigManager::getConfigOption(COPY_ORIGINAL_ELEMENT_NAME, copy_original_str, config_ptr))
00144 {
00145 if (copy_original_str == "all-terms")
00146 m_copy_original = COPY_ALL;
00147 else if (copy_original_str == "none")
00148 m_copy_original = COPY_NONE;
00149
00150 }
00151
00152
00153
00154 xmlNodePtr transformation_node = config_ptr;
00155 while ( (transformation_node = ConfigManager::findConfigNodeByName(TRANSFORMATION_ELEMENT_NAME, transformation_node)) != NULL)
00156 {
00157
00158
00159
00160
00161 std::string term_id;
00162 if (! ConfigManager::getConfigOption(TERM_ELEMENT_NAME, term_id,
00163 transformation_node->children))
00164 throw EmptyTermException(getId());
00165
00166
00167 const Vocabulary::TermRef term_ref = v.findTerm(term_id);
00168 if (term_ref == Vocabulary::UNDEFINED_TERM_REF)
00169 throw UnknownTermException(getId());
00170
00171
00172
00173 std::string type_str;
00174 if (! ConfigManager::getConfigOption(TYPE_ELEMENT_NAME, type_str,
00175 transformation_node->children))
00176 throw EmptyTypeException(getId());
00177
00178
00179 Transform *new_transform;
00180 if (type_str == "AssignValue")
00181 new_transform = new TransformAssignValue(v, v[term_ref], transformation_node->children);
00182 else if (type_str == "AssignTerm")
00183 new_transform = new TransformAssignTerm(v, v[term_ref], transformation_node->children);
00184 else if (type_str == "Lookup")
00185 new_transform = new TransformLookup(v, v[term_ref], transformation_node->children);
00186 else if (type_str == "Rules")
00187 new_transform = new TransformRules(v, v[term_ref], transformation_node->children);
00188 else if (type_str == "Regex")
00189 new_transform = new TransformRegex(v, v[term_ref], transformation_node->children);
00190 else if (type_str == "SplitTerm")
00191 new_transform = new TransformSplitTerm(v, v[term_ref], transformation_node->children);
00192 else if (type_str == "JoinTerm")
00193 new_transform = new TransformJoinTerm(v, v[term_ref], transformation_node->children);
00194 else if (type_str == "URLEncode")
00195 new_transform = new TransformURLEncode(v, v[term_ref], transformation_node->children);
00196 else if (type_str == "URLDecode")
00197 new_transform = new TransformURLDecode(v, v[term_ref], transformation_node->children);
00198 else
00199 throw InvalidTransformation(type_str);
00200
00201 m_transforms.push_back(new_transform);
00202
00203
00204 transformation_node = transformation_node->next;
00205 }
00206 }
00207
00208 void TransformReactor::updateVocabulary(const Vocabulary& v)
00209 {
00210
00211 ConfigWriteLock cfg_lock(*this);
00212 Reactor::updateVocabulary(v);
00213
00214
00215 for (TransformChain::iterator i = m_transforms.begin(); i != m_transforms.end(); ++i) {
00216 (*i)->updateVocabulary(v);
00217 }
00218 }
00219
00220 void TransformReactor::process(const EventPtr& e)
00221 {
00222 EventPtr new_e;
00223
00224 m_event_factory.create(new_e, m_event_type == Vocabulary::UNDEFINED_TERM_REF ? e->getType() : m_event_type);
00225
00226
00227 switch (m_copy_original) {
00228 case COPY_ALL:
00229 *new_e += *e;
00230 break;
00231 case COPY_UNCHANGED:
00232 *new_e += *e;
00233
00234 for (TransformChain::iterator i = m_transforms.begin(); i != m_transforms.end(); i++)
00235 (*i)->removeTerm(new_e);
00236
00237 break;
00238 case COPY_NONE:
00239 break;
00240 }
00241
00242 try {
00243 for (TransformChain::iterator i = m_transforms.begin(); i != m_transforms.end(); i++)
00244 (*i)->transform(new_e, e);
00245 } catch (...) {
00246
00247 if (getReactionEngine().getDebugMode())
00248 stop();
00249 throw TransformFailureException(getId());
00250 }
00251
00252 deliverEvent(new_e);
00253
00254
00255 if (m_deliver_original != DO_NEVER)
00256 deliverEvent(e);
00257 }
00258
00259
00260 }
00261 }
00262
00263
00265 extern "C" PION_PLUGIN_API pion::platform::Reactor *pion_create_TransformReactor(void) {
00266 return new pion::plugins::TransformReactor();
00267 }
00268
00270 extern "C" PION_PLUGIN_API void pion_destroy_TransformReactor(pion::plugins::TransformReactor *reactor_ptr) {
00271 delete reactor_ptr;
00272 }