1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_desktop.hxx" 26 #include "dp_sfwk.hrc" 27 #include "dp_backend.h" 28 #include "dp_ucb.h" 29 #include "dp_parceldesc.hxx" 30 #include "rtl/uri.hxx" 31 #include "ucbhelper/content.hxx" 32 #include "cppuhelper/exc_hlp.hxx" 33 #include "comphelper/servicedecl.hxx" 34 #include "svl/inettype.hxx" 35 #include <com/sun/star/container/XNameContainer.hpp> 36 #include <com/sun/star/script/provider/XScriptProviderFactory.hpp> 37 #include <memory> 38 39 40 using namespace ::dp_misc; 41 using namespace ::com::sun::star; 42 using namespace ::com::sun::star::uno; 43 using namespace ::com::sun::star::ucb; 44 using namespace ::com::sun::star::script; 45 46 using ::rtl::OUString; 47 namespace css = ::com::sun::star; 48 49 namespace dp_registry 50 { 51 namespace backend 52 { 53 namespace sfwk 54 { 55 56 //============================================================================== 57 class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend 58 { 59 class PackageImpl : public ::dp_registry::backend::Package 60 { 61 BackendImpl * getMyBackend() const; 62 63 Reference< container::XNameContainer > m_xNameCntrPkgHandler; 64 OUString m_descr; 65 66 void initPackageHandler(); 67 68 // Package 69 virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_( 70 ::osl::ResettableMutexGuard & guard, 71 ::rtl::Reference<AbortChannel> const & abortChannel, 72 Reference<XCommandEnvironment> const & xCmdEnv ); 73 virtual void processPackage_( 74 ::osl::ResettableMutexGuard & guard, 75 bool registerPackage, 76 bool startup, 77 ::rtl::Reference<AbortChannel> const & abortChannel, 78 Reference<XCommandEnvironment> const & xCmdEnv ); 79 80 public: 81 PackageImpl( 82 ::rtl::Reference<BackendImpl> const & myBackend, 83 OUString const & url, OUString const & libType, bool bRemoved, 84 OUString const & identifier); 85 // XPackage 86 virtual OUString SAL_CALL getDescription() throw (RuntimeException); 87 virtual OUString SAL_CALL getLicenseText() throw (RuntimeException); 88 }; 89 friend class PackageImpl; 90 91 // PackageRegistryBackend 92 virtual Reference<deployment::XPackage> bindPackage_( 93 OUString const & url, OUString const & mediaType, 94 sal_Bool bRemoved, OUString const & identifier, 95 Reference<XCommandEnvironment> const & xCmdEnv ); 96 97 const Reference<deployment::XPackageTypeInfo> m_xTypeInfo; 98 99 100 public: 101 BackendImpl( 102 Sequence<Any> const & args, 103 Reference<XComponentContext> const & xComponentContext ); 104 105 // XPackageRegistry 106 virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL 107 getSupportedPackageTypes() throw (RuntimeException); 108 virtual void SAL_CALL packageRemoved(OUString const & url, OUString const & mediaType) 109 throw (deployment::DeploymentException, 110 uno::RuntimeException); 111 }; 112 113 BackendImpl * BackendImpl::PackageImpl::getMyBackend() const 114 { 115 BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get()); 116 if (NULL == pBackend) 117 { 118 //May throw a DisposedException 119 check(); 120 //We should never get here... 121 throw RuntimeException( 122 OUSTR("Failed to get the BackendImpl"), 123 static_cast<OWeakObject*>(const_cast<PackageImpl *>(this))); 124 } 125 return pBackend; 126 } 127 //______________________________________________________________________________ 128 OUString BackendImpl::PackageImpl::getDescription() throw (RuntimeException) 129 { 130 if (m_descr.getLength() == 0) 131 return Package::getDescription(); 132 else 133 return m_descr; 134 } 135 136 //______________________________________________________________________________ 137 OUString BackendImpl::PackageImpl::getLicenseText() throw (RuntimeException) 138 { 139 return Package::getDescription(); 140 } 141 142 //______________________________________________________________________________ 143 BackendImpl::PackageImpl::PackageImpl( 144 ::rtl::Reference<BackendImpl> const & myBackend, 145 OUString const & url, OUString const & libType, bool bRemoved, 146 OUString const & identifier) 147 : Package( myBackend.get(), url, OUString(), OUString(), 148 myBackend->m_xTypeInfo, bRemoved, identifier), 149 m_descr(libType) 150 { 151 initPackageHandler(); 152 153 sal_Int32 segmEnd = url.getLength(); 154 if (url.getLength() > 0 && url[ url.getLength() - 1 ] == '/') 155 --segmEnd; 156 sal_Int32 segmStart = (url.lastIndexOf( '/', segmEnd ) + 1); 157 if (segmStart < 0) 158 segmStart = 0; 159 // name and display name default the same: 160 m_displayName = ::rtl::Uri::decode( 161 url.copy( segmStart, segmEnd - segmStart ), 162 rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 ); 163 m_name = m_displayName; 164 165 dp_misc::TRACE(OUSTR("PakageImpl displayName is ") + m_displayName); 166 } 167 168 //______________________________________________________________________________ 169 BackendImpl::BackendImpl( 170 Sequence<Any> const & args, 171 Reference<XComponentContext> const & xComponentContext ) 172 : PackageRegistryBackend( args, xComponentContext ), 173 m_xTypeInfo( new Package::TypeInfo( 174 OUSTR("application/vnd.sun.star.framework-script"), 175 OUString() /* no file filter */, 176 OUSTR("Scripting Framework Script Library"), 177 RID_IMG_SCRIPTLIB, RID_IMG_SCRIPTLIB_HC ) ) 178 { 179 if (! transientMode()) 180 { 181 /* 182 if (office_is_running()) 183 { 184 Reference<XComponentContext> xContext( getComponentContext() ); 185 m_xScriptLibs.set( 186 xContext->getServiceManager()->createInstanceWithContext( 187 OUSTR("com.sun.star." 188 "script.ApplicationScriptLibraryContainer"), 189 xContext ), UNO_QUERY_THROW ); 190 m_xDialogLibs.set( 191 xContext->getServiceManager()->createInstanceWithContext( 192 OUSTR("com.sun.star." 193 "script.ApplicationDialogLibraryContainer"), 194 xContext ), UNO_QUERY_THROW ); 195 } 196 else 197 { 198 OUString basic_path( 199 m_eContext == CONTEXT_USER 200 ? OUSTR("vnd.sun.star.expand:${$BRAND_BASE_DIR/program/" 201 SAL_CONFIGFILE("bootstrap") 202 ":UserInstallation}/user/basic") 203 : OUSTR("vnd.sun.star.expand:${$BRAND_BASE_DIR/program/" 204 SAL_CONFIGFILE("bootstrap") 205 ":BaseInstallation}/share/basic") ); 206 m_basic_script_libs.reset( 207 new LibraryContainer( 208 makeURL( basic_path, OUSTR("script.xlc") ), 209 getMutex(), 210 getComponentContext() ) ); 211 m_dialog_libs.reset( 212 new LibraryContainer( 213 makeURL( basic_path, OUSTR("dialog.xlc") ), 214 getMutex(), 215 getComponentContext() ) ); 216 } 217 */ 218 } 219 } 220 221 222 223 // XPackageRegistry 224 //______________________________________________________________________________ 225 Sequence< Reference<deployment::XPackageTypeInfo> > 226 BackendImpl::getSupportedPackageTypes() throw (RuntimeException) 227 { 228 return Sequence< Reference<deployment::XPackageTypeInfo> >(&m_xTypeInfo, 1); 229 } 230 231 void BackendImpl::packageRemoved(OUString const & /*url*/, OUString const & /*mediaType*/) 232 throw (deployment::DeploymentException, 233 uno::RuntimeException) 234 { 235 } 236 237 // PackageRegistryBackend 238 //______________________________________________________________________________ 239 Reference<deployment::XPackage> BackendImpl::bindPackage_( 240 OUString const & url, OUString const & mediaType_, sal_Bool bRemoved, 241 OUString const & identifier, Reference<XCommandEnvironment> const & xCmdEnv ) 242 { 243 OUString mediaType( mediaType_ ); 244 if (mediaType.getLength() == 0) 245 { 246 // detect media-type: 247 ::ucbhelper::Content ucbContent; 248 if (create_ucb_content( &ucbContent, url, xCmdEnv ) && 249 ucbContent.isFolder()) 250 { 251 // probe for parcel-descriptor.xml: 252 if (create_ucb_content( 253 0, makeURL( url, OUSTR("parcel-descriptor.xml") ), 254 xCmdEnv, false /* no throw */ )) 255 { 256 mediaType = OUSTR("application/vnd.sun.star.framework-script"); 257 } 258 } 259 if (mediaType.getLength() == 0) 260 throw lang::IllegalArgumentException( 261 StrCannotDetectMediaType::get() + url, 262 static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) ); 263 } 264 265 String type, subType; 266 INetContentTypeParameterList params; 267 if (INetContentTypes::parse( mediaType, type, subType, ¶ms )) 268 { 269 if (type.EqualsIgnoreCaseAscii("application")) 270 { 271 if (subType.EqualsIgnoreCaseAscii("vnd.sun.star.framework-script")) 272 { 273 OUString lang = OUString::createFromAscii("Script"); 274 OUString sParcelDescURL = makeURL( 275 url, OUSTR("parcel-descriptor.xml") ); 276 277 ::ucbhelper::Content ucb_content; 278 279 if (create_ucb_content( &ucb_content, sParcelDescURL, 280 xCmdEnv, false /* no throw */ )) 281 { 282 ParcelDescDocHandler* pHandler = 283 new ParcelDescDocHandler(); 284 Reference< xml::sax::XDocumentHandler > 285 xDocHandler = pHandler; 286 287 Reference<XComponentContext> 288 xContext( getComponentContext() ); 289 290 Reference< xml::sax::XParser > xParser( 291 xContext->getServiceManager()->createInstanceWithContext( 292 OUSTR("com.sun.star.xml.sax.Parser"), xContext ), 293 UNO_QUERY_THROW ); 294 295 xParser->setDocumentHandler( xDocHandler ); 296 xml::sax::InputSource source; 297 source.aInputStream = ucb_content.openStream(); 298 source.sSystemId = ucb_content.getURL(); 299 xParser->parseStream( source ); 300 301 if ( pHandler->isParsed() ) 302 { 303 lang = pHandler->getParcelLanguage(); 304 } 305 } 306 307 OUString sfwkLibType = getResourceString( RID_STR_SFWK_LIB ); 308 // replace %MACRONAME placeholder with language name 309 OUString MACRONAME( OUSTR("%MACROLANG" ) ); 310 sal_Int32 startOfReplace = sfwkLibType.indexOf( MACRONAME ); 311 sal_Int32 charsToReplace = MACRONAME.getLength(); 312 sfwkLibType = sfwkLibType.replaceAt( startOfReplace, charsToReplace, lang ); 313 dp_misc::TRACE("******************************\n"); 314 dp_misc::TRACE(OUSTR(" BackEnd detected lang = ") + lang + OUSTR("\n")); 315 dp_misc::TRACE(OUSTR(" for url ") + sParcelDescURL + OUSTR("\n") ); 316 dp_misc::TRACE("******************************\n"); 317 return new PackageImpl( this, url, sfwkLibType, bRemoved, identifier); 318 } 319 } 320 } 321 throw lang::IllegalArgumentException( 322 StrUnsupportedMediaType::get() + mediaType, 323 static_cast<OWeakObject *>(this), 324 static_cast<sal_Int16>(-1) ); 325 } 326 327 //############################################################################## 328 329 void BackendImpl::PackageImpl:: initPackageHandler() 330 { 331 if (m_xNameCntrPkgHandler.is()) 332 return; 333 334 BackendImpl * that = getMyBackend(); 335 Any aContext; 336 337 if ( that->m_eContext == CONTEXT_USER ) 338 { 339 aContext <<= OUSTR("user"); 340 } 341 else if ( that->m_eContext == CONTEXT_SHARED ) 342 { 343 aContext <<= OUSTR("share"); 344 } 345 else if ( that->m_eContext == CONTEXT_BUNDLED ) 346 { 347 aContext <<= OUSTR("bundled"); 348 } 349 else if ( that->m_eContext == CONTEXT_BUNDLED_PREREG ) 350 { 351 aContext <<= OUSTR("bundled_prereg"); 352 } 353 354 else 355 { 356 OSL_ASSERT( 0 ); 357 // NOT supported at the momemtn // TODO 358 } 359 360 Reference< provider::XScriptProviderFactory > xFac( 361 that->getComponentContext()->getValueByName( 362 OUSTR( "/singletons/com.sun.star.script.provider.theMasterScriptProviderFactory") ), UNO_QUERY ); 363 364 if ( xFac.is() ) 365 { 366 Reference< container::XNameContainer > xName( xFac->createScriptProvider( aContext ), UNO_QUERY ); 367 if ( xName.is() ) 368 { 369 m_xNameCntrPkgHandler.set( xName ); 370 } 371 } 372 // TODO what happens if above fails?? 373 } 374 375 // Package 376 //______________________________________________________________________________ 377 beans::Optional< beans::Ambiguous<sal_Bool> > 378 BackendImpl::PackageImpl::isRegistered_( 379 ::osl::ResettableMutexGuard &, 380 ::rtl::Reference<AbortChannel> const &, 381 Reference<XCommandEnvironment> const & ) 382 { 383 return beans::Optional< beans::Ambiguous<sal_Bool> >( 384 true /* IsPresent */, 385 beans::Ambiguous<sal_Bool>( 386 m_xNameCntrPkgHandler.is() && m_xNameCntrPkgHandler->hasByName( 387 m_url ), 388 false /* IsAmbiguous */ ) ); 389 } 390 391 //______________________________________________________________________________ 392 void BackendImpl::PackageImpl::processPackage_( 393 ::osl::ResettableMutexGuard &, 394 bool doRegisterPackage, 395 bool /* startup */, 396 ::rtl::Reference<AbortChannel> const &, 397 Reference<XCommandEnvironment> const & ) 398 { 399 if ( !m_xNameCntrPkgHandler.is() ) 400 { 401 dp_misc::TRACE("no package handler!!!!\n"); 402 throw RuntimeException( OUSTR("No package Handler " ), 403 Reference< XInterface >() ); 404 } 405 406 if (doRegisterPackage) 407 { 408 // will throw if it fails 409 m_xNameCntrPkgHandler->insertByName( m_url, makeAny( Reference< XPackage >(this) ) ); 410 411 } 412 else // revokePackage() 413 { 414 m_xNameCntrPkgHandler->removeByName( m_url ); 415 } 416 } 417 418 namespace sdecl = comphelper::service_decl; 419 sdecl::class_<BackendImpl, sdecl::with_args<true> > serviceBI; 420 extern sdecl::ServiceDecl const serviceDecl( 421 serviceBI, 422 "com.sun.star.comp.deployment.sfwk.PackageRegistryBackend", 423 BACKEND_SERVICE_NAME ); 424 425 } // namespace sfwk 426 } // namespace backend 427 } // namespace dp_registry 428 429