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