1 /*-----------------------------------------------------------------------------
2 Name: XmlHandlerBase.cpp
3 Project: xmlBlaster.org
4 Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file
5 Comment: Default handling of Sax callbacks
6 -----------------------------------------------------------------------------*/
7
8 #ifndef _UTIL_XMLHANDLERBASE_C
9 #define _UTIL_XMLHANDLERBASE_C
10
11 #if defined(_WIN32)
12 #pragma warning(disable:4786)
13 #endif
14
15 #include <util/parser/XmlHandlerBase.h>
16 #include <util/StopParseException.h>
17 #include <util/XmlBlasterException.h>
18 #include <util/Global.h>
19 #include <util/StopWatch.h>
20 #include <util/lexical_cast.h>
21 #include <iostream>
22 #include <util/parser/ParserFactory.h>
23 #include <climits> // LONG_MAX
24
25
26 namespace org { namespace xmlBlaster { namespace util { namespace parser {
27
28 using namespace std;
29 using namespace org::xmlBlaster::util;
30 using namespace org::xmlBlaster::util::thread;
31
32 XmlHandlerBase::XmlHandlerBase(Global& global) :
33 ME("XmlHandlerBase"),
34 inAttribute_(false),
35 global_(global),
36 log_(global.getLog("org.xmlBlaster.util.xml")),
37 invocationMutex_()
38 {
39 doTrimStrings_ = true;
40 //if (log_.call()) log_.trace(ME, "Creating new XmlHandlerBase");
41 }
42
43 /**
44 * Used to initialize the parser
45 */
46 string XmlHandlerBase::getLocale()
47 {
48 // xerces defaults to "en_US";
49 locale_ = global_.getProperty().getStringProperty("xmlBlaster/locale", "de_DE.iso-8859-1");
50 return locale_;
51 }
52
53 void XmlHandlerBase::init(const string &xmlLiteral)
54 {
55 xmlLiteral_ = xmlLiteral;
56 if (xmlLiteral_.size() > 0) {
57 parse(xmlLiteral_);
58 }
59 }
60
61 /**
62 * Does the actual parsing
63 * @param xmlData Quality of service in XML notation
64 */
65 void XmlHandlerBase::parse(const string &xmlData)
66 {
67 log_.call(ME, "parse");
68 //if (log_.trace()) log_.trace(ME, string("parse content:'") + xmlData + string("'"));
69
70 StopWatch stopWatch;
71 I_Parser *parser = NULL;
72 try {
73 parser = ParserFactory::getFactory().createParser(global_, this);
74 }
75 catch (XmlBlasterException& ex) {
76 throw ex;
77 }
78 catch (std::exception e) {
79 throw XmlBlasterException(INTERNAL_UNKNOWN, ME + "::parse", string("ParserFactory: ") + e.what());
80 }
81 catch (...) {
82 throw XmlBlasterException(INTERNAL_UNKNOWN, ME + "::parse", string("ParserFactory: unknown exception"));
83 }
84
85 Lock lock(invocationMutex_);
86
87 try {
88 parser->parse(xmlData);
89 delete parser;
90 }
91 catch (StopParseException&) {
92 // If it does not work, it could be wrapped into SAXParseException
93 log_.error(ME, string("StopParseException: ") + "Parsing execution stopped half the way ");
94 if (log_.trace()) {
95 string help = XmlBlasterException::getStackTrace();
96 log_.plain(ME, help);
97 }
98 delete parser;
99 return;
100 }
101 catch (XmlBlasterException& ex) {
102 if (log_.trace()) log_.trace(ME, ex.getMessage() + ": " + xmlData); // Remove logging here
103 delete parser;
104 throw ex;
105 }
106 catch (const exception& err) {
107 delete parser;
108 throw XmlBlasterException(INTERNAL_UNKNOWN, ME + "::parse", string("parse: std::exception. message:") + err.what() + ": " + xmlData);
109 }
110 catch (const string& err) {
111 delete parser;
112 throw XmlBlasterException(INTERNAL_UNKNOWN, ME + "::parse", string("parse: exception-string. message:") + err + ": " + xmlData);
113 }
114 catch (const char* err) {
115 delete parser;
116 throw XmlBlasterException(INTERNAL_UNKNOWN, ME + "::parse", string("parse: exception-char*. message:") + err + ": " + xmlData);
117 }
118 catch (...) {
119 delete parser;
120 throw XmlBlasterException(INTERNAL_UNKNOWN, ME + "::parse", string("parse: unknown exception ...: ") + xmlData);
121 }
122 if (log_.trace()) log_.trace(ME, "Time used for parsing: " + stopWatch.nice());
123 }
124
125 /**
126 * This characters emulates the java version but keep in mind that it is
127 * not the virtual method inherited from DocumentHandler !!
128 */
129 void XmlHandlerBase::characters(const string &ch)
130 {
131 if (doTrimStrings_) {
132 if (inAttribute_)
133 attributeCharacter_ += trimmer_.trim(ch);
134 else
135 character_ += trimmer_.trim(ch);
136 }
137 else {
138 if (inAttribute_)
139 attributeCharacter_ += ch;
140 else
141 character_ += ch;
142 }
143 //if (log_.trace()) log_.trace(ME, string("characters, character:'") + character_ + string("'"));
144 }
145
146 void XmlHandlerBase::endCDATA()
147 {
148 if (inAttribute_)
149 attributeCharacter_ += "]]>";
150 else
151 character_ += "]]>";
152 doTrimStrings_ = true;
153 if (log_.trace()) log_.trace(ME, "end of cdata");
154 }
155
156 void XmlHandlerBase::startCDATA()
157 {
158 if (inAttribute_)
159 attributeCharacter_ += "<![CDATA[";
160 else
161 character_ += "<![CDATA[";
162 doTrimStrings_ = false;
163 if (log_.trace()) log_.trace(ME, "start of cdata");
164 }
165
166 void XmlHandlerBase::startDocument()
167 {
168 if (log_.trace()) log_.trace(ME, "startDocument");
169 }
170
171 void XmlHandlerBase::endDocument()
172 {
173 if (log_.trace()) log_.trace(ME, "endDocument");
174 }
175
176 void XmlHandlerBase::startElement(const string &name, const AttributeMap& attrs)
177 {
178 log_.warn(ME,"Please provide your startElement() impl. for: " + getStartElementAsString(name, attrs));
179 }
180
181 /** End element. */
182 void XmlHandlerBase::endElement(const string &/*name*/)
183 {
184 log_.warn(ME,"Please provide your endElement() impl.");
185 }
186
187 //
188 // ErrorHandler methods
189 //
190
191 /** Warning. */
192 void XmlHandlerBase::warning(const string &exTxt)
193 {
194 string txt = exTxt + xmlLiteral_;
195 log_.warn(ME+".warning()", txt);
196 }
197
198
199 /** Error. */
200 void XmlHandlerBase::error(const string &exTxt)
201 {
202 string txt = exTxt + xmlLiteral_;
203 log_.warn(ME+".error()", txt);
204 }
205
206
207 /** Fatal error. */
208 void XmlHandlerBase::fatalError(const string &exTxt)
209 {
210 string txt = exTxt + xmlLiteral_;
211 log_.warn(ME+".fatalError()", txt);
212 throw XmlBlasterException(INTERNAL_UNKNOWN, ME + "::parse", string("parse: fatalError exception. message:") + exTxt);
213 }
214
215 /**
216 * gets the attribute specified by 'name' in the attribute list specified by 'list'. The result is put in
217 * the 'value' argument which is passed by reference. It returns 'true' if the attribute was found in the
218 * specified attribute list or 'false' if it was not. In the later case, the value is untouched by this
219 * method.
220 */
221 bool XmlHandlerBase::getStringAttr(const AttributeMap& attrs, const string &name, string& value, bool doTrim) const
222 {
223 AttributeMap::const_iterator iter = attrs.find(name);
224 if (iter == attrs.end()) return false;
225 if (doTrim) {
226 value.assign(StringTrim::trim((*iter).second));
227 }
228 else value.assign((*iter).second);
229 return true;
230 }
231
232 /**
233 * gets the attribute specified by 'name' in the attribute list specified by 'list'. The result is put in
234 * the 'value' argument which is passed by reference. It returns 'true' if the attribute was found in the
235 * specified attribute list or 'false' if it was not. In the later case, the value is untouched by this
236 * method.
237 */
238 bool XmlHandlerBase::getIntAttr(const AttributeMap &attrs, const string &name, int& value) const
239 {
240 string buf;
241 bool ret = getStringAttr(attrs, name, buf);
242 if (ret) {
243 value = atoi(buf.c_str());
244 return true;
245 }
246 return false;
247 }
248
249 /**
250 * gets the attribute specified by 'name' in the attribute list specified by 'list'. The result is put in
251 * the 'value' argument which is passed by reference. It returns 'true' if the attribute was found in the
252 * specified attribute list or 'false' if it was not. In the later case, the value is untouched by this
253 * method.
254 */
255 bool XmlHandlerBase::getLongAttr(const AttributeMap &attrs, const string &name, long& value) const
256 {
257 string buf;
258 bool ret = getStringAttr(attrs, name, buf);
259 if (ret) {
260 value = atol(buf.c_str());
261 return true;
262 }
263 return false;
264 }
265
266 /**
267 * gets the attribute specified by 'name' in the attribute list specified by 'list'. The result is put in
268 * the 'value' argument which is passed by reference. It returns 'true' if the attribute was found in the
269 * specified attribute list or 'false' if it was not. In the later case, the value is untouched by this
270 * method.
271 */
272 bool XmlHandlerBase::getTimestampAttr(const AttributeMap& attrs, const string &name, Timestamp& value) const
273 {
274 string buf;
275 bool ret = getStringAttr(attrs, name, buf);
276 if (ret) {
277 // value = STRING_TO_TIMESTAMP(buf.c_str());
278 value = lexical_cast<Timestamp>(buf);
279 return true;
280 }
281 return false;
282 }
283
284 /**
285 * gets the attribute specified by 'name' in the attribute list specified by 'list'. The result is put in
286 * the 'value' argument which is passed by reference. It returns 'true' if the attribute was found in the
287 * specified attribute list or 'false' if it was not. In the later case, the value is untouched by this
288 * method.
289 */
290 bool XmlHandlerBase::getBoolAttr(const AttributeMap &attrs, const string &name, bool& value) const
291 {
292 string buf;
293 bool ret = getStringAttr(attrs, name, buf);
294 if (ret) {
295 value = lexical_cast<bool>(buf);
296 return true;
297 }
298 return false;
299 }
300
301
302 /**
303 * returns a value (usually from an attribute) as an integer
304 */
305 int XmlHandlerBase::getIntValue(const string &value) const
306 {
307 if (value.length() < 1) return 0;
308 try {
309 return lexical_cast<int>(value);
310 }
311 catch (...) {
312 cerr << "XmlHandlerBase:: Conversion from " << value << " to int failed" << endl;
313 }
314 return 0;
315 }
316
317 /**
318 * returns a value (usually from an attribute) as a long
319 */
320 long XmlHandlerBase::getLongValue(const string &value) const
321 {
322 if (value.length() < 1) return 0l;
323 try {
324 long long llvalue = lexical_cast<long long>(value);
325 if ( llvalue > LONG_MAX ) {
326 cerr << "XmlHandlerBase:: Conversion from " << value << " to long failed, using " << LONG_MAX << endl;
327 return LONG_MAX;
328 }
329 else if ( llvalue < LONG_MIN ) {
330 cerr << "XmlHandlerBase:: Conversion from " << value << " to long failed, using " << LONG_MIN << endl;
331 return LONG_MIN;
332 }
333 return (long)llvalue; //lexical_cast<long long>(value);
334 }
335 catch (...) {
336 cerr << "XmlHandlerBase:: Conversion from " << value << " to long failed, using 0L" << endl;
337 }
338 return 0l;
339 /*
340 try {
341 return lexical_cast<long>(value);
342 }
343 catch (...) {
344 cerr << "XmlHandlerBase:: Conversion from " << value << " to long failed" << endl;
345 }
346 return 0l;
347 */
348 }
349
350 /**
351 * returns a value (usually from an attribute) as a Timestamp
352 */
353 Timestamp XmlHandlerBase::getTimestampValue(const string &value) const
354 {
355 Timestamp ret = 0l;
356 try {
357 ret = lexical_cast<Timestamp>(value);
358 }
359 catch (...) {
360 cerr << "XmlHandlerBase:: Conversion from " << value << " to Timestamp failed" << endl;
361 }
362 return ret;
363 }
364
365 /**
366 * returns a value (usually from an attribute) as a bool
367 */
368 bool XmlHandlerBase::getBoolValue(const string &value) const
369 {
370 try {
371 return StringTrim::isTrue(value);
372 }
373 catch (...) {
374 cerr << "XmlHandlerBase:: Conversion from " << value << " to bool failed" << endl;
375 }
376 return false;
377 }
378
379 std::string XmlHandlerBase::getStartElementAsString(const std::string &name, const AttributeMap &attrMap)
380 {
381 string ret = string("<") + name + string(" ");
382 AttributeMap::const_iterator iter = attrMap.begin();
383 while (iter != attrMap.end()) {
384 ret += (*iter).first + string("='") + (*iter).second + string("' ");
385 iter++;
386 }
387 ret += string(">");
388 return ret;
389 }
390
391 #endif
392
393 }}}} // namespace
syntax highlighted by Code2HTML, v. 0.9.1