[jbpm-commits] JBoss JBPM SVN: r2690 - projects/gwt-console/trunk/server/src/main/java/org/jboss/bpm/console/server/util.

do-not-reply at jboss.org do-not-reply at jboss.org
Fri Oct 31 05:09:52 EDT 2008


Author: heiko.braun at jboss.com
Date: 2008-10-31 05:09:52 -0400 (Fri, 31 Oct 2008)
New Revision: 2690

Added:
   projects/gwt-console/trunk/server/src/main/java/org/jboss/bpm/console/server/util/DOMUtils.java
   projects/gwt-console/trunk/server/src/main/java/org/jboss/bpm/console/server/util/ServiceLoader.java
Log:
Migrate DOMUtils and ServiceLoader fom JBossWS

Added: projects/gwt-console/trunk/server/src/main/java/org/jboss/bpm/console/server/util/DOMUtils.java
===================================================================
--- projects/gwt-console/trunk/server/src/main/java/org/jboss/bpm/console/server/util/DOMUtils.java	                        (rev 0)
+++ projects/gwt-console/trunk/server/src/main/java/org/jboss/bpm/console/server/util/DOMUtils.java	2008-10-31 09:09:52 UTC (rev 2690)
@@ -0,0 +1,732 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.bpm.console.server.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.util.LinkedList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.jboss.logging.Logger;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * DOM2 utilites
+ *
+ * @author Thomas.Diesler at jboss.org
+ * @author alessio.soldano at jboss.com
+ */
+public final class DOMUtils
+{
+   private static Logger log = Logger.getLogger(DOMUtils.class);
+
+   // All elements created by the same thread are created by the same builder and belong to the same doc
+   private static ThreadLocal<Document> documentThreadLocal = new ThreadLocal<Document>();
+   private static ThreadLocal<DocumentBuilder> builderThreadLocal = new ThreadLocal<DocumentBuilder>()
+   {
+      protected DocumentBuilder initialValue()
+      {
+         try
+         {
+            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+            factory.setValidating(false);
+            factory.setNamespaceAware(true);
+            DocumentBuilder builder = factory.newDocumentBuilder();
+            setEntityResolver(builder);
+            return builder;
+         }
+         catch (ParserConfigurationException e)
+         {
+            throw new RuntimeException("Failed to create DocumentBuilder", e);
+         }
+      }
+
+      private void setEntityResolver(DocumentBuilder builder)
+      {
+         String[] resolvers = new String[] { "org.jboss.ws.core.utils.JBossWSEntityResolver", "org.jboss.util.xml.JBossEntityResolver" };
+
+         EntityResolver entityResolver = null;
+         ClassLoader loader = Thread.currentThread().getContextClassLoader();
+         for (String resolver : resolvers)
+         {
+            try
+            {
+               Class<?> resolverClass = loader.loadClass(resolver);
+               entityResolver = (EntityResolver)resolverClass.newInstance();
+            }
+            catch (Exception ex)
+            {
+               log.debug("Cannot load: " + resolver);
+            }
+         }
+
+         if (entityResolver != null)
+            builder.setEntityResolver(entityResolver);
+      }
+   };
+
+   public static void clearThreadLocals()
+   {
+      documentThreadLocal.remove();
+      builderThreadLocal.remove();
+   }
+
+   // Hide the constructor
+   private DOMUtils()
+   {
+   }
+
+   /** Initialize the DocumentBuilder
+    */
+   public static DocumentBuilder getDocumentBuilder()
+   {
+      return builderThreadLocal.get();
+   }
+
+   /** Parse the given XML string and return the root Element
+    */
+   public static Element parse(String xmlString) throws IOException
+   {
+      try
+      {
+         return parse(new ByteArrayInputStream(xmlString.getBytes("UTF-8")));
+      }
+      catch (IOException e)
+      {
+         log.error("Cannot parse: " + xmlString);
+         throw e;
+      }
+   }
+
+   /** Parse the given XML stream and return the root Element
+    */
+   public static Element parse(InputStream xmlStream) throws IOException
+   {
+      try
+      {
+         return getDocumentBuilder().parse(xmlStream).getDocumentElement();
+      }
+      catch (SAXException se)
+      {
+         throw new IOException(se.toString());
+      }
+      finally
+      {
+         xmlStream.close();
+      }
+   }
+
+   /** Parse the given input source and return the root Element
+    */
+   public static Element parse(InputSource source) throws IOException
+   {
+      try
+      {
+         return getDocumentBuilder().parse(source).getDocumentElement();
+      }
+      catch (SAXException se)
+      {
+         throw new IOException(se.toString());
+      }
+      finally
+      {
+         InputStream is = source.getByteStream();
+         if (is != null)
+         {
+            is.close();
+         }
+         Reader r = source.getCharacterStream();
+         if (r != null)
+         {
+            r.close();
+         }
+      }
+   }
+
+   /** Create an Element for a given name
+    */
+   public static Element createElement(String localPart)
+   {
+      Document doc = getOwnerDocument();
+      log.trace("createElement {}" + localPart);
+      return doc.createElement(localPart);
+   }
+
+   /** Create an Element for a given name and prefix
+    */
+   public static Element createElement(String localPart, String prefix)
+   {
+      Document doc = getOwnerDocument();
+      log.trace("createElement {}" + prefix + ":" + localPart);
+      return doc.createElement(prefix + ":" + localPart);
+   }
+
+   /** Create an Element for a given name, prefix and uri
+    */
+   public static Element createElement(String localPart, String prefix, String uri)
+   {
+      Document doc = getOwnerDocument();
+      if (prefix == null || prefix.length() == 0)
+      {
+         log.trace("createElement {" + uri + "}" + localPart);
+         return doc.createElementNS(uri, localPart);
+      }
+      else
+      {
+         log.trace("createElement {" + uri + "}" + prefix + ":" + localPart);
+         return doc.createElementNS(uri, prefix + ":" + localPart);
+      }
+   }
+
+   /** Create an Element for a given QName
+    */
+   public static Element createElement(QName qname)
+   {
+      return createElement(qname.getLocalPart(), qname.getPrefix(), qname.getNamespaceURI());
+   }
+
+   /** Create a org.w3c.dom.Text node
+    */
+   public static Text createTextNode(String value)
+   {
+      Document doc = getOwnerDocument();
+      return doc.createTextNode(value);
+   }
+
+   /** Get the qname of the given node.
+    */
+   public static QName getElementQName(Element el)
+   {
+      String qualifiedName = el.getNodeName();
+      return resolveQName(el, qualifiedName);
+   }
+
+   /** Transform the given qualified name into a QName
+    */
+   public static QName resolveQName(Element el, String qualifiedName)
+   {
+      QName qname;
+      String prefix = "";
+      String namespaceURI = "";
+      String localPart = qualifiedName;
+
+      int colIndex = qualifiedName.indexOf(":");
+      if (colIndex > 0)
+      {
+         prefix = qualifiedName.substring(0, colIndex);
+         localPart = qualifiedName.substring(colIndex + 1);
+
+         if ("xmlns".equals(prefix))
+         {
+            namespaceURI = "URI:XML_PREDEFINED_NAMESPACE";
+         }
+         else
+         {
+            Element nsElement = el;
+            while (namespaceURI.equals("") && nsElement != null)
+            {
+               namespaceURI = nsElement.getAttribute("xmlns:" + prefix);
+               if (namespaceURI.equals(""))
+                  nsElement = getParentElement(nsElement);
+            }
+         }
+
+         if (namespaceURI.equals(""))
+            throw new IllegalArgumentException("Cannot find namespace uri for: " + qualifiedName);
+      }
+      else
+      {
+         Element nsElement = el;
+         while (namespaceURI.equals("") && nsElement != null)
+         {
+            namespaceURI = nsElement.getAttribute("xmlns");
+            if (namespaceURI.equals(""))
+               nsElement = getParentElement(nsElement);
+         }
+      }
+
+      qname = new QName(namespaceURI, localPart, prefix);
+      return qname;
+   }
+
+   /** Get the value from the given attribute
+    *
+    * @return null if the attribute value is empty or the attribute is not present
+    */
+   public static String getAttributeValue(Element el, String attrName)
+   {
+      return getAttributeValue(el, new QName(attrName));
+   }
+
+   /** Get the value from the given attribute
+    *
+    * @return null if the attribute value is empty or the attribute is not present
+    */
+   public static String getAttributeValue(Element el, QName attrName)
+   {
+      String attr = null;
+      if ("".equals(attrName.getNamespaceURI()))
+         attr = el.getAttribute(attrName.getLocalPart());
+      else attr = el.getAttributeNS(attrName.getNamespaceURI(), attrName.getLocalPart());
+
+      if ("".equals(attr))
+         attr = null;
+
+      return attr;
+   }
+
+   /** Get the qname value from the given attribute
+    */
+   public static QName getAttributeValueAsQName(Element el, String attrName)
+   {
+      return getAttributeValueAsQName(el, new QName(attrName));
+
+   }
+
+   /** Get the qname value from the given attribute
+    */
+   public static QName getAttributeValueAsQName(Element el, QName attrName)
+   {
+      QName qname = null;
+
+      String qualifiedName = getAttributeValue(el, attrName);
+      if (qualifiedName != null)
+      {
+         qname = resolveQName(el, qualifiedName);
+      }
+
+      return qname;
+   }
+
+   /** Get the boolean value from the given attribute
+    */
+   public static boolean getAttributeValueAsBoolean(Element el, String attrName)
+   {
+      return getAttributeValueAsBoolean(el, new QName(attrName));
+   }
+
+   /** Get the boolean value from the given attribute
+    */
+   public static boolean getAttributeValueAsBoolean(Element el, QName attrName)
+   {
+      String attrVal = getAttributeValue(el, attrName);
+      boolean ret = "true".equalsIgnoreCase(attrVal) || "1".equalsIgnoreCase(attrVal);
+      return ret;
+   }
+
+   /** Get the integer value from the given attribute
+    */
+   public static Integer getAttributeValueAsInteger(Element el, String attrName)
+   {
+      return getAttributeValueAsInteger(el, new QName(attrName));
+   }
+
+   /** Get the integer value from the given attribute
+    */
+   public static Integer getAttributeValueAsInteger(Element el, QName attrName)
+   {
+      String attrVal = getAttributeValue(el, attrName);
+      return (attrVal != null ? new Integer(attrVal) : null);
+   }
+
+   /** Get the attributes as Map<QName, String>
+    */
+   public static Map getAttributes(Element el)
+   {
+      Map attmap = new HashMap();
+      NamedNodeMap attribs = el.getAttributes();
+      for (int i = 0; i < attribs.getLength(); i++)
+      {
+         Attr attr = (Attr)attribs.item(i);
+         String name = attr.getName();
+         QName qname = resolveQName(el, name);
+         String value = attr.getNodeValue();
+         attmap.put(qname, value);
+      }
+      return attmap;
+   }
+
+   /** Copy attributes between elements
+    */
+   public static void copyAttributes(Element destElement, Element srcElement)
+   {
+      NamedNodeMap attribs = srcElement.getAttributes();
+      for (int i = 0; i < attribs.getLength(); i++)
+      {
+         Attr attr = (Attr)attribs.item(i);
+         String uri = attr.getNamespaceURI();
+         String qname = attr.getName();
+         String value = attr.getNodeValue();
+
+         // Prevent DOMException: NAMESPACE_ERR: An attempt is made to create or
+         // change an object in a way which is incorrect with regard to namespaces.
+         if (uri == null && qname.startsWith("xmlns"))
+         {
+            log.trace("Ignore attribute: [uri=" + uri + ",qname=" + qname + ",value=" + value + "]");
+         }
+         else
+         {
+            destElement.setAttributeNS(uri, qname, value);
+         }
+      }
+   }
+
+   /** True if the node has text child elements only
+    */
+   public static boolean hasTextChildNodesOnly(Node node)
+   {
+      NodeList nodeList = node.getChildNodes();
+      if (nodeList.getLength() == 0)
+         return false;
+
+      for (int i = 0; i < nodeList.getLength(); i++)
+      {
+         Node acksToChildNode = nodeList.item(i);
+         if (acksToChildNode.getNodeType() != Node.TEXT_NODE)
+            return false;
+      }
+
+      return true;
+   }
+
+   /** True if the node has child elements
+    */
+   public static boolean hasChildElements(Node node)
+   {
+      NodeList nlist = node.getChildNodes();
+      for (int i = 0; i < nlist.getLength(); i++)
+      {
+         Node child = nlist.item(i);
+         if (child.getNodeType() == Node.ELEMENT_NODE)
+            return true;
+      }
+      return false;
+   }
+
+   /** Gets child elements
+    */
+   public static Iterator<Element> getChildElements(Node node)
+   {
+      List<Element> list = new LinkedList<Element>();
+      NodeList nlist = node.getChildNodes();
+      for (int i = 0; i < nlist.getLength(); i++)
+      {
+         Node child = nlist.item(i);
+         if (child.getNodeType() == Node.ELEMENT_NODE)
+            list.add((Element)child);
+      }
+      return list.iterator();
+   }
+
+   /** Get the concatenated text content, or null.
+    */
+   public static String getTextContent(Node node)
+   {
+      boolean hasTextContent = false;
+      StringBuffer buffer = new StringBuffer();
+      NodeList nlist = node.getChildNodes();
+      for (int i = 0; i < nlist.getLength(); i++)
+      {
+         Node child = nlist.item(i);
+         if (child.getNodeType() == Node.TEXT_NODE)
+         {
+            buffer.append(child.getNodeValue());
+            hasTextContent = true;
+         }
+      }
+      return (hasTextContent ? buffer.toString() : null);
+   }
+
+   /** Gets the first child element
+    */
+   public static Element getFirstChildElement(Node node)
+   {
+      return getFirstChildElement(node, false);
+   }
+
+   /** Gets the first child element
+    */
+   public static Element getFirstChildElement(Node node, boolean recursive)
+   {
+      return getFirstChildElementIntern(node, null, recursive);
+   }
+
+   /** Gets the first child element for a given local name without namespace
+    */
+   public static Element getFirstChildElement(Node node, String nodeName)
+   {
+      return getFirstChildElement(node, nodeName, false);
+   }
+
+   /** Gets the first child element for a given local name without namespace
+    */
+   public static Element getFirstChildElement(Node node, String nodeName, boolean recursive)
+   {
+      return getFirstChildElementIntern(node, new QName(nodeName), recursive);
+   }
+
+   /** Gets the first child element for a given qname
+    */
+   public static Element getFirstChildElement(Node node, QName nodeName)
+   {
+      return getFirstChildElement(node, nodeName, false);
+   }
+
+   /** Gets the first child element for a given qname
+    */
+   public static Element getFirstChildElement(Node node, QName nodeName, boolean recursive)
+   {
+      return getFirstChildElementIntern(node, nodeName, recursive);
+   }
+
+   private static Element getFirstChildElementIntern(Node node, QName nodeName, boolean recursive)
+   {
+      Element childElement = null;
+      Iterator it = getChildElementsIntern(node, nodeName, recursive);
+      if (it.hasNext())
+      {
+         childElement = (Element)it.next();
+      }
+      return childElement;
+   }
+
+   /** Gets the child elements for a given local name without namespace
+    */
+   public static Iterator getChildElements(Node node, String nodeName)
+   {
+      return getChildElements(node, nodeName, false);
+   }
+
+   /** Gets the child elements for a given local name without namespace
+    */
+   public static Iterator getChildElements(Node node, String nodeName, boolean recursive)
+   {
+      return getChildElementsIntern(node, new QName(nodeName), recursive);
+   }
+
+   /** Gets the child element for a given qname
+    */
+   public static Iterator getChildElements(Node node, QName nodeName)
+   {
+      return getChildElements(node, nodeName, false);
+   }
+
+   /** Gets the child element for a given qname
+    */
+   public static Iterator getChildElements(Node node, QName nodeName, boolean recursive)
+   {
+      return getChildElementsIntern(node, nodeName, recursive);
+   }
+
+   public static List<Element> getChildElementsAsList(Node node, String nodeName)
+   {
+      return getChildElementsAsList(node, nodeName, false);
+   }
+
+   public static List<Element> getChildElementsAsList(Node node, String nodeName, boolean recursive)
+   {
+      return getChildElementsAsListIntern(node, new QName(nodeName), recursive);
+   }
+
+   public static List<Element> getChildElementsAsList(Node node, QName nodeName)
+   {
+      return getChildElementsAsList(node, nodeName, false);
+   }
+
+   public static List<Element> getChildElementsAsList(Node node, QName nodeName, boolean recursive)
+   {
+      return getChildElementsAsListIntern(node, nodeName, recursive);
+   }
+
+   private static List<Element> getChildElementsAsListIntern(Node node, QName nodeName, boolean recursive)
+   {
+      List<Element> list = new LinkedList<Element>();
+      NodeList nlist = node.getChildNodes();
+      for (int i = 0; i < nlist.getLength(); i++)
+      {
+         Node child = nlist.item(i);
+         if (child.getNodeType() == Node.ELEMENT_NODE)
+         {
+            search(list, (Element)child, nodeName, recursive);
+         }
+      }
+      return list;
+   }
+
+   private static void search(List<Element> list, Element baseElement, QName nodeName, boolean recursive)
+   {
+      if (nodeName == null)
+      {
+         list.add(baseElement);
+      }
+      else
+      {
+         QName qname;
+         if (nodeName.getNamespaceURI().length() > 0)
+         {
+            qname = new QName(baseElement.getNamespaceURI(), baseElement.getLocalName());
+         }
+         else
+         {
+            qname = new QName(baseElement.getLocalName());
+         }
+         if (qname.equals(nodeName))
+         {
+            list.add(baseElement);
+         }
+      }
+      if (recursive)
+      {
+         NodeList nlist = baseElement.getChildNodes();
+         for (int i = 0; i < nlist.getLength(); i++)
+         {
+            Node child = nlist.item(i);
+            if (child.getNodeType() == Node.ELEMENT_NODE)
+            {
+               search(list, (Element)child, nodeName, recursive);
+            }
+         }
+      }
+   }
+
+   private static Iterator getChildElementsIntern(Node node, QName nodeName, boolean recursive)
+   {
+      return getChildElementsAsListIntern(node, nodeName, recursive).iterator();
+   }
+
+   /** Gets parent element or null if there is none
+    */
+   public static Element getParentElement(Node node)
+   {
+      Node parent = node.getParentNode();
+      return (parent instanceof Element ? (Element)parent : null);
+   }
+
+   /** Get the owner document that is associated with the current thread */
+   public static Document getOwnerDocument()
+   {
+      Document doc = documentThreadLocal.get();
+      if (doc == null)
+      {
+         doc = getDocumentBuilder().newDocument();
+         documentThreadLocal.set(doc);
+      }
+      return doc;
+   }
+
+   public static Element sourceToElement(Source source) throws IOException
+   {
+      Element retElement = null;
+
+      try
+      {
+         if (source instanceof StreamSource)
+         {
+            StreamSource streamSource = (StreamSource)source;
+
+            InputStream ins = streamSource.getInputStream();
+            if (ins != null)
+            {
+               retElement = DOMUtils.parse(ins);
+            }
+            else
+            {
+               Reader reader = streamSource.getReader();
+               retElement = DOMUtils.parse(new InputSource(reader));
+            }
+         }
+         else if (source instanceof DOMSource)
+         {
+            DOMSource domSource = (DOMSource)source;
+            Node node = domSource.getNode();
+            if (node instanceof Element)
+            {
+               retElement = (Element)node;
+            }
+            else if (node instanceof Document)
+            {
+               retElement = ((Document)node).getDocumentElement();
+            }
+            else
+            {
+               throw new RuntimeException("Unsupported Node type: " + node.getClass().getName());
+            }
+         }
+         else if (source instanceof SAXSource)
+         {
+            // The fact that JAXBSource derives from SAXSource is an implementation detail.
+            // Thus in general applications are strongly discouraged from accessing methods defined on SAXSource.
+            // The XMLReader object obtained by the getXMLReader method shall be used only for parsing the InputSource object returned by the getInputSource method.
+
+            TransformerFactory tf = TransformerFactory.newInstance();
+            ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
+            Transformer transformer = tf.newTransformer();
+            transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+            transformer.setOutputProperty(OutputKeys.METHOD, "xml");
+            transformer.transform(source, new StreamResult(baos));
+            retElement = DOMUtils.parse(new ByteArrayInputStream(baos.toByteArray()));
+         }
+         else
+         {
+            throw new RuntimeException("Source type not implemented: " + source.getClass().getName());
+         }
+
+      }
+      catch (TransformerException ex)
+      {
+         IOException ioex = new IOException();
+         ioex.initCause(ex);
+         throw ioex;
+      }
+
+      return retElement;
+   }
+}
\ No newline at end of file

Added: projects/gwt-console/trunk/server/src/main/java/org/jboss/bpm/console/server/util/ServiceLoader.java
===================================================================
--- projects/gwt-console/trunk/server/src/main/java/org/jboss/bpm/console/server/util/ServiceLoader.java	                        (rev 0)
+++ projects/gwt-console/trunk/server/src/main/java/org/jboss/bpm/console/server/util/ServiceLoader.java	2008-10-31 09:09:52 UTC (rev 2690)
@@ -0,0 +1,249 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.bpm.console.server.util;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Properties;
+
+/**
+ * Load a service class using this ordered lookup procedure
+ *
+ * @author Thomas.Diesler at jboss.com
+ * @since 14-Dec-2006
+ */
+public abstract class ServiceLoader
+{
+   /**
+    * This method uses the algorithm below using the JAXWS Provider as an example.
+    *
+    * 1. If a resource with the name of META-INF/services/javax.xml.ws.spi.Provider exists, then
+    * its first line, if present, is used as the UTF-8 encoded name of the implementation class.
+    *
+    * 2. If the ${java.home}/lib/jaxws.properties file exists and it is readable by the
+    * java.util.Properties.load(InputStream) method and it contains an entry whose key is
+    * javax.xml.ws.spi.Provider, then the value of that entry is used as the name of the implementation class.
+    *
+    * 3. If a system property with the name javax.xml.ws.spi.Provider is defined, then its value is used
+    * as the name of the implementation class.
+    *
+    * 4. Finally, a default implementation class name is used.
+    */
+   public static Object loadService(String propertyName, String defaultFactory)
+   {
+      Object factory = loadFromServices(propertyName, null);
+      if (factory == null)
+      {
+         factory = loadFromPropertiesFile(propertyName, null);
+      }
+      if (factory == null)
+      {
+         factory = loadFromSystemProperty(propertyName, defaultFactory);
+      }
+      return factory;
+   }
+
+   /** Use the Services API (as detailed in the JAR specification), if available, to determine the classname.
+    */
+   public static Object loadFromServices(String propertyName, String defaultFactory)
+   {
+      Object factory = null;
+      String factoryName = null;
+      ClassLoader loader = Thread.currentThread().getContextClassLoader();
+
+      // Use the Services API (as detailed in the JAR specification), if available, to determine the classname.
+      String filename = "META-INF/services/" + propertyName;
+      InputStream inStream = loader.getResourceAsStream(filename);
+      if (inStream != null)
+      {
+         try
+         {
+            BufferedReader br = new BufferedReader(new InputStreamReader(inStream, "UTF-8"));
+            factoryName = br.readLine();
+            br.close();
+            if (factoryName != null)
+            {
+               Class factoryClass = loader.loadClass(factoryName);
+               factory = factoryClass.newInstance();
+            }
+         }
+         catch (Throwable t)
+         {
+            throw new IllegalStateException("Failed to load " + propertyName + ": " + factoryName, t);
+         }
+      }
+
+      // Use the default factory implementation class.
+      if (factory == null && defaultFactory != null)
+      {
+         factory = loadDefault(defaultFactory);
+      }
+
+      return factory;
+   }
+
+   /** Use the system property
+    */
+   public static Object loadFromSystemProperty(String propertyName, String defaultFactory)
+   {
+      Object factory = null;
+      ClassLoader loader = Thread.currentThread().getContextClassLoader();
+
+      PrivilegedAction action = new PropertyAccessAction(propertyName);
+      String factoryName = (String)AccessController.doPrivileged(action);
+      if (factoryName != null)
+      {
+         try
+         {
+            //if(log.isDebugEnabled()) log.debug("Load from system property: " + factoryName);
+            Class factoryClass = loader.loadClass(factoryName);
+            factory = factoryClass.newInstance();
+         }
+         catch (Throwable t)
+         {
+            throw new IllegalStateException("Failed to load " + propertyName + ": " + factoryName, t);
+         }
+      }
+
+      // Use the default factory implementation class.
+      if (factory == null && defaultFactory != null)
+      {
+         factory = loadDefault(defaultFactory);
+      }
+
+      return factory;
+   }
+
+   /**
+    * Use the properties file "${java.home}/lib/jaxws.properties" in the JRE directory.
+    * This configuration file is in standard java.util.Properties format and contains the
+    * fully qualified name of the implementation class with the key being the system property defined above.
+    */
+   public static Object loadFromPropertiesFile(String propertyName, String defaultFactory)
+   {
+      Object factory = null;
+      String factoryName = null;
+      ClassLoader loader = Thread.currentThread().getContextClassLoader();
+
+      // Use the properties file "lib/jaxm.properties" in the JRE directory.
+      // This configuration file is in standard java.util.Properties format and contains the fully qualified name of the implementation class with the key being the system property defined above.
+      PrivilegedAction action = new PropertyAccessAction("java.home");
+      String javaHome = (String)AccessController.doPrivileged(action);
+      File jaxmFile = new File(javaHome + "/lib/jaxws.properties");
+      if (jaxmFile.exists())
+      {
+         try
+         {
+            action = new PropertyFileAccessAction(jaxmFile.getCanonicalPath());
+            Properties jaxmProperties = (Properties)AccessController.doPrivileged(action);
+            factoryName = jaxmProperties.getProperty(propertyName);
+            if (factoryName != null)
+            {
+               //if(log.isDebugEnabled()) log.debug("Load from " + jaxmFile + ": " + factoryName);
+               Class factoryClass = loader.loadClass(factoryName);
+               factory = factoryClass.newInstance();
+            }
+         }
+         catch (Throwable t)
+         {
+            throw new IllegalStateException("Failed to load " + propertyName + ": " + factoryName, t);
+         }
+      }
+
+      // Use the default factory implementation class.
+      if (factory == null && defaultFactory != null)
+      {
+         factory = loadDefault(defaultFactory);
+      }
+
+      return factory;
+   }
+
+   private static Object loadDefault(String defaultFactory)
+   {
+      Object factory = null;
+      ClassLoader loader = Thread.currentThread().getContextClassLoader();
+
+      // Use the default factory implementation class.
+      if (defaultFactory != null)
+      {
+         try
+         {
+            //if(log.isDebugEnabled()) log.debug("Load from default: " + factoryName);
+            Class factoryClass = loader.loadClass(defaultFactory);
+            factory = factoryClass.newInstance();
+         }
+         catch (Throwable t)
+         {
+            throw new IllegalStateException("Failed to load: " + defaultFactory, t);
+         }
+      }
+
+      return factory;
+   }
+
+   private static class PropertyAccessAction implements PrivilegedAction
+   {
+      private String name;
+
+      PropertyAccessAction(String name)
+      {
+         this.name = name;
+      }
+
+      public Object run()
+      {
+         return System.getProperty(name);
+      }
+   }
+
+   private static class PropertyFileAccessAction implements PrivilegedAction
+   {
+      private String filename;
+
+      PropertyFileAccessAction(String filename)
+      {
+         this.filename = filename;
+      }
+
+      public Object run()
+      {
+         try
+         {
+            InputStream inStream = new FileInputStream(filename);
+            Properties props = new Properties();
+            props.load(inStream);
+            return props;
+         }
+         catch (IOException ex)
+         {
+            throw new SecurityException("Cannot load properties: " + filename, ex);
+         }
+      }
+   }
+}




More information about the jbpm-commits mailing list