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