LibreOffice Module desktop (master)  1
dp_sfwk.cxx
Go to the documentation of this file.
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 <sal/config.h>
21 
22 #include <dp_services.hxx>
23 #include <strings.hrc>
24 #include <dp_backend.h>
25 #include <dp_ucb.h>
26 #include "dp_parceldesc.hxx"
27 #include <rtl/uri.hxx>
28 #include <ucbhelper/content.hxx>
29 #include <cppuhelper/exc_hlp.hxx>
31 #include <svl/inettype.hxx>
32 #include <com/sun/star/container/XNameContainer.hpp>
33 #include <com/sun/star/script/provider/theMasterScriptProviderFactory.hpp>
34 #include <com/sun/star/xml/sax/Parser.hpp>
35 
36 
37 using namespace ::dp_misc;
38 using namespace ::com::sun::star;
39 using namespace ::com::sun::star::uno;
40 using namespace ::com::sun::star::ucb;
41 using namespace ::com::sun::star::script;
42 
43 
44 namespace dp_registry
45 {
46 namespace backend
47 {
48 namespace sfwk
49 {
50 
51 
53 {
55  {
56  BackendImpl * getMyBackend() const;
57 
59  OUString m_descr;
60 
61  void initPackageHandler();
62 
63  // Package
64  virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
65  ::osl::ResettableMutexGuard & guard,
66  ::rtl::Reference<AbortChannel> const & abortChannel,
67  Reference<XCommandEnvironment> const & xCmdEnv ) override;
68  virtual void processPackage_(
69  ::osl::ResettableMutexGuard & guard,
70  bool registerPackage,
71  bool startup,
72  ::rtl::Reference<AbortChannel> const & abortChannel,
73  Reference<XCommandEnvironment> const & xCmdEnv ) override;
74 
75  public:
77  ::rtl::Reference<BackendImpl> const & myBackend,
78  OUString const & url, OUString const & libType, bool bRemoved,
79  OUString const & identifier);
80  // XPackage
81  virtual OUString SAL_CALL getDescription() override;
82  virtual OUString SAL_CALL getLicenseText() override;
83  };
84  friend class PackageImpl;
85 
86  // PackageRegistryBackend
87  virtual Reference<deployment::XPackage> bindPackage_(
88  OUString const & url, OUString const & mediaType,
89  bool bRemoved, OUString const & identifier,
90  Reference<XCommandEnvironment> const & xCmdEnv ) override;
91 
92  const Reference<deployment::XPackageTypeInfo> m_xTypeInfo;
93 
94 
95 public:
97  Sequence<Any> const & args,
98  Reference<XComponentContext> const & xComponentContext );
99 
100  // XPackageRegistry
101  virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL
102  getSupportedPackageTypes() override;
103  virtual void SAL_CALL packageRemoved(OUString const & url, OUString const & mediaType) override;
104 };
105 
107 {
108  BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
109  if (nullptr == pBackend)
110  {
111  //May throw a DisposedException
112  check();
113  //We should never get here...
114  throw RuntimeException("Failed to get the BackendImpl",
115  static_cast<OWeakObject*>(const_cast<PackageImpl *>(this)));
116  }
117  return pBackend;
118 }
119 
121 {
122  if (m_descr.isEmpty())
123  return Package::getDescription();
124  else
125  return m_descr;
126 }
127 
129 {
130  return Package::getDescription();
131 }
132 
134  ::rtl::Reference<BackendImpl> const & myBackend,
135  OUString const & url, OUString const & libType, bool bRemoved,
136  OUString const & identifier)
137  : Package( myBackend.get(), url, OUString(), OUString(),
138  myBackend->m_xTypeInfo, bRemoved, identifier),
139  m_descr(libType)
140 {
142 
143  sal_Int32 segmEnd = url.getLength();
144  if ( url.endsWith("/") )
145  --segmEnd;
146  sal_Int32 segmStart = url.lastIndexOf( '/', segmEnd ) + 1;
147  if (segmStart < 0)
148  segmStart = 0;
149  // name and display name default the same:
150  m_displayName = ::rtl::Uri::decode(
151  url.copy( segmStart, segmEnd - segmStart ),
152  rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
154 
155  dp_misc::TRACE("PackageImpl displayName is " + m_displayName);
156 }
157 
158 
160  Sequence<Any> const & args,
161  Reference<XComponentContext> const & xComponentContext )
162  : PackageRegistryBackend( args, xComponentContext ),
163  m_xTypeInfo( new Package::TypeInfo(
164  "application/vnd.sun.star.framework-script",
165  OUString() /* no file filter */,
166  "Scripting Framework Script Library"
167  ) )
168 {
169 }
170 
171 
172 // XPackageRegistry
173 
174 Sequence< Reference<deployment::XPackageTypeInfo> >
176 {
177  return Sequence< Reference<deployment::XPackageTypeInfo> >(&m_xTypeInfo, 1);
178 }
179 
180 void BackendImpl::packageRemoved(OUString const & /*url*/, OUString const & /*mediaType*/)
181 {
182 }
183 
184 // PackageRegistryBackend
185 
186 Reference<deployment::XPackage> BackendImpl::bindPackage_(
187  OUString const & url, OUString const & mediaType_, bool bRemoved,
188  OUString const & identifier, Reference<XCommandEnvironment> const & xCmdEnv )
189 {
190  OUString mediaType( mediaType_ );
191  if (mediaType.isEmpty())
192  {
193  // detect media-type:
194  ::ucbhelper::Content ucbContent;
195  if (create_ucb_content( &ucbContent, url, xCmdEnv ) &&
196  ucbContent.isFolder())
197  {
198  // probe for parcel-descriptor.xml:
199  if (create_ucb_content(
200  nullptr, makeURL( url, "parcel-descriptor.xml" ),
201  xCmdEnv, false /* no throw */ ))
202  {
203  mediaType = "application/vnd.sun.star.framework-script";
204  }
205  }
206  if (mediaType.isEmpty())
207  throw lang::IllegalArgumentException(
208  StrCannotDetectMediaType() + url,
209  static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
210  }
211 
212  OUString type, subType;
214  if (INetContentTypes::parse( mediaType, type, subType, &params ))
215  {
216  if (type.equalsIgnoreAsciiCase("application"))
217  {
218  if (subType.equalsIgnoreAsciiCase("vnd.sun.star.framework-script"))
219  {
220  OUString lang = "Script";
221  OUString sParcelDescURL = makeURL(
222  url, "parcel-descriptor.xml" );
223 
224  ::ucbhelper::Content ucb_content;
225 
226  if (create_ucb_content( &ucb_content, sParcelDescURL,
227  xCmdEnv, false /* no throw */ ))
228  {
229  ParcelDescDocHandler* pHandler =
230  new ParcelDescDocHandler();
232  xDocHandler = pHandler;
233 
236 
237  Reference< xml::sax::XParser > xParser = xml::sax::Parser::create(xContext);
238 
239  xParser->setDocumentHandler( xDocHandler );
240  xml::sax::InputSource source;
241  source.aInputStream = ucb_content.openStream();
242  source.sSystemId = ucb_content.getURL();
243  xParser->parseStream( source );
244 
245  if ( pHandler->isParsed() )
246  {
247  lang = pHandler->getParcelLanguage();
248  }
249  }
250 
251  OUString sfwkLibType = DpResId( RID_STR_SFWK_LIB );
252  // replace %MACRONAME placeholder with language name
253  OUString MACRONAME( "%MACROLANG" );
254  sal_Int32 startOfReplace = sfwkLibType.indexOf( MACRONAME );
255  sal_Int32 charsToReplace = MACRONAME.getLength();
256  sfwkLibType = sfwkLibType.replaceAt( startOfReplace, charsToReplace, lang );
257  dp_misc::TRACE("******************************\n");
258  dp_misc::TRACE(" BackEnd detected lang = " + lang + "\n");
259  dp_misc::TRACE(" for url " + sParcelDescURL + "\n");
260  dp_misc::TRACE("******************************\n");
261  return new PackageImpl( this, url, sfwkLibType, bRemoved, identifier);
262  }
263  }
264  }
265  throw lang::IllegalArgumentException(
266  StrUnsupportedMediaType() + mediaType,
267  static_cast<OWeakObject *>(this),
268  static_cast<sal_Int16>(-1) );
269 }
270 
271 
273 {
274  if (m_xNameCntrPkgHandler.is())
275  return;
276 
277  BackendImpl * that = getMyBackend();
278  Any aContext;
279 
280  if ( that->m_eContext == Context::User )
281  {
282  aContext <<= OUString("user");
283  }
284  else if ( that->m_eContext == Context::Shared )
285  {
286  aContext <<= OUString("share");
287  }
288  else if ( that->m_eContext == Context::Bundled )
289  {
290  aContext <<= OUString("bundled");
291  }
292  else
293  {
294  OSL_ASSERT( false );
295  // NOT supported at the moment // TODO
296  }
297 
298  Reference< provider::XScriptProviderFactory > xFac =
299  provider::theMasterScriptProviderFactory::get( that->getComponentContext() );
300 
301  Reference< container::XNameContainer > xName( xFac->createScriptProvider( aContext ), UNO_QUERY );
302  if ( xName.is() )
303  {
304  m_xNameCntrPkgHandler.set( xName );
305  }
306  // TODO what happens if above fails??
307 }
308 
309 // Package
310 
311 beans::Optional< beans::Ambiguous<sal_Bool> >
313  ::osl::ResettableMutexGuard &,
316 {
317  return beans::Optional< beans::Ambiguous<sal_Bool> >(
318  true /* IsPresent */,
319  beans::Ambiguous<sal_Bool>(
320  m_xNameCntrPkgHandler.is() && m_xNameCntrPkgHandler->hasByName(
321  m_url ),
322  false /* IsAmbiguous */ ) );
323 }
324 
325 
327  ::osl::ResettableMutexGuard &,
328  bool doRegisterPackage,
329  bool /* startup */,
332 {
333  if ( !m_xNameCntrPkgHandler.is() )
334  {
335  dp_misc::TRACE("no package handler!!!!\n");
336  throw RuntimeException( "No package Handler " );
337  }
338 
339  if (doRegisterPackage)
340  {
341  // will throw if it fails
342  m_xNameCntrPkgHandler->insertByName( m_url, makeAny( Reference< XPackage >(this) ) );
343 
344  }
345  else // revokePackage()
346  {
347  m_xNameCntrPkgHandler->removeByName( m_url );
348  }
349 }
350 
351 namespace sdecl = comphelper::service_decl;
354  serviceBI,
355  "com.sun.star.comp.deployment.sfwk.PackageRegistryBackend",
357 
358 } // namespace sfwk
359 } // namespace backend
360 } // namespace dp_registry
361 
362 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
virtual Sequence< Reference< deployment::XPackageTypeInfo > > SAL_CALL getSupportedPackageTypes() override
Definition: dp_sfwk.cxx:175
enum dp_registry::backend::PackageRegistryBackend::Context m_eContext
virtual void processPackage_(::osl::ResettableMutexGuard &guard, bool registerPackage, bool startup,::rtl::Reference< AbortChannel > const &abortChannel, Reference< XCommandEnvironment > const &xCmdEnv) override
Definition: dp_sfwk.cxx:326
PackageImpl(::rtl::Reference< BackendImpl > const &myBackend, OUString const &url, OUString const &libType, bool bRemoved, OUString const &identifier)
Definition: dp_sfwk.cxx:133
OUString makeURL(OUString const &baseURL, OUString const &relPath_)
appends a relative path to a url.
Definition: dp_misc.cxx:266
virtual void SAL_CALL registerPackage(sal_Bool startup, css::uno::Reference< css::task::XAbortChannel > const &xAbortChannel, css::uno::Reference< css::ucb::XCommandEnvironment > const &xCmdEnv) override
Definition: dp_backend.cxx:682
virtual Reference< deployment::XPackage > bindPackage_(OUString const &url, OUString const &mediaType, bool bRemoved, OUString const &identifier, Reference< XCommandEnvironment > const &xCmdEnv) override
Definition: dp_sfwk.cxx:186
css::uno::Reference< css::deployment::XPackageRegistry > create(css::uno::Reference< css::deployment::XPackageRegistry > const &xRootRegistry, OUString const &context, OUString const &cachePath, css::uno::Reference< css::uno::XComponentContext > const &xComponentContext)
static bool parse(OUString const &rMediaType, OUString &rType, OUString &rSubType, INetContentTypeParameterList *pParameters=nullptr)
sdecl::class_< BackendImpl, sdecl::with_args< true > > const serviceBI
Definition: dp_sfwk.cxx:352
Reference< container::XNameContainer > m_xNameCntrPkgHandler
Definition: dp_sfwk.cxx:58
const Reference< deployment::XPackageTypeInfo > m_xTypeInfo
Definition: dp_sfwk.cxx:92
virtual OUString SAL_CALL getLicenseText() override
Definition: dp_sfwk.cxx:128
const OUString & getURL() const
comphelper::service_decl::ServiceDecl const serviceDecl
Definition: dp_services.hxx:22
virtual beans::Optional< beans::Ambiguous< sal_Bool > > isRegistered_(::osl::ResettableMutexGuard &guard,::rtl::Reference< AbortChannel > const &abortChannel, Reference< XCommandEnvironment > const &xCmdEnv) override
Definition: dp_sfwk.cxx:312
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC bool create_ucb_content(::ucbhelper::Content *ucb_content, OUString const &url, css::uno::Reference< css::ucb::XCommandEnvironment > const &xCmdEnv, bool throw_exc=true)
#define BACKEND_SERVICE_NAME
Definition: dp_backend.h:45
static uno::Reference< css::uno::XComponentContext > xContext
Definition: init.cxx:1604
css::uno::Reference< css::io::XInputStream > openStream()
void TRACE(OUString const &sText)
print the text to the console in a debug build.
Definition: dp_misc.cxx:527
BackendImpl(Sequence< Any > const &args, Reference< XComponentContext > const &xComponentContext)
Definition: dp_sfwk.cxx:159
std::unordered_map< OString, INetContentTypeParameter > INetContentTypeParameterList
css::uno::Reference< css::uno::XComponentContext > const & getComponentContext() const
Definition: dp_backend.h:265
OUString DpResId(const char *pId)
Definition: dp_shared.hxx:38
::rtl::Reference< PackageRegistryBackend > m_myBackend
Definition: dp_backend.h:61
virtual void SAL_CALL packageRemoved(OUString const &url, OUString const &mediaType) override
Definition: dp_sfwk.cxx:180
virtual OUString SAL_CALL getDescription() override
Definition: dp_sfwk.cxx:120
virtual OUString SAL_CALL getDescription() override
Definition: dp_backend.cxx:482
css::uno::Any SAL_CALL makeAny(const SharedUNOComponent< INTERFACE, COMPONENT > &value)