diff options
Diffstat (limited to '')
-rw-r--r-- | scripting/java/com/sun/star/script/framework/container/UnoPkgContainer.java | 401 |
1 files changed, 401 insertions, 0 deletions
diff --git a/scripting/java/com/sun/star/script/framework/container/UnoPkgContainer.java b/scripting/java/com/sun/star/script/framework/container/UnoPkgContainer.java new file mode 100644 index 000000000..4b6a75520 --- /dev/null +++ b/scripting/java/com/sun/star/script/framework/container/UnoPkgContainer.java @@ -0,0 +1,401 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +package com.sun.star.script.framework.container; + +import com.sun.star.deployment.XPackage; + +import com.sun.star.io.XOutputStream; +import com.sun.star.io.XTruncate; + +import com.sun.star.script.framework.io.XInputStreamWrapper; +import com.sun.star.script.framework.io.XOutputStreamWrapper; +import com.sun.star.script.framework.log.LogUtils; +import com.sun.star.script.framework.provider.PathUtils; + +import com.sun.star.uno.UnoRuntime; +import com.sun.star.uno.XComponentContext; + +import java.io.InputStream; +import java.io.OutputStream; + +import java.util.HashMap; +import java.util.Map; + +public class UnoPkgContainer extends ParcelContainer { + + private final Map<String, ParcelContainer> registeredPackages = new HashMap<String, ParcelContainer>(); + private final String extensionDb; + private final String extensionRepository; + + public UnoPkgContainer(XComponentContext xCtx, String locationURL, + String _extensionDb, String _extensionRepository, + String language) throws + com.sun.star.lang.IllegalArgumentException, + com.sun.star.lang.WrappedTargetException { + + super(xCtx, locationURL, language, false); + extensionDb = _extensionDb; + extensionRepository = _extensionRepository; + init(); + } + + // gets the ParcelContainer for persisted uno packages + public ParcelContainer getRegisteredUnoPkgContainer(String url) { + + if (!url.endsWith("/")) { + url += "/"; + } + + LogUtils.DEBUG("** getRegisterPackage ctx = " + containerUrl); + LogUtils.DEBUG("** getRegisterPackage for uri " + url); + LogUtils.DEBUG("** getRegisterPackage for language " + language); + + ParcelContainer result = registeredPackages.get(url); + LogUtils.DEBUG("getRegisterPackage result is " + result); + return result; + } + + public boolean hasRegisteredUnoPkgContainer(String url) { + return getRegisteredUnoPkgContainer(url) != null; + } + + private void registerPackageContainer(String url, ParcelContainer c) { + + if (!url.endsWith("/")) { + url += "/"; + } + + LogUtils.DEBUG("RegisterPackage ctx = " + containerUrl); + LogUtils.DEBUG("RegisterPackage language = " + language); + LogUtils.DEBUG("RegisterPackage " + c + " for url " + url); + registeredPackages.put(url, c); + } + + public void deRegisterPackageContainer(String url) { + + if (!url.endsWith("/")) { + url += "/"; + } + + LogUtils.DEBUG("In deRegisterPackageContainer for " + url); + + if (hasRegisteredUnoPkgContainer(url)) { + try { + DeployedUnoPackagesDB db = getUnoPackagesDB(); + + if (db != null && db.removePackage(language, url)) { + writeUnoPackageDB(db); + ParcelContainer container = registeredPackages.get(url); + + if (!container.hasElements()) { + // When all libraries within a package bundle + // ( for this language ) are removed also + // remove the container from its parent + // Otherwise, a container ( with no containers ) + // representing the uno package bundle will + // still exist and so will get displayed + if (container.parent() != null) { + container.parent().removeChildContainer(container); + } + } + + registeredPackages.remove(url); + } + } catch (Exception e) { + //TODO revisit exception handling and exception here + //means something very wrong + LogUtils.DEBUG("***** deRegisterPackageContainer() got exception " + e); + } + } + + LogUtils.DEBUG("Leaving deRegisterPackageContainer for " + url); + } + + private void init() throws com.sun.star.lang.IllegalArgumentException { + LogUtils.DEBUG("getting container for " + containerUrl); + + try { + DeployedUnoPackagesDB db = getUnoPackagesDB(); + + if (db != null) { + String[] packages = db.getDeployedPackages(language); + + for (String thepackage : packages) { + try { + processUnoPackage(thepackage, language); + } catch (com.sun.star.lang.IllegalArgumentException ila) { + LogUtils.DEBUG("Failed to process " + thepackage + + " for " + language); + LogUtils.DEBUG(" Reason: " + ila); + } catch (Exception e) { + // TODO proper exception or do we wish + // to ignore errors here + LogUtils.DEBUG("Something very wrong!!!!!"); + LogUtils.DEBUG("Failed to process " + thepackage + + " for " + language); + LogUtils.DEBUG(" Reason: " + e); + } + } + } + } catch (com.sun.star.lang.WrappedTargetException e) { + // no deployed packages + LogUtils.DEBUG("No deployed uno-packages for " + containerUrl); + } + } + + @Override + public ScriptMetaData findScript(ParsedScriptUri psu) throws + com.sun.star.container.NoSuchElementException, + com.sun.star.lang.WrappedTargetException { + + String functionName = psu.function; + String parcelName = psu.parcel; + String location = psu.location; + + LogUtils.DEBUG("*** UnoPkgContainer.findScript() ***" + + "\ncontainerUrl = " + containerUrl + + "\nfunction = " + functionName + + "\nlocation = " + location + + "\nparcel = " + parcelName); + + ParcelContainer pc = getChildContainer(location); + + if (pc == null) { + 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)); + } + + return pc.findScript(psu); + } + + private DeployedUnoPackagesDB getUnoPackagesDB() throws + com.sun.star.lang.WrappedTargetException { + + InputStream is = null; + DeployedUnoPackagesDB dp = null; + + try { + + String packagesUrl = + PathUtils.make_url(extensionDb, + "/Scripts/" + extensionRepository + "-extension-desc.xml"); + + LogUtils.DEBUG("getUnoPackagesDB() looking for existing db in " + + packagesUrl); + + if (m_xSFA.exists(packagesUrl)) { + if (packagesUrl.startsWith("vnd.sun.star.tdoc")) { + // handles using XStorage directly + throw new com.sun.star.lang.WrappedTargetException( + "Can't handle documents yet"); + } + + is = new XInputStreamWrapper(m_xSFA.openFileRead(packagesUrl)); + dp = new DeployedUnoPackagesDB(is); + + try { + is.close(); + is = null; + } catch (Exception ignore) { + } + } else { + LogUtils.DEBUG("getUnoPackagesDB() " + packagesUrl + + " does not exist"); + } + } catch (Exception e) { + LogUtils.DEBUG("getUnoPackagesDB() caught Exception: " + e); + LogUtils.DEBUG(LogUtils.getTrace(e)); + throw new com.sun.star.lang.WrappedTargetException(e); + } finally { + if (is != null) { + try { + is.close(); + is = null; + } catch (Exception ignore) { + } + } + } + + return dp; + } + + private void writeUnoPackageDB(DeployedUnoPackagesDB dp) throws + com.sun.star.lang.IllegalArgumentException, + com.sun.star.lang.WrappedTargetException { + + LogUtils.DEBUG("In writeUnoPackageDB() "); + + XOutputStream xos = null; + OutputStream os = null; + + try { + + String packagesUrl = + PathUtils.make_url(extensionDb, "/Scripts/" + extensionRepository + + "-extension-desc.xml"); + + xos = m_xSFA.openFileWrite(packagesUrl); + XTruncate xTrc = UnoRuntime.queryInterface(XTruncate.class, xos); + + if (xTrc != null) { + LogUtils.DEBUG("In writeUnoPackageDB() Truncating..."); + xTrc.truncate(); + } else { + LogUtils.DEBUG("In writeUnoPackageDB() CAN'T Truncate..."); + } + + os = new XOutputStreamWrapper(xos); + dp.write(os); + + try { + os.close(); // will close xos + os = null; + } catch (Exception ignore) { + } + } catch (Exception e) { + LogUtils.DEBUG("In writeUnoPackageDB() Exception: " + e); + throw new com.sun.star.lang.WrappedTargetException(e); + } finally { + if (os != null) { + try { + os.close(); // will close xos + os = null; + } catch (Exception ignore) { + } + } + } + } + + public void processUnoPackage(XPackage dPackage, + String language) throws + com.sun.star.lang.IllegalArgumentException, + com.sun.star.lang.WrappedTargetException, + com.sun.star.container.ElementExistException { + + LogUtils.DEBUG("** in processUnoPackage "); + + String uri = dPackage.getURL(); + + if (!uri.endsWith("/")) { + uri += "/"; + } + + LogUtils.DEBUG("** processUnoPackage getURL() -> " + uri); + LogUtils.DEBUG("** processUnoPackage getName() -> " + dPackage.getName()); + LogUtils.DEBUG("** processUnoPackage getMediaType() -> " + + dPackage.getPackageType().getMediaType()); + + try { + LogUtils.DEBUG("** processUnoPackage getDisplayName() -> " + + dPackage.getDisplayName()); + } catch (com.sun.star.deployment.ExtensionRemovedException e) { + throw new com.sun.star.lang.WrappedTargetException(e.getMessage(), this, e); + } + + processUnoPackage(uri, language); + + DeployedUnoPackagesDB db = getUnoPackagesDB(); + + if (db == null) { + try { + db = new DeployedUnoPackagesDB(); + } catch (java.io.IOException ioe) { + throw new com.sun.star.lang.WrappedTargetException(ioe); + } + } + + db.addPackage(language, uri); + writeUnoPackageDB(db); + } + + private void processUnoPackage(String uri, + String language) throws + com.sun.star.lang.IllegalArgumentException, + com.sun.star.lang.WrappedTargetException, + com.sun.star.container.ElementExistException { + + if (hasRegisteredUnoPkgContainer(uri)) { + throw new com.sun.star.container.ElementExistException( + "Already a registered uno package " + uri + " for language " + + language); + } + + LogUtils.DEBUG("processUnoPackage - URL = " + uri); + LogUtils.DEBUG("processUnoPackage - script library package"); + String parentUrl = uri; + + if (uri.contains("%2Funo_packages%2F") || + uri.contains("/uno_packages/") || + uri.contains("$UNO_USER_PACKAGES_CACHE/") || + uri.contains("$UNO_SHARED_PACKAGES_CACHE/") || + uri.contains("$BUNDLED_EXTENSIONS/")) { + + //its in a bundle need to determine the uno-package file its in + LogUtils.DEBUG("processUnoPackage - is part of a UNO bundle"); + + int index = uri.lastIndexOf('/'); + + if (uri.endsWith("/")) { + uri = uri.substring(0, index); + index = uri.lastIndexOf('/'); + } + + if (index > -1) { + parentUrl = uri.substring(0, index); + LogUtils.DEBUG("processUnoPackage - composition is contained in " + + parentUrl); + } + + ParcelContainer pkgContainer = getChildContainerForURL(parentUrl); + + if (pkgContainer == null) { + pkgContainer = + new ParcelContainer(this, m_xCtx, parentUrl, language, false); + + if (pkgContainer.loadParcel(uri) == null) { + throw new com.sun.star.lang.IllegalArgumentException( + "Couldn't load script library from composition package " + + uri + " for language " + language); + } + + addChildContainer(pkgContainer); + } else { + if (pkgContainer.loadParcel(uri) == null) { + throw new com.sun.star.lang.IllegalArgumentException( + "Couldn't load script library from composition package " + + uri + " for language " + language); + } + + } + + registerPackageContainer(uri, pkgContainer); + } else { + // stand-alone library package, e.g. not contained in + // a uno package + if (loadParcel(uri) == null) { + throw new com.sun.star.lang.IllegalArgumentException( + "Couldn't load script library package " + uri + + " for language " + language); + } + + registerPackageContainer(uri, this); + } + } +} |