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 package com.sun.star.script.framework.container; 24 25 import com.sun.star.script.framework.log.LogUtils; 26 import com.sun.star.script.framework.provider.PathUtils; 27 import com.sun.star.script.framework.io.XOutputStreamWrapper; 28 import com.sun.star.script.framework.io.XInputStreamWrapper; 29 30 import java.util.Map; 31 import java.util.HashMap; 32 import java.io.OutputStream; 33 import java.io.InputStream; 34 35 import com.sun.star.uno.XComponentContext; 36 37 import com.sun.star.uno.UnoRuntime; 38 39 import com.sun.star.io.XOutputStream; 40 import com.sun.star.io.XTruncate; 41 42 import com.sun.star.deployment.XPackage; 43 import com.sun.star.deployment.ExtensionRemovedException; 44 45 public class UnoPkgContainer extends ParcelContainer 46 { 47 48 private Map registeredPackages = new HashMap(); 49 protected String extensionDb; 50 protected String extensionRepository; 51 UnoPkgContainer( XComponentContext xCtx, String locationURL, String _extensionDb, String _extensionRepository, String language )52 public UnoPkgContainer( XComponentContext xCtx, String locationURL, 53 String _extensionDb, String _extensionRepository, String language ) throws com.sun.star.lang.IllegalArgumentException, com.sun.star.lang.WrappedTargetException 54 { 55 super( xCtx, locationURL, language, false ); 56 extensionDb = _extensionDb; 57 extensionRepository = _extensionRepository; 58 init(); 59 } 60 61 // gets the ParcelContainer for persisted uno packages getRegisteredUnoPkgContainer( String url )62 public ParcelContainer getRegisteredUnoPkgContainer( String url ) 63 { 64 if (!url.endsWith("/")) 65 { 66 url += "/"; 67 } 68 69 LogUtils.DEBUG("** getRegisterPackage ctx = " + containerUrl ); 70 LogUtils.DEBUG("** getRegisterPackage for uri " + url ); 71 LogUtils.DEBUG("** getRegisterPackage for langugage " + language ); 72 ParcelContainer result = (ParcelContainer)registeredPackages.get( url ); 73 LogUtils.DEBUG("getRegisterPackage result is " + result ); 74 return result; 75 } 76 hasRegisteredUnoPkgContainer( String url )77 public boolean hasRegisteredUnoPkgContainer( String url ) 78 { 79 boolean result = false; 80 if ( getRegisteredUnoPkgContainer( url ) != null ) 81 { 82 result = true; 83 } 84 return result; 85 } 86 registerPackageContainer( String url, ParcelContainer c )87 private void registerPackageContainer( String url, ParcelContainer c ) 88 { 89 if (!url.endsWith("/")) 90 { 91 url += "/"; 92 } 93 94 LogUtils.DEBUG("RegisterPackage ctx = " + containerUrl ); 95 LogUtils.DEBUG("RegisterPackage language = " + language ); 96 LogUtils.DEBUG("RegisterPackage " + c + " for url " + url ); 97 registeredPackages.put( url, c ); 98 } 99 deRegisterPackageContainer( String url )100 public void deRegisterPackageContainer( String url ) 101 { 102 if (!url.endsWith("/")) 103 { 104 url += "/"; 105 } 106 107 LogUtils.DEBUG("In deRegisterPackageContainer for " + url ); 108 if ( hasRegisteredUnoPkgContainer( url ) ) 109 { 110 try 111 { 112 DeployedUnoPackagesDB db = getUnoPackagesDB(); 113 if ( db != null ) 114 { 115 if ( db.removePackage( language, url ) ) 116 { 117 writeUnoPackageDB( db ); 118 ParcelContainer container = 119 ( ParcelContainer ) registeredPackages.get( url ); 120 if ( !container.hasElements() ) 121 { 122 // When all libraries within a package bundle 123 // ( for this language ) are removed also 124 // remove the container from its parent 125 // Otherwise, a container ( with no containees ) 126 // representing the uno package bundle will 127 // still exist and so will get displayed 128 if ( container.parent() != null ) 129 { 130 container.parent().removeChildContainer( container ); 131 } 132 } 133 registeredPackages.remove( url ); 134 } 135 } 136 } 137 catch (Exception e) 138 { 139 //TODO revisit exception handling and exception here 140 //means something very wrong 141 LogUtils.DEBUG("***** deRegisterPackageContainer() got exception " + e ); 142 } 143 } 144 LogUtils.DEBUG("Leaving deRegisterPackageContainer for " + url ); 145 } 146 init()147 private void init() throws com.sun.star.lang.IllegalArgumentException, com.sun.star.lang.WrappedTargetException 148 { 149 LogUtils.DEBUG("getting container for " + containerUrl ); 150 DeployedUnoPackagesDB db = null; 151 try 152 { 153 db = getUnoPackagesDB(); 154 if ( db != null ) 155 { 156 String[] packages = db.getDeployedPackages( language ); 157 158 for ( int i=0; i<packages.length;i++) 159 { 160 try 161 { 162 processUnoPackage( packages[i], language ); 163 } 164 catch ( com.sun.star.lang.IllegalArgumentException ila) 165 { 166 LogUtils.DEBUG("Failed to process " + packages[i] + " for " + language); 167 LogUtils.DEBUG(" Reason: " + ila ); 168 } 169 catch( Exception e ) 170 { 171 // TODO proper exception or do we wish 172 // to ignore errors here 173 LogUtils.DEBUG("Something very wrong!!!!!"); 174 LogUtils.DEBUG("Failed to process " + packages[i] + " for " + language); 175 LogUtils.DEBUG(" Reason: " + e ); 176 } 177 } 178 } 179 } 180 catch ( com.sun.star.lang.WrappedTargetException e ) 181 { 182 // no deployed packages 183 LogUtils.DEBUG("No deployed uno-packages for " + containerUrl ); 184 } 185 } 186 187 findScript( ParsedScriptUri psu )188 public ScriptMetaData findScript( ParsedScriptUri psu ) throws com.sun.star.container.NoSuchElementException, com.sun.star.lang.WrappedTargetException 189 190 { 191 ScriptMetaData scriptData = null; 192 193 String language = psu.language; 194 String functionName = psu.function; 195 String parcelName = psu.parcel; 196 String location = psu.location; 197 198 LogUtils.DEBUG("*** UnoPkgContainer.findScript() ***" + 199 "\ncontainerUrl = " + containerUrl + 200 "\nfunction = " + functionName + 201 "\nlocation = " + location + 202 "\nparcel = " + parcelName ); 203 204 ParcelContainer pc = getChildContainer( location ); 205 206 if ( pc == null ) 207 { 208 throw new com.sun.star.lang.WrappedTargetException( "Failed to resolve script " , null, new com.sun.star.lang.IllegalArgumentException( "Cannot resolve script location for script = " + functionName ) ); 209 } 210 211 scriptData = pc.findScript( psu ); 212 return scriptData; 213 214 } 215 getUnoPackagesDB()216 private DeployedUnoPackagesDB getUnoPackagesDB() throws com.sun.star.lang.WrappedTargetException 217 { 218 InputStream is = null; 219 DeployedUnoPackagesDB dp = null; 220 try 221 { 222 // String path = containerUrl.substring( 0, containerUrl.lastIndexOf("/") ); 223 String packagesUrl = PathUtils.make_url( extensionDb, "/Scripts/" + extensionRepository + "-extension-desc.xml" ); 224 LogUtils.DEBUG("getUnoPackagesDB() looking for existing db in " + packagesUrl ); 225 if ( m_xSFA.exists( packagesUrl ) ) 226 { 227 if ( packagesUrl.startsWith( "vnd.sun.star.tdoc" ) ) 228 { 229 // handles using XStorage directly 230 throw new com.sun.star.lang.WrappedTargetException("Can't handle documents yet"); 231 } 232 233 is = new XInputStreamWrapper( m_xSFA.openFileRead( packagesUrl ) ); 234 dp = new DeployedUnoPackagesDB( is ); 235 try 236 { 237 is.close(); 238 is = null; 239 } 240 catch ( Exception ignore ) 241 { 242 } 243 } 244 else 245 { 246 LogUtils.DEBUG("getUnoPackagesDB() " + packagesUrl + " does not exist"); 247 } 248 } 249 catch( Exception e ) 250 { 251 LogUtils.DEBUG("getUnoPackagesDB() caught Exception: " + e ); 252 LogUtils.DEBUG( LogUtils.getTrace( e ) ); 253 throw new com.sun.star.lang.WrappedTargetException( e.toString()); 254 } 255 finally 256 { 257 if ( is != null ) 258 { 259 try 260 { 261 is.close(); 262 is = null; 263 } 264 catch ( Exception ignore ) 265 { 266 } 267 } 268 } 269 270 return dp; 271 } 272 writeUnoPackageDB( DeployedUnoPackagesDB dp )273 private void writeUnoPackageDB( DeployedUnoPackagesDB dp ) throws com.sun.star.lang.IllegalArgumentException, com.sun.star.lang.WrappedTargetException 274 { 275 LogUtils.DEBUG("In writeUnoPackageDB() "); 276 277 XOutputStream xos = null; 278 OutputStream os = null; 279 try 280 { 281 // String path = containerUrl.substring( 0, containerUrl.lastIndexOf("/") ); 282 String packagesUrl = PathUtils.make_url( extensionDb, "/Scripts/" + extensionRepository + "-extension-desc.xml" ); 283 xos = m_xSFA.openFileWrite( packagesUrl ); 284 XTruncate xTrc = (XTruncate) UnoRuntime.queryInterface( XTruncate.class, xos ); 285 if ( xTrc != null ) 286 { 287 LogUtils.DEBUG("In writeUnoPackageDB() Truncating...." ); 288 xTrc.truncate(); 289 } 290 else 291 { 292 LogUtils.DEBUG("In writeUnoPackageDB() CAN'T Truncate...." ); 293 } 294 os = new XOutputStreamWrapper( xos ); 295 dp.write( os ); 296 try 297 { 298 os.close(); // will close xos 299 os = null; 300 } 301 catch( Exception ignore ) 302 { 303 } 304 } 305 catch( Exception e ) 306 { 307 LogUtils.DEBUG("In writeUnoPackageDB() Exception: " + e ); 308 throw new com.sun.star.lang.WrappedTargetException( e.toString()); 309 } 310 finally 311 { 312 if ( os != null ) 313 { 314 try 315 { 316 os.close(); // will close xos 317 os = null; 318 } 319 catch ( Exception ignore ) 320 { 321 } 322 } 323 } 324 } 325 processUnoPackage( XPackage dPackage, String language )326 public void processUnoPackage( XPackage dPackage, String language ) throws com.sun.star.lang.IllegalArgumentException, com.sun.star.lang.WrappedTargetException, com.sun.star.container.ElementExistException 327 { 328 LogUtils.DEBUG("** in processUnoPackage " ); 329 String uri = null; 330 DeployedUnoPackagesDB db = null; 331 uri = dPackage.getURL(); 332 333 if ( !uri.endsWith( "/" ) ) 334 { 335 uri += "/"; 336 } 337 338 LogUtils.DEBUG("** processUnoPackage getURL() -> " + uri ); 339 LogUtils.DEBUG("** processUnoPackage getName() -> " + dPackage.getName() ); 340 LogUtils.DEBUG("** processUnoPackage getMediaType() -> " + dPackage.getPackageType().getMediaType() ); 341 try 342 { 343 LogUtils.DEBUG("** processUnoPackage getDisplayName() -> " + dPackage.getDisplayName() ); 344 } 345 catch (com.sun.star.deployment.ExtensionRemovedException e) 346 { 347 throw new com.sun.star.lang.WrappedTargetException(e.toString(), this, e); 348 } 349 350 processUnoPackage( uri, language ); 351 352 db = getUnoPackagesDB(); 353 if ( db == null ) 354 { 355 try 356 { 357 db = new DeployedUnoPackagesDB(); 358 } 359 catch ( java.io.IOException ioe ) 360 { 361 throw new com.sun.star.lang.WrappedTargetException( ioe.toString()); 362 } 363 } 364 db.addPackage( language, uri ); 365 writeUnoPackageDB( db ); 366 } 367 processUnoPackage( String uri, String language )368 private void processUnoPackage( String uri, String language ) throws com.sun.star.lang.IllegalArgumentException, com.sun.star.lang.WrappedTargetException, com.sun.star.container.ElementExistException 369 { 370 if ( hasRegisteredUnoPkgContainer( uri ) ) 371 { 372 throw new com.sun.star.container.ElementExistException( "Already a registered uno package " + uri + " for language " + language ); 373 } 374 LogUtils.DEBUG("processUnoPackage - URL = " + uri ); 375 LogUtils.DEBUG("processUnoPackage - script library package"); 376 String parentUrl = uri; 377 378 if ( uri.indexOf( "%2Funo_packages%2F" ) > -1 || 379 uri.indexOf( "/uno_packages/" ) > -1 || 380 uri.indexOf("$UNO_USER_PACKAGES_CACHE/") > -1 || 381 uri.indexOf("$UNO_SHARED_PACKAGES_CACHE/") > -1 || 382 uri.indexOf("$BUNDLED_EXTENSIONS/") > -1 ) 383 { 384 //its in a bundle need to determine the uno-package file its in 385 LogUtils.DEBUG("processUnoPackage - is part of a uno bundle"); 386 387 int index = uri.lastIndexOf("/"); 388 if ( uri.endsWith("/") ) 389 { 390 uri = uri.substring( 0, index ); 391 index = uri.lastIndexOf("/"); 392 } 393 394 if ( index > -1 ) 395 { 396 parentUrl = uri.substring( 0, index ); 397 LogUtils.DEBUG("processUnoPackage - composition is contained in " + parentUrl); 398 } 399 400 ParcelContainer pkgContainer = getChildContainerForURL( parentUrl ); 401 if ( pkgContainer == null ) 402 { 403 pkgContainer = new ParcelContainer( this, m_xCtx, parentUrl, language, false ); 404 if ( pkgContainer.loadParcel( uri ) == null ) 405 { 406 throw new com.sun.star.lang.IllegalArgumentException( "Couldn't load script library from composition package " + uri + " for language " + language ); 407 408 } 409 addChildContainer( pkgContainer ); 410 } 411 else 412 { 413 if ( pkgContainer.loadParcel( uri ) == null ) 414 { 415 throw new com.sun.star.lang.IllegalArgumentException( "Couldn't load script library from composition package " + uri + " for language " + language ); 416 } 417 418 } 419 registerPackageContainer( uri, pkgContainer ); 420 } 421 else 422 { 423 // stand-alone library package, e.g. not contained in 424 // an uno package 425 if ( loadParcel( uri ) == null ) 426 { 427 throw new com.sun.star.lang.IllegalArgumentException( "Couldn't load script library package " + uri + " for language " + language ); 428 } 429 registerPackageContainer( uri, this ); 430 } 431 432 } 433 434 } 435