Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include "dp_sfwk.hrc"
21 : #include "dp_backend.h"
22 : #include "dp_ucb.h"
23 : #include "dp_parceldesc.hxx"
24 : #include "rtl/uri.hxx"
25 : #include "ucbhelper/content.hxx"
26 : #include "cppuhelper/exc_hlp.hxx"
27 : #include "comphelper/servicedecl.hxx"
28 : #include "svl/inettype.hxx"
29 : #include <com/sun/star/container/XNameContainer.hpp>
30 : #include <com/sun/star/script/provider/XScriptProviderFactory.hpp>
31 : #include <com/sun/star/xml/sax/Parser.hpp>
32 : #include <memory>
33 :
34 :
35 : using namespace ::dp_misc;
36 : using namespace ::com::sun::star;
37 : using namespace ::com::sun::star::uno;
38 : using namespace ::com::sun::star::ucb;
39 : using namespace ::com::sun::star::script;
40 :
41 : using ::rtl::OUString;
42 :
43 : namespace dp_registry
44 : {
45 : namespace backend
46 : {
47 : namespace sfwk
48 : {
49 :
50 : //==============================================================================
51 0 : class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend
52 : {
53 0 : class PackageImpl : public ::dp_registry::backend::Package
54 : {
55 : BackendImpl * getMyBackend() const;
56 :
57 : Reference< container::XNameContainer > m_xNameCntrPkgHandler;
58 : OUString m_descr;
59 :
60 : void initPackageHandler();
61 :
62 : // Package
63 : virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
64 : ::osl::ResettableMutexGuard & guard,
65 : ::rtl::Reference<AbortChannel> const & abortChannel,
66 : Reference<XCommandEnvironment> const & xCmdEnv );
67 : virtual void processPackage_(
68 : ::osl::ResettableMutexGuard & guard,
69 : bool registerPackage,
70 : bool startup,
71 : ::rtl::Reference<AbortChannel> const & abortChannel,
72 : Reference<XCommandEnvironment> const & xCmdEnv );
73 :
74 : public:
75 : PackageImpl(
76 : ::rtl::Reference<BackendImpl> const & myBackend,
77 : OUString const & url, OUString const & libType, bool bRemoved,
78 : OUString const & identifier);
79 : // XPackage
80 : virtual OUString SAL_CALL getDescription() throw (RuntimeException);
81 : virtual OUString SAL_CALL getLicenseText() throw (RuntimeException);
82 : };
83 : friend class PackageImpl;
84 :
85 : // PackageRegistryBackend
86 : virtual Reference<deployment::XPackage> bindPackage_(
87 : OUString const & url, OUString const & mediaType,
88 : sal_Bool bRemoved, OUString const & identifier,
89 : Reference<XCommandEnvironment> const & xCmdEnv );
90 :
91 : const Reference<deployment::XPackageTypeInfo> m_xTypeInfo;
92 :
93 :
94 : public:
95 : BackendImpl(
96 : Sequence<Any> const & args,
97 : Reference<XComponentContext> const & xComponentContext );
98 :
99 : // XPackageRegistry
100 : virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL
101 : getSupportedPackageTypes() throw (RuntimeException);
102 : virtual void SAL_CALL packageRemoved(OUString const & url, OUString const & mediaType)
103 : throw (deployment::DeploymentException,
104 : uno::RuntimeException);
105 : };
106 :
107 0 : BackendImpl * BackendImpl::PackageImpl::getMyBackend() const
108 : {
109 0 : BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
110 0 : if (NULL == pBackend)
111 : {
112 : //May throw a DisposedException
113 0 : check();
114 : //We should never get here...
115 : throw RuntimeException(
116 : OUSTR("Failed to get the BackendImpl"),
117 0 : static_cast<OWeakObject*>(const_cast<PackageImpl *>(this)));
118 : }
119 0 : return pBackend;
120 : }
121 : //______________________________________________________________________________
122 0 : OUString BackendImpl::PackageImpl::getDescription() throw (RuntimeException)
123 : {
124 0 : if (m_descr.isEmpty())
125 0 : return Package::getDescription();
126 : else
127 0 : return m_descr;
128 : }
129 :
130 : //______________________________________________________________________________
131 0 : OUString BackendImpl::PackageImpl::getLicenseText() throw (RuntimeException)
132 : {
133 0 : return Package::getDescription();
134 : }
135 :
136 : //______________________________________________________________________________
137 0 : BackendImpl::PackageImpl::PackageImpl(
138 : ::rtl::Reference<BackendImpl> const & myBackend,
139 : OUString const & url, OUString const & libType, bool bRemoved,
140 : OUString const & identifier)
141 0 : : Package( myBackend.get(), url, OUString(), OUString(),
142 0 : myBackend->m_xTypeInfo, bRemoved, identifier),
143 0 : m_descr(libType)
144 : {
145 0 : initPackageHandler();
146 :
147 0 : sal_Int32 segmEnd = url.getLength();
148 0 : if (!url.isEmpty() && url[ url.getLength() - 1 ] == '/')
149 0 : --segmEnd;
150 0 : sal_Int32 segmStart = (url.lastIndexOf( '/', segmEnd ) + 1);
151 0 : if (segmStart < 0)
152 0 : segmStart = 0;
153 : // name and display name default the same:
154 : m_displayName = ::rtl::Uri::decode(
155 : url.copy( segmStart, segmEnd - segmStart ),
156 0 : rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
157 0 : m_name = m_displayName;
158 :
159 0 : dp_misc::TRACE(OUSTR("PakageImpl displayName is ") + m_displayName);
160 0 : }
161 :
162 : //______________________________________________________________________________
163 0 : BackendImpl::BackendImpl(
164 : Sequence<Any> const & args,
165 : Reference<XComponentContext> const & xComponentContext )
166 : : PackageRegistryBackend( args, xComponentContext ),
167 : m_xTypeInfo( new Package::TypeInfo(
168 : OUSTR("application/vnd.sun.star.framework-script"),
169 : OUString() /* no file filter */,
170 : OUSTR("Scripting Framework Script Library"),
171 0 : RID_IMG_SCRIPTLIB ) )
172 : {
173 0 : if (! transientMode())
174 : {
175 : }
176 0 : }
177 :
178 :
179 :
180 : // XPackageRegistry
181 : //______________________________________________________________________________
182 : Sequence< Reference<deployment::XPackageTypeInfo> >
183 0 : BackendImpl::getSupportedPackageTypes() throw (RuntimeException)
184 : {
185 0 : return Sequence< Reference<deployment::XPackageTypeInfo> >(&m_xTypeInfo, 1);
186 : }
187 :
188 0 : void BackendImpl::packageRemoved(OUString const & /*url*/, OUString const & /*mediaType*/)
189 : throw (deployment::DeploymentException,
190 : uno::RuntimeException)
191 : {
192 0 : }
193 :
194 : // PackageRegistryBackend
195 : //______________________________________________________________________________
196 0 : Reference<deployment::XPackage> BackendImpl::bindPackage_(
197 : OUString const & url, OUString const & mediaType_, sal_Bool bRemoved,
198 : OUString const & identifier, Reference<XCommandEnvironment> const & xCmdEnv )
199 : {
200 0 : OUString mediaType( mediaType_ );
201 0 : if (mediaType.isEmpty())
202 : {
203 : // detect media-type:
204 0 : ::ucbhelper::Content ucbContent;
205 0 : if (create_ucb_content( &ucbContent, url, xCmdEnv ) &&
206 0 : ucbContent.isFolder())
207 : {
208 : // probe for parcel-descriptor.xml:
209 0 : if (create_ucb_content(
210 : 0, makeURL( url, OUSTR("parcel-descriptor.xml") ),
211 0 : xCmdEnv, false /* no throw */ ))
212 : {
213 0 : mediaType = OUSTR("application/vnd.sun.star.framework-script");
214 : }
215 : }
216 0 : if (mediaType.isEmpty())
217 : throw lang::IllegalArgumentException(
218 0 : StrCannotDetectMediaType::get() + url,
219 0 : static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
220 : }
221 :
222 0 : OUString type, subType;
223 0 : INetContentTypeParameterList params;
224 0 : if (INetContentTypes::parse( mediaType, type, subType, ¶ms ))
225 : {
226 0 : if (type.equalsIgnoreAsciiCaseAscii("application"))
227 : {
228 0 : if (subType.equalsIgnoreAsciiCaseAscii("vnd.sun.star.framework-script"))
229 : {
230 0 : OUString lang = OUString("Script");
231 : OUString sParcelDescURL = makeURL(
232 0 : url, OUSTR("parcel-descriptor.xml") );
233 :
234 0 : ::ucbhelper::Content ucb_content;
235 :
236 0 : if (create_ucb_content( &ucb_content, sParcelDescURL,
237 : xCmdEnv, false /* no throw */ ))
238 : {
239 : ParcelDescDocHandler* pHandler =
240 0 : new ParcelDescDocHandler();
241 : Reference< xml::sax::XDocumentHandler >
242 0 : xDocHandler = pHandler;
243 :
244 : Reference<XComponentContext>
245 0 : xContext( getComponentContext() );
246 :
247 0 : Reference< xml::sax::XParser > xParser = xml::sax::Parser::create(xContext);
248 :
249 0 : xParser->setDocumentHandler( xDocHandler );
250 0 : xml::sax::InputSource source;
251 0 : source.aInputStream = ucb_content.openStream();
252 0 : source.sSystemId = ucb_content.getURL();
253 0 : xParser->parseStream( source );
254 :
255 0 : if ( pHandler->isParsed() )
256 : {
257 0 : lang = pHandler->getParcelLanguage();
258 0 : }
259 : }
260 :
261 0 : OUString sfwkLibType = getResourceString( RID_STR_SFWK_LIB );
262 : // replace %MACRONAME placeholder with language name
263 0 : OUString MACRONAME( OUSTR("%MACROLANG" ) );
264 0 : sal_Int32 startOfReplace = sfwkLibType.indexOf( MACRONAME );
265 0 : sal_Int32 charsToReplace = MACRONAME.getLength();
266 0 : sfwkLibType = sfwkLibType.replaceAt( startOfReplace, charsToReplace, lang );
267 0 : dp_misc::TRACE("******************************\n");
268 0 : dp_misc::TRACE(OUSTR(" BackEnd detected lang = ") + lang + OUSTR("\n"));
269 0 : dp_misc::TRACE(OUSTR(" for url ") + sParcelDescURL + OUSTR("\n") );
270 0 : dp_misc::TRACE("******************************\n");
271 0 : return new PackageImpl( this, url, sfwkLibType, bRemoved, identifier);
272 : }
273 : }
274 : }
275 : throw lang::IllegalArgumentException(
276 0 : StrUnsupportedMediaType::get() + mediaType,
277 : static_cast<OWeakObject *>(this),
278 0 : static_cast<sal_Int16>(-1) );
279 : }
280 :
281 :
282 0 : void BackendImpl::PackageImpl:: initPackageHandler()
283 : {
284 0 : if (m_xNameCntrPkgHandler.is())
285 0 : return;
286 :
287 0 : BackendImpl * that = getMyBackend();
288 0 : Any aContext;
289 :
290 0 : if ( that->m_eContext == CONTEXT_USER )
291 : {
292 0 : aContext <<= OUSTR("user");
293 : }
294 0 : else if ( that->m_eContext == CONTEXT_SHARED )
295 : {
296 0 : aContext <<= OUSTR("share");
297 : }
298 0 : else if ( that->m_eContext == CONTEXT_BUNDLED )
299 : {
300 0 : aContext <<= OUSTR("bundled");
301 : }
302 : else
303 : {
304 : OSL_ASSERT( 0 );
305 : // NOT supported at the momemtn // TODO
306 : }
307 :
308 : Reference< provider::XScriptProviderFactory > xFac(
309 0 : that->getComponentContext()->getValueByName(
310 0 : OUSTR( "/singletons/com.sun.star.script.provider.theMasterScriptProviderFactory") ), UNO_QUERY );
311 :
312 0 : if ( xFac.is() )
313 : {
314 0 : Reference< container::XNameContainer > xName( xFac->createScriptProvider( aContext ), UNO_QUERY );
315 0 : if ( xName.is() )
316 : {
317 0 : m_xNameCntrPkgHandler.set( xName );
318 0 : }
319 0 : }
320 : // TODO what happens if above fails??
321 : }
322 :
323 : // Package
324 : //______________________________________________________________________________
325 : beans::Optional< beans::Ambiguous<sal_Bool> >
326 0 : BackendImpl::PackageImpl::isRegistered_(
327 : ::osl::ResettableMutexGuard &,
328 : ::rtl::Reference<AbortChannel> const &,
329 : Reference<XCommandEnvironment> const & )
330 : {
331 : return beans::Optional< beans::Ambiguous<sal_Bool> >(
332 : true /* IsPresent */,
333 : beans::Ambiguous<sal_Bool>(
334 0 : m_xNameCntrPkgHandler.is() && m_xNameCntrPkgHandler->hasByName(
335 0 : m_url ),
336 0 : false /* IsAmbiguous */ ) );
337 : }
338 :
339 : //______________________________________________________________________________
340 0 : void BackendImpl::PackageImpl::processPackage_(
341 : ::osl::ResettableMutexGuard &,
342 : bool doRegisterPackage,
343 : bool /* startup */,
344 : ::rtl::Reference<AbortChannel> const &,
345 : Reference<XCommandEnvironment> const & )
346 : {
347 0 : if ( !m_xNameCntrPkgHandler.is() )
348 : {
349 0 : dp_misc::TRACE("no package handler!!!!\n");
350 : throw RuntimeException( OUSTR("No package Handler " ),
351 0 : Reference< XInterface >() );
352 : }
353 :
354 0 : if (doRegisterPackage)
355 : {
356 : // will throw if it fails
357 0 : m_xNameCntrPkgHandler->insertByName( m_url, makeAny( Reference< XPackage >(this) ) );
358 :
359 : }
360 : else // revokePackage()
361 : {
362 0 : m_xNameCntrPkgHandler->removeByName( m_url );
363 : }
364 0 : }
365 :
366 : namespace sdecl = comphelper::service_decl;
367 1 : sdecl::class_<BackendImpl, sdecl::with_args<true> > serviceBI;
368 1 : extern sdecl::ServiceDecl const serviceDecl(
369 : serviceBI,
370 : "com.sun.star.comp.deployment.sfwk.PackageRegistryBackend",
371 : BACKEND_SERVICE_NAME );
372 :
373 : } // namespace sfwk
374 : } // namespace backend
375 3 : } // namespace dp_registry
376 :
377 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|