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 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_scripting.hxx"
26 
27 #ifdef _DEBUG
28 #include <stdio.h>
29 #endif
30 
31 #include "ScriptMetadataImporter.hxx"
32 
33 #include <osl/mutex.hxx>
34 
35 #include <com/sun/star/xml/sax/XParser.hpp>
36 #include <rtl/string.h>
37 #include <tools/diagnose_ex.h>
38 
39 #include <util/util.hxx>
40 
41 using namespace ::rtl;
42 using namespace ::com::sun::star;
43 using namespace ::com::sun::star::uno;
44 
45 namespace scripting_impl
46 {
47 //*************************************************************************
ScriptMetadataImporter(const Reference<XComponentContext> & xContext)48 ScriptMetadataImporter::ScriptMetadataImporter(
49     const Reference< XComponentContext > & xContext )
50     : m_xContext( xContext )
51 {
52     OSL_TRACE( "< ScriptMetadataImporter ctor called >\n" );
53     ms_localeDesc = new OUStringBuffer();
54 }
55 
56 //*************************************************************************
~ScriptMetadataImporter()57 ScriptMetadataImporter::~ScriptMetadataImporter() SAL_THROW( () )
58 {
59     OSL_TRACE( "< ScriptMetadataImporter dtor called >\n" );
60     delete ms_localeDesc;
61 }
62 
63 
64 //*************************************************************************
parseMetaData(Reference<io::XInputStream> const & xInput,const::rtl::OUString & parcelURI,InfoImpls_vec & io_ScriptDatas)65 void ScriptMetadataImporter::parseMetaData(
66     Reference< io::XInputStream > const & xInput,
67     const ::rtl::OUString & parcelURI,
68     InfoImpls_vec &  io_ScriptDatas )
69     throw ( xml::sax::SAXException, io::IOException, RuntimeException )
70 {
71 
72     ::osl::Guard< ::osl::Mutex > aGuard( m_mutex );
73 
74     mpv_ScriptDatas = &io_ScriptDatas;
75     mpv_ScriptDatas->clear();
76 
77     //Set the placeholder for the parcel URI
78     ms_parcelURI = parcelURI;
79 
80     //Get the parser service
81     ENSURE_OR_THROW( m_xContext.is(),
82         "ScriptMetadataImporter::parseMetaData: No context available" );
83 
84     Reference< lang::XMultiComponentFactory > xMgr( m_xContext->getServiceManager(), UNO_SET_THROW );
85 
86     Reference< xml::sax::XParser > xParser(
87         xMgr->createInstanceWithContext( OUString::createFromAscii( "com.sun.star.xml.sax.Parser" ), m_xContext ),
88         UNO_QUERY_THROW );
89 
90     // xxx todo: error handler, entity resolver omitted
91     // This class is the document handler for the parser
92     Reference< xml::sax::XDocumentHandler > t_smI( this );
93     xParser->setDocumentHandler( t_smI );
94 
95     //Set up the input for the parser, the XInputStream
96     xml::sax::InputSource source;
97     source.aInputStream = xInput;
98     source.sSystemId = OUSTR( "virtual file" );
99 
100     OSL_TRACE( "ScriptMetadataImporter: Start the parser\n" );
101 
102     try
103     {
104         xParser->parseStream( source );
105     }
106     catch ( xml::sax::SAXException & saxe )
107     {
108         OUString msg = OUString::createFromAscii(
109             "ScriptMetadata:Importer::parserMetaData SAXException" );
110         msg.concat( saxe.Message );
111         throw xml::sax::SAXException( msg, Reference< XInterface > (),
112             saxe.WrappedException );
113     }
114     catch ( io::IOException & ioe )
115     {
116         throw io::IOException( OUString::createFromAscii(
117             "ScriptMetadataImporter::parseMetaData IOException: " ) + ioe.Message,
118             Reference< XInterface > () );
119     }
120 
121 #ifdef _DEBUG
122     catch ( ... )
123     {
124         throw RuntimeException( OUString::createFromAscii(
125             "ScriptMetadataImporter::parseMetadata UnknownException: " ),
126             Reference< XInterface > () );
127     }
128 #endif
129 
130     OSL_TRACE( "ScriptMetadataImporter: Parser finished\n ");
131 
132     OSL_TRACE(  "ScriptMetadataImporter: vector size is %d\n",
133         mpv_ScriptDatas->size() );
134 }
135 
136 //*************************************************************************
137 // XExtendedDocumentHandler impl
startCDATA()138 void ScriptMetadataImporter::startCDATA()
139     throw ( xml::sax::SAXException, RuntimeException )
140 {
141     OSL_TRACE( "ScriptMetadataImporter: startCDATA()\n" );
142 }
143 
144 //*************************************************************************
endCDATA()145 void ScriptMetadataImporter::endCDATA()
146     throw ( RuntimeException )
147 {
148     OSL_TRACE( "ScriptMetadataImporter: endDATA()\n" );
149 }
150 
151 //*************************************************************************
comment(const::rtl::OUString & sComment)152 void ScriptMetadataImporter::comment( const ::rtl::OUString & sComment )
153     throw ( xml::sax::SAXException, RuntimeException )
154 {
155     OSL_TRACE( "ScriptMetadataImporter: comment()\n" );
156 }
157 
158 //*************************************************************************
allowLineBreak()159 void ScriptMetadataImporter::allowLineBreak()
160     throw ( xml::sax::SAXException, RuntimeException )
161 {
162     OSL_TRACE( "ScriptMetadataImporter: allowLineBreak()\n" );
163 }
164 
165 //*************************************************************************
unknown(const::rtl::OUString & sString)166 void ScriptMetadataImporter::unknown( const ::rtl::OUString & sString )
167     throw ( xml::sax::SAXException, RuntimeException )
168 {
169     OSL_TRACE( "ScriptMetadataImporter: unknown()\n" );
170 }
171 
172 //*************************************************************************
173 // XDocumentHandler impl
startDocument()174 void ScriptMetadataImporter::startDocument()
175     throw ( xml::sax::SAXException, RuntimeException )
176 {
177     // Ignore for now
178     OSL_TRACE( "ScriptMetadataImporter: startDocument()\n" );
179 }
180 
181 //*************************************************************************
endDocument()182 void ScriptMetadataImporter::endDocument()
183     throw ( xml::sax::SAXException, RuntimeException )
184 {
185     // Ignore for now
186     OSL_TRACE( "ScriptMetadataImporter: endDocument()\n" );
187 }
188 
189 //*************************************************************************
startElement(const::rtl::OUString & tagName,const Reference<xml::sax::XAttributeList> & xAttribs)190 void ScriptMetadataImporter::startElement(
191     const ::rtl::OUString& tagName,
192     const Reference< xml::sax::XAttributeList >& xAttribs )
193     throw ( xml::sax::SAXException, RuntimeException )
194 {
195 
196     OSL_TRACE(  "Trace Message : ScriptMetadataImporter: startElement() %s\n",
197            ::rtl::OUStringToOString( tagName,
198                                     RTL_TEXTENCODING_ASCII_US ).pData->buffer );
199 
200     ::osl::Guard< ::osl::Mutex > aGuard( m_mutex );
201 
202     //Set the state of the state machine
203     setState( tagName );
204 
205     //Processing the elements
206     switch( m_state )
207     {
208         case SCRIPT:
209             m_ScriptData.parcelURI = ms_parcelURI;
210             m_ScriptData.language = xAttribs->getValueByName(
211                 ::rtl::OUString::createFromAscii( "language" ));
212             OSL_TRACE(  "Trace Message: language is %s\n",
213                 ::rtl::OUStringToOString( m_ScriptData.language,
214                     RTL_TEXTENCODING_ASCII_US ).pData->buffer );
215             break;
216         case LOCALE:
217             ms_localeLang = xAttribs->getValueByName(
218                ::rtl::OUString::createFromAscii( "lang" ) );
219             OSL_TRACE(  "Trace Message: Locale is %s\n",
220                 ::rtl::OUStringToOString( ms_localeLang,
221                     RTL_TEXTENCODING_ASCII_US ).pData->buffer );
222             break;
223         case DISPLAYNAME:
224             ms_localeDisName = xAttribs->getValueByName(
225                ::rtl::OUString::createFromAscii( "value" ));
226             OSL_TRACE(  "Trace Message: Displyaname is %s\n",
227                 ::rtl::OUStringToOString( ms_localeDisName,
228                     RTL_TEXTENCODING_ASCII_US ).pData->buffer );
229             break;
230         case FUNCTIONNAME:
231             m_ScriptData.functionname = xAttribs->getValueByName(
232                ::rtl::OUString::createFromAscii( "value" ) );
233             OSL_TRACE(  "Trace Message: Functionname is %s\n",
234                 ::rtl::OUStringToOString( m_ScriptData.functionname,
235                     RTL_TEXTENCODING_ASCII_US ).pData->buffer );
236             break;
237         case LOGICALNAME:
238             m_ScriptData.logicalname = xAttribs->getValueByName(
239                ::rtl::OUString::createFromAscii( "value" ));
240 #ifdef _DEBUG
241             fprintf(stderr, "Trace Message: logicalname is %s\n",
242                 ::rtl::OUStringToOString( m_ScriptData.logicalname,
243                     RTL_TEXTENCODING_ASCII_US ).pData->buffer );
244 #endif
245             break;
246         case LANGDEPPROPS:
247              m_ScriptData.languagedepprops.push_back(
248                 ::std::make_pair( xAttribs->getValueByName(
249                      ::rtl::OUString::createFromAscii( "name" ) ),
250                  xAttribs->getValueByName(
251                      ::rtl::OUString::createFromAscii( "value" ) )
252                  ));
253             OSL_TRACE(  "Trace Message: Langdepprops is %s\t%s\n",
254                 ::rtl::OUStringToOString( xAttribs->getValueByName(
255                    ::rtl::OUString::createFromAscii( "name" ) ),
256                    RTL_TEXTENCODING_ASCII_US ).pData->buffer,
257                 ::rtl::OUStringToOString( xAttribs->getValueByName(
258                    ::rtl::OUString::createFromAscii( "value" ) ),
259                    RTL_TEXTENCODING_ASCII_US ).pData->buffer );
260              break;
261         case FILESET:
262             ms_filesetname = xAttribs->getValueByName(
263                ::rtl::OUString::createFromAscii( "name" ) );
264             OSL_TRACE(  "Trace Message: filesetname is %s\n",
265                 ::rtl::OUStringToOString(ms_filesetname,
266                     RTL_TEXTENCODING_ASCII_US ).pData->buffer );
267             break;
268         case FILESETPROPS:
269             mv_filesetprops.push_back( ::std::make_pair(
270                 xAttribs->getValueByName(
271                     ::rtl::OUString::createFromAscii( "name" ) ),
272                 xAttribs->getValueByName(
273                     ::rtl::OUString::createFromAscii( "value" ) )
274                 ));
275             OSL_TRACE(  "Trace Message: filesetprops is %s\t%s\n",
276                 ::rtl::OUStringToOString( xAttribs->getValueByName(
277                    ::rtl::OUString::createFromAscii( "name" ) ),
278                    RTL_TEXTENCODING_ASCII_US ).pData->buffer,
279                 ::rtl::OUStringToOString( xAttribs->getValueByName(
280                    ::rtl::OUString::createFromAscii( "value" ) ),
281                    RTL_TEXTENCODING_ASCII_US ).pData->buffer );
282             break;
283         case FILES:
284             ms_filename = xAttribs->getValueByName(
285                 ::rtl::OUString::createFromAscii( "name" ) );
286             OSL_TRACE(  "Trace Message: filename is %s\n",
287                 ::rtl::OUStringToOString( ms_filename,
288                     RTL_TEXTENCODING_ASCII_US).pData->buffer );
289             break;
290         case FILEPROPS:
291             /**
292             mm_files.insert( strpair_pair( ms_filename,
293                 str_pair( xAttribs->getValueByName(
294                     ::rtl::OUString::createFromAscii( "name" ) ),
295                 xAttribs->getValueByName(
296                     ::rtl::OUString::createFromAscii( "value") ) )
297                 )
298             );
299             */
300             mv_fileprops.push_back(str_pair( xAttribs->getValueByName(
301                 ::rtl::OUString::createFromAscii( "name" ) ),
302                 xAttribs->getValueByName(
303                 ::rtl::OUString::createFromAscii( "value") ) ) );
304             OSL_TRACE(  "Trace Message: fileprops is %s\t%s\n",
305                 ::rtl::OUStringToOString( xAttribs->getValueByName(
306                    ::rtl::OUString::createFromAscii( "name" ) ),
307                    RTL_TEXTENCODING_ASCII_US ).pData->buffer,
308                 ::rtl::OUStringToOString( xAttribs->getValueByName(
309                    ::rtl::OUString::createFromAscii( "value" ) ),
310                    RTL_TEXTENCODING_ASCII_US ).pData->buffer );
311             break;
312 
313         // to prevent compiler warnings
314         case PARCEL:
315         case DESCRIPTION:
316         case LANGUAGEDEPPROPS:
317             break;
318     }
319 }
320 
321 //*************************************************************************
endElement(const::rtl::OUString & aName)322 void ScriptMetadataImporter::endElement( const ::rtl::OUString & aName )
323     throw ( xml::sax::SAXException, RuntimeException )
324 {
325 
326     //The end tag of an element
327     OSL_TRACE(  "ScriptMetadataImporter: endElement() %s\n",
328         ::rtl::OUStringToOString( aName,
329             RTL_TEXTENCODING_ASCII_US ).pData->buffer );
330 
331     ::osl::Guard< ::osl::Mutex > aGuard( m_mutex );
332 
333     //Set the state
334     setState( aName );
335 
336 
337     switch ( m_state )
338     {
339         case PARCEL:
340             break;
341         case SCRIPT:
342 	    // np adjust logicalName to be equal to function name
343 	    // as logical name concept has been removed
344 	    m_ScriptData.logicalname = m_ScriptData.functionname;
345             mpv_ScriptDatas->push_back( m_ScriptData );
346             m_ScriptData =  ScriptData();
347             break;
348         case LOCALE:
349             m_ScriptData.locales[ ms_localeLang ] = ::std::make_pair(
350                 ms_localeDisName, ms_localeDesc->makeStringAndClear().trim() );
351             break;
352         case FILESET:
353             OSL_TRACE("adding fileset %s to filesets map",
354                    ::rtl::OUStringToOString( ms_filesetname,
355                    RTL_TEXTENCODING_ASCII_US ).pData->buffer );
356             m_ScriptData.filesets[ ms_filesetname ] = ::std::make_pair(
357                 mv_filesetprops, mm_files );
358             mm_files.clear();
359             mv_filesetprops.clear();
360             break;
361         case FILES:
362             OSL_TRACE("adding files %s to files map",
363                    ::rtl::OUStringToOString( ms_filename,
364                    RTL_TEXTENCODING_ASCII_US ).pData->buffer );
365             mm_files[ ms_filename ] = mv_fileprops;
366             mv_fileprops.clear();
367             break;
368             //
369         // to prevent compiler warnings
370         case DISPLAYNAME:
371         case DESCRIPTION:
372         case FUNCTIONNAME:
373         case LOGICALNAME:
374         case LANGUAGEDEPPROPS:
375         case LANGDEPPROPS:
376         case FILESETPROPS:
377         case FILEPROPS:
378             break;
379     }
380 }
381 
382 //*************************************************************************
characters(const::rtl::OUString & aChars)383 void ScriptMetadataImporter::characters( const ::rtl::OUString & aChars )
384     throw ( xml::sax::SAXException, RuntimeException )
385 {
386     OSL_TRACE( "ScriptMetadataImporter: characters()\n");
387 
388     ::osl::Guard< ::osl::Mutex > aGuard( m_mutex );
389 
390     switch ( m_state )
391     {
392         case DESCRIPTION:
393             //Put description into the struct
394             ms_localeDesc->append(aChars);
395             break;
396         case PARCEL:
397         case SCRIPT:
398         case LOCALE:
399         case DISPLAYNAME:
400         case FUNCTIONNAME:
401         case LOGICALNAME:
402         case LANGUAGEDEPPROPS:
403         case LANGDEPPROPS:
404         case FILESETPROPS:
405         case FILEPROPS:
406             break;
407     }
408 }
409 
410 //*************************************************************************
ignorableWhitespace(const::rtl::OUString & aWhitespaces)411 void ScriptMetadataImporter::ignorableWhitespace(
412     const ::rtl::OUString & aWhitespaces )
413     throw ( xml::sax::SAXException, RuntimeException )
414 {
415     OSL_TRACE( "ScriptMetadataImporter: ignorableWhiteSpace()\n" );
416 }
417 
418 //*************************************************************************
processingInstruction(const::rtl::OUString & aTarget,const::rtl::OUString & aData)419 void ScriptMetadataImporter::processingInstruction(
420     const ::rtl::OUString & aTarget, const ::rtl::OUString & aData )
421     throw ( xml::sax::SAXException, RuntimeException )
422 {
423     OSL_TRACE( "ScriptMetadataImporter: processingInstruction()\n" );
424 }
425 
426 //*************************************************************************
setDocumentLocator(const Reference<xml::sax::XLocator> & xLocator)427 void ScriptMetadataImporter::setDocumentLocator(
428     const Reference< xml::sax::XLocator >& xLocator )
429     throw ( xml::sax::SAXException, RuntimeException )
430 {
431     OSL_TRACE( "ScriptMetadataImporter: setDocumentLocator()\n" );
432 }
433 
434 //*************************************************************************
setState(const::rtl::OUString & tagName)435 void ScriptMetadataImporter::setState( const ::rtl::OUString & tagName )
436 {
437     //Set the state depending on the tag name of the current
438     //element the parser has arrived at
439     ::osl::Guard< ::osl::Mutex > aGuard( m_mutex );
440 
441     if( tagName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "parcel" ) ) )
442     {
443         //Parcel tag
444         m_state = PARCEL;
445     }
446     else if( tagName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "script" ) ) )
447     {
448         m_state = SCRIPT;
449     }
450     else if( tagName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "locale" ) ) )
451     {
452         m_state = LOCALE;
453     }
454     else if( tagName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "displayname" ) ) )
455     {
456         m_state = DISPLAYNAME;
457     }
458     else if( tagName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "description" ) ) )
459     {
460         m_state = DESCRIPTION;
461     }
462     else if( tagName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "functionname" ) ) )
463     {
464         m_state = FUNCTIONNAME;
465     }
466     else if( tagName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "logicalname" ) ) )
467     {
468         m_state = LOGICALNAME;
469     }
470     else if( tagName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "languagedepprops" ) ) )
471     {
472         m_state = LANGUAGEDEPPROPS;
473     }
474     else if( tagName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "prop" ) ) )
475     {
476         if( m_state == LANGUAGEDEPPROPS )
477         {
478             m_state = LANGDEPPROPS;
479         }
480         else if( m_state == FILESET )
481         {
482             m_state = FILESETPROPS;
483         }
484         else if( m_state == FILES )
485         {
486             m_state = FILEPROPS;
487         }
488     }
489     else if( tagName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "fileset" ) ) )
490     {
491         m_state = FILESET;
492     }
493     else if( tagName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "file" ) ) )
494     {
495         m_state = FILES;
496     }
497     else
498     {
499         //If there is a tag we don't know about, throw a exception (wobbler) :)
500         ::rtl::OUString str_sax = ::rtl::OUString::createFromAscii( "No Such Tag" );
501 
502         OSL_TRACE(  "ScriptMetadataImporter: No Such Tag: %s\n",
503             ::rtl::OUStringToOString(
504                 tagName, RTL_TEXTENCODING_ASCII_US ).pData->buffer );
505 
506         throw xml::sax::SAXException(
507             str_sax, Reference< XInterface >(), Any() );
508     }
509 }
510 
511 }
512