Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <com/sun/star/xml/sax/InputSource.hpp>
30 : : #include <com/sun/star/xml/sax/XParser.hpp>
31 : : #include <com/sun/star/xml/sax/XAttributeList.hpp>
32 : : #include <com/sun/star/beans/PropertyValue.hpp>
33 : :
34 : : #include "typedetectionimport.hxx"
35 : : #include "xmlfiltersettingsdialog.hxx"
36 : :
37 : : using namespace com::sun::star::lang;
38 : : using namespace com::sun::star::uno;
39 : : using namespace com::sun::star::io;
40 : : using namespace com::sun::star::beans;
41 : : using namespace com::sun::star::xml::sax;
42 : : using namespace com::sun::star;
43 : : using namespace std;
44 : :
45 : : using ::rtl::OUString;
46 : :
47 : 0 : TypeDetectionImporter::TypeDetectionImporter( Reference< XMultiServiceFactory >& xMSF )
48 : : : mxMSF(xMSF),
49 : : sRootNode( RTL_CONSTASCII_USTRINGPARAM( "oor:component-data" ) ),
50 : : sNode( RTL_CONSTASCII_USTRINGPARAM( "node" ) ),
51 : : sName( RTL_CONSTASCII_USTRINGPARAM( "oor:name" ) ),
52 : : sProp( RTL_CONSTASCII_USTRINGPARAM( "prop" ) ),
53 : : sValue( RTL_CONSTASCII_USTRINGPARAM( "value" ) ),
54 : : sUIName( RTL_CONSTASCII_USTRINGPARAM( "UIName" ) ),
55 : : sData( RTL_CONSTASCII_USTRINGPARAM( "Data" ) ),
56 : : sFilters( RTL_CONSTASCII_USTRINGPARAM( "Filters" ) ),
57 : : sTypes( RTL_CONSTASCII_USTRINGPARAM( "Types" ) ),
58 : : sFilterAdaptorService( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.comp.Writer.XmlFilterAdaptor" ) ),
59 : : sXSLTFilterService( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.documentconversion.XSLTFilter" ) ),
60 : : sCdataAttribute( RTL_CONSTASCII_USTRINGPARAM( "CDATA" ) ),
61 : 0 : sWhiteSpace( RTL_CONSTASCII_USTRINGPARAM( " " ) )
62 : : {
63 : 0 : }
64 : :
65 : 0 : TypeDetectionImporter::~TypeDetectionImporter (void )
66 : : {
67 : 0 : }
68 : :
69 : 0 : void TypeDetectionImporter::doImport( Reference< XMultiServiceFactory >& xMSF, Reference< XInputStream > xIS, XMLFilterVector& rFilters )
70 : : {
71 : : try
72 : : {
73 : 0 : Reference< XParser > xParser( xMSF->createInstance(OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Parser" )) ), UNO_QUERY );
74 : 0 : if( xParser.is() )
75 : : {
76 : 0 : TypeDetectionImporter* pImporter = new TypeDetectionImporter( xMSF );
77 : 0 : Reference < XDocumentHandler > xDocHandler( pImporter );
78 : 0 : xParser->setDocumentHandler( xDocHandler );
79 : :
80 : 0 : InputSource source;
81 : 0 : source.aInputStream = xIS;
82 : :
83 : : // start parsing
84 : 0 : xParser->parseStream( source );
85 : :
86 : 0 : pImporter->fillFilterVector( rFilters );
87 : 0 : }
88 : : }
89 : 0 : catch( const Exception& /* e */ )
90 : : {
91 : : OSL_FAIL( "TypeDetectionImporter::doImport exception catched!" );
92 : : }
93 : 0 : }
94 : :
95 : 0 : void TypeDetectionImporter::fillFilterVector( XMLFilterVector& rFilters )
96 : : {
97 : : // create filter infos from imported filter nodes
98 : 0 : NodeVector::iterator aIter = maFilterNodes.begin();
99 : 0 : while( aIter != maFilterNodes.end() )
100 : : {
101 : 0 : filter_info_impl* pFilter = createFilterForNode( (*aIter) );
102 : 0 : if( pFilter )
103 : 0 : rFilters.push_back( pFilter );
104 : :
105 : 0 : delete (*aIter++);
106 : : }
107 : :
108 : : // now delete type nodes
109 : 0 : aIter = maTypeNodes.begin();
110 : 0 : while( aIter != maTypeNodes.end() )
111 : 0 : delete (*aIter++);
112 : 0 : }
113 : :
114 : 0 : static OUString getSubdata( int index, sal_Unicode delimeter, const OUString& rData )
115 : : {
116 : 0 : sal_Int32 nLastIndex = 0;
117 : :
118 : 0 : sal_Int32 nNextIndex = rData.indexOf( delimeter );
119 : :
120 : 0 : OUString aSubdata;
121 : :
122 : 0 : while( index )
123 : : {
124 : 0 : nLastIndex = nNextIndex + 1;
125 : 0 : nNextIndex = rData.indexOf( delimeter, nLastIndex );
126 : :
127 : 0 : index--;
128 : :
129 : 0 : if( (index > 0) && (nLastIndex == 0) )
130 : 0 : return aSubdata;
131 : : }
132 : :
133 : 0 : if( nNextIndex == -1 )
134 : : {
135 : 0 : aSubdata = rData.copy( nLastIndex );
136 : : }
137 : : else
138 : : {
139 : 0 : aSubdata = rData.copy( nLastIndex, nNextIndex - nLastIndex );
140 : : }
141 : :
142 : 0 : return aSubdata;
143 : : }
144 : :
145 : 0 : Node* TypeDetectionImporter::findTypeNode( const OUString& rType )
146 : : {
147 : : // now delete type nodes
148 : 0 : NodeVector::iterator aIter = maTypeNodes.begin();
149 : 0 : while( aIter != maTypeNodes.end() )
150 : : {
151 : 0 : if( (*aIter)->maName == rType )
152 : 0 : return (*aIter);
153 : :
154 : 0 : ++aIter;
155 : : }
156 : :
157 : 0 : return NULL;
158 : : }
159 : :
160 : 0 : filter_info_impl* TypeDetectionImporter::createFilterForNode( Node * pNode )
161 : : {
162 : 0 : filter_info_impl* pFilter = new filter_info_impl;
163 : :
164 : 0 : pFilter->maFilterName = pNode->maName;
165 : 0 : pFilter->maInterfaceName = pNode->maPropertyMap[sUIName];
166 : :
167 : 0 : OUString aData = pNode->maPropertyMap[sData];
168 : :
169 : 0 : sal_Unicode aComma(',');
170 : :
171 : 0 : pFilter->maType = getSubdata( 1, aComma, aData );
172 : 0 : pFilter->maDocumentService = getSubdata( 2, aComma, aData );
173 : :
174 : 0 : OUString aFilterService( getSubdata( 3, aComma, aData ) );
175 : 0 : pFilter->maFlags = getSubdata( 4, aComma, aData ).toInt32();
176 : :
177 : : // parse filter user data
178 : 0 : sal_Unicode aDelim(';');
179 : 0 : OUString aFilterUserData( getSubdata( 5, aComma, aData ) );
180 : :
181 : 0 : OUString aAdapterService( getSubdata( 0, aDelim, aFilterUserData ) );
182 : : //Import/ExportService
183 : 0 : pFilter->maXSLTTransformerImpl = getSubdata( 1, aDelim, aFilterUserData );
184 : 0 : pFilter->maImportService = getSubdata( 2, aDelim, aFilterUserData );
185 : 0 : pFilter->maExportService = getSubdata( 3, aDelim, aFilterUserData );
186 : 0 : pFilter->maImportXSLT = getSubdata( 4, aDelim, aFilterUserData );
187 : 0 : pFilter->maExportXSLT = getSubdata( 5, aDelim, aFilterUserData );
188 : 0 : pFilter->maDTD = getSubdata( 6, aDelim, aFilterUserData );
189 : 0 : pFilter->maComment = getSubdata( 7, aDelim, aFilterUserData );
190 : :
191 : :
192 : 0 : pFilter->maImportTemplate = getSubdata( 7, aComma, aData );
193 : :
194 : 0 : Node* pTypeNode = findTypeNode( pFilter->maType );
195 : 0 : if( pTypeNode )
196 : : {
197 : 0 : OUString aTypeUserData( pTypeNode->maPropertyMap[sData] );
198 : :
199 : 0 : pFilter->maDocType = getSubdata( 2, aComma, aTypeUserData );
200 : 0 : pFilter->maExtension = getSubdata( 4, aComma, aTypeUserData );
201 : 0 : pFilter->mnDocumentIconID = getSubdata( 5, aComma, aTypeUserData ).toInt32();
202 : : }
203 : :
204 : 0 : bool bOk = true;
205 : :
206 : 0 : if( pTypeNode == NULL )
207 : 0 : bOk = false;
208 : :
209 : 0 : if( pFilter->maFilterName.isEmpty() )
210 : 0 : bOk = false;
211 : :
212 : 0 : if( pFilter->maInterfaceName.isEmpty() )
213 : 0 : bOk = false;
214 : :
215 : 0 : if( pFilter->maType.isEmpty() )
216 : 0 : bOk = false;
217 : :
218 : 0 : if( pFilter->maFlags == 0 )
219 : 0 : bOk = false;
220 : :
221 : 0 : if( aFilterService != sFilterAdaptorService )
222 : 0 : bOk = false;
223 : :
224 : 0 : if( aAdapterService != sXSLTFilterService )
225 : 0 : bOk = false;
226 : :
227 : 0 : if( pFilter->maExtension.isEmpty() )
228 : 0 : bOk = false;
229 : :
230 : 0 : if( !bOk )
231 : : {
232 : 0 : delete pFilter;
233 : 0 : pFilter = NULL;
234 : : }
235 : :
236 : 0 : return pFilter;
237 : : }
238 : :
239 : 0 : void SAL_CALL TypeDetectionImporter::startDocument( )
240 : : throw(xml::sax::SAXException, uno::RuntimeException)
241 : : {
242 : 0 : }
243 : :
244 : 0 : void SAL_CALL TypeDetectionImporter::endDocument( )
245 : : throw(xml::sax::SAXException, uno::RuntimeException)
246 : : {
247 : 0 : }
248 : :
249 : 0 : void SAL_CALL TypeDetectionImporter::startElement( const OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs )
250 : : throw(xml::sax::SAXException, uno::RuntimeException)
251 : : {
252 : 0 : ImportState eNewState = e_Unknown;
253 : :
254 : 0 : if( maStack.empty() )
255 : : {
256 : : // #109668# support legacy name as well on import
257 : 0 : if( aName == sRootNode || aName == "oor:node" )
258 : : {
259 : 0 : eNewState = e_Root;
260 : : }
261 : : }
262 : 0 : else if( maStack.top() == e_Root )
263 : : {
264 : 0 : if( aName == sNode )
265 : : {
266 : 0 : OUString aNodeName( xAttribs->getValueByName( sName ) );
267 : :
268 : 0 : if( aNodeName == sFilters )
269 : : {
270 : 0 : eNewState = e_Filters;
271 : : }
272 : 0 : else if( aNodeName == sTypes )
273 : : {
274 : 0 : eNewState = e_Types;
275 : 0 : }
276 : : }
277 : : }
278 : 0 : else if( (maStack.top() == e_Filters) || (maStack.top() == e_Types) )
279 : : {
280 : 0 : if( aName == sNode )
281 : : {
282 : 0 : maNodeName = xAttribs->getValueByName( sName );
283 : :
284 : 0 : eNewState = (maStack.top() == e_Filters) ? e_Filter : e_Type;
285 : : }
286 : : }
287 : 0 : else if( (maStack.top() == e_Filter) || (maStack.top() == e_Type))
288 : : {
289 : 0 : if( aName == sProp )
290 : : {
291 : 0 : maPropertyName = xAttribs->getValueByName( sName );
292 : 0 : eNewState = e_Property;
293 : : }
294 : : }
295 : 0 : else if( maStack.top() == e_Property )
296 : : {
297 : 0 : if( aName == sValue )
298 : : {
299 : 0 : eNewState = e_Value;
300 : 0 : maValue = OUString();
301 : : }
302 : : }
303 : :
304 : 0 : maStack.push( eNewState );
305 : 0 : }
306 : 0 : void SAL_CALL TypeDetectionImporter::endElement( const OUString& /* aName */ )
307 : : throw(xml::sax::SAXException, uno::RuntimeException)
308 : : {
309 : 0 : if( !maStack.empty() )
310 : : {
311 : 0 : ImportState eCurrentState = maStack.top();
312 : 0 : switch( eCurrentState )
313 : : {
314 : : case e_Filter:
315 : : case e_Type:
316 : : {
317 : 0 : Node* pNode = new Node;
318 : 0 : pNode->maName = maNodeName;
319 : 0 : pNode->maPropertyMap = maPropertyMap;
320 : 0 : maPropertyMap.clear();
321 : :
322 : 0 : if( eCurrentState == e_Filter )
323 : : {
324 : 0 : maFilterNodes.push_back( pNode );
325 : : }
326 : : else
327 : : {
328 : 0 : maTypeNodes.push_back( pNode );
329 : : }
330 : : }
331 : 0 : break;
332 : :
333 : : case e_Property:
334 : 0 : maPropertyMap[ maPropertyName ] = maValue;
335 : 0 : break;
336 : 0 : default: break;
337 : : }
338 : :
339 : 0 : maStack.pop();
340 : : }
341 : 0 : }
342 : 0 : void SAL_CALL TypeDetectionImporter::characters( const OUString& aChars )
343 : : throw(xml::sax::SAXException, uno::RuntimeException)
344 : : {
345 : 0 : if( !maStack.empty() && maStack.top() == e_Value )
346 : : {
347 : 0 : maValue += aChars;
348 : : }
349 : 0 : }
350 : 0 : void SAL_CALL TypeDetectionImporter::ignorableWhitespace( const OUString& /* aWhitespaces */ )
351 : : throw(xml::sax::SAXException, uno::RuntimeException)
352 : : {
353 : 0 : }
354 : 0 : void SAL_CALL TypeDetectionImporter::processingInstruction( const OUString& /* aTarget */, const OUString& /* aData */ )
355 : : throw(xml::sax::SAXException, uno::RuntimeException)
356 : : {
357 : 0 : }
358 : 0 : void SAL_CALL TypeDetectionImporter::setDocumentLocator( const uno::Reference< xml::sax::XLocator >& /* xLocator */ )
359 : : throw(xml::sax::SAXException, uno::RuntimeException)
360 : : {
361 : 0 : }
362 : :
363 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|