Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <iostream>
30 : : #include <stdlib.h>
31 : : #include <ctype.h>
32 : : #include <stdio.h>
33 : : #include <cstring>
34 : : #include "filterdetect.hxx"
35 : : #include <osl/diagnose.h>
36 : : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
37 : : #include <com/sun/star/io/XActiveDataSource.hpp>
38 : : #include <com/sun/star/io/XOutputStream.hpp>
39 : : #include <com/sun/star/io/XInputStream.hpp>
40 : : #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
41 : : #include <com/sun/star/xml/sax/InputSource.hpp>
42 : : #include <com/sun/star/xml/sax/XParser.hpp>
43 : : #include <com/sun/star/xml/XImportFilter.hpp>
44 : : #include <com/sun/star/xml/XExportFilter.hpp>
45 : : #include <com/sun/star/frame/XController.hpp>
46 : : #include <com/sun/star/task/XStatusIndicator.hpp>
47 : : #include <com/sun/star/task/XStatusIndicatorFactory.hpp>
48 : : #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
49 : : #include <com/sun/star/style/XStyleLoader.hpp>
50 : : #include <com/sun/star/document/XExtendedFilterDetection.hpp>
51 : : #include <com/sun/star/container/XNameAccess.hpp>
52 : : #include <com/sun/star/beans/PropertyState.hpp>
53 : :
54 : : #include <ucbhelper/content.hxx>
55 : : #include <ucbhelper/contentbroker.hxx>
56 : : #include <ucbhelper/commandenvironment.hxx>
57 : : #include <unotools/ucbhelper.hxx>
58 : : #include <com/sun/star/ucb/XCommandEnvironment.hpp>
59 : :
60 : :
61 : :
62 : : using rtl::OUString;
63 : : using com::sun::star::uno::Sequence;
64 : : using com::sun::star::uno::Reference;
65 : : using com::sun::star::uno::Any;
66 : : using com::sun::star::uno::UNO_QUERY;
67 : : using com::sun::star::uno::XInterface;
68 : : using com::sun::star::uno::Exception;
69 : : using com::sun::star::uno::RuntimeException;
70 : : using com::sun::star::lang::XMultiServiceFactory;
71 : : using com::sun::star::io::XActiveDataSource;
72 : : using com::sun::star::io::XOutputStream;
73 : : using com::sun::star::beans::PropertyValue;
74 : : using com::sun::star::document::XExporter;
75 : : using com::sun::star::document::XFilter;
76 : : using com::sun::star::document::XExtendedFilterDetection;
77 : :
78 : : using com::sun::star::io::XInputStream;
79 : : using com::sun::star::document::XImporter;
80 : : using com::sun::star::xml::sax::InputSource;
81 : : using com::sun::star::xml::sax::XDocumentHandler;
82 : : using com::sun::star::xml::sax::XParser;
83 : : using com::sun::star::task::XInteractionHandler;
84 : :
85 : : using namespace ::com::sun::star::frame;
86 : : using namespace ::com::sun::star;
87 : : using namespace com::sun::star::container;
88 : : using namespace com::sun::star::uno;
89 : : using namespace com::sun::star::beans;
90 : :
91 : : namespace {
92 : :
93 : 16 : bool isXMLStream(const ::rtl::OString& aHeaderStrm)
94 : : {
95 : 16 : const char* p = aHeaderStrm.getStr();
96 : 16 : size_t n = aHeaderStrm.getLength();
97 : 16 : size_t i = 0;
98 : :
99 : : // Skip all preceding blank characters.
100 [ + - ]: 16 : for (i = 0; i < n; ++i, ++p)
101 : : {
102 : 16 : sal_Char c = *p;
103 [ + - ][ + - ]: 16 : if (c == ' ' || c == '\n' || c == '\t')
[ - + ]
104 : 0 : continue;
105 : 16 : break;
106 : : }
107 : :
108 : 16 : n -= i;
109 : :
110 : : // First text must be '<?xml', else it's not a valid XML file stream.
111 : 16 : const char* sInitChars = "<?xml";
112 : 16 : const size_t nInitCharLen = std::strlen(sInitChars);
113 [ + - ]: 18 : for (i = 0; i < n; ++i, ++p)
114 : : {
115 [ + - ]: 18 : if (i < nInitCharLen)
116 : : {
117 [ + + ]: 18 : if (*p != sInitChars[i])
118 : 16 : return false;
119 : : }
120 : : }
121 : 16 : return true;
122 : : }
123 : :
124 : 0 : ::rtl::OUString supportedByType( const ::rtl::OUString clipBoardFormat , const ::rtl::OString resultString, const ::rtl::OUString checkType)
125 : : {
126 : 0 : ::rtl::OUString sTypeName;
127 [ # # ]: 0 : if ( clipBoardFormat.match(OUString("doctype:")) )
128 : : {
129 [ # # ]: 0 : ::rtl::OString tryStr = ::rtl::OUStringToOString(clipBoardFormat.copy(8),RTL_TEXTENCODING_ASCII_US).getStr();
130 [ # # ]: 0 : if (resultString.indexOf(tryStr) >= 0)
131 : : {
132 : 0 : sTypeName = checkType;
133 : 0 : }
134 : : }
135 : 0 : return sTypeName;
136 : : }
137 : :
138 : : }
139 : :
140 : 16 : ::rtl::OUString SAL_CALL FilterDetect::detect( com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >& aArguments ) throw( com::sun::star::uno::RuntimeException )
141 : : {
142 : 16 : ::rtl::OUString sTypeName;
143 : 16 : ::rtl::OUString sUrl;
144 [ + - ]: 16 : Sequence<PropertyValue > lProps ;
145 : :
146 : 16 : com::sun::star::uno::Reference< com::sun::star::io::XInputStream > xInStream;
147 : 16 : const PropertyValue * pValue = aArguments.getConstArray();
148 : : sal_Int32 nLength;
149 : 16 : ::rtl::OString resultString;
150 : :
151 : 16 : nLength = aArguments.getLength();
152 : 16 : sal_Int32 location=nLength;
153 [ + + ]: 140 : for (sal_Int32 i = 0 ; i < nLength; i++)
154 : : {
155 [ + + ]: 124 : if ( pValue[i].Name == "TypeName" )
156 : : {
157 : 6 : location=i;
158 : : }
159 [ + + ]: 118 : else if ( pValue[i].Name == "URL" )
160 : : {
161 : 16 : pValue[i].Value >>= sUrl;
162 : : }
163 [ + + ]: 102 : else if ( pValue[i].Name == "InputStream" )
164 : : {
165 [ + - ]: 16 : pValue[i].Value >>= xInStream ;
166 : : }
167 : : }
168 : : try
169 : : {
170 : 16 : Reference< com::sun::star::ucb::XCommandEnvironment > xEnv;
171 [ - + ]: 16 : if (!xInStream.is())
172 : : {
173 [ # # ]: 0 : ::ucbhelper::Content aContent(sUrl,xEnv);
174 [ # # ][ # # ]: 0 : xInStream = aContent.openStream();
175 [ # # ]: 0 : if (!xInStream.is())
176 : : {
177 : 0 : return sTypeName;
178 [ # # ][ # # ]: 0 : }
179 : : }
180 [ + - ]: 16 : com::sun::star::uno::Sequence< sal_Int8 > aData;
181 [ + - ][ + - ]: 16 : /* long nBytesToRead= */ xInStream->available();
182 [ + - ][ + - ]: 16 : xInStream->skipBytes (0);
183 [ + - ][ + - ]: 16 : long bytestRead =xInStream->readBytes (aData, 4000);
184 : 16 : resultString=::rtl::OString((const sal_Char *)aData.getConstArray(),bytestRead) ;
185 : :
186 [ + - ]: 16 : if (!isXMLStream(resultString))
187 : : // This is not an XML stream. It makes no sense to try to detect
188 : : // a non-XML file type here.
189 : 16 : return ::rtl::OUString();
190 : :
191 : : // test typedetect code
192 [ # # ][ # # ]: 0 : Reference <XNameAccess> xTypeCont(mxMSF->createInstance(OUString( "com.sun.star.document.TypeDetection" )),UNO_QUERY);
[ # # ]
193 [ # # ][ # # ]: 0 : Sequence < ::rtl::OUString > myTypes= xTypeCont->getElementNames();
194 : 0 : nLength = myTypes.getLength();
195 : :
196 : 0 : sal_Int32 new_nlength=0;
197 : 0 : sal_Int32 i = 0 ;
198 [ # # ][ # # ]: 0 : while ((i < nLength) && (sTypeName.isEmpty()))
[ # # ]
199 : : {
200 [ # # ][ # # ]: 0 : Any elem = xTypeCont->getByName(myTypes[i]);
[ # # ]
201 [ # # ]: 0 : elem >>=lProps;
202 : 0 : new_nlength = lProps.getLength();
203 : 0 : sal_Int32 j =0;
204 [ # # ][ # # ]: 0 : while (j < new_nlength && (sTypeName.isEmpty()))
[ # # ]
205 : : {
206 : 0 : ::rtl::OUString tmpStr;
207 [ # # ]: 0 : lProps[j].Value >>=tmpStr;
208 [ # # ][ # # ]: 0 : if ( lProps[j].Name == "ClipboardFormat" && !tmpStr.isEmpty() )
[ # # ][ # # ]
209 : : {
210 [ # # ][ # # ]: 0 : sTypeName = supportedByType(tmpStr,resultString, myTypes[i]);
211 : : }
212 : 0 : j++;
213 : 0 : }
214 : 0 : i++;
215 [ # # ][ + - ]: 16 : }
[ + - ][ - + ]
[ # # ]
216 : : }
217 [ # # ]: 0 : catch (const Exception &)
218 : : {
219 : : OSL_FAIL( "An Exception occurred while opening File stream" );
220 : : }
221 : :
222 [ # # ]: 0 : if (!sTypeName.isEmpty())
223 : : {
224 [ # # ]: 0 : if (location == aArguments.getLength())
225 : : {
226 [ # # ]: 0 : aArguments.realloc(nLength+1);
227 [ # # ]: 0 : aArguments[location].Name = ::rtl::OUString( "TypeName" );
228 : : }
229 [ # # ][ # # ]: 0 : aArguments[location].Value <<=sTypeName;
230 : : }
231 : :
232 [ + - ]: 16 : return sTypeName;
233 : : }
234 : :
235 : : // XInitialization
236 : :
237 : 0 : void SAL_CALL FilterDetect::initialize( const Sequence< Any >& aArguments )
238 : : throw (Exception, RuntimeException)
239 : : {
240 [ # # ]: 0 : Sequence < PropertyValue > aAnySeq;
241 : 0 : sal_Int32 nLength = aArguments.getLength();
242 [ # # ][ # # ]: 0 : if ( nLength && ( aArguments[0] >>= aAnySeq ) )
[ # # ][ # # ]
243 : : {
244 : 0 : const PropertyValue * pValue = aAnySeq.getConstArray();
245 : 0 : nLength = aAnySeq.getLength();
246 [ # # ]: 0 : for ( sal_Int32 i = 0 ; i < nLength; i++)
247 : : {
248 : :
249 [ # # ]: 0 : if ( pValue[i].Name == "Type" )
250 : : {
251 : 0 : pValue[i].Value >>= msFilterName;
252 : :
253 : : }
254 [ # # ]: 0 : else if ( pValue[i].Name == "UserData" )
255 : : {
256 : :
257 [ # # ]: 0 : pValue[i].Value >>= msUserData;
258 : :
259 : : }
260 [ # # ]: 0 : else if ( pValue[i].Name == "TemplateName" )
261 : : {
262 : :
263 : 0 : pValue[i].Value>>=msTemplateName;
264 : : }
265 : :
266 : : }
267 [ # # ]: 0 : }
268 : 0 : }
269 : :
270 : :
271 : :
272 : 8 : OUString FilterDetect_getImplementationName ()
273 : : throw (RuntimeException)
274 : : {
275 : 8 : return OUString ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.comp.filters.XMLFilterDetect" ) );
276 : : }
277 : : #define SERVICE_NAME1 "com.sun.star.document.ExtendedTypeDetection"
278 : :
279 : 0 : sal_Bool SAL_CALL FilterDetect_supportsService( const OUString& ServiceName )
280 : : throw (RuntimeException)
281 : : {
282 : 0 : return ServiceName == SERVICE_NAME1;
283 : : }
284 : 8 : Sequence< OUString > SAL_CALL FilterDetect_getSupportedServiceNames( )
285 : : throw (RuntimeException)
286 : : {
287 : 8 : Sequence < OUString > aRet(2);
288 [ + - ]: 8 : OUString* pArray = aRet.getArray();
289 [ + - ]: 8 : pArray[0] = OUString ( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME1 ) );
290 : 8 : return aRet;
291 : : }
292 : : #undef SERVICE_NAME1
293 : : #undef SERVICE_NAME2
294 : :
295 : 16 : Reference< XInterface > SAL_CALL FilterDetect_createInstance( const Reference< XMultiServiceFactory > & rSMgr)
296 : : throw( Exception )
297 : : {
298 [ + - ]: 16 : return (cppu::OWeakObject*) new FilterDetect( rSMgr );
299 : : }
300 : :
301 : : // XServiceInfo
302 : 0 : OUString SAL_CALL FilterDetect::getImplementationName( )
303 : : throw (RuntimeException)
304 : : {
305 : 0 : return FilterDetect_getImplementationName();
306 : : }
307 : 0 : sal_Bool SAL_CALL FilterDetect::supportsService( const OUString& rServiceName )
308 : : throw (RuntimeException)
309 : : {
310 : 0 : return FilterDetect_supportsService( rServiceName );
311 : : }
312 : 0 : Sequence< OUString > SAL_CALL FilterDetect::getSupportedServiceNames( )
313 : : throw (RuntimeException)
314 : : {
315 : 0 : return FilterDetect_getSupportedServiceNames();
316 [ + - ][ + - ]: 24 : }
317 : :
318 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|