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 catched!" );
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