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 :
38 0 : TypeDetectionImporter::TypeDetectionImporter()
39 : : sRootNode( "oor:component-data" ),
40 : sNode( "node" ),
41 : sName( "oor:name" ),
42 : sProp( "prop" ),
43 : sValue( "value" ),
44 : sUIName( "UIName" ),
45 : sData( "Data" ),
46 : sFilters( "Filters" ),
47 : sTypes( "Types" ),
48 : sFilterAdaptorService( "com.sun.star.comp.Writer.XmlFilterAdaptor" ),
49 : sXSLTFilterService( "com.sun.star.documentconversion.XSLTFilter" ),
50 : sCdataAttribute( "CDATA" ),
51 0 : sWhiteSpace( " " )
52 : {
53 0 : }
54 :
55 0 : TypeDetectionImporter::~TypeDetectionImporter (void )
56 : {
57 0 : }
58 :
59 0 : void TypeDetectionImporter::doImport( const Reference< XComponentContext >& rxContext, Reference< XInputStream > xIS, XMLFilterVector& rFilters )
60 : {
61 : try
62 : {
63 0 : Reference< XParser > xParser = xml::sax::Parser::create( rxContext );
64 :
65 0 : TypeDetectionImporter* pImporter = new TypeDetectionImporter;
66 0 : Reference < XDocumentHandler > xDocHandler( pImporter );
67 0 : xParser->setDocumentHandler( xDocHandler );
68 :
69 0 : InputSource source;
70 0 : source.aInputStream = xIS;
71 :
72 : // start parsing
73 0 : xParser->parseStream( source );
74 :
75 0 : pImporter->fillFilterVector( rFilters );
76 : }
77 0 : catch( const Exception& /* e */ )
78 : {
79 : OSL_FAIL( "TypeDetectionImporter::doImport exception catched!" );
80 : }
81 0 : }
82 :
83 0 : void TypeDetectionImporter::fillFilterVector( XMLFilterVector& rFilters )
84 : {
85 : // create filter infos from imported filter nodes
86 0 : NodeVector::iterator aIter = maFilterNodes.begin();
87 0 : while( aIter != maFilterNodes.end() )
88 : {
89 0 : filter_info_impl* pFilter = createFilterForNode( (*aIter) );
90 0 : if( pFilter )
91 0 : rFilters.push_back( pFilter );
92 :
93 0 : delete (*aIter++);
94 : }
95 :
96 : // now delete type nodes
97 0 : aIter = maTypeNodes.begin();
98 0 : while( aIter != maTypeNodes.end() )
99 0 : delete (*aIter++);
100 0 : }
101 :
102 0 : static OUString getSubdata( int index, sal_Unicode delimeter, const OUString& rData )
103 : {
104 0 : sal_Int32 nLastIndex = 0;
105 :
106 0 : sal_Int32 nNextIndex = rData.indexOf( delimeter );
107 :
108 0 : OUString aSubdata;
109 :
110 0 : while( index )
111 : {
112 0 : nLastIndex = nNextIndex + 1;
113 0 : nNextIndex = rData.indexOf( delimeter, nLastIndex );
114 :
115 0 : index--;
116 :
117 0 : if( (index > 0) && (nLastIndex == 0) )
118 0 : return aSubdata;
119 : }
120 :
121 0 : if( nNextIndex == -1 )
122 : {
123 0 : aSubdata = rData.copy( nLastIndex );
124 : }
125 : else
126 : {
127 0 : aSubdata = rData.copy( nLastIndex, nNextIndex - nLastIndex );
128 : }
129 :
130 0 : return aSubdata;
131 : }
132 :
133 0 : Node* TypeDetectionImporter::findTypeNode( const OUString& rType )
134 : {
135 : // now delete type nodes
136 0 : for (NodeVector::const_iterator aIter(maTypeNodes.begin()), aEnd(maTypeNodes.end()); aIter != aEnd; ++aIter)
137 : {
138 0 : if( (*aIter)->maName == rType )
139 0 : return (*aIter);
140 : }
141 :
142 0 : return NULL;
143 : }
144 :
145 0 : filter_info_impl* TypeDetectionImporter::createFilterForNode( Node * pNode )
146 : {
147 0 : filter_info_impl* pFilter = new filter_info_impl;
148 :
149 0 : pFilter->maFilterName = pNode->maName;
150 0 : pFilter->maInterfaceName = pNode->maPropertyMap[sUIName];
151 :
152 0 : OUString aData = pNode->maPropertyMap[sData];
153 :
154 0 : sal_Unicode aComma(',');
155 :
156 0 : pFilter->maType = getSubdata( 1, aComma, aData );
157 0 : pFilter->maDocumentService = getSubdata( 2, aComma, aData );
158 :
159 0 : OUString aFilterService( getSubdata( 3, aComma, aData ) );
160 0 : pFilter->maFlags = getSubdata( 4, aComma, aData ).toInt32();
161 :
162 : // parse filter user data
163 0 : sal_Unicode aDelim(';');
164 0 : OUString aFilterUserData( getSubdata( 5, aComma, aData ) );
165 :
166 0 : OUString aAdapterService( getSubdata( 0, aDelim, aFilterUserData ) );
167 : //Import/ExportService
168 0 : pFilter->mbNeedsXSLT2 = getSubdata( 1, aDelim, aFilterUserData ).toBoolean();
169 0 : pFilter->maImportService = getSubdata( 2, aDelim, aFilterUserData );
170 0 : pFilter->maExportService = getSubdata( 3, aDelim, aFilterUserData );
171 0 : pFilter->maImportXSLT = getSubdata( 4, aDelim, aFilterUserData );
172 0 : pFilter->maExportXSLT = getSubdata( 5, aDelim, aFilterUserData );
173 0 : pFilter->maComment = getSubdata( 7, aDelim, aFilterUserData );
174 :
175 :
176 0 : pFilter->maImportTemplate = getSubdata( 7, aComma, aData );
177 :
178 0 : Node* pTypeNode = findTypeNode( pFilter->maType );
179 0 : if( pTypeNode )
180 : {
181 0 : OUString aTypeUserData( pTypeNode->maPropertyMap[sData] );
182 :
183 0 : pFilter->maDocType = getSubdata( 2, aComma, aTypeUserData );
184 0 : pFilter->maExtension = getSubdata( 4, aComma, aTypeUserData );
185 0 : pFilter->mnDocumentIconID = getSubdata( 5, aComma, aTypeUserData ).toInt32();
186 : }
187 :
188 0 : bool bOk = true;
189 :
190 0 : if( pTypeNode == NULL )
191 0 : bOk = false;
192 :
193 0 : if( pFilter->maFilterName.isEmpty() )
194 0 : bOk = false;
195 :
196 0 : if( pFilter->maInterfaceName.isEmpty() )
197 0 : bOk = false;
198 :
199 0 : if( pFilter->maType.isEmpty() )
200 0 : bOk = false;
201 :
202 0 : if( pFilter->maFlags == 0 )
203 0 : bOk = false;
204 :
205 0 : if( aFilterService != sFilterAdaptorService )
206 0 : bOk = false;
207 :
208 0 : if( aAdapterService != sXSLTFilterService )
209 0 : bOk = false;
210 :
211 0 : if( pFilter->maExtension.isEmpty() )
212 0 : bOk = false;
213 :
214 0 : if( !bOk )
215 : {
216 0 : delete pFilter;
217 0 : pFilter = NULL;
218 : }
219 :
220 0 : return pFilter;
221 : }
222 :
223 0 : void SAL_CALL TypeDetectionImporter::startDocument( )
224 : throw(xml::sax::SAXException, uno::RuntimeException)
225 : {
226 0 : }
227 :
228 0 : void SAL_CALL TypeDetectionImporter::endDocument( )
229 : throw(xml::sax::SAXException, uno::RuntimeException)
230 : {
231 0 : }
232 :
233 0 : void SAL_CALL TypeDetectionImporter::startElement( const OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs )
234 : throw(xml::sax::SAXException, uno::RuntimeException)
235 : {
236 0 : ImportState eNewState = e_Unknown;
237 :
238 0 : if( maStack.empty() )
239 : {
240 : // #109668# support legacy name as well on import
241 0 : if( aName == sRootNode || aName == "oor:node" )
242 : {
243 0 : eNewState = e_Root;
244 : }
245 : }
246 0 : else if( maStack.top() == e_Root )
247 : {
248 0 : if( aName == sNode )
249 : {
250 0 : OUString aNodeName( xAttribs->getValueByName( sName ) );
251 :
252 0 : if( aNodeName == sFilters )
253 : {
254 0 : eNewState = e_Filters;
255 : }
256 0 : else if( aNodeName == sTypes )
257 : {
258 0 : eNewState = e_Types;
259 0 : }
260 : }
261 : }
262 0 : else if( (maStack.top() == e_Filters) || (maStack.top() == e_Types) )
263 : {
264 0 : if( aName == sNode )
265 : {
266 0 : maNodeName = xAttribs->getValueByName( sName );
267 :
268 0 : eNewState = (maStack.top() == e_Filters) ? e_Filter : e_Type;
269 : }
270 : }
271 0 : else if( (maStack.top() == e_Filter) || (maStack.top() == e_Type))
272 : {
273 0 : if( aName == sProp )
274 : {
275 0 : maPropertyName = xAttribs->getValueByName( sName );
276 0 : eNewState = e_Property;
277 : }
278 : }
279 0 : else if( maStack.top() == e_Property )
280 : {
281 0 : if( aName == sValue )
282 : {
283 0 : eNewState = e_Value;
284 0 : maValue = OUString();
285 : }
286 : }
287 :
288 0 : maStack.push( eNewState );
289 0 : }
290 0 : void SAL_CALL TypeDetectionImporter::endElement( const OUString& /* aName */ )
291 : throw(xml::sax::SAXException, uno::RuntimeException)
292 : {
293 0 : if( !maStack.empty() )
294 : {
295 0 : ImportState eCurrentState = maStack.top();
296 0 : switch( eCurrentState )
297 : {
298 : case e_Filter:
299 : case e_Type:
300 : {
301 0 : Node* pNode = new Node;
302 0 : pNode->maName = maNodeName;
303 0 : pNode->maPropertyMap = maPropertyMap;
304 0 : maPropertyMap.clear();
305 :
306 0 : if( eCurrentState == e_Filter )
307 : {
308 0 : maFilterNodes.push_back( pNode );
309 : }
310 : else
311 : {
312 0 : maTypeNodes.push_back( pNode );
313 : }
314 : }
315 0 : break;
316 :
317 : case e_Property:
318 0 : maPropertyMap[ maPropertyName ] = maValue;
319 0 : break;
320 0 : default: break;
321 : }
322 :
323 0 : maStack.pop();
324 : }
325 0 : }
326 0 : void SAL_CALL TypeDetectionImporter::characters( const OUString& aChars )
327 : throw(xml::sax::SAXException, uno::RuntimeException)
328 : {
329 0 : if( !maStack.empty() && maStack.top() == e_Value )
330 : {
331 0 : maValue += aChars;
332 : }
333 0 : }
334 0 : void SAL_CALL TypeDetectionImporter::ignorableWhitespace( const OUString& /* aWhitespaces */ )
335 : throw(xml::sax::SAXException, uno::RuntimeException)
336 : {
337 0 : }
338 0 : void SAL_CALL TypeDetectionImporter::processingInstruction( const OUString& /* aTarget */, const OUString& /* aData */ )
339 : throw(xml::sax::SAXException, uno::RuntimeException)
340 : {
341 0 : }
342 0 : void SAL_CALL TypeDetectionImporter::setDocumentLocator( const uno::Reference< xml::sax::XLocator >& /* xLocator */ )
343 : throw(xml::sax::SAXException, uno::RuntimeException)
344 : {
345 0 : }
346 :
347 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|