diff options
Diffstat (limited to '')
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 |