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
output(ostream & o,const string & sIndent) const174 ostream & XMLTag::output(ostream & o, const string & sIndent) const
175 {
176 bool bHasContent = mChars.size() > 0 || mTags.size() > 0;
177
178 if (mMode == START || mMode == COMPLETE)
179 {
180 o << sIndent << "<" << mTag;
181
182 XMLAttributes_t::const_iterator aItAttrs(mAttrs.begin());
183 while (aItAttrs != mAttrs.end())
184 {
185 o << " " << aItAttrs->mName << "=\""
186 << xmlify(aItAttrs->mValue)
187 << "\"";
188
189 aItAttrs++;
190 }
191
192 if (bHasContent)
193 {
194 o << ">";
195
196 string sNewIndent = sIndent + " ";
197 XMLTags_t::const_iterator aItTags(mTags.begin());
198 while (aItTags != mTags.end())
199 {
200 if (aItTags == mTags.begin())
201 o << endl;
202
203 (*aItTags)->output(o, sNewIndent);
204 aItTags++;
205 }
206
207 o << mChars;
208 }
209 }
210
211 if (mMode == END || mMode == COMPLETE)
212 {
213 if (bHasContent)
214 {
215 if (mTags.size() > 0)
216 o << sIndent;
217
218 o << "</" << mTag << ">" << endl;
219 }
220 else
221 o << "/>" << endl;
222 }
223
224 return o;
225 }
226
227 typedef hash_map< const char*, TagLogger::Pointer_t, rtl::CStringHash, rtl::CStringEqual> TagLoggerHashMap_t;
228 static TagLoggerHashMap_t * tagLoggers = NULL;
229
TagLogger()230 TagLogger::TagLogger()
231 : mFileName("writerfilter")
232 {
233 }
234
~TagLogger()235 TagLogger::~TagLogger()
236 {
237 }
238
setFileName(const string & rName)239 void TagLogger::setFileName(const string & rName)
240 {
241 mFileName = rName;
242 }
243
getInstance(const char * name)244 TagLogger::Pointer_t TagLogger::getInstance(const char * name)
245 {
246 if (tagLoggers == NULL)
247 tagLoggers = new TagLoggerHashMap_t();
248
249 TagLoggerHashMap_t::iterator aIt = tagLoggers->end();
250
251 if (! tagLoggers->empty())
252 aIt = tagLoggers->find(name);
253
254 if (aIt == tagLoggers->end())
255 {
256 TagLogger::Pointer_t pTagLogger(new TagLogger());
257 pair<const char *, TagLogger::Pointer_t> entry(name, pTagLogger);
258 aIt = tagLoggers->insert(entry).first;
259 }
260
261 return aIt->second;
262 }
263
currentTag() const264 XMLTag::Pointer_t TagLogger::currentTag() const
265 {
266 bool bEmpty=mTags.empty();
267 if (!bEmpty)
268 return mTags.top();
269
270 return XMLTag::NIL;
271 }
272
startDocument()273 void TagLogger::startDocument()
274 {
275 XMLTag::Pointer_t pTag(new XMLTag("root"));
276 mTags.push(pTag);
277 mpRoot = pTag;
278 }
279
element(const string & name)280 void TagLogger::element(const string & name)
281 {
282 startElement(name);
283 endElement(name);
284 }
285
startElement(const string & name)286 void TagLogger::startElement(const string & name)
287 {
288 XMLTag::Pointer_t pTag(new XMLTag(name));
289 currentTag()->addTag(pTag);
290 mTags.push(pTag);
291 }
292
attribute(const string & name,const string & value)293 void TagLogger::attribute(const string & name, const string & value)
294 {
295 currentTag()->addAttr(name, value);
296 }
297
attribute(const string & name,const::rtl::OUString & value)298 void TagLogger::attribute(const string & name, const ::rtl::OUString & value)
299 {
300 currentTag()->addAttr(name, value);
301 }
302
attribute(const string & name,sal_uInt32 value)303 void TagLogger::attribute(const string & name, sal_uInt32 value)
304 {
305 currentTag()->addAttr(name, value);
306 }
307
attribute(const string & name,const uno::Any aAny)308 void TagLogger::attribute(const string & name, const uno::Any aAny)
309 {
310 currentTag()->addAttr(name, aAny);
311 }
312
addTag(XMLTag::Pointer_t pTag)313 void TagLogger::addTag(XMLTag::Pointer_t pTag)
314 {
315 currentTag()->addTag(pTag);
316 }
317
chars(const string & rChars)318 void TagLogger::chars(const string & rChars)
319 {
320 currentTag()->chars(xmlify(rChars));
321 }
322
chars(const::rtl::OUString & rChars)323 void TagLogger::chars(const ::rtl::OUString & rChars)
324 {
325 chars(OUStringToOString(rChars, RTL_TEXTENCODING_ASCII_US).getStr());
326 }
327
endElement(const string & name)328 void TagLogger::endElement(const string & name)
329 {
330 string nameRemoved = currentTag()->getTag();
331
332 if (name == nameRemoved)
333 mTags.pop();
334 else {
335 XMLTag::Pointer_t pTag(new XMLTag("end.mismatch"));
336 pTag->addAttr("name", name);
337 pTag->addAttr("top", nameRemoved);
338
339 currentTag()->addTag(pTag);
340 }
341
342 }
343
endDocument()344 void TagLogger::endDocument()
345 {
346 mTags.pop();
347 }
348
output(ostream & o) const349 ostream & TagLogger::output(ostream & o) const
350 {
351 return mpRoot->output(o);
352 }
353
dump(const char * name)354 void TagLogger::dump(const char * name)
355 {
356 TagLoggerHashMap_t::iterator aIt(tagLoggers->find(name));
357 if (aIt != tagLoggers->end())
358 {
359 string fileName;
360 char * temp = getenv("TAGLOGGERTMP");
361
362 if (temp != NULL)
363 fileName += temp;
364 else
365 fileName += "/tmp";
366
367 string sPrefix = aIt->second->mFileName;
368 size_t nLastSlash = sPrefix.find_last_of('/');
369 size_t nLastBackslash = sPrefix.find_last_of('\\');
370 size_t nCutPos = nLastSlash;
371 if (nLastBackslash < nCutPos)
372 nCutPos = nLastBackslash;
373 if (nCutPos < sPrefix.size())
374 sPrefix = sPrefix.substr(nCutPos + 1);
375
376 fileName += "/";
377 fileName += sPrefix;
378 fileName +=".";
379 fileName += name;
380 fileName += ".xml";
381
382 ofstream dumpStream(fileName.c_str());
383 aIt->second->output(dumpStream);
384 }
385 }
386
PropertySetToTagHandler(IdToString::Pointer_t pIdToString)387 PropertySetToTagHandler::PropertySetToTagHandler(IdToString::Pointer_t pIdToString)
388 : mpTag(new XMLTag("propertyset")), mpIdToString(pIdToString)
389 {
390 }
391
~PropertySetToTagHandler()392 PropertySetToTagHandler::~PropertySetToTagHandler()
393 {
394 }
395
resolve(XMLTag & rTag,writerfilter::Reference<Properties>::Pointer_t pProps)396 void PropertySetToTagHandler::resolve
397 (XMLTag & rTag, writerfilter::Reference<Properties>::Pointer_t pProps)
398 {
399 if (pProps.get() != NULL)
400 {
401 PropertySetToTagHandler aHandler(mpIdToString);
402 pProps->resolve(aHandler);
403 rTag.addTag(aHandler.getTag());
404 }
405 }
406
attribute(Id name,Value & val)407 void PropertySetToTagHandler::attribute(Id name, Value & val)
408 {
409 XMLTag::Pointer_t pTag(new XMLTag("attribute"));
410
411 pTag->addAttr("name", (*QNameToString::Instance())(name));
412 pTag->addAttr("value", val.toString());
413
414 resolve(*pTag, val.getProperties());
415
416 mpTag->addTag(pTag);
417 }
418
sprm(Sprm & rSprm)419 void PropertySetToTagHandler::sprm(Sprm & rSprm)
420 {
421 XMLTag::Pointer_t pTag(new XMLTag("sprm"));
422
423 string sName;
424
425 if (mpIdToString != IdToString::Pointer_t())
426 sName = mpIdToString->toString(rSprm.getId());
427
428 pTag->addAttr("name", sName);
429
430 static char sBuffer[256];
431 snprintf(sBuffer, sizeof(sBuffer),
432 "0x%" SAL_PRIxUINT32 ", %" SAL_PRIuUINT32, rSprm.getId(),
433 rSprm.getId());
434 pTag->addAttr("id", sBuffer);
435 pTag->addAttr("value", rSprm.getValue()->toString());
436
437 resolve(*pTag, rSprm.getProps());
438
439 mpTag->addTag(pTag);
440 }
441
442
unoPropertySetToTag(uno::Reference<beans::XPropertySet> rPropSet)443 XMLTag::Pointer_t unoPropertySetToTag(uno::Reference<beans::XPropertySet> rPropSet)
444 {
445 uno::Reference<beans::XPropertySetInfo> xPropSetInfo(rPropSet->getPropertySetInfo());
446 uno::Sequence<beans::Property> aProps(xPropSetInfo->getProperties());
447
448 XMLTag::Pointer_t pResult(new XMLTag("unoPropertySet"));
449
450 for (int i = 0; i < aProps.getLength(); ++i)
451 {
452 XMLTag::Pointer_t pPropTag(new XMLTag("property"));
453
454 ::rtl::OUString sName(aProps[i].Name);
455
456 pPropTag->addAttr("name", sName);
457 try
458 {
459 pPropTag->addAttr("value", rPropSet->getPropertyValue(sName));
460 }
461 catch (uno::Exception aException)
462 {
463 XMLTag::Pointer_t pException(new XMLTag("exception"));
464
465 pException->chars("getPropertyValue(\"");
466 pException->chars(sName);
467 pException->chars("\")");
468 pPropTag->addTag(pException);
469 }
470
471 pResult->addTag(pPropTag);
472 }
473
474 return pResult;
475 }
476
477 }
478