GPU-Calc: remove Alloc_Host_Ptr for clmem of NAN vector
[LibreOffice.git] / desktop / source / migration / services / oo3extensionmigration.cxx
blob18465296783f04fd1dff7894afaea8bdc86c0866
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 .
21 #include "oo3extensionmigration.hxx"
22 #include <rtl/instance.hxx>
23 #include <osl/file.hxx>
24 #include <osl/thread.h>
25 #include <tools/urlobj.hxx>
26 #include <unotools/bootstrap.hxx>
27 #include <unotools/ucbstreamhelper.hxx>
28 #include <unotools/textsearch.hxx>
29 #include <comphelper/sequence.hxx>
30 #include <comphelper/processfactory.hxx>
31 #include <cppuhelper/supportsservice.hxx>
32 #include <ucbhelper/content.hxx>
34 #include <com/sun/star/task/XInteractionApprove.hpp>
35 #include <com/sun/star/task/XInteractionAbort.hpp>
36 #include <com/sun/star/ucb/XCommandInfo.hpp>
37 #include <com/sun/star/ucb/TransferInfo.hpp>
38 #include <com/sun/star/ucb/NameClash.hpp>
39 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
40 #include <com/sun/star/xml/xpath/XPathAPI.hpp>
41 #include <com/sun/star/xml/dom/DocumentBuilder.hpp>
42 #include <com/sun/star/beans/NamedValue.hpp>
43 #include <com/sun/star/deployment/ExtensionManager.hpp>
44 #include <com/sun/star/deployment/XExtensionManager.hpp>
46 using namespace ::com::sun::star;
47 using namespace ::com::sun::star::uno;
49 namespace migration
52 static OUString sExtensionSubDir( "/user/uno_packages/" );
53 static OUString sSubDirName( "cache" );
54 static OUString sDescriptionXmlFile( "/description.xml" );
55 static OUString sExtensionRootSubDirName( "/uno_packages" );
57 // =============================================================================
58 // component operations
59 // =============================================================================
61 OUString OO3ExtensionMigration_getImplementationName()
63 static OUString* pImplName = 0;
64 if ( !pImplName )
66 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
67 if ( !pImplName )
69 static OUString aImplName( "com.sun.star.comp.desktop.migration.OOo3Extensions" );
70 pImplName = &aImplName;
73 return *pImplName;
76 // -----------------------------------------------------------------------------
78 Sequence< OUString > OO3ExtensionMigration_getSupportedServiceNames()
80 static Sequence< OUString >* pNames = 0;
81 if ( !pNames )
83 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
84 if ( !pNames )
86 static Sequence< OUString > aNames(1);
87 aNames.getArray()[0] = "com.sun.star.migration.Extensions";
88 pNames = &aNames;
91 return *pNames;
94 // =============================================================================
95 // ExtensionMigration
96 // =============================================================================
98 OO3ExtensionMigration::OO3ExtensionMigration(Reference< XComponentContext > const & ctx) :
99 m_ctx(ctx)
103 // -----------------------------------------------------------------------------
105 OO3ExtensionMigration::~OO3ExtensionMigration()
109 ::osl::FileBase::RC OO3ExtensionMigration::checkAndCreateDirectory( INetURLObject& rDirURL )
111 ::osl::FileBase::RC aResult = ::osl::Directory::create( rDirURL.GetMainURL( INetURLObject::DECODE_TO_IURI ) );
112 if ( aResult == ::osl::FileBase::E_NOENT )
114 INetURLObject aBaseURL( rDirURL );
115 aBaseURL.removeSegment();
116 checkAndCreateDirectory( aBaseURL );
117 return ::osl::Directory::create( rDirURL.GetMainURL( INetURLObject::DECODE_TO_IURI ) );
119 else
121 return aResult;
125 void OO3ExtensionMigration::scanUserExtensions( const OUString& sSourceDir, TStringVector& aMigrateExtensions )
127 osl::Directory aScanRootDir( sSourceDir );
128 osl::FileStatus fs(osl_FileStatus_Mask_Type | osl_FileStatus_Mask_FileURL);
129 osl::FileBase::RC nRetCode = aScanRootDir.open();
130 if ( nRetCode == osl::Directory::E_None )
132 sal_uInt32 nHint( 0 );
133 osl::DirectoryItem aItem;
134 while ( aScanRootDir.getNextItem( aItem, nHint ) == osl::Directory::E_None )
136 if (( aItem.getFileStatus(fs) == osl::FileBase::E_None ) &&
137 ( fs.getFileType() == osl::FileStatus::Directory ))
139 //Check next folder as the "real" extension folder is below a temp folder!
140 OUString sExtensionFolderURL = fs.getFileURL();
142 osl::Directory aExtensionRootDir( sExtensionFolderURL );
144 nRetCode = aExtensionRootDir.open();
145 if ( nRetCode == osl::Directory::E_None )
147 osl::DirectoryItem aExtDirItem;
148 while ( aExtensionRootDir.getNextItem( aExtDirItem, nHint ) == osl::Directory::E_None )
150 bool bFileStatus = aExtDirItem.getFileStatus(fs) == osl::FileBase::E_None;
151 bool bIsDir = fs.getFileType() == osl::FileStatus::Directory;
153 if ( bFileStatus && bIsDir )
155 sExtensionFolderURL = fs.getFileURL();
156 ScanResult eResult = scanExtensionFolder( sExtensionFolderURL );
157 if ( eResult == SCANRESULT_MIGRATE_EXTENSION )
158 aMigrateExtensions.push_back( sExtensionFolderURL );
159 break;
168 OO3ExtensionMigration::ScanResult OO3ExtensionMigration::scanExtensionFolder( const OUString& sExtFolder )
170 ScanResult aResult = SCANRESULT_NOTFOUND;
171 osl::Directory aDir(sExtFolder);
173 // get sub dirs
174 if (aDir.open() == osl::FileBase::E_None)
176 // work through directory contents...
177 osl::DirectoryItem item;
178 osl::FileStatus fs(osl_FileStatus_Mask_Type | osl_FileStatus_Mask_FileURL);
179 TStringVector aDirectories;
180 while ((aDir.getNextItem(item) == osl::FileBase::E_None ) &&
181 ( aResult == SCANRESULT_NOTFOUND ))
183 if (item.getFileStatus(fs) == osl::FileBase::E_None)
185 OUString aDirEntryURL;
186 if (fs.getFileType() == osl::FileStatus::Directory)
187 aDirectories.push_back( fs.getFileURL() );
188 else
190 aDirEntryURL = fs.getFileURL();
191 if ( aDirEntryURL.indexOf( sDescriptionXmlFile ) > 0 )
192 aResult = scanDescriptionXml( aDirEntryURL ) ? SCANRESULT_MIGRATE_EXTENSION : SCANRESULT_DONTMIGRATE_EXTENSION;
197 TStringVector::const_iterator pIter = aDirectories.begin();
198 while ( pIter != aDirectories.end() && aResult == SCANRESULT_NOTFOUND )
200 aResult = scanExtensionFolder( *pIter );
201 ++pIter;
204 return aResult;
207 bool OO3ExtensionMigration::scanDescriptionXml( const OUString& sDescriptionXmlURL )
209 if ( !m_xDocBuilder.is() )
211 m_xDocBuilder = uno::Reference< xml::dom::XDocumentBuilder >( xml::dom::DocumentBuilder::create(m_ctx) );
214 if ( !m_xSimpleFileAccess.is() )
216 m_xSimpleFileAccess = ucb::SimpleFileAccess::create(m_ctx);
219 OUString aExtIdentifier;
222 uno::Reference< io::XInputStream > xIn =
223 m_xSimpleFileAccess->openFileRead( sDescriptionXmlURL );
225 if ( xIn.is() )
227 uno::Reference< xml::dom::XDocument > xDoc = m_xDocBuilder->parse( xIn );
228 if ( xDoc.is() )
230 uno::Reference< xml::dom::XElement > xRoot = xDoc->getDocumentElement();
231 if ( xRoot.is() && xRoot->getTagName() == "description" )
233 uno::Reference< xml::xpath::XXPathAPI > xPath = xml::xpath::XPathAPI::create(m_ctx);
235 xPath->registerNS("desc", xRoot->getNamespaceURI());
236 xPath->registerNS("xlink", "http://www.w3.org/1999/xlink");
240 uno::Reference< xml::dom::XNode > xRootNode( xRoot, uno::UNO_QUERY );
241 uno::Reference< xml::dom::XNode > xNode(
242 xPath->selectSingleNode(
243 xRootNode, "desc:identifier/@value" ));
244 if ( xNode.is() )
245 aExtIdentifier = xNode->getNodeValue();
247 catch ( const xml::xpath::XPathException& )
250 catch ( const xml::dom::DOMException& )
257 if ( !aExtIdentifier.isEmpty() )
259 // scan extension identifier and try to match with our black list entries
260 for ( sal_uInt32 i = 0; i < m_aBlackList.size(); i++ )
262 utl::SearchParam param(m_aBlackList[i], utl::SearchParam::SRCH_REGEXP);
263 utl::TextSearch ts(param, LANGUAGE_DONTKNOW);
265 sal_Int32 start = 0;
266 sal_Int32 end = aExtIdentifier.getLength();
267 if (ts.SearchForward(aExtIdentifier, &start, &end))
268 return false;
272 catch ( const ucb::CommandAbortedException& )
275 catch ( const uno::RuntimeException& )
279 if ( aExtIdentifier.isEmpty() )
281 // Fallback:
282 // Try to use the folder name to match our black list
283 // as some extensions don't provide an identifier in the
284 // description.xml!
285 for ( sal_uInt32 i = 0; i < m_aBlackList.size(); i++ )
287 utl::SearchParam param(m_aBlackList[i], utl::SearchParam::SRCH_REGEXP);
288 utl::TextSearch ts(param, LANGUAGE_DONTKNOW);
290 sal_Int32 start = 0;
291 sal_Int32 end = sDescriptionXmlURL.getLength();
292 if (ts.SearchForward(sDescriptionXmlURL, &start, &end))
293 return false;
297 return true;
300 void OO3ExtensionMigration::migrateExtension( const OUString& sSourceDir )
302 css::uno::Reference< css::deployment::XExtensionManager > extMgr(
303 deployment::ExtensionManager::get( m_ctx ) );
306 TmpRepositoryCommandEnv* pCmdEnv = new TmpRepositoryCommandEnv();
308 uno::Reference< ucb::XCommandEnvironment > xCmdEnv(
309 static_cast< cppu::OWeakObject* >( pCmdEnv ), uno::UNO_QUERY );
310 uno::Reference< task::XAbortChannel > xAbortChannel;
311 extMgr->addExtension(
312 sSourceDir, uno::Sequence<beans::NamedValue>(), "user",
313 xAbortChannel, xCmdEnv );
315 catch ( css::uno::Exception & e )
317 SAL_WARN(
318 "desktop.migration",
319 "Ignoring UNO Exception while migrating extension from <"
320 << sSourceDir << ">: \"" << e.Message << "\"");
325 // -----------------------------------------------------------------------------
326 // XServiceInfo
327 // -----------------------------------------------------------------------------
329 OUString OO3ExtensionMigration::getImplementationName() throw (RuntimeException)
331 return OO3ExtensionMigration_getImplementationName();
334 // -----------------------------------------------------------------------------
336 sal_Bool OO3ExtensionMigration::supportsService(OUString const & ServiceName)
337 throw (css::uno::RuntimeException)
339 return cppu::supportsService(this, ServiceName);
342 // -----------------------------------------------------------------------------
344 Sequence< OUString > OO3ExtensionMigration::getSupportedServiceNames() throw (RuntimeException)
346 return OO3ExtensionMigration_getSupportedServiceNames();
349 // -----------------------------------------------------------------------------
350 // XInitialization
351 // -----------------------------------------------------------------------------
353 void OO3ExtensionMigration::initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException)
355 ::osl::MutexGuard aGuard( m_aMutex );
357 const Any* pIter = aArguments.getConstArray();
358 const Any* pEnd = pIter + aArguments.getLength();
359 for ( ; pIter != pEnd ; ++pIter )
361 beans::NamedValue aValue;
362 *pIter >>= aValue;
363 if ( aValue.Name == "UserData" )
365 if ( !(aValue.Value >>= m_sSourceDir) )
367 OSL_FAIL( "ExtensionMigration::initialize: argument UserData has wrong type!" );
370 else if ( aValue.Name == "ExtensionBlackList" )
372 Sequence< OUString > aBlackList;
373 if ( (aValue.Value >>= aBlackList ) && ( aBlackList.getLength() > 0 ))
375 m_aBlackList.resize( aBlackList.getLength() );
376 ::comphelper::sequenceToArray< OUString >( &m_aBlackList[0], aBlackList );
382 Any OO3ExtensionMigration::execute( const Sequence< beans::NamedValue >& )
383 throw (lang::IllegalArgumentException, Exception, RuntimeException)
385 ::osl::MutexGuard aGuard( m_aMutex );
387 ::utl::Bootstrap::PathStatus aStatus = ::utl::Bootstrap::locateUserInstallation( m_sTargetDir );
388 if ( aStatus == ::utl::Bootstrap::PATH_EXISTS )
390 // copy all extensions
391 OUString sSourceDir( m_sSourceDir );
392 sSourceDir += sExtensionSubDir;
393 sSourceDir += sSubDirName;
394 sSourceDir += sExtensionRootSubDirName;
395 TStringVector aExtensionToMigrate;
396 scanUserExtensions( sSourceDir, aExtensionToMigrate );
397 if ( aExtensionToMigrate.size() > 0 )
399 TStringVector::iterator pIter = aExtensionToMigrate.begin();
400 while ( pIter != aExtensionToMigrate.end() )
402 migrateExtension( *pIter );
403 ++pIter;
408 return Any();
411 // -----------------------------------------------------------------------------
412 // TmpRepositoryCommandEnv
413 // -----------------------------------------------------------------------------
415 TmpRepositoryCommandEnv::TmpRepositoryCommandEnv()
419 TmpRepositoryCommandEnv::~TmpRepositoryCommandEnv()
422 // XCommandEnvironment
423 //______________________________________________________________________________
424 uno::Reference< task::XInteractionHandler > TmpRepositoryCommandEnv::getInteractionHandler()
425 throw ( uno::RuntimeException )
427 return this;
430 //______________________________________________________________________________
431 uno::Reference< ucb::XProgressHandler > TmpRepositoryCommandEnv::getProgressHandler()
432 throw ( uno::RuntimeException )
434 return this;
437 // XInteractionHandler
438 void TmpRepositoryCommandEnv::handle(
439 uno::Reference< task::XInteractionRequest> const & xRequest )
440 throw ( uno::RuntimeException )
442 OSL_ASSERT( xRequest->getRequest().getValueTypeClass() == uno::TypeClass_EXCEPTION );
444 bool approve = true;
445 bool abort = false;
447 // select:
448 uno::Sequence< Reference< task::XInteractionContinuation > > conts(
449 xRequest->getContinuations() );
450 Reference< task::XInteractionContinuation > const * pConts =
451 conts.getConstArray();
452 sal_Int32 len = conts.getLength();
453 for ( sal_Int32 pos = 0; pos < len; ++pos )
455 if (approve) {
456 uno::Reference< task::XInteractionApprove > xInteractionApprove(
457 pConts[ pos ], uno::UNO_QUERY );
458 if (xInteractionApprove.is()) {
459 xInteractionApprove->select();
460 // don't query again for ongoing continuations:
461 approve = false;
464 else if (abort) {
465 uno::Reference< task::XInteractionAbort > xInteractionAbort(
466 pConts[ pos ], uno::UNO_QUERY );
467 if (xInteractionAbort.is()) {
468 xInteractionAbort->select();
469 // don't query again for ongoing continuations:
470 abort = false;
476 // XProgressHandler
477 void TmpRepositoryCommandEnv::push( uno::Any const & /*Status*/ )
478 throw (uno::RuntimeException)
483 void TmpRepositoryCommandEnv::update( uno::Any const & /*Status */)
484 throw (uno::RuntimeException)
488 void TmpRepositoryCommandEnv::pop() throw (uno::RuntimeException)
492 // =============================================================================
493 // component operations
494 // =============================================================================
496 Reference< XInterface > SAL_CALL OO3ExtensionMigration_create(
497 Reference< XComponentContext > const & ctx )
498 SAL_THROW(())
500 return static_cast< lang::XTypeProvider * >( new OO3ExtensionMigration(
501 ctx) );
504 // -----------------------------------------------------------------------------
506 } // namespace migration
508 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */