1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_comphelper.hxx"
30 #include <com/sun/star/embed/ElementModes.hpp>
31 #include <com/sun/star/embed/XEncryptionProtectedSource.hpp>
32 #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
33 #include <com/sun/star/beans/XPropertySet.hpp>
34 #include <com/sun/star/beans/PropertyValue.hpp>
35 #include <com/sun/star/beans/IllegalTypeException.hpp>
37 #include <ucbhelper/content.hxx>
39 #include <comphelper/fileformat.h>
40 #include <comphelper/processfactory.hxx>
41 #include <comphelper/documentconstants.hxx>
43 #include <comphelper/storagehelper.hxx>
46 using namespace ::com::sun::star
;
48 namespace comphelper
{
50 // ----------------------------------------------------------------------
51 uno::Reference
< lang::XSingleServiceFactory
> OStorageHelper::GetStorageFactory(
52 const uno::Reference
< lang::XMultiServiceFactory
>& xSF
)
53 throw ( uno::Exception
)
55 uno::Reference
< lang::XMultiServiceFactory
> xFactory
= xSF
.is() ? xSF
: ::comphelper::getProcessServiceFactory();
57 throw uno::RuntimeException();
59 uno::Reference
< lang::XSingleServiceFactory
> xStorageFactory(
60 xFactory
->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.embed.StorageFactory" ) ),
63 if ( !xStorageFactory
.is() )
64 throw uno::RuntimeException();
66 return xStorageFactory
;
69 // ----------------------------------------------------------------------
70 uno::Reference
< lang::XSingleServiceFactory
> OStorageHelper::GetFileSystemStorageFactory(
71 const uno::Reference
< lang::XMultiServiceFactory
>& xSF
)
72 throw ( uno::Exception
)
74 uno::Reference
< lang::XMultiServiceFactory
> xFactory
= xSF
.is() ? xSF
: ::comphelper::getProcessServiceFactory();
76 throw uno::RuntimeException();
78 uno::Reference
< lang::XSingleServiceFactory
> xStorageFactory(
79 xFactory
->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.embed.FileSystemStorageFactory" ) ),
82 if ( !xStorageFactory
.is() )
83 throw uno::RuntimeException();
85 return xStorageFactory
;
88 // ----------------------------------------------------------------------
89 uno::Reference
< embed::XStorage
> OStorageHelper::GetTemporaryStorage(
90 const uno::Reference
< lang::XMultiServiceFactory
>& xFactory
)
91 throw ( uno::Exception
)
93 uno::Reference
< embed::XStorage
> xTempStorage( GetStorageFactory( xFactory
)->createInstance(),
95 if ( !xTempStorage
.is() )
96 throw uno::RuntimeException();
101 // ----------------------------------------------------------------------
102 uno::Reference
< embed::XStorage
> OStorageHelper::GetStorageFromURL(
103 const ::rtl::OUString
& aURL
,
104 sal_Int32 nStorageMode
,
105 const uno::Reference
< lang::XMultiServiceFactory
>& xFactory
)
106 throw ( uno::Exception
)
108 uno::Sequence
< uno::Any
> aArgs( 2 );
110 aArgs
[1] <<= nStorageMode
;
112 uno::Reference
< embed::XStorage
> xTempStorage( GetStorageFactory( xFactory
)->createInstanceWithArguments( aArgs
),
114 if ( !xTempStorage
.is() )
115 throw uno::RuntimeException();
120 // ----------------------------------------------------------------------
121 uno::Reference
< embed::XStorage
> OStorageHelper::GetStorageFromURL2(
122 const ::rtl::OUString
& aURL
,
123 sal_Int32 nStorageMode
,
124 const uno::Reference
< lang::XMultiServiceFactory
>& xFactory
)
125 throw ( uno::Exception
)
127 uno::Sequence
< uno::Any
> aArgs( 2 );
129 aArgs
[1] <<= nStorageMode
;
131 uno::Reference
< lang::XSingleServiceFactory
> xFact
;
133 ::ucbhelper::Content
aCntnt( aURL
,
134 uno::Reference
< ::com::sun::star::ucb::XCommandEnvironment
> () );
135 if (aCntnt
.isDocument()) {
136 xFact
= GetStorageFactory( xFactory
);
138 xFact
= GetFileSystemStorageFactory( xFactory
);
140 } catch (uno::Exception
&) { }
142 if (!xFact
.is()) throw uno::RuntimeException();
144 uno::Reference
< embed::XStorage
> xTempStorage(
145 xFact
->createInstanceWithArguments( aArgs
), uno::UNO_QUERY
);
146 if ( !xTempStorage
.is() )
147 throw uno::RuntimeException();
152 // ----------------------------------------------------------------------
153 uno::Reference
< embed::XStorage
> OStorageHelper::GetStorageFromInputStream(
154 const uno::Reference
< io::XInputStream
>& xStream
,
155 const uno::Reference
< lang::XMultiServiceFactory
>& xFactory
)
156 throw ( uno::Exception
)
158 uno::Sequence
< uno::Any
> aArgs( 2 );
159 aArgs
[0] <<= xStream
;
160 aArgs
[1] <<= embed::ElementModes::READ
;
162 uno::Reference
< embed::XStorage
> xTempStorage( GetStorageFactory( xFactory
)->createInstanceWithArguments( aArgs
),
164 if ( !xTempStorage
.is() )
165 throw uno::RuntimeException();
170 // ----------------------------------------------------------------------
171 uno::Reference
< embed::XStorage
> OStorageHelper::GetStorageFromStream(
172 const uno::Reference
< io::XStream
>& xStream
,
173 sal_Int32 nStorageMode
,
174 const uno::Reference
< lang::XMultiServiceFactory
>& xFactory
)
175 throw ( uno::Exception
)
177 uno::Sequence
< uno::Any
> aArgs( 2 );
178 aArgs
[0] <<= xStream
;
179 aArgs
[1] <<= nStorageMode
;
181 uno::Reference
< embed::XStorage
> xTempStorage( GetStorageFactory( xFactory
)->createInstanceWithArguments( aArgs
),
183 if ( !xTempStorage
.is() )
184 throw uno::RuntimeException();
189 // ----------------------------------------------------------------------
190 void OStorageHelper::CopyInputToOutput(
191 const uno::Reference
< io::XInputStream
>& xInput
,
192 const uno::Reference
< io::XOutputStream
>& xOutput
)
193 throw ( uno::Exception
)
195 static const sal_Int32 nConstBufferSize
= 32000;
198 uno::Sequence
< sal_Int8
> aSequence ( nConstBufferSize
);
202 nRead
= xInput
->readBytes ( aSequence
, nConstBufferSize
);
203 if ( nRead
< nConstBufferSize
)
205 uno::Sequence
< sal_Int8
> aTempBuf ( aSequence
.getConstArray(), nRead
);
206 xOutput
->writeBytes ( aTempBuf
);
209 xOutput
->writeBytes ( aSequence
);
211 while ( nRead
== nConstBufferSize
);
214 // ----------------------------------------------------------------------
215 uno::Reference
< io::XInputStream
> OStorageHelper::GetInputStreamFromURL(
216 const ::rtl::OUString
& aURL
,
217 const uno::Reference
< lang::XMultiServiceFactory
>& xSF
)
218 throw ( uno::Exception
)
220 uno::Reference
< lang::XMultiServiceFactory
> xFactory
= xSF
.is() ? xSF
: ::comphelper::getProcessServiceFactory();
221 if ( !xFactory
.is() )
222 throw uno::RuntimeException();
224 uno::Reference
< ::com::sun::star::ucb::XSimpleFileAccess
> xTempAccess(
225 xFactory
->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ),
228 if ( !xTempAccess
.is() )
229 throw uno::RuntimeException();
231 uno::Reference
< io::XInputStream
> xInputStream
= xTempAccess
->openFileRead( aURL
);
232 if ( !xInputStream
.is() )
233 throw uno::RuntimeException();
238 // ----------------------------------------------------------------------
239 void OStorageHelper::SetCommonStoragePassword(
240 const uno::Reference
< embed::XStorage
>& xStorage
,
241 const ::rtl::OUString
& aPass
)
242 throw ( uno::Exception
)
244 uno::Reference
< embed::XEncryptionProtectedSource
> xEncrSet( xStorage
, uno::UNO_QUERY
);
245 if ( !xEncrSet
.is() )
246 throw io::IOException(); // TODO
248 xEncrSet
->setEncryptionPassword( aPass
);
251 // ----------------------------------------------------------------------
252 sal_Int32
OStorageHelper::GetXStorageFormat(
253 const uno::Reference
< embed::XStorage
>& xStorage
)
254 throw ( uno::Exception
)
256 uno::Reference
< beans::XPropertySet
> xStorProps( xStorage
, uno::UNO_QUERY_THROW
);
258 ::rtl::OUString aMediaType
;
259 xStorProps
->getPropertyValue( ::rtl::OUString::createFromAscii( "MediaType" ) ) >>= aMediaType
;
261 sal_Int32 nResult
= 0;
263 // TODO/LATER: the filter configuration could be used to detect it later, or batter a special service
265 aMediaType
.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_WRITER_ASCII
) ||
266 aMediaType
.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_WRITER_WEB_ASCII
) ||
267 aMediaType
.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_WRITER_GLOBAL_ASCII
) ||
268 aMediaType
.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_DRAW_ASCII
) ||
269 aMediaType
.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_IMPRESS_ASCII
) ||
270 aMediaType
.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_CALC_ASCII
) ||
271 aMediaType
.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_CHART_ASCII
) ||
272 aMediaType
.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_MATH_ASCII
)
275 nResult
= SOFFICE_FILEFORMAT_60
;
279 aMediaType
.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_TEXT_ASCII
) ||
280 aMediaType
.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_TEXT_WEB_ASCII
) ||
281 aMediaType
.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_TEXT_GLOBAL_ASCII
) ||
282 aMediaType
.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_ASCII
) ||
283 aMediaType
.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_ASCII
) ||
284 aMediaType
.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_ASCII
) ||
285 aMediaType
.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_CHART_ASCII
) ||
286 aMediaType
.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_ASCII
) ||
287 aMediaType
.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_DATABASE_ASCII
) ||
288 aMediaType
.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_REPORT_ASCII
) ||
289 aMediaType
.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_REPORT_CHART_ASCII
) ||
290 aMediaType
.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_TEXT_TEMPLATE_ASCII
) ||
291 aMediaType
.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_TEMPLATE_ASCII
) ||
292 aMediaType
.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_TEMPLATE_ASCII
) ||
293 aMediaType
.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_TEMPLATE_ASCII
) ||
294 aMediaType
.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_CHART_TEMPLATE_ASCII
) ||
295 aMediaType
.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_TEMPLATE_ASCII
)
298 nResult
= SOFFICE_FILEFORMAT_8
;
302 // the mediatype is not known
303 throw beans::IllegalTypeException();
309 // ----------------------------------------------------------------------
310 uno::Reference
< embed::XStorage
> OStorageHelper::GetTemporaryStorageOfFormat(
311 const ::rtl::OUString
& aFormat
,
312 const uno::Reference
< lang::XMultiServiceFactory
>& xFactory
)
313 throw ( uno::Exception
)
315 uno::Reference
< lang::XMultiServiceFactory
> xFactoryToUse
= xFactory
.is() ? xFactory
: ::comphelper::getProcessServiceFactory();
316 if ( !xFactoryToUse
.is() )
317 throw uno::RuntimeException();
319 uno::Reference
< io::XStream
> xTmpStream(
320 xFactoryToUse
->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.TempFile" ) ) ),
321 uno::UNO_QUERY_THROW
);
323 return GetStorageOfFormatFromStream( aFormat
, xTmpStream
, embed::ElementModes::READWRITE
, xFactoryToUse
);
326 // ----------------------------------------------------------------------
327 uno::Reference
< embed::XStorage
> OStorageHelper::GetStorageOfFormatFromURL(
328 const ::rtl::OUString
& aFormat
,
329 const ::rtl::OUString
& aURL
,
330 sal_Int32 nStorageMode
,
331 const uno::Reference
< lang::XMultiServiceFactory
>& xFactory
,
332 sal_Bool bRepairStorage
)
333 throw ( uno::Exception
)
335 uno::Sequence
< beans::PropertyValue
> aProps( 1 );
336 aProps
[0].Name
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StorageFormat" ) );
337 aProps
[0].Value
<<= aFormat
;
338 if ( bRepairStorage
)
341 aProps
[1].Name
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RepairPackage" ) );
342 aProps
[1].Value
<<= bRepairStorage
;
345 uno::Sequence
< uno::Any
> aArgs( 3 );
347 aArgs
[1] <<= nStorageMode
;
350 uno::Reference
< embed::XStorage
> xTempStorage( GetStorageFactory( xFactory
)->createInstanceWithArguments( aArgs
),
352 if ( !xTempStorage
.is() )
353 throw uno::RuntimeException();
358 // ----------------------------------------------------------------------
359 uno::Reference
< embed::XStorage
> OStorageHelper::GetStorageOfFormatFromInputStream(
360 const ::rtl::OUString
& aFormat
,
361 const uno::Reference
< io::XInputStream
>& xStream
,
362 const uno::Reference
< lang::XMultiServiceFactory
>& xFactory
,
363 sal_Bool bRepairStorage
)
364 throw ( uno::Exception
)
366 uno::Sequence
< beans::PropertyValue
> aProps( 1 );
367 aProps
[0].Name
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StorageFormat" ) );
368 aProps
[0].Value
<<= aFormat
;
369 if ( bRepairStorage
)
372 aProps
[1].Name
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RepairPackage" ) );
373 aProps
[1].Value
<<= bRepairStorage
;
376 uno::Sequence
< uno::Any
> aArgs( 3 );
377 aArgs
[0] <<= xStream
;
378 aArgs
[1] <<= embed::ElementModes::READ
;
381 uno::Reference
< embed::XStorage
> xTempStorage( GetStorageFactory( xFactory
)->createInstanceWithArguments( aArgs
),
383 if ( !xTempStorage
.is() )
384 throw uno::RuntimeException();
389 // ----------------------------------------------------------------------
390 uno::Reference
< embed::XStorage
> OStorageHelper::GetStorageOfFormatFromStream(
391 const ::rtl::OUString
& aFormat
,
392 const uno::Reference
< io::XStream
>& xStream
,
393 sal_Int32 nStorageMode
,
394 const uno::Reference
< lang::XMultiServiceFactory
>& xFactory
,
395 sal_Bool bRepairStorage
)
396 throw ( uno::Exception
)
398 uno::Sequence
< beans::PropertyValue
> aProps( 1 );
399 aProps
[0].Name
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StorageFormat" ) );
400 aProps
[0].Value
<<= aFormat
;
401 if ( bRepairStorage
)
404 aProps
[1].Name
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RepairPackage" ) );
405 aProps
[1].Value
<<= bRepairStorage
;
408 uno::Sequence
< uno::Any
> aArgs( 3 );
409 aArgs
[0] <<= xStream
;
410 aArgs
[1] <<= nStorageMode
;
413 uno::Reference
< embed::XStorage
> xTempStorage( GetStorageFactory( xFactory
)->createInstanceWithArguments( aArgs
),
415 if ( !xTempStorage
.is() )
416 throw uno::RuntimeException();
421 // ----------------------------------------------------------------------
422 sal_Bool
OStorageHelper::IsValidZipEntryFileName( const ::rtl::OUString
& aName
, sal_Bool bSlashAllowed
)
424 return IsValidZipEntryFileName( aName
.getStr(), aName
.getLength(), bSlashAllowed
);
427 // ----------------------------------------------------------------------
428 sal_Bool
OStorageHelper::IsValidZipEntryFileName(
429 const sal_Unicode
*pChar
, sal_Int32 nLength
, sal_Bool bSlashAllowed
)
431 for ( sal_Int32 i
= 0; i
< nLength
; i
++ )
444 if ( !bSlashAllowed
)
448 if ( pChar
[i
] < 32 || (pChar
[i
] >= 0xD800 && pChar
[i
] <= 0xDFFF) )
455 // ----------------------------------------------------------------------
456 sal_Bool
OStorageHelper::PathHasSegment( const ::rtl::OUString
& aPath
, const ::rtl::OUString
& aSegment
)
458 sal_Bool bResult
= sal_False
;
459 const sal_Int32 nPathLen
= aPath
.getLength();
460 const sal_Int32 nSegLen
= aSegment
.getLength();
462 if ( nSegLen
&& nPathLen
>= nSegLen
)
464 ::rtl::OUString
aEndSegment( RTL_CONSTASCII_USTRINGPARAM( "/" ) );
465 aEndSegment
+= aSegment
;
467 ::rtl::OUString
aInternalSegment( aEndSegment
);
468 aInternalSegment
+= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) );
470 if ( aPath
.indexOf( aInternalSegment
) >= 0 )
473 if ( !bResult
&& !aPath
.compareTo( aSegment
, nSegLen
) )
475 if ( nPathLen
== nSegLen
|| aPath
.getStr()[nSegLen
] == (sal_Unicode
)'/' )
479 if ( !bResult
&& nPathLen
> nSegLen
&& aPath
.copy( nPathLen
- nSegLen
- 1, nSegLen
+ 1 ).equals( aEndSegment
) )