bump product version to 4.1.6.2
[LibreOffice.git] / filter / source / xsltdialog / xmlfilterjar.cxx
blob12241c771286ce404a024f343013fa846d9e7f28
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 <com/sun/star/io/XActiveDataControl.hpp>
21 #include <com/sun/star/io/XActiveDataSource.hpp>
22 #include <com/sun/star/frame/XConfigManager.hpp>
23 #include <com/sun/star/io/XInputStream.hpp>
24 #include <com/sun/star/io/XActiveDataSink.hpp>
25 #include <com/sun/star/beans/PropertyValue.hpp>
26 #include <com/sun/star/beans/NamedValue.hpp>
27 #include <com/sun/star/container/XNamed.hpp>
28 #include <com/sun/star/container/XChild.hpp>
29 #include <com/sun/star/util/XChangesBatch.hpp>
32 #include <comphelper/processfactory.hxx>
33 #include <comphelper/oslfile2streamwrap.hxx>
34 #include <comphelper/storagehelper.hxx>
35 #include <unotools/streamwrap.hxx>
36 #include <tools/stream.hxx>
37 #include <tools/urlobj.hxx>
38 #include <unotools/tempfile.hxx>
39 #include <svl/urihelper.hxx>
40 #include <osl/file.hxx>
42 #include <rtl/uri.hxx>
44 #include "xmlfilterjar.hxx"
45 #include "xmlfilterdialogstrings.hrc"
46 #include "xmlfiltersettingsdialog.hxx"
47 #include "typedetectionexport.hxx"
48 #include "typedetectionimport.hxx"
50 using namespace osl;
51 using namespace comphelper;
52 using namespace com::sun::star;
53 using namespace com::sun::star::lang;
54 using namespace com::sun::star::frame;
55 using namespace com::sun::star::uno;
56 using namespace com::sun::star::util;
57 using namespace com::sun::star::container;
58 using namespace com::sun::star::beans;
59 using namespace com::sun::star::io;
61 using ::rtl::Uri;
63 XMLFilterJarHelper::XMLFilterJarHelper( Reference< XMultiServiceFactory >& xMSF )
64 : mxMSF( xMSF ),
65 sVndSunStarPackage( "vnd.sun.star.Package:" ),
66 sXSLTPath( "$(user)/xslt/" ),
67 sTemplatePath( "$(user)/template/" ),
68 sSpecialConfigManager( "com.sun.star.config.SpecialConfigManager" ),
69 sPump( "com.sun.star.io.Pump" ),
70 sProgPath( "$(prog)/" )
72 try
74 Reference< XConfigManager > xCfgMgr( xMSF->createInstance(OUString( "com.sun.star.config.SpecialConfigManager" )), UNO_QUERY );
75 if( xCfgMgr.is() )
77 sProgPath = xCfgMgr->substituteVariables( sProgPath );
78 sXSLTPath = xCfgMgr->substituteVariables( sXSLTPath );
79 sTemplatePath = xCfgMgr->substituteVariables( sTemplatePath );
82 catch(const Exception&)
87 static OUString encodeZipUri( const OUString& rURI )
89 return Uri::encode( rURI, rtl_UriCharClassUric, rtl_UriEncodeCheckEscapes, RTL_TEXTENCODING_UTF8 );
92 static Reference< XInterface > addFolder( Reference< XInterface >& xRootFolder, Reference< XSingleServiceFactory >& xFactory, const OUString& rName ) throw( Exception )
94 if ( rName == ".." || rName == "." )
95 throw lang::IllegalArgumentException();
97 Sequence< Any > aArgs(1);
98 aArgs[0] <<= (sal_Bool)sal_True;
100 Reference< XInterface > xFolder( xFactory->createInstanceWithArguments(aArgs) );
101 Reference< XNamed > xNamed( xFolder, UNO_QUERY );
102 Reference< XChild > xChild( xFolder, UNO_QUERY );
104 if( xNamed.is() && xChild.is() )
106 OUString aName( encodeZipUri( rName ) );
107 xNamed->setName( aName );
108 xChild->setParent( xRootFolder );
111 return xFolder;
114 static void _addFile( Reference< XInterface >& xRootFolder, Reference< XSingleServiceFactory >& xFactory, Reference< XInputStream >& xInput, OUString aName ) throw( Exception )
117 Reference< XActiveDataSink > xSink( xFactory->createInstance(), UNO_QUERY );
118 Reference< XUnoTunnel > xTunnel( xSink, UNO_QUERY );
119 if( xSink.is() && xTunnel.is())
121 Reference< XNameContainer > xNameContainer(xRootFolder, UNO_QUERY );
122 xNameContainer->insertByName(aName = encodeZipUri( aName ), makeAny(xTunnel));
123 xSink->setInputStream( xInput );
127 void XMLFilterJarHelper::addFile( Reference< XInterface > xRootFolder, Reference< XSingleServiceFactory > xFactory, const OUString& rSourceFile ) throw( Exception )
129 if( !rSourceFile.isEmpty() &&
130 !rSourceFile.startsWith("http:") &&
131 !rSourceFile.startsWith("https:") &&
132 !rSourceFile.startsWith("jar:") &&
133 !rSourceFile.startsWith("ftp:") )
135 OUString aFileURL( rSourceFile );
137 if( !aFileURL.matchIgnoreAsciiCase( OUString("file://") ) )
139 aFileURL = URIHelper::SmartRel2Abs( sProgPath, aFileURL, Link(), false );
142 INetURLObject aURL( aFileURL );
143 OUString aName( aURL.getName() );
145 SvFileStream* pStream = new SvFileStream(aFileURL, STREAM_READ );
146 Reference< XInputStream > xInput( new utl::OSeekableInputStreamWrapper( pStream, true ) );
147 _addFile( xRootFolder, xFactory, xInput, aName );
151 bool XMLFilterJarHelper::savePackage( const OUString& rPackageURL, const XMLFilterVector& rFilters )
155 osl::File::remove( rPackageURL );
157 // create the package jar file
159 Sequence< Any > aArguments( 2 );
160 aArguments[ 0 ] <<= rPackageURL;
162 // let ZipPackage be used ( no manifest.xml is required )
163 beans::NamedValue aArg;
164 aArg.Name = OUString( "StorageFormat" );
165 aArg.Value <<= ZIP_STORAGE_FORMAT_STRING;
166 aArguments[ 1 ] <<= aArg;
168 Reference< XHierarchicalNameAccess > xIfc(
169 mxMSF->createInstanceWithArguments(
170 OUString( "com.sun.star.packages.comp.ZipPackage" ),
171 aArguments ), UNO_QUERY );
173 if( xIfc.is() )
175 Reference< XSingleServiceFactory > xFactory( xIfc, UNO_QUERY );
177 // get root zip folder
178 Reference< XInterface > xRootFolder;
179 OUString szRootFolder("/");
180 xIfc->getByHierarchicalName( szRootFolder ) >>= xRootFolder;
182 // export filters files
183 XMLFilterVector::const_iterator aIter( rFilters.begin() );
184 while( aIter != rFilters.end() )
186 const filter_info_impl* pFilter = (*aIter);
188 Reference< XInterface > xFilterRoot( addFolder( xRootFolder, xFactory, pFilter->maFilterName ) );
190 if( xFilterRoot.is() )
192 if( !pFilter->maExportXSLT.isEmpty() )
193 addFile( xFilterRoot, xFactory, pFilter->maExportXSLT );
196 if( !pFilter->maImportXSLT.isEmpty() )
197 addFile( xFilterRoot, xFactory, pFilter->maImportXSLT );
199 catch(const com::sun::star::container::ElementExistException&)
201 // in case of same named import / export XSLT the latter
202 // is ignored
203 OSL_FAIL( "XMLFilterJarHelper::same named xslt filter exception!" );
206 if( !pFilter->maImportTemplate.isEmpty() )
207 addFile( xFilterRoot, xFactory, pFilter->maImportTemplate );
210 ++aIter;
213 // create TypeDetection.xcu
214 utl::TempFile aTempFile;
215 aTempFile.EnableKillingFile();
216 OUString aTempFileURL( aTempFile.GetURL() );
219 osl::File aOutputFile( aTempFileURL );
220 /* osl::File::RC rc = */ aOutputFile.open( osl_File_OpenFlag_Write );
221 Reference< XOutputStream > xOS( new OSLOutputStreamWrapper( aOutputFile ) );
223 Reference<XComponentContext> xContext( comphelper::getComponentContext(mxMSF) );
224 TypeDetectionExporter aExporter( xContext );
225 aExporter.doExport(xOS,rFilters);
228 Reference< XInputStream > XIS( new utl::OSeekableInputStreamWrapper( new SvFileStream(aTempFileURL, STREAM_READ ), true ) );
229 OUString szTypeDetection( "TypeDetection.xcu" );
230 _addFile( xRootFolder, xFactory, XIS, szTypeDetection );
232 Reference< XChangesBatch > xBatch( xIfc, UNO_QUERY );
233 if( xBatch.is() )
234 xBatch->commitChanges();
236 return true;
239 catch( const Exception& )
241 OSL_FAIL( "XMLFilterJarHelper::savePackage exception catched!" );
244 osl::File::remove( rPackageURL );
246 return false;
253 void XMLFilterJarHelper::openPackage( const OUString& rPackageURL, XMLFilterVector& rFilters )
257 // create the package jar file
259 Sequence< Any > aArguments( 2 );
260 aArguments[ 0 ] <<= rPackageURL;
262 // let ZipPackage be used ( no manifest.xml is required )
263 beans::NamedValue aArg;
264 aArg.Name = OUString( "StorageFormat" );
265 aArg.Value <<= ZIP_STORAGE_FORMAT_STRING;
266 aArguments[ 1 ] <<= aArg;
268 Reference< XHierarchicalNameAccess > xIfc(
269 mxMSF->createInstanceWithArguments(
270 OUString( "com.sun.star.packages.comp.ZipPackage" ),
271 aArguments ), UNO_QUERY );
273 if( xIfc.is() )
275 Reference< XSingleServiceFactory > xFactory( xIfc, UNO_QUERY );
277 // get root zip folder
278 Reference< XInterface > xRootFolder;
279 OUString szRootFolder("/");
280 xIfc->getByHierarchicalName( szRootFolder ) >>= xRootFolder;
282 OUString szTypeDetection("TypeDetection.xcu");
283 if( xIfc->hasByHierarchicalName( szTypeDetection ) )
285 Reference< XActiveDataSink > xTypeDetection;
286 xIfc->getByHierarchicalName( szTypeDetection ) >>= xTypeDetection;
288 if( xTypeDetection.is() )
290 Reference< XInputStream > xIS( xTypeDetection->getInputStream() );
292 XMLFilterVector aFilters;
293 TypeDetectionImporter::doImport( mxMSF, xIS, aFilters );
295 // copy all files used by the filters imported from the
296 // typedetection to office/user/xslt
297 XMLFilterVector::iterator aIter( aFilters.begin() );
298 while( aIter != aFilters.end() )
300 if( copyFiles( xIfc, (*aIter) ) )
302 rFilters.push_back( (*aIter) );
304 else
306 // failed to copy all files
307 delete (*aIter);
309 ++aIter;
315 catch( const Exception& )
317 OSL_FAIL( "XMLFilterJarHelper::savePackage exception catched!" );
321 bool XMLFilterJarHelper::copyFiles( Reference< XHierarchicalNameAccess > xIfc, filter_info_impl* pFilter )
323 bool bOk = copyFile( xIfc, pFilter->maExportXSLT, sXSLTPath );
325 if( bOk )
326 bOk = copyFile( xIfc, pFilter->maImportXSLT, sXSLTPath );
328 if( bOk )
329 bOk = copyFile( xIfc, pFilter->maImportTemplate, sTemplatePath );
331 return bOk;
334 bool XMLFilterJarHelper::copyFile( Reference< XHierarchicalNameAccess > xIfc, OUString& rURL, const OUString& rTargetURL )
336 if( !rURL.matchIgnoreAsciiCase( sVndSunStarPackage ) )
337 return true;
341 OUString szPackagePath( encodeZipUri( rURL.copy( sVndSunStarPackage.getLength() ) ) );
343 if ( ::comphelper::OStorageHelper::PathHasSegment( szPackagePath, OUString( ".." ) )
344 || ::comphelper::OStorageHelper::PathHasSegment( szPackagePath, OUString( "." ) ) )
345 throw lang::IllegalArgumentException();
347 if( xIfc->hasByHierarchicalName( szPackagePath ) )
349 Reference< XActiveDataSink > xFileEntry;
350 xIfc->getByHierarchicalName( szPackagePath ) >>= xFileEntry;
352 if( xFileEntry.is() )
354 Reference< XInputStream > xIS( xFileEntry->getInputStream() );
356 INetURLObject aBaseURL( rTargetURL );
358 rURL = URIHelper::SmartRel2Abs( aBaseURL, szPackagePath, Link(), false );
360 if( !rURL.isEmpty() )
362 // create output directory if needed
363 if( !createDirectory( rURL ) )
364 return false;
366 ::osl::File file(rURL);
367 ::osl::FileBase::RC rc =
368 file.open(osl_File_OpenFlag_Write|osl_File_OpenFlag_Create);
369 if (::osl::FileBase::E_EXIST == rc) {
370 rc = file.open(osl_File_OpenFlag_Write);
371 if (::osl::FileBase::E_None == rc) {
372 file.setSize(0); // #i97170# truncate
375 if (::osl::FileBase::E_None != rc) {
376 throw RuntimeException();
378 Reference< XOutputStream > const xOS(
379 new comphelper::OSLOutputStreamWrapper(file));
381 return copyStreams( xIS, xOS );
386 catch( const Exception& )
388 OSL_FAIL( "XMLFilterJarHelper::copyFile exception catched" );
390 return false;
393 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */