1 /*************************************************************************
3 * The Contents of this file are made available subject to the terms of
4 * either of the following licenses
6 * - GNU Lesser General Public License Version 2.1
7 * - Sun Industry Standards Source License Version 1.1
9 * Sun Microsystems Inc., October, 2000
11 * GNU Lesser General Public License Version 2.1
12 * =============================================
13 * Copyright 2000 by Sun Microsystems, Inc.
14 * 901 San Antonio Road, Palo Alto, CA 94303, USA
16 * This library is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU Lesser General Public
18 * License version 2.1, as published by the Free Software Foundation.
20 * This library is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * Lesser General Public License for more details.
25 * You should have received a copy of the GNU Lesser General Public
26 * License along with this library; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
31 * Sun Industry Standards Source License Version 1.1
32 * =================================================
33 * The contents of this file are subject to the Sun Industry Standards
34 * Source License Version 1.1 (the "License"); You may not use this file
35 * except in compliance with the License. You may obtain a copy of the
36 * License at http://www.openoffice.org/license.html.
38 * Software provided under this License is provided on an "AS IS" basis,
39 * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
40 * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
41 * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
42 * See the License for the specific provisions governing your rights and
43 * obligations concerning the Software.
45 * The Initial Developer of the Original Code is: IBM Corporation
47 * Copyright: 2008 by IBM Corporation
49 * All Rights Reserved.
51 * Contributor(s): _______________________________________
54 ************************************************************************/
55 /*************************************************************************
58 ************************************************************************/
59 /*************************************************************************
61 * 2005-1-17 create this file.
62 ************************************************************************/
63 #include "lwpfilter.hxx"
64 #include "lwpresource.hxx"
66 #include "xfilter/xfsaxstream.hxx"
67 #include "xfilter/xffilestream.hxx"
69 #include "lwp9reader.hxx"
70 #include "lwpsvstream.hxx"
72 #include "xfilter/xffontfactory.hxx"
73 #include "xfilter/xfstylemanager.hxx"
76 #include <osl/file.hxx>
77 #include <vcl/svapp.hxx>
78 //#include <vcl/vclasynload.hxx>
79 #include <xmloff/attrlist.hxx>
80 #include <com/sun/star/io/IOException.hpp>
81 #include <com/sun/star/frame/XDesktop.hpp>
82 #include <com/sun/star/frame/XController.hpp>
83 #include <com/sun/star/text/XTextDocument.hpp>
84 #include <com/sun/star/text/XText.hpp>
86 #include <tools/stream.hxx>
87 #include <sfx2/docfile.hxx>
89 using namespace ::cppu
;
90 using namespace ::com::sun::star::lang
;
91 using namespace ::com::sun::star::frame
;
92 using namespace ::com::sun::star::text
;
93 using namespace ::com::sun::star::io
;
94 using namespace ::com::sun::star::registry
;
95 using namespace ::com::sun::star::document
;
96 using namespace ::com::sun::star::beans
;
97 using namespace ::com::sun::star::xml::sax
;
98 using namespace ::com::sun::star
;
99 using ::rtl::OUString
;
100 using ::com::sun::star::uno::Sequence
;
102 sal_Bool
IsWordproFile( uno::Reference
<XInputStream
>& rInputStream
);
103 sal_Bool
IsWordproFile(rtl::OUString file
);
105 LWPFilterReader::LWPFilterReader()
109 LWPFilterReader::~LWPFilterReader()
113 sal_Bool
LWPFilterReader::filter( const Sequence
< PropertyValue
>& aDescriptor
)
114 throw( RuntimeException
)
116 uno::Reference
< XInputStream
> xInputStream
;
117 ::rtl::OUString sURL
;
118 for( sal_Int32 i
= 0; i
< aDescriptor
.getLength(); i
++ )
120 if( aDescriptor
[i
].Name
== OUString::createFromAscii( "InputStream" ) )
121 aDescriptor
[i
].Value
>>= xInputStream
;
122 if( aDescriptor
[i
].Name
== OUString::createFromAscii( "URL" ) )
123 aDescriptor
[i
].Value
>>= sURL
;
126 if ( !xInputStream
.is() )
133 sFileName
= ::rtl::OUStringToOString(sURL
, RTL_TEXTENCODING_INFO_ASCII
);
135 SvFileStream
inputStream( sURL
, STREAM_READ
);
136 if ( inputStream
.IsEof() || ( inputStream
.GetError() != SVSTREAM_OK
) )
140 return (ReadWordproFile( &inputStream
,m_DocumentHandler
) == 0);
143 void LWPFilterReader::cancel() throw (com::sun::star::uno::RuntimeException
)
147 uno::Reference
< XInterface
> LWPFilterImportFilter_CreateInstance(
148 const uno::Reference
< XMultiServiceFactory
>& rSMgr
) throw( Exception
)
150 LWPFilterImportFilter
*p
= new LWPFilterImportFilter( rSMgr
);
152 return uno::Reference
< XInterface
> ( (OWeakObject
* )p
);
155 Sequence
< OUString
> LWPFilterImportFilter::getSupportedServiceNames_Static( void ) throw ()
157 Sequence
< OUString
> aRet(1);
158 aRet
.getArray()[0] = LWPFilterImportFilter::getImplementationName_Static();
162 LWPFilterImportFilter::LWPFilterImportFilter( const uno::Reference
< XMultiServiceFactory
>& xFact
)
164 //OUString sService = OUString( SwXMLImport_getImplementationName ); //STR_WRITER_IMPORTER_NAME
168 uno::Reference
< XDocumentHandler
> xDoc( xFact
->createInstance( OUString::createFromAscii( STR_WRITER_IMPORTER_NAME
) ), UNO_QUERY
);
170 LWPFilterReader
*p
= new LWPFilterReader
;
171 p
->setDocumentHandler( xDoc
);
173 uno::Reference
< XImporter
> xImporter
= uno::Reference
< XImporter
>( xDoc
, UNO_QUERY
);
174 rImporter
= xImporter
;
175 uno::Reference
< XFilter
> xFilter
= uno::Reference
< XFilter
>( p
);
184 LWPFilterImportFilter::~LWPFilterImportFilter()
188 sal_Bool
LWPFilterImportFilter::filter( const Sequence
< PropertyValue
>& aDescriptor
)
189 throw( RuntimeException
)
191 sal_Bool ret
= rFilter
->filter( aDescriptor
);
196 void LWPFilterImportFilter::cancel() throw (::com::sun::star::uno::RuntimeException
)
201 void LWPFilterImportFilter::setTargetDocument( const uno::Reference
< XComponent
>& xDoc
)
202 throw( IllegalArgumentException
, RuntimeException
)
204 rImporter
->setTargetDocument( xDoc
);
207 OUString
LWPFilterImportFilter::getImplementationName_Static() throw()
209 return OUString::createFromAscii( STR_IMPLEMENTATION_NAME
);
212 OUString
LWPFilterImportFilter::getImplementationName() throw()
214 return OUString::createFromAscii( STR_IMPLEMENTATION_NAME
);
217 sal_Bool
LWPFilterImportFilter::supportsService( const OUString
& ServiceName
) throw()
219 Sequence
< OUString
> aSNL
= getSupportedServiceNames();
220 const OUString
*pArray
= aSNL
.getConstArray();
222 for ( sal_Int32 i
= 0; i
< aSNL
.getLength(); i
++ )
224 if ( pArray
[i
] == ServiceName
) return sal_True
;
230 Sequence
< OUString
> LWPFilterImportFilter::getSupportedServiceNames( void ) throw()
232 Sequence
< OUString
> seq(1);
233 seq
.getArray()[0] = OUString::createFromAscii( STR_SERVICE_NAME
);
238 ::rtl::OUString SAL_CALL
LWPFilterImportFilter::detect( ::com::sun::star::uno::Sequence
< ::com::sun::star::beans::PropertyValue
>& aDescriptor
)
239 throw (::com::sun::star::uno::RuntimeException
)
242 rtl::OUString aTypeName
; // a name describing the type (from MediaDescriptor, usually from flat detection)
243 // opening as template is done when a parameter tells to do so and a template filter can be detected
244 // (otherwise no valid filter would be found) or if the detected filter is a template filter and
245 // there is no parameter that forbids to open as template
246 sal_Bool bOpenAsTemplate
= sal_False
;
247 sal_Int32 nPropertyCount
= aDescriptor
.getLength();
248 for( sal_Int32 nProperty
=0; nProperty
<nPropertyCount
; ++nProperty
)
250 if( aDescriptor
[nProperty
].Name
== OUString(RTL_CONSTASCII_USTRINGPARAM("TypeName")) )
252 aDescriptor
[nProperty
].Value
>>= aTypeName
;
254 else if( aDescriptor
[nProperty
].Name
== OUString(RTL_CONSTASCII_USTRINGPARAM("AsTemplate")) )
256 bOpenAsTemplate
= sal_True
;
260 for( sal_Int32 i
= 0; i
< aDescriptor
.getLength(); i
++ )
263 aDescriptor
[i
].Value
>>= strTemp
;
264 if( aDescriptor
[i
].Name
== OUString::createFromAscii( "InputStream" ) )
266 uno::Reference
< XInputStream
> rInputStream
;
267 aDescriptor
[i
].Value
>>= rInputStream
;
269 // TRANSFORM IMPLEMENTATION HERE!!!!!!
270 // and call m_DocumentHandler's SAX mDochods
272 if( IsWordproFile(rInputStream
) )
274 if( aTypeName
== OUString(RTL_CONSTASCII_USTRINGPARAM("wordpro_template")) )
278 aDescriptor
.realloc( nPropertyCount
+ 1 );
279 aDescriptor
[nPropertyCount
].Name
= ::rtl::OUString::createFromAscii("AsTemplate");
280 aDescriptor
[nPropertyCount
].Value
<<= sal_True
;
282 return OUString::createFromAscii("wordpro_template");
286 return OUString::createFromAscii("wordpro");
291 else if( aDescriptor
[i
].Name
== OUString::createFromAscii( "URL" ) )
296 aDescriptor
[i
].Value
>>= sURL
;
298 osl::FileBase::RC rc = osl::FileBase::getSystemPathFromFileURL( sURL, sFileName );
299 if(rc != osl::FileBase::E_None)
302 except.Message = OUString( RTL_CONSTASCII_USTRINGPARAM( "GDocting system path from URL failed!"));
307 if( IsWordproFile(sURL
) )
309 if( aTypeName
== OUString(RTL_CONSTASCII_USTRINGPARAM("wordpro_template")) )
313 aDescriptor
.realloc( nPropertyCount
+ 1 );
314 aDescriptor
[nPropertyCount
].Name
= ::rtl::OUString::createFromAscii("AsTemplate");
315 aDescriptor
[nPropertyCount
].Value
<<= sal_True
;
317 return OUString::createFromAscii("wordpro_template");
321 return OUString::createFromAscii("wordpro");
330 EXTERN_C
void SAL_CALL
331 component_getImplementationEnvironment(const sal_Char
** ppEnvTypeName
, uno_Environment
** ppEnv
)
333 *ppEnvTypeName
= CPPU_CURRENT_LANGUAGE_BINDING_NAME
;
336 EXTERN_C sal_Bool SAL_CALL
337 component_writeInfo(void* pServiceManager
, void* pRegistryKey
)
343 uno::Reference
< XRegistryKey
> xKey( reinterpret_cast<XRegistryKey
*>(pRegistryKey
) );
345 uno::Reference
< XRegistryKey
> xNewKey
= xKey
->createKey( OUString::createFromAscii( IMPLEMENTATION_NAME
) );
346 xNewKey
= xNewKey
->createKey( OUString::createFromAscii( "/UNO/SERVICES" ) );
348 xNewKey
->createKey( OUString::createFromAscii( STR_SERVICE_NAME
) );
352 catch (InvalidRegistryException
&)
354 OSL_ENSURE( sal_False
, "### InvalidRegistryException!" );
360 EXTERN_C
void* SAL_CALL
361 component_getFactory(const sal_Char
* pImplName
, void* pServiceManager
, void* pRegistryKey
)
367 uno::Reference
< XSingleServiceFactory
> xRet
;
368 uno::Reference
< XMultiServiceFactory
> xSMgr
= reinterpret_cast< XMultiServiceFactory
* > ( pServiceManager
);
370 OUString aImplementationName
= OUString::createFromAscii( pImplName
);
372 if(aImplementationName
== OUString::createFromAscii( STR_IMPLEMENTATION_NAME
) )
374 xRet
= createSingleFactory( xSMgr
, aImplementationName
,
375 LWPFilterImportFilter_CreateInstance
,
376 LWPFilterImportFilter::getSupportedServiceNames_Static() );
390 * @descr decompressed small file
391 * @param pCompressed - real file stream
392 * @param pDecompressed - file decompressed, create inside, caller should delete it
393 * @return success - sal_True, fail - sal_False
396 using namespace OpenStormBento
;
397 #include "explode.hxx"
398 sal_Bool
Decompress(SvStream
*pCompressed
, SvStream
* & pDecompressed
)
400 pCompressed
->Seek(0);
401 pDecompressed
= new SvMemoryStream(4096, 4096);
402 unsigned char buffer
[512];
403 pCompressed
->Read(buffer
, 16);
404 pDecompressed
->Write(buffer
, 16);
406 LwpSvStream
* pLwpStream
= new LwpSvStream(pCompressed
);
407 LtcBenContainer
* pBentoContainer
;
408 ULONG ulRet
= BenOpenContainer(pLwpStream
, &pBentoContainer
);
409 LtcUtBenValueStream
* pWordProData
= (LtcUtBenValueStream
*)pBentoContainer
->FindValueStreamWithPropertyName("WordProData");
412 Decompression
decompress(pWordProData
, pDecompressed
);
413 if (0!= decompress
.explode())
415 delete pDecompressed
;
416 pDecompressed
= NULL
;
422 sal_uInt32 nPos
= pWordProData
->GetSize();
425 pCompressed
->Seek(nPos
);
426 while (sal_uInt32 iRead
= pCompressed
->Read(buffer
, 512))
428 pDecompressed
->Write(buffer
, iRead
);
437 * @descr Get LwpSvStream, if small file, both compressed/decompressed stream
438 * Otherwise, only normal stream
439 * @param pStream - real file stream
440 * @param LwpSvStream * , created inside, deleted outside
441 * @param sal_Bool, sal_True -
443 sal_Bool
GetLwpSvStream(SvStream
*pStream
, LwpSvStream
* & pLwpSvStream
)
445 SvStream
* pDecompressed
= NULL
;
449 pStream
->Read(&nTag
, sizeof(nTag
));
450 if (nTag
!= 0x3750574c) // "LWP7"
452 // small file, needs decompression
453 if (!Decompress(pStream
, pDecompressed
))
459 pDecompressed
->Seek(0);
463 sal_Bool bCompressed
= sal_False
;
466 LwpSvStream
*pOriginalLwpSvStream
= new LwpSvStream(pStream
);
467 pLwpSvStream
= new LwpSvStream(pDecompressed
, pOriginalLwpSvStream
);
468 bCompressed
= sal_True
;
472 pLwpSvStream
= new LwpSvStream(pStream
);
476 int ReadWordproFile(SvStream
* pStream
, uno::Reference
<XDocumentHandler
>& xHandler
)
480 LwpSvStream
*pLwpSvStream
= NULL
;
481 SvStream
* pDecompressed
= NULL
;
482 if ( GetLwpSvStream(pStream
, pLwpSvStream
) && pLwpSvStream
)
484 pDecompressed
= pLwpSvStream
->GetStream();
488 // nothing returned, fail when uncompressing
492 IXFStream
*pStrm
= new XFSaxStream(xHandler
);
493 Lwp9Reader
reader(pLwpSvStream
, pStrm
);
494 //Reset all static objects,because this function may be called many times.
502 delete pDecompressed
;
503 LwpSvStream
* pTemp
= pLwpSvStream
->GetCompressedStream();
519 void ErrorMsg(int iErrCode
)
525 * @descr Compare if pBuf equals with the first 16 bytes
526 * @param pBuf that contains the file data
527 * @return if equals with the Word Pro characteristic strings
529 sal_Bool
IsWordProStr(const sal_Int8
*pBuf
)
531 sal_Bool bRet
= sal_True
;
532 const sal_Int8 pLotusLwp
[] =
534 0x57, 0x6F, 0x72, 0x64,
542 for(int i
=0; i
<sizeof(pLotusLwp
); i
++)
544 if( pBuf
[i
] != pLotusLwp
[i
] )
552 sal_Bool
IsWordproFile(rtl::OUString file
)
554 sal_Bool bRet
= sal_False
;
555 SfxMedium
aMedium( file
, STREAM_STD_READ
, FALSE
);
556 SvStream
* pStm
= aMedium
.GetInStream();
562 sal_Int32 nRead
= -1;
564 pStm
->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN
);
565 pStm
->Seek(STREAM_SEEK_TO_BEGIN
);
566 nRead
= pStm
->Read(buf
, sizeof(buf
));
567 if( nRead
< sizeof(buf
) )
570 bRet
= IsWordProStr(buf
);
576 sal_Bool
IsWordproFile( uno::Reference
<XInputStream
>& rInputStream
)
578 Sequence
<sal_Int8
> aData
;
579 sal_Int32 nRead
= -1;
580 sal_Bool bRet
= sal_False
;
582 nRead
= rInputStream
->readBytes(aData
,16);
589 const sal_Int8
*data
= aData
.getConstArray();
590 bRet
= IsWordProStr(data
);