1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: dp_script.cxx,v $
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"
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>
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
{
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
;
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
,
86 ::rtl::Reference
<AbortChannel
> const & abortChannel
,
87 Reference
<XCommandEnvironment
> const & xCmdEnv
);
91 ::rtl::Reference
<BackendImpl
> const & myBackend
,
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
;
113 BackendImpl( Sequence
<Any
> const & args
,
114 Reference
<XComponentContext
> const & xComponentContext
);
117 virtual void SAL_CALL
update() throw (RuntimeException
);
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() );
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(
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(
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
) ),
170 m_typeInfos
[ 0 ] = m_xBasicLibTypeInfo
;
171 m_typeInfos
[ 1 ] = m_xDialogLibTypeInfo
;
173 OSL_ASSERT( ! transientMode() );
177 //______________________________________________________________________________
178 void BackendImpl::update() throw (RuntimeException
)
180 // Nothing to do here after fixing i70283!?
184 //______________________________________________________________________________
185 Sequence
< Reference
<deployment::XPackageTypeInfo
> >
186 BackendImpl::getSupportedPackageTypes() throw (RuntimeException
)
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
, ¶ms
))
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") ),
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
;
258 rtl::OUString aHelpURL
= xPackage
->getURL();
259 aRetURL
= expandURL( aHelpURL
);
260 aRetURL
+= rtl::OUString::createFromAscii( "/RegisteredFlag" );
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();
274 xFac
= Reference
< uri::XUriReferenceFactory
>(
275 xContext
->getServiceManager()->createInstanceWithContext( rtl::OUString::createFromAscii(
276 "com.sun.star.uri.UriReferenceFactory"), xContext
) , UNO_QUERY
);
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" ) ),
293 rtl::OUString aRetURL
= aURL
;
294 if( xMacroExpander
.is() )
296 Reference
< uri::XUriReference
> uriRef
;
299 uriRef
= Reference
< uri::XUriReference
>( xFac
->parse( aRetURL
), UNO_QUERY
);
302 Reference
< uri::XVndSunStarExpandUrl
> sxUri( uriRef
, UNO_QUERY
);
306 aRetURL
= sxUri
->expand( xMacroExpander
);
313 Reference
< ucb::XSimpleFileAccess
> BackendImpl::getFileAccess( void )
317 Reference
<XComponentContext
> const & xContext
= getComponentContext();
320 m_xSFA
= Reference
< ucb::XSimpleFileAccess
>(
321 xContext
->getServiceManager()->createInstanceWithContext(
322 rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ),
323 xContext
), UNO_QUERY
);
327 throw RuntimeException(
328 ::rtl::OUString::createFromAscii(
329 "dp_registry::backend::help::BackendImpl::getFileAccess(), "
330 "could not instatiate SimpleFileAccess." ),
331 Reference
< XInterface
>() );
337 //##############################################################################
340 BackendImpl
* BackendImpl::PackageImpl::getMyBackend() const
342 BackendImpl
* pBackend
= static_cast<BackendImpl
*>(m_myBackend
.get());
343 if (NULL
== pBackend
)
345 //May throw a DisposedException
347 //We should never get here...
348 throw RuntimeException(
349 OUSTR("Failed to get the BackendImpl"),
350 static_cast<OWeakObject
*>(const_cast<PackageImpl
*>(this)));
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
)
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
)
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();
403 xComponentContext
->getServiceManager()->createInstanceWithContext(
404 OUSTR("com.sun.star.script.ApplicationScriptLibraryContainer"),
405 xComponentContext
), UNO_QUERY_THROW
);
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
);
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
453 if( (bScript
&& !bScriptSuccess
) || (bDialog
&& !bDialogSuccess
) )
456 if( bSuccess
&& !xSFA
->exists( aRegisteredFlagFile
) )
458 Reference
< io::XOutputStream
> xOutputStream
= xSFA
->openFileWrite( aRegisteredFlagFile
);
459 if( xOutputStream
.is() )
460 xOutputStream
->closeOutput();
466 namespace sdecl
= comphelper::service_decl
;
467 sdecl::class_
<BackendImpl
, sdecl::with_args
<true> > serviceBI
;
468 extern sdecl::ServiceDecl
const serviceDecl(
470 "com.sun.star.comp.deployment.script.PackageRegistryBackend",
471 BACKEND_SERVICE_NAME
);
473 } // namespace script
474 } // namespace backend
475 } // namespace dp_registry