bump product version to 4.1.6.2
[LibreOffice.git] / filter / source / xmlfilterdetect / filterdetect.cxx
blobe665f9d738b93c6d1089468efdb9edf6089755e1
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <iostream>
21 #include <stdlib.h>
22 #include <ctype.h>
23 #include <stdio.h>
24 #include <cstring>
25 #include "filterdetect.hxx"
26 #include <osl/diagnose.h>
27 #include <com/sun/star/io/XActiveDataSource.hpp>
28 #include <com/sun/star/io/XOutputStream.hpp>
29 #include <com/sun/star/io/XInputStream.hpp>
30 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
31 #include <com/sun/star/xml/sax/InputSource.hpp>
32 #include <com/sun/star/xml/sax/XParser.hpp>
33 #include <com/sun/star/xml/XImportFilter.hpp>
34 #include <com/sun/star/xml/XExportFilter.hpp>
35 #include <com/sun/star/frame/XController.hpp>
36 #include <com/sun/star/task/XStatusIndicator.hpp>
37 #include <com/sun/star/task/XStatusIndicatorFactory.hpp>
38 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
39 #include <com/sun/star/style/XStyleLoader.hpp>
40 #include <com/sun/star/uno/XComponentContext.hpp>
41 #include <com/sun/star/document/XExtendedFilterDetection.hpp>
42 #include <com/sun/star/container/XNameAccess.hpp>
43 #include <com/sun/star/beans/PropertyState.hpp>
44 #include <ucbhelper/content.hxx>
46 using com::sun::star::uno::Sequence;
47 using com::sun::star::uno::Reference;
48 using com::sun::star::uno::Any;
49 using com::sun::star::uno::UNO_QUERY;
50 using com::sun::star::uno::XComponentContext;
51 using com::sun::star::uno::XInterface;
52 using com::sun::star::uno::Exception;
53 using com::sun::star::uno::RuntimeException;
54 using com::sun::star::io::XActiveDataSource;
55 using com::sun::star::io::XOutputStream;
56 using com::sun::star::beans::PropertyValue;
57 using com::sun::star::document::XExporter;
58 using com::sun::star::document::XFilter;
59 using com::sun::star::document::XExtendedFilterDetection;
61 using com::sun::star::io::XInputStream;
62 using com::sun::star::document::XImporter;
63 using com::sun::star::xml::sax::InputSource;
64 using com::sun::star::xml::sax::XDocumentHandler;
65 using com::sun::star::xml::sax::XParser;
67 using namespace ::com::sun::star::frame;
68 using namespace ::com::sun::star;
69 using namespace com::sun::star::container;
70 using namespace com::sun::star::uno;
71 using namespace com::sun::star::beans;
73 namespace {
75 bool isXMLStream(const OString& aHeaderStrm)
77 const char* p = aHeaderStrm.getStr();
78 size_t n = aHeaderStrm.getLength();
79 size_t i = 0;
81 // Skip all preceding blank characters.
82 for (i = 0; i < n; ++i, ++p)
84 sal_Char c = *p;
85 if (c == ' ' || c == '\n' || c == '\t')
86 continue;
87 break;
90 n -= i;
92 // First text must be '<?xml', else it's not a valid XML file stream.
93 const char* sInitChars = "<?xml";
94 const size_t nInitCharLen = std::strlen(sInitChars);
95 for (i = 0; i < n; ++i, ++p)
97 if (i < nInitCharLen)
99 if (*p != sInitChars[i])
100 return false;
103 return true;
106 OUString supportedByType( const OUString clipBoardFormat , const OString resultString, const OUString checkType)
108 OUString sTypeName;
109 if ( clipBoardFormat.match(OUString("doctype:")) )
111 OString tryStr = OUStringToOString(clipBoardFormat.copy(8),RTL_TEXTENCODING_ASCII_US).getStr();
112 if (resultString.indexOf(tryStr) >= 0)
114 sTypeName = checkType;
117 return sTypeName;
122 OUString SAL_CALL FilterDetect::detect( com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >& aArguments ) throw( com::sun::star::uno::RuntimeException )
124 OUString sTypeName;
125 OUString sUrl;
126 Sequence<PropertyValue > lProps ;
128 com::sun::star::uno::Reference< com::sun::star::io::XInputStream > xInStream;
129 const PropertyValue * pValue = aArguments.getConstArray();
130 sal_Int32 nLength;
131 OString resultString;
133 nLength = aArguments.getLength();
134 sal_Int32 location=nLength;
135 for (sal_Int32 i = 0 ; i < nLength; i++)
137 if ( pValue[i].Name == "TypeName" )
139 location=i;
141 else if ( pValue[i].Name == "URL" )
143 pValue[i].Value >>= sUrl;
145 else if ( pValue[i].Name == "InputStream" )
147 pValue[i].Value >>= xInStream ;
152 if (!xInStream.is())
154 ::ucbhelper::Content aContent(
155 sUrl, Reference< com::sun::star::ucb::XCommandEnvironment >(),
156 mxCtx);
157 xInStream = aContent.openStream();
158 if (!xInStream.is())
160 return sTypeName;
163 com::sun::star::uno::Sequence< sal_Int8 > aData;
164 /* long nBytesToRead= */ xInStream->available();
165 xInStream->skipBytes (0);
166 long bytestRead =xInStream->readBytes (aData, 4000);
167 resultString=OString((const sal_Char *)aData.getConstArray(),bytestRead) ;
169 if (!isXMLStream(resultString))
170 // This is not an XML stream. It makes no sense to try to detect
171 // a non-XML file type here.
172 return OUString();
174 // test typedetect code
175 Reference <XNameAccess> xTypeCont(mxCtx->getServiceManager()->createInstanceWithContext("com.sun.star.document.TypeDetection", mxCtx), UNO_QUERY);
176 Sequence < OUString > myTypes= xTypeCont->getElementNames();
177 nLength = myTypes.getLength();
179 sal_Int32 new_nlength=0;
180 sal_Int32 i = 0 ;
181 while ((i < nLength) && (sTypeName.isEmpty()))
183 Any elem = xTypeCont->getByName(myTypes[i]);
184 elem >>=lProps;
185 new_nlength = lProps.getLength();
186 sal_Int32 j =0;
187 while (j < new_nlength && (sTypeName.isEmpty()))
189 OUString tmpStr;
190 lProps[j].Value >>=tmpStr;
191 if ( lProps[j].Name == "ClipboardFormat" && !tmpStr.isEmpty() )
193 sTypeName = supportedByType(tmpStr,resultString, myTypes[i]);
195 j++;
197 i++;
200 catch (const Exception &)
202 OSL_FAIL( "An Exception occurred while opening File stream" );
205 if (!sTypeName.isEmpty())
207 if (location == aArguments.getLength())
209 aArguments.realloc(nLength+1);
210 aArguments[location].Name = OUString( "TypeName" );
212 aArguments[location].Value <<=sTypeName;
215 return sTypeName;
218 // XInitialization
220 void SAL_CALL FilterDetect::initialize( const Sequence< Any >& aArguments )
221 throw (Exception, RuntimeException)
223 Sequence < PropertyValue > aAnySeq;
224 sal_Int32 nLength = aArguments.getLength();
225 if ( nLength && ( aArguments[0] >>= aAnySeq ) )
227 const PropertyValue * pValue = aAnySeq.getConstArray();
228 nLength = aAnySeq.getLength();
229 for ( sal_Int32 i = 0 ; i < nLength; i++)
232 if ( pValue[i].Name == "Type" )
234 pValue[i].Value >>= msFilterName;
237 else if ( pValue[i].Name == "UserData" )
240 pValue[i].Value >>= msUserData;
243 else if ( pValue[i].Name == "TemplateName" )
246 pValue[i].Value>>=msTemplateName;
255 OUString FilterDetect_getImplementationName ()
257 return OUString( "com.sun.star.comp.filters.XMLFilterDetect" );
259 #define SERVICE_NAME1 "com.sun.star.document.ExtendedTypeDetection"
261 Sequence< OUString > FilterDetect_getSupportedServiceNames()
263 Sequence < OUString > aRet(1);
264 aRet[0] = SERVICE_NAME1;
265 return aRet;
268 Reference< XInterface > FilterDetect_createInstance( const Reference< XComponentContext > & context)
270 return static_cast< cppu::OWeakObject * >( new FilterDetect( context ) );
273 // XServiceInfo
274 OUString SAL_CALL FilterDetect::getImplementationName( )
275 throw (RuntimeException)
277 return FilterDetect_getImplementationName();
279 sal_Bool SAL_CALL FilterDetect::supportsService( const OUString& rServiceName )
280 throw (RuntimeException)
282 return rServiceName == SERVICE_NAME1;
284 Sequence< OUString > SAL_CALL FilterDetect::getSupportedServiceNames( )
285 throw (RuntimeException)
287 return FilterDetect_getSupportedServiceNames();
290 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */