Mercurial > dive4elements > framework
changeset 472:783cc1b6b615
Moved directories to org.dive4elements
author | Sascha L. Teichmann <teichmann@intevation.de> |
---|---|
date | Thu, 25 Apr 2013 10:53:15 +0200 |
parents | 1a87cb24a446 |
children | d0ac790a6c89 |
files | artifacts-common/src/main/java/de/intevation/artifacts/common/ArtifactNamespaceContext.java artifacts-common/src/main/java/de/intevation/artifacts/common/model/DefaultUser.java artifacts-common/src/main/java/de/intevation/artifacts/common/model/KVP.java artifacts-common/src/main/java/de/intevation/artifacts/common/model/User.java artifacts-common/src/main/java/de/intevation/artifacts/common/utils/ClientProtocolUtils.java artifacts-common/src/main/java/de/intevation/artifacts/common/utils/Config.java artifacts-common/src/main/java/de/intevation/artifacts/common/utils/CreationFilter.java artifacts-common/src/main/java/de/intevation/artifacts/common/utils/DateUtils.java artifacts-common/src/main/java/de/intevation/artifacts/common/utils/FileTools.java artifacts-common/src/main/java/de/intevation/artifacts/common/utils/JSON.java artifacts-common/src/main/java/de/intevation/artifacts/common/utils/LRUCache.java artifacts-common/src/main/java/de/intevation/artifacts/common/utils/MapXPathVariableResolver.java artifacts-common/src/main/java/de/intevation/artifacts/common/utils/StringUtils.java artifacts-common/src/main/java/de/intevation/artifacts/common/utils/XMLUtils.java artifacts-common/src/main/java/de/intevation/artifacts/common/utils/XSLTransformer.java artifacts-common/src/main/java/org/dive4elements/artifacts/common/ArtifactNamespaceContext.java artifacts-common/src/main/java/org/dive4elements/artifacts/common/model/DefaultUser.java artifacts-common/src/main/java/org/dive4elements/artifacts/common/model/KVP.java artifacts-common/src/main/java/org/dive4elements/artifacts/common/model/User.java artifacts-common/src/main/java/org/dive4elements/artifacts/common/utils/ClientProtocolUtils.java artifacts-common/src/main/java/org/dive4elements/artifacts/common/utils/Config.java artifacts-common/src/main/java/org/dive4elements/artifacts/common/utils/CreationFilter.java artifacts-common/src/main/java/org/dive4elements/artifacts/common/utils/DateUtils.java artifacts-common/src/main/java/org/dive4elements/artifacts/common/utils/FileTools.java artifacts-common/src/main/java/org/dive4elements/artifacts/common/utils/JSON.java artifacts-common/src/main/java/org/dive4elements/artifacts/common/utils/LRUCache.java artifacts-common/src/main/java/org/dive4elements/artifacts/common/utils/MapXPathVariableResolver.java artifacts-common/src/main/java/org/dive4elements/artifacts/common/utils/StringUtils.java artifacts-common/src/main/java/org/dive4elements/artifacts/common/utils/XMLUtils.java artifacts-common/src/main/java/org/dive4elements/artifacts/common/utils/XSLTransformer.java |
diffstat | 30 files changed, 3437 insertions(+), 3437 deletions(-) [+] |
line wrap: on
line diff
--- a/artifacts-common/src/main/java/de/intevation/artifacts/common/ArtifactNamespaceContext.java Thu Apr 25 10:50:31 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2010 by Intevation GmbH - * - * This program is free software under the LGPL (>=v2.1) - * Read the file LGPL.txt coming with the software for details - * or visit http://www.gnu.org/licenses/ if it does not exist. - */ - -package de.intevation.artifacts.common; - -import java.util.Iterator; - -import javax.xml.XMLConstants; - -import javax.xml.namespace.NamespaceContext; - -/** - * The namespace used in artifact documents. - * @author <a href="mailto:sascha.teichmann@intevation">Sascha L. Teichmann</a> - */ -public class ArtifactNamespaceContext -implements NamespaceContext -{ - /** - * The URI of the namespace of the artifacts. - */ - public final static String NAMESPACE_URI = - "http://www.intevation.de/2009/artifacts"; - - /** - * The XML prefix for the artifacts namespace. - */ - public final static String NAMESPACE_PREFIX = "art"; - - /** - * Final instance to be easily used to avoid creation - * of instances. - */ - public static final ArtifactNamespaceContext INSTANCE = - new ArtifactNamespaceContext(); - - /** - * The default constructor. - */ - public ArtifactNamespaceContext() { - } - - /** - * @see javax.xml.namespace.NamespaceContext#getNamespaceURI(String) - * @param prefix The prefix - * @return The corresponing URI - */ - public String getNamespaceURI(String prefix) { - - if (prefix == null) { - throw new NullPointerException("Null prefix"); - } - - if (NAMESPACE_PREFIX.equals(prefix)) { - return NAMESPACE_URI; - } - - if ("xml".equals(prefix)) { - return XMLConstants.XML_NS_URI; - } - - return XMLConstants.NULL_NS_URI; - } - - /** - * @see javax.xml.namespace.NamespaceContext#getPrefix(String) - * @param uri The URI - * @return nothing. - * @throws java.lang.UnsupportedOperationException - */ - public String getPrefix(String uri) { - throw new UnsupportedOperationException(); - } - - /** - * @see javax.xml.namespace.NamespaceContext#getPrefixes(java.lang.String) - * @param uri The URI - * @return nothing - * @throws java.lang.UnsupportedOperationException - */ - public Iterator getPrefixes(String uri) { - throw new UnsupportedOperationException(); - } -} -// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/artifacts-common/src/main/java/de/intevation/artifacts/common/model/DefaultUser.java Thu Apr 25 10:50:31 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +0,0 @@ -package de.intevation.artifacts.common.model; - -/** - * The default implementation of the {@link User} interface. - * - * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> - */ -public class DefaultUser implements User { - - /** The user's firstname. */ - protected String firstName; - - /** The user's lastname. */ - protected String lastName; - - - /** - * Creates an empty user without name. - */ - public DefaultUser() { - } - - - /** - * Creates a user with first and lastname. - * - * @param firstName The user's firstname. - * @param lastName The user's lastname. - */ - public DefaultUser(String firstName, String lastName) { - this.firstName = firstName; - this.lastName = lastName; - } - - - /** - * This method returns the firstname of the user. - * - * @return the firstname. - */ - public String getFirstName() { - return firstName; - } - - - /** - * Sets the user's firstname. - * - * @param firstName The user's firstname. - */ - public void setFirstName(String firstName) { - this.firstName = firstName; - } - - - /** - * This method returns the lastname of the user. - * - * @return the lastname. - */ - public String getLastName() { - return lastName; - } - - - /** - * Sets the user's lastname. - * - * @param lastName The user's lastname. - */ - public void setLastName(String lastName) { - this.lastName = lastName; - } -} -// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/artifacts-common/src/main/java/de/intevation/artifacts/common/model/KVP.java Thu Apr 25 10:50:31 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2010 by Intevation GmbH - * - * This program is free software under the LGPL (>=v2.1) - * Read the file LGPL.txt coming with the software for details - * or visit http://www.gnu.org/licenses/ if it does not exist. - */ -package de.intevation.artifacts.common.model; - - -public class KVP<K, V> { - - private K key; - private V value; - - - public KVP(K key, V value) { - this.key = key; - this.value = value; - } - - - public K getKey() { - return key; - } - - - public V getValue() { - return value; - } -} -// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/artifacts-common/src/main/java/de/intevation/artifacts/common/model/User.java Thu Apr 25 10:50:31 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,43 +0,0 @@ -package de.intevation.artifacts.common.model; - -import java.io.Serializable; - -/** - * An interface that describes a user of the system. - * - * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> - */ -public interface User extends Serializable { - - /** - * This method returns the firstname of the user. - * - * @return the firstname. - */ - public String getFirstName(); - - - /** - * Sets the user's firstname. - * - * @param firstName The user's firstname. - */ - public void setFirstName(String firstName); - - - /** - * This method returns the lastname of the user. - * - * @return the lastname. - */ - public String getLastName(); - - - /** - * Sets the user's lastname. - * - * @param lastName The user's lastname. - */ - public void setLastName(String lastName); -} -// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/artifacts-common/src/main/java/de/intevation/artifacts/common/utils/ClientProtocolUtils.java Thu Apr 25 10:50:31 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,860 +0,0 @@ -/* - * Copyright (c) 2011 by Intevation GmbH - * - * This program is free software under the LGPL (>=v2.1) - * Read the file LGPL.txt coming with the software for details - * or visit http://www.gnu.org/licenses/ if it does not exist. - */ -package de.intevation.artifacts.common.utils; - -import javax.xml.xpath.XPathConstants; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -import de.intevation.artifacts.common.ArtifactNamespaceContext; - - -/** - * This class provides methods that help creating the artifact protocol - * documents DESCRIBE, FEED, ADVANCE and OUT. - * - * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> - */ -public class ClientProtocolUtils { - - /** The XPath to the current state in the DESCRIBE document. */ - public static final String XPATH_CURRENT_STATE = "/art:result/art:state"; - - /** The XPath to the static UI part in the DESCRIBE document. */ - public static final String XPATH_STATIC = "/art:result/art:ui/art:static"; - - /** The XPath to the dynamic UI part in the DESCRIBE document. */ - public static final String XPATH_DYNAMIC = "/art:result/art:ui/art:dynamic"; - - /** The XPath to the reachable states part in the DESCRIBE document. */ - public static final String XPATH_STATES = - "/art:result/art:reachable-states"; - - /** The XPath to the output modes in the DESCRIBE document. */ - public static final String XPATH_OUTPUT_MODES = - "/art:result/art:outputmodes/art:output"; - - /** The XPath to the select node relative to the dynamic UI node in the - * DESCRIBE document. */ - public static final String XPATH_DATA_SELECT = "art:select"; - - /** The XPath to the choices nodes relative to the select node in the - * DESCRIBE document. */ - public static final String XPATH_DATA_ITEMS = "art:choices/art:item"; - - /** The XPath that points to the min value of a range.*/ - public static final String XPATH_MIN_NODE = "art:min/@art:value"; - - /** The XPath that points to the max value of a range.*/ - public static final String XPATH_MAX_NODE = "art:max/@art:value"; - - /** The XPath that points to the default min value of a range.*/ - public static final String XPATH_DEF_MIN = "art:min/@art:default"; - - /** The XPath that points to the default max value of a range.*/ - public static final String XPATH_DEF_MAX = "art:max/@art:default"; - - /** The XPath to a label in the artifact's DESCRIBE document. */ - public static final String XPATH_LABEL = "art:label/text()"; - - /** The XPath to a value in the artifact's DESCRIBE document. */ - public static final String XPATH_VALUE = "art:value/text()"; - - - /** - * It should not be necessary to create instances of this class. - */ - private ClientProtocolUtils() { - } - - - /** - * This method creates a new CREATE document. - * - * @return the CREATE document. - */ - public static Document newCreateDocument(String factory) { - return newCreateDocument(factory, null); - } - - - /** - * This method creates a new CREATE document. - * - * @return the CREATE document. - */ - public static Document newCreateDocument(String factory, String uuid) { - return newCreateDocument(factory, uuid, null); - } - - public static Document newCreateDocument( - String factory, - String uuid, - String ids - ) { - return newCreateDocument(factory, uuid, ids, null); - } - - /** - * This method creates a new CREATE document. - * - * @return the CREATE document. - */ - public static Document newCreateDocument( - String factory, - String uuid, - String ids, - CreationFilter filter - ) { - Document doc = XMLUtils.newDocument(); - - XMLUtils.ElementCreator cr = new XMLUtils.ElementCreator( - doc, - ArtifactNamespaceContext.NAMESPACE_URI, - ArtifactNamespaceContext.NAMESPACE_PREFIX); - - Element action = cr.create("action"); - Element type = cr.create("type"); - Element fac = cr.create("factory"); - - type.setAttribute("name", "create"); - fac.setAttribute("name", factory); - - action.appendChild(type); - action.appendChild(fac); - - if (uuid != null) { - Element templ = cr.create("template"); - templ.setAttribute("uuid", uuid); - action.appendChild(templ); - } - - if (ids != null) { - Element id = cr.create("ids"); - id.setAttribute("value", ids); - action.appendChild(id); - } - - if (filter != null) { - action.appendChild(filter.toXML(cr)); - } - - doc.appendChild(action); - - return doc; - } - - - /** - * This method creates a new FEED document. - * - * @param theUuid The identifier of the artifact. - * @param theHash The hash of the artifact. - * @param theData An array that contains key/value pairs that represent the - * data that should be included in the FEED document. - * - * @return the FEED document. - */ - public static Document newFeedDocument( - String theUuid, - String theHash, - String[][] theData) - { - Document doc = XMLUtils.newDocument(); - - XMLUtils.ElementCreator cr = new XMLUtils.ElementCreator( - doc, - ArtifactNamespaceContext.NAMESPACE_URI, - ArtifactNamespaceContext.NAMESPACE_PREFIX); - - Element action = cr.create("action"); - Element type = cr.create("type"); - Element uuid = cr.create("uuid"); - Element hash = cr.create("hash"); - Element data = cr.create("data"); - - // XXX It is not nice that the type has no attribute namespace, but to - // be backward compatible, we don't change this now. - cr.addAttr(type, "name", "feed", false); - cr.addAttr(uuid, "value", theUuid, true); - cr.addAttr(hash, "value", theHash, true); - - for (String[] kvp: theData) { - Element input = cr.create("input"); - cr.addAttr(input, "name", kvp[0], true); - cr.addAttr(input, "value", kvp[1], true); - - data.appendChild(input); - } - - action.appendChild(type); - action.appendChild(uuid); - action.appendChild(hash); - action.appendChild(data); - - doc.appendChild(action); - - return doc; - } - - - /** - * This method creates a new DESCRIBE document. - * - * @param theUuid The identifier of the artifact. - * @param theHash The hash of the artifact. - * @param ui If true, the UI part is included. - * - * @return the DESCRIBE document. - */ - public static Document newDescribeDocument( - String theUuid, - String theHash, - boolean incUI) - { - Document doc = XMLUtils.newDocument(); - - XMLUtils.ElementCreator cr = new XMLUtils.ElementCreator( - doc, - ArtifactNamespaceContext.NAMESPACE_URI, - ArtifactNamespaceContext.NAMESPACE_PREFIX); - - Element action = cr.create("action"); - Element type = cr.create("type"); - Element uuid = cr.create("uuid"); - Element hash = cr.create("hash"); - Element ui = cr.create("include-ui"); - - // XXX It is not nice that the type has no attribute namespace, but to - // be backward compatible, we don't change this now. - cr.addAttr(type, "name", "describe", false); - cr.addAttr(uuid, "value", theUuid, true); - cr.addAttr(hash, "value", theHash, true); - - ui.setTextContent(incUI ? "true" : "false"); - - action.appendChild(type); - action.appendChild(uuid); - action.appendChild(hash); - action.appendChild(ui); - - doc.appendChild(action); - - return doc; - } - - - /** - * This method creates a new ADVANCE document. - * - * @param theUuid The identifier of the artifact. - * @param theHash The hash of the artifact. - * @param theTarget The target state identifier. - * - * @return the ADVANCE document. - */ - public static Document newAdvanceDocument( - String theUuid, - String theHash, - String theTarget) - { - Document doc = XMLUtils.newDocument(); - - XMLUtils.ElementCreator cr = new XMLUtils.ElementCreator( - doc, - ArtifactNamespaceContext.NAMESPACE_URI, - ArtifactNamespaceContext.NAMESPACE_PREFIX); - - Element action = cr.create("action"); - Element type = cr.create("type"); - Element uuid = cr.create("uuid"); - Element hash = cr.create("hash"); - Element target = cr.create("target"); - - // XXX It is not nice that the type has no attribute namespace, but to - // be backward compatible, we don't change this now. - cr.addAttr(type, "name", "advance", false); - cr.addAttr(uuid, "value", theUuid, true); - cr.addAttr(hash, "value", theHash, true); - cr.addAttr(target, "name", theTarget, true); - - action.appendChild(type); - action.appendChild(uuid); - action.appendChild(hash); - action.appendChild(target); - - doc.appendChild(action); - - return doc; - } - - - /** - * This method creates a new document that is used to create new artifact - * collections in the artifact server. - * - * @param name <b>Optional</b> name of the collection. - * - * @return the document to create new collections. - */ - public static Document newCreateCollectionDocument(String name) { - Document doc = XMLUtils.newDocument(); - - XMLUtils.ElementCreator cr = new XMLUtils.ElementCreator( - doc, - ArtifactNamespaceContext.NAMESPACE_URI, - ArtifactNamespaceContext.NAMESPACE_PREFIX); - - Element action = cr.create("action"); - Element type = cr.create("type"); - Element collection = cr.create("collection"); - Element attribute = cr.create("attribute"); - - cr.addAttr(type, "name", "create"); - cr.addAttr(collection, "name", name != null ? name : ""); - - action.appendChild(type); - type.appendChild(collection); - collection.appendChild(attribute); - - doc.appendChild(action); - - return doc; - } - - - /** - * This method creates a new Document that is used to add an artifact to a - * collection in the artifact server. - * - * @param artId The identifier of the artifact that should be added. - * @param attr A document that contains attributes for the artifact's - * life in the collection. - * - * @return the document to add an artifact into a collection. - */ - public static Document newAddArtifactDocument(String artId, Document attr) { - Document doc = XMLUtils.newDocument(); - - XMLUtils.ElementCreator cr = new XMLUtils.ElementCreator( - doc, - ArtifactNamespaceContext.NAMESPACE_URI, - ArtifactNamespaceContext.NAMESPACE_PREFIX); - - Element action = cr.create("action"); - Element type = cr.create("type"); - Element artifact = cr.create("artifact"); - Element attribute = cr.create("attribute"); - - cr.addAttr(artifact, "uuid", artId); - cr.addAttr(type, "name", "addartifact"); - - if (attr != null) { - attr.appendChild(attr); - } - - action.appendChild(type); - type.appendChild(artifact); - artifact.appendChild(attribute); - - doc.appendChild(action); - - return doc; - } - - - /** - * Create a new Document that is used to remove an artifact from a - * collection in the artifact server. - * - * @param artId The identifier of the artifact that should be added. - * - * @return the document to add an artifact into a collection. - */ - public static Document newRemoveArtifactDocument(String artId) { - Document doc = XMLUtils.newDocument(); - - XMLUtils.ElementCreator cr = new XMLUtils.ElementCreator( - doc, - ArtifactNamespaceContext.NAMESPACE_URI, - ArtifactNamespaceContext.NAMESPACE_PREFIX); - - Element action = cr.create("action"); - Element type = cr.create("type"); - Element artifact = cr.create("artifact"); - - cr.addAttr(artifact, "uuid", artId); - cr.addAttr(type, "name", "removeartifact"); - - action.appendChild(type); - type.appendChild(artifact); - - doc.appendChild(action); - - return doc; - } - - - /** - * This method creates a new Document that is used to trigger the DESCRIBE - * operation of a collection in the artifact server. - * - * @param uuid The identifier of the collection that should be described. - * - * @return the document to describe a collection. - */ - public static Document newDescribeCollectionDocument(String uuid) { - Document doc = XMLUtils.newDocument(); - - XMLUtils.ElementCreator cr = new XMLUtils.ElementCreator( - doc, - ArtifactNamespaceContext.NAMESPACE_URI, - ArtifactNamespaceContext.NAMESPACE_PREFIX); - - Element action = cr.create("action"); - Element type = cr.create("type"); - cr.addAttr(type, "name", "describe"); - - action.appendChild(type); - - doc.appendChild(action); - - return doc; - } - - - - /** - * This function builds a document that is used as request document of the - * out() operation of Collections. - * - * @param uuid The identifier of the collection. - * @param mode The name of the desired output mode. - * @param type The name of the desired output type. - * - * @return the request document. - */ - public static Document newOutCollectionDocument( - String uuid, - String mode, - String type) { - return newOutCollectionDocument(uuid, mode, type, null); - } - - - /** - * This function builds a document that is used as request document of the - * out() operation of Collections. The document <i>attr</i> might be used to - * adjust some settings specific to the output. - * - * @param uuid The identifier of the collection. - * @param mode The name of the desired output mode. - * @param type The name of the desired output type. - * @param attr A document that contains settings specific to the output. - * - * @return the request document. - */ - public static Document newOutCollectionDocument( - String uuid, - String mode, - String type, - Document attr) - { - Document doc = XMLUtils.newDocument(); - - XMLUtils.ElementCreator cr = new XMLUtils.ElementCreator( - doc, - ArtifactNamespaceContext.NAMESPACE_URI, - ArtifactNamespaceContext.NAMESPACE_PREFIX); - - Element action = cr.create("action"); - - cr.addAttr(action, "name", mode, true); - cr.addAttr(action, "type", type, true); - - doc.appendChild(action); - - if (attr != null) { - Node root = attr.getFirstChild(); - - if (root != null) { - action.appendChild(doc.importNode(root, true)); - } - } - - return doc; - } - - - /** - * This function creates a document that is used to set the attribute of a - * Collection. - * - * @param uuid The identifier of the Collection. - * @param attr The new attribute value for the Collection. - * - * @return the document that is used to set the attribute. - */ - public static Document newSetAttributeDocument( - String uuid, - Document attr) - { - Node root = attr != null ? attr.getFirstChild() : null; - - if (root == null) { - return null; - } - - Document doc = XMLUtils.newDocument(); - - XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator( - doc, - ArtifactNamespaceContext.NAMESPACE_URI, - ArtifactNamespaceContext.NAMESPACE_PREFIX); - - Element action = ec.create("action"); - Element type = ec.create("type"); - Element collection = ec.create("collection"); - - ec.addAttr(type, "name", "setattribute", false); - ec.addAttr(collection, "uuid", uuid, false); - - doc.appendChild(action); - action.appendChild(type); - type.appendChild(collection); - - collection.appendChild(doc.importNode(root, true)); - - return doc; - } - - /** - * This function creates a document that is used to set the attribute of a - * CollectionItem. - * - * @param uuid The identifier of the CollectionItem. - * @param attr The new attribute value for the CollectionItem. - * - * @return the document that is used to set the attribute. - */ - public static Document newSetItemAttributeDocument( - String uuid, - Document attr) - { - Node root = attr.getFirstChild(); - - if (root == null) { - return null; - } - - Document doc = XMLUtils.newDocument(); - - XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator( - doc, - ArtifactNamespaceContext.NAMESPACE_URI, - ArtifactNamespaceContext.NAMESPACE_PREFIX); - - Element action = ec.create("action"); - Element type = ec.create("type"); - Element artifact = ec.create("artifact"); - - ec.addAttr(type, "name", "setitemattribute"); - ec.addAttr(artifact, "uuid", uuid); - - doc.appendChild(action); - action.appendChild(type); - type.appendChild(artifact); - - artifact.appendChild(doc.importNode(root, true)); - - return doc; - } - - - /** - * This function creates a document that is used to set the time-to-live - * of a collection. - * - * @param ttl The ttl for the Collection. - * - * @return the document that is used to set the time-to-live. - */ - public static Document newSetCollectionTTLDocument(String ttl) { - Document doc = XMLUtils.newDocument(); - - XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator( - doc, - ArtifactNamespaceContext.NAMESPACE_URI, - ArtifactNamespaceContext.NAMESPACE_PREFIX); - - Element action = ec.create("action"); - Element type = ec.create("type"); - Element ttlEl = ec.create("ttl"); - - ec.addAttr(type, "name", "settimetolive"); - ec.addAttr(ttlEl, "value", ttl); - - doc.appendChild(action); - action.appendChild(type); - type.appendChild(ttlEl); - - return doc; - } - - - /** - * This function creates a document that is used to set the name of a - * collection. - * - * @param name The name for the Collection. - * - * @return the document that is used to set the name of a collection. - */ - public static Document newSetCollectionNameDocument(String name) { - Document doc = XMLUtils.newDocument(); - - XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator( - doc, - ArtifactNamespaceContext.NAMESPACE_URI, - ArtifactNamespaceContext.NAMESPACE_PREFIX); - - Element action = ec.create("action"); - Element type = ec.create("type"); - Element coll = ec.create("collection"); - - ec.addAttr(type, "name", "setname"); - ec.addAttr(coll, "name", name); - - doc.appendChild(action); - action.appendChild(type); - type.appendChild(coll); - - return doc; - } - - - /** - * This function creates a document that is used to delete an existing - * collection. - * - * @return the document that is used to delete an existing collection. - */ - public static Document newDeleteCollectionDocument() { - Document doc = XMLUtils.newDocument(); - - XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator( - doc, - ArtifactNamespaceContext.NAMESPACE_URI, - ArtifactNamespaceContext.NAMESPACE_PREFIX); - - Element action = ec.create("action"); - Element type = ec.create("type"); - - ec.addAttr(type, "name", "delete"); - - doc.appendChild(action); - action.appendChild(type); - - return doc; - } - - - /** - * Returns string value found by {@link XPATH_LABEL} relative to - * <i>node</i>. - * - * @param node A node. - * - * @return the string value found by {@link XPATH_LABEL}. - */ - public static String getLabel(Node node) { - return (String) XMLUtils.xpath( - node, - XPATH_LABEL, - XPathConstants.STRING, - ArtifactNamespaceContext.INSTANCE); - } - - - /** - * Returns string value found by {@link XPATH_VALUE} relative to - * <i>node</i>. - * - * @param node A node. - * - * @return the string value found by {@link XPATH_VALUE}. - */ - public static String getValue(Node node) { - return (String) XMLUtils.xpath( - node, - XPATH_VALUE, - XPathConstants.STRING, - ArtifactNamespaceContext.INSTANCE); - } - - - /** - * This method returns the static UI part of the artifact's DESCRIBE - * document. - * - * @param description The document returned by the artifact server's - * DESCRIBE operation. - * - * @return the static UI node. - */ - public static Node getStaticUI(Document description) { - return (Node) XMLUtils.xpath( - description, - XPATH_STATIC, - XPathConstants.NODE, - ArtifactNamespaceContext.INSTANCE); - } - - - /** - * This method returns the dynamic UI part of the artifact's DESCRIBE - * document. - * - * @param description The document returned by the artifact server's - * DESCRIBE operation. - * - * @return the dynamic UI node. - */ - public static Node getDynamicUI(Document description) { - return (Node) XMLUtils.xpath( - description, - XPATH_DYNAMIC, - XPathConstants.NODE, - ArtifactNamespaceContext.INSTANCE); - } - - - /** - * This method returns the current state node contained in the DESCRIBE - * document. - * - * @param description The document returned by the artifact server's - * DESCRIBE operation. - * - * @return the node containing information about the current state. - */ - public static Node getCurrentState(Document description) { - return (Node) XMLUtils.xpath( - description, - XPATH_CURRENT_STATE, - XPathConstants.NODE, - ArtifactNamespaceContext.INSTANCE); - } - - - /** - * This method returns the node that contains information about the - * reachable states of the artifact in the artifact's DESCRIBE document. - * - * @param description The document returned by the artifact server's - * DESCRIBE operation. - * - * @return the node that contains the reachable states. - */ - public static Node getReachableStates(Document description) { - return (Node) XMLUtils.xpath( - description, - XPATH_STATES, - XPathConstants.NODE, - ArtifactNamespaceContext.INSTANCE); - } - - - /** - * This method returns the output mode nodes of the DESCRIBE document. - * - * @param description The document returned by the artifact server's - * DESCRIBE operation. - * - * @return the node that contains the output modes. - */ - public static NodeList getOutputModes(Document description) { - return (NodeList) XMLUtils.xpath( - description, - XPATH_OUTPUT_MODES, - XPathConstants.NODESET, - ArtifactNamespaceContext.INSTANCE); - } - - - /** - * Returns the node found by {@link XPATH_DATA_SELECT}. - * - * @param dynamicNode The dynamic UI node of the DESCRIBE document. - * - * @return the select node found in the dynamic UI node. - */ - public static NodeList getSelectNode(Node dynamicNode) { - return (NodeList) XMLUtils.xpath( - dynamicNode, - XPATH_DATA_SELECT, - XPathConstants.NODESET, - ArtifactNamespaceContext.INSTANCE); - } - - - /** - * Returns the items that could be found in the <i>node</i>. - * - * @param node A select node. - * - * @return the choices nodes as node list. - */ - public static NodeList getItemNodes(Node node) { - return (NodeList) XMLUtils.xpath( - node, - XPATH_DATA_ITEMS, - XPathConstants.NODESET, - ArtifactNamespaceContext.INSTANCE); - } - - - public static String getMinNode(Node parent) { - return (String) XMLUtils.xpath( - parent, - XPATH_MIN_NODE, - XPathConstants.STRING, - ArtifactNamespaceContext.INSTANCE); - } - - - public static String getMaxNode(Node parent) { - return (String) XMLUtils.xpath( - parent, - XPATH_MAX_NODE, - XPathConstants.STRING, - ArtifactNamespaceContext.INSTANCE); - } - - - public static String getDefMin(Node parent) { - return (String) XMLUtils.xpath( - parent, - XPATH_DEF_MIN, - XPathConstants.STRING, - ArtifactNamespaceContext.INSTANCE); - } - - - public static String getDefMax(Node parent) { - return (String) XMLUtils.xpath( - parent, - XPATH_DEF_MAX, - XPathConstants.STRING, - ArtifactNamespaceContext.INSTANCE); - } -} -// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/artifacts-common/src/main/java/de/intevation/artifacts/common/utils/Config.java Thu Apr 25 10:50:31 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,276 +0,0 @@ -/* - * Copyright (c) 2010 by Intevation GmbH - * - * This program is free software under the LGPL (>=v2.1) - * Read the file LGPL.txt coming with the software for details - * or visit http://www.gnu.org/licenses/ if it does not exist. - */ - -package de.intevation.artifacts.common.utils; - -import java.io.File; -import java.io.IOException; - -import javax.xml.namespace.QName; - -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; - -import javax.xml.xpath.XPathConstants; - -import org.apache.log4j.Logger; - -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -import org.xml.sax.SAXException; - -/** - * The central access to the configuration of the artifact database. - * This class provides some static methods to access the central - * configuration XML file via XPath. - * - * @author <a href="mailto:sascha.teichmann@intevation.de">Sascha L. Teichmann</a> - */ -public final class Config -{ - private static Logger logger = Logger.getLogger(Config.class); - - /** - * System property name where to find the configuration directory. - */ - public static final String CONFIG_DIR = "artifact.database.dir"; - - /** - * Default path to the configuration directory if none - * was specified by the CONFIG_DIR system property. - */ - public static final File CONFIG_DIR_DEFAULT = - new File(new File(System.getProperty("user.home", - System.getProperty("user.dir", "."))), ".artifactdb"); - - /** - * Name of the central configuration XML file. - */ - public static final String CONFIG_FILE = "conf.xml"; - - /** - * Name of the configuration filename alias to be use - * within the configuration. This alias is replaced by - * the real path. - */ - public static final String CONFIG_DIR_PLACEHOLDER = - "${artifacts.config.dir}"; - - private static Document config; - - private Config() { - } - - /** - * Singleton access to the central XML configuration document. - * @return The central XML configuration document. - */ - public static synchronized final Document getConfig() { - if (config == null) { - config = loadConfig(); - } - return config; - } - - /** - * Returns the path to the configuartion directory. If a path - * was specified via the CONFIG_DIR system property this one - * is used. Else it falls back to default configuration path. - * @return The path to the configuartion directory. - */ - public static File getConfigDirectory() { - String configDirString = System.getProperty(CONFIG_DIR); - - File configDir = configDirString != null - ? new File(configDirString) - : CONFIG_DIR_DEFAULT; - - if (!configDir.isDirectory()) { - logger.warn("'" + configDir + "' is not a directory."); - configDir = CONFIG_DIR_DEFAULT; - } - - return configDir; - } - - /** - * Replaces the CONFIG_DIR_PLACEHOLDER alias with the real path - * of the configuration directory. - * @param path The path containing the CONFIG_DIR_PLACEHOLDER placeholder. - * @return The path where the CONFIG_DIR_PLACEHOLDER placeholders are - * replaced by the real path name. - */ - public static String replaceConfigDir(String path) { - String configDir = getConfigDirectory().getAbsolutePath(); - return path.replace(CONFIG_DIR_PLACEHOLDER, configDir); - } - - private static Document loadConfig() { - - File configDir = getConfigDirectory(); - - File file = new File(configDir, CONFIG_FILE); - - if (!file.canRead() && !file.isFile()) { - logger.error("Cannot read config file '" - + file + "'."); - return null; - } - - try { - DocumentBuilderFactory factory = - DocumentBuilderFactory.newInstance(); - factory.setValidating(false); // XXX: This may change in future. - return factory.newDocumentBuilder().parse(file); - } - catch (SAXException se) { - logger.error(se.getLocalizedMessage(), se); - } - catch (ParserConfigurationException pce) { - logger.error(pce.getLocalizedMessage(), pce); - } - catch (IOException ioe) { - logger.error(ioe.getLocalizedMessage()); - } - - return null; - } - - /** - * Convenience method to search within a given document tree via XPath. - * See {@link XMLUtils#xpath(Object, String, QName) } for details. - * @param root The object which is used as the root of the tree to - * be searched in. - * @param query The XPath query. - * @param returnType The type of the result. - * @return The result of type 'returnTyp' or null if something went - * wrong during XPath evaluation. - */ - public static final Object getXPath( - Object root, String query, QName returnType - ) { - return XMLUtils.xpath(root, query, returnType); - } - - /** - * Convenience method to search within the central configuration via XPath. - * See {@link XMLUtils#xpath(Object, String, QName) } for details. - * @param query The XPath query. - * @param returnType The type of the result. - * @return The result of type 'returnTyp' or null if something went - * wrong during XPath evaluation. - */ - public static final Object getXPath(String query, QName returnType) { - return XMLUtils.xpath(getConfig(), query, returnType); - } - - /** - * Convenience method to search for a node list within the central - * configuation document via XPath. - * @param query The XPath query. - * @return The queried node list or null if something went - * wrong during XPath evaluation. - */ - public static final NodeList getNodeSetXPath(String query) { - return (NodeList)getXPath(query, XPathConstants.NODESET); - } - - /** - * Convenience method to search for a node within the central - * configuation document via XPath. - * @param query The XPath query. - * @return The queried node or null if something went - * wrong during XPath evaluation. - */ - public static final Node getNodeXPath(String query) { - return (Node)getXPath(query, XPathConstants.NODE); - } - - /** - * Convenience method to search for a string within the central - * configuation document via XPath. - * @param xpath The XPath query. - * @return The queried string or null if something went - * wrong during XPath evaluation. - */ - public static final String getStringXPath(String xpath) { - return getStringXPath(xpath, null); - } - - /** - * Convenience method to search for a string within the central - * configuation document via XPath. - * @param query The XPath query. - * @param def The string to be returned if the search has no results. - * @return The queried string or the default value if something went - * wrong during XPath evaluation. - */ - public static final String getStringXPath(String query, String def) { - String s = (String)getXPath(query, XPathConstants.STRING); - return s == null || s.length() == 0 - ? def - : s; - } - - /** - * Convenience method to search for a node list within a given tree - * via XPath. - * @param root The root of the tree to be searched in. - * @param query The XPath query. - * @return The queried node list or null if something went - * wrong during XPath evaluation. - */ - public static final NodeList getNodeSetXPath(Object root, String query) { - return (NodeList)getXPath(root, query, XPathConstants.NODESET); - } - - /** - * Convenience method to search for a node within a given tree - * via XPath. - * @param root The root of the tree to be searched in. - * @param query The XPath query. - * @return The queried node or null if something went - * wrong during XPath evaluation. - */ - public static final Node getNodeXPath(Object root, String query) { - return (Node)getXPath(root, query, XPathConstants.NODE); - } - - /** - * Convenience method to search for a string within a given tree - * via XPath. - * @param root The root of the tree to be searched in. - * @param xpath The XPath query. - * @return The queried string or null if something went - * wrong during XPath evaluation. - */ - public static final String getStringXPath(Object root, String xpath) { - return getStringXPath(root, xpath, null); - } - - /** - * Convenience method to search for a string within a given tree - * via XPath. - * @param root The root of the tree to be searched in. - * @param query xpath The XPath query. - * @param def The string to be returned if the search has no results. - * @return The queried string or the default value if something went - * wrong during XPath evaluation. - */ - public static final String getStringXPath( - Object root, String query, String def - ) { - String s = (String)getXPath(root, query, XPathConstants.STRING); - return s == null || s.length() == 0 - ? def - : s; - } -} -// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/artifacts-common/src/main/java/de/intevation/artifacts/common/utils/CreationFilter.java Thu Apr 25 10:50:31 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +0,0 @@ -package de.intevation.artifacts.common.utils; - -import java.util.List; -import java.util.Map; -import java.util.HashMap; - -import org.w3c.dom.Element; - -public class CreationFilter -{ - public static class Facet { - - protected String name; - protected String index; - - public Facet() { - } - - public Facet(String name, String index) { - this.name = name; - this.index = index; - } - - public String getName() { - return name; - } - - public String getIndex() { - return index; - } - } - - protected Map<String, List<Facet>> outs; - - public CreationFilter() { - outs = new HashMap<String, List<Facet>>(); - } - - public void add(String out, List<Facet> facets) { - outs.put(out, facets); - } - - public Element toXML(XMLUtils.ElementCreator ec) { - Element filter = ec.create("filter"); - - for (Map.Entry<String, List<Facet>> entry: outs.entrySet()) { - Element out = ec.create("out"); - out.setAttribute("name", entry.getKey()); - for (Facet facet: entry.getValue()) { - Element f = ec.create("facet"); - f.setAttribute("name", facet.getName()); - f.setAttribute("index", facet.getIndex()); - out.appendChild(f); - } - filter.appendChild(out); - } - - return filter; - } -} -// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/artifacts-common/src/main/java/de/intevation/artifacts/common/utils/DateUtils.java Thu Apr 25 10:50:31 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +0,0 @@ -package de.intevation.artifacts.common.utils; - -import java.util.Calendar; -import java.util.Date; - - -public class DateUtils { - - private DateUtils() { - } - - - /** - * This function extracts the year as int value from <i>date</i>. - * - * @param date The source date. - * - * @return the year as integer or -1 if date is empty. - */ - public static int getYearFromDate(Date date) { - if (date == null) { - return -1; - } - - Calendar cal = Calendar.getInstance(); - cal.setTime(date); - - return cal.get(Calendar.YEAR); - } -}
--- a/artifacts-common/src/main/java/de/intevation/artifacts/common/utils/FileTools.java Thu Apr 25 10:50:31 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,613 +0,0 @@ -/* - * Copyright (c) 2010, 2011 by Intevation GmbH - * - * This program is free software under the LGPL (>=v2.1) - * Read the file LGPL.txt coming with the software for details - * or visit http://www.gnu.org/licenses/ if it does not exist. - */ -package de.intevation.artifacts.common.utils; - -import java.io.BufferedInputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.OutputStream; -import java.io.BufferedOutputStream; -import java.nio.channels.FileChannel; - -import java.util.Deque; -import java.util.ArrayDeque; -import java.util.List; -import java.util.Set; -import java.util.HashSet; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.zip.ZipFile; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; - -import org.apache.log4j.Logger; - -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; - -public class FileTools -{ - private static Logger log = Logger.getLogger(FileTools.class); - - public static final String DIGEST = - System.getProperty("artifacts.common.file.cmp.digest", "MD5"); - - private FileTools() { - } - - - /** Remove everything after dot from name. */ - public static final String removeExtension(String name) { - int index = name.lastIndexOf('.'); - return index == -1 - ? name - : name.substring(0, index); - } - - - public static File getDirectory(String path, String name) { - if (path == null || name == null) { - return null; - } - - File dir = new File(path, name); - - if (!dir.exists()) { - log.debug( - "Directory '" + dir.getAbsolutePath() + "' doesn't " + - "exist. Try to create it."); - - return dir.mkdir() ? dir : null; - } - else { - return dir.isDirectory() ? dir : null; - } - } - - public static File repair(File file) { - file = file.getAbsoluteFile(); - if (file.exists()) { - return file; - } - Deque<String> parts = new ArrayDeque<String>(); - File curr = file; - while (curr != null) { - String name = curr.getName(); - if (name.length() > 0) { - parts.push(curr.getName()); - } - curr = curr.getParentFile(); - } - - curr = null; - OUTER: while (!parts.isEmpty()) { - String f = parts.pop(); - log.debug("fixing: '" + f + "'"); - if (f.equals(".") || f.equals("..")) { - // No need to fix . or .. - continue; - } - if (curr == null) { - // XXX: Not totaly correct because there - // more than one root on none unix systems. - for (File root: File.listRoots()) { - File [] files = root.listFiles(); - if (files == null) { - log.warn("cannot list '" + root); - continue; - } - for (File candidate: files) { - if (candidate.getName().equalsIgnoreCase(f)) { - curr = new File(root, candidate.getName()); - continue OUTER; - } - } - } - break; - } - else { - File [] files = curr.listFiles(); - if (files == null) { - log.warn("cannot list: '" + curr + "'"); - return file; - } - for (File candidate: files) { - if (candidate.getName().equalsIgnoreCase(f)) { - curr = new File(curr, candidate.getName()); - continue OUTER; - } - } - curr = null; - break; - } - } - - if (curr == null) { - log.warn("cannot repair path '" + file + "'"); - return file; - } - - return curr; - } - - /** Object that can calculate hash of file, compare two hashed files etc. */ - public static class HashedFile - implements Comparable<HashedFile> - { - protected File file; - protected long length; - protected byte [] hash; - - public HashedFile(File file) { - this.file = file; - length = file.length(); - } - - public File getFile() { - return file; - } - - protected byte [] getHash() { - if (hash == null) { - InputStream in = null; - - try { - in = new FileInputStream(file); - - MessageDigest digest = MessageDigest.getInstance(DIGEST); - - byte [] buf = new byte[40*1024]; - int r; - - while ((r = in.read(buf)) >= 0) { - digest.update(buf, 0, r); - } - - hash = digest.digest(); - } - catch (IOException ioe) { - log.error(ioe); - hash = new byte[0]; - } - catch (NoSuchAlgorithmException nsae) { - log.error(nsae); - hash = new byte[0]; - } - finally { - if (in != null) { - try { - in.close(); - } - catch (IOException ioe) { - log.error(ioe); - } - } - } - } - return hash; - } - - @Override - public int compareTo(HashedFile other) { - if (length < other.length) return -1; - if (length > other.length) return +1; - return compare(getHash(), other.getHash()); - } - - private static int compare(byte [] a, byte [] b) { - if (a.length < b.length) return -1; - if (a.length > b.length) return +1; - for (int i = 0; i < a.length; ++i) { - int x = a[i] & 0xff; - int y = b[i] & 0xff; - if (x < y) return -1; - if (x > y) return +1; - } - return 0; - } - - @Override - public boolean equals(Object other) { - return other instanceof HashedFile - && ((HashedFile)other).compareTo(this) == 0; - } - - @Override - public int hashCode() { - return (int)(length ^ (length >>> 32)); - } - } // class HashedFile - - public static List<File> uniqueFiles(List<File> files) { - - Set<HashedFile> set = new HashSet<HashedFile>(); - - for (File file: files) { - if (!set.add(new HashedFile(file))) { - log.warn("file '" + file + "' is a duplicate."); - } - } - - ArrayList<File> out = new ArrayList<File>(set.size()); - for (HashedFile hf: set) { - out.add(hf.file); - } - - return out; - } - - public interface FileVisitor { - boolean visit(File file); - } // Visitor - - public static void walkTree(File root, FileVisitor visitor) { - - Deque<File> stack = new ArrayDeque<File>(); - - stack.push(root); - - while (!stack.isEmpty()) { - File current = stack.pop(); - if (!visitor.visit(current)) break; - if (current.isDirectory()) { - File [] subs = current.listFiles(); - if (subs != null) { - for (File f: subs) { - stack.push(f); - } - } - } - } - } - - /** - * Deletes everything in a directory. - * - * @param dir The directory. - */ - public final static void deleteContent(File dir) { - if (dir == null || !dir.isDirectory()) { - return; - } - - File[] files = dir.listFiles(); - if (files != null) { - for (File file: files) { - deleteRecursive(file); - } - } - - return; - } - - /** - * Delete <i>file</i> and everything in <i>file</i> if it is a directory. - * - * @param file The file or directory. - * @return true, if deletion was successful - otherwise false. - */ - public final static boolean deleteRecursive(File file) { - - if (file == null) { - return false; - } - - if (file.isDirectory()) { - File [] files = file.listFiles(); - if (files != null) { - for (File sub: files) { - if (!deleteRecursive(sub)) { - return false; - } - } - } - } - - return file.delete(); - } - - /** - * Put the given file or directory into a zip archive. - * - * @param file The file or directory. - * @param outputStream The stream to write the archive to. - * @throws IOException if an error occured while zip creation or writing to - * output stream. - */ - public static void createZipArchive( - File file, - OutputStream outputStream - ) - throws IOException - { - ZipOutputStream out = new ZipOutputStream(outputStream); - - if (file.isFile()) { - copyFileToZip("", file, out); - } - else if (file.isDirectory()) { - - Deque<PrefixDir> stack = new ArrayDeque<PrefixDir>(); - stack.push(new PrefixDir(file.getName() + "/", file)); - - while (!stack.isEmpty()) { - PrefixDir pd = stack.pop(); - - ZipEntry dirEntry = new ZipEntry(pd.prefix); - out.putNextEntry(dirEntry); - out.closeEntry(); - - File [] files = pd.dir.listFiles(); - if (files != null) { - for (File sub: files) { - if (sub.isDirectory()) { - stack.push(new PrefixDir( - pd.prefix + sub.getName() + "/", - sub)); - } - else if (sub.isFile()) { - copyFileToZip(pd.prefix, sub, out); - } - } - } - } - } - - out.finish(); - } - - - public static void extractArchive(File archive, File destDir) - throws IOException { - if (!destDir.exists()) { - destDir.mkdir(); - } - - ZipFile zipFile = new ZipFile(archive); - try { - Enumeration<? extends ZipEntry> entries = zipFile.entries(); - - byte [] buffer = new byte[16384]; - - while (entries.hasMoreElements()) { - ZipEntry entry = entries.nextElement(); - - String entryFileName = entry.getName(); - - File dir = buildDirectoryHierarchyFor(entryFileName, destDir); - if (!dir.exists()) { - dir.mkdirs(); - } - - if (!entry.isDirectory()) { - BufferedInputStream bis = new BufferedInputStream( - zipFile.getInputStream(entry)); - try { - BufferedOutputStream bos = new BufferedOutputStream( - new FileOutputStream(new File(destDir, entryFileName))); - - try { - int len; - while ((len = bis.read(buffer)) > 0) { - bos.write(buffer, 0, len); - } - bos.flush(); - } - finally { - bos.close(); - } - } - finally { - bis.close(); - } - } // is file - } - } - finally { - zipFile.close(); - } - } - - private static File buildDirectoryHierarchyFor( - String entryName, - File destDir) - { - int lastIndex = entryName.lastIndexOf('/'); - String internalPathToEntry = entryName.substring(0, lastIndex + 1); - return new File(destDir, internalPathToEntry); - } - - /** - * A class representing a directory with a prefix. - */ - private static final class PrefixDir { - - String prefix; - File dir; - - public PrefixDir(String prefix, File dir) { - this.prefix = prefix; - this.dir = dir; - } - - } // class PrefixDir - - /** - * Write a file to zip archive. - * - * @param prefix A prefix. - * @param file The file. - * @param out The output stream. - * @throws IOException if an error occured while writing to zip output - * stream. - */ - private static void copyFileToZip( - String prefix, - File file, - ZipOutputStream out - ) - throws IOException - { - String entryName = prefix + file.getName(); - ZipEntry entry = new ZipEntry(entryName); - out.putNextEntry(entry); - InputStream in = null; - try { - in = - new BufferedInputStream( - new FileInputStream(file), 20*1024); - - byte [] buf = new byte[2048]; - - int r; - while ((r = in.read(buf)) > 0) { - out.write(buf, 0, r); - } - } - finally { - if (in != null) { - try { in.close(); } - catch (IOException ioe) {} - } - } - out.closeEntry(); - } - - - /** - * Copies a <i>src</i> file to <i>target</i>. - * - * @param src A file (not a directory) that should be copied. - * @param target The destination. This might be a file or a directory. - * - * @return true, if <i>src</i> has been successfully copied; otherwise - * false. - */ - public static boolean copyFile(File src, File target) - throws IOException - { - if (src == null || !src.exists()) { - log.warn("Source file does not exist!"); - return false; - } - - if (!src.canRead()) { - log.warn("Cannot read Source file!"); - return false; - } - - if (src.isDirectory()) { - log.warn("Source is a directory!"); - return false; - } - - if (target.isDirectory()) { - target = new File(target, src.getName()); - } - - FileInputStream in = null; - FileOutputStream out = null; - - try { - in = new FileInputStream(src); - out = new FileOutputStream(target); - - FileChannel inChannel = in.getChannel(); - FileChannel outChannel = out.getChannel(); - - inChannel.transferTo(0l, inChannel.size(), outChannel); - - return true; - } - catch (IOException ioe) { - log.warn(ioe, ioe); - } - finally { - if (in != null) { - try { - in.close(); - } - catch (IOException ioe) { /* do nothing here */ } - } - - if (out != null) { - try { - out.close(); - } - catch (IOException ioe) { /* do nothing here */ } - } - } - - return false; - } - - - /** - * Copies a directory <i>source</i> to a destination path <i>dest</i>. - * - * @param source A directory that should be copied. - * @param dest A destination directory which is created if it is not - * existing yet. - * - * @return true, if the directory has been successfully copied; otherwise - * false. - */ - public static boolean copyDirectory(final File source, final File dest) { - if (source == null || !source.exists()) { - log.warn("Source directory does not exist!"); - return false; - } - - if (!source.isDirectory()) { - log.warn("Source is not a directory!"); - return false; - } - - if (dest == null) { - log.warn("Destination directory is null!"); - return false; - } - - if (!dest.exists()) { - if (!dest.mkdir()) { - log.warn("Cannot create destination directory!"); - return false; - } - } - - File[] children = source.listFiles(); - int failed = 0; - - if (children != null && children.length > 0) { - for (File child: children) { - if (child.isFile()) { - try { - if (!copyFile(child, dest)) { - failed++; - } - } - catch (IOException ioe) { - log.warn(ioe, ioe); - failed++; - } - } - else if (child.isDirectory()) { - copyDirectory(child, new File(dest, child.getName())); - } - } - } - - log.debug("Failed to copy " + failed + " files."); - - return true; - } -} -// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/artifacts-common/src/main/java/de/intevation/artifacts/common/utils/JSON.java Thu Apr 25 10:50:31 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,445 +0,0 @@ -package de.intevation.artifacts.common.utils; - -import java.util.Map; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.ArrayList; -import java.util.Iterator; - -import java.io.IOException; -import java.io.PushbackInputStream; -import java.io.InputStream; -import java.io.PrintWriter; -import java.io.ByteArrayInputStream; -import java.io.StringWriter; - -import java.nio.charset.Charset; -import java.nio.charset.UnsupportedCharsetException; - -public final class JSON -{ - private JSON() { - } - - private static final boolean isDigit(int c) { - return c >= '0' && c <= '9'; - } - - public static final boolean isWhitespace(int c) { - return c == ' ' || c == '\n' || c == '\r' - || c == '\t' || c == '\f'; - } - - private static final void match(int c, int x) throws IOException { - if (c != x) { - throw new IOException( - "Expecting '" + (char)c + "' found '" + (char)x + "'"); - } - } - - private static final int eof(InputStream in) - throws IOException - { - int c = in.read(); - if (c == -1) { - throw new IOException("EOF unexpected."); - } - return c; - } - - private static final int whitespace(InputStream in) - throws IOException - { - int c; - while (isWhitespace(c = eof(in))); - return c; - } - - private static final int parseHex(String hex) throws IOException { - try { - return Integer.parseInt(hex, 16); - } - catch (NumberFormatException nfe) { - throw new IOException("'" + hex + "' is not a hex string."); - } - } - - public static final String jsonString(String string) { - StringBuilder sb = new StringBuilder(string.length()+2); - - sb.append('"'); - - for (int i = 0, N = string.length(); i < N; ++i) { - char c = string.charAt(i); - switch (c) { - case '"': sb.append("\\\""); break; - case '\t': sb.append("\\t"); break; - case '\r': sb.append("\\r"); break; - case '\n': sb.append("\\n"); break; - case '\b': sb.append("\\b"); break; - case '\f': sb.append("\\f"); break; - default: - if (c >= 128) { - sb.append("\\u"); - String hex = Integer.toHexString((int)c); - for (int j = 4-hex.length(); j > 0; --j) { - sb.append('0'); - } - sb.append(hex); - } - else { - sb.append(c); - } - } - } - - sb.append('"'); - - return sb.toString(); - } - - public static String toJSONString(Map<String, Object> map) { - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - write(pw, map); - pw.flush(); - return sw.toString(); - } - - - public static void write(PrintWriter out, Map<String, Object> map) { - writeObject(out, map); - } - - private static void writeValue(PrintWriter out, Object value) { - if (value instanceof Map) { - writeObject(out, (Map)value); - } - else if (value instanceof List) { - writeList(out, (List)value); - } - else if (value instanceof Number) { - out.print(value); - } - else if (value instanceof Boolean) { - out.print(((Boolean)value) ? "true" : "false"); - } - else if (value == null) { - out.print("null"); - } - else { - out.print(jsonString(value.toString())); - } - } - - private static void writeObject(PrintWriter out, Map map) { - - out.print('{'); - Iterator iter = map.entrySet().iterator(); - while (iter.hasNext()) { - Map.Entry entry = (Map.Entry)iter.next(); - out.print(jsonString(entry.getKey().toString())); - out.print(':'); - writeValue(out, entry.getValue()); - if (iter.hasNext()) { - out.print(','); - } - } - out.print('}'); - } - - private static void writeList(PrintWriter out, List list) { - out.print('['); - Iterator iter = list.iterator(); - while (iter.hasNext()) { - writeValue(out, iter.next()); - if (iter.hasNext()) { - out.print(','); - } - } - out.print(']'); - } - - public static Map<String, Object> parse(String in) - throws IOException - { - return parse(asInputStream(in)); - } - - private static InputStream asInputStream(String in) { - byte [] bytes; - try { - bytes = in.getBytes(Charset.forName("US-ASCII")); - } - catch (UnsupportedCharsetException uce) { - // Should not happen. - bytes = in.getBytes(); - } - return new ByteArrayInputStream(bytes); - } - - public static Map<String, Object> parse(InputStream in) - throws IOException - { - return parseObject(new PushbackInputStream(in, 1)); - } - - public static Map<String, Object> parse(PushbackInputStream in) - throws IOException - { - return parseObject(in); - } - - private static final String parseString( - PushbackInputStream in - ) - throws IOException - { - StringBuilder sb = new StringBuilder(); - - int mode = 0; - - char [] hex = new char[4]; - - match('"', eof(in)); - - OUT: for (int c = eof(in);; c = eof(in)) { - - switch (mode) { - case 0: - if (c == '"') { - break OUT; - } - if (c == '\\') { - mode = 1; - } - else { - sb.append((char)c); - } - break; - case 1: - switch (c) { - case 'u': - mode = 2; - continue; - case 'b': - sb.append('\b'); - break; - case 'f': - sb.append('\f'); - break; - case 'n': - sb.append('\n'); - break; - case 'r': - sb.append('\r'); - break; - case 't': - sb.append('\t'); - break; - default: - sb.append((char)c); - } - mode = 0; - break; - case 2: - hex[0] = (char)c; - mode = 3; - break; - case 3: - hex[1] = (char)c; - mode = 4; - break; - case 4: - hex[2] = (char)c; - mode = 5; - break; - case 5: - hex[3] = (char)c; - sb.append((char)parseHex(new String(hex))); - mode = 0; - break; - } - } - return sb.toString(); - } - - private static final Boolean parseTrue(InputStream in) - throws IOException - { - match('t', eof(in)); - match('r', eof(in)); - match('u', eof(in)); - match('e', eof(in)); - return Boolean.TRUE; - } - - private static final Boolean parseFalse(InputStream in) - throws IOException - { - match('f', eof(in)); - match('a', eof(in)); - match('l', eof(in)); - match('s', eof(in)); - match('e', eof(in)); - return Boolean.FALSE; - } - - private static final Object parseNull(InputStream in) - throws IOException - { - match('n', eof(in)); - match('u', eof(in)); - match('l', eof(in)); - match('l', eof(in)); - return null; - } - - private static final Number parseNumber(PushbackInputStream in) - throws IOException - { - StringBuilder sb = new StringBuilder(); - - boolean isInteger = true; - - int c; - OUT: for (;;) { - switch (c = eof(in)) { - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - case '-': case '+': - sb.append((char)c); - break; - case '.': case 'e': case 'E': - isInteger = false; - sb.append((char)c); - break; - default: - in.unread(c); - break OUT; - } - } - - try { - if (isInteger) { - return sb.length() > 9 - ? (Number)Long .valueOf(sb.toString()) - : (Number)Integer.valueOf(sb.toString()); - } - return (Number)Double.valueOf(sb.toString()); - } - catch (NumberFormatException nfe) { - throw new IOException("Not a number '" + sb + "'"); - } - } - - private static List<Object> parseList(PushbackInputStream in) - throws IOException - { - List<Object> list = new ArrayList<Object>(); - match('[', whitespace(in)); - int c = whitespace(in); - if (c == ']') { - return list; - } - - for (;; c = whitespace(in)) { - Object value; - in.unread(c); - switch (c) { - case '{': - value = parseObject(in); - break; - case '[': - value = parseList(in); - break; - case '"': - value = parseString(in); - break; - case 't': - value = parseTrue(in); - break; - case 'f': - value = parseFalse(in); - break; - case 'n': - value = parseNull(in); - break; - default: - value = parseNumber(in); - } - list.add(value); - - if ((c = whitespace(in)) == ']') break; - match(',', c); - } - return list; - } - - private static void parsePair( - PushbackInputStream in, - Map<String, Object> pairs - ) - throws IOException - { - in.unread(whitespace(in)); - String string = parseString(in); - match(':', whitespace(in)); - - Object value; - - int c = whitespace(in); - in.unread(c); - switch (c) { - case '{': - value = parseObject(in); - break; - case '[': - value = parseList(in); - break; - case '"': - value = parseString(in); - break; - case 't': - value = parseTrue(in); - break; - case 'f': - value = parseFalse(in); - break; - case 'n': - value = parseNull(in); - break; - default: - value = parseNumber(in); - } - pairs.put(string, value); - } - - private static Map<String, Object> parseObject(PushbackInputStream in) - throws IOException - { - Map<String, Object> pairs = new LinkedHashMap<String, Object>(); - - int c = whitespace(in); - match('{', c); - - if ((c = whitespace(in)) == '}') { - return pairs; - } - - in.unread(c); - - for (;;) { - parsePair(in, pairs); - - if ((c = whitespace(in)) == '}') { - break; - } - - if (c == '}') break; - match(',', c); - } - - return pairs; - } -}
--- a/artifacts-common/src/main/java/de/intevation/artifacts/common/utils/LRUCache.java Thu Apr 25 10:50:31 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,26 +0,0 @@ -package de.intevation.artifacts.common.utils; - -import java.util.Map; -import java.util.LinkedHashMap; - -public class LRUCache<K, V> -extends LinkedHashMap<K, V> -{ - public static final int DEFAULT_MAX_CAPACITY = 25; - - private int maxCapacity; - - public LRUCache() { - this(DEFAULT_MAX_CAPACITY); - } - - public LRUCache(int maxCapacity) { - this.maxCapacity = maxCapacity; - } - - @Override - protected boolean removeEldestEntry(Map.Entry<K, V> eldest) { - return size() > maxCapacity; - } -} -// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/artifacts-common/src/main/java/de/intevation/artifacts/common/utils/MapXPathVariableResolver.java Thu Apr 25 10:50:31 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2011 by Intevation GmbH - * - * This program is free software under the LGPL (>=v2.1) - * Read the file LGPL.txt coming with the software for details - * or visit http://www.gnu.org/licenses/ if it does not exist. - */ -package de.intevation.artifacts.common.utils; - -import java.util.HashMap; -import java.util.Map; - -import javax.xml.namespace.QName; -import javax.xml.xpath.XPathVariableResolver; - - -/** - * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> - */ -public class MapXPathVariableResolver implements XPathVariableResolver { - - protected Map<String, String> variables; - - - public MapXPathVariableResolver() { - this.variables = new HashMap<String, String>(); - } - - - public MapXPathVariableResolver(Map<String, String> variables) { - this.variables = variables; - } - - - public void addVariable(String name, String value) { - if (name != null && value != null) { - variables.put(name, value); - } - } - - - @Override - public Object resolveVariable(QName variableName) { - String key = variableName.getLocalPart(); - return variables.get(key); - } -} -// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/artifacts-common/src/main/java/de/intevation/artifacts/common/utils/StringUtils.java Thu Apr 25 10:50:31 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2010 by Intevation GmbH - * - * This program is free software under the LGPL (>=v2.1) - * Read the file LGPL.txt coming with the software for details - * or visit http://www.gnu.org/licenses/ if it does not exist. - */ - -package de.intevation.artifacts.common.utils; - -import java.io.UnsupportedEncodingException; - -import java.util.UUID; - -import org.apache.commons.codec.DecoderException; - -import org.apache.commons.codec.binary.Hex; - -import org.apache.log4j.Logger; - -/** - * Commonly used string functions. - * - * @author <a href="mailto:sascha.teichmann@intevation.de">Sascha L. Teichmann</a> - */ -public final class StringUtils -{ - private static Logger logger = Logger.getLogger(StringUtils.class); - - /** - * Generated a random UUIDv4 in form of a string. - * @return the UUID - */ - public static final String newUUID() { - return UUID.randomUUID().toString(); - } - - /** - * Checks if a given string is a valid UUID. - * @param uuid The string to test. - * @return true if the string is a valid UUID else false. - */ - public static final boolean checkUUID(String uuid) { - try { - UUID.fromString(uuid); - } - catch (IllegalArgumentException iae) { - logger.warn(iae.getLocalizedMessage()); - return false; - } - return true; - } - - /** - * Returns the UTF-8 byte array representation of a given string. - * @param s The string to be transformed. - * @return The byte array representation. - */ - public static final byte [] getUTF8Bytes(String s) { - try { - return s.getBytes("UTF-8"); - } - catch (UnsupportedEncodingException usee) { - logger.error(usee.getLocalizedMessage(), usee); - return s.getBytes(); - } - } - - /** - * Tries to convert a Base64 encoded string into the - * corresponing byte array. - * @param s The Base64 encoded string - * @return The byte array representation or null if - * an decoding error occurs. - */ - public static final byte [] decodeHex(String s) { - try { - return Hex.decodeHex(s.toCharArray()); - } - catch (DecoderException de) { - return null; - } - } - - public static final String repeat(String s, int count, String sep) { - if (count <= 0) { - return ""; - } - StringBuilder sb = new StringBuilder(s); - for (--count; count > 0; --count) { - sb.append(sep).append(s); - } - return sb.toString(); - } - - public static final String repeat(char c, int count, char sep) { - if (count <= 0) { - return ""; - } - StringBuilder sb = new StringBuilder(2*count-1).append(c); - for (--count; count > 0; --count) { - sb.append(sep).append(c); - } - return sb.toString(); - } - - public static final String [] toUpperCase(String [] s) { - if (s == null) { - return null; - } - String [] d = new String[s.length]; - for (int i = 0; i < s.length; ++i) { - if (s[i] != null) { - d[i] = s[i].toUpperCase(); - } - } - return d; - } - - public static String join(String sep, String [] strings) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < strings.length; ++i) { - if (i > 0) sb.append(sep); - sb.append(strings[i]); - } - return sb.toString(); - } - - public static final String [] join(String [] a, String [] b) { - if (a == null && b == null) return null; - if (a == null) return b; - if (b == null) return a; - String [] dst = new String[a.length + b.length]; - System.arraycopy(a, 0, dst, 0, a.length); - System.arraycopy(b, 0, dst, a.length, b.length); - return dst; - } - - public static final boolean contains(String needle, String [] haystack) { - for (String stray: haystack) { - if (needle.equals(stray)) { - return true; - } - } - return false; - } -} -// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/artifacts-common/src/main/java/de/intevation/artifacts/common/utils/XMLUtils.java Thu Apr 25 10:50:31 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,617 +0,0 @@ -/* - * Copyright (c) 2010 by Intevation GmbH - * - * This program is free software under the LGPL (>=v2.1) - * Read the file LGPL.txt coming with the software for details - * or visit http://www.gnu.org/licenses/ if it does not exist. - */ - -package de.intevation.artifacts.common.utils; - -import java.util.List; -import java.util.ArrayList; -import java.util.Map; -import java.util.LinkedHashMap; -import java.util.zip.GZIPInputStream; -import java.util.zip.GZIPOutputStream; - -import java.io.ByteArrayInputStream; -import java.io.FileInputStream; -import java.io.BufferedInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.StringWriter; - -import javax.xml.namespace.NamespaceContext; -import javax.xml.namespace.QName; - -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; - -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.TransformerFactoryConfigurationError; - -import javax.xml.transform.dom.DOMSource; - -import javax.xml.transform.stream.StreamResult; - -import javax.xml.xpath.XPath; -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathExpressionException; -import javax.xml.xpath.XPathFactory; -import javax.xml.xpath.XPathVariableResolver; - -import org.apache.log4j.Logger; - -import org.w3c.dom.Attr; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; - -import org.xml.sax.SAXException; - -/** - * Some helper functions to ease work with XML concering namespaces, XPATH - * and so on. - * @author <a href="mailto:sascha.teichmann@intevation.de">Sascha L. Teichmann</a> - */ -public final class XMLUtils -{ - /** W3C URL of XForms. */ - public static final String XFORM_URL = "http://www.w3.org/2002/xforms"; - - /** W3C prefix of XForms. */ - public static final String XFORM_PREFIX = "xform"; - - /** Logger for this class. */ - private static Logger logger = Logger.getLogger(XMLUtils.class); - - private XMLUtils() { - } - - /** - * Helper class to generate elements and attributes with - * namespaces. - */ - public static class ElementCreator - { - /** Owner document of the elements to be created. */ - protected Document document; - - /** Namespace to be used. */ - protected String ns; - - /** Prefix to be used. */ - protected String prefix; - - /** - * Constructor to create an element/attribute creator - * with a given namespace and namespace prefix using a - * given owner document. - * @param document The owning document - * @param ns The namespace - * @param prefix The namespace prefix - */ - public ElementCreator(Document document, String ns, String prefix) { - this.document = document; - this.ns = ns; - this.prefix = prefix; - } - - /** - * Creates a new element using the owning document with - * the this creators namespace and namespace prefix. - * @param name The name of the element - * @return The new element - */ - public Element create(String name) { - Element element = document.createElementNS(ns, name); - element.setPrefix(prefix); - return element; - } - - /** - * Adds a new attribute and its value to a given element. - * It does not set the namespace prefix. - * @param element The element to add the attribute to - * @param name The name of the attribute - * @param value The value of the attribute - */ - public void addAttr(Element element, String name, String value) { - addAttr(element, name, value, false); - } - - /** - * Adds a new attribute and its value to a given element. - * If the namespace prefix is used is decided by the 'addPrefix' flag. - * @param element The element to add the attribute to - * @param name The name of the attribute - * @param value The value of the attribute - * @param addPrefix If true the creators namespace prefix is - * set on the attribute. - */ - public void addAttr( - Element element, - String name, - String value, - boolean addPrefix - ) { - if (addPrefix) { - Attr attr = document.createAttributeNS(ns, name); - attr.setValue(value); - attr.setPrefix(prefix); - - element.setAttributeNode(attr); - } - else { - element.setAttribute(name, value); - } - } - } // class ElementCreator - - /** - * Creates a new XML document - * @return the new XML document ot null if something went wrong during - * creation. - */ - public static final Document newDocument() { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - factory.setNamespaceAware(true); - - try { - return factory.newDocumentBuilder().newDocument(); - } - catch (ParserConfigurationException pce) { - logger.error(pce.getLocalizedMessage(), pce); - } - return null; - } - - - /** - * Create xml/string representation of element (nested in otherwise empty - * document). - * @param element element to inspect in string. - * @return string with xml representation of element. - */ - public final static String toString(Node node) { - Document doc = newDocument(); - doc.appendChild(doc.importNode(node,true)); - return toString(doc); - } - - - /** - * Loads a XML document namespace aware from a file - * @param file The file to load. - * @return the XML document or null if something went wrong - * during loading. - */ - public static final Document parseDocument(File file) { - InputStream inputStream = null; - try { - inputStream = new BufferedInputStream(new FileInputStream(file)); - return parseDocument(inputStream); - } - catch (IOException ioe) { - logger.error(ioe.getLocalizedMessage(), ioe); - } - finally { - if (inputStream != null) { - try { inputStream.close(); } - catch (IOException ioe) {} - } - } - return null; - } - - /** - * Parses a String to a xml document. - * - * @param string The xml string - * @return the XML document or null if something went wrong. - */ - public static final Document parseDocument(String string) { - InputStream inputStream = new ByteArrayInputStream(string.getBytes()); - return parseDocument(inputStream); - } - - - public static final Document parseDocument(InputStream inputStream) { - return parseDocument(inputStream, Boolean.TRUE); - } - - public static final Document parseDocument( - InputStream inputStream, - Boolean namespaceAware - ) { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - - if (namespaceAware != null) { - factory.setNamespaceAware(namespaceAware.booleanValue()); - } - - try { - return factory.newDocumentBuilder().parse(inputStream); - } - catch (ParserConfigurationException pce) { - logger.error(pce.getLocalizedMessage(), pce); - } - catch (SAXException se) { - logger.error(se.getLocalizedMessage(), se); - } - catch (IOException ioe) { - logger.error(ioe.getLocalizedMessage(), ioe); - } - return null; - } - - /** - * Creates a new XPath without a namespace context. - * @return the new XPath. - */ - public static final XPath newXPath() { - return newXPath(null, null); - } - - /** - * Creates a new XPath with a given namespace context. - * @param namespaceContext The namespace context to be used or null - * if none should be used. - * @return The new XPath - */ - public static final XPath newXPath( - NamespaceContext namespaceContext, - XPathVariableResolver resolver) - { - XPathFactory factory = XPathFactory.newInstance(); - XPath xpath = factory.newXPath(); - if (namespaceContext != null) { - xpath.setNamespaceContext(namespaceContext); - } - - if (resolver != null) { - xpath.setXPathVariableResolver(resolver); - } - return xpath; - } - - /** - * Evaluates an XPath query on a given object and returns the result - * as a given type. No namespace context is used. - * @param root The object which is used as the root of the tree to - * be searched in. - * @param query The XPath query - * @param returnTyp The type of the result. - * @return The result of type 'returnTyp' or null if something - * went wrong during XPath evaluation. - */ - public static final Object xpath( - Object root, - String query, - QName returnTyp - ) { - return xpath(root, query, returnTyp, null); - } - - /** - * Evaluates an XPath query on a given object and returns the result - * as a string. A given namespace context is used. - * @param root The object which is used as the root of the tree to - * be searched in. - * @param query The XPath query - * @param namespaceContext The namespace context to be used or null - * if none should be used. - * @return The result of the query or null if something went wrong - * during XPath evaluation. - */ - public static final String xpathString( - Object root, String query, NamespaceContext namespaceContext - ) { - return (String)xpath( - root, query, XPathConstants.STRING, namespaceContext); - } - - /** - * Evaluates an XPath query on a given object and returns the result - * as a given type. Optionally a namespace context is used. - * @param root The object which is used as the root of the tree to - * be searched in. - * @param query The XPath query - * @param returnType The type of the result. - * @param namespaceContext The namespace context to be used or null - * if none should be used. - * @return The result of type 'returnTyp' or null if something - * went wrong during XPath evaluation. - */ - public static final Object xpath( - Object root, - String query, - QName returnType, - NamespaceContext namespaceContext - ) { - return xpath(root, query, returnType, namespaceContext, null); - } - - public static final Object xpath( - Object root, - String query, - QName returnType, - NamespaceContext namespaceContext, - Map<String, String> variables) - { - if (root == null) { - return null; - } - - XPathVariableResolver resolver = variables != null - ? new MapXPathVariableResolver(variables) - : null; - - try { - XPath xpath = newXPath(namespaceContext, resolver); - if (xpath != null) { - return xpath.evaluate(query, root, returnType); - } - } - catch (XPathExpressionException xpee) { - logger.error(xpee.getLocalizedMessage(), xpee); - } - - return null; - } - - /** - * Streams out an XML document to a given output stream. - * @param document The document to be streamed out. - * @param out The output stream to be used. - * @return true if operation succeeded else false. - */ - public static boolean toStream(Document document, OutputStream out) { - try { - Transformer transformer = - TransformerFactory.newInstance().newTransformer(); - DOMSource source = new DOMSource(document); - StreamResult result = new StreamResult(out); - transformer.transform(source, result); - return true; - } - catch (TransformerConfigurationException tce) { - logger.error(tce.getLocalizedMessage(), tce); - } - catch (TransformerFactoryConfigurationError tfce) { - logger.error(tfce.getLocalizedMessage(), tfce); - } - catch (TransformerException te) { - logger.error(te.getLocalizedMessage(), te); - } - - return false; - } - - public static String toString(Document document) { - try { - Transformer transformer = - TransformerFactory.newInstance().newTransformer(); - DOMSource source = new DOMSource(document); - StringWriter out = new StringWriter(); - StreamResult result = new StreamResult(out); - transformer.transform(source, result); - out.flush(); - return out.toString(); - } - catch (TransformerConfigurationException tce) { - logger.error(tce.getLocalizedMessage(), tce); - } - catch (TransformerFactoryConfigurationError tfce) { - logger.error(tfce.getLocalizedMessage(), tfce); - } - catch (TransformerException te) { - logger.error(te.getLocalizedMessage(), te); - } - - return null; - } - - public static byte [] toByteArray(Document document) { - return toByteArray(document, false); - } - - /** - * Transforms an XML document into a byte array. - * @param document The document to be streamed out. - * @param compress The document should be compressed, too. - * @return the byte array or null if operation failed or - * document is null. - */ - public static byte [] toByteArray(Document document, boolean compress) { - if (document != null) { - try { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - OutputStream out = compress - ? new GZIPOutputStream(baos) - : baos; - boolean success = toStream(document, out); - out.flush(); - out.close(); - return success - ? baos.toByteArray() - : null; - } - catch (IOException ioe) { - logger.error(ioe); - } - } - return null; - } - - public static Document fromByteArray(byte [] data) { - return fromByteArray(data, false); - } - - public static Document fromByteArray(byte [] data, boolean decompress) { - if (data != null) { - InputStream in = new ByteArrayInputStream(data); - try { - if (decompress) { - in = new GZIPInputStream(in); - } - return parseDocument(in); - } - catch (IOException ioe) { - logger.error(ioe); - } - finally { - try { - in.close(); - } - catch (IOException ioe) { - logger.error(ioe); - } - } - } - return null; - } - - private static class BuildResult { - List<Node> children; - Map<String, String> attributes; - BuildResult() { - children = new ArrayList<Node>(); - attributes = new LinkedHashMap<String, String>(); - } - - void setAttributes(Element element) { - for (Map.Entry<String, String> entry: attributes.entrySet()) { - element.setAttribute(entry.getKey(), entry.getValue()); - } - } - - void finish(Element element) { - setAttributes(element); - for (Node child: children) { - element.appendChild(child); - } - } - - void add(Node node) { - children.add(node); - } - - void add(String key, Object value) { - attributes.put(key, value != null ? value.toString() : "null"); - } - - int numChildren() { - return children.size(); - } - - Node firstChild() { - return children.get(0); - } - } // class BuildResult - - private static BuildResult recursiveBuild( - List list, - Document document - ) { - BuildResult result = new BuildResult(); - for (Object entry: list) { - if (entry instanceof Map) { - BuildResult subResult = recursiveBuild( - (Map<String, Object>)entry, document); - if (subResult.numChildren() == 1) { - result.add(subResult.firstChild()); - } - else { - Element element = document.createElement("map"); - subResult.finish(element); - result.add(element); - } - } - else if (entry instanceof List) { - Element element = document.createElement("list"); - BuildResult subResult = recursiveBuild((List)entry, document); - subResult.finish(element); - result.add(element); - } - else { - Element element = document.createElement("entry"); - element.setAttribute( - "value", - entry != null ? entry.toString() : "null"); - } - } - return result; - } - - private static BuildResult recursiveBuild( - Map<String, Object> map, - Document document - ) { - BuildResult result = new BuildResult(); - - List<Node> nodes = new ArrayList<Node>(); - for (Map.Entry<String, Object> entry: map.entrySet()) { - Object value = entry.getValue(); - if (value instanceof Map) { - Element element = document.createElement(entry.getKey()); - BuildResult subResult = recursiveBuild( - (Map<String, Object>)value, document); - subResult.finish(element); - result.add(element); - } - else if (value instanceof List) { - Element element = document.createElement(entry.getKey()); - BuildResult subResult = recursiveBuild((List)value, document); - subResult.finish(element); - result.add(element); - } - else { - result.add(entry.getKey(), value); - } - } - return result; - } - - public static Document jsonToXML(String input) { - Document document = newDocument(); - - if (document == null) { - return null; - } - - Map<String, Object> map; - try { - map = JSON.parse(input); - } - catch (IOException ioe) { - logger.error(ioe); - return null; - } - - BuildResult roots = recursiveBuild(map, document); - - int N = roots.children.size(); - - if (N == 1) { - document.appendChild(roots.children.get(0)); - } - else if (N > 1) { - Node root = document.createElement("root"); - for (int i = 0; i < N; ++i) { - root.appendChild(roots.children.get(i)); - } - document.appendChild(root); - } - - return document; - } -} -// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/artifacts-common/src/main/java/de/intevation/artifacts/common/utils/XSLTransformer.java Thu Apr 25 10:50:31 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -package de.intevation.artifacts.common.utils; - -import java.io.InputStream; -import java.io.StringWriter; - -import java.util.HashMap; -import java.util.Map; - -import javax.xml.transform.Source; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; - -import javax.xml.transform.dom.DOMSource; - -import javax.xml.transform.stream.StreamResult; -import javax.xml.transform.stream.StreamSource; - -import org.apache.log4j.Logger; - -import org.w3c.dom.Node; - -public class XSLTransformer { - - private static Logger log = Logger.getLogger(XSLTransformer.class); - - protected Map<String, Object> parameters; - - public XSLTransformer() { - } - - public String transform(Node source, InputStream transform) { - - try { - Source templateSource = new StreamSource(transform); - TransformerFactory xformFactory = - TransformerFactory.newInstance(); - Transformer transformer = - xformFactory.newTransformer(templateSource); - - if (parameters != null) { - for (Map.Entry<String, Object> entry: parameters.entrySet()) { - transformer.setParameter(entry.getKey(), entry.getValue()); - } - } - - StringWriter result = new StringWriter(); - - DOMSource src = new DOMSource(source); - StreamResult dst = new StreamResult(result); - transformer.transform(src, dst); - - return result.toString(); - } - catch (TransformerConfigurationException tce) { - log.error(tce, tce); - } - catch (TransformerException te) { - log.error(te, te); - } - - return null; - } - - public void addParameter(String key, Object value) { - if (parameters == null) { - parameters = new HashMap<String, Object>(); - } - parameters.put(key, value); - } -} -// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts-common/src/main/java/org/dive4elements/artifacts/common/ArtifactNamespaceContext.java Thu Apr 25 10:53:15 2013 +0200 @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2010 by Intevation GmbH + * + * This program is free software under the LGPL (>=v2.1) + * Read the file LGPL.txt coming with the software for details + * or visit http://www.gnu.org/licenses/ if it does not exist. + */ + +package de.intevation.artifacts.common; + +import java.util.Iterator; + +import javax.xml.XMLConstants; + +import javax.xml.namespace.NamespaceContext; + +/** + * The namespace used in artifact documents. + * @author <a href="mailto:sascha.teichmann@intevation">Sascha L. Teichmann</a> + */ +public class ArtifactNamespaceContext +implements NamespaceContext +{ + /** + * The URI of the namespace of the artifacts. + */ + public final static String NAMESPACE_URI = + "http://www.intevation.de/2009/artifacts"; + + /** + * The XML prefix for the artifacts namespace. + */ + public final static String NAMESPACE_PREFIX = "art"; + + /** + * Final instance to be easily used to avoid creation + * of instances. + */ + public static final ArtifactNamespaceContext INSTANCE = + new ArtifactNamespaceContext(); + + /** + * The default constructor. + */ + public ArtifactNamespaceContext() { + } + + /** + * @see javax.xml.namespace.NamespaceContext#getNamespaceURI(String) + * @param prefix The prefix + * @return The corresponing URI + */ + public String getNamespaceURI(String prefix) { + + if (prefix == null) { + throw new NullPointerException("Null prefix"); + } + + if (NAMESPACE_PREFIX.equals(prefix)) { + return NAMESPACE_URI; + } + + if ("xml".equals(prefix)) { + return XMLConstants.XML_NS_URI; + } + + return XMLConstants.NULL_NS_URI; + } + + /** + * @see javax.xml.namespace.NamespaceContext#getPrefix(String) + * @param uri The URI + * @return nothing. + * @throws java.lang.UnsupportedOperationException + */ + public String getPrefix(String uri) { + throw new UnsupportedOperationException(); + } + + /** + * @see javax.xml.namespace.NamespaceContext#getPrefixes(java.lang.String) + * @param uri The URI + * @return nothing + * @throws java.lang.UnsupportedOperationException + */ + public Iterator getPrefixes(String uri) { + throw new UnsupportedOperationException(); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts-common/src/main/java/org/dive4elements/artifacts/common/model/DefaultUser.java Thu Apr 25 10:53:15 2013 +0200 @@ -0,0 +1,75 @@ +package de.intevation.artifacts.common.model; + +/** + * The default implementation of the {@link User} interface. + * + * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> + */ +public class DefaultUser implements User { + + /** The user's firstname. */ + protected String firstName; + + /** The user's lastname. */ + protected String lastName; + + + /** + * Creates an empty user without name. + */ + public DefaultUser() { + } + + + /** + * Creates a user with first and lastname. + * + * @param firstName The user's firstname. + * @param lastName The user's lastname. + */ + public DefaultUser(String firstName, String lastName) { + this.firstName = firstName; + this.lastName = lastName; + } + + + /** + * This method returns the firstname of the user. + * + * @return the firstname. + */ + public String getFirstName() { + return firstName; + } + + + /** + * Sets the user's firstname. + * + * @param firstName The user's firstname. + */ + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + + /** + * This method returns the lastname of the user. + * + * @return the lastname. + */ + public String getLastName() { + return lastName; + } + + + /** + * Sets the user's lastname. + * + * @param lastName The user's lastname. + */ + public void setLastName(String lastName) { + this.lastName = lastName; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts-common/src/main/java/org/dive4elements/artifacts/common/model/KVP.java Thu Apr 25 10:53:15 2013 +0200 @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2010 by Intevation GmbH + * + * This program is free software under the LGPL (>=v2.1) + * Read the file LGPL.txt coming with the software for details + * or visit http://www.gnu.org/licenses/ if it does not exist. + */ +package de.intevation.artifacts.common.model; + + +public class KVP<K, V> { + + private K key; + private V value; + + + public KVP(K key, V value) { + this.key = key; + this.value = value; + } + + + public K getKey() { + return key; + } + + + public V getValue() { + return value; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts-common/src/main/java/org/dive4elements/artifacts/common/model/User.java Thu Apr 25 10:53:15 2013 +0200 @@ -0,0 +1,43 @@ +package de.intevation.artifacts.common.model; + +import java.io.Serializable; + +/** + * An interface that describes a user of the system. + * + * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> + */ +public interface User extends Serializable { + + /** + * This method returns the firstname of the user. + * + * @return the firstname. + */ + public String getFirstName(); + + + /** + * Sets the user's firstname. + * + * @param firstName The user's firstname. + */ + public void setFirstName(String firstName); + + + /** + * This method returns the lastname of the user. + * + * @return the lastname. + */ + public String getLastName(); + + + /** + * Sets the user's lastname. + * + * @param lastName The user's lastname. + */ + public void setLastName(String lastName); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts-common/src/main/java/org/dive4elements/artifacts/common/utils/ClientProtocolUtils.java Thu Apr 25 10:53:15 2013 +0200 @@ -0,0 +1,860 @@ +/* + * Copyright (c) 2011 by Intevation GmbH + * + * This program is free software under the LGPL (>=v2.1) + * Read the file LGPL.txt coming with the software for details + * or visit http://www.gnu.org/licenses/ if it does not exist. + */ +package de.intevation.artifacts.common.utils; + +import javax.xml.xpath.XPathConstants; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import de.intevation.artifacts.common.ArtifactNamespaceContext; + + +/** + * This class provides methods that help creating the artifact protocol + * documents DESCRIBE, FEED, ADVANCE and OUT. + * + * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> + */ +public class ClientProtocolUtils { + + /** The XPath to the current state in the DESCRIBE document. */ + public static final String XPATH_CURRENT_STATE = "/art:result/art:state"; + + /** The XPath to the static UI part in the DESCRIBE document. */ + public static final String XPATH_STATIC = "/art:result/art:ui/art:static"; + + /** The XPath to the dynamic UI part in the DESCRIBE document. */ + public static final String XPATH_DYNAMIC = "/art:result/art:ui/art:dynamic"; + + /** The XPath to the reachable states part in the DESCRIBE document. */ + public static final String XPATH_STATES = + "/art:result/art:reachable-states"; + + /** The XPath to the output modes in the DESCRIBE document. */ + public static final String XPATH_OUTPUT_MODES = + "/art:result/art:outputmodes/art:output"; + + /** The XPath to the select node relative to the dynamic UI node in the + * DESCRIBE document. */ + public static final String XPATH_DATA_SELECT = "art:select"; + + /** The XPath to the choices nodes relative to the select node in the + * DESCRIBE document. */ + public static final String XPATH_DATA_ITEMS = "art:choices/art:item"; + + /** The XPath that points to the min value of a range.*/ + public static final String XPATH_MIN_NODE = "art:min/@art:value"; + + /** The XPath that points to the max value of a range.*/ + public static final String XPATH_MAX_NODE = "art:max/@art:value"; + + /** The XPath that points to the default min value of a range.*/ + public static final String XPATH_DEF_MIN = "art:min/@art:default"; + + /** The XPath that points to the default max value of a range.*/ + public static final String XPATH_DEF_MAX = "art:max/@art:default"; + + /** The XPath to a label in the artifact's DESCRIBE document. */ + public static final String XPATH_LABEL = "art:label/text()"; + + /** The XPath to a value in the artifact's DESCRIBE document. */ + public static final String XPATH_VALUE = "art:value/text()"; + + + /** + * It should not be necessary to create instances of this class. + */ + private ClientProtocolUtils() { + } + + + /** + * This method creates a new CREATE document. + * + * @return the CREATE document. + */ + public static Document newCreateDocument(String factory) { + return newCreateDocument(factory, null); + } + + + /** + * This method creates a new CREATE document. + * + * @return the CREATE document. + */ + public static Document newCreateDocument(String factory, String uuid) { + return newCreateDocument(factory, uuid, null); + } + + public static Document newCreateDocument( + String factory, + String uuid, + String ids + ) { + return newCreateDocument(factory, uuid, ids, null); + } + + /** + * This method creates a new CREATE document. + * + * @return the CREATE document. + */ + public static Document newCreateDocument( + String factory, + String uuid, + String ids, + CreationFilter filter + ) { + Document doc = XMLUtils.newDocument(); + + XMLUtils.ElementCreator cr = new XMLUtils.ElementCreator( + doc, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX); + + Element action = cr.create("action"); + Element type = cr.create("type"); + Element fac = cr.create("factory"); + + type.setAttribute("name", "create"); + fac.setAttribute("name", factory); + + action.appendChild(type); + action.appendChild(fac); + + if (uuid != null) { + Element templ = cr.create("template"); + templ.setAttribute("uuid", uuid); + action.appendChild(templ); + } + + if (ids != null) { + Element id = cr.create("ids"); + id.setAttribute("value", ids); + action.appendChild(id); + } + + if (filter != null) { + action.appendChild(filter.toXML(cr)); + } + + doc.appendChild(action); + + return doc; + } + + + /** + * This method creates a new FEED document. + * + * @param theUuid The identifier of the artifact. + * @param theHash The hash of the artifact. + * @param theData An array that contains key/value pairs that represent the + * data that should be included in the FEED document. + * + * @return the FEED document. + */ + public static Document newFeedDocument( + String theUuid, + String theHash, + String[][] theData) + { + Document doc = XMLUtils.newDocument(); + + XMLUtils.ElementCreator cr = new XMLUtils.ElementCreator( + doc, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX); + + Element action = cr.create("action"); + Element type = cr.create("type"); + Element uuid = cr.create("uuid"); + Element hash = cr.create("hash"); + Element data = cr.create("data"); + + // XXX It is not nice that the type has no attribute namespace, but to + // be backward compatible, we don't change this now. + cr.addAttr(type, "name", "feed", false); + cr.addAttr(uuid, "value", theUuid, true); + cr.addAttr(hash, "value", theHash, true); + + for (String[] kvp: theData) { + Element input = cr.create("input"); + cr.addAttr(input, "name", kvp[0], true); + cr.addAttr(input, "value", kvp[1], true); + + data.appendChild(input); + } + + action.appendChild(type); + action.appendChild(uuid); + action.appendChild(hash); + action.appendChild(data); + + doc.appendChild(action); + + return doc; + } + + + /** + * This method creates a new DESCRIBE document. + * + * @param theUuid The identifier of the artifact. + * @param theHash The hash of the artifact. + * @param ui If true, the UI part is included. + * + * @return the DESCRIBE document. + */ + public static Document newDescribeDocument( + String theUuid, + String theHash, + boolean incUI) + { + Document doc = XMLUtils.newDocument(); + + XMLUtils.ElementCreator cr = new XMLUtils.ElementCreator( + doc, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX); + + Element action = cr.create("action"); + Element type = cr.create("type"); + Element uuid = cr.create("uuid"); + Element hash = cr.create("hash"); + Element ui = cr.create("include-ui"); + + // XXX It is not nice that the type has no attribute namespace, but to + // be backward compatible, we don't change this now. + cr.addAttr(type, "name", "describe", false); + cr.addAttr(uuid, "value", theUuid, true); + cr.addAttr(hash, "value", theHash, true); + + ui.setTextContent(incUI ? "true" : "false"); + + action.appendChild(type); + action.appendChild(uuid); + action.appendChild(hash); + action.appendChild(ui); + + doc.appendChild(action); + + return doc; + } + + + /** + * This method creates a new ADVANCE document. + * + * @param theUuid The identifier of the artifact. + * @param theHash The hash of the artifact. + * @param theTarget The target state identifier. + * + * @return the ADVANCE document. + */ + public static Document newAdvanceDocument( + String theUuid, + String theHash, + String theTarget) + { + Document doc = XMLUtils.newDocument(); + + XMLUtils.ElementCreator cr = new XMLUtils.ElementCreator( + doc, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX); + + Element action = cr.create("action"); + Element type = cr.create("type"); + Element uuid = cr.create("uuid"); + Element hash = cr.create("hash"); + Element target = cr.create("target"); + + // XXX It is not nice that the type has no attribute namespace, but to + // be backward compatible, we don't change this now. + cr.addAttr(type, "name", "advance", false); + cr.addAttr(uuid, "value", theUuid, true); + cr.addAttr(hash, "value", theHash, true); + cr.addAttr(target, "name", theTarget, true); + + action.appendChild(type); + action.appendChild(uuid); + action.appendChild(hash); + action.appendChild(target); + + doc.appendChild(action); + + return doc; + } + + + /** + * This method creates a new document that is used to create new artifact + * collections in the artifact server. + * + * @param name <b>Optional</b> name of the collection. + * + * @return the document to create new collections. + */ + public static Document newCreateCollectionDocument(String name) { + Document doc = XMLUtils.newDocument(); + + XMLUtils.ElementCreator cr = new XMLUtils.ElementCreator( + doc, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX); + + Element action = cr.create("action"); + Element type = cr.create("type"); + Element collection = cr.create("collection"); + Element attribute = cr.create("attribute"); + + cr.addAttr(type, "name", "create"); + cr.addAttr(collection, "name", name != null ? name : ""); + + action.appendChild(type); + type.appendChild(collection); + collection.appendChild(attribute); + + doc.appendChild(action); + + return doc; + } + + + /** + * This method creates a new Document that is used to add an artifact to a + * collection in the artifact server. + * + * @param artId The identifier of the artifact that should be added. + * @param attr A document that contains attributes for the artifact's + * life in the collection. + * + * @return the document to add an artifact into a collection. + */ + public static Document newAddArtifactDocument(String artId, Document attr) { + Document doc = XMLUtils.newDocument(); + + XMLUtils.ElementCreator cr = new XMLUtils.ElementCreator( + doc, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX); + + Element action = cr.create("action"); + Element type = cr.create("type"); + Element artifact = cr.create("artifact"); + Element attribute = cr.create("attribute"); + + cr.addAttr(artifact, "uuid", artId); + cr.addAttr(type, "name", "addartifact"); + + if (attr != null) { + attr.appendChild(attr); + } + + action.appendChild(type); + type.appendChild(artifact); + artifact.appendChild(attribute); + + doc.appendChild(action); + + return doc; + } + + + /** + * Create a new Document that is used to remove an artifact from a + * collection in the artifact server. + * + * @param artId The identifier of the artifact that should be added. + * + * @return the document to add an artifact into a collection. + */ + public static Document newRemoveArtifactDocument(String artId) { + Document doc = XMLUtils.newDocument(); + + XMLUtils.ElementCreator cr = new XMLUtils.ElementCreator( + doc, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX); + + Element action = cr.create("action"); + Element type = cr.create("type"); + Element artifact = cr.create("artifact"); + + cr.addAttr(artifact, "uuid", artId); + cr.addAttr(type, "name", "removeartifact"); + + action.appendChild(type); + type.appendChild(artifact); + + doc.appendChild(action); + + return doc; + } + + + /** + * This method creates a new Document that is used to trigger the DESCRIBE + * operation of a collection in the artifact server. + * + * @param uuid The identifier of the collection that should be described. + * + * @return the document to describe a collection. + */ + public static Document newDescribeCollectionDocument(String uuid) { + Document doc = XMLUtils.newDocument(); + + XMLUtils.ElementCreator cr = new XMLUtils.ElementCreator( + doc, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX); + + Element action = cr.create("action"); + Element type = cr.create("type"); + cr.addAttr(type, "name", "describe"); + + action.appendChild(type); + + doc.appendChild(action); + + return doc; + } + + + + /** + * This function builds a document that is used as request document of the + * out() operation of Collections. + * + * @param uuid The identifier of the collection. + * @param mode The name of the desired output mode. + * @param type The name of the desired output type. + * + * @return the request document. + */ + public static Document newOutCollectionDocument( + String uuid, + String mode, + String type) { + return newOutCollectionDocument(uuid, mode, type, null); + } + + + /** + * This function builds a document that is used as request document of the + * out() operation of Collections. The document <i>attr</i> might be used to + * adjust some settings specific to the output. + * + * @param uuid The identifier of the collection. + * @param mode The name of the desired output mode. + * @param type The name of the desired output type. + * @param attr A document that contains settings specific to the output. + * + * @return the request document. + */ + public static Document newOutCollectionDocument( + String uuid, + String mode, + String type, + Document attr) + { + Document doc = XMLUtils.newDocument(); + + XMLUtils.ElementCreator cr = new XMLUtils.ElementCreator( + doc, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX); + + Element action = cr.create("action"); + + cr.addAttr(action, "name", mode, true); + cr.addAttr(action, "type", type, true); + + doc.appendChild(action); + + if (attr != null) { + Node root = attr.getFirstChild(); + + if (root != null) { + action.appendChild(doc.importNode(root, true)); + } + } + + return doc; + } + + + /** + * This function creates a document that is used to set the attribute of a + * Collection. + * + * @param uuid The identifier of the Collection. + * @param attr The new attribute value for the Collection. + * + * @return the document that is used to set the attribute. + */ + public static Document newSetAttributeDocument( + String uuid, + Document attr) + { + Node root = attr != null ? attr.getFirstChild() : null; + + if (root == null) { + return null; + } + + Document doc = XMLUtils.newDocument(); + + XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator( + doc, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX); + + Element action = ec.create("action"); + Element type = ec.create("type"); + Element collection = ec.create("collection"); + + ec.addAttr(type, "name", "setattribute", false); + ec.addAttr(collection, "uuid", uuid, false); + + doc.appendChild(action); + action.appendChild(type); + type.appendChild(collection); + + collection.appendChild(doc.importNode(root, true)); + + return doc; + } + + /** + * This function creates a document that is used to set the attribute of a + * CollectionItem. + * + * @param uuid The identifier of the CollectionItem. + * @param attr The new attribute value for the CollectionItem. + * + * @return the document that is used to set the attribute. + */ + public static Document newSetItemAttributeDocument( + String uuid, + Document attr) + { + Node root = attr.getFirstChild(); + + if (root == null) { + return null; + } + + Document doc = XMLUtils.newDocument(); + + XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator( + doc, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX); + + Element action = ec.create("action"); + Element type = ec.create("type"); + Element artifact = ec.create("artifact"); + + ec.addAttr(type, "name", "setitemattribute"); + ec.addAttr(artifact, "uuid", uuid); + + doc.appendChild(action); + action.appendChild(type); + type.appendChild(artifact); + + artifact.appendChild(doc.importNode(root, true)); + + return doc; + } + + + /** + * This function creates a document that is used to set the time-to-live + * of a collection. + * + * @param ttl The ttl for the Collection. + * + * @return the document that is used to set the time-to-live. + */ + public static Document newSetCollectionTTLDocument(String ttl) { + Document doc = XMLUtils.newDocument(); + + XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator( + doc, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX); + + Element action = ec.create("action"); + Element type = ec.create("type"); + Element ttlEl = ec.create("ttl"); + + ec.addAttr(type, "name", "settimetolive"); + ec.addAttr(ttlEl, "value", ttl); + + doc.appendChild(action); + action.appendChild(type); + type.appendChild(ttlEl); + + return doc; + } + + + /** + * This function creates a document that is used to set the name of a + * collection. + * + * @param name The name for the Collection. + * + * @return the document that is used to set the name of a collection. + */ + public static Document newSetCollectionNameDocument(String name) { + Document doc = XMLUtils.newDocument(); + + XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator( + doc, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX); + + Element action = ec.create("action"); + Element type = ec.create("type"); + Element coll = ec.create("collection"); + + ec.addAttr(type, "name", "setname"); + ec.addAttr(coll, "name", name); + + doc.appendChild(action); + action.appendChild(type); + type.appendChild(coll); + + return doc; + } + + + /** + * This function creates a document that is used to delete an existing + * collection. + * + * @return the document that is used to delete an existing collection. + */ + public static Document newDeleteCollectionDocument() { + Document doc = XMLUtils.newDocument(); + + XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator( + doc, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX); + + Element action = ec.create("action"); + Element type = ec.create("type"); + + ec.addAttr(type, "name", "delete"); + + doc.appendChild(action); + action.appendChild(type); + + return doc; + } + + + /** + * Returns string value found by {@link XPATH_LABEL} relative to + * <i>node</i>. + * + * @param node A node. + * + * @return the string value found by {@link XPATH_LABEL}. + */ + public static String getLabel(Node node) { + return (String) XMLUtils.xpath( + node, + XPATH_LABEL, + XPathConstants.STRING, + ArtifactNamespaceContext.INSTANCE); + } + + + /** + * Returns string value found by {@link XPATH_VALUE} relative to + * <i>node</i>. + * + * @param node A node. + * + * @return the string value found by {@link XPATH_VALUE}. + */ + public static String getValue(Node node) { + return (String) XMLUtils.xpath( + node, + XPATH_VALUE, + XPathConstants.STRING, + ArtifactNamespaceContext.INSTANCE); + } + + + /** + * This method returns the static UI part of the artifact's DESCRIBE + * document. + * + * @param description The document returned by the artifact server's + * DESCRIBE operation. + * + * @return the static UI node. + */ + public static Node getStaticUI(Document description) { + return (Node) XMLUtils.xpath( + description, + XPATH_STATIC, + XPathConstants.NODE, + ArtifactNamespaceContext.INSTANCE); + } + + + /** + * This method returns the dynamic UI part of the artifact's DESCRIBE + * document. + * + * @param description The document returned by the artifact server's + * DESCRIBE operation. + * + * @return the dynamic UI node. + */ + public static Node getDynamicUI(Document description) { + return (Node) XMLUtils.xpath( + description, + XPATH_DYNAMIC, + XPathConstants.NODE, + ArtifactNamespaceContext.INSTANCE); + } + + + /** + * This method returns the current state node contained in the DESCRIBE + * document. + * + * @param description The document returned by the artifact server's + * DESCRIBE operation. + * + * @return the node containing information about the current state. + */ + public static Node getCurrentState(Document description) { + return (Node) XMLUtils.xpath( + description, + XPATH_CURRENT_STATE, + XPathConstants.NODE, + ArtifactNamespaceContext.INSTANCE); + } + + + /** + * This method returns the node that contains information about the + * reachable states of the artifact in the artifact's DESCRIBE document. + * + * @param description The document returned by the artifact server's + * DESCRIBE operation. + * + * @return the node that contains the reachable states. + */ + public static Node getReachableStates(Document description) { + return (Node) XMLUtils.xpath( + description, + XPATH_STATES, + XPathConstants.NODE, + ArtifactNamespaceContext.INSTANCE); + } + + + /** + * This method returns the output mode nodes of the DESCRIBE document. + * + * @param description The document returned by the artifact server's + * DESCRIBE operation. + * + * @return the node that contains the output modes. + */ + public static NodeList getOutputModes(Document description) { + return (NodeList) XMLUtils.xpath( + description, + XPATH_OUTPUT_MODES, + XPathConstants.NODESET, + ArtifactNamespaceContext.INSTANCE); + } + + + /** + * Returns the node found by {@link XPATH_DATA_SELECT}. + * + * @param dynamicNode The dynamic UI node of the DESCRIBE document. + * + * @return the select node found in the dynamic UI node. + */ + public static NodeList getSelectNode(Node dynamicNode) { + return (NodeList) XMLUtils.xpath( + dynamicNode, + XPATH_DATA_SELECT, + XPathConstants.NODESET, + ArtifactNamespaceContext.INSTANCE); + } + + + /** + * Returns the items that could be found in the <i>node</i>. + * + * @param node A select node. + * + * @return the choices nodes as node list. + */ + public static NodeList getItemNodes(Node node) { + return (NodeList) XMLUtils.xpath( + node, + XPATH_DATA_ITEMS, + XPathConstants.NODESET, + ArtifactNamespaceContext.INSTANCE); + } + + + public static String getMinNode(Node parent) { + return (String) XMLUtils.xpath( + parent, + XPATH_MIN_NODE, + XPathConstants.STRING, + ArtifactNamespaceContext.INSTANCE); + } + + + public static String getMaxNode(Node parent) { + return (String) XMLUtils.xpath( + parent, + XPATH_MAX_NODE, + XPathConstants.STRING, + ArtifactNamespaceContext.INSTANCE); + } + + + public static String getDefMin(Node parent) { + return (String) XMLUtils.xpath( + parent, + XPATH_DEF_MIN, + XPathConstants.STRING, + ArtifactNamespaceContext.INSTANCE); + } + + + public static String getDefMax(Node parent) { + return (String) XMLUtils.xpath( + parent, + XPATH_DEF_MAX, + XPathConstants.STRING, + ArtifactNamespaceContext.INSTANCE); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts-common/src/main/java/org/dive4elements/artifacts/common/utils/Config.java Thu Apr 25 10:53:15 2013 +0200 @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2010 by Intevation GmbH + * + * This program is free software under the LGPL (>=v2.1) + * Read the file LGPL.txt coming with the software for details + * or visit http://www.gnu.org/licenses/ if it does not exist. + */ + +package de.intevation.artifacts.common.utils; + +import java.io.File; +import java.io.IOException; + +import javax.xml.namespace.QName; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import javax.xml.xpath.XPathConstants; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import org.xml.sax.SAXException; + +/** + * The central access to the configuration of the artifact database. + * This class provides some static methods to access the central + * configuration XML file via XPath. + * + * @author <a href="mailto:sascha.teichmann@intevation.de">Sascha L. Teichmann</a> + */ +public final class Config +{ + private static Logger logger = Logger.getLogger(Config.class); + + /** + * System property name where to find the configuration directory. + */ + public static final String CONFIG_DIR = "artifact.database.dir"; + + /** + * Default path to the configuration directory if none + * was specified by the CONFIG_DIR system property. + */ + public static final File CONFIG_DIR_DEFAULT = + new File(new File(System.getProperty("user.home", + System.getProperty("user.dir", "."))), ".artifactdb"); + + /** + * Name of the central configuration XML file. + */ + public static final String CONFIG_FILE = "conf.xml"; + + /** + * Name of the configuration filename alias to be use + * within the configuration. This alias is replaced by + * the real path. + */ + public static final String CONFIG_DIR_PLACEHOLDER = + "${artifacts.config.dir}"; + + private static Document config; + + private Config() { + } + + /** + * Singleton access to the central XML configuration document. + * @return The central XML configuration document. + */ + public static synchronized final Document getConfig() { + if (config == null) { + config = loadConfig(); + } + return config; + } + + /** + * Returns the path to the configuartion directory. If a path + * was specified via the CONFIG_DIR system property this one + * is used. Else it falls back to default configuration path. + * @return The path to the configuartion directory. + */ + public static File getConfigDirectory() { + String configDirString = System.getProperty(CONFIG_DIR); + + File configDir = configDirString != null + ? new File(configDirString) + : CONFIG_DIR_DEFAULT; + + if (!configDir.isDirectory()) { + logger.warn("'" + configDir + "' is not a directory."); + configDir = CONFIG_DIR_DEFAULT; + } + + return configDir; + } + + /** + * Replaces the CONFIG_DIR_PLACEHOLDER alias with the real path + * of the configuration directory. + * @param path The path containing the CONFIG_DIR_PLACEHOLDER placeholder. + * @return The path where the CONFIG_DIR_PLACEHOLDER placeholders are + * replaced by the real path name. + */ + public static String replaceConfigDir(String path) { + String configDir = getConfigDirectory().getAbsolutePath(); + return path.replace(CONFIG_DIR_PLACEHOLDER, configDir); + } + + private static Document loadConfig() { + + File configDir = getConfigDirectory(); + + File file = new File(configDir, CONFIG_FILE); + + if (!file.canRead() && !file.isFile()) { + logger.error("Cannot read config file '" + + file + "'."); + return null; + } + + try { + DocumentBuilderFactory factory = + DocumentBuilderFactory.newInstance(); + factory.setValidating(false); // XXX: This may change in future. + return factory.newDocumentBuilder().parse(file); + } + catch (SAXException se) { + logger.error(se.getLocalizedMessage(), se); + } + catch (ParserConfigurationException pce) { + logger.error(pce.getLocalizedMessage(), pce); + } + catch (IOException ioe) { + logger.error(ioe.getLocalizedMessage()); + } + + return null; + } + + /** + * Convenience method to search within a given document tree via XPath. + * See {@link XMLUtils#xpath(Object, String, QName) } for details. + * @param root The object which is used as the root of the tree to + * be searched in. + * @param query The XPath query. + * @param returnType The type of the result. + * @return The result of type 'returnTyp' or null if something went + * wrong during XPath evaluation. + */ + public static final Object getXPath( + Object root, String query, QName returnType + ) { + return XMLUtils.xpath(root, query, returnType); + } + + /** + * Convenience method to search within the central configuration via XPath. + * See {@link XMLUtils#xpath(Object, String, QName) } for details. + * @param query The XPath query. + * @param returnType The type of the result. + * @return The result of type 'returnTyp' or null if something went + * wrong during XPath evaluation. + */ + public static final Object getXPath(String query, QName returnType) { + return XMLUtils.xpath(getConfig(), query, returnType); + } + + /** + * Convenience method to search for a node list within the central + * configuation document via XPath. + * @param query The XPath query. + * @return The queried node list or null if something went + * wrong during XPath evaluation. + */ + public static final NodeList getNodeSetXPath(String query) { + return (NodeList)getXPath(query, XPathConstants.NODESET); + } + + /** + * Convenience method to search for a node within the central + * configuation document via XPath. + * @param query The XPath query. + * @return The queried node or null if something went + * wrong during XPath evaluation. + */ + public static final Node getNodeXPath(String query) { + return (Node)getXPath(query, XPathConstants.NODE); + } + + /** + * Convenience method to search for a string within the central + * configuation document via XPath. + * @param xpath The XPath query. + * @return The queried string or null if something went + * wrong during XPath evaluation. + */ + public static final String getStringXPath(String xpath) { + return getStringXPath(xpath, null); + } + + /** + * Convenience method to search for a string within the central + * configuation document via XPath. + * @param query The XPath query. + * @param def The string to be returned if the search has no results. + * @return The queried string or the default value if something went + * wrong during XPath evaluation. + */ + public static final String getStringXPath(String query, String def) { + String s = (String)getXPath(query, XPathConstants.STRING); + return s == null || s.length() == 0 + ? def + : s; + } + + /** + * Convenience method to search for a node list within a given tree + * via XPath. + * @param root The root of the tree to be searched in. + * @param query The XPath query. + * @return The queried node list or null if something went + * wrong during XPath evaluation. + */ + public static final NodeList getNodeSetXPath(Object root, String query) { + return (NodeList)getXPath(root, query, XPathConstants.NODESET); + } + + /** + * Convenience method to search for a node within a given tree + * via XPath. + * @param root The root of the tree to be searched in. + * @param query The XPath query. + * @return The queried node or null if something went + * wrong during XPath evaluation. + */ + public static final Node getNodeXPath(Object root, String query) { + return (Node)getXPath(root, query, XPathConstants.NODE); + } + + /** + * Convenience method to search for a string within a given tree + * via XPath. + * @param root The root of the tree to be searched in. + * @param xpath The XPath query. + * @return The queried string or null if something went + * wrong during XPath evaluation. + */ + public static final String getStringXPath(Object root, String xpath) { + return getStringXPath(root, xpath, null); + } + + /** + * Convenience method to search for a string within a given tree + * via XPath. + * @param root The root of the tree to be searched in. + * @param query xpath The XPath query. + * @param def The string to be returned if the search has no results. + * @return The queried string or the default value if something went + * wrong during XPath evaluation. + */ + public static final String getStringXPath( + Object root, String query, String def + ) { + String s = (String)getXPath(root, query, XPathConstants.STRING); + return s == null || s.length() == 0 + ? def + : s; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts-common/src/main/java/org/dive4elements/artifacts/common/utils/CreationFilter.java Thu Apr 25 10:53:15 2013 +0200 @@ -0,0 +1,61 @@ +package de.intevation.artifacts.common.utils; + +import java.util.List; +import java.util.Map; +import java.util.HashMap; + +import org.w3c.dom.Element; + +public class CreationFilter +{ + public static class Facet { + + protected String name; + protected String index; + + public Facet() { + } + + public Facet(String name, String index) { + this.name = name; + this.index = index; + } + + public String getName() { + return name; + } + + public String getIndex() { + return index; + } + } + + protected Map<String, List<Facet>> outs; + + public CreationFilter() { + outs = new HashMap<String, List<Facet>>(); + } + + public void add(String out, List<Facet> facets) { + outs.put(out, facets); + } + + public Element toXML(XMLUtils.ElementCreator ec) { + Element filter = ec.create("filter"); + + for (Map.Entry<String, List<Facet>> entry: outs.entrySet()) { + Element out = ec.create("out"); + out.setAttribute("name", entry.getKey()); + for (Facet facet: entry.getValue()) { + Element f = ec.create("facet"); + f.setAttribute("name", facet.getName()); + f.setAttribute("index", facet.getIndex()); + out.appendChild(f); + } + filter.appendChild(out); + } + + return filter; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts-common/src/main/java/org/dive4elements/artifacts/common/utils/DateUtils.java Thu Apr 25 10:53:15 2013 +0200 @@ -0,0 +1,30 @@ +package de.intevation.artifacts.common.utils; + +import java.util.Calendar; +import java.util.Date; + + +public class DateUtils { + + private DateUtils() { + } + + + /** + * This function extracts the year as int value from <i>date</i>. + * + * @param date The source date. + * + * @return the year as integer or -1 if date is empty. + */ + public static int getYearFromDate(Date date) { + if (date == null) { + return -1; + } + + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + + return cal.get(Calendar.YEAR); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts-common/src/main/java/org/dive4elements/artifacts/common/utils/FileTools.java Thu Apr 25 10:53:15 2013 +0200 @@ -0,0 +1,613 @@ +/* + * Copyright (c) 2010, 2011 by Intevation GmbH + * + * This program is free software under the LGPL (>=v2.1) + * Read the file LGPL.txt coming with the software for details + * or visit http://www.gnu.org/licenses/ if it does not exist. + */ +package de.intevation.artifacts.common.utils; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.io.BufferedOutputStream; +import java.nio.channels.FileChannel; + +import java.util.Deque; +import java.util.ArrayDeque; +import java.util.List; +import java.util.Set; +import java.util.HashSet; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.zip.ZipFile; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import org.apache.log4j.Logger; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +public class FileTools +{ + private static Logger log = Logger.getLogger(FileTools.class); + + public static final String DIGEST = + System.getProperty("artifacts.common.file.cmp.digest", "MD5"); + + private FileTools() { + } + + + /** Remove everything after dot from name. */ + public static final String removeExtension(String name) { + int index = name.lastIndexOf('.'); + return index == -1 + ? name + : name.substring(0, index); + } + + + public static File getDirectory(String path, String name) { + if (path == null || name == null) { + return null; + } + + File dir = new File(path, name); + + if (!dir.exists()) { + log.debug( + "Directory '" + dir.getAbsolutePath() + "' doesn't " + + "exist. Try to create it."); + + return dir.mkdir() ? dir : null; + } + else { + return dir.isDirectory() ? dir : null; + } + } + + public static File repair(File file) { + file = file.getAbsoluteFile(); + if (file.exists()) { + return file; + } + Deque<String> parts = new ArrayDeque<String>(); + File curr = file; + while (curr != null) { + String name = curr.getName(); + if (name.length() > 0) { + parts.push(curr.getName()); + } + curr = curr.getParentFile(); + } + + curr = null; + OUTER: while (!parts.isEmpty()) { + String f = parts.pop(); + log.debug("fixing: '" + f + "'"); + if (f.equals(".") || f.equals("..")) { + // No need to fix . or .. + continue; + } + if (curr == null) { + // XXX: Not totaly correct because there + // more than one root on none unix systems. + for (File root: File.listRoots()) { + File [] files = root.listFiles(); + if (files == null) { + log.warn("cannot list '" + root); + continue; + } + for (File candidate: files) { + if (candidate.getName().equalsIgnoreCase(f)) { + curr = new File(root, candidate.getName()); + continue OUTER; + } + } + } + break; + } + else { + File [] files = curr.listFiles(); + if (files == null) { + log.warn("cannot list: '" + curr + "'"); + return file; + } + for (File candidate: files) { + if (candidate.getName().equalsIgnoreCase(f)) { + curr = new File(curr, candidate.getName()); + continue OUTER; + } + } + curr = null; + break; + } + } + + if (curr == null) { + log.warn("cannot repair path '" + file + "'"); + return file; + } + + return curr; + } + + /** Object that can calculate hash of file, compare two hashed files etc. */ + public static class HashedFile + implements Comparable<HashedFile> + { + protected File file; + protected long length; + protected byte [] hash; + + public HashedFile(File file) { + this.file = file; + length = file.length(); + } + + public File getFile() { + return file; + } + + protected byte [] getHash() { + if (hash == null) { + InputStream in = null; + + try { + in = new FileInputStream(file); + + MessageDigest digest = MessageDigest.getInstance(DIGEST); + + byte [] buf = new byte[40*1024]; + int r; + + while ((r = in.read(buf)) >= 0) { + digest.update(buf, 0, r); + } + + hash = digest.digest(); + } + catch (IOException ioe) { + log.error(ioe); + hash = new byte[0]; + } + catch (NoSuchAlgorithmException nsae) { + log.error(nsae); + hash = new byte[0]; + } + finally { + if (in != null) { + try { + in.close(); + } + catch (IOException ioe) { + log.error(ioe); + } + } + } + } + return hash; + } + + @Override + public int compareTo(HashedFile other) { + if (length < other.length) return -1; + if (length > other.length) return +1; + return compare(getHash(), other.getHash()); + } + + private static int compare(byte [] a, byte [] b) { + if (a.length < b.length) return -1; + if (a.length > b.length) return +1; + for (int i = 0; i < a.length; ++i) { + int x = a[i] & 0xff; + int y = b[i] & 0xff; + if (x < y) return -1; + if (x > y) return +1; + } + return 0; + } + + @Override + public boolean equals(Object other) { + return other instanceof HashedFile + && ((HashedFile)other).compareTo(this) == 0; + } + + @Override + public int hashCode() { + return (int)(length ^ (length >>> 32)); + } + } // class HashedFile + + public static List<File> uniqueFiles(List<File> files) { + + Set<HashedFile> set = new HashSet<HashedFile>(); + + for (File file: files) { + if (!set.add(new HashedFile(file))) { + log.warn("file '" + file + "' is a duplicate."); + } + } + + ArrayList<File> out = new ArrayList<File>(set.size()); + for (HashedFile hf: set) { + out.add(hf.file); + } + + return out; + } + + public interface FileVisitor { + boolean visit(File file); + } // Visitor + + public static void walkTree(File root, FileVisitor visitor) { + + Deque<File> stack = new ArrayDeque<File>(); + + stack.push(root); + + while (!stack.isEmpty()) { + File current = stack.pop(); + if (!visitor.visit(current)) break; + if (current.isDirectory()) { + File [] subs = current.listFiles(); + if (subs != null) { + for (File f: subs) { + stack.push(f); + } + } + } + } + } + + /** + * Deletes everything in a directory. + * + * @param dir The directory. + */ + public final static void deleteContent(File dir) { + if (dir == null || !dir.isDirectory()) { + return; + } + + File[] files = dir.listFiles(); + if (files != null) { + for (File file: files) { + deleteRecursive(file); + } + } + + return; + } + + /** + * Delete <i>file</i> and everything in <i>file</i> if it is a directory. + * + * @param file The file or directory. + * @return true, if deletion was successful - otherwise false. + */ + public final static boolean deleteRecursive(File file) { + + if (file == null) { + return false; + } + + if (file.isDirectory()) { + File [] files = file.listFiles(); + if (files != null) { + for (File sub: files) { + if (!deleteRecursive(sub)) { + return false; + } + } + } + } + + return file.delete(); + } + + /** + * Put the given file or directory into a zip archive. + * + * @param file The file or directory. + * @param outputStream The stream to write the archive to. + * @throws IOException if an error occured while zip creation or writing to + * output stream. + */ + public static void createZipArchive( + File file, + OutputStream outputStream + ) + throws IOException + { + ZipOutputStream out = new ZipOutputStream(outputStream); + + if (file.isFile()) { + copyFileToZip("", file, out); + } + else if (file.isDirectory()) { + + Deque<PrefixDir> stack = new ArrayDeque<PrefixDir>(); + stack.push(new PrefixDir(file.getName() + "/", file)); + + while (!stack.isEmpty()) { + PrefixDir pd = stack.pop(); + + ZipEntry dirEntry = new ZipEntry(pd.prefix); + out.putNextEntry(dirEntry); + out.closeEntry(); + + File [] files = pd.dir.listFiles(); + if (files != null) { + for (File sub: files) { + if (sub.isDirectory()) { + stack.push(new PrefixDir( + pd.prefix + sub.getName() + "/", + sub)); + } + else if (sub.isFile()) { + copyFileToZip(pd.prefix, sub, out); + } + } + } + } + } + + out.finish(); + } + + + public static void extractArchive(File archive, File destDir) + throws IOException { + if (!destDir.exists()) { + destDir.mkdir(); + } + + ZipFile zipFile = new ZipFile(archive); + try { + Enumeration<? extends ZipEntry> entries = zipFile.entries(); + + byte [] buffer = new byte[16384]; + + while (entries.hasMoreElements()) { + ZipEntry entry = entries.nextElement(); + + String entryFileName = entry.getName(); + + File dir = buildDirectoryHierarchyFor(entryFileName, destDir); + if (!dir.exists()) { + dir.mkdirs(); + } + + if (!entry.isDirectory()) { + BufferedInputStream bis = new BufferedInputStream( + zipFile.getInputStream(entry)); + try { + BufferedOutputStream bos = new BufferedOutputStream( + new FileOutputStream(new File(destDir, entryFileName))); + + try { + int len; + while ((len = bis.read(buffer)) > 0) { + bos.write(buffer, 0, len); + } + bos.flush(); + } + finally { + bos.close(); + } + } + finally { + bis.close(); + } + } // is file + } + } + finally { + zipFile.close(); + } + } + + private static File buildDirectoryHierarchyFor( + String entryName, + File destDir) + { + int lastIndex = entryName.lastIndexOf('/'); + String internalPathToEntry = entryName.substring(0, lastIndex + 1); + return new File(destDir, internalPathToEntry); + } + + /** + * A class representing a directory with a prefix. + */ + private static final class PrefixDir { + + String prefix; + File dir; + + public PrefixDir(String prefix, File dir) { + this.prefix = prefix; + this.dir = dir; + } + + } // class PrefixDir + + /** + * Write a file to zip archive. + * + * @param prefix A prefix. + * @param file The file. + * @param out The output stream. + * @throws IOException if an error occured while writing to zip output + * stream. + */ + private static void copyFileToZip( + String prefix, + File file, + ZipOutputStream out + ) + throws IOException + { + String entryName = prefix + file.getName(); + ZipEntry entry = new ZipEntry(entryName); + out.putNextEntry(entry); + InputStream in = null; + try { + in = + new BufferedInputStream( + new FileInputStream(file), 20*1024); + + byte [] buf = new byte[2048]; + + int r; + while ((r = in.read(buf)) > 0) { + out.write(buf, 0, r); + } + } + finally { + if (in != null) { + try { in.close(); } + catch (IOException ioe) {} + } + } + out.closeEntry(); + } + + + /** + * Copies a <i>src</i> file to <i>target</i>. + * + * @param src A file (not a directory) that should be copied. + * @param target The destination. This might be a file or a directory. + * + * @return true, if <i>src</i> has been successfully copied; otherwise + * false. + */ + public static boolean copyFile(File src, File target) + throws IOException + { + if (src == null || !src.exists()) { + log.warn("Source file does not exist!"); + return false; + } + + if (!src.canRead()) { + log.warn("Cannot read Source file!"); + return false; + } + + if (src.isDirectory()) { + log.warn("Source is a directory!"); + return false; + } + + if (target.isDirectory()) { + target = new File(target, src.getName()); + } + + FileInputStream in = null; + FileOutputStream out = null; + + try { + in = new FileInputStream(src); + out = new FileOutputStream(target); + + FileChannel inChannel = in.getChannel(); + FileChannel outChannel = out.getChannel(); + + inChannel.transferTo(0l, inChannel.size(), outChannel); + + return true; + } + catch (IOException ioe) { + log.warn(ioe, ioe); + } + finally { + if (in != null) { + try { + in.close(); + } + catch (IOException ioe) { /* do nothing here */ } + } + + if (out != null) { + try { + out.close(); + } + catch (IOException ioe) { /* do nothing here */ } + } + } + + return false; + } + + + /** + * Copies a directory <i>source</i> to a destination path <i>dest</i>. + * + * @param source A directory that should be copied. + * @param dest A destination directory which is created if it is not + * existing yet. + * + * @return true, if the directory has been successfully copied; otherwise + * false. + */ + public static boolean copyDirectory(final File source, final File dest) { + if (source == null || !source.exists()) { + log.warn("Source directory does not exist!"); + return false; + } + + if (!source.isDirectory()) { + log.warn("Source is not a directory!"); + return false; + } + + if (dest == null) { + log.warn("Destination directory is null!"); + return false; + } + + if (!dest.exists()) { + if (!dest.mkdir()) { + log.warn("Cannot create destination directory!"); + return false; + } + } + + File[] children = source.listFiles(); + int failed = 0; + + if (children != null && children.length > 0) { + for (File child: children) { + if (child.isFile()) { + try { + if (!copyFile(child, dest)) { + failed++; + } + } + catch (IOException ioe) { + log.warn(ioe, ioe); + failed++; + } + } + else if (child.isDirectory()) { + copyDirectory(child, new File(dest, child.getName())); + } + } + } + + log.debug("Failed to copy " + failed + " files."); + + return true; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts-common/src/main/java/org/dive4elements/artifacts/common/utils/JSON.java Thu Apr 25 10:53:15 2013 +0200 @@ -0,0 +1,445 @@ +package de.intevation.artifacts.common.utils; + +import java.util.Map; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.ArrayList; +import java.util.Iterator; + +import java.io.IOException; +import java.io.PushbackInputStream; +import java.io.InputStream; +import java.io.PrintWriter; +import java.io.ByteArrayInputStream; +import java.io.StringWriter; + +import java.nio.charset.Charset; +import java.nio.charset.UnsupportedCharsetException; + +public final class JSON +{ + private JSON() { + } + + private static final boolean isDigit(int c) { + return c >= '0' && c <= '9'; + } + + public static final boolean isWhitespace(int c) { + return c == ' ' || c == '\n' || c == '\r' + || c == '\t' || c == '\f'; + } + + private static final void match(int c, int x) throws IOException { + if (c != x) { + throw new IOException( + "Expecting '" + (char)c + "' found '" + (char)x + "'"); + } + } + + private static final int eof(InputStream in) + throws IOException + { + int c = in.read(); + if (c == -1) { + throw new IOException("EOF unexpected."); + } + return c; + } + + private static final int whitespace(InputStream in) + throws IOException + { + int c; + while (isWhitespace(c = eof(in))); + return c; + } + + private static final int parseHex(String hex) throws IOException { + try { + return Integer.parseInt(hex, 16); + } + catch (NumberFormatException nfe) { + throw new IOException("'" + hex + "' is not a hex string."); + } + } + + public static final String jsonString(String string) { + StringBuilder sb = new StringBuilder(string.length()+2); + + sb.append('"'); + + for (int i = 0, N = string.length(); i < N; ++i) { + char c = string.charAt(i); + switch (c) { + case '"': sb.append("\\\""); break; + case '\t': sb.append("\\t"); break; + case '\r': sb.append("\\r"); break; + case '\n': sb.append("\\n"); break; + case '\b': sb.append("\\b"); break; + case '\f': sb.append("\\f"); break; + default: + if (c >= 128) { + sb.append("\\u"); + String hex = Integer.toHexString((int)c); + for (int j = 4-hex.length(); j > 0; --j) { + sb.append('0'); + } + sb.append(hex); + } + else { + sb.append(c); + } + } + } + + sb.append('"'); + + return sb.toString(); + } + + public static String toJSONString(Map<String, Object> map) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + write(pw, map); + pw.flush(); + return sw.toString(); + } + + + public static void write(PrintWriter out, Map<String, Object> map) { + writeObject(out, map); + } + + private static void writeValue(PrintWriter out, Object value) { + if (value instanceof Map) { + writeObject(out, (Map)value); + } + else if (value instanceof List) { + writeList(out, (List)value); + } + else if (value instanceof Number) { + out.print(value); + } + else if (value instanceof Boolean) { + out.print(((Boolean)value) ? "true" : "false"); + } + else if (value == null) { + out.print("null"); + } + else { + out.print(jsonString(value.toString())); + } + } + + private static void writeObject(PrintWriter out, Map map) { + + out.print('{'); + Iterator iter = map.entrySet().iterator(); + while (iter.hasNext()) { + Map.Entry entry = (Map.Entry)iter.next(); + out.print(jsonString(entry.getKey().toString())); + out.print(':'); + writeValue(out, entry.getValue()); + if (iter.hasNext()) { + out.print(','); + } + } + out.print('}'); + } + + private static void writeList(PrintWriter out, List list) { + out.print('['); + Iterator iter = list.iterator(); + while (iter.hasNext()) { + writeValue(out, iter.next()); + if (iter.hasNext()) { + out.print(','); + } + } + out.print(']'); + } + + public static Map<String, Object> parse(String in) + throws IOException + { + return parse(asInputStream(in)); + } + + private static InputStream asInputStream(String in) { + byte [] bytes; + try { + bytes = in.getBytes(Charset.forName("US-ASCII")); + } + catch (UnsupportedCharsetException uce) { + // Should not happen. + bytes = in.getBytes(); + } + return new ByteArrayInputStream(bytes); + } + + public static Map<String, Object> parse(InputStream in) + throws IOException + { + return parseObject(new PushbackInputStream(in, 1)); + } + + public static Map<String, Object> parse(PushbackInputStream in) + throws IOException + { + return parseObject(in); + } + + private static final String parseString( + PushbackInputStream in + ) + throws IOException + { + StringBuilder sb = new StringBuilder(); + + int mode = 0; + + char [] hex = new char[4]; + + match('"', eof(in)); + + OUT: for (int c = eof(in);; c = eof(in)) { + + switch (mode) { + case 0: + if (c == '"') { + break OUT; + } + if (c == '\\') { + mode = 1; + } + else { + sb.append((char)c); + } + break; + case 1: + switch (c) { + case 'u': + mode = 2; + continue; + case 'b': + sb.append('\b'); + break; + case 'f': + sb.append('\f'); + break; + case 'n': + sb.append('\n'); + break; + case 'r': + sb.append('\r'); + break; + case 't': + sb.append('\t'); + break; + default: + sb.append((char)c); + } + mode = 0; + break; + case 2: + hex[0] = (char)c; + mode = 3; + break; + case 3: + hex[1] = (char)c; + mode = 4; + break; + case 4: + hex[2] = (char)c; + mode = 5; + break; + case 5: + hex[3] = (char)c; + sb.append((char)parseHex(new String(hex))); + mode = 0; + break; + } + } + return sb.toString(); + } + + private static final Boolean parseTrue(InputStream in) + throws IOException + { + match('t', eof(in)); + match('r', eof(in)); + match('u', eof(in)); + match('e', eof(in)); + return Boolean.TRUE; + } + + private static final Boolean parseFalse(InputStream in) + throws IOException + { + match('f', eof(in)); + match('a', eof(in)); + match('l', eof(in)); + match('s', eof(in)); + match('e', eof(in)); + return Boolean.FALSE; + } + + private static final Object parseNull(InputStream in) + throws IOException + { + match('n', eof(in)); + match('u', eof(in)); + match('l', eof(in)); + match('l', eof(in)); + return null; + } + + private static final Number parseNumber(PushbackInputStream in) + throws IOException + { + StringBuilder sb = new StringBuilder(); + + boolean isInteger = true; + + int c; + OUT: for (;;) { + switch (c = eof(in)) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + case '-': case '+': + sb.append((char)c); + break; + case '.': case 'e': case 'E': + isInteger = false; + sb.append((char)c); + break; + default: + in.unread(c); + break OUT; + } + } + + try { + if (isInteger) { + return sb.length() > 9 + ? (Number)Long .valueOf(sb.toString()) + : (Number)Integer.valueOf(sb.toString()); + } + return (Number)Double.valueOf(sb.toString()); + } + catch (NumberFormatException nfe) { + throw new IOException("Not a number '" + sb + "'"); + } + } + + private static List<Object> parseList(PushbackInputStream in) + throws IOException + { + List<Object> list = new ArrayList<Object>(); + match('[', whitespace(in)); + int c = whitespace(in); + if (c == ']') { + return list; + } + + for (;; c = whitespace(in)) { + Object value; + in.unread(c); + switch (c) { + case '{': + value = parseObject(in); + break; + case '[': + value = parseList(in); + break; + case '"': + value = parseString(in); + break; + case 't': + value = parseTrue(in); + break; + case 'f': + value = parseFalse(in); + break; + case 'n': + value = parseNull(in); + break; + default: + value = parseNumber(in); + } + list.add(value); + + if ((c = whitespace(in)) == ']') break; + match(',', c); + } + return list; + } + + private static void parsePair( + PushbackInputStream in, + Map<String, Object> pairs + ) + throws IOException + { + in.unread(whitespace(in)); + String string = parseString(in); + match(':', whitespace(in)); + + Object value; + + int c = whitespace(in); + in.unread(c); + switch (c) { + case '{': + value = parseObject(in); + break; + case '[': + value = parseList(in); + break; + case '"': + value = parseString(in); + break; + case 't': + value = parseTrue(in); + break; + case 'f': + value = parseFalse(in); + break; + case 'n': + value = parseNull(in); + break; + default: + value = parseNumber(in); + } + pairs.put(string, value); + } + + private static Map<String, Object> parseObject(PushbackInputStream in) + throws IOException + { + Map<String, Object> pairs = new LinkedHashMap<String, Object>(); + + int c = whitespace(in); + match('{', c); + + if ((c = whitespace(in)) == '}') { + return pairs; + } + + in.unread(c); + + for (;;) { + parsePair(in, pairs); + + if ((c = whitespace(in)) == '}') { + break; + } + + if (c == '}') break; + match(',', c); + } + + return pairs; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts-common/src/main/java/org/dive4elements/artifacts/common/utils/LRUCache.java Thu Apr 25 10:53:15 2013 +0200 @@ -0,0 +1,26 @@ +package de.intevation.artifacts.common.utils; + +import java.util.Map; +import java.util.LinkedHashMap; + +public class LRUCache<K, V> +extends LinkedHashMap<K, V> +{ + public static final int DEFAULT_MAX_CAPACITY = 25; + + private int maxCapacity; + + public LRUCache() { + this(DEFAULT_MAX_CAPACITY); + } + + public LRUCache(int maxCapacity) { + this.maxCapacity = maxCapacity; + } + + @Override + protected boolean removeEldestEntry(Map.Entry<K, V> eldest) { + return size() > maxCapacity; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts-common/src/main/java/org/dive4elements/artifacts/common/utils/MapXPathVariableResolver.java Thu Apr 25 10:53:15 2013 +0200 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2011 by Intevation GmbH + * + * This program is free software under the LGPL (>=v2.1) + * Read the file LGPL.txt coming with the software for details + * or visit http://www.gnu.org/licenses/ if it does not exist. + */ +package de.intevation.artifacts.common.utils; + +import java.util.HashMap; +import java.util.Map; + +import javax.xml.namespace.QName; +import javax.xml.xpath.XPathVariableResolver; + + +/** + * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> + */ +public class MapXPathVariableResolver implements XPathVariableResolver { + + protected Map<String, String> variables; + + + public MapXPathVariableResolver() { + this.variables = new HashMap<String, String>(); + } + + + public MapXPathVariableResolver(Map<String, String> variables) { + this.variables = variables; + } + + + public void addVariable(String name, String value) { + if (name != null && value != null) { + variables.put(name, value); + } + } + + + @Override + public Object resolveVariable(QName variableName) { + String key = variableName.getLocalPart(); + return variables.get(key); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts-common/src/main/java/org/dive4elements/artifacts/common/utils/StringUtils.java Thu Apr 25 10:53:15 2013 +0200 @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2010 by Intevation GmbH + * + * This program is free software under the LGPL (>=v2.1) + * Read the file LGPL.txt coming with the software for details + * or visit http://www.gnu.org/licenses/ if it does not exist. + */ + +package de.intevation.artifacts.common.utils; + +import java.io.UnsupportedEncodingException; + +import java.util.UUID; + +import org.apache.commons.codec.DecoderException; + +import org.apache.commons.codec.binary.Hex; + +import org.apache.log4j.Logger; + +/** + * Commonly used string functions. + * + * @author <a href="mailto:sascha.teichmann@intevation.de">Sascha L. Teichmann</a> + */ +public final class StringUtils +{ + private static Logger logger = Logger.getLogger(StringUtils.class); + + /** + * Generated a random UUIDv4 in form of a string. + * @return the UUID + */ + public static final String newUUID() { + return UUID.randomUUID().toString(); + } + + /** + * Checks if a given string is a valid UUID. + * @param uuid The string to test. + * @return true if the string is a valid UUID else false. + */ + public static final boolean checkUUID(String uuid) { + try { + UUID.fromString(uuid); + } + catch (IllegalArgumentException iae) { + logger.warn(iae.getLocalizedMessage()); + return false; + } + return true; + } + + /** + * Returns the UTF-8 byte array representation of a given string. + * @param s The string to be transformed. + * @return The byte array representation. + */ + public static final byte [] getUTF8Bytes(String s) { + try { + return s.getBytes("UTF-8"); + } + catch (UnsupportedEncodingException usee) { + logger.error(usee.getLocalizedMessage(), usee); + return s.getBytes(); + } + } + + /** + * Tries to convert a Base64 encoded string into the + * corresponing byte array. + * @param s The Base64 encoded string + * @return The byte array representation or null if + * an decoding error occurs. + */ + public static final byte [] decodeHex(String s) { + try { + return Hex.decodeHex(s.toCharArray()); + } + catch (DecoderException de) { + return null; + } + } + + public static final String repeat(String s, int count, String sep) { + if (count <= 0) { + return ""; + } + StringBuilder sb = new StringBuilder(s); + for (--count; count > 0; --count) { + sb.append(sep).append(s); + } + return sb.toString(); + } + + public static final String repeat(char c, int count, char sep) { + if (count <= 0) { + return ""; + } + StringBuilder sb = new StringBuilder(2*count-1).append(c); + for (--count; count > 0; --count) { + sb.append(sep).append(c); + } + return sb.toString(); + } + + public static final String [] toUpperCase(String [] s) { + if (s == null) { + return null; + } + String [] d = new String[s.length]; + for (int i = 0; i < s.length; ++i) { + if (s[i] != null) { + d[i] = s[i].toUpperCase(); + } + } + return d; + } + + public static String join(String sep, String [] strings) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < strings.length; ++i) { + if (i > 0) sb.append(sep); + sb.append(strings[i]); + } + return sb.toString(); + } + + public static final String [] join(String [] a, String [] b) { + if (a == null && b == null) return null; + if (a == null) return b; + if (b == null) return a; + String [] dst = new String[a.length + b.length]; + System.arraycopy(a, 0, dst, 0, a.length); + System.arraycopy(b, 0, dst, a.length, b.length); + return dst; + } + + public static final boolean contains(String needle, String [] haystack) { + for (String stray: haystack) { + if (needle.equals(stray)) { + return true; + } + } + return false; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts-common/src/main/java/org/dive4elements/artifacts/common/utils/XMLUtils.java Thu Apr 25 10:53:15 2013 +0200 @@ -0,0 +1,617 @@ +/* + * Copyright (c) 2010 by Intevation GmbH + * + * This program is free software under the LGPL (>=v2.1) + * Read the file LGPL.txt coming with the software for details + * or visit http://www.gnu.org/licenses/ if it does not exist. + */ + +package de.intevation.artifacts.common.utils; + +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.LinkedHashMap; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; + +import java.io.ByteArrayInputStream; +import java.io.FileInputStream; +import java.io.BufferedInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.StringWriter; + +import javax.xml.namespace.NamespaceContext; +import javax.xml.namespace.QName; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.TransformerFactoryConfigurationError; + +import javax.xml.transform.dom.DOMSource; + +import javax.xml.transform.stream.StreamResult; + +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; +import javax.xml.xpath.XPathVariableResolver; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import org.xml.sax.SAXException; + +/** + * Some helper functions to ease work with XML concering namespaces, XPATH + * and so on. + * @author <a href="mailto:sascha.teichmann@intevation.de">Sascha L. Teichmann</a> + */ +public final class XMLUtils +{ + /** W3C URL of XForms. */ + public static final String XFORM_URL = "http://www.w3.org/2002/xforms"; + + /** W3C prefix of XForms. */ + public static final String XFORM_PREFIX = "xform"; + + /** Logger for this class. */ + private static Logger logger = Logger.getLogger(XMLUtils.class); + + private XMLUtils() { + } + + /** + * Helper class to generate elements and attributes with + * namespaces. + */ + public static class ElementCreator + { + /** Owner document of the elements to be created. */ + protected Document document; + + /** Namespace to be used. */ + protected String ns; + + /** Prefix to be used. */ + protected String prefix; + + /** + * Constructor to create an element/attribute creator + * with a given namespace and namespace prefix using a + * given owner document. + * @param document The owning document + * @param ns The namespace + * @param prefix The namespace prefix + */ + public ElementCreator(Document document, String ns, String prefix) { + this.document = document; + this.ns = ns; + this.prefix = prefix; + } + + /** + * Creates a new element using the owning document with + * the this creators namespace and namespace prefix. + * @param name The name of the element + * @return The new element + */ + public Element create(String name) { + Element element = document.createElementNS(ns, name); + element.setPrefix(prefix); + return element; + } + + /** + * Adds a new attribute and its value to a given element. + * It does not set the namespace prefix. + * @param element The element to add the attribute to + * @param name The name of the attribute + * @param value The value of the attribute + */ + public void addAttr(Element element, String name, String value) { + addAttr(element, name, value, false); + } + + /** + * Adds a new attribute and its value to a given element. + * If the namespace prefix is used is decided by the 'addPrefix' flag. + * @param element The element to add the attribute to + * @param name The name of the attribute + * @param value The value of the attribute + * @param addPrefix If true the creators namespace prefix is + * set on the attribute. + */ + public void addAttr( + Element element, + String name, + String value, + boolean addPrefix + ) { + if (addPrefix) { + Attr attr = document.createAttributeNS(ns, name); + attr.setValue(value); + attr.setPrefix(prefix); + + element.setAttributeNode(attr); + } + else { + element.setAttribute(name, value); + } + } + } // class ElementCreator + + /** + * Creates a new XML document + * @return the new XML document ot null if something went wrong during + * creation. + */ + public static final Document newDocument() { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); + + try { + return factory.newDocumentBuilder().newDocument(); + } + catch (ParserConfigurationException pce) { + logger.error(pce.getLocalizedMessage(), pce); + } + return null; + } + + + /** + * Create xml/string representation of element (nested in otherwise empty + * document). + * @param element element to inspect in string. + * @return string with xml representation of element. + */ + public final static String toString(Node node) { + Document doc = newDocument(); + doc.appendChild(doc.importNode(node,true)); + return toString(doc); + } + + + /** + * Loads a XML document namespace aware from a file + * @param file The file to load. + * @return the XML document or null if something went wrong + * during loading. + */ + public static final Document parseDocument(File file) { + InputStream inputStream = null; + try { + inputStream = new BufferedInputStream(new FileInputStream(file)); + return parseDocument(inputStream); + } + catch (IOException ioe) { + logger.error(ioe.getLocalizedMessage(), ioe); + } + finally { + if (inputStream != null) { + try { inputStream.close(); } + catch (IOException ioe) {} + } + } + return null; + } + + /** + * Parses a String to a xml document. + * + * @param string The xml string + * @return the XML document or null if something went wrong. + */ + public static final Document parseDocument(String string) { + InputStream inputStream = new ByteArrayInputStream(string.getBytes()); + return parseDocument(inputStream); + } + + + public static final Document parseDocument(InputStream inputStream) { + return parseDocument(inputStream, Boolean.TRUE); + } + + public static final Document parseDocument( + InputStream inputStream, + Boolean namespaceAware + ) { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + + if (namespaceAware != null) { + factory.setNamespaceAware(namespaceAware.booleanValue()); + } + + try { + return factory.newDocumentBuilder().parse(inputStream); + } + catch (ParserConfigurationException pce) { + logger.error(pce.getLocalizedMessage(), pce); + } + catch (SAXException se) { + logger.error(se.getLocalizedMessage(), se); + } + catch (IOException ioe) { + logger.error(ioe.getLocalizedMessage(), ioe); + } + return null; + } + + /** + * Creates a new XPath without a namespace context. + * @return the new XPath. + */ + public static final XPath newXPath() { + return newXPath(null, null); + } + + /** + * Creates a new XPath with a given namespace context. + * @param namespaceContext The namespace context to be used or null + * if none should be used. + * @return The new XPath + */ + public static final XPath newXPath( + NamespaceContext namespaceContext, + XPathVariableResolver resolver) + { + XPathFactory factory = XPathFactory.newInstance(); + XPath xpath = factory.newXPath(); + if (namespaceContext != null) { + xpath.setNamespaceContext(namespaceContext); + } + + if (resolver != null) { + xpath.setXPathVariableResolver(resolver); + } + return xpath; + } + + /** + * Evaluates an XPath query on a given object and returns the result + * as a given type. No namespace context is used. + * @param root The object which is used as the root of the tree to + * be searched in. + * @param query The XPath query + * @param returnTyp The type of the result. + * @return The result of type 'returnTyp' or null if something + * went wrong during XPath evaluation. + */ + public static final Object xpath( + Object root, + String query, + QName returnTyp + ) { + return xpath(root, query, returnTyp, null); + } + + /** + * Evaluates an XPath query on a given object and returns the result + * as a string. A given namespace context is used. + * @param root The object which is used as the root of the tree to + * be searched in. + * @param query The XPath query + * @param namespaceContext The namespace context to be used or null + * if none should be used. + * @return The result of the query or null if something went wrong + * during XPath evaluation. + */ + public static final String xpathString( + Object root, String query, NamespaceContext namespaceContext + ) { + return (String)xpath( + root, query, XPathConstants.STRING, namespaceContext); + } + + /** + * Evaluates an XPath query on a given object and returns the result + * as a given type. Optionally a namespace context is used. + * @param root The object which is used as the root of the tree to + * be searched in. + * @param query The XPath query + * @param returnType The type of the result. + * @param namespaceContext The namespace context to be used or null + * if none should be used. + * @return The result of type 'returnTyp' or null if something + * went wrong during XPath evaluation. + */ + public static final Object xpath( + Object root, + String query, + QName returnType, + NamespaceContext namespaceContext + ) { + return xpath(root, query, returnType, namespaceContext, null); + } + + public static final Object xpath( + Object root, + String query, + QName returnType, + NamespaceContext namespaceContext, + Map<String, String> variables) + { + if (root == null) { + return null; + } + + XPathVariableResolver resolver = variables != null + ? new MapXPathVariableResolver(variables) + : null; + + try { + XPath xpath = newXPath(namespaceContext, resolver); + if (xpath != null) { + return xpath.evaluate(query, root, returnType); + } + } + catch (XPathExpressionException xpee) { + logger.error(xpee.getLocalizedMessage(), xpee); + } + + return null; + } + + /** + * Streams out an XML document to a given output stream. + * @param document The document to be streamed out. + * @param out The output stream to be used. + * @return true if operation succeeded else false. + */ + public static boolean toStream(Document document, OutputStream out) { + try { + Transformer transformer = + TransformerFactory.newInstance().newTransformer(); + DOMSource source = new DOMSource(document); + StreamResult result = new StreamResult(out); + transformer.transform(source, result); + return true; + } + catch (TransformerConfigurationException tce) { + logger.error(tce.getLocalizedMessage(), tce); + } + catch (TransformerFactoryConfigurationError tfce) { + logger.error(tfce.getLocalizedMessage(), tfce); + } + catch (TransformerException te) { + logger.error(te.getLocalizedMessage(), te); + } + + return false; + } + + public static String toString(Document document) { + try { + Transformer transformer = + TransformerFactory.newInstance().newTransformer(); + DOMSource source = new DOMSource(document); + StringWriter out = new StringWriter(); + StreamResult result = new StreamResult(out); + transformer.transform(source, result); + out.flush(); + return out.toString(); + } + catch (TransformerConfigurationException tce) { + logger.error(tce.getLocalizedMessage(), tce); + } + catch (TransformerFactoryConfigurationError tfce) { + logger.error(tfce.getLocalizedMessage(), tfce); + } + catch (TransformerException te) { + logger.error(te.getLocalizedMessage(), te); + } + + return null; + } + + public static byte [] toByteArray(Document document) { + return toByteArray(document, false); + } + + /** + * Transforms an XML document into a byte array. + * @param document The document to be streamed out. + * @param compress The document should be compressed, too. + * @return the byte array or null if operation failed or + * document is null. + */ + public static byte [] toByteArray(Document document, boolean compress) { + if (document != null) { + try { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + OutputStream out = compress + ? new GZIPOutputStream(baos) + : baos; + boolean success = toStream(document, out); + out.flush(); + out.close(); + return success + ? baos.toByteArray() + : null; + } + catch (IOException ioe) { + logger.error(ioe); + } + } + return null; + } + + public static Document fromByteArray(byte [] data) { + return fromByteArray(data, false); + } + + public static Document fromByteArray(byte [] data, boolean decompress) { + if (data != null) { + InputStream in = new ByteArrayInputStream(data); + try { + if (decompress) { + in = new GZIPInputStream(in); + } + return parseDocument(in); + } + catch (IOException ioe) { + logger.error(ioe); + } + finally { + try { + in.close(); + } + catch (IOException ioe) { + logger.error(ioe); + } + } + } + return null; + } + + private static class BuildResult { + List<Node> children; + Map<String, String> attributes; + BuildResult() { + children = new ArrayList<Node>(); + attributes = new LinkedHashMap<String, String>(); + } + + void setAttributes(Element element) { + for (Map.Entry<String, String> entry: attributes.entrySet()) { + element.setAttribute(entry.getKey(), entry.getValue()); + } + } + + void finish(Element element) { + setAttributes(element); + for (Node child: children) { + element.appendChild(child); + } + } + + void add(Node node) { + children.add(node); + } + + void add(String key, Object value) { + attributes.put(key, value != null ? value.toString() : "null"); + } + + int numChildren() { + return children.size(); + } + + Node firstChild() { + return children.get(0); + } + } // class BuildResult + + private static BuildResult recursiveBuild( + List list, + Document document + ) { + BuildResult result = new BuildResult(); + for (Object entry: list) { + if (entry instanceof Map) { + BuildResult subResult = recursiveBuild( + (Map<String, Object>)entry, document); + if (subResult.numChildren() == 1) { + result.add(subResult.firstChild()); + } + else { + Element element = document.createElement("map"); + subResult.finish(element); + result.add(element); + } + } + else if (entry instanceof List) { + Element element = document.createElement("list"); + BuildResult subResult = recursiveBuild((List)entry, document); + subResult.finish(element); + result.add(element); + } + else { + Element element = document.createElement("entry"); + element.setAttribute( + "value", + entry != null ? entry.toString() : "null"); + } + } + return result; + } + + private static BuildResult recursiveBuild( + Map<String, Object> map, + Document document + ) { + BuildResult result = new BuildResult(); + + List<Node> nodes = new ArrayList<Node>(); + for (Map.Entry<String, Object> entry: map.entrySet()) { + Object value = entry.getValue(); + if (value instanceof Map) { + Element element = document.createElement(entry.getKey()); + BuildResult subResult = recursiveBuild( + (Map<String, Object>)value, document); + subResult.finish(element); + result.add(element); + } + else if (value instanceof List) { + Element element = document.createElement(entry.getKey()); + BuildResult subResult = recursiveBuild((List)value, document); + subResult.finish(element); + result.add(element); + } + else { + result.add(entry.getKey(), value); + } + } + return result; + } + + public static Document jsonToXML(String input) { + Document document = newDocument(); + + if (document == null) { + return null; + } + + Map<String, Object> map; + try { + map = JSON.parse(input); + } + catch (IOException ioe) { + logger.error(ioe); + return null; + } + + BuildResult roots = recursiveBuild(map, document); + + int N = roots.children.size(); + + if (N == 1) { + document.appendChild(roots.children.get(0)); + } + else if (N > 1) { + Node root = document.createElement("root"); + for (int i = 0; i < N; ++i) { + root.appendChild(roots.children.get(i)); + } + document.appendChild(root); + } + + return document; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts-common/src/main/java/org/dive4elements/artifacts/common/utils/XSLTransformer.java Thu Apr 25 10:53:15 2013 +0200 @@ -0,0 +1,73 @@ +package de.intevation.artifacts.common.utils; + +import java.io.InputStream; +import java.io.StringWriter; + +import java.util.HashMap; +import java.util.Map; + +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; + +import javax.xml.transform.dom.DOMSource; + +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Node; + +public class XSLTransformer { + + private static Logger log = Logger.getLogger(XSLTransformer.class); + + protected Map<String, Object> parameters; + + public XSLTransformer() { + } + + public String transform(Node source, InputStream transform) { + + try { + Source templateSource = new StreamSource(transform); + TransformerFactory xformFactory = + TransformerFactory.newInstance(); + Transformer transformer = + xformFactory.newTransformer(templateSource); + + if (parameters != null) { + for (Map.Entry<String, Object> entry: parameters.entrySet()) { + transformer.setParameter(entry.getKey(), entry.getValue()); + } + } + + StringWriter result = new StringWriter(); + + DOMSource src = new DOMSource(source); + StreamResult dst = new StreamResult(result); + transformer.transform(src, dst); + + return result.toString(); + } + catch (TransformerConfigurationException tce) { + log.error(tce, tce); + } + catch (TransformerException te) { + log.error(te, te); + } + + return null; + } + + public void addParameter(String key, Object value) { + if (parameters == null) { + parameters = new HashMap<String, Object>(); + } + parameters.put(key, value); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :