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