1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 #include <fstream>
25 #include <string.h>
26 #include <resourcemodel/TagLogger.hxx>
27 #include <resourcemodel/util.hxx>
28 #include <resourcemodel/QNameToString.hxx>
29
30 namespace writerfilter
31 {
32 XMLTag::Pointer_t XMLTag::NIL(new XMLTag("NIL"));
33
addAttr(string sName,string sValue)34 void XMLTag::addAttr(string sName, string sValue)
35 {
36 XMLAttribute aAttr(sName, sValue);
37
38 mAttrs.push_back(aAttr);
39 }
40
addAttr(string sName,const::rtl::OUString & sValue)41 void XMLTag::addAttr(string sName, const ::rtl::OUString & sValue)
42 {
43 addAttr(sName,
44 OUStringToOString
45 (sValue, RTL_TEXTENCODING_ASCII_US).getStr());
46 }
47
addAttr(string sName,sal_uInt32 nValue)48 void XMLTag::addAttr(string sName, sal_uInt32 nValue)
49 {
50 static char buffer[256];
51 snprintf(buffer, sizeof(buffer), "%" SAL_PRIdINT32, nValue);
52 addAttr(sName, buffer);
53 }
54
addAttr(string sName,uno::Any aAny)55 void XMLTag::addAttr(string sName, uno::Any aAny)
56 {
57 string aTmpStrInt;
58 string aTmpStrFloat;
59 string aTmpStrString;
60
61 static char buffer[256];
62
63 try
64 {
65 sal_Int32 nInt = 0;
66 aAny >>= nInt;
67
68 snprintf(buffer, sizeof(buffer), "%" SAL_PRIdINT32,
69 nInt);
70
71 aTmpStrInt = buffer;
72 }
73 catch (uno::Exception aExcept)
74 {
75 aTmpStrInt = "exception";
76 }
77
78 try
79 {
80 float nFloat = 0.0;
81 aAny >>= nFloat;
82
83 snprintf(buffer, sizeof(buffer), "%f",
84 nFloat);
85
86 aTmpStrFloat = buffer;
87 }
88 catch (uno::Exception aExcept)
89 {
90 aTmpStrFloat = "exception";
91 }
92
93 try
94 {
95 ::rtl::OUString aStr;
96 aAny >>= aStr;
97
98 aTmpStrString = OUStringToOString(aStr, RTL_TEXTENCODING_ASCII_US).getStr();
99 }
100 catch (uno::Exception aExcept)
101 {
102 aTmpStrString = "exception";
103 }
104
105 addAttr(sName, "i:" + aTmpStrInt + " f:" + aTmpStrFloat + " s:" +
106 aTmpStrString);
107 }
108
addTag(XMLTag::Pointer_t pTag)109 void XMLTag::addTag(XMLTag::Pointer_t pTag)
110 {
111 if (pTag != XMLTag::Pointer_t())
112 mTags.push_back(pTag);
113 }
114
chars(const string & rChars)115 void XMLTag::chars(const string & rChars)
116 {
117 mChars += rChars;
118 }
119
chars(const::rtl::OUString & rChars)120 void XMLTag::chars(const ::rtl::OUString & rChars)
121 {
122 chars(OUStringToOString(rChars, RTL_TEXTENCODING_ASCII_US).getStr());
123 }
124
getTag() const125 const string & XMLTag::getTag() const
126 {
127 return mTag;
128 }
129
toString() const130 string XMLTag::toString() const
131 {
132 if (mChars.length() > 0)
133 return mChars;
134
135 string sResult;
136
137 if (mMode == START || mMode == COMPLETE)
138 {
139 sResult += "<" + mTag;
140
141 XMLAttributes_t::const_iterator aIt = mAttrs.begin();
142 while (aIt != mAttrs.end())
143 {
144 sResult += " ";
145 sResult += aIt->mName;
146 sResult += "=\"";
147 sResult += xmlify(aIt->mValue);
148 sResult += "\"";
149
150 aIt++;
151 }
152
153 sResult +=">";
154
155 if (mTags.size() > 0)
156 {
157 XMLTags_t::const_iterator aItTags = mTags.begin();
158 while (aItTags != mTags.end())
159 {
160 if ((*aItTags).get() != NULL)
161 sResult += (*aItTags)->toString();
162
163 aItTags++;
164 }
165 }
166 }
167
168 if (mMode == END || mMode == COMPLETE)
169 sResult += "</" + mTag + ">";
170
171 return sResult;
172 }
173
toTree(const string & sIndent) const174 string XMLTag::toTree(const string & sIndent) const
175 {
176 if (mChars.length() > 0)
177 return sIndent + mChars;
178
179 string sResult;
180
181 {
182 size_t nSize = sIndent.size();
183 if (nSize > 1)
184 {
185 sResult += sIndent.substr(0, nSize - 2) + "+-\\" + mTag;
186 }
187 else
188 {
189 sResult += "\\" + mTag;
190 }
191 }
192
193 XMLAttributes_t::const_iterator aIt = mAttrs.begin();
194 while (aIt != mAttrs.end())
195 {
196 if (aIt == mAttrs.begin())
197 {
198 sResult += "(";
199 }
200 else
201 {
202 sResult += sIndent + ", ";
203 }
204
205 sResult += aIt->mName;
206 sResult += "=";
207 sResult += aIt->mValue;
208
209 aIt++;
210
211 if (aIt == mAttrs.end())
212 {
213 sResult += ")";
214 }
215 }
216
217 sResult += "\n";
218
219 if (mTags.size() > 0)
220 {
221 XMLTags_t::const_iterator aItTags = mTags.begin();
222 size_t nSize = mTags.size();
223 while (aItTags != mTags.end())
224 {
225 if ((*aItTags).get() != NULL)
226 {
227 if (nSize == 1)
228 {
229 sResult += (*aItTags)->toTree(sIndent + " ");
230 }
231 else
232 {
233 sResult += (*aItTags)->toTree(sIndent + "| ");
234 }
235 }
236
237 aItTags++;
238 nSize--;
239 }
240 }
241
242 return sResult;
243 }
244
output(ostream & o,const string & sIndent) const245 ostream & XMLTag::output(ostream & o, const string & sIndent) const
246 {
247 bool bHasContent = mChars.size() > 0 || mTags.size() > 0;
248
249 if (mMode == START || mMode == COMPLETE)
250 {
251 o << sIndent << "<" << mTag;
252
253 XMLAttributes_t::const_iterator aItAttrs(mAttrs.begin());
254 while (aItAttrs != mAttrs.end())
255 {
256 o << " " << aItAttrs->mName << "=\""
257 << xmlify(aItAttrs->mValue)
258 << "\"";
259
260 aItAttrs++;
261 }
262
263 if (bHasContent)
264 {
265 o << ">";
266
267 string sNewIndent = sIndent + " ";
268 XMLTags_t::const_iterator aItTags(mTags.begin());
269 while (aItTags != mTags.end())
270 {
271 if (aItTags == mTags.begin())
272 o << endl;
273
274 (*aItTags)->output(o, sNewIndent);
275 aItTags++;
276 }
277
278 o << mChars;
279 }
280 }
281
282 if (mMode == END || mMode == COMPLETE)
283 {
284 if (bHasContent)
285 {
286 if (mTags.size() > 0)
287 o << sIndent;
288
289 o << "</" << mTag << ">" << endl;
290 }
291 else
292 o << "/>" << endl;
293 }
294
295 return o;
296 }
297
298 typedef hash_map< const char*, TagLogger::Pointer_t, rtl::CStringHash, rtl::CStringEqual> TagLoggerHashMap_t;
299 static TagLoggerHashMap_t * tagLoggers = NULL;
300
TagLogger()301 TagLogger::TagLogger()
302 : mFileName("writerfilter")
303 {
304 }
305
~TagLogger()306 TagLogger::~TagLogger()
307 {
308 }
309
setFileName(const string & rName)310 void TagLogger::setFileName(const string & rName)
311 {
312 mFileName = rName;
313 }
314
getInstance(const char * name)315 TagLogger::Pointer_t TagLogger::getInstance(const char * name)
316 {
317 if (tagLoggers == NULL)
318 tagLoggers = new TagLoggerHashMap_t();
319
320 TagLoggerHashMap_t::iterator aIt = tagLoggers->end();
321
322 if (! tagLoggers->empty())
323 aIt = tagLoggers->find(name);
324
325 if (aIt == tagLoggers->end())
326 {
327 TagLogger::Pointer_t pTagLogger(new TagLogger());
328 pair<const char *, TagLogger::Pointer_t> entry(name, pTagLogger);
329 aIt = tagLoggers->insert(entry).first;
330 }
331
332 return aIt->second;
333 }
334
currentTag() const335 XMLTag::Pointer_t TagLogger::currentTag() const
336 {
337 bool bEmpty=mTags.empty();
338 if (!bEmpty)
339 return mTags.top();
340
341 return XMLTag::NIL;
342 }
343
startDocument()344 void TagLogger::startDocument()
345 {
346 XMLTag::Pointer_t pTag(new XMLTag("root"));
347 mTags.push(pTag);
348 mpRoot = pTag;
349 }
350
element(const string & name)351 void TagLogger::element(const string & name)
352 {
353 startElement(name);
354 endElement(name);
355 }
356
startElement(const string & name)357 void TagLogger::startElement(const string & name)
358 {
359 XMLTag::Pointer_t pTag(new XMLTag(name));
360 currentTag()->addTag(pTag);
361 mTags.push(pTag);
362 }
363
attribute(const string & name,const string & value)364 void TagLogger::attribute(const string & name, const string & value)
365 {
366 currentTag()->addAttr(name, value);
367 }
368
attribute(const string & name,const::rtl::OUString & value)369 void TagLogger::attribute(const string & name, const ::rtl::OUString & value)
370 {
371 currentTag()->addAttr(name, value);
372 }
373
attribute(const string & name,sal_uInt32 value)374 void TagLogger::attribute(const string & name, sal_uInt32 value)
375 {
376 currentTag()->addAttr(name, value);
377 }
378
attribute(const string & name,const uno::Any aAny)379 void TagLogger::attribute(const string & name, const uno::Any aAny)
380 {
381 currentTag()->addAttr(name, aAny);
382 }
383
addTag(XMLTag::Pointer_t pTag)384 void TagLogger::addTag(XMLTag::Pointer_t pTag)
385 {
386 currentTag()->addTag(pTag);
387 }
388
chars(const string & rChars)389 void TagLogger::chars(const string & rChars)
390 {
391 currentTag()->chars(xmlify(rChars));
392 }
393
chars(const::rtl::OUString & rChars)394 void TagLogger::chars(const ::rtl::OUString & rChars)
395 {
396 chars(OUStringToOString(rChars, RTL_TEXTENCODING_ASCII_US).getStr());
397 }
398
endElement(const string & name)399 void TagLogger::endElement(const string & name)
400 {
401 string nameRemoved = currentTag()->getTag();
402
403 if (name == nameRemoved)
404 mTags.pop();
405 else {
406 XMLTag::Pointer_t pTag(new XMLTag("end.mismatch"));
407 pTag->addAttr("name", name);
408 pTag->addAttr("top", nameRemoved);
409
410 currentTag()->addTag(pTag);
411 }
412
413 }
414
endDocument()415 void TagLogger::endDocument()
416 {
417 mTags.pop();
418 }
419
output(ostream & o) const420 ostream & TagLogger::output(ostream & o) const
421 {
422 return mpRoot->output(o);
423 }
424
dump(const char * name)425 void TagLogger::dump(const char * name)
426 {
427 TagLoggerHashMap_t::iterator aIt(tagLoggers->find(name));
428 if (aIt != tagLoggers->end())
429 {
430 string fileName;
431 char * temp = getenv("TAGLOGGERTMP");
432
433 if (temp != NULL)
434 fileName += temp;
435 else
436 fileName += "/tmp";
437
438 string sPrefix = aIt->second->mFileName;
439 size_t nLastSlash = sPrefix.find_last_of('/');
440 size_t nLastBackslash = sPrefix.find_last_of('\\');
441 size_t nCutPos = nLastSlash;
442 if (nLastBackslash < nCutPos)
443 nCutPos = nLastBackslash;
444 if (nCutPos < sPrefix.size())
445 sPrefix = sPrefix.substr(nCutPos + 1);
446
447 fileName += "/";
448 fileName += sPrefix;
449 fileName +=".";
450 fileName += name;
451 fileName += ".xml";
452
453 ofstream dumpStream(fileName.c_str());
454 aIt->second->output(dumpStream);
455 }
456 }
457
PropertySetToTagHandler(IdToString::Pointer_t pIdToString)458 PropertySetToTagHandler::PropertySetToTagHandler(IdToString::Pointer_t pIdToString)
459 : mpTag(new XMLTag("propertyset")), mpIdToString(pIdToString)
460 {
461 }
462
~PropertySetToTagHandler()463 PropertySetToTagHandler::~PropertySetToTagHandler()
464 {
465 }
466
resolve(XMLTag & rTag,writerfilter::Reference<Properties>::Pointer_t pProps)467 void PropertySetToTagHandler::resolve
468 (XMLTag & rTag, writerfilter::Reference<Properties>::Pointer_t pProps)
469 {
470 if (pProps.get() != NULL)
471 {
472 PropertySetToTagHandler aHandler(mpIdToString);
473 pProps->resolve(aHandler);
474 rTag.addTag(aHandler.getTag());
475 }
476 }
477
attribute(Id name,Value & val)478 void PropertySetToTagHandler::attribute(Id name, Value & val)
479 {
480 XMLTag::Pointer_t pTag(new XMLTag("attribute"));
481
482 pTag->addAttr("name", (*QNameToString::Instance())(name));
483 pTag->addAttr("value", val.toString());
484
485 resolve(*pTag, val.getProperties());
486
487 mpTag->addTag(pTag);
488 }
489
sprm(Sprm & rSprm)490 void PropertySetToTagHandler::sprm(Sprm & rSprm)
491 {
492 XMLTag::Pointer_t pTag(new XMLTag("sprm"));
493
494 string sName;
495
496 if (mpIdToString != IdToString::Pointer_t())
497 sName = mpIdToString->toString(rSprm.getId());
498
499 pTag->addAttr("name", sName);
500
501 static char sBuffer[256];
502 snprintf(sBuffer, sizeof(sBuffer),
503 "0x%" SAL_PRIxUINT32 ", %" SAL_PRIuUINT32, rSprm.getId(),
504 rSprm.getId());
505 pTag->addAttr("id", sBuffer);
506 pTag->addAttr("value", rSprm.getValue()->toString());
507
508 resolve(*pTag, rSprm.getProps());
509
510 mpTag->addTag(pTag);
511 }
512
513
unoPropertySetToTag(uno::Reference<beans::XPropertySet> rPropSet)514 XMLTag::Pointer_t unoPropertySetToTag(uno::Reference<beans::XPropertySet> rPropSet)
515 {
516 uno::Reference<beans::XPropertySetInfo> xPropSetInfo(rPropSet->getPropertySetInfo());
517 uno::Sequence<beans::Property> aProps(xPropSetInfo->getProperties());
518
519 XMLTag::Pointer_t pResult(new XMLTag("unoPropertySet"));
520
521 for (int i = 0; i < aProps.getLength(); ++i)
522 {
523 XMLTag::Pointer_t pPropTag(new XMLTag("property"));
524
525 ::rtl::OUString sName(aProps[i].Name);
526
527 pPropTag->addAttr("name", sName);
528 try
529 {
530 pPropTag->addAttr("value", rPropSet->getPropertyValue(sName));
531 }
532 catch (uno::Exception aException)
533 {
534 XMLTag::Pointer_t pException(new XMLTag("exception"));
535
536 pException->chars("getPropertyValue(\"");
537 pException->chars(sName);
538 pException->chars("\")");
539 pPropTag->addTag(pException);
540 }
541
542 pResult->addTag(pPropTag);
543 }
544
545 return pResult;
546 }
547
548 }
549