xref: /trunk/main/filter/source/xsltdialog/typedetectionimport.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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 {
237 }
238 
endDocument()239 void SAL_CALL TypeDetectionImporter::endDocument(  )
240 {
241 }
242 
startElement(const OUString & aName,const uno::Reference<xml::sax::XAttributeList> & xAttribs)243 void SAL_CALL TypeDetectionImporter::startElement( const OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs )
244 {
245     ImportState eNewState = e_Unknown;
246 
247     if( maStack.empty() )
248     {
249         // #109668# support legacy name as well on import
250         if( aName == sRootNode || aName.equalsAscii("oor:node") )
251         {
252             eNewState = e_Root;
253         }
254     }
255     else if( maStack.top() == e_Root )
256     {
257         if( aName == sNode )
258         {
259             OUString aNodeName( xAttribs->getValueByName( sName ) );
260 
261             if( aNodeName == sFilters )
262             {
263                 eNewState = e_Filters;
264             }
265             else if( aNodeName == sTypes )
266             {
267                 eNewState = e_Types;
268             }
269         }
270     }
271     else if( (maStack.top() == e_Filters) || (maStack.top() == e_Types) )
272     {
273         if( aName == sNode )
274         {
275             maNodeName = xAttribs->getValueByName( sName );
276 
277             eNewState = (maStack.top() == e_Filters) ? e_Filter : e_Type;
278         }
279     }
280     else if( (maStack.top() == e_Filter) || (maStack.top() == e_Type))
281     {
282         if( aName == sProp )
283         {
284             maPropertyName = xAttribs->getValueByName( sName );
285             eNewState = e_Property;
286         }
287     }
288     else if( maStack.top() == e_Property )
289     {
290         if( aName == sValue )
291         {
292             eNewState = e_Value;
293             maValue = OUString();
294         }
295     }
296 
297     maStack.push( eNewState );
298 }
endElement(const OUString &)299 void SAL_CALL TypeDetectionImporter::endElement( const OUString& /* aName */ )
300 {
301     if( !maStack.empty() )
302     {
303         ImportState eCurrentState = maStack.top();
304         switch( eCurrentState )
305         {
306         case e_Filter:
307         case e_Type:
308             {
309                 Node* pNode = new Node;
310                 pNode->maName = maNodeName;
311                 pNode->maPropertyMap = maPropertyMap;
312                 maPropertyMap.clear();
313 
314                 if( eCurrentState == e_Filter )
315                 {
316                     maFilterNodes.push_back( pNode );
317                 }
318                 else
319                 {
320                     maTypeNodes.push_back( pNode );
321                 }
322             }
323             break;
324 
325         case e_Property:
326             maPropertyMap[ maPropertyName ] = maValue;
327             break;
328         default: break;
329         }
330 
331         maStack.pop();
332     }
333 }
characters(const OUString & aChars)334 void SAL_CALL TypeDetectionImporter::characters( const OUString& aChars )
335 {
336     if( !maStack.empty() && maStack.top() == e_Value )
337     {
338         maValue += aChars;
339     }
340 }
ignorableWhitespace(const OUString &)341 void SAL_CALL TypeDetectionImporter::ignorableWhitespace( const OUString& /* aWhitespaces */ )
342 {
343 }
processingInstruction(const OUString &,const OUString &)344 void SAL_CALL TypeDetectionImporter::processingInstruction( const OUString& /* aTarget */, const OUString& /* aData */ )
345 {
346 }
setDocumentLocator(const uno::Reference<xml::sax::XLocator> &)347 void SAL_CALL TypeDetectionImporter::setDocumentLocator( const uno::Reference< xml::sax::XLocator >& /* xLocator */ )
348 {
349 }
350