summaryrefslogtreecommitdiffstats
path: root/scripting/java/com/sun/star/script/framework/container
diff options
context:
space:
mode:
Diffstat (limited to 'scripting/java/com/sun/star/script/framework/container')
-rw-r--r--scripting/java/com/sun/star/script/framework/container/DeployedUnoPackagesDB.java192
-rw-r--r--scripting/java/com/sun/star/script/framework/container/Parcel.java302
-rw-r--r--scripting/java/com/sun/star/script/framework/container/ParcelContainer.java725
-rw-r--r--scripting/java/com/sun/star/script/framework/container/ParcelDescriptor.java354
-rw-r--r--scripting/java/com/sun/star/script/framework/container/ParsedScriptUri.java25
-rw-r--r--scripting/java/com/sun/star/script/framework/container/ScriptEntry.java85
-rw-r--r--scripting/java/com/sun/star/script/framework/container/ScriptMetaData.java328
-rw-r--r--scripting/java/com/sun/star/script/framework/container/UnoPkgContainer.java401
-rw-r--r--scripting/java/com/sun/star/script/framework/container/XMLParser.java30
-rw-r--r--scripting/java/com/sun/star/script/framework/container/XMLParserFactory.java106
10 files changed, 2548 insertions, 0 deletions
diff --git a/scripting/java/com/sun/star/script/framework/container/DeployedUnoPackagesDB.java b/scripting/java/com/sun/star/script/framework/container/DeployedUnoPackagesDB.java
new file mode 100644
index 000000000..c187fb0e1
--- /dev/null
+++ b/scripting/java/com/sun/star/script/framework/container/DeployedUnoPackagesDB.java
@@ -0,0 +1,192 @@
+/*
+ * 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 java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import java.util.ArrayList;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+public class DeployedUnoPackagesDB {
+
+ // This is the default contents of a parcel descriptor to be used when
+ // creating empty descriptors
+ private static final byte[] EMPTY_DOCUMENT =
+ ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
+ "<unopackages xmlns:unopackages=\"unopackages.dtd\">\n" +
+ "</unopackages>").getBytes();
+
+ private Document document = null;
+
+ public DeployedUnoPackagesDB() throws IOException {
+
+ ByteArrayInputStream bis = null;
+
+ try {
+ bis = new ByteArrayInputStream(EMPTY_DOCUMENT);
+ this.document = XMLParserFactory.getParser().parse(bis);
+ } finally {
+ if (bis != null)
+ bis.close();
+ }
+ }
+
+ private DeployedUnoPackagesDB(Document document) {
+ this.document = document;
+ }
+
+ public DeployedUnoPackagesDB(InputStream is) throws IOException {
+ this(XMLParserFactory.getParser().parse(is));
+ }
+
+ public String[] getDeployedPackages(String language) {
+
+ ArrayList<String> packageUrls = new ArrayList<String>(4);
+ Element main = document.getDocumentElement();
+ Element root = null;
+ int len = 0;
+ NodeList langNodes = null;
+
+ if ((langNodes = main.getElementsByTagName("language")) != null &&
+ (len = langNodes.getLength()) != 0) {
+ for (int i = 0; i < len; i++) {
+ Element e = (Element)langNodes.item(i);
+
+ if (e.getAttribute("value").equals(language)) {
+ root = e;
+ break;
+ }
+ }
+ }
+
+ if (root != null) {
+ len = 0;
+ NodeList packages = null;
+
+ if ((packages = root.getElementsByTagName("package")) != null &&
+ (len = packages.getLength()) != 0) {
+
+ for (int i = 0; i < len; i++) {
+ Element e = (Element)packages.item(i);
+ packageUrls.add(e.getAttribute("value"));
+ }
+
+ }
+ }
+
+ if (!packageUrls.isEmpty()) {
+ return packageUrls.toArray(new String[packageUrls.size()]);
+ }
+
+ return new String[0];
+ }
+
+ public void write(OutputStream out) throws IOException {
+ XMLParserFactory.getParser().write(document, out);
+ }
+
+ public Document getDocument() {
+ return document;
+ }
+
+
+ public boolean removePackage(String language, String url) {
+
+ Element main = document.getDocumentElement();
+ Element langNode = null;
+ int len = 0;
+ NodeList langNodes = null;
+
+ if ((langNodes = main.getElementsByTagName("language")) != null &&
+ (len = langNodes.getLength()) != 0) {
+ for (int i = 0; i < len; i++) {
+ Element e = (Element)langNodes.item(i);
+
+ if (e.getAttribute("value").equals(language)) {
+ langNode = e;
+ break;
+ }
+ }
+ }
+
+ if (langNode == null) {
+ return false;
+ }
+ len = 0;
+ NodeList packages = null;
+ boolean result = false;
+
+ if ((packages = langNode.getElementsByTagName("package")) != null &&
+ (len = packages.getLength()) != 0) {
+ for (int i = 0; i < len; i++) {
+
+ Element e = (Element)packages.item(i);
+ String value = e.getAttribute("value");
+
+ if (value.equals(url)) {
+ langNode.removeChild(e);
+ result = true;
+ break;
+ }
+ }
+ }
+
+ return result;
+ }
+
+ public void addPackage(String language, String url) {
+
+ Element main = document.getDocumentElement();
+ Element langNode = null;
+ Element pkgNode = null;
+
+ int len = 0;
+ NodeList langNodes = null;
+
+ if ((langNodes = document.getElementsByTagName("language")) != null &&
+ (len = langNodes.getLength()) != 0) {
+ for (int i = 0; i < len; i++) {
+ Element e = (Element)langNodes.item(i);
+
+ if (e.getAttribute("value").equals(language)) {
+ langNode = e;
+ break;
+ }
+ }
+ }
+
+ if (langNode == null) {
+ langNode = document.createElement("language");
+ langNode.setAttribute("value", language);
+ }
+
+ pkgNode = document.createElement("package");
+ pkgNode.setAttribute("value", url);
+
+ langNode.appendChild(pkgNode);
+ //add to the Top Element
+ main.appendChild(langNode);
+ }
+} \ No newline at end of file
diff --git a/scripting/java/com/sun/star/script/framework/container/Parcel.java b/scripting/java/com/sun/star/script/framework/container/Parcel.java
new file mode 100644
index 000000000..6be4cad99
--- /dev/null
+++ b/scripting/java/com/sun/star/script/framework/container/Parcel.java
@@ -0,0 +1,302 @@
+/*
+ * 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.container.ElementExistException;
+import com.sun.star.container.XNameContainer;
+
+import com.sun.star.script.framework.io.XInputStreamImpl;
+import com.sun.star.script.framework.log.LogUtils;
+import com.sun.star.script.framework.provider.PathUtils;
+
+import com.sun.star.ucb.XSimpleFileAccess;
+import com.sun.star.ucb.XSimpleFileAccess2;
+
+import com.sun.star.uno.Type;
+import com.sun.star.uno.UnoRuntime;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+
+public class Parcel implements XNameContainer {
+
+ private ParcelDescriptor m_descriptor;
+ private String name;
+ protected ParcelContainer parent;
+ protected XSimpleFileAccess m_xSFA;
+
+ public Parcel(XSimpleFileAccess xSFA, ParcelContainer parent,
+ ParcelDescriptor desc, String parcelName) {
+
+ this(parent, desc, parcelName);
+ this.m_xSFA = xSFA;
+ }
+
+ private Parcel(ParcelContainer parent, ParcelDescriptor desc,
+ String parcelName) {
+
+ this.parent = parent;
+ this.m_descriptor = desc;
+ this.name = parcelName;
+ }
+
+ /**
+ * Tests if this <tt>Parcel</tt> is in a UNO package
+ * or within a sub package within a UNO package
+ *
+ * @return <tt>true</tt> if has parent <tt>false</tt> otherwise
+ */
+ public boolean isUnoPkg() {
+ return parent.isUnoPkg();
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public ScriptMetaData getByName(String aName) throws
+ com.sun.star.container.NoSuchElementException,
+ com.sun.star.lang.WrappedTargetException {
+
+ LogUtils.DEBUG("** Parcel.getByName for " + aName);
+ ScriptEntry thescript = null;
+
+ try {
+ if (m_descriptor != null && hasElements()) {
+ ScriptEntry[] scripts = m_descriptor.getScriptEntries();
+
+ if (scripts.length != 0) {
+ for (ScriptEntry script : scripts) {
+ if (script.getLanguageName().equals(aName)) {
+ thescript = script;
+ break;
+ }
+ }
+ }
+ }
+ }
+ // catch unknown or un-checked exceptions
+ catch (Exception e) {
+ throw new com.sun.star.lang.WrappedTargetException(e);
+ }
+
+ if (thescript == null) {
+ LogUtils.DEBUG("No script for " + aName);
+ throw new com.sun.star.container.NoSuchElementException("No script named " +
+ aName);
+ }
+
+ ScriptMetaData data = new ScriptMetaData(this, thescript, null);
+
+ LogUtils.DEBUG("returning date for " + aName);
+ return data;
+ }
+
+ public String[] getElementNames() {
+
+ String[] results = new String[0];
+
+ if (m_descriptor != null) {
+ ScriptEntry[] scripts = m_descriptor.getScriptEntries();
+ results = new String[ scripts.length ];
+
+ for (int index = 0; index < scripts.length; index++) {
+ results[ index ] = scripts[ index ].getLanguageName();
+ }
+ }
+
+ return results;
+ }
+
+ public boolean hasByName(String aName) {
+
+ boolean result = true;
+ ScriptMetaData containee = null;
+
+ try {
+ containee = getByName(aName);
+
+ if (containee != null) {
+ result = true;
+ }
+ } catch (Exception e) {
+ result = false;
+ }
+
+ return result;
+ }
+
+ public com.sun.star.uno.Type getElementType() {
+ // TODO at the moment this returns void indicating
+ // type is unknown ( from UNO point of view this is correct )
+ // but, maybe we want to have a private UNO interface
+
+ return new Type();
+ }
+
+ public boolean hasElements() {
+ return m_descriptor != null && m_descriptor.getScriptEntries().length > 0;
+ }
+
+ public void replaceByName(String aName, java.lang.Object aElement) throws
+ com.sun.star.lang.IllegalArgumentException,
+ com.sun.star.container.NoSuchElementException,
+ com.sun.star.lang.WrappedTargetException {
+
+ // TODO check type of aElement
+ // if not ok, throw IllegalArgument
+ if (m_descriptor != null) {
+ try {
+ ScriptMetaData script = getByName(aName);
+
+ if (script != null) {
+ //m_descriptor.removeScriptEntry( script );
+ // TODO needs to create source file ( if there is one )
+ //m_descriptor.write();
+ } else {
+ throw new com.sun.star.container.NoSuchElementException(
+ "No script named " + aName);
+ }
+
+ }
+ // TO DO should catch specified exceptions
+ catch (Exception ex) {
+ throw new com.sun.star.lang.WrappedTargetException(ex);
+ }
+
+ }
+ }
+
+ // create
+ public void insertByName(String aName, java.lang.Object aElement) throws
+ com.sun.star.lang.IllegalArgumentException, ElementExistException,
+ com.sun.star.lang.WrappedTargetException {
+
+ // TODO check the type of aElement and throw#
+ // if not appropriate
+ try {
+ if (hasByName(aName)) {
+ throw new ElementExistException(aName);
+ }
+
+ ScriptMetaData script = (ScriptMetaData)aElement;
+
+ if (script.hasSource()) {
+ LogUtils.DEBUG("Inserting source: " + script.getSource());
+
+ if (!script.writeSourceFile()) {
+ throw new com.sun.star.lang.WrappedTargetException(
+ "Failed to create source file " + script.getLanguageName());
+ }
+ }
+
+ m_descriptor.addScriptEntry(script);
+ writeParcelDescriptor();
+ } catch (Exception e) {
+ LogUtils.DEBUG("Failed to insert entry " + aName + ": " + e.getMessage());
+ throw new com.sun.star.lang.WrappedTargetException(e);
+ }
+ }
+
+ private void writeParcelDescriptor()
+ throws com.sun.star.ucb.CommandAbortedException,
+ com.sun.star.io.IOException,
+ com.sun.star.uno.Exception, java.io.IOException {
+
+ String pathToDescriptor =
+ PathUtils.make_url(getPathToParcel(), ParcelDescriptor.PARCEL_DESCRIPTOR_NAME);
+
+ XSimpleFileAccess2 xSFA2 =
+ UnoRuntime.queryInterface(XSimpleFileAccess2.class, m_xSFA);
+
+ if (xSFA2 != null) {
+
+ ByteArrayOutputStream bos = null;
+ ByteArrayInputStream bis = null;
+ XInputStreamImpl xis = null;
+
+ try {
+ bos = new ByteArrayOutputStream(1024);
+ m_descriptor.write(bos);
+ bis = new ByteArrayInputStream(bos.toByteArray());
+
+ xis = new XInputStreamImpl(bis);
+ xSFA2.writeFile(pathToDescriptor, xis);
+ } finally {
+ if (bos != null) bos.close();
+
+ if (bis != null) bis.close();
+
+ if (xis != null) xis.closeInput();
+ }
+ }
+ }
+
+ // delete
+ public void removeByName(String Name) throws
+ com.sun.star.container.NoSuchElementException,
+ com.sun.star.lang.WrappedTargetException {
+
+ try {
+ ScriptMetaData script = getByName(Name);
+
+ if (script != null) {
+ if (!script.removeSourceFile()) {
+ LogUtils.DEBUG("** Parcel.removeByName Failed to remove script "
+ + Name);
+ throw new com.sun.star.lang.WrappedTargetException(
+ "Failed to remove script " + Name);
+ }
+
+ LogUtils.DEBUG("** Parcel.removeByName have removed script source file "
+ + Name);
+
+ m_descriptor.removeScriptEntry(script);
+ writeParcelDescriptor();
+ } else {
+ throw new com.sun.star.container.NoSuchElementException(
+ "No script named " + Name);
+ }
+
+ } catch (Exception e) {
+ LogUtils.DEBUG("** Parcel.removeByName Exception: " + e);
+ throw new com.sun.star.lang.WrappedTargetException(e);
+ }
+
+ }
+
+ // rename parcel
+ public void rename(String name) {
+ this.name = name;
+ }
+
+ public ParcelContainer getParent() {
+ return parent;
+ }
+
+ /**
+ * Returns the path of this <tt>Parcel</tt>
+ *
+ * @return <tt>String</tt> path to parcel
+ */
+ public String getPathToParcel() {
+ String path = parent.getParcelContainerDir() + "/" + name;
+ return path;
+ }
+
+}
diff --git a/scripting/java/com/sun/star/script/framework/container/ParcelContainer.java b/scripting/java/com/sun/star/script/framework/container/ParcelContainer.java
new file mode 100644
index 000000000..4a2bece39
--- /dev/null
+++ b/scripting/java/com/sun/star/script/framework/container/ParcelContainer.java
@@ -0,0 +1,725 @@
+/*
+ * 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.container.ElementExistException;
+import com.sun.star.container.XNameAccess;
+import com.sun.star.container.XNameContainer;
+
+import com.sun.star.io.XInputStream;
+
+import com.sun.star.lang.WrappedTargetException;
+import com.sun.star.lang.XMultiComponentFactory;
+
+import com.sun.star.script.framework.io.XInputStreamImpl;
+import com.sun.star.script.framework.io.XInputStreamWrapper;
+import com.sun.star.script.framework.log.LogUtils;
+import com.sun.star.script.framework.provider.PathUtils;
+
+import com.sun.star.ucb.XSimpleFileAccess;
+import com.sun.star.ucb.XSimpleFileAccess2;
+
+import com.sun.star.uno.Type;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XComponentContext;
+
+import com.sun.star.uri.XUriReference;
+import com.sun.star.uri.XUriReferenceFactory;
+import com.sun.star.uri.XVndSunStarScriptUrl;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.StringTokenizer;
+
+/**
+ * The <code>ParcelContainer</code> object is used to store the
+ * ScriptingFramework specific Libraries.
+ */
+public class ParcelContainer implements XNameAccess {
+
+ protected static XSimpleFileAccess m_xSFA;
+
+ protected String language;
+ protected String containerUrl;
+ private Collection<Parcel> parcels = new ArrayList<Parcel>(10);
+ protected XComponentContext m_xCtx;
+ private ParcelContainer parent = null;
+ private final Collection<ParcelContainer> childContainers = new ArrayList<ParcelContainer>(10);
+ private boolean isPkgContainer = false;
+
+ /**
+ * Tests if this <tt>ParcelContainer</tt> represents a UNO package
+ * or sub package within a UNO package
+ *
+ * @return <tt>true</tt> if has parent <tt>false</tt> otherwise
+ */
+ public boolean isUnoPkg() {
+ return isPkgContainer;
+ }
+
+ /**
+ * Returns this <tt>ParcelContainer</tt>'s parent
+ *
+ * @return <tt>ParcelContainer</tt> if has parent null otherwise
+ */
+ public ParcelContainer parent() {
+ return parent;
+ }
+
+ /**
+ * Returns all child <tt>ParcelContainer</tt>
+ * this instance of <tt>ParcelContainer</tt>
+ *
+ * @return a new array of ParcelContainers. A zero
+ * length array is returned if no child ParcelContainers.
+ */
+ public ParcelContainer[] getChildContainers() {
+ if (childContainers.isEmpty()) {
+ return new ParcelContainer[0];
+ }
+
+ return childContainers.toArray(new ParcelContainer[childContainers.size()]);
+ }
+
+ /**
+ * Removes a child <tt>ParcelContainer</tt>
+ * from this instance.
+ * @param child <tt>ParcelContainer</tt> to be added.
+ *
+ * @return <tt>true</tt> if child successfully removed
+ */
+ public boolean removeChildContainer(ParcelContainer child) {
+ return childContainers.remove(child);
+ }
+
+ /**
+ * Adds a new child <tt>ParcelContainer</tt>
+ * to this instance.
+ * @param child <tt>ParcelContainer</tt> to be added.
+ *
+ */
+ public void addChildContainer(ParcelContainer child) {
+ childContainers.add(child);
+ }
+
+ /**
+ * Returns a child <tt>ParcelContainer</tt> whose location
+ * matches the <tt>location</tt> argument passed to this method.
+ * @param key the <tt>location</tt> which is to
+ * be matched.
+ *
+ * @return child <tt>ParcelContainer</tt> or {@code null} if none
+ * found.
+ */
+ public ParcelContainer getChildContainer(String key) {
+ ParcelContainer result = null;
+
+ for (ParcelContainer c : childContainers) {
+
+ String name = c.getName();
+ if (name == null)
+ {
+ continue;
+ }
+
+ String location =
+ ScriptMetaData.getLocationPlaceHolder(c.containerUrl, name);
+
+ if (key.equals(location)) {
+ result = c;
+ break;
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Returns a child <tt>ParcelContainer</tt> whose member
+ * <tt>containerUrl</tt> matches the <tt>containerUrl</tt>
+ * argument passed to this method.
+ * @param containerUrl the <tt>containerUrl</tt> which is to
+ * be matched.
+ *
+ * @return child <tt>ParcelContainer</tt> or {@code null} if none
+ * found.
+ */
+ public ParcelContainer getChildContainerForURL(String containerUrl) {
+ ParcelContainer result = null;
+
+ for (ParcelContainer c : childContainers) {
+ if (containerUrl.equals(c.containerUrl)) {
+ result = c;
+ break;
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Returns Name of this container. Name of this <tt>ParcelContainer</tt>
+ * is determined from the <tt>containerUrl</tt> as the last portion
+ * of the URL after the last forward slash.
+ * @return name of <tt>ParcelContainer</tt>
+ * found.
+ */
+ public String getName() {
+ String name = null;
+
+ // TODO handler package ParcelContainer?
+ if (!containerUrl.startsWith("vnd.sun.star.tdoc:")) {
+ try {
+ // return name
+ String decodedUrl = java.net.URLDecoder.decode(containerUrl, "UTF-8");
+ int indexOfSlash = decodedUrl.lastIndexOf('/');
+
+ if (indexOfSlash != -1) {
+ name = decodedUrl.substring(indexOfSlash + 1);
+ }
+ } catch (UnsupportedEncodingException e) {
+ throw new com.sun.star.uno.RuntimeException(e);
+ }
+ } else {
+ name = "document";
+ }
+
+ return name;
+ }
+
+ /**
+ * Initializes a newly created <code>ParcelContainer</code> object.
+ * @param xCtx UNO component context
+ * @param containerUrl location of this container.
+ * @param language language for which entries are stored
+ */
+ public ParcelContainer(XComponentContext xCtx, String containerUrl,
+ String language) throws
+ com.sun.star.lang.IllegalArgumentException,
+ com.sun.star.lang.WrappedTargetException {
+
+ this(null, xCtx, containerUrl, language, true);
+ }
+
+ /**
+ * Initializes a newly created <code>ParcelContainer</code> object.
+ * @param xCtx UNO component context
+ * @param containerUrl location of this container.
+ * @param language language for which entries are stored
+ * @param loadParcels set to <tt>true</tt> if parcels are to be loaded
+ * on construction.
+ */
+ public ParcelContainer(XComponentContext xCtx, String containerUrl,
+ String language, boolean loadParcels) throws
+ com.sun.star.lang.IllegalArgumentException,
+ com.sun.star.lang.WrappedTargetException {
+
+ this(null, xCtx, containerUrl, language, loadParcels);
+ }
+
+ /**
+ * Initializes a newly created <code>ParcelContainer</code> object.
+ * @param parent parent ParcelContainer
+ * @param xCtx UNO component context
+ * @param containerUrl location of this container.
+ * @param language language for which entries are stored
+ * @param loadParcels set to <tt>true</tt> if parcels are to be loaded
+ * on construction.
+ */
+ public ParcelContainer(ParcelContainer parent, XComponentContext xCtx,
+ String containerUrl, String language,
+ boolean loadParcels) throws
+ com.sun.star.lang.IllegalArgumentException,
+ com.sun.star.lang.WrappedTargetException {
+
+ LogUtils.DEBUG("Creating ParcelContainer for " + containerUrl +
+ " loadParcels = " + loadParcels + " language = " + language);
+
+ this.m_xCtx = xCtx;
+ this.language = language;
+ this.parent = parent;
+ this.containerUrl = containerUrl;
+
+ initSimpleFileAccess();
+ boolean parentIsPkgContainer = false;
+
+ if (parent != null) {
+ parentIsPkgContainer = parent.isUnoPkg();
+ }
+
+ if (containerUrl.endsWith("uno_packages") || parentIsPkgContainer) {
+ isPkgContainer = true;
+ }
+
+ if (loadParcels) {
+ loadParcels();
+ }
+ }
+
+
+ public String getContainerURL() {
+ return this.containerUrl;
+ }
+
+ private void initSimpleFileAccess() {
+ synchronized (ParcelContainer.class) {
+ if (m_xSFA != null) {
+ return;
+ }
+
+ try {
+
+ m_xSFA = UnoRuntime.queryInterface(
+ XSimpleFileAccess.class,
+ m_xCtx.getServiceManager().createInstanceWithContext(
+ "com.sun.star.ucb.SimpleFileAccess", m_xCtx));
+
+ } catch (Exception e) {
+ // TODO should throw
+ LogUtils.DEBUG("Error instantiating simplefile access ");
+ LogUtils.DEBUG(LogUtils.getTrace(e));
+ }
+ }
+ }
+
+ public String getParcelContainerDir() {
+ // If this container does not represent a uno-package
+ // then it is a document, user or share
+ // in each case the convention is to have a Scripts/[language]
+ // dir where scripts reside
+ if (!isUnoPkg()) {
+ return PathUtils.make_url(containerUrl , "Scripts/" + language.toLowerCase());
+ }
+
+ return containerUrl;
+ }
+
+ public Object getByName(String aName) throws
+ com.sun.star.container.NoSuchElementException, WrappedTargetException {
+
+ Parcel parcel = null;
+
+ try {
+ if (hasElements()) {
+ for (Parcel parcelToCheck : parcels) {
+ if (parcelToCheck.getName().equals(aName)) {
+ parcel = parcelToCheck;
+ break;
+ }
+ }
+ }
+ } catch (Exception e) {
+ throw new WrappedTargetException(e);
+ }
+
+ if (parcel == null) {
+ throw new com.sun.star.container.NoSuchElementException("Macro Library " + aName
+ + " not found");
+ }
+
+ return parcel;
+ }
+
+ public String[] getElementNames() {
+
+ if (hasElements()) {
+
+ Parcel[] theParcels = parcels.toArray(new Parcel[parcels.size()]);
+ String[] names = new String[ theParcels.length ];
+
+ for (int count = 0; count < names.length; count++) {
+ names[count] = theParcels[ count ].getName();
+ }
+
+ return names;
+ }
+
+ return new String[0];
+ }
+
+ public boolean hasByName(String aName) {
+
+ boolean isFound = false;
+
+ try {
+ if (getByName(aName) != null) {
+ isFound = true;
+ }
+
+ } catch (Exception e) {
+ //TODO - handle trace
+ }
+
+ return isFound;
+ }
+
+ public Type getElementType() {
+ return new Type();
+ }
+
+ public boolean hasElements() {
+ return !(parcels == null || parcels.isEmpty());
+ }
+
+ private void loadParcels() throws com.sun.star.lang.IllegalArgumentException,
+ com.sun.star.lang.WrappedTargetException {
+
+ try {
+ LogUtils.DEBUG("About to load parcels from " + containerUrl);
+
+ if (m_xSFA.isFolder(getParcelContainerDir())) {
+ LogUtils.DEBUG(getParcelContainerDir() + " is a folder ");
+ String[] children = m_xSFA.getFolderContents(getParcelContainerDir(), true);
+ parcels = new ArrayList<Parcel>(children.length);
+
+ for (String child : children) {
+ LogUtils.DEBUG("Processing " + child);
+
+ try {
+ loadParcel(child);
+ } catch (java.lang.Exception e) {
+ // print an error message and move on to
+ // the next parcel
+ LogUtils.DEBUG("ParcelContainer.loadParcels caught " + e.getClass().getName() +
+ " exception loading parcel " + child + ": " + e.getMessage());
+ }
+ }
+ } else {
+ LogUtils.DEBUG(" ParcelCOntainer.loadParcels " + getParcelContainerDir() +
+ " is not a folder ");
+ }
+
+ } catch (com.sun.star.ucb.CommandAbortedException e) {
+ LogUtils.DEBUG("ParcelContainer.loadParcels caught exception processing folders for "
+ + getParcelContainerDir());
+ LogUtils.DEBUG("TRACE: " + LogUtils.getTrace(e));
+ throw new com.sun.star.lang.WrappedTargetException(e);
+ } catch (com.sun.star.uno.Exception e) {
+ LogUtils.DEBUG("ParcelContainer.loadParcels caught exception processing folders for "
+ + getParcelContainerDir());
+ LogUtils.DEBUG("TRACE: " + LogUtils.getTrace(e));
+ throw new com.sun.star.lang.WrappedTargetException(e);
+ }
+ }
+
+ public XNameContainer createParcel(String name) throws
+ ElementExistException, com.sun.star.lang.WrappedTargetException {
+
+ Parcel p = null;
+
+ if (hasByName(name)) {
+ throw new ElementExistException("Parcel " + name + " already exists");
+ }
+
+ String pathToParcel = PathUtils.make_url(getParcelContainerDir(), name);
+
+ try {
+ LogUtils.DEBUG("ParcelContainer.createParcel, creating folder "
+ + pathToParcel);
+
+ m_xSFA.createFolder(pathToParcel);
+
+ LogUtils.DEBUG("ParcelContainer.createParcel, folder " + pathToParcel +
+ " created ");
+
+ ParcelDescriptor pd = new ParcelDescriptor();
+ pd.setLanguage(language);
+
+ String parcelDesc =
+ PathUtils.make_url(pathToParcel, ParcelDescriptor.PARCEL_DESCRIPTOR_NAME);
+
+ XSimpleFileAccess2 xSFA2 =
+ UnoRuntime.queryInterface(XSimpleFileAccess2.class, m_xSFA);
+
+ if (xSFA2 != null) {
+ LogUtils.DEBUG("createParcel() Using XSIMPLEFILEACCESS2 " + parcelDesc);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream(1024);
+ pd.write(bos);
+ bos.close();
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ XInputStreamImpl xis = new XInputStreamImpl(bis);
+ xSFA2.writeFile(parcelDesc, xis);
+ xis.closeInput();
+ p = loadParcel(pathToParcel);
+ }
+ } catch (Exception e) {
+ LogUtils.DEBUG("createParcel() Exception while attempting to create = "
+ + name);
+ throw new com.sun.star.lang.WrappedTargetException(e);
+ }
+
+ return p;
+ }
+
+ public Parcel loadParcel(String parcelUrl) throws
+ com.sun.star.lang.WrappedTargetException,
+ com.sun.star.lang.IllegalArgumentException {
+
+ String parcelDescUrl =
+ PathUtils.make_url(parcelUrl, ParcelDescriptor.PARCEL_DESCRIPTOR_NAME);
+
+ Parcel parcel = null;
+ XInputStream xis = null;
+ InputStream is = null;
+
+ try {
+ if (m_xSFA.exists(parcelDescUrl)) {
+
+ LogUtils.DEBUG("ParcelContainer.loadParcel opening " + parcelDescUrl);
+
+ xis = m_xSFA.openFileRead(parcelDescUrl);
+ is = new XInputStreamWrapper(xis);
+ ParcelDescriptor pd = new ParcelDescriptor(is) ;
+
+ try {
+ is.close();
+ is = null;
+ } catch (Exception e) {
+ LogUtils.DEBUG(
+ "ParcelContainer.loadParcel Exception when closing stream for "
+ + parcelDescUrl + " :" + e);
+ }
+
+ LogUtils.DEBUG("ParcelContainer.loadParcel closed " + parcelDescUrl);
+
+ if (!pd.getLanguage().equals(language)) {
+ LogUtils.DEBUG("ParcelContainer.loadParcel Language of Parcel does not match this container ");
+ return null;
+ }
+
+ LogUtils.DEBUG("Processing " + parcelDescUrl + " closed ");
+
+ int indexOfSlash = parcelUrl.lastIndexOf('/');
+ String name = parcelUrl.substring(indexOfSlash + 1);
+
+ parcel = new Parcel(m_xSFA, this, pd, name);
+
+ LogUtils.DEBUG(" ParcelContainer.loadParcel created parcel for "
+ + parcelDescUrl + " for language " + language);
+
+ parcels.add(parcel);
+ } else {
+ throw new java.io.IOException(parcelDescUrl + " does NOT exist!");
+ }
+ } catch (com.sun.star.ucb.CommandAbortedException e) {
+ LogUtils.DEBUG("loadParcel() Exception while accessing filesystem url = "
+ + parcelDescUrl + e);
+ throw new com.sun.star.lang.WrappedTargetException(e);
+ } catch (java.io.IOException e) {
+ LogUtils.DEBUG("ParcelContainer.loadParcel() caught IOException while accessing "
+ + parcelDescUrl + ": " + e);
+ throw new com.sun.star.lang.WrappedTargetException(e);
+ } catch (com.sun.star.uno.Exception e) {
+ LogUtils.DEBUG("loadParcel() Exception while accessing filesystem url = "
+ + parcelDescUrl + e);
+ throw new com.sun.star.lang.WrappedTargetException(e);
+ }
+
+ finally {
+ if (is != null) {
+ try {
+ is.close(); // is will close xis
+ } catch (Exception ignore) {
+ }
+ } else if (xis != null) {
+ try {
+ xis.closeInput();
+ } catch (Exception ignore) {
+ }
+ }
+ }
+
+ return parcel;
+ }
+ public void renameParcel(String oldName, String newName) throws
+ com.sun.star.container.NoSuchElementException,
+ com.sun.star.lang.WrappedTargetException {
+
+ LogUtils.DEBUG(" ** ParcelContainer Renaming parcel " + oldName + " to " +
+ newName);
+ LogUtils.DEBUG(" ** ParcelContainer is " + this);
+
+ Parcel p = (Parcel)getByName(oldName);
+
+ if (p == null) {
+ throw new com.sun.star.container.NoSuchElementException(
+ "No parcel named " + oldName);
+ }
+
+ String oldParcelDirUrl =
+ PathUtils.make_url(getParcelContainerDir(), oldName);
+
+ String newParcelDirUrl =
+ PathUtils.make_url(getParcelContainerDir(), newName);
+
+ try {
+ if (!m_xSFA.isFolder(oldParcelDirUrl)) {
+ Exception e = new com.sun.star.io.IOException(
+ "Invalid Parcel directory: " + oldName);
+ throw new com.sun.star.lang.WrappedTargetException(e);
+ }
+
+ LogUtils.DEBUG(" ** ParcelContainer Renaming folder " + oldParcelDirUrl
+ + " to " + newParcelDirUrl);
+
+ m_xSFA.move(oldParcelDirUrl, newParcelDirUrl);
+
+ } catch (com.sun.star.ucb.CommandAbortedException ce) {
+ LogUtils.DEBUG(" ** ParcelContainer Renaming failed with " + ce);
+ throw new com.sun.star.lang.WrappedTargetException(ce);
+ } catch (com.sun.star.uno.Exception e) {
+ LogUtils.DEBUG(" ** ParcelContainer Renaming failed with " + e);
+ throw new com.sun.star.lang.WrappedTargetException(e);
+ }
+
+ p.rename(newName);
+ }
+ // removes but doesn't physically delete parcel from container
+ public boolean removeParcel(String name) throws
+ com.sun.star.container.NoSuchElementException,
+ com.sun.star.lang.WrappedTargetException {
+
+ Parcel p = (Parcel)getByName(name);
+
+ if (p == null) {
+ throw new com.sun.star.container.NoSuchElementException(
+ "No parcel named " + name);
+ }
+
+ return parcels.remove(p);
+ }
+
+ public boolean deleteParcel(String name) throws
+ com.sun.star.container.NoSuchElementException,
+ com.sun.star.lang.WrappedTargetException {
+
+ LogUtils.DEBUG("deleteParcel for containerURL " + containerUrl
+ + " name = " + name + " Language = " + language);
+
+ Parcel p = (Parcel)getByName(name);
+
+ if (p == null) {
+ throw new com.sun.star.container.NoSuchElementException(
+ "No parcel named " + name);
+ }
+
+ try {
+ String pathToParcel = PathUtils.make_url(getParcelContainerDir(), name);
+ m_xSFA.kill(pathToParcel);
+ } catch (Exception e) {
+ LogUtils.DEBUG("Error deleting parcel " + name);
+ throw new com.sun.star.lang.WrappedTargetException(e);
+ }
+
+ return parcels.remove(p);
+ }
+
+ public String getLanguage() {
+ return language;
+ }
+
+ public ScriptMetaData findScript(ParsedScriptUri parsedUri) throws
+ com.sun.star.container.NoSuchElementException,
+ com.sun.star.lang.WrappedTargetException {
+
+ Parcel p = (Parcel)getByName(parsedUri.parcel);
+ ScriptMetaData scriptData = p.getByName(parsedUri.function);
+
+ LogUtils.DEBUG("** found script data for " + parsedUri.function + " script is "
+ + scriptData);
+
+ return scriptData;
+ }
+
+ public ParsedScriptUri parseScriptUri(String scriptURI) throws
+ com.sun.star.lang.IllegalArgumentException {
+
+ XMultiComponentFactory xMcFac = null;
+ XUriReferenceFactory xFac = null;
+
+ try {
+ xMcFac = m_xCtx.getServiceManager();
+
+ xFac = UnoRuntime.queryInterface(
+ XUriReferenceFactory.class, xMcFac.createInstanceWithContext(
+ "com.sun.star.uri.UriReferenceFactory", m_xCtx));
+
+ } catch (com.sun.star.uno.Exception e) {
+ LogUtils.DEBUG("Problems parsing URL:" + e.toString());
+ throw new com.sun.star.lang.IllegalArgumentException(
+ e, "Problems parsing URL");
+ }
+
+ if (xFac == null) {
+ LogUtils.DEBUG("Failed to create UrlReference factory");
+ throw new com.sun.star.lang.IllegalArgumentException(
+ "Failed to create UrlReference factory for url " + scriptURI);
+ }
+
+ XUriReference uriRef = xFac.parse(scriptURI);
+
+ XVndSunStarScriptUrl sfUri =
+ UnoRuntime.queryInterface(XVndSunStarScriptUrl.class, uriRef);
+
+ if (sfUri == null) {
+ LogUtils.DEBUG("Failed to parse url");
+ throw new com.sun.star.lang.IllegalArgumentException(
+ "Failed to parse url " + scriptURI);
+ }
+
+ ParsedScriptUri parsedUri = new ParsedScriptUri();
+ parsedUri.function = sfUri.getName();
+ parsedUri.parcel = "";
+
+ // parse parcel name;
+ StringTokenizer tokenizer = new StringTokenizer(parsedUri.function, ".");
+
+ if (tokenizer.hasMoreElements()) {
+ parsedUri.parcel = (String)tokenizer.nextElement();
+ LogUtils.DEBUG("** parcelName = " + parsedUri.parcel);
+ }
+
+ if (parsedUri.function.length() > 0) {
+
+ // strip out parcel name
+ parsedUri.function =
+ parsedUri.function.substring(parsedUri.parcel.length() + 1);
+
+ }
+
+ // parse location
+ parsedUri.location = sfUri.getParameter("location");
+
+ // TODO basic sanity check on language, location, function name, parcel
+ // should be correct e.g. verified by MSP and LangProvider by the
+ // time it's got to here
+
+ LogUtils.DEBUG("** location = " + parsedUri.location +
+ "\nfunction = " + parsedUri.function +
+ "\nparcel = " + parsedUri.parcel +
+ "\nlocation = " + parsedUri.location);
+
+ return parsedUri;
+ }
+}
diff --git a/scripting/java/com/sun/star/script/framework/container/ParcelDescriptor.java b/scripting/java/com/sun/star/script/framework/container/ParcelDescriptor.java
new file mode 100644
index 000000000..eeb8f9ef2
--- /dev/null
+++ b/scripting/java/com/sun/star/script/framework/container/ParcelDescriptor.java
@@ -0,0 +1,354 @@
+/*
+ * 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 java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.w3c.dom.CharacterData;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+public class ParcelDescriptor {
+
+ // File name to be used for parcel descriptor files
+ public static final String
+ PARCEL_DESCRIPTOR_NAME = "parcel-descriptor.xml";
+
+ // This is the default contents of a parcel descriptor to be used when
+ // creating empty descriptors
+ private static final byte[] EMPTY_DOCUMENT =
+ ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
+ "<parcel xmlns:parcel=\"scripting.dtd\" language=\"Java\">\n" +
+ "</parcel>").getBytes();
+
+ private Document document = null;
+ private String language = null;
+ private final Map<String, String> languagedepprops = new HashMap<String, String>(3);
+
+ public ParcelDescriptor() throws IOException {
+ ByteArrayInputStream bis = null;
+
+ try {
+ bis = new ByteArrayInputStream(EMPTY_DOCUMENT);
+ this.document = XMLParserFactory.getParser().parse(bis);
+ } finally {
+ if (bis != null)
+ bis.close();
+ }
+ }
+
+ private ParcelDescriptor(Document document) {
+ this.document = document;
+ initLanguageProperties();
+ }
+
+ public ParcelDescriptor(InputStream is) throws IOException {
+ this(XMLParserFactory.getParser().parse(is));
+ }
+
+ public ParcelDescriptor(File file) throws IOException {
+ this(file, "Java");
+ }
+
+ private ParcelDescriptor(File file, String language) throws IOException {
+ if (file.exists()) {
+ FileInputStream fis = null;
+
+ try {
+ fis = new FileInputStream(file);
+ this.document = XMLParserFactory.getParser().parse(fis);
+ } finally {
+ if (fis != null)
+ fis.close();
+ }
+ } else {
+ ByteArrayInputStream bis = null;
+
+ try {
+ bis = new ByteArrayInputStream(EMPTY_DOCUMENT);
+ this.document = XMLParserFactory.getParser().parse(bis);
+ } finally {
+ if (bis != null)
+ bis.close();
+ }
+
+ setLanguage(language);
+ }
+
+ initLanguageProperties();
+ }
+
+ public void write(OutputStream out) throws IOException {
+ XMLParserFactory.getParser().write(document, out);
+ }
+
+ public Document getDocument() {
+ return document;
+ }
+
+ public String getLanguage() {
+ if (language == null && document != null) {
+ Element e = document.getDocumentElement();
+ language = e.getAttribute("language");
+ }
+
+ return language;
+ }
+
+ public void setLanguage(String language) {
+ this.language = language;
+
+ if (document != null) {
+ try {
+ Element e = document.getDocumentElement();
+ e.setAttribute("language", language);
+ } catch (DOMException de) {
+ }
+ }
+ }
+
+ public ScriptEntry[] getScriptEntries() {
+
+ ArrayList<ScriptEntry> scripts = new ArrayList<ScriptEntry>();
+ NodeList scriptNodes;
+ int len;
+
+ if (document == null ||
+ (scriptNodes = document.getElementsByTagName("script")) == null ||
+ (len = scriptNodes.getLength()) == 0)
+ return new ScriptEntry[0];
+
+ for (int i = 0; i < len; i++) {
+ String language, languagename, description = "";
+ Map<String, String> langProps = new HashMap<String, String>();
+ NodeList nl;
+
+ Element scriptElement = (Element)scriptNodes.item(i);
+ language = scriptElement.getAttribute("language");
+
+ // get the text of the description element
+ nl = scriptElement.getElementsByTagName("locale");
+
+ if (nl != null) {
+ nl = nl.item(0).getChildNodes();
+
+ if (nl != null) {
+ for (int j = 0 ; j < nl.getLength(); j++) {
+ if (nl.item(j).getNodeName().equals("description")) {
+ CharacterData cd =
+ (CharacterData)nl.item(j).getFirstChild();
+ description = cd.getData().trim();
+ }
+ }
+ }
+ }
+
+ nl = scriptElement.getElementsByTagName("functionname");
+
+ if (nl == null) {
+ languagename = "";
+ } else {
+ Element tmp = (Element)nl.item(0);
+ languagename = tmp.getAttribute("value");
+ }
+
+ nl = scriptElement.getElementsByTagName("languagedepprops");
+
+ if (nl != null && nl.getLength() > 0) {
+
+ NodeList props = ((Element)nl.item(0)).getElementsByTagName("prop");
+
+ if (props != null) {
+ for (int j = 0; j < props.getLength(); j++) {
+ Element tmp = (Element)props.item(j);
+ String key = tmp.getAttribute("name");
+ String val = tmp.getAttribute("value");
+ langProps.put(key, val);
+ }
+ }
+ }
+
+ ScriptEntry entry =
+ new ScriptEntry(language, languagename, langProps, description);
+ scripts.add(entry);
+ }
+
+ return scripts.toArray(new ScriptEntry[scripts.size()]);
+ }
+
+ public void setScriptEntries(ScriptEntry[] scripts) {
+ clearEntries();
+
+ for (ScriptEntry script : scripts) {
+ addScriptEntry(script);
+ }
+ }
+
+ public void setScriptEntries(Iterator<ScriptEntry> scripts) {
+ clearEntries();
+
+ while (scripts.hasNext()) {
+ addScriptEntry(scripts.next());
+ }
+ }
+
+ private String getLanguageProperty(String name) {
+ return languagedepprops.get(name);
+ }
+
+
+
+ private void initLanguageProperties() {
+ NodeList nl = document.getElementsByTagName("languagedepprops");
+ int len;
+
+ if (nl != null && (len = nl.getLength()) != 0) {
+
+ for (int i = 0; i < len; i++) {
+ Element e = (Element)nl.item(i);
+ NodeList nl2 = e.getElementsByTagName("prop");
+ int len2;
+
+ if (nl2 != null && (len2 = nl2.getLength()) != 0) {
+ for (int j = 0; j < len2; j++) {
+ Element e2 = (Element)nl2.item(j);
+
+ String name = e2.getAttribute("name");
+ String value = e2.getAttribute("value");
+
+ if (getLanguageProperty(name) == null) {
+ languagedepprops.put(name, value);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private void clearEntries() {
+ NodeList scriptNodes;
+ Element main = document.getDocumentElement();
+ int len;
+
+ if ((scriptNodes = document.getElementsByTagName("script")) != null &&
+ (len = scriptNodes.getLength()) != 0) {
+ for (int i = len - 1; i >= 0; i--) {
+ try {
+ main.removeChild(scriptNodes.item(i));
+ } catch (DOMException de) {
+ // ignore
+ }
+ }
+ }
+ }
+
+ public void removeScriptEntry(ScriptEntry script) {
+ NodeList scriptNodes;
+ Element main = document.getDocumentElement();
+ int len;
+
+ if ((scriptNodes = document.getElementsByTagName("script")) != null &&
+ (len = scriptNodes.getLength()) != 0) {
+ for (int i = len - 1; i >= 0; i--) {
+ try {
+ Element scriptElement = (Element)scriptNodes.item(i);
+ String languagename = "";
+
+ NodeList nl =
+ scriptElement.getElementsByTagName("functionname");
+
+ if (nl == null) {
+ continue;
+ } else {
+ Element tmp = (Element)nl.item(0);
+ languagename = tmp.getAttribute("value");
+ }
+
+ if (languagename.equals(script.getLanguageName())) {
+ main.removeChild(scriptElement);
+ }
+ } catch (DOMException de) {
+ // ignore
+ }
+ }
+ }
+ }
+
+ public void addScriptEntry(ScriptEntry script) {
+ Element main = document.getDocumentElement();
+ Element root, item, tempitem;
+
+ root = document.createElement("script");
+ root.setAttribute("language", script.getLanguage());
+
+ item = document.createElement("locale");
+ item.setAttribute("lang", "en");
+ tempitem = document.createElement("displayname");
+ tempitem.setAttribute("value", script.getLogicalName());
+ item.appendChild(tempitem);
+
+ tempitem = document.createElement("description");
+ String description = script.getDescription();
+
+ if (description == null || description.length() == 0) {
+ description = script.getLogicalName();
+ }
+
+ tempitem.appendChild(document.createTextNode(description));
+ item.appendChild(tempitem);
+
+ root.appendChild(item);
+
+ item = document.createElement("logicalname");
+ item.setAttribute("value", script.getLogicalName());
+ root.appendChild(item);
+
+ item = document.createElement("functionname");
+ item.setAttribute("value", script.getLanguageName());
+ root.appendChild(item);
+
+ if (languagedepprops != null && !languagedepprops.isEmpty()) {
+ String key;
+ item = document.createElement("languagedepprops");
+
+ for (Map.Entry<String, String> entry : languagedepprops.entrySet()) {
+ tempitem = document.createElement("prop");
+ tempitem.setAttribute("name", entry.getKey());
+ tempitem.setAttribute("value", entry.getValue());
+ item.appendChild(tempitem);
+ }
+
+ root.appendChild(item);
+ }
+
+ //add to the Top Element
+ main.appendChild(root);
+ }
+}
diff --git a/scripting/java/com/sun/star/script/framework/container/ParsedScriptUri.java b/scripting/java/com/sun/star/script/framework/container/ParsedScriptUri.java
new file mode 100644
index 000000000..796314f00
--- /dev/null
+++ b/scripting/java/com/sun/star/script/framework/container/ParsedScriptUri.java
@@ -0,0 +1,25 @@
+/*
+ * 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;
+
+public class ParsedScriptUri {
+
+ public String location;
+ public String function;
+ public String parcel;
+} \ No newline at end of file
diff --git a/scripting/java/com/sun/star/script/framework/container/ScriptEntry.java b/scripting/java/com/sun/star/script/framework/container/ScriptEntry.java
new file mode 100644
index 000000000..92870c680
--- /dev/null
+++ b/scripting/java/com/sun/star/script/framework/container/ScriptEntry.java
@@ -0,0 +1,85 @@
+/*
+ * 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 java.util.HashMap;
+import java.util.Map;
+
+public class ScriptEntry {
+
+ private final String language;
+ private final String languagename;
+ private final String logicalname;
+ private final String description;
+
+ private final Map<String, String> languagedepprops;
+
+ protected ScriptEntry(ScriptEntry entry) {
+ this.language = entry.language;
+ this.languagename = entry.languagename;
+ this.logicalname = entry.languagename;
+ this.languagedepprops = entry.languagedepprops;
+ this.description = entry.description;
+ }
+
+ public ScriptEntry(String language, String languagename) {
+ this(language, languagename, new HashMap<String, String>(), "");
+ }
+
+ public ScriptEntry(String language, String languagename,
+ Map<String, String> languagedepprops,
+ String description) {
+ this.language = language;
+ this.languagename = languagename;
+ // logical name/ function name concept
+ // needs to be reworked, in meantime
+ // function name ( from xml ) will be used
+ // as logical name also
+ this.logicalname = languagename;
+ this.languagedepprops = languagedepprops;
+ this.description = description;
+ }
+
+ public Map<String, String> getLanguageProperties() {
+ return languagedepprops;
+ }
+
+ public String getLanguageName() {
+ return languagename;
+ }
+
+ public String getLogicalName() {
+ return logicalname;
+ }
+
+ public String getLanguage() {
+ return language;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ @Override
+ public String toString() {
+ return "\nLogicalName = " + logicalname +
+ "\nLanguageName = " + languagename +
+ "\nLanguaguageProperties = " + languagedepprops;
+ }
+}
diff --git a/scripting/java/com/sun/star/script/framework/container/ScriptMetaData.java b/scripting/java/com/sun/star/script/framework/container/ScriptMetaData.java
new file mode 100644
index 000000000..de51b1247
--- /dev/null
+++ b/scripting/java/com/sun/star/script/framework/container/ScriptMetaData.java
@@ -0,0 +1,328 @@
+/*
+ * 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.script.framework.io.UCBStreamHandler;
+import com.sun.star.script.framework.io.XInputStreamImpl;
+import com.sun.star.script.framework.log.LogUtils;
+import com.sun.star.script.framework.provider.PathUtils;
+
+import com.sun.star.ucb.XSimpleFileAccess2;
+
+import com.sun.star.uno.UnoRuntime;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+import java.net.URL;
+
+import java.util.ArrayList;
+import java.util.StringTokenizer;
+
+public class ScriptMetaData extends ScriptEntry {
+
+ private boolean hasSource = false;
+ private static final String locationPlaceHolder = "";
+ private String source;
+ private final Parcel parent;
+
+
+ public ScriptMetaData(Parcel parent, ScriptEntry entry,
+ String source) {
+ super(entry);
+ this.parent = parent;
+
+ if (source != null) {
+ this.hasSource = true;
+ this.source = source;
+ }
+ }
+
+ public boolean hasSource() {
+ return hasSource;
+ }
+
+ public String getSource() {
+ return (source != null && hasSource) ? source : null;
+ }
+
+ public byte[] getSourceBytes() {
+ return (source != null && hasSource) ? source.getBytes() : null;
+ }
+
+ public String getScriptFullURL() {
+ String url = "vnd.sun.star.script:" + parent.getName() + "."
+ + getLanguageName() + "?" + "language=" + getLanguage()
+ + "&location=" + getParcelLocation();
+
+ return url;
+ }
+
+ public String getShortFormScriptURL() {
+ String url = "vnd.sun.star.script:" + parent.getName() + "."
+ + getLanguageName() + "?" + "language=" + getLanguage()
+ + "&location=" + getLocationPlaceHolder();
+
+ return url;
+ }
+
+ // TODO probably should be private should not be necessary
+ // to be exposed at all
+
+ private static final String SHARE =
+ "vnd.sun.star.expand:$BRAND_BASE_DIR/$BRAND_SHARE_SUBDIR";
+
+ private static final String USER =
+ "vnd.sun.star.expand:${$BRAND_INI_DIR/" + PathUtils.BOOTSTRAP_NAME
+ + "::UserInstallation}/user";
+
+ private static final String UNO_USER_PACKAGES1 =
+ "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE";
+
+ private static final String UNO_USER_PACKAGES2 = USER + "/uno_packages";
+
+ private static final String UNO_SHARED_PACKAGES1 =
+ "$UNO_SHARED_PACKAGES_CACHE";
+
+ private static final String UNO_SHARED_PACKAGES2 = SHARE + "/uno_packages";
+
+ public static String getFileName(URL url) {
+ String fileName = url.toExternalForm();
+ if (fileName.lastIndexOf(UCBStreamHandler.separator) != -1) {
+ fileName = fileName.substring(0, fileName.lastIndexOf(UCBStreamHandler.separator));
+ fileName = fileName.substring(fileName.lastIndexOf("/") + 1);
+ }
+ return fileName;
+ }
+
+ public static String getLocationPlaceHolder(String url, String pkgname) {
+ String result = "Unknown";
+
+ if (url.contains(UNO_USER_PACKAGES1) ||
+ url.contains(UNO_USER_PACKAGES2)) {
+ result = PathUtils.make_url("user:uno_packages", pkgname);
+ } else if (url.contains(UNO_SHARED_PACKAGES1) ||
+ url.contains(UNO_SHARED_PACKAGES2)) {
+ result = PathUtils.make_url("share:uno_packages", pkgname);
+ } else if (url.indexOf(SHARE) == 0) {
+ result = "share";
+ } else if (url.indexOf(USER) == 0) {
+ result = "user";
+ } else if (url.indexOf("vnd.sun.star.tdoc:") == 0) {
+ result = "document";
+ }
+
+ return result;
+ }
+
+ public String getLocationPlaceHolder() {
+ String placeHolder = "Unknown";
+ String pathToParcel = parent.getPathToParcel();
+
+ if (pathToParcel.contains(UNO_USER_PACKAGES1) ||
+ pathToParcel.contains(UNO_USER_PACKAGES2)) {
+ // it's a package
+ placeHolder = "user:uno_packages";
+ String unoPkg = parent.parent.getName();
+
+ if (unoPkg != null) {
+ placeHolder = PathUtils.make_url(placeHolder, unoPkg);
+ }
+ } else if (pathToParcel.contains(UNO_SHARED_PACKAGES1) ||
+ pathToParcel.contains(UNO_SHARED_PACKAGES2)) {
+ //it's a package
+ placeHolder = "share:uno_packages";
+ String unoPkg = parent.parent.getName();
+
+ if (unoPkg != null) {
+ placeHolder = PathUtils.make_url(placeHolder, unoPkg);
+ }
+ } else if (pathToParcel.indexOf(SHARE) == 0) {
+ placeHolder = "share";
+ } else if (pathToParcel.indexOf(USER) == 0) {
+ placeHolder = "user";
+ } else if (pathToParcel.indexOf("vnd.sun.star.tdoc:") == 0) {
+ placeHolder = "document";
+ }
+
+ // TODO handling document packages ??? not really sure of package url
+ /* else
+ {
+ } */
+ return placeHolder;
+ }
+
+ // TODO probably should be private should not be necessary
+ // to be exposed at all only used in lang providers at the moment
+ // to generate URL for script, editors should use a model of script
+ // source and not interact with the URL
+ // Also if it is to remain needs to be renamed to getParcelLocationURL
+
+ // return URL string to parcel
+ public String getParcelLocation() {
+ return parent.getPathToParcel();
+ }
+
+ @Override
+ public String toString() {
+ return "\nParcelLocation = " + getParcelLocation() + "\nLocationPlaceHolder = "
+ + locationPlaceHolder + super.toString();
+ }
+
+ public URL[] getClassPath() {
+ try {
+ String classpath = getLanguageProperties().get("classpath");
+
+ if (classpath == null) {
+ classpath = "";
+ }
+
+ String parcelPath = getParcelLocation();
+
+ // make sure path ends with /
+ if (!parcelPath.endsWith("/")) {
+ parcelPath += "/";
+ }
+
+ // replace \ with /
+ parcelPath = parcelPath.replace('\\', '/');
+
+ ArrayList<URL> classPathVec = new ArrayList<URL>();
+ StringTokenizer stk = new StringTokenizer(classpath, ":");
+
+ while (stk.hasMoreElements()) {
+ String relativeClasspath = stk.nextToken();
+ String pathToProcess = PathUtils.make_url(parcelPath, relativeClasspath);
+ URL url = createURL(pathToProcess);
+
+ if (url != null) {
+ classPathVec.add(url);
+ }
+
+ }
+
+ if (classPathVec.isEmpty()) {
+ URL url = createURL(parcelPath);
+
+ if (url != null) {
+ classPathVec.add(url);
+ }
+ }
+
+ return classPathVec.toArray(new URL[classPathVec.size()]);
+ } catch (Exception e) {
+ LogUtils.DEBUG("Failed to build class path " + e.toString());
+ LogUtils.DEBUG(LogUtils.getTrace(e));
+ return new URL[0];
+ }
+ }
+
+ private URL createURL(String path) throws java.net.MalformedURLException {
+ int indexOfColon = path.indexOf(':');
+ String scheme = path.substring(0, indexOfColon);
+ UCBStreamHandler handler = new UCBStreamHandler(scheme, parent.m_xSFA);
+
+ path += UCBStreamHandler.separator;
+ return new URL(null, path, handler);
+ }
+
+ // TODO should decide whether this should throw or not
+ // decide whether it should be public or protected ( final ? )
+ public void loadSource() {
+ try {
+ URL sourceUrl = getSourceURL();
+
+ LogUtils.DEBUG("** In load source BUT not loading yet for "
+ + sourceUrl);
+
+ if (sourceUrl != null) {
+ StringBuilder buf = new StringBuilder();
+ InputStream in = sourceUrl.openStream();
+
+ byte[] contents = new byte[1024];
+ int len;
+
+ while ((len = in.read(contents, 0, 1024)) != -1) {
+ buf.append(new String(contents, 0, len));
+ }
+
+ try {
+ in.close();
+ } catch (java.io.IOException ignore) {
+ LogUtils.DEBUG("** Failed to read scriot from url "
+ + ignore.toString());
+ }
+
+ source = buf.toString();
+ hasSource = true;
+ }
+ } catch (java.io.IOException e) {
+ LogUtils.DEBUG("** Failed to read scriot from url " + e.toString());
+ }
+
+ }
+
+ protected boolean writeSourceFile() {
+ String sourceFilePath = parent.getPathToParcel() + "/" + getLanguageName();
+ boolean result = false;
+
+ try {
+
+ XSimpleFileAccess2 xSFA2 =
+ UnoRuntime.queryInterface(XSimpleFileAccess2.class, parent.m_xSFA);
+
+ if (xSFA2 != null) {
+ ByteArrayInputStream bis = new ByteArrayInputStream(getSourceBytes());
+ XInputStreamImpl xis = new XInputStreamImpl(bis);
+ xSFA2.writeFile(sourceFilePath, xis);
+ xis.closeInput();
+ result = true;
+ }
+ }
+ // TODO re-examine exception processing should probably throw
+ // exceptions back to caller
+ catch (Exception ignore) {
+ }
+
+ return result;
+ }
+
+ protected boolean removeSourceFile() {
+ String parcelLocation = parent.getPathToParcel();
+ String sourceFilePath = parcelLocation + "/" + getLanguageName();
+ boolean result = false;
+
+ try {
+ parent.m_xSFA.kill(sourceFilePath);
+ result = true;
+ }
+ // TODO reexamine exception handling
+ catch (Exception e) {
+ }
+
+ return result;
+ }
+
+ public URL getSourceURL() throws java.net.MalformedURLException {
+ String sUrl = getParcelLocation();
+ sUrl = PathUtils.make_url(sUrl, getLanguageName());
+ LogUtils.DEBUG("Creating script url for " + sUrl);
+ return createURL(sUrl);
+ }
+}
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);
+ }
+ }
+}
diff --git a/scripting/java/com/sun/star/script/framework/container/XMLParser.java b/scripting/java/com/sun/star/script/framework/container/XMLParser.java
new file mode 100644
index 000000000..38e504ff4
--- /dev/null
+++ b/scripting/java/com/sun/star/script/framework/container/XMLParser.java
@@ -0,0 +1,30 @@
+/*
+ * 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 java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.w3c.dom.Document;
+
+public interface XMLParser {
+ Document parse(InputStream inputStream) throws IOException;
+ void write(Document doc, OutputStream out) throws IOException;
+} \ No newline at end of file
diff --git a/scripting/java/com/sun/star/script/framework/container/XMLParserFactory.java b/scripting/java/com/sun/star/script/framework/container/XMLParserFactory.java
new file mode 100644
index 000000000..02c9e6c34
--- /dev/null
+++ b/scripting/java/com/sun/star/script/framework/container/XMLParserFactory.java
@@ -0,0 +1,106 @@
+/*
+ * 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 java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.w3c.dom.Document;
+
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+public class XMLParserFactory {
+
+ private static XMLParser parser = null;
+ private static String officedtdurl = null;
+
+ private XMLParserFactory() {}
+
+ public static synchronized XMLParser getParser() {
+ if (parser == null)
+ parser = new DefaultParser();
+
+ return parser;
+ }
+
+ public static void setOfficeDTDURL(String url) {
+ officedtdurl = url;
+ }
+
+ private static class DefaultParser implements XMLParser {
+
+ private final DocumentBuilderFactory factory;
+
+ public DefaultParser() {
+ factory = DocumentBuilderFactory.newInstance();
+ }
+
+ public Document parse(InputStream inputStream) throws IOException {
+
+ Document result = null;
+
+ try {
+ DocumentBuilder builder = factory.newDocumentBuilder();
+ InputSource is = new InputSource(inputStream);
+
+ if (officedtdurl != null) {
+ is.setSystemId(officedtdurl);
+ }
+
+ result = builder.parse(is);
+ } catch (SAXParseException ex1) {
+ IOException ex2 = new IOException();
+ ex2.initCause(ex1);
+ throw ex2;
+ } catch (SAXException ex1) {
+ IOException ex2 = new IOException();
+ ex2.initCause(ex1);
+ throw ex2;
+ } catch (ParserConfigurationException ex1) {
+ IOException ex2 = new IOException();
+ ex2.initCause(ex1);
+ throw ex2;
+ }
+
+ return result;
+ }
+
+ public void write(Document doc, OutputStream out) throws IOException {
+ try {
+ TransformerFactory.newInstance().newTransformer().transform(
+ new DOMSource(doc), new StreamResult(out));
+ } catch (TransformerException ex1) {
+ IOException ex2 = new IOException();
+ ex2.initCause(ex1);
+ throw ex2;
+ }
+ }
+ }
+} \ No newline at end of file