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