[jbossws-commits] JBossWS SVN: r14278 - in api/trunk/src/main/java/org/jboss: ws/api and 3 other directories.

jbossws-commits at lists.jboss.org jbossws-commits at lists.jboss.org
Fri May 6 08:39:16 EDT 2011


Author: richard.opalka at jboss.com
Date: 2011-05-06 08:39:15 -0400 (Fri, 06 May 2011)
New Revision: 14278

Added:
   api/trunk/src/main/java/org/jboss/ws/api/util/
   api/trunk/src/main/java/org/jboss/ws/api/util/DOMUtils.java
   api/trunk/src/main/java/org/jboss/ws/api/util/SecurityActions.java
   api/trunk/src/main/java/org/jboss/ws/api/util/ServiceLoader.java
Removed:
   api/trunk/src/main/java/org/jboss/wsf/
Modified:
   api/trunk/src/main/java/org/jboss/ws/api/addressing/MAPBuilderFactory.java
   api/trunk/src/main/java/org/jboss/ws/api/tools/WSContractConsumer.java
   api/trunk/src/main/java/org/jboss/ws/api/tools/WSContractProvider.java
Log:
[JBWS-3289] refactoring packages: org.jboss.wsf.spi.util -> org.jboss.ws.api.util

Modified: api/trunk/src/main/java/org/jboss/ws/api/addressing/MAPBuilderFactory.java
===================================================================
--- api/trunk/src/main/java/org/jboss/ws/api/addressing/MAPBuilderFactory.java	2011-05-06 11:35:20 UTC (rev 14277)
+++ api/trunk/src/main/java/org/jboss/ws/api/addressing/MAPBuilderFactory.java	2011-05-06 12:39:15 UTC (rev 14278)
@@ -25,7 +25,7 @@
 import java.security.PrivilegedAction;
 
 import org.jboss.logging.Logger;
-import org.jboss.wsf.spi.util.ServiceLoader;
+import org.jboss.ws.api.util.ServiceLoader;
 
 /**
  * Factory for MAPBuilder; to be used to get an instance of the proper MAPBuilder

Modified: api/trunk/src/main/java/org/jboss/ws/api/tools/WSContractConsumer.java
===================================================================
--- api/trunk/src/main/java/org/jboss/ws/api/tools/WSContractConsumer.java	2011-05-06 11:35:20 UTC (rev 14277)
+++ api/trunk/src/main/java/org/jboss/ws/api/tools/WSContractConsumer.java	2011-05-06 12:39:15 UTC (rev 14278)
@@ -27,7 +27,7 @@
 import java.net.URL;
 import java.util.List;
 
-import org.jboss.wsf.spi.util.ServiceLoader;
+import org.jboss.ws.api.util.ServiceLoader;
 
 /**
  * WSContractConsumer is responsible for generating JAX-WS client and server

Modified: api/trunk/src/main/java/org/jboss/ws/api/tools/WSContractProvider.java
===================================================================
--- api/trunk/src/main/java/org/jboss/ws/api/tools/WSContractProvider.java	2011-05-06 11:35:20 UTC (rev 14277)
+++ api/trunk/src/main/java/org/jboss/ws/api/tools/WSContractProvider.java	2011-05-06 12:39:15 UTC (rev 14278)
@@ -24,7 +24,7 @@
 import java.io.File;
 import java.io.PrintStream;
 
-import org.jboss.wsf.spi.util.ServiceLoader;
+import org.jboss.ws.api.util.ServiceLoader;
 
 /**
  * WSContractProvider is responsible for generating the required portable

Added: api/trunk/src/main/java/org/jboss/ws/api/util/DOMUtils.java
===================================================================
--- api/trunk/src/main/java/org/jboss/ws/api/util/DOMUtils.java	                        (rev 0)
+++ api/trunk/src/main/java/org/jboss/ws/api/util/DOMUtils.java	2011-05-06 12:39:15 UTC (rev 14278)
@@ -0,0 +1,647 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2011, 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.ws.api.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilder;
+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.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * Basic DOM2 utilities
+ *
+ * @author alessio.soldano at jboss.com
+ * @author Thomas.Diesler at jboss.org
+ * 
+ */
+public abstract class DOMUtils
+{
+   private static Logger log = Logger.getLogger(DOMUtils.class);
+
+   /** 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("") && el.getNamespaceURI() != null)
+         {
+            namespaceURI = el.getNamespaceURI();
+         }
+
+         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<QName, String> getAttributes(Element el)
+   {
+      Map<QName, String> attmap = new HashMap<QName, String>();
+      NamedNodeMap attribs = el.getAttributes();
+      int len = attribs.getLength();
+      for (int i = 0; i < len; 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();
+      int len = attribs.getLength();
+      for (int i = 0; i < len; 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"))
+         {
+            if (log.isTraceEnabled())
+               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();
+      int len = nodeList.getLength();
+      if (len == 0)
+         return false;
+
+      for (int i = 0; i < len; 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();
+      int len = nlist.getLength();
+      for (int i = 0; i < len; 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();
+      int len = nlist.getLength();
+      for (int i = 0; i < len; 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;
+      StringBuilder buffer = new StringBuilder();
+      NodeList nlist = node.getChildNodes();
+      int len = nlist.getLength();
+      for (int i = 0; i < len; 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<Element> 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<Element> getChildElements(Node node, String nodeName)
+   {
+      return getChildElements(node, nodeName, false);
+   }
+
+   /** Gets the child elements for a given local name without namespace
+    */
+   public static Iterator<Element> 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<Element> getChildElements(Node node, QName nodeName)
+   {
+      return getChildElements(node, nodeName, false);
+   }
+
+   /** Gets the child element for a given qname
+    */
+   public static Iterator<Element> 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();
+      int len = nlist.getLength();
+      for (int i = 0; i < len; 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();
+         int len = nlist.getLength();
+         for (int i = 0; i < len; i++)
+         {
+            Node child = nlist.item(i);
+            if (child.getNodeType() == Node.ELEMENT_NODE)
+            {
+               search(list, (Element) child, nodeName, recursive);
+            }
+         }
+      }
+   }
+
+   private static Iterator<Element> 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);
+   }
+
+   public static Element sourceToElement(Source source, DocumentBuilder builder) throws IOException
+   {
+      Element retElement = null;
+
+      if (source instanceof StreamSource)
+      {
+         StreamSource streamSource = (StreamSource) source;
+
+         InputStream ins = streamSource.getInputStream();
+         if (ins != null)
+         {
+            retElement = DOMUtils.parse(ins, builder);
+         }
+         Reader reader = streamSource.getReader();
+         if (reader != null)
+         {
+            retElement = DOMUtils.parse(new InputSource(reader), builder);
+         }
+      }
+      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 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.
+
+         final boolean hasInputSource = ((SAXSource) source).getInputSource() != null;
+         final boolean hasXMLReader = ((SAXSource) source).getXMLReader() != null;
+
+         if (hasInputSource || hasXMLReader)
+         {
+            try
+            {
+               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()), builder);
+            }
+            catch (TransformerException ex)
+            {
+               throw new IOException(ex);
+            }
+         }
+      }
+      else
+      {
+         throw new RuntimeException("Source type not implemented: " + source.getClass().getName());
+      }
+
+      return retElement;
+   }
+
+   /** Parse the given XML string and return the root Element
+    */
+   public static Element parse(String xmlString, DocumentBuilder builder) throws IOException
+   {
+      try
+      {
+         return parse(new ByteArrayInputStream(xmlString.getBytes("UTF-8")), builder);
+      }
+      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, DocumentBuilder builder) throws IOException
+   {
+      try
+      {
+         Document doc;
+         synchronized (builder) //synchronize to prevent concurrent parsing on the same DocumentBuilder
+         {
+            doc = builder.parse(xmlStream);
+         }
+         return doc.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, DocumentBuilder builder) throws IOException
+   {
+      try
+      {
+         Document doc;
+         synchronized (builder) //synchronize to prevent concurrent parsing on the same DocumentBuilder
+         {
+            doc = builder.parse(source);
+         }
+         return doc.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, prefix and uri
+    */
+   public static Element createElement(String localPart, String prefix, String uri, Document doc)
+   {
+      if (prefix == null || prefix.length() == 0)
+      {
+         if (log.isTraceEnabled())
+            log.trace("createElement {" + uri + "}" + localPart);
+         return doc.createElementNS(uri, localPart);
+      }
+      else
+      {
+         if (log.isTraceEnabled())
+            log.trace("createElement {" + uri + "}" + prefix + ":" + localPart);
+         return doc.createElementNS(uri, prefix + ":" + localPart);
+      }
+   }
+}


Property changes on: api/trunk/src/main/java/org/jboss/ws/api/util/DOMUtils.java
___________________________________________________________________
Added: svn:executable
   + *

Added: api/trunk/src/main/java/org/jboss/ws/api/util/SecurityActions.java
===================================================================
--- api/trunk/src/main/java/org/jboss/ws/api/util/SecurityActions.java	                        (rev 0)
+++ api/trunk/src/main/java/org/jboss/ws/api/util/SecurityActions.java	2011-05-06 12:39:15 UTC (rev 14278)
@@ -0,0 +1,142 @@
+/*
+ * 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.ws.api.util;
+
+import java.io.InputStream;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+/**
+ * Security actions for this package
+ * 
+ * @author alessio.soldano at jboss.com
+ * @since 19-Jun-2009
+ *
+ */
+class SecurityActions
+{
+   /**
+    * Get context classloader.
+    * 
+    * @return the current context classloader
+    */
+   static ClassLoader getContextClassLoader()
+   {
+      SecurityManager sm = System.getSecurityManager();
+      if (sm == null)
+      {
+         return Thread.currentThread().getContextClassLoader();
+      }
+      else
+      {
+         return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+            public ClassLoader run()
+            {
+               return Thread.currentThread().getContextClassLoader();
+            }
+         });
+      }
+   }
+   
+   /**
+    * Set context classloader.
+    * 
+    */
+   static void setContextClassLoader(final ClassLoader cl)
+   {
+      SecurityManager sm = System.getSecurityManager();
+      if (sm == null)
+      {
+         Thread.currentThread().setContextClassLoader(cl);
+      }
+      else
+      {
+         AccessController.doPrivileged(new PrivilegedAction<Object>() {
+            public Object run()
+            {
+               Thread.currentThread().setContextClassLoader(cl);
+               return null;
+            }
+         });
+      }
+   }
+   
+   /**
+    * Get resource as stream
+    * 
+    * @param cl
+    * @param filename
+    * @return input stream
+    * @throws PrivilegedActionException
+    */
+   static InputStream getResourceAsStream(final ClassLoader cl, final String filename)
+   {
+      SecurityManager sm = System.getSecurityManager();
+      if (sm == null)
+      {
+         return cl.getResourceAsStream(filename);
+      }
+      else
+      {
+         return AccessController.doPrivileged(new PrivilegedAction<InputStream>() {
+            public InputStream run()
+            {
+               return cl.getResourceAsStream(filename);
+            }
+         });
+      }
+   }
+   
+   /**
+    * Load a class using the provided classloader
+    * 
+    * @param name
+    * @return
+    * @throws PrivilegedActionException
+    */
+   static Class<?> loadClass(final ClassLoader cl, final String name) throws PrivilegedActionException, ClassNotFoundException
+   {
+      SecurityManager sm = System.getSecurityManager();
+      if (sm == null)
+      {
+         return cl.loadClass(name);
+      }
+      else
+      {
+         return AccessController.doPrivileged(new PrivilegedExceptionAction<Class<?>>() {
+            public Class<?> run() throws PrivilegedActionException
+            {
+               try
+               {
+                  return cl.loadClass(name);
+               }
+               catch (Exception e)
+               {
+                  throw new PrivilegedActionException(e);
+               }
+            }
+         });
+      }
+   }
+}

Added: api/trunk/src/main/java/org/jboss/ws/api/util/ServiceLoader.java
===================================================================
--- api/trunk/src/main/java/org/jboss/ws/api/util/ServiceLoader.java	                        (rev 0)
+++ api/trunk/src/main/java/org/jboss/ws/api/util/ServiceLoader.java	2011-05-06 12:39:15 UTC (rev 14278)
@@ -0,0 +1,330 @@
+/*
+ * 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.ws.api.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.Collections;
+import java.util.Map;
+import java.util.Properties;
+import java.util.WeakHashMap;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Load a service class using this ordered lookup procedure
+ *
+ * @author Thomas.Diesler at jboss.com
+ * @author alessio.soldano at jboss.com
+ * @since 14-Dec-2006
+ */
+public final class ServiceLoader
+{
+   /**
+    * A synchronized weak hash map that keeps factory names retrieved using Service API (META-INF/services/*) for each classloader.
+    * Weak keys are used to remove entries when classloaders are garbage collected; values are service-property-name -> factory name maps.
+    */
+   private static Map<ClassLoader, Map<String, String>> serviceMap = Collections.synchronizedMap(new WeakHashMap<ClassLoader, Map<String, String>>());
+   
+   /**
+    * Constructor.
+    */
+   private ServiceLoader()
+   {
+       // forbidden instantiation
+   }
+
+   /**
+    * 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.
+    * 
+    * @param propertyName   The property name for the service to resolve
+    * @param defaultFactory Default factory class name to be used when not able to resolve anything
+    * @param cl             The classLoader to be used for loading resolved service
+    * @return               A new instance of the required service
+    */
+   public static Object loadService(String propertyName, String defaultFactory, ClassLoader cl)
+   {
+      Object factory = loadFromServices(propertyName, cl);
+      if (factory == null)
+      {
+         factory = loadFromPropertiesFile(propertyName, cl);
+      }
+      if (factory == null)
+      {
+         factory = loadFromSystemProperty(propertyName, defaultFactory, cl);
+      }
+      return factory;
+   }
+   
+   /**
+    * 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.
+    * 
+    * This is equivalent to calling {@link loadService(String propertyName, String defaultFactory, ClassLoader cl)}
+    * passing in the Thread.currentThread().getContextClassLoader().
+    * 
+    * @param propertyName   The property name for the service to resolve
+    * @param defaultFactory Default factory class name to be used when not able to resolve anything
+    * @return               A new instance of the required service
+    */
+   public static Object loadService(String propertyName, String defaultFactory)
+   {
+      return loadService(propertyName, defaultFactory, SecurityActions.getContextClassLoader());
+   }
+   
+   /** Use the Services API (as detailed in the JAR specification), if available, to determine the classname.
+    */
+   private static Object loadFromServices(String propertyName, ClassLoader loader)
+   {
+      Object factory = null;
+      String factoryName = null;
+      
+      // Use the Services API (as detailed in the JAR specification), if available, to determine the classname.
+      String filename = "META-INF/services/" + propertyName;
+      
+      try
+      {
+         factoryName = getServiceNameUsingCache(loader, filename);
+         if (factoryName != null)
+         {
+            Class<?> factoryClass = SecurityActions.loadClass(loader, factoryName);
+            factory = factoryClass.newInstance();
+         }
+      }
+      catch (Throwable t)
+      {
+         throw new IllegalStateException("Failed to load " + propertyName + ": " + factoryName, t);
+      }
+      
+      return factory;
+   }
+
+   private static String getServiceNameUsingCache(ClassLoader loader, String filename) throws IOException
+   {
+      Map<String, String> map = serviceMap.get(loader);
+      if (map != null && map.containsKey(filename))
+      {
+         return map.get(filename);
+      }
+      else
+      {
+         if (map == null)
+         {
+            map = new ConcurrentHashMap<String, String>();
+            serviceMap.put(loader, map);
+         }
+         InputStream inStream = SecurityActions.getResourceAsStream(loader, filename);
+         String factoryName = null;
+         if (inStream != null)
+         {
+            BufferedReader br = new BufferedReader(new InputStreamReader(inStream, "UTF-8"));
+            factoryName = br.readLine();
+            br.close();
+            map.put(filename, factoryName);
+         }
+         return factoryName;
+      }
+   }
+   
+   /** Use the system property
+    */
+   private static Object loadFromSystemProperty(String propertyName, String defaultFactory, ClassLoader loader)
+   {
+      Object factory = null;
+
+      PrivilegedAction<String> action = new PropertyAccessAction(propertyName);
+      String factoryName = AccessController.doPrivileged(action);
+      if (factoryName != null)
+      {
+         try
+         {
+            Class<?> factoryClass = SecurityActions.loadClass(loader, 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, loader);
+      }
+
+      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.
+    */
+   private static Object loadFromPropertiesFile(String propertyName, ClassLoader loader)
+   {
+      Object factory = null;
+      String factoryName = null;
+
+      // 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<String> propertyReadAction = new PropertyAccessAction("java.home");
+      String javaHome = AccessController.doPrivileged(propertyReadAction);
+      File jaxmFile = new File(javaHome + "/lib/jaxws.properties");
+      if ((Boolean)AccessController.doPrivileged(new PropertyFileExistAction(jaxmFile)))
+      {
+         try
+         {
+            PropertyFileAccessAction propertyFileAccessAction = new PropertyFileAccessAction(jaxmFile.getCanonicalPath());
+            Properties jaxmProperties = AccessController.doPrivileged(propertyFileAccessAction);
+            factoryName = jaxmProperties.getProperty(propertyName);
+            if (factoryName != null)
+            {
+               Class<?> factoryClass = SecurityActions.loadClass(loader, factoryName);
+               factory = factoryClass.newInstance();
+            }
+         }
+         catch (Throwable t)
+         {
+            throw new IllegalStateException("Failed to load " + propertyName + ": " + factoryName, t);
+         }
+      }
+
+      return factory;
+   }
+
+   private static Object loadDefault(String defaultFactory, ClassLoader loader)
+   {
+      Object factory = null;
+
+      // Use the default factory implementation class.
+      if (defaultFactory != null)
+      {
+         try
+         {
+            Class<?> factoryClass = SecurityActions.loadClass(loader, defaultFactory);
+            factory = factoryClass.newInstance();
+         }
+         catch (Throwable t)
+         {
+            throw new IllegalStateException("Failed to load: " + defaultFactory, t);
+         }
+      }
+
+      return factory;
+   }
+
+   private static class PropertyAccessAction implements PrivilegedAction<String>
+   {
+      private String name;
+
+      PropertyAccessAction(String name)
+      {
+         this.name = name;
+      }
+
+      public String run()
+      {
+         return System.getProperty(name);
+      }
+   }
+
+   private static class PropertyFileAccessAction implements PrivilegedAction<Properties>
+   {
+      private String filename;
+
+      PropertyFileAccessAction(String filename)
+      {
+         this.filename = filename;
+      }
+
+      public Properties run()
+      {
+         InputStream inStream = null;
+         try
+         {
+            inStream = new FileInputStream(filename);
+            Properties props = new Properties();
+            props.load(inStream);
+            return props;
+         }
+         catch (IOException ex)
+         {
+            throw new SecurityException("Cannot load properties: " + filename, ex);
+         }
+         finally
+         {
+            try
+            {
+               if (inStream != null)
+               {
+                  inStream.close();
+               }
+            }
+            catch (Exception ignore) {}
+         }
+      }
+   }
+   
+   private static class PropertyFileExistAction implements PrivilegedAction<Boolean>
+   {
+      private File file;
+
+      PropertyFileExistAction(File file)
+      {
+         this.file = file;
+      }
+
+      public Boolean run()
+      {
+         return file.exists();
+      }
+   }
+}



More information about the jbossws-commits mailing list