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 <iostream>
27 #include <stdlib.h>
28 #include <ctype.h>
29 #include <stdio.h>
30 #include "filterdetect.hxx"
31 #include <osl/diagnose.h>
32 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
33 #include <com/sun/star/io/XActiveDataSource.hpp>
34 #include <com/sun/star/io/XOutputStream.hpp>
35 #include <com/sun/star/io/XInputStream.hpp>
36 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
37 #include <com/sun/star/xml/sax/InputSource.hpp>
38 #include <com/sun/star/xml/sax/XParser.hpp>
39 #include <com/sun/star/xml/XImportFilter.hpp>
40 #include <com/sun/star/xml/XExportFilter.hpp>
41 #include <com/sun/star/frame/XModel.hpp>
42 #include <com/sun/star/frame/XController.hpp>
43 #include <com/sun/star/task/XStatusIndicator.hpp>
44 #include <com/sun/star/task/XStatusIndicatorFactory.hpp>
45 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
46 #include <com/sun/star/style/XStyleLoader.hpp>
47 #include <com/sun/star/io/XInputStream.hpp>
48 #include <com/sun/star/document/XExtendedFilterDetection.hpp>
49 #include <com/sun/star/container/XNameAccess.hpp>
50 #include <com/sun/star/beans/PropertyState.hpp>
51 
52 #include <ucbhelper/content.hxx>
53 #include <ucbhelper/contentbroker.hxx>
54 #include <ucbhelper/commandenvironment.hxx>
55 #include <unotools/ucbhelper.hxx>
56 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
57 
58 //UOF v2 deep type detection
59 #include "../xsltfilter/uof2storage.cxx"
60 #include <rtl/string.hxx>
61 
62 
63 using rtl::OUString;
64 using com::sun::star::uno::Sequence;
65 using com::sun::star::uno::Reference;
66 using com::sun::star::uno::Any;
67 using com::sun::star::uno::UNO_QUERY;
68 using com::sun::star::uno::XInterface;
69 using com::sun::star::uno::Exception;
70 using com::sun::star::uno::RuntimeException;
71 using com::sun::star::lang::XMultiServiceFactory;
72 using com::sun::star::io::XActiveDataSource;
73 using com::sun::star::io::XOutputStream;
74 using com::sun::star::beans::PropertyValue;
75 using com::sun::star::document::XExporter;
76 using com::sun::star::document::XFilter;
77 using com::sun::star::document::XExtendedFilterDetection;
78 
79 using com::sun::star::io::XInputStream;
80 using com::sun::star::document::XImporter;
81 using com::sun::star::xml::sax::InputSource;
82 using com::sun::star::xml::sax::XDocumentHandler;
83 using com::sun::star::xml::sax::XParser;
84 using com::sun::star::task::XInteractionHandler;
85 
86 using namespace ::com::sun::star::frame;
87 using namespace ::com::sun::star;
88 using namespace com::sun::star::container;
89 using namespace com::sun::star::uno;
90 using namespace com::sun::star::beans;
91 
92 
93 Reference< com::sun::star::frame::XModel > xModel;
94 
95 ::rtl::OUString SAL_CALL supportedByType( const ::rtl::OUString  clipBoardFormat ,  const ::rtl::OString resultString, const ::rtl::OUString checkType);
96 
97 
detect(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> & aArguments)98 ::rtl::OUString SAL_CALL FilterDetect::detect( com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >& aArguments ) throw( com::sun::star::uno::RuntimeException )
99 {
100         ::rtl::OUString sTypeName = OUString::createFromAscii("");
101         ::rtl::OUString sUrl = OUString::createFromAscii("");
102         ::rtl::OUString originalTypeName;
103         Sequence<PropertyValue > lProps ;
104 
105         com::sun::star::uno::Reference< com::sun::star::io::XInputStream > xInStream;
106 		com::sun::star::uno::Reference< com::sun::star::io::XInputStream > xIn;
107         ::rtl::OUString temp;
108 	    //OSL_ENSURE( sal_False, " starting Detect" );
109 		const PropertyValue * pValue = aArguments.getConstArray();
110 	    sal_Int32 nLength;
111         ::rtl::OString resultString;
112 
113         nLength = aArguments.getLength();
114         sal_Int32 location=nLength;
115 		for ( sal_Int32 i = 0 ; i < nLength; i++)
116 		{
117 		  	//OSL_ENSURE( sal_False, ::rtl::OUStringToOString(pValue[i].Name,RTL_TEXTENCODING_ASCII_US).getStr() );
118 			if ( pValue[i].Name.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "TypeName" ) ) )
119 			{
120 			      //pValue[i].Value >>= originalTypeName;
121                     location=i;
122                    // OSL_ENSURE( sal_False, ::rtl::OUStringToOString(sTypeName,RTL_TEXTENCODING_ASCII_US).getStr() );
123 
124 			}
125 			else if ( pValue[i].Name.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "URL" ) ) )
126 			{
127 
128 				pValue[i].Value >>= sUrl;
129                    //OSL_ENSURE( sal_False, ::rtl::OUStringToOString(sUrl,RTL_TEXTENCODING_ASCII_US).getStr() );
130 
131 			}
132 			else if ( pValue[i].Name.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "InputStream" ) ) )
133 			{
134 				pValue[i].Value >>= xInStream ;
135 				pValue[i].Value >>= xIn ;
136 			}
137 
138 		}
139         try{
140             Reference< com::sun::star::ucb::XCommandEnvironment > xEnv;
141     		if (!xInStream.is())
142              {
143             	::ucbhelper::Content aContent(sUrl,xEnv);
144             	xInStream = aContent.openStream();
145              	if (!xInStream.is())
146              	{
147                  		return sTypeName;
148              	}
149              }
150 		com::sun::star::uno::Sequence< sal_Int8 > aData;
151             /* long nBytesToRead= */ xInStream->available();
152             xInStream->skipBytes (0);
153             long bytestRead =xInStream->readBytes (aData,  4000);
154             resultString=::rtl::OString((const sal_Char *)aData.getConstArray(),bytestRead) ;
155 
156 
157              // test typedetect code
158             Reference <XNameAccess> xTypeCont(mxMSF->createInstance(OUString::createFromAscii("com.sun.star.document.TypeDetection")),UNO_QUERY);
159             Sequence < ::rtl::OUString > myTypes= xTypeCont->getElementNames();
160             nLength = myTypes.getLength();
161 
162 
163             sal_Int32 new_nlength=0;
164             sal_Int32 i = 0 ;
165  	        while(  (i < nLength) && (sTypeName.equalsAscii("")))
166             {
167 
168                 Any elem = xTypeCont->getByName(myTypes[i]);
169                 elem >>=lProps;
170                 new_nlength = lProps.getLength();
171                 sal_Int32 j =0;
172                 while( j < new_nlength && sTypeName.equalsAscii(""))
173                 {
174                     ::rtl::OUString tmpStr =OUString::createFromAscii("");
175                     lProps[j].Value >>=tmpStr;
176                     if((lProps[j].Name.equalsAscii("ClipboardFormat")) && (!tmpStr.equalsAscii("")) )
177                     {
178                         sTypeName = supportedByType(tmpStr,resultString, myTypes[i]);
179                     }
180                  j++;
181                 }
182             i++;
183         }
184         //end test
185 
186         }
187         catch(Exception &)
188         {
189                  OSL_ENSURE( sal_False, "An Exception occured while opening File stream" );
190         }
191         if(sTypeName.equalsAscii(""))
192         {
193             //sTypeName=::rtl::OUString::createFromAscii("writer_Flat_XML_File");
194 			//UOF v2.0 deep type detection
195 			if(sUrl.indexOf( ::rtl::OUString::createFromAscii(".uot") ) != -1 ||
196 				sUrl.indexOf( ::rtl::OUString::createFromAscii(".uos") ) != -1 ||
197 				sUrl.indexOf( ::rtl::OUString::createFromAscii(".uop") ) != -1)
198 			{
199 				if(xIn.is())
200 				{
201 					XSLT::UOF2Storage aUOF2Storage(mxMSF, xIn);
202 					if(aUOF2Storage.isValidUOF2Doc())
203 					{
204 						xIn->skipBytes(0);
205 						Reference< XInputStream > xUOFInputStream = aUOF2Storage.getMainStorageRef()->openInputStream(XSLT::UOFELEMNAME);
206 						if(xUOFInputStream.is())
207 						{
208 							Sequence< sal_Int8 > aSeq;
209 							xUOFInputStream->readBytes(aSeq, 2000);
210 							::rtl::OString sUOFXML( reinterpret_cast< sal_Char* >(aSeq.getArray()));
211 							OUString sOUSUOFXML( OStringToOUString(sUOFXML, RTL_TEXTENCODING_UTF8));
212 							if(sOUSUOFXML.getLength())
213 							{
214 								const OUString sText( OUString::createFromAscii("vnd.uof.text"));
215 								const OUString sCalc( OUString::createFromAscii("vnd.uof.spreadsheet"));
216 								const OUString sImpress( OUString::createFromAscii("vnd.uof.presentation"));
217 
218 								if(sOUSUOFXML.indexOf(sText) != -1)
219 									sTypeName = OUString::createFromAscii("writer_NSO_UOF2");
220 								else if(sOUSUOFXML.indexOf(sCalc) != -1)
221 									sTypeName = OUString::createFromAscii("calc_NSO_UOF2");
222 								else if(sOUSUOFXML.indexOf(sImpress) != -1)
223 									sTypeName = OUString::createFromAscii("impress_NSO_UOF2");
224 							}
225 						}
226 					}
227 				}
228 			}
229         }
230         else
231         {
232 			if ( location == aArguments.getLength() )
233 			{
234 				aArguments.realloc(nLength+1);
235 				aArguments[location].Name = ::rtl::OUString::createFromAscii( "TypeName" );
236 			}
237         	aArguments[location].Value <<=sTypeName;
238         }
239        // OSL_ENSURE( sal_False, ::rtl::OUStringToOString(sTypeName,RTL_TEXTENCODING_ASCII_US).getStr() );
240 
241 
242     return sTypeName;
243 }
244 
245 
246 
supportedByType(const::rtl::OUString clipBoardFormat,const::rtl::OString resultString,const::rtl::OUString checkType)247 ::rtl::OUString SAL_CALL supportedByType( const ::rtl::OUString clipBoardFormat ,  const ::rtl::OString resultString, const ::rtl::OUString checkType)
248 {
249 
250     ::rtl::OUString sTypeName= OUString::createFromAscii("");
251     if((clipBoardFormat.match(OUString::createFromAscii("doctype:"))))
252     {
253             ::rtl::OString tryStr = ::rtl::OUStringToOString(clipBoardFormat.copy(8),RTL_TEXTENCODING_ASCII_US).getStr();
254             // OSL_ENSURE( sal_False, tryStr);
255             if (resultString.indexOf(tryStr) >= 0)
256             {
257                     sTypeName = checkType;
258             }
259     }
260     return sTypeName;
261 }
262 
263 // XInitialization
264 
initialize(const Sequence<Any> & aArguments)265 void SAL_CALL FilterDetect::initialize( const Sequence< Any >& aArguments )
266 	throw (Exception, RuntimeException)
267 {
268 	Sequence < PropertyValue > aAnySeq;
269 	sal_Int32 nLength = aArguments.getLength();
270 	if ( nLength && ( aArguments[0] >>= aAnySeq ) )
271 	{
272 		const PropertyValue * pValue = aAnySeq.getConstArray();
273 		nLength = aAnySeq.getLength();
274 		for ( sal_Int32 i = 0 ; i < nLength; i++)
275 		{
276 
277 			if ( pValue[i].Name.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "Type" ) ) )
278 			{
279 			     pValue[i].Value >>= msFilterName;
280 
281 			}
282 			else if ( pValue[i].Name.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "UserData" ) ) )
283 			{
284 
285 				pValue[i].Value >>= msUserData;
286 
287 			}
288 			else if ( pValue[i].Name.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "TemplateName" ) ) )
289 			{
290 
291 			  pValue[i].Value>>=msTemplateName;
292 			}
293 
294 		}
295 	}
296 }
297 
298 
299 
FilterDetect_getImplementationName()300 OUString FilterDetect_getImplementationName ()
301 	throw (RuntimeException)
302 {
303 	return OUString ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.comp.filters.XMLFilterDetect" ) );
304 }
305 #define SERVICE_NAME1 "com.sun.star.document.ExtendedTypeDetection"
306 
FilterDetect_supportsService(const OUString & ServiceName)307 sal_Bool SAL_CALL FilterDetect_supportsService( const OUString& ServiceName )
308 	throw (RuntimeException)
309 {
310     return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME1 ) );
311 }
FilterDetect_getSupportedServiceNames()312 Sequence< OUString > SAL_CALL FilterDetect_getSupportedServiceNames(  )
313 	throw (RuntimeException)
314 {
315 	Sequence < OUString > aRet(2);
316     OUString* pArray = aRet.getArray();
317     pArray[0] =  OUString ( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME1 ) );
318     return aRet;
319 }
320 #undef SERVICE_NAME1
321 #undef SERVICE_NAME2
322 
FilterDetect_createInstance(const Reference<XMultiServiceFactory> & rSMgr)323 Reference< XInterface > SAL_CALL FilterDetect_createInstance( const Reference< XMultiServiceFactory > & rSMgr)
324 	throw( Exception )
325 {
326 	return (cppu::OWeakObject*) new FilterDetect( rSMgr );
327 }
328 
329 // XServiceInfo
getImplementationName()330 OUString SAL_CALL FilterDetect::getImplementationName(  )
331 	throw (RuntimeException)
332 {
333 	return FilterDetect_getImplementationName();
334 }
supportsService(const OUString & rServiceName)335 sal_Bool SAL_CALL FilterDetect::supportsService( const OUString& rServiceName )
336 	throw (RuntimeException)
337 {
338     return FilterDetect_supportsService( rServiceName );
339 }
getSupportedServiceNames()340 Sequence< OUString > SAL_CALL FilterDetect::getSupportedServiceNames(  )
341 	throw (RuntimeException)
342 {
343     return FilterDetect_getSupportedServiceNames();
344 }
345