[jbossws-commits] JBossWS SVN: r14292 - in common/trunk/src/main/java/org/jboss/ws: common and 1 other directories.
jbossws-commits at lists.jboss.org
jbossws-commits at lists.jboss.org
Fri May 6 17:42:01 EDT 2011
Author: richard.opalka at jboss.com
Date: 2011-05-06 17:42:00 -0400 (Fri, 06 May 2011)
New Revision: 14292
Added:
common/trunk/src/main/java/org/jboss/ws/common/utils/AbstractWSDLFilePublisher.java
common/trunk/src/main/java/org/jboss/ws/common/utils/DelegateClassLoader.java
common/trunk/src/main/java/org/jboss/ws/common/utils/HashCodeUtil.java
common/trunk/src/main/java/org/jboss/ws/common/utils/JBossWSEntityResolver.java
common/trunk/src/main/java/org/jboss/ws/common/utils/JarUrlConnection.java
common/trunk/src/main/java/org/jboss/ws/common/utils/NullPrintStream.java
common/trunk/src/main/java/org/jboss/ws/common/utils/ResourceURL.java
common/trunk/src/main/java/org/jboss/ws/common/utils/SecurityActions.java
common/trunk/src/main/java/org/jboss/ws/common/utils/XMLPredefinedEntityReferenceResolver.java
Removed:
common/trunk/src/main/java/org/jboss/ws/core/
common/trunk/src/main/java/org/jboss/ws/tools/
Modified:
common/trunk/src/main/java/org/jboss/ws/common/DOMUtils.java
Log:
[JBWS-3289] final refactoring of common packages
Modified: common/trunk/src/main/java/org/jboss/ws/common/DOMUtils.java
===================================================================
--- common/trunk/src/main/java/org/jboss/ws/common/DOMUtils.java 2011-05-06 21:39:51 UTC (rev 14291)
+++ common/trunk/src/main/java/org/jboss/ws/common/DOMUtils.java 2011-05-06 21:42:00 UTC (rev 14292)
@@ -46,7 +46,7 @@
import org.jboss.logging.Logger;
import org.jboss.ws.Constants;
-import org.jboss.ws.core.utils.JBossWSEntityResolver;
+import org.jboss.ws.common.utils.JBossWSEntityResolver;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
Added: common/trunk/src/main/java/org/jboss/ws/common/utils/AbstractWSDLFilePublisher.java
===================================================================
--- common/trunk/src/main/java/org/jboss/ws/common/utils/AbstractWSDLFilePublisher.java (rev 0)
+++ common/trunk/src/main/java/org/jboss/ws/common/utils/AbstractWSDLFilePublisher.java 2011-05-06 21:42:00 UTC (rev 14292)
@@ -0,0 +1,248 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2010, 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.common.utils;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.wsdl.Definition;
+import javax.wsdl.Import;
+import javax.wsdl.factory.WSDLFactory;
+
+import org.jboss.logging.Logger;
+import org.jboss.ws.common.DOMUtils;
+import org.jboss.ws.common.IOUtils;
+import org.jboss.wsf.spi.SPIProvider;
+import org.jboss.wsf.spi.SPIProviderResolver;
+import org.jboss.wsf.spi.deployment.ArchiveDeployment;
+import org.jboss.wsf.spi.management.ServerConfig;
+import org.jboss.wsf.spi.management.ServerConfigFactory;
+import org.w3c.dom.Element;
+
+/**
+ * Abstract WSDL file publisher
+ *
+ * @author alessio.soldano at jboss.com
+ * @since 25-Mar-2010
+ *
+ */
+public abstract class AbstractWSDLFilePublisher
+{
+ private static final Logger log = Logger.getLogger(AbstractWSDLFilePublisher.class);
+
+ // The deployment info for the web service archive
+ protected ArchiveDeployment dep;
+ // The expected wsdl location in the deployment
+ protected String expLocation;
+ // The server config
+ protected ServerConfig serverConfig;
+
+ public AbstractWSDLFilePublisher(ArchiveDeployment dep)
+ {
+ this.dep = dep;
+
+ serverConfig = dep.getAttachment(ServerConfig.class);
+ if (serverConfig == null)
+ {
+ SPIProvider spiProvider = SPIProviderResolver.getInstance().getProvider();
+ serverConfig = spiProvider.getSPI(ServerConfigFactory.class).getServerConfig();
+ }
+
+ if (dep.getType().toString().endsWith("JSE"))
+ {
+ expLocation = "WEB-INF/wsdl/";
+ }
+ else
+ {
+ expLocation = "META-INF/wsdl/";
+ }
+ }
+
+ /** Publish the wsdl imports for a given wsdl definition
+ */
+ @SuppressWarnings("unchecked")
+ protected void publishWsdlImports(URL parentURL, Definition parentDefinition, List<String> published) throws Exception
+ {
+ String baseURI = parentURL.toExternalForm();
+
+ Iterator it = parentDefinition.getImports().values().iterator();
+ while (it.hasNext())
+ {
+ for (Import wsdlImport : (List<Import>)it.next())
+ {
+ String locationURI = wsdlImport.getLocationURI();
+ Definition subdef = wsdlImport.getDefinition();
+
+ // its an external import, don't publish locally
+ if (locationURI.startsWith("http://") == false)
+ {
+ // infinity loops prevention
+ if (published.contains(locationURI))
+ {
+ continue;
+ }
+ else
+ {
+ published.add(locationURI);
+ }
+
+ URL targetURL = new URL(baseURI.substring(0, baseURI.lastIndexOf("/") + 1) + locationURI);
+ File targetFile = new File(targetURL.getPath());
+ targetFile.getParentFile().mkdirs();
+
+ WSDLFactory wsdlFactory = WSDLFactory.newInstance();
+ javax.wsdl.xml.WSDLWriter wsdlWriter = wsdlFactory.newWSDLWriter();
+ FileWriter fw = new FileWriter(targetFile);
+ wsdlWriter.writeWSDL(subdef, fw);
+ fw.close();
+
+ log.debug("WSDL import published to: " + targetURL);
+
+ // recursively publish imports
+ publishWsdlImports(targetURL, subdef, published);
+
+ // Publish XMLSchema imports
+ Element subdoc = DOMUtils.parse(targetURL.openStream());
+ publishSchemaImports(targetURL, subdoc, published);
+ }
+ }
+ }
+ }
+
+ /** Publish the schema imports for a given wsdl definition
+ */
+ protected void publishSchemaImports(URL parentURL, Element element, List<String> published) throws Exception
+ {
+ String baseURI = parentURL.toExternalForm();
+
+ Iterator<Element> it = DOMUtils.getChildElements(element);
+ while (it.hasNext())
+ {
+ Element childElement = (Element)it.next();
+ if ("import".equals(childElement.getLocalName()) || "include".equals(childElement.getLocalName()))
+ {
+ String schemaLocation = childElement.getAttribute("schemaLocation");
+ if (schemaLocation.length() > 0)
+ {
+ if (schemaLocation.startsWith("http://") == false)
+ {
+ // infinity loops prevention
+ if (published.contains(schemaLocation))
+ {
+ continue;
+ }
+ else
+ {
+ published.add(schemaLocation);
+ }
+
+ URL xsdURL = new URL(baseURI.substring(0, baseURI.lastIndexOf("/") + 1) + schemaLocation);
+ File targetFile = new File(xsdURL.getPath());
+ targetFile.getParentFile().mkdirs();
+
+ String deploymentName = dep.getCanonicalName();
+
+ // get the resource path including the separator
+ int index = baseURI.indexOf(deploymentName) + 1;
+ String resourcePath = baseURI.substring(index + deploymentName.length());
+ //check for sub-directories
+ resourcePath = resourcePath.substring(0, resourcePath.lastIndexOf("/") + 1);
+
+ resourcePath = expLocation + resourcePath + schemaLocation;
+ while (resourcePath.indexOf("//") != -1)
+ {
+ resourcePath = resourcePath.replace("//", "/");
+ }
+ URL resourceURL = dep.getResourceResolver().resolve(resourcePath);
+// URL resourceURL = dep.getMetaDataFileURL(resourcePath);
+ InputStream is = new ResourceURL(resourceURL).openStream();
+ if (is == null)
+ throw new IllegalArgumentException("Cannot find schema import in deployment: " + resourcePath);
+
+ FileOutputStream fos = null;
+ try
+ {
+ fos = new FileOutputStream(targetFile);
+ IOUtils.copyStream(fos, is);
+ }
+ finally
+ {
+ if (fos != null) fos.close();
+ }
+
+ log.debug("XMLSchema import published to: " + xsdURL);
+
+ // recursively publish imports
+ Element subdoc = DOMUtils.parse(xsdURL.openStream());
+ publishSchemaImports(xsdURL, subdoc, published);
+ }
+ }
+ }
+ else
+ {
+ publishSchemaImports(parentURL, childElement, published);
+ }
+ }
+ }
+
+ /**
+ * Delete the published wsdl
+ */
+ public void unpublishWsdlFiles() throws IOException
+ {
+ String deploymentDir = (dep.getParent() != null ? dep.getParent().getSimpleName() : dep.getSimpleName());
+
+ File serviceDir = new File(serverConfig.getServerDataDir().getCanonicalPath() + "/wsdl/" + deploymentDir);
+ deleteWsdlPublishDirectory(serviceDir);
+ }
+
+ /**
+ * Delete the published wsdl document, traversing down the dir structure
+ */
+ protected void deleteWsdlPublishDirectory(File dir) throws IOException
+ {
+ String[] files = dir.list();
+ for (int i = 0; files != null && i < files.length; i++)
+ {
+ String fileName = files[i];
+ File file = new File(dir + "/" + fileName);
+ if (file.isDirectory())
+ {
+ deleteWsdlPublishDirectory(file);
+ }
+ else
+ {
+ if (file.delete() == false)
+ log.warn("Cannot delete published wsdl document: " + file.toURL());
+ }
+ }
+
+ // delete the directory as well
+ dir.delete();
+ }
+}
Added: common/trunk/src/main/java/org/jboss/ws/common/utils/DelegateClassLoader.java
===================================================================
--- common/trunk/src/main/java/org/jboss/ws/common/utils/DelegateClassLoader.java (rev 0)
+++ common/trunk/src/main/java/org/jboss/ws/common/utils/DelegateClassLoader.java 2011-05-06 21:42:00 UTC (rev 14292)
@@ -0,0 +1,145 @@
+/*
+ * 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.common.utils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.security.SecureClassLoader;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.NoSuchElementException;
+
+/**
+ * A delegate classloader
+ *
+ * @author alessio.soldano at jboss.com
+ *
+ */
+public class DelegateClassLoader extends SecureClassLoader
+{
+ private ClassLoader delegate;
+
+ private ClassLoader parent;
+
+ public DelegateClassLoader(final ClassLoader delegate, final ClassLoader parent)
+ {
+ super(parent);
+ this.delegate = delegate;
+ this.parent = parent;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Class<?> loadClass(final String className) throws ClassNotFoundException
+ {
+ if (parent != null)
+ {
+ try
+ {
+ return parent.loadClass(className);
+ }
+ catch (ClassNotFoundException cnfe)
+ {
+ //NOOP, use delegate
+ }
+ }
+ return delegate.loadClass(className);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public URL getResource(final String name)
+ {
+ URL url = null;
+ if (parent != null)
+ {
+ url = parent.getResource(name);
+ }
+ return (url == null) ? delegate.getResource(name) : url;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Enumeration<URL> getResources(final String name) throws IOException
+ {
+ final ArrayList<Enumeration<URL>> foundResources = new ArrayList<Enumeration<URL>>();
+
+ foundResources.add(delegate.getResources(name));
+ if (parent != null)
+ {
+ foundResources.add(parent.getResources(name));
+ }
+
+ return new Enumeration<URL>()
+ {
+ private int position = foundResources.size() - 1;
+
+ public boolean hasMoreElements()
+ {
+ while (position >= 0)
+ {
+ if (foundResources.get(position).hasMoreElements())
+ {
+ return true;
+ }
+ position--;
+ }
+ return false;
+ }
+
+ public URL nextElement()
+ {
+ while (position >= 0)
+ {
+ try
+ {
+ return (foundResources.get(position)).nextElement();
+ }
+ catch (NoSuchElementException e)
+ {
+ }
+ position--;
+ }
+ throw new NoSuchElementException();
+ }
+ };
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public InputStream getResourceAsStream(final String name)
+ {
+ URL foundResource = getResource(name);
+ if (foundResource != null)
+ {
+ try
+ {
+ return foundResource.openStream();
+ }
+ catch (IOException e)
+ {
+ }
+ }
+ return null;
+ }
+}
\ No newline at end of file
Added: common/trunk/src/main/java/org/jboss/ws/common/utils/HashCodeUtil.java
===================================================================
--- common/trunk/src/main/java/org/jboss/ws/common/utils/HashCodeUtil.java (rev 0)
+++ common/trunk/src/main/java/org/jboss/ws/common/utils/HashCodeUtil.java 2011-05-06 21:42:00 UTC (rev 14292)
@@ -0,0 +1,146 @@
+/*
+ * 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.common.utils;
+
+import java.lang.reflect.Array;
+
+/**
+ * Collected methods which allow easy implementation of <code>hashCode</code>.
+ *
+ * Example use case:
+ * <pre>
+ * public int hashCode(){
+ * int result = HashCodeUtil.SEED;
+ * //collect the contributions of various fields
+ * result = HashCodeUtil.hash(result, fPrimitive);
+ * result = HashCodeUtil.hash(result, fObject);
+ * result = HashCodeUtil.hash(result, fArray);
+ * return result;
+ * }
+ * </pre>
+ */
+public final class HashCodeUtil
+{
+
+ /**
+ * An initial value for a <code>hashCode</code>, to which is added contributions
+ * from fields. Using a non-zero value decreases collisons of <code>hashCode</code>
+ * values.
+ */
+ public static final int SEED = 23;
+
+ /**
+ * booleans.
+ */
+ public static int hash(int aSeed, boolean aBoolean)
+ {
+ return org.jboss.ws.common.utils.HashCodeUtil.firstTerm(aSeed) + (aBoolean ? 1 : 0);
+ }
+
+ /**
+ * chars.
+ */
+ public static int hash(int aSeed, char aChar)
+ {
+ return org.jboss.ws.common.utils.HashCodeUtil.firstTerm(aSeed) + (int)aChar;
+ }
+
+ /**
+ * ints.
+ */
+ public static int hash(int aSeed, int aInt)
+ {
+ /*
+ * Implementation Note
+ * Note that byte and short are handled by this method, through
+ * implicit conversion.
+ */
+ return org.jboss.ws.common.utils.HashCodeUtil.firstTerm(aSeed) + aInt;
+ }
+
+ /**
+ * longs.
+ */
+ public static int hash(int aSeed, long aLong)
+ {
+ return org.jboss.ws.common.utils.HashCodeUtil.firstTerm(aSeed) + (int)(aLong ^ (aLong >>> 32));
+ }
+
+ /**
+ * floats.
+ */
+ public static int hash(int aSeed, float aFloat)
+ {
+ return org.jboss.ws.common.utils.HashCodeUtil.hash(aSeed, Float.floatToIntBits(aFloat));
+ }
+
+ /**
+ * doubles.
+ */
+ public static int hash(int aSeed, double aDouble)
+ {
+ return org.jboss.ws.common.utils.HashCodeUtil.hash(aSeed, Double.doubleToLongBits(aDouble));
+ }
+
+ /**
+ * <code>aObject</code> is a possibly-null object field, and possibly an array.
+ *
+ * If <code>aObject</code> is an array, then each element may be a primitive
+ * or a possibly-null object.
+ */
+ public static int hash(int aSeed, Object aObject)
+ {
+ int result = aSeed;
+ if (aObject == null)
+ {
+ result = org.jboss.ws.common.utils.HashCodeUtil.hash(result, 0);
+ }
+ else if (!org.jboss.ws.common.utils.HashCodeUtil.isArray(aObject))
+ {
+ result = org.jboss.ws.common.utils.HashCodeUtil.hash(result, aObject.hashCode());
+ }
+ else
+ {
+ int length = Array.getLength(aObject);
+ for (int idx = 0; idx < length; ++idx)
+ {
+ Object item = Array.get(aObject, idx);
+ //recursive call!
+ result = org.jboss.ws.common.utils.HashCodeUtil.hash(result, item);
+ }
+ }
+ return result;
+ }
+
+ /// PRIVATE ///
+ private static final int fODD_PRIME_NUMBER = 37;
+
+ private static int firstTerm(int aSeed)
+ {
+ return org.jboss.ws.common.utils.HashCodeUtil.fODD_PRIME_NUMBER * aSeed;
+ }
+
+ private static boolean isArray(Object aObject)
+ {
+ return aObject.getClass().isArray();
+ }
+}
Added: common/trunk/src/main/java/org/jboss/ws/common/utils/JBossWSEntityResolver.java
===================================================================
--- common/trunk/src/main/java/org/jboss/ws/common/utils/JBossWSEntityResolver.java (rev 0)
+++ common/trunk/src/main/java/org/jboss/ws/common/utils/JBossWSEntityResolver.java 2011-05-06 21:42:00 UTC (rev 14292)
@@ -0,0 +1,200 @@
+/*
+ * 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.common.utils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Map;
+import java.util.Properties;
+import java.util.WeakHashMap;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.jboss.logging.Logger;
+import org.jboss.util.xml.JBossEntityResolver;
+import org.jboss.wsf.spi.classloading.ClassLoaderProvider;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * Dynamically register the JBossWS entities.
+ *
+ * @author Thomas.Diesler at jboss.org
+ * @author Richard.Opalka at jboss.org
+ */
+public class JBossWSEntityResolver extends JBossEntityResolver
+{
+ /**
+ * A synchronized weak hash map that keeps entities' properties for each classloader.
+ * Weak keys are used to remove entries when classloaders are garbage collected; values are filenames -> properties.
+ */
+ private static Map<ClassLoader, Map<String, Properties>> propertiesMap = Collections.synchronizedMap(new WeakHashMap<ClassLoader, Map<String, Properties>>());
+
+ // provide logging
+ private static final Logger log = Logger.getLogger(JBossWSEntityResolver.class);
+
+ public JBossWSEntityResolver()
+ {
+ this("META-INF/jbossws-entities.properties");
+ }
+
+ public JBossWSEntityResolver(final String entitiesResource)
+ {
+ super();
+
+ Properties props = null;
+ ClassLoader loader = SecurityActions.getContextClassLoader();
+ Map<String, Properties> map = propertiesMap.get(loader);
+ if (map != null && map.containsKey(entitiesResource))
+ {
+ props = map.get(entitiesResource);
+ }
+ else
+ {
+ if (map == null)
+ {
+ map = new ConcurrentHashMap<String, Properties>();
+ propertiesMap.put(loader, map);
+ }
+ // load entities
+ props = loadEntitiesMappingFromClasspath(entitiesResource, loader);
+ if (props.size() == 0)
+ throw new IllegalArgumentException("No entities mapping defined in resource file: " + entitiesResource);
+ map.put(entitiesResource, props);
+ }
+
+ // register entities
+ String key = null, val = null;
+ for (Enumeration<Object> keys = props.keys(); keys.hasMoreElements();)
+ {
+ key = (String)keys.nextElement();
+ val = props.getProperty(key);
+
+ registerEntity(key, val);
+ }
+ }
+
+ private Properties loadEntitiesMappingFromClasspath(final String entitiesResource, final ClassLoader classLoader)
+ {
+ return AccessController.doPrivileged(new PrivilegedAction<Properties>()
+ {
+ public Properties run()
+ {
+ //use a delegate classloader: first try lookup using the provided classloader,
+ //otherwise use server integration classloader which has the default configuration
+ final ClassLoader intCl = ClassLoaderProvider.getDefaultProvider().getServerIntegrationClassLoader();
+ InputStream is = new DelegateClassLoader(intCl, classLoader).getResourceAsStream(entitiesResource);
+ // get stream
+ if (is == null)
+ throw new IllegalArgumentException("Resource " + entitiesResource + " not found");
+
+ // load props
+ Properties props = new Properties();
+ try
+ {
+ props.load(is);
+ }
+ catch (IOException ioe)
+ {
+ log.error("Cannot read resource: " + entitiesResource, ioe);
+ }
+ finally
+ {
+ try { is.close(); } catch (IOException ioe) {} // ignore
+ }
+
+ return props;
+ }
+ });
+ }
+
+ public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException
+ {
+ if(log.isTraceEnabled()) log.trace("resolveEntity: [pub=" + publicId + ",sysid=" + systemId + "]");
+ InputSource inputSource = super.resolveEntity(publicId, systemId);
+
+ if (inputSource == null)
+ inputSource = resolveSystemIDAsURL(systemId, log.isTraceEnabled());
+
+ if (inputSource == null)
+ {
+ if (log.isDebugEnabled())
+ log.debug("Cannot resolve entity: [pub=" + publicId + ",sysid=" + systemId + "]");
+ }
+
+ return inputSource;
+ }
+
+ /** Use a ResourceURL to access the resource.
+ * This method should be protected in the super class. */
+ protected InputSource resolveSystemIDAsURL(String id, boolean trace)
+ {
+ if (id == null)
+ return null;
+
+ if (trace)
+ log.trace("resolveIDAsResourceURL, id=" + id);
+
+ InputSource inputSource = null;
+
+ // Try to use the systemId as a URL to the schema
+ try
+ {
+ if (trace)
+ log.trace("Trying to resolve id as a URL");
+
+ URL url = new URL(id);
+ if (url.getProtocol().equalsIgnoreCase("file") == false)
+ log.warn("Trying to resolve id as a non-file URL: " + id);
+
+ InputStream ins = new ResourceURL(url).openStream();
+ if (ins != null)
+ {
+ inputSource = new InputSource(ins);
+ inputSource.setSystemId(id);
+ }
+ else
+ {
+ log.warn("Cannot load id as URL: " + id);
+ }
+
+ if (trace)
+ log.trace("Resolved id as a URL");
+ }
+ catch (MalformedURLException ignored)
+ {
+ if (trace)
+ log.trace("id is not a url: " + id, ignored);
+ }
+ catch (IOException e)
+ {
+ if (trace)
+ log.trace("Failed to obtain URL.InputStream from id: " + id, e);
+ }
+ return inputSource;
+ }
+}
Added: common/trunk/src/main/java/org/jboss/ws/common/utils/JarUrlConnection.java
===================================================================
--- common/trunk/src/main/java/org/jboss/ws/common/utils/JarUrlConnection.java (rev 0)
+++ common/trunk/src/main/java/org/jboss/ws/common/utils/JarUrlConnection.java 2011-05-06 21:42:00 UTC (rev 14292)
@@ -0,0 +1,276 @@
+/*
+ * 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.common.utils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.JarURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.JarInputStream;
+
+/** <code>URLConnection</code> capable of handling multiply-nested jars.
+ *
+ * @author <a href="mailto:bob at eng.werken.com">bob mcwhirter</a>
+ */
+public class JarUrlConnection extends JarURLConnection
+{
+ // ----------------------------------------------------------------------
+ // Instance members
+ // ----------------------------------------------------------------------
+
+ /** Base resource. */
+ private URL baseResource;
+
+ /** Additional nested segments. */
+ private String[] segments;
+
+ /** Terminal input-stream. */
+ private InputStream in;
+
+ // ----------------------------------------------------------------------
+ // Constructors
+ // ----------------------------------------------------------------------
+
+ /** Construct.
+ *
+ * @param url Target URL of the connections.
+ *
+ * @throws java.io.IOException If an error occurs while attempting to initialize
+ * the connection.
+ */
+ public JarUrlConnection(URL url) throws IOException
+ {
+ super(url = normaliseURL(url));
+
+ String baseText = url.getPath();
+
+ int bangLoc = baseText.indexOf("!");
+
+ String baseResourceText = baseText.substring(0, bangLoc);
+
+ String extraText = "";
+
+ if (bangLoc <= (baseText.length() - 2) && baseText.charAt(bangLoc + 1) == '/')
+ {
+ if (bangLoc + 2 == baseText.length())
+ {
+ extraText = "";
+ }
+ else
+ {
+ extraText = baseText.substring(bangLoc + 1);
+ }
+ }
+ else
+ {
+ throw new MalformedURLException("No !/ in url: " + url.toExternalForm());
+ }
+
+ List segments = new ArrayList();
+
+ StringTokenizer tokens = new StringTokenizer(extraText, "!");
+
+ while (tokens.hasMoreTokens())
+ {
+ segments.add(tokens.nextToken());
+ }
+
+ this.segments = (String[])segments.toArray(new String[segments.size()]);
+
+ this.baseResource = new URL(baseResourceText);
+ }
+
+ protected static URL normaliseURL(URL url) throws MalformedURLException
+ {
+ String text = normalizeUrlPath(url.toString());
+
+ if (!text.startsWith("jar:"))
+ {
+ text = "jar:" + text;
+ }
+
+ if (text.indexOf('!') < 0)
+ {
+ text = text + "!/";
+ }
+
+ return new URL(text);
+ }
+
+ // ----------------------------------------------------------------------
+ // Instance methods
+ // ----------------------------------------------------------------------
+
+ /** Retrieve the nesting path segments.
+ *
+ * @return The segments.
+ */
+ protected String[] getSegments()
+ {
+ return this.segments;
+ }
+
+ /** Retrieve the base resource <code>URL</code>.
+ *
+ * @return The base resource url.
+ */
+ protected URL getBaseResource()
+ {
+ return this.baseResource;
+ }
+
+ /** @see java.net.URLConnection
+ */
+ public void connect() throws IOException
+ {
+ if (this.segments.length == 0)
+ {
+ setupBaseResourceInputStream();
+ }
+ else
+ {
+ setupPathedInputStream();
+ }
+ }
+
+ /** Setup the <code>InputStream</code> purely from the base resource.
+ *
+ * @throws java.io.IOException If an I/O error occurs.
+ */
+ protected void setupBaseResourceInputStream() throws IOException
+ {
+ this.in = getBaseResource().openStream();
+ }
+
+ /** Setup the <code>InputStream</code> for URL with nested segments.
+ *
+ * @throws java.io.IOException If an I/O error occurs.
+ */
+ protected void setupPathedInputStream() throws IOException
+ {
+ InputStream curIn = getBaseResource().openStream();
+
+ for (int i = 0; i < this.segments.length; ++i)
+ {
+ curIn = getSegmentInputStream(curIn, segments[i]);
+ }
+
+ this.in = curIn;
+ }
+
+ /** Retrieve the <code>InputStream</code> for the nesting
+ * segment relative to a base <code>InputStream</code>.
+ *
+ * @param baseIn The base input-stream.
+ * @param segment The nesting segment path.
+ *
+ * @return The input-stream to the segment.
+ *
+ * @throws java.io.IOException If an I/O error occurs.
+ */
+ protected InputStream getSegmentInputStream(InputStream baseIn, String segment) throws IOException
+ {
+ JarInputStream jarIn = new JarInputStream(baseIn);
+ JarEntry entry = null;
+
+ while (jarIn.available() != 0)
+ {
+ entry = jarIn.getNextJarEntry();
+
+ if (entry == null)
+ {
+ break;
+ }
+
+ if (("/" + entry.getName()).equals(segment))
+ {
+ return jarIn;
+ }
+ }
+
+ throw new IOException("unable to locate segment: " + segment);
+ }
+
+ /** @see java.net.URLConnection
+ */
+ public InputStream getInputStream() throws IOException
+ {
+ if (this.in == null)
+ {
+ connect();
+ }
+ return this.in;
+ }
+
+ /**
+ * @return JarFile
+ * @throws java.io.IOException
+ * @see java.net.JarURLConnection#getJarFile()
+ */
+ public JarFile getJarFile() throws IOException
+ {
+ String url = baseResource.toExternalForm();
+
+ if (url.startsWith("file:/"))
+ {
+ url = url.substring(6);
+ }
+
+ return new JarFile(URLDecoder.decode(url, "UTF-8"));
+ }
+
+ private static String normalizeUrlPath(String name)
+ {
+ if (name.startsWith("/"))
+ {
+ name = name.substring(1);
+
+ System.out.println("1 name = " + name);
+ }
+
+ // Looking for org/codehaus/werkflow/personality/basic/../common/core-idioms.xml
+ // | i |
+ // +-------+ remove
+ //
+ int i = name.indexOf("/..");
+
+ // Can't be at the beginning because we have no root to refer to so
+ // we start at 1.
+ if (i > 0)
+ {
+ int j = name.lastIndexOf("/", i - 1);
+
+ name = name.substring(0, j) + name.substring(i + 3);
+
+ System.out.println("2 name = " + name);
+ }
+
+ return name;
+ }
+}
Added: common/trunk/src/main/java/org/jboss/ws/common/utils/NullPrintStream.java
===================================================================
--- common/trunk/src/main/java/org/jboss/ws/common/utils/NullPrintStream.java (rev 0)
+++ common/trunk/src/main/java/org/jboss/ws/common/utils/NullPrintStream.java 2011-05-06 21:42:00 UTC (rev 14292)
@@ -0,0 +1,224 @@
+/*
+ * 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.common.utils;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.Locale;
+
+/**
+ * Print stream singleton that does nothing
+ *
+ * @author richard.opalka at jboss.com
+ *
+ * @since Oct 12, 2007
+ */
+public final class NullPrintStream extends PrintStream
+{
+
+ private static final PrintStream instance = new NullPrintStream();
+
+ public static PrintStream getInstance()
+ {
+ return instance;
+ }
+
+ private NullPrintStream()
+ {
+ super(new ByteArrayOutputStream());
+ }
+
+ @Override
+ public PrintStream append(char c)
+ {
+ return this;
+ }
+
+ @Override
+ public PrintStream append(CharSequence csq, int start, int end)
+ {
+ return this;
+ }
+
+ @Override
+ public PrintStream append(CharSequence csq)
+ {
+ return this;
+ }
+
+ @Override
+ public boolean checkError()
+ {
+ return false;
+ }
+
+ @Override
+ public void close()
+ {
+ }
+
+ @Override
+ public void flush()
+ {
+ }
+
+ @Override
+ public PrintStream format(Locale l, String format, Object... args)
+ {
+ return this;
+ }
+
+ @Override
+ public PrintStream format(String format, Object... args)
+ {
+ return this;
+ }
+
+ @Override
+ public void print(boolean b)
+ {
+ }
+
+ @Override
+ public void print(char c)
+ {
+ }
+
+ @Override
+ public void print(char[] s)
+ {
+ }
+
+ @Override
+ public void print(double d)
+ {
+ }
+
+ @Override
+ public void print(float f)
+ {
+ }
+
+ @Override
+ public void print(int i)
+ {
+ }
+
+ @Override
+ public void print(long l)
+ {
+ }
+
+ @Override
+ public void print(Object obj)
+ {
+ }
+
+ @Override
+ public void print(String s)
+ {
+ }
+
+ @Override
+ public PrintStream printf(Locale l, String format, Object... args)
+ {
+ return this;
+ }
+
+ @Override
+ public PrintStream printf(String format, Object... args)
+ {
+ return this;
+ }
+
+ @Override
+ public void println()
+ {
+ }
+
+ @Override
+ public void println(boolean x)
+ {
+ }
+
+ @Override
+ public void println(char x)
+ {
+ }
+
+ @Override
+ public void println(char[] x)
+ {
+ }
+
+ @Override
+ public void println(double x)
+ {
+ }
+
+ @Override
+ public void println(float x)
+ {
+ }
+
+ @Override
+ public void println(int x)
+ {
+ }
+
+ @Override
+ public void println(long x)
+ {
+ }
+
+ @Override
+ public void println(Object x)
+ {
+ }
+
+ @Override
+ public void println(String x)
+ {
+ }
+
+ @Override
+ protected void setError()
+ {
+ }
+
+ @Override
+ public void write(byte[] buf, int off, int len)
+ {
+ }
+
+ @Override
+ public void write(int b)
+ {
+ }
+
+ @Override
+ public void write(byte[] b) throws IOException
+ {
+ }
+
+}
Added: common/trunk/src/main/java/org/jboss/ws/common/utils/ResourceURL.java
===================================================================
--- common/trunk/src/main/java/org/jboss/ws/common/utils/ResourceURL.java (rev 0)
+++ common/trunk/src/main/java/org/jboss/ws/common/utils/ResourceURL.java 2011-05-06 21:42:00 UTC (rev 14292)
@@ -0,0 +1,74 @@
+/*
+ * 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.common.utils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+/**
+ * A wrapper around an URL that can handle input streams for resources in nested jars.
+ *
+ * The jdk-1.5.0_10 cannot handle this type of URL
+ *
+ * jar:file://somepath/jaxws-eardeployment.ear!/jaxws-eardeployment.war!/WEB-INF/wsdl/TestEndpoint.wsdl
+ *
+ * @author Thomas.Diesler at jboss.org
+ * @since 12-Dec-2006 (Dosi's birthday)
+ */
+public class ResourceURL
+{
+ private URL targetURL;
+
+ public ResourceURL(URL targetURL)
+ {
+ this.targetURL = targetURL;
+ }
+
+ public URL getTargetURL()
+ {
+ return targetURL;
+ }
+
+ public InputStream openStream() throws IOException
+ {
+ boolean isJarUrl = "jar".equals(targetURL.getProtocol());
+ return isJarUrl ? new JarUrlConnection(targetURL).getInputStream() : targetURL.openStream();
+ }
+
+ public int hashCode()
+ {
+ return toString().hashCode();
+ }
+
+ public boolean equals(Object obj)
+ {
+ if (!(obj instanceof ResourceURL)) return false;
+ ResourceURL other = (ResourceURL)obj;
+ return toString().equals(other.toString());
+ }
+
+ public String toString()
+ {
+ return targetURL.toString();
+ }
+}
Added: common/trunk/src/main/java/org/jboss/ws/common/utils/SecurityActions.java
===================================================================
--- common/trunk/src/main/java/org/jboss/ws/common/utils/SecurityActions.java (rev 0)
+++ common/trunk/src/main/java/org/jboss/ws/common/utils/SecurityActions.java 2011-05-06 21:42:00 UTC (rev 14292)
@@ -0,0 +1,82 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2010, 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.common.utils;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ *
+ * @author alessio.soldano at jboss.com
+ * @since 17-Feb-2010
+ *
+ */
+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.
+ *
+ * @param classLoader the classloader
+ */
+ static void setContextClassLoader(final ClassLoader classLoader)
+ {
+ if (System.getSecurityManager() == null)
+ {
+ Thread.currentThread().setContextClassLoader(classLoader);
+ }
+ else
+ {
+ AccessController.doPrivileged(new PrivilegedAction<Object>()
+ {
+ public Object run()
+ {
+ Thread.currentThread().setContextClassLoader(classLoader);
+ return null;
+ }
+ });
+ }
+ }
+
+}
Added: common/trunk/src/main/java/org/jboss/ws/common/utils/XMLPredefinedEntityReferenceResolver.java
===================================================================
--- common/trunk/src/main/java/org/jboss/ws/common/utils/XMLPredefinedEntityReferenceResolver.java (rev 0)
+++ common/trunk/src/main/java/org/jboss/ws/common/utils/XMLPredefinedEntityReferenceResolver.java 2011-05-06 21:42:00 UTC (rev 14292)
@@ -0,0 +1,122 @@
+/*
+ * 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.common.utils;
+
+import java.util.HashMap;
+
+/**
+ * Utility class for resolving predefined XML entity and character references.
+ *
+ * @author <a href="mailto:jason.greene at jboss.com">Jason T. Greene</a>
+ */
+public class XMLPredefinedEntityReferenceResolver
+{
+ private static HashMap<String, Character> entities = new HashMap<String, Character>();
+
+ static
+ {
+ entities.put("quot", '"');
+ entities.put("amp", '&');
+ entities.put("lt", '<');
+ entities.put("gt", '>');
+ entities.put("apos", '\'');
+ }
+
+ private static int resolveCharRef(String source, int pos, StringBuilder builder)
+ {
+ int radix = 10;
+ if (source.charAt(pos += 2) == 'x')
+ {
+ pos++;
+ radix = 16;
+ }
+
+ int end = source.indexOf(';', pos);
+ if (end == -1)
+ throw new IllegalArgumentException("Invalid character reference");
+
+ int c = Integer.parseInt(source.substring(pos, end), radix);
+ builder.append((char) c);
+
+ return end + 1;
+ }
+
+ private static int resolveEntityRef(String source, int pos, StringBuilder builder)
+ {
+ int end = source.indexOf(';', ++pos);
+ if (end == -1)
+ throw new IllegalArgumentException("Invalid entity reference");
+
+ String entity = source.substring(pos, end);
+ Character c = entities.get(entity);
+ if (c == null)
+ throw new IllegalArgumentException("Invalid entity: " + entity);
+
+ builder.append(c.charValue());
+
+ return end + 1;
+ }
+
+ /**
+ * Transforms an XML normalized string by resolving all predefined character and entity references
+ *
+ * @param normalized an XML normalized string
+ * @return a standard java string that is no longer XML normalized
+ */
+ public static String resolve(String normalized)
+ {
+ StringBuilder builder = new StringBuilder();
+ int end = normalized.length();
+ int pos = normalized.indexOf('&');
+ int last = 0;
+
+ // No references
+ if (pos == -1)
+ return normalized;
+
+ while (pos != -1)
+ {
+ String sub = normalized.subSequence(last, pos).toString();
+ builder.append(sub);
+
+ int peek = pos + 1;
+ if (peek == end)
+ throw new IllegalArgumentException("Invalid entity reference");
+
+ if (normalized.charAt(peek) == '#')
+ pos = resolveCharRef(normalized, pos, builder);
+ else
+ pos = resolveEntityRef(normalized, pos, builder);
+
+ last = pos;
+ pos = normalized.indexOf('&', pos);
+ }
+
+ if (last < end)
+ {
+ String sub = normalized.subSequence(last, end).toString();
+ builder.append(sub);
+ }
+
+ return builder.toString();
+ }
+}
More information about the jbossws-commits
mailing list