1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
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
;
75 bool isXMLStream(const OString
& aHeaderStrm
)
77 const char* p
= aHeaderStrm
.getStr();
78 size_t n
= aHeaderStrm
.getLength();
81 // Skip all preceding blank characters.
82 for (i
= 0; i
< n
; ++i
, ++p
)
85 if (c
== ' ' || c
== '\n' || c
== '\t')
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
)
99 if (*p
!= sInitChars
[i
])
106 OUString
supportedByType( const OUString clipBoardFormat
, const OString resultString
, const OUString checkType
)
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
;
122 OUString SAL_CALL
FilterDetect::detect( com::sun::star::uno::Sequence
< com::sun::star::beans::PropertyValue
>& aArguments
) throw( com::sun::star::uno::RuntimeException
)
126 Sequence
<PropertyValue
> lProps
;
128 com::sun::star::uno::Reference
< com::sun::star::io::XInputStream
> xInStream
;
129 const PropertyValue
* pValue
= aArguments
.getConstArray();
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" )
141 else if ( pValue
[i
].Name
== "URL" )
143 pValue
[i
].Value
>>= sUrl
;
145 else if ( pValue
[i
].Name
== "InputStream" )
147 pValue
[i
].Value
>>= xInStream
;
154 ::ucbhelper::Content
aContent(
155 sUrl
, Reference
< com::sun::star::ucb::XCommandEnvironment
>(),
157 xInStream
= aContent
.openStream();
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.
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;
181 while ((i
< nLength
) && (sTypeName
.isEmpty()))
183 Any elem
= xTypeCont
->getByName(myTypes
[i
]);
185 new_nlength
= lProps
.getLength();
187 while (j
< new_nlength
&& (sTypeName
.isEmpty()))
190 lProps
[j
].Value
>>=tmpStr
;
191 if ( lProps
[j
].Name
== "ClipboardFormat" && !tmpStr
.isEmpty() )
193 sTypeName
= supportedByType(tmpStr
,resultString
, myTypes
[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
;
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
;
268 Reference
< XInterface
> FilterDetect_createInstance( const Reference
< XComponentContext
> & context
)
270 return static_cast< cppu::OWeakObject
* >( new FilterDetect( context
) );
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: */