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