Update ooo320-m1
[ooovba.git] / desktop / source / deployment / registry / script / dp_script.cxx
blob1a8a0e4d1b756ce8e19dc0899f007a46093e6478
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: dp_script.cxx,v $
10 * $Revision: 1.15 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_desktop.hxx"
34 #include "dp_script.hrc"
35 #include "dp_lib_container.h"
36 #include "dp_backend.h"
37 #include "dp_ucb.h"
38 #include "rtl/uri.hxx"
39 #include "ucbhelper/content.hxx"
40 #include "cppuhelper/exc_hlp.hxx"
41 #include "cppuhelper/implbase1.hxx"
42 #include "comphelper/servicedecl.hxx"
43 #include "svtools/inettype.hxx"
44 #include "com/sun/star/util/XUpdatable.hpp"
45 #include "com/sun/star/script/XLibraryContainer.hpp"
46 #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
47 #include <com/sun/star/util/XMacroExpander.hpp>
48 #include <com/sun/star/uri/XUriReferenceFactory.hpp>
49 #include <com/sun/star/uri/XVndSunStarExpandUrl.hpp>
50 #include <memory>
52 using namespace ::dp_misc;
53 using namespace ::com::sun::star;
54 using namespace ::com::sun::star::uno;
55 using namespace ::com::sun::star::ucb;
56 using ::rtl::OUString;
57 namespace css = ::com::sun::star;
59 namespace dp_registry {
60 namespace backend {
61 namespace script {
62 namespace {
64 typedef ::cppu::ImplInheritanceHelper1<
65 ::dp_registry::backend::PackageRegistryBackend, util::XUpdatable > t_helper;
67 //==============================================================================
68 class BackendImpl : public t_helper
70 class PackageImpl : public ::dp_registry::backend::Package
72 BackendImpl * getMyBackend() const;
74 const OUString m_scriptURL;
75 const OUString m_dialogURL;
76 OUString m_dialogName;
78 // Package
79 virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
80 ::osl::ResettableMutexGuard & guard,
81 ::rtl::Reference<AbortChannel> const & abortChannel,
82 Reference<XCommandEnvironment> const & xCmdEnv );
83 virtual void processPackage_(
84 ::osl::ResettableMutexGuard & guard,
85 bool registerPackage,
86 ::rtl::Reference<AbortChannel> const & abortChannel,
87 Reference<XCommandEnvironment> const & xCmdEnv );
89 public:
90 PackageImpl(
91 ::rtl::Reference<BackendImpl> const & myBackend,
92 OUString const & url,
93 Reference<XCommandEnvironment> const &xCmdEnv,
94 OUString const & scriptURL, OUString const & dialogURL );
96 friend class PackageImpl;
98 // PackageRegistryBackend
99 virtual Reference<deployment::XPackage> bindPackage_(
100 OUString const & url, OUString const & mediaType,
101 Reference<XCommandEnvironment> const & xCmdEnv );
103 rtl::OUString getRegisteredFlagFileURL( Reference< deployment::XPackage > xPackage );
104 rtl::OUString expandURL( const rtl::OUString& aURL );
105 Reference< ucb::XSimpleFileAccess > getFileAccess( void );
106 Reference< ucb::XSimpleFileAccess > m_xSFA;
108 const Reference<deployment::XPackageTypeInfo> m_xBasicLibTypeInfo;
109 const Reference<deployment::XPackageTypeInfo> m_xDialogLibTypeInfo;
110 Sequence< Reference<deployment::XPackageTypeInfo> > m_typeInfos;
112 public:
113 BackendImpl( Sequence<Any> const & args,
114 Reference<XComponentContext> const & xComponentContext );
116 // XUpdatable
117 virtual void SAL_CALL update() throw (RuntimeException);
119 // XPackageRegistry
120 virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL
121 getSupportedPackageTypes() throw (RuntimeException);
124 //______________________________________________________________________________
125 BackendImpl::PackageImpl::PackageImpl(
126 ::rtl::Reference<BackendImpl> const & myBackend,
127 OUString const & url,
128 Reference<XCommandEnvironment> const &xCmdEnv,
129 OUString const & scriptURL, OUString const & dialogURL )
130 : Package( myBackend.get(), url,
131 OUString(), OUString(), // will be late-initialized
132 scriptURL.getLength() > 0 ? myBackend->m_xBasicLibTypeInfo
133 : myBackend->m_xDialogLibTypeInfo ),
134 m_scriptURL( scriptURL ),
135 m_dialogURL( dialogURL )
137 // name, displayName:
138 if (dialogURL.getLength() > 0) {
139 m_dialogName = LibraryContainer::get_libname(
140 dialogURL, xCmdEnv, myBackend->getComponentContext() );
142 if (scriptURL.getLength() > 0) {
143 m_name = LibraryContainer::get_libname(
144 scriptURL, xCmdEnv, myBackend->getComponentContext() );
146 else
147 m_name = m_dialogName;
148 m_displayName = m_name;
151 //______________________________________________________________________________
152 BackendImpl::BackendImpl(
153 Sequence<Any> const & args,
154 Reference<XComponentContext> const & xComponentContext )
155 : t_helper( args, xComponentContext ),
156 m_xBasicLibTypeInfo( new Package::TypeInfo(
157 OUSTR("application/"
158 "vnd.sun.star.basic-library"),
159 OUString() /* no file filter */,
160 getResourceString(RID_STR_BASIC_LIB),
161 RID_IMG_SCRIPTLIB, RID_IMG_SCRIPTLIB_HC ) ),
162 m_xDialogLibTypeInfo( new Package::TypeInfo(
163 OUSTR("application/"
164 "vnd.sun.star.dialog-library"),
165 OUString() /* no file filter */,
166 getResourceString(RID_STR_DIALOG_LIB),
167 RID_IMG_DIALOGLIB, RID_IMG_DIALOGLIB_HC ) ),
168 m_typeInfos( 2 )
170 m_typeInfos[ 0 ] = m_xBasicLibTypeInfo;
171 m_typeInfos[ 1 ] = m_xDialogLibTypeInfo;
173 OSL_ASSERT( ! transientMode() );
176 // XUpdatable
177 //______________________________________________________________________________
178 void BackendImpl::update() throw (RuntimeException)
180 // Nothing to do here after fixing i70283!?
183 // XPackageRegistry
184 //______________________________________________________________________________
185 Sequence< Reference<deployment::XPackageTypeInfo> >
186 BackendImpl::getSupportedPackageTypes() throw (RuntimeException)
188 return m_typeInfos;
191 // PackageRegistryBackend
192 //______________________________________________________________________________
193 Reference<deployment::XPackage> BackendImpl::bindPackage_(
194 OUString const & url, OUString const & mediaType_,
195 Reference<XCommandEnvironment> const & xCmdEnv )
197 OUString mediaType( mediaType_ );
198 if (mediaType.getLength() == 0)
200 // detect media-type:
201 ::ucbhelper::Content ucbContent;
202 if (create_ucb_content( &ucbContent, url, xCmdEnv ) &&
203 ucbContent.isFolder())
205 // probe for script.xlb:
206 if (create_ucb_content(
207 0, makeURL( url, OUSTR("script.xlb") ),
208 xCmdEnv, false /* no throw */ ))
209 mediaType = OUSTR("application/vnd.sun.star.basic-library");
210 // probe for dialog.xlb:
211 else if (create_ucb_content(
212 0, makeURL( url, OUSTR("dialog.xlb") ),
213 xCmdEnv, false /* no throw */ ))
214 mediaType = OUSTR("application/vnd.sun.star.dialog-library");
216 if (mediaType.getLength() == 0)
217 throw lang::IllegalArgumentException(
218 StrCannotDetectMediaType::get() + url,
219 static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
222 String type, subType;
223 INetContentTypeParameterList params;
224 if (INetContentTypes::parse( mediaType, type, subType, &params ))
226 if (type.EqualsIgnoreCaseAscii("application"))
228 if (subType.EqualsIgnoreCaseAscii("vnd.sun.star.basic-library"))
230 OUString dialogURL( makeURL( url, OUSTR("dialog.xlb") ) );
231 if (! create_ucb_content(
232 0, dialogURL, xCmdEnv, false /* no throw */ )) {
233 dialogURL = OUString();
235 return new PackageImpl( this, url, xCmdEnv,
236 makeURL( url, OUSTR("script.xlb") ),
237 dialogURL );
239 else if (subType.EqualsIgnoreCaseAscii(
240 "vnd.sun.star.dialog-library")) {
241 return new PackageImpl( this, url, xCmdEnv,
242 OUString() /* no script lib */,
243 makeURL( url, OUSTR("dialog.xlb") ) );
247 throw lang::IllegalArgumentException(
248 StrUnsupportedMediaType::get() + mediaType,
249 static_cast<OWeakObject *>(this),
250 static_cast<sal_Int16>(-1) );
253 rtl::OUString BackendImpl::getRegisteredFlagFileURL( Reference< deployment::XPackage > xPackage )
255 rtl::OUString aRetURL;
256 if( !xPackage.is() )
257 return aRetURL;
258 rtl::OUString aHelpURL = xPackage->getURL();
259 aRetURL = expandURL( aHelpURL );
260 aRetURL += rtl::OUString::createFromAscii( "/RegisteredFlag" );
261 return aRetURL;
264 rtl::OUString BackendImpl::expandURL( const rtl::OUString& aURL )
266 static Reference< util::XMacroExpander > xMacroExpander;
267 static Reference< uri::XUriReferenceFactory > xFac;
269 if( !xMacroExpander.is() || !xFac.is() )
271 Reference<XComponentContext> const & xContext = getComponentContext();
272 if( xContext.is() )
274 xFac = Reference< uri::XUriReferenceFactory >(
275 xContext->getServiceManager()->createInstanceWithContext( rtl::OUString::createFromAscii(
276 "com.sun.star.uri.UriReferenceFactory"), xContext ) , UNO_QUERY );
278 if( !xFac.is() )
280 throw RuntimeException(
281 ::rtl::OUString::createFromAscii(
282 "dp_registry::backend::help::BackendImpl::expandURL(), "
283 "could not instatiate UriReferenceFactory." ),
284 Reference< XInterface >() );
287 xMacroExpander = Reference< util::XMacroExpander >(
288 xContext->getValueByName(
289 ::rtl::OUString::createFromAscii( "/singletons/com.sun.star.util.theMacroExpander" ) ),
290 UNO_QUERY_THROW );
293 rtl::OUString aRetURL = aURL;
294 if( xMacroExpander.is() )
296 Reference< uri::XUriReference > uriRef;
297 for (;;)
299 uriRef = Reference< uri::XUriReference >( xFac->parse( aRetURL ), UNO_QUERY );
300 if ( uriRef.is() )
302 Reference < uri::XVndSunStarExpandUrl > sxUri( uriRef, UNO_QUERY );
303 if( !sxUri.is() )
304 break;
306 aRetURL = sxUri->expand( xMacroExpander );
310 return aRetURL;
313 Reference< ucb::XSimpleFileAccess > BackendImpl::getFileAccess( void )
315 if( !m_xSFA.is() )
317 Reference<XComponentContext> const & xContext = getComponentContext();
318 if( xContext.is() )
320 m_xSFA = Reference< ucb::XSimpleFileAccess >(
321 xContext->getServiceManager()->createInstanceWithContext(
322 rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ),
323 xContext ), UNO_QUERY );
325 if( !m_xSFA.is() )
327 throw RuntimeException(
328 ::rtl::OUString::createFromAscii(
329 "dp_registry::backend::help::BackendImpl::getFileAccess(), "
330 "could not instatiate SimpleFileAccess." ),
331 Reference< XInterface >() );
334 return m_xSFA;
337 //##############################################################################
339 // Package
340 BackendImpl * BackendImpl::PackageImpl::getMyBackend() const
342 BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
343 if (NULL == pBackend)
345 //May throw a DisposedException
346 check();
347 //We should never get here...
348 throw RuntimeException(
349 OUSTR("Failed to get the BackendImpl"),
350 static_cast<OWeakObject*>(const_cast<PackageImpl *>(this)));
352 return pBackend;
354 //______________________________________________________________________________
355 beans::Optional< beans::Ambiguous<sal_Bool> >
356 BackendImpl::PackageImpl::isRegistered_(
357 ::osl::ResettableMutexGuard &,
358 ::rtl::Reference<AbortChannel> const &,
359 Reference<XCommandEnvironment> const & xCmdEnv )
361 (void)xCmdEnv;
363 BackendImpl * that = getMyBackend();
364 Reference< deployment::XPackage > xThisPackage( this );
365 rtl::OUString aRegisteredFlagFile = that->getRegisteredFlagFileURL( xThisPackage );
367 Reference< ucb::XSimpleFileAccess > xSFA = that->getFileAccess();
368 bool bReg = xSFA->exists( aRegisteredFlagFile );
370 return beans::Optional< beans::Ambiguous<sal_Bool> >(
371 true /* IsPresent */,
372 beans::Ambiguous<sal_Bool>( bReg, false /* IsAmbiguous */ ) );
375 //______________________________________________________________________________
376 void BackendImpl::PackageImpl::processPackage_(
377 ::osl::ResettableMutexGuard &,
378 bool doRegisterPackage,
379 ::rtl::Reference<AbortChannel> const &,
380 Reference<XCommandEnvironment> const & xCmdEnv )
382 (void)xCmdEnv;
384 BackendImpl * that = getMyBackend();
386 Reference< deployment::XPackage > xThisPackage( this );
387 rtl::OUString aRegisteredFlagFile = that->getRegisteredFlagFileURL( xThisPackage );
388 Reference< ucb::XSimpleFileAccess > xSFA = that->getFileAccess();
389 Reference<XComponentContext> const & xComponentContext = that->getComponentContext();
391 bool bScript = (m_scriptURL.getLength() > 0);
392 Reference<css::script::XLibraryContainer> xScriptLibs;
394 bool bDialog = (m_dialogURL.getLength() > 0);
395 Reference<css::script::XLibraryContainer> xDialogLibs;
397 bool bRunning = office_is_running();
398 if( bRunning )
400 if( bScript )
402 xScriptLibs.set(
403 xComponentContext->getServiceManager()->createInstanceWithContext(
404 OUSTR("com.sun.star.script.ApplicationScriptLibraryContainer"),
405 xComponentContext ), UNO_QUERY_THROW );
408 if( bDialog )
410 xDialogLibs.set(
411 xComponentContext->getServiceManager()->createInstanceWithContext(
412 OUSTR("com.sun.star.script.ApplicationDialogLibraryContainer"),
413 xComponentContext ), UNO_QUERY_THROW );
417 if( !doRegisterPackage )
419 if( xSFA->exists( aRegisteredFlagFile ) )
421 xSFA->kill( aRegisteredFlagFile );
423 if( bScript && xScriptLibs.is() && xScriptLibs->hasByName( m_name ) )
424 xScriptLibs->removeLibrary( m_name );
426 if( bDialog && xDialogLibs.is() && xDialogLibs->hasByName( m_dialogName ) )
427 xDialogLibs->removeLibrary( m_dialogName );
429 return;
432 if( xSFA->exists( aRegisteredFlagFile ) )
433 return; // Already registered
435 // Update LibraryContainer
436 bool bScriptSuccess = false;
437 const bool bReadOnly = false;
438 if( bScript && xScriptLibs.is() && !xScriptLibs->hasByName( m_name ) )
440 xScriptLibs->createLibraryLink( m_name, m_scriptURL, bReadOnly );
441 bScriptSuccess = xScriptLibs->hasByName( m_name );
444 bool bDialogSuccess = false;
445 if( bDialog && xDialogLibs.is() && !xDialogLibs->hasByName( m_dialogName ) )
447 xDialogLibs->createLibraryLink( m_dialogName, m_dialogURL, bReadOnly );
448 bDialogSuccess = xDialogLibs->hasByName( m_dialogName );
451 bool bSuccess = bScript || bDialog; // Something must have happened
452 if( bRunning )
453 if( (bScript && !bScriptSuccess) || (bDialog && !bDialogSuccess) )
454 bSuccess = false;
456 if( bSuccess && !xSFA->exists( aRegisteredFlagFile ) )
458 Reference< io::XOutputStream > xOutputStream = xSFA->openFileWrite( aRegisteredFlagFile );
459 if( xOutputStream.is() )
460 xOutputStream->closeOutput();
464 } // anon namespace
466 namespace sdecl = comphelper::service_decl;
467 sdecl::class_<BackendImpl, sdecl::with_args<true> > serviceBI;
468 extern sdecl::ServiceDecl const serviceDecl(
469 serviceBI,
470 "com.sun.star.comp.deployment.script.PackageRegistryBackend",
471 BACKEND_SERVICE_NAME );
473 } // namespace script
474 } // namespace backend
475 } // namespace dp_registry