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