[jboss-svn-commits] JBL Code SVN: r34800 - in labs/jbossesb/tags: JBESB_4_7_CP2_SOA_2210_3/product and 6 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Thu Aug 19 13:44:43 EDT 2010


Author: kevin.conner at jboss.com
Date: 2010-08-19 13:44:42 -0400 (Thu, 19 Aug 2010)
New Revision: 34800

Added:
   labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/
   labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/rosetta/src/org/jboss/soa/esb/actions/routing/http/AbstractHttpMethodFactory.java
   labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/rosetta/src/org/jboss/soa/esb/client/MessageMulticaster.java
   labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/rosetta/tests/src/org/jboss/soa/esb/actions/routing/http/HttpMethodFactoryTest.java
   labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/rosetta/tests/src/org/jboss/soa/esb/client/MessageMulticasterUnitTest.java
   labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/RemoteWsdlLoader.java
   labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/proxy/SOAPProxy.java
   labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/proxy/SOAPProxyWsdlContractPublisher.java
   labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/proxy/SOAPProxyWsdlLoader.java
Removed:
   labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/rosetta/src/org/jboss/soa/esb/actions/routing/http/AbstractHttpMethodFactory.java
   labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/rosetta/src/org/jboss/soa/esb/client/MessageMulticaster.java
   labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/rosetta/tests/src/org/jboss/soa/esb/actions/routing/http/HttpMethodFactoryTest.java
   labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/rosetta/tests/src/org/jboss/soa/esb/client/MessageMulticasterUnitTest.java
   labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/RemoteWsdlLoader.java
   labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/proxy/SOAPProxy.java
   labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/proxy/SOAPProxyWsdlContractPublisher.java
   labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/proxy/SOAPProxyWsdlLoader.java
Modified:
   labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/build.xml
Log:
Tag third version of SOA 2210 work

Copied: labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3 (from rev 34695, labs/jbossesb/branches/JBESB_4_7_CP)

Modified: labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/build.xml
===================================================================
--- labs/jbossesb/branches/JBESB_4_7_CP/product/build.xml	2010-08-13 08:26:20 UTC (rev 34695)
+++ labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/build.xml	2010-08-19 17:44:42 UTC (rev 34800)
@@ -40,8 +40,8 @@
 	<property name="org.jboss.esb.internal.jar.dest" location="build/jbossesb/lib"/>
 
 	<!-- JBoss ESB version -->
-	<property name="version" value="4.7"/>
-	<property name="esb.server.name" value="jbossesb-server-${version}"/>
+	<property name="version" value="4.7_SOA_5.0_soa_2210"/>
+	<property name="esb.server.name" value="soa-server-5.0.2_soa_2210"/>
 	<property name="esbserver.dist.dir" value="${org.jboss.esb.internal.dest}/${esb.server.name}"/>
 
 	<!-- Set internal property defaults -->

Deleted: labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/rosetta/src/org/jboss/soa/esb/actions/routing/http/AbstractHttpMethodFactory.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_7_CP/product/rosetta/src/org/jboss/soa/esb/actions/routing/http/AbstractHttpMethodFactory.java	2010-08-13 08:26:20 UTC (rev 34695)
+++ labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/rosetta/src/org/jboss/soa/esb/actions/routing/http/AbstractHttpMethodFactory.java	2010-08-19 17:44:42 UTC (rev 34800)
@@ -1,146 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2006, JBoss Inc., and others contributors as indicated 
- * by the @authors tag. All rights reserved. 
- * See the copyright.txt in the distribution for a
- * full listing of individual contributors. 
- * This copyrighted material is made available to anyone wishing to use,
- * modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU Lesser General Public License, v. 2.1.
- * This program is distributed in the hope that it will be useful, but WITHOUT A 
- * 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,
- * v.2.1 along with this distribution; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
- * MA  02110-1301, USA.
- * 
- * (C) 2005-2009
- */
-package org.jboss.soa.esb.actions.routing.http;
-
-import java.io.IOException;
-import java.net.SocketException;
-import java.net.URL;
-
-import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
-import org.apache.commons.httpclient.HttpMethod;
-import org.apache.commons.httpclient.HttpMethodRetryHandler;
-import org.apache.commons.httpclient.params.HttpMethodParams;
-import org.jboss.soa.esb.Configurable;
-import org.jboss.soa.esb.ConfigurationException;
-import org.jboss.soa.esb.helpers.ConfigTree;
-import org.jboss.soa.esb.util.ClassUtil;
-
-/**
- * AbstractHttpMethodFactory.
- * 
- * @author dward at jboss.org
- */
-public abstract class AbstractHttpMethodFactory implements HttpMethodFactory
-{
-    public static final String ROUTING_HANDLER = "org.jboss.soa.esb.actions.routing.http.routingHandler";
-	
-	private URL endpoint;
-	private Class<?> retryHandlerClass ;
-	private boolean isConfigurable ;
-	private ConfigTree config ;
-
-    public void setEndpoint(URL endpoint)
-    {
-    	this.endpoint = endpoint;
-    }
-    
-    protected String getEndpointPathAndQuery()
-    {
-    	StringBuilder sb = new StringBuilder();
-    	String path = endpoint.getPath();
-    	sb.append("".equals(path) ? "/" : path);
-    	String query = endpoint.getQuery();
-    	if (query != null)
-    	{
-    		sb.append("?");
-    		sb.append(query);
-    	}
-    	return sb.toString();
-    }
-    
-    public void setConfiguration(ConfigTree config)
-        throws ConfigurationException
-    {
-        this.config = config ;
-        final String retryHandler = config.getAttribute(ROUTING_HANDLER) ;
-        if (retryHandler != null)
-        {
-            final Class<?> retryHandlerClass ;
-            try
-            {
-                retryHandlerClass = ClassUtil.forName(retryHandler, getClass()) ;
-            }
-            catch (final ClassNotFoundException cnfe)
-            {
-                throw new ConfigurationException("Could not locate Retry Handler: " + retryHandler, cnfe) ;
-            }
-            if (!HttpMethodRetryHandler.class.isAssignableFrom(retryHandlerClass))
-            {
-                throw new ConfigurationException("Retry Handler does not implement HttpMethodRetryHandler: " + retryHandler) ;
-            }
-            try
-            {
-                retryHandlerClass.getConstructor() ;
-            }
-            catch (final NoSuchMethodException nsme)
-            {
-                throw new ConfigurationException("Retry Handler does not have a default constructor: " + retryHandler, nsme) ;
-            }
-            this.retryHandlerClass = retryHandlerClass ;
-            isConfigurable = Configurable.class.isAssignableFrom(retryHandlerClass) ;
-        }
-    }
-    
-    protected void initialiseRetryHandler(HttpMethod method) throws IOException {
-    	HttpMethodParams params = method.getParams();
-    	if (retryHandlerClass != null) {
-    	    final Object handler ;
-    	    try {
-    	        handler = retryHandlerClass.newInstance() ;
-    	    } catch (final Throwable th) {
-    	        final IOException ioe = new IOException("Failed to instantiate Retry Handler") ;
-    	        ioe.initCause(th) ;
-    	        throw ioe ;
-    	    }
-    	    if (isConfigurable) {
-    	        final Configurable configurable = Configurable.class.cast(handler) ;
-    	        try {
-    	            configurable.setConfiguration(config) ;
-    	        } catch (final ConfigurationException ce) {
-    	            final IOException ioe = new IOException("Failed to configure Retry Handler") ;
-    	            ioe.initCause(ce) ;
-    	            throw ioe ;
-    	        }
-    	    }
-    	    params.setParameter(HttpMethodParams.RETRY_HANDLER, handler);
-    	} else {
-    	    HttpMethodRetryHandler other = (HttpMethodRetryHandler)params.getParameter(HttpMethodParams.RETRY_HANDLER);
-    	    params.setParameter(HttpMethodParams.RETRY_HANDLER, new HttpMethodRetryHandlerWrapper(other));
-    	}
-    }
-    
-    static class HttpMethodRetryHandlerWrapper implements HttpMethodRetryHandler {
-    	
-    	private HttpMethodRetryHandler other;
-    	
-    	private HttpMethodRetryHandlerWrapper(HttpMethodRetryHandler other) {
-    		this.other = (other != null ? other : new DefaultHttpMethodRetryHandler());
-    	}
-    	
-    	public boolean retryMethod(HttpMethod method, IOException exception, int executionCount) {
-    		boolean retry = other.retryMethod(method, exception, executionCount);
-    		if (retry && exception instanceof SocketException) {
-    			retry = false;
-    		}
-    		return retry;
-    	}
-    	
-    }
-}

Copied: labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/rosetta/src/org/jboss/soa/esb/actions/routing/http/AbstractHttpMethodFactory.java (from rev 34783, labs/jbossesb/branches/JBESB_4_7_CP/product/rosetta/src/org/jboss/soa/esb/actions/routing/http/AbstractHttpMethodFactory.java)
===================================================================
--- labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/rosetta/src/org/jboss/soa/esb/actions/routing/http/AbstractHttpMethodFactory.java	                        (rev 0)
+++ labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/rosetta/src/org/jboss/soa/esb/actions/routing/http/AbstractHttpMethodFactory.java	2010-08-19 17:44:42 UTC (rev 34800)
@@ -0,0 +1,146 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, JBoss Inc., and others contributors as indicated 
+ * by the @authors tag. All rights reserved. 
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors. 
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A 
+ * 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,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+ * MA  02110-1301, USA.
+ * 
+ * (C) 2005-2009
+ */
+package org.jboss.soa.esb.actions.routing.http;
+
+import java.io.IOException;
+import java.net.SocketException;
+import java.net.URL;
+
+import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
+import org.apache.commons.httpclient.HttpMethod;
+import org.apache.commons.httpclient.HttpMethodRetryHandler;
+import org.apache.commons.httpclient.params.HttpMethodParams;
+import org.jboss.soa.esb.Configurable;
+import org.jboss.soa.esb.ConfigurationException;
+import org.jboss.soa.esb.helpers.ConfigTree;
+import org.jboss.soa.esb.util.ClassUtil;
+
+/**
+ * AbstractHttpMethodFactory.
+ * 
+ * @author dward at jboss.org
+ */
+public abstract class AbstractHttpMethodFactory implements HttpMethodFactory
+{
+    public static final String RETRY_HANDLER = "org.jboss.soa.esb.actions.routing.http.retryHandler";
+	
+	private URL endpoint;
+	private Class<?> retryHandlerClass ;
+	private boolean isConfigurable ;
+	private ConfigTree config ;
+
+    public void setEndpoint(URL endpoint)
+    {
+    	this.endpoint = endpoint;
+    }
+    
+    protected String getEndpointPathAndQuery()
+    {
+    	StringBuilder sb = new StringBuilder();
+    	String path = endpoint.getPath();
+    	sb.append("".equals(path) ? "/" : path);
+    	String query = endpoint.getQuery();
+    	if (query != null)
+    	{
+    		sb.append("?");
+    		sb.append(query);
+    	}
+    	return sb.toString();
+    }
+    
+    public void setConfiguration(ConfigTree config)
+        throws ConfigurationException
+    {
+        this.config = config ;
+        final String retryHandler = config.getAttribute(RETRY_HANDLER) ;
+        if (retryHandler != null)
+        {
+            final Class<?> retryHandlerClass ;
+            try
+            {
+                retryHandlerClass = ClassUtil.forName(retryHandler, getClass()) ;
+            }
+            catch (final ClassNotFoundException cnfe)
+            {
+                throw new ConfigurationException("Could not locate Retry Handler: " + retryHandler, cnfe) ;
+            }
+            if (!HttpMethodRetryHandler.class.isAssignableFrom(retryHandlerClass))
+            {
+                throw new ConfigurationException("Retry Handler does not implement HttpMethodRetryHandler: " + retryHandler) ;
+            }
+            try
+            {
+                retryHandlerClass.getConstructor() ;
+            }
+            catch (final NoSuchMethodException nsme)
+            {
+                throw new ConfigurationException("Retry Handler does not have a default constructor: " + retryHandler, nsme) ;
+            }
+            this.retryHandlerClass = retryHandlerClass ;
+            isConfigurable = Configurable.class.isAssignableFrom(retryHandlerClass) ;
+        }
+    }
+    
+    protected void initialiseRetryHandler(HttpMethod method) throws IOException {
+    	HttpMethodParams params = method.getParams();
+    	if (retryHandlerClass != null) {
+    	    final Object handler ;
+    	    try {
+    	        handler = retryHandlerClass.newInstance() ;
+    	    } catch (final Throwable th) {
+    	        final IOException ioe = new IOException("Failed to instantiate Retry Handler") ;
+    	        ioe.initCause(th) ;
+    	        throw ioe ;
+    	    }
+    	    if (isConfigurable) {
+    	        final Configurable configurable = Configurable.class.cast(handler) ;
+    	        try {
+    	            configurable.setConfiguration(config) ;
+    	        } catch (final ConfigurationException ce) {
+    	            final IOException ioe = new IOException("Failed to configure Retry Handler") ;
+    	            ioe.initCause(ce) ;
+    	            throw ioe ;
+    	        }
+    	    }
+    	    params.setParameter(HttpMethodParams.RETRY_HANDLER, handler);
+    	} else {
+    	    HttpMethodRetryHandler other = (HttpMethodRetryHandler)params.getParameter(HttpMethodParams.RETRY_HANDLER);
+    	    params.setParameter(HttpMethodParams.RETRY_HANDLER, new HttpMethodRetryHandlerWrapper(other));
+    	}
+    }
+    
+    static class HttpMethodRetryHandlerWrapper implements HttpMethodRetryHandler {
+    	
+    	private HttpMethodRetryHandler other;
+    	
+    	private HttpMethodRetryHandlerWrapper(HttpMethodRetryHandler other) {
+    		this.other = (other != null ? other : new DefaultHttpMethodRetryHandler());
+    	}
+    	
+    	public boolean retryMethod(HttpMethod method, IOException exception, int executionCount) {
+    		boolean retry = other.retryMethod(method, exception, executionCount);
+    		if (retry && exception instanceof SocketException) {
+    			retry = false;
+    		}
+    		return retry;
+    	}
+    	
+    }
+}

Deleted: labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/rosetta/src/org/jboss/soa/esb/client/MessageMulticaster.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_7_CP/product/rosetta/src/org/jboss/soa/esb/client/MessageMulticaster.java	2010-08-13 08:26:20 UTC (rev 34695)
+++ labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/rosetta/src/org/jboss/soa/esb/client/MessageMulticaster.java	2010-08-19 17:44:42 UTC (rev 34800)
@@ -1,208 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2006, JBoss Inc., and others contributors as indicated
- * by the @authors tag. All rights reserved.
- * See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- * This copyrighted material is made available to anyone wishing to use,
- * modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU Lesser General Public License, v. 2.1.
- * This program is distributed in the hope that it will be useful, but WITHOUT A
- * 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,
- * v.2.1 along with this distribution; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA  02110-1301, USA.
- *
- * (C) 2005-2006, JBoss Inc.
- */
-package org.jboss.soa.esb.client;
-
-import org.apache.log4j.Logger;
-import org.jboss.internal.soa.esb.assertion.AssertArgument;
-import org.jboss.soa.esb.Service;
-import org.jboss.soa.esb.actions.AggregationDetails;
-import org.jboss.soa.esb.actions.Aggregator;
-import org.jboss.soa.esb.listeners.message.MessageDeliverException;
-import org.jboss.soa.esb.message.Message;
-import org.jboss.soa.esb.services.registry.RegistryException;
-
-import java.util.*;
-
-/**
- * Message Multicaster.
- * <p/>
- * Used to send a message to a recipient list, or a subset of that recipient list.
- * <p/>
- * Caches a {@link ServiceInvoker} instance for each recipient.
- * <p/>
- * <b>Note</b>:  This doesn't "multicast" message delivery in the true IP sense of the
- * word "multicast".  It sends the message to all recipients in its recipient list,
- * one at a time, in the order the recipients were added via the
- * {@link #addRecipient(org.jboss.soa.esb.Service)} method.
- *
- * @author <a href="mailto:tom.fennely at jboss.com">tom.fennelly at jboss.com</a>
- */
-public class MessageMulticaster {
-
-    private static Logger logger = Logger.getLogger(MessageMulticaster.class);
-
-    private Map<Service, ServiceInvoker> invokers = new LinkedHashMap<Service, ServiceInvoker>();
-    private String splitId;
-    private boolean aggregatorOnProperties = false; // By default... set on context.
-
-    /**
-     * Public default constructor.
-     */
-    public MessageMulticaster() {        
-    }
-
-    /**
-     * Public default constructor.
-     * @param splitId Split ID for this multicaster.
-     */
-    public MessageMulticaster(String splitId) {
-        AssertArgument.isNotNullAndNotEmpty(splitId, "splitId");
-        this.splitId = splitId;
-    }
-
-    /**
-     * Add a message recipient Service.
-     * @param service Recipient service for receipt of messages from this miltcaster instance.
-     * @throws RegistryException Failed to lookup Service endpoint.
-     * @throws MessageDeliverException Failed to deliver message to endpoint.
-     */
-    public void addRecipient(Service service) throws RegistryException, MessageDeliverException {
-        AssertArgument.isNotNull(service, "service");
-        // The ServiceInvoker will be lazilly created in the getInvoker method.
-        // This is effectively a registration of the service as being a potential recipient.
-        invokers.put(service, null);
-    }
-
-    /**
-     * Is the specified service a recipient of this multicaster instance.
-     * @param service The service to check for.
-     * @return True if the supplied service is one of the recipients, otherwise false.
-     */
-    public boolean isRecipient(Service service) {
-        return invokers.containsKey(service);
-    }
-
-    /**
-     * Get the number ot recipients associated with this multicaster instance.
-     * @return The number of recipients.
-     */
-    public int getRecipientCount() {
-        return invokers.size();
-    }
-
-    /**
-     * Send the message to all the recipients associated with this multicaster.
-     * @param message The message.
-     * @throws RegistryException Failed to lookup Service endpoint.
-     * @throws MessageDeliverException Failed to deliver message to endpoint.
-     */
-    public void sendToAll(Message message) throws RegistryException, MessageDeliverException {
-        sendToSubset(message, new ArrayList<Service>(invokers.keySet()));
-    }
-
-    /**
-     * Send the message to all the recipients associated with this multicaster and
-     * also listed in the supplied recipient list.
-     * <p/>
-     * The recipients supplied in the list must have been added through the {@link #addRecipient(org.jboss.soa.esb.Service)}
-     * method, otherwise the message will be delivered to the Dead Letter Channel.
-     *
-     * @param message The message.
-     * @param recipients The recipient subset to which the supplied message is to be sent.
-     * @throws RegistryException Failed to lookup Service endpoint.
-     * @throws MessageDeliverException Failed to deliver message to endpoint.
-     */
-    public void sendToSubset(Message message, List<Service> recipients) throws RegistryException, MessageDeliverException {
-        if (recipients.isEmpty()) {
-            logger.warn("MessageMulticaster.sendToSubset: empty recipients list!");
-        } else{
-            String seriesUUID = UUID.randomUUID().toString();
-            long seriesTimestamp = System.currentTimeMillis();
-            int recipientCount = recipients.size();
-
-            for(int i = 0; i < recipientCount; i++) {
-                Service recipient = recipients.get(i);
-                ServiceInvoker invoker = getInvoker(recipient);
-
-                if(recipientCount > 1) {
-                    // Only add aggregation info if we're splitting the message i.e. sending it to
-                    // more than 1 recipient...
-                    addAggregationDetails(message, seriesUUID, recipientCount, seriesTimestamp, i + 1);
-                }
-
-                if(invoker == null) {
-                    logger.error("Service '" + recipient + "' is not in recipient list.  Delivering message to Dead Letter Channel.");
-                    ServiceInvoker.deliverToDeadLetterService(message);
-                } else {
-                    try {
-                        invoker.deliverAsync(message);
-                    } catch(MessageDeliverException e) {
-                        logger.error("Failed to deliver message to Service '" + recipient + "'.  Delivering message to Dead Letter Channel.");
-                        ServiceInvoker.deliverToDeadLetterService(message);
-                    }
-                }
-            }
-        }
-    }
-
-    protected void addAggregationDetails(Message message, String uuId, int recipientCount, long seriesTimestamp, int messageIndex) {
-        AggregationDetails aggrDetails = new AggregationDetails(uuId, messageIndex, recipientCount, seriesTimestamp);
-        ArrayList<String> aggregatorTags;
-        
-        if(aggregatorOnProperties) {
-        	aggregatorTags = (ArrayList<String>) message.getProperties().getProperty(Aggregator.AGGEGRATOR_TAG);
-        } else {
-        	aggregatorTags = (ArrayList<String>) message.getContext().getContext(Aggregator.AGGEGRATOR_TAG);
-        }
-
-        // This is useful during aggregation - as a way of id'ing where the split occurred.
-        aggrDetails.setSplitId(splitId);
-
-        if(aggregatorTags == null) {
-            aggregatorTags = new ArrayList<String>();
-            if(aggregatorOnProperties) {
-            	message.getProperties().setProperty(Aggregator.AGGEGRATOR_TAG, aggregatorTags);
-            } else {
-            	message.getContext().setContext(Aggregator.AGGEGRATOR_TAG, aggregatorTags);
-            }
-        }
-
-        if(messageIndex > 1) {
-            // remove the tag string for the last recipient...
-            aggregatorTags.remove(aggregatorTags.size() - 1);
-        }
-        aggregatorTags.add(aggrDetails.toString());
-
-        if (logger.isDebugEnabled()) {
-            logger.debug(Aggregator. AGGEGRATOR_TAG + "=" + aggrDetails);
-        }
-    }
-
-	public void setAggregatorOnProperties(boolean aggregatorOnProperties) {
-		this.aggregatorOnProperties = aggregatorOnProperties;
-	}
-
-	private ServiceInvoker getInvoker(Service recipient) throws RegistryException, MessageDeliverException {
-        ServiceInvoker invoker = invokers.get(recipient);
-
-        // We lazilly create the invokers...
-        if(invoker == null) {
-            if(!invokers.containsKey(recipient)) {
-                // We don't create an invoker for the Service if it wasn't
-                // already "registered" via the addRecipient method.
-                return null;
-            }
-            invoker = new ServiceInvoker(recipient);
-            invokers.put(recipient, invoker);
-        }
-
-        return invoker;
-    }
-}
\ No newline at end of file

Copied: labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/rosetta/src/org/jboss/soa/esb/client/MessageMulticaster.java (from rev 34762, labs/jbossesb/branches/JBESB_4_7_CP/product/rosetta/src/org/jboss/soa/esb/client/MessageMulticaster.java)
===================================================================
--- labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/rosetta/src/org/jboss/soa/esb/client/MessageMulticaster.java	                        (rev 0)
+++ labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/rosetta/src/org/jboss/soa/esb/client/MessageMulticaster.java	2010-08-19 17:44:42 UTC (rev 34800)
@@ -0,0 +1,213 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, JBoss Inc., and others contributors as indicated
+ * by the @authors tag. All rights reserved.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * 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,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA  02110-1301, USA.
+ *
+ * (C) 2005-2006, JBoss Inc.
+ */
+package org.jboss.soa.esb.client;
+
+import org.apache.log4j.Logger;
+import org.jboss.internal.soa.esb.assertion.AssertArgument;
+import org.jboss.soa.esb.Service;
+import org.jboss.soa.esb.actions.AggregationDetails;
+import org.jboss.soa.esb.actions.Aggregator;
+import org.jboss.soa.esb.listeners.message.MessageDeliverException;
+import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.services.registry.RegistryException;
+
+import java.util.*;
+
+/**
+ * Message Multicaster.
+ * <p/>
+ * Used to send a message to a recipient list, or a subset of that recipient list.
+ * <p/>
+ * Caches a {@link ServiceInvoker} instance for each recipient.
+ * <p/>
+ * <b>Note</b>:  This doesn't "multicast" message delivery in the true IP sense of the
+ * word "multicast".  It sends the message to all recipients in its recipient list,
+ * one at a time, in the order the recipients were added via the
+ * {@link #addRecipient(org.jboss.soa.esb.Service)} method.
+ *
+ * @author <a href="mailto:tom.fennely at jboss.com">tom.fennelly at jboss.com</a>
+ */
+public class MessageMulticaster {
+
+    private static Logger logger = Logger.getLogger(MessageMulticaster.class);
+
+    private Map<Service, ServiceInvoker> invokers = new LinkedHashMap<Service, ServiceInvoker>();
+    private String splitId;
+    private boolean aggregatorOnProperties = false; // By default... set on context.
+
+    /**
+     * Public default constructor.
+     */
+    public MessageMulticaster() {        
+    }
+
+    /**
+     * Public default constructor.
+     * @param splitId Split ID for this multicaster.
+     */
+    public MessageMulticaster(String splitId) {
+        AssertArgument.isNotNullAndNotEmpty(splitId, "splitId");
+        this.splitId = splitId;
+    }
+
+    /**
+     * Add a message recipient Service.
+     * @param service Recipient service for receipt of messages from this miltcaster instance.
+     * @throws RegistryException Failed to lookup Service endpoint.
+     * @throws MessageDeliverException Failed to deliver message to endpoint.
+     */
+    public void addRecipient(Service service) throws RegistryException, MessageDeliverException {
+        AssertArgument.isNotNull(service, "service");
+        // The ServiceInvoker will be lazilly created in the getInvoker method.
+        // This is effectively a registration of the service as being a potential recipient.
+        invokers.put(service, null);
+    }
+
+    /**
+     * Is the specified service a recipient of this multicaster instance.
+     * @param service The service to check for.
+     * @return True if the supplied service is one of the recipients, otherwise false.
+     */
+    public boolean isRecipient(Service service) {
+        return invokers.containsKey(service);
+    }
+
+    /**
+     * Get the number ot recipients associated with this multicaster instance.
+     * @return The number of recipients.
+     */
+    public int getRecipientCount() {
+        return invokers.size();
+    }
+
+    /**
+     * Send the message to all the recipients associated with this multicaster.
+     * @param message The message.
+     * @throws RegistryException Failed to lookup Service endpoint.
+     * @throws MessageDeliverException Failed to deliver message to endpoint.
+     */
+    public void sendToAll(Message message) throws RegistryException, MessageDeliverException {
+        sendToSubset(message, new ArrayList<Service>(invokers.keySet()));
+    }
+
+    /**
+     * Send the message to all the recipients associated with this multicaster and
+     * also listed in the supplied recipient list.
+     * <p/>
+     * The recipients supplied in the list must have been added through the {@link #addRecipient(org.jboss.soa.esb.Service)}
+     * method, otherwise the message will be delivered to the Dead Letter Channel.
+     *
+     * @param message The message.
+     * @param recipients The recipient subset to which the supplied message is to be sent.
+     * @throws RegistryException Failed to lookup Service endpoint.
+     * @throws MessageDeliverException Failed to deliver message to endpoint.
+     */
+    public void sendToSubset(Message message, List<Service> recipients) throws RegistryException, MessageDeliverException {
+        if (recipients.isEmpty()) {
+            logger.warn("MessageMulticaster.sendToSubset: empty recipients list!");
+        } else{
+            String seriesUUID = UUID.randomUUID().toString();
+            long seriesTimestamp = System.currentTimeMillis();
+            int recipientCount = recipients.size();
+
+            for(int i = 0; i < recipientCount; i++) {
+                Service recipient = recipients.get(i);
+                ServiceInvoker invoker = getInvoker(recipient);
+
+                if(recipientCount > 1) {
+                    // Only add aggregation info if we're splitting the message i.e. sending it to
+                    // more than 1 recipient...
+                    addAggregationDetails(message, seriesUUID, recipientCount, seriesTimestamp, i + 1);
+                }
+
+                if(invoker == null) {
+                    logger.error("Service '" + recipient + "' is not in recipient list.  Delivering message to Dead Letter Channel.");
+                    ServiceInvoker.deliverToDeadLetterService(message);
+                } else {
+                    try {
+                        invoker.deliverAsync(message);
+                    } catch(MessageDeliverException e) {
+                        logger.error("Failed to deliver message to Service '" + recipient + "'.  Delivering message to Dead Letter Channel.");
+                        ServiceInvoker.deliverToDeadLetterService(message);
+                    }
+                }
+            }
+        }
+    }
+
+    protected void addAggregationDetails(Message message, String uuId, int recipientCount, long seriesTimestamp, int messageIndex) {
+        AggregationDetails aggrDetails = new AggregationDetails(uuId, messageIndex, recipientCount, seriesTimestamp);
+        ArrayList<String> aggregatorTags;
+        
+        if(aggregatorOnProperties) {
+        	aggregatorTags = (ArrayList<String>) message.getProperties().getProperty(Aggregator.AGGEGRATOR_TAG);
+        } else {
+        	aggregatorTags = (ArrayList<String>) message.getContext().getContext(Aggregator.AGGEGRATOR_TAG);
+        }
+
+        // This is useful during aggregation - as a way of id'ing where the split occurred.
+        aggrDetails.setSplitId(splitId);
+
+        if ((aggregatorTags == null) || !aggregatorOnProperties) {
+            if (aggregatorTags == null) {
+                aggregatorTags = new ArrayList<String>();
+            } else {
+                aggregatorTags = new ArrayList<String>(aggregatorTags) ;
+            }
+            
+            if(aggregatorOnProperties) {
+            	message.getProperties().setProperty(Aggregator.AGGEGRATOR_TAG, aggregatorTags);
+            } else {
+            	message.getContext().setContext(Aggregator.AGGEGRATOR_TAG, aggregatorTags);
+            }
+        }
+
+        if(messageIndex > 1) {
+            // remove the tag string for the last recipient...
+            aggregatorTags.remove(aggregatorTags.size() - 1);
+        }
+        aggregatorTags.add(aggrDetails.toString());
+
+        if (logger.isDebugEnabled()) {
+            logger.debug(Aggregator. AGGEGRATOR_TAG + "=" + aggrDetails);
+        }
+    }
+
+	public void setAggregatorOnProperties(boolean aggregatorOnProperties) {
+		this.aggregatorOnProperties = aggregatorOnProperties;
+	}
+
+	private ServiceInvoker getInvoker(Service recipient) throws RegistryException, MessageDeliverException {
+        ServiceInvoker invoker = invokers.get(recipient);
+
+        // We lazilly create the invokers...
+        if(invoker == null) {
+            if(!invokers.containsKey(recipient)) {
+                // We don't create an invoker for the Service if it wasn't
+                // already "registered" via the addRecipient method.
+                return null;
+            }
+            invoker = new ServiceInvoker(recipient);
+            invokers.put(recipient, invoker);
+        }
+
+        return invoker;
+    }
+}
\ No newline at end of file

Deleted: labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/rosetta/tests/src/org/jboss/soa/esb/actions/routing/http/HttpMethodFactoryTest.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_7_CP/product/rosetta/tests/src/org/jboss/soa/esb/actions/routing/http/HttpMethodFactoryTest.java	2010-08-13 08:26:20 UTC (rev 34695)
+++ labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/rosetta/tests/src/org/jboss/soa/esb/actions/routing/http/HttpMethodFactoryTest.java	2010-08-19 17:44:42 UTC (rev 34800)
@@ -1,164 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2010, Red Hat Middleware LLC, and others contributors as indicated
- * by the @authors tag. All rights reserved.
- * See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- * This copyrighted material is made available to anyone wishing to use,
- * modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU Lesser General Public License, v. 2.1.
- * This program is distributed in the hope that it will be useful, but WITHOUT A
- * 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,
- * v.2.1 along with this distribution; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA  02110-1301, USA.
- */
-
-package org.jboss.soa.esb.actions.routing.http;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-import java.io.IOException;
-import java.net.URL;
-
-import junit.framework.JUnit4TestAdapter;
-
-import org.apache.commons.httpclient.HttpMethod;
-import org.apache.commons.httpclient.HttpMethodBase;
-import org.apache.commons.httpclient.HttpMethodRetryHandler;
-import org.apache.commons.httpclient.params.HttpMethodParams;
-import org.jboss.soa.esb.Configurable;
-import org.jboss.soa.esb.ConfigurationException;
-import org.jboss.soa.esb.helpers.ConfigTree;
-import org.jboss.soa.esb.message.Message;
-import org.jboss.soa.esb.message.format.MessageFactory;
-import org.junit.Test;
-
-public class HttpMethodFactoryTest
-{
-    @Test
-    public void testDefaultRetryHandlerPOST()
-        throws Exception
-    {
-        testDefaultRetryHandler("POST") ;
-    }
-
-    @Test
-    public void testDefaultRetryHandlerGET()
-        throws Exception
-    {
-        testDefaultRetryHandler("GET") ;
-    }
-
-    private void testDefaultRetryHandler(final String method)
-        throws Exception
-    {
-        final HttpMethodBase httpMethodBase = executeTest(method, null) ;
-        final HttpMethodParams params = httpMethodBase.getParams() ;
-        final Object handler = params.getParameter(HttpMethodParams.RETRY_HANDLER) ;
-        assertNotNull("retry handler", handler) ;
-        assertEquals("handler class", AbstractHttpMethodFactory.HttpMethodRetryHandlerWrapper.class, handler.getClass()) ;
-    }
-
-    @Test
-    public void testRetryHandlerPOST()
-        throws Exception
-    {
-        testRetryHandler("POST") ;
-    }
-
-    @Test
-    public void testRetryHandlerGET()
-        throws Exception
-    {
-        testRetryHandler("GET") ;
-    }
-
-    private void testRetryHandler(final String method)
-        throws Exception
-    {
-        final Class<?> handlerClass = RetryHandler.class ;
-        final HttpMethodBase httpMethodBase = executeTest(method, handlerClass.getName()) ;
-        final HttpMethodParams params = httpMethodBase.getParams() ;
-        final Object handler = params.getParameter(HttpMethodParams.RETRY_HANDLER) ;
-        assertNotNull("retry handler", handler) ;
-        assertEquals("handler class", handlerClass, handler.getClass()) ;
-    }
-
-    @Test
-    public void testConfigurableRetryHandlerPOST()
-        throws Exception
-    {
-        testConfigurableRetryHandler("POST") ;
-    }
-
-    @Test
-    public void testConfigurableRetryHandlerGET()
-        throws Exception
-    {
-        testConfigurableRetryHandler("GET") ;
-    }
-
-    private void testConfigurableRetryHandler(final String method)
-        throws Exception
-    {
-        final Class<ConfigurableRetryHandler> handlerClass = ConfigurableRetryHandler.class ;
-        final HttpMethodBase httpMethodBase = executeTest(method, handlerClass.getName()) ;
-        final HttpMethodParams params = httpMethodBase.getParams() ;
-        final Object handler = params.getParameter(HttpMethodParams.RETRY_HANDLER) ;
-        assertNotNull("retry handler", handler) ;
-        assertEquals("handler class", handlerClass, handler.getClass()) ;
-        final ConfigurableRetryHandler configurableRetryHandler = handlerClass.cast(handler) ;
-        assertNotNull("config", configurableRetryHandler.getConfig()) ;
-    }
-
-    private HttpMethodBase executeTest(final String method, final String handlerName)
-        throws Exception
-    {
-        final Message message = MessageFactory.getInstance().getMessage() ;
-        message.getBody().add("test") ;
-        final ConfigTree config = new ConfigTree("test") ;
-        if (handlerName != null)
-        {
-            config.setAttribute(AbstractHttpMethodFactory.ROUTING_HANDLER, handlerName) ;
-        }
-        final HttpMethodFactory factory = HttpMethodFactory.Factory.getInstance(method, config, new URL("http://dummy")) ;
-        return factory.getInstance(message) ;
-    }
-
-    public static final class RetryHandler implements HttpMethodRetryHandler
-    {
-        public boolean retryMethod(final HttpMethod method, final IOException exception, final int executionCount)
-        {
-            return false;
-        }
-    }
-
-    public static final class ConfigurableRetryHandler implements HttpMethodRetryHandler, Configurable
-    {
-        private ConfigTree config ;
-
-        public boolean retryMethod(final HttpMethod method, final IOException exception, final int executionCount)
-        {
-            return false;
-        }
-
-        public void setConfiguration(final ConfigTree config)
-            throws ConfigurationException
-        {
-            this.config = config ;
-        }
-
-        public ConfigTree getConfig()
-        {
-            return config ;
-        }
-    }
-
-    public static junit.framework.Test suite() {
-        return new JUnit4TestAdapter(HttpMethodFactoryTest.class);
-    }
-}

Copied: labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/rosetta/tests/src/org/jboss/soa/esb/actions/routing/http/HttpMethodFactoryTest.java (from rev 34783, labs/jbossesb/branches/JBESB_4_7_CP/product/rosetta/tests/src/org/jboss/soa/esb/actions/routing/http/HttpMethodFactoryTest.java)
===================================================================
--- labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/rosetta/tests/src/org/jboss/soa/esb/actions/routing/http/HttpMethodFactoryTest.java	                        (rev 0)
+++ labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/rosetta/tests/src/org/jboss/soa/esb/actions/routing/http/HttpMethodFactoryTest.java	2010-08-19 17:44:42 UTC (rev 34800)
@@ -0,0 +1,164 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat Middleware LLC, and others contributors as indicated
+ * by the @authors tag. All rights reserved.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * 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,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA  02110-1301, USA.
+ */
+
+package org.jboss.soa.esb.actions.routing.http;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.IOException;
+import java.net.URL;
+
+import junit.framework.JUnit4TestAdapter;
+
+import org.apache.commons.httpclient.HttpMethod;
+import org.apache.commons.httpclient.HttpMethodBase;
+import org.apache.commons.httpclient.HttpMethodRetryHandler;
+import org.apache.commons.httpclient.params.HttpMethodParams;
+import org.jboss.soa.esb.Configurable;
+import org.jboss.soa.esb.ConfigurationException;
+import org.jboss.soa.esb.helpers.ConfigTree;
+import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.message.format.MessageFactory;
+import org.junit.Test;
+
+public class HttpMethodFactoryTest
+{
+    @Test
+    public void testDefaultRetryHandlerPOST()
+        throws Exception
+    {
+        testDefaultRetryHandler("POST") ;
+    }
+
+    @Test
+    public void testDefaultRetryHandlerGET()
+        throws Exception
+    {
+        testDefaultRetryHandler("GET") ;
+    }
+
+    private void testDefaultRetryHandler(final String method)
+        throws Exception
+    {
+        final HttpMethodBase httpMethodBase = executeTest(method, null) ;
+        final HttpMethodParams params = httpMethodBase.getParams() ;
+        final Object handler = params.getParameter(HttpMethodParams.RETRY_HANDLER) ;
+        assertNotNull("retry handler", handler) ;
+        assertEquals("handler class", AbstractHttpMethodFactory.HttpMethodRetryHandlerWrapper.class, handler.getClass()) ;
+    }
+
+    @Test
+    public void testRetryHandlerPOST()
+        throws Exception
+    {
+        testRetryHandler("POST") ;
+    }
+
+    @Test
+    public void testRetryHandlerGET()
+        throws Exception
+    {
+        testRetryHandler("GET") ;
+    }
+
+    private void testRetryHandler(final String method)
+        throws Exception
+    {
+        final Class<?> handlerClass = RetryHandler.class ;
+        final HttpMethodBase httpMethodBase = executeTest(method, handlerClass.getName()) ;
+        final HttpMethodParams params = httpMethodBase.getParams() ;
+        final Object handler = params.getParameter(HttpMethodParams.RETRY_HANDLER) ;
+        assertNotNull("retry handler", handler) ;
+        assertEquals("handler class", handlerClass, handler.getClass()) ;
+    }
+
+    @Test
+    public void testConfigurableRetryHandlerPOST()
+        throws Exception
+    {
+        testConfigurableRetryHandler("POST") ;
+    }
+
+    @Test
+    public void testConfigurableRetryHandlerGET()
+        throws Exception
+    {
+        testConfigurableRetryHandler("GET") ;
+    }
+
+    private void testConfigurableRetryHandler(final String method)
+        throws Exception
+    {
+        final Class<ConfigurableRetryHandler> handlerClass = ConfigurableRetryHandler.class ;
+        final HttpMethodBase httpMethodBase = executeTest(method, handlerClass.getName()) ;
+        final HttpMethodParams params = httpMethodBase.getParams() ;
+        final Object handler = params.getParameter(HttpMethodParams.RETRY_HANDLER) ;
+        assertNotNull("retry handler", handler) ;
+        assertEquals("handler class", handlerClass, handler.getClass()) ;
+        final ConfigurableRetryHandler configurableRetryHandler = handlerClass.cast(handler) ;
+        assertNotNull("config", configurableRetryHandler.getConfig()) ;
+    }
+
+    private HttpMethodBase executeTest(final String method, final String handlerName)
+        throws Exception
+    {
+        final Message message = MessageFactory.getInstance().getMessage() ;
+        message.getBody().add("test") ;
+        final ConfigTree config = new ConfigTree("test") ;
+        if (handlerName != null)
+        {
+            config.setAttribute(AbstractHttpMethodFactory.RETRY_HANDLER, handlerName) ;
+        }
+        final HttpMethodFactory factory = HttpMethodFactory.Factory.getInstance(method, config, new URL("http://dummy")) ;
+        return factory.getInstance(message) ;
+    }
+
+    public static final class RetryHandler implements HttpMethodRetryHandler
+    {
+        public boolean retryMethod(final HttpMethod method, final IOException exception, final int executionCount)
+        {
+            return false;
+        }
+    }
+
+    public static final class ConfigurableRetryHandler implements HttpMethodRetryHandler, Configurable
+    {
+        private ConfigTree config ;
+
+        public boolean retryMethod(final HttpMethod method, final IOException exception, final int executionCount)
+        {
+            return false;
+        }
+
+        public void setConfiguration(final ConfigTree config)
+            throws ConfigurationException
+        {
+            this.config = config ;
+        }
+
+        public ConfigTree getConfig()
+        {
+            return config ;
+        }
+    }
+
+    public static junit.framework.Test suite() {
+        return new JUnit4TestAdapter(HttpMethodFactoryTest.class);
+    }
+}

Deleted: labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/rosetta/tests/src/org/jboss/soa/esb/client/MessageMulticasterUnitTest.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_7_CP/product/rosetta/tests/src/org/jboss/soa/esb/client/MessageMulticasterUnitTest.java	2010-08-13 08:26:20 UTC (rev 34695)
+++ labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/rosetta/tests/src/org/jboss/soa/esb/client/MessageMulticasterUnitTest.java	2010-08-19 17:44:42 UTC (rev 34800)
@@ -1,54 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2006, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt 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.soa.esb.client;
-
-import org.jboss.soa.esb.actions.Aggregator;
-import org.jboss.soa.esb.message.Message;
-import org.jboss.soa.esb.message.format.MessageFactory;
-
-import junit.framework.TestCase;
-
-/**
- * @author <a href="mailto:tom.fennelly at gmail.com">tom.fennelly at gmail.com</a>
- */
-public class MessageMulticasterUnitTest extends TestCase {
-
-	public void test_on_properties() {
-		MessageMulticaster multicaster = new MessageMulticaster();
-		Message message = MessageFactory.getInstance().getMessage();
-		
-		multicaster.setAggregatorOnProperties(true);
-		
-		assertTrue(Aggregator.getAggregatorTags(message, true) == null);		
-		multicaster.addAggregationDetails(message, "uuid", 3, 123123123123L, 1);
-		assertTrue(Aggregator.getAggregatorTags(message, true) != null);		
-	}
-
-	public void test_on_context() {
-		MessageMulticaster multicaster = new MessageMulticaster();
-		Message message = MessageFactory.getInstance().getMessage();
-		
-		assertTrue(Aggregator.getAggregatorTags(message, false) == null);		
-		multicaster.addAggregationDetails(message, "uuid", 3, 123123123123L, 1);
-		assertTrue(Aggregator.getAggregatorTags(message, false) != null);		
-	}
-}

Copied: labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/rosetta/tests/src/org/jboss/soa/esb/client/MessageMulticasterUnitTest.java (from rev 34762, labs/jbossesb/branches/JBESB_4_7_CP/product/rosetta/tests/src/org/jboss/soa/esb/client/MessageMulticasterUnitTest.java)
===================================================================
--- labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/rosetta/tests/src/org/jboss/soa/esb/client/MessageMulticasterUnitTest.java	                        (rev 0)
+++ labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/rosetta/tests/src/org/jboss/soa/esb/client/MessageMulticasterUnitTest.java	2010-08-19 17:44:42 UTC (rev 34800)
@@ -0,0 +1,83 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt 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.soa.esb.client;
+
+import java.util.List;
+
+import org.jboss.soa.esb.actions.Aggregator;
+import org.jboss.soa.esb.message.ByReferenceMessage;
+import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.message.format.MessageFactory;
+
+import junit.framework.TestCase;
+
+/**
+ * @author <a href="mailto:tom.fennelly at gmail.com">tom.fennelly at gmail.com</a>
+ */
+public class MessageMulticasterUnitTest extends TestCase {
+
+	public void test_on_properties() {
+		MessageMulticaster multicaster = new MessageMulticaster();
+		Message message = MessageFactory.getInstance().getMessage();
+		
+		multicaster.setAggregatorOnProperties(true);
+		
+		assertTrue(Aggregator.getAggregatorTags(message, true) == null);		
+		multicaster.addAggregationDetails(message, "uuid", 3, 123123123123L, 1);
+		assertTrue(Aggregator.getAggregatorTags(message, true) != null);		
+	}
+
+	public void test_on_context() {
+		MessageMulticaster multicaster = new MessageMulticaster();
+		Message message = MessageFactory.getInstance().getMessage();
+		
+		assertTrue(Aggregator.getAggregatorTags(message, false) == null);		
+		multicaster.addAggregationDetails(message, "uuid", 3, 123123123123L, 1);
+		assertTrue(Aggregator.getAggregatorTags(message, false) != null);		
+	}
+
+	public void test_on_duplicated_context() {
+		MessageMulticaster multicaster = new MessageMulticaster();
+		Message message = MessageFactory.getInstance().getMessage();
+		
+		assertNull("Aggregator tags", Aggregator.getAggregatorTags(message, false));
+		
+		multicaster.addAggregationDetails(message, "uuid", 2, 123123123123L, 1);
+		assertNotNull("First aggregator tags", Aggregator.getAggregatorTags(message, false));
+		
+		final Message referenceMessage = ((ByReferenceMessage)message).reference() ;
+		
+		multicaster.addAggregationDetails(message, "uuid", 2, 123123123123L, 2);
+		assertNotNull("Second aggregator tags", Aggregator.getAggregatorTags(message, false));
+		
+		final List<String> referenceAggregatorTags = Aggregator.getAggregatorTags(referenceMessage, false) ;
+		final List<String> finalAggregatorTags = Aggregator.getAggregatorTags(message, false) ;
+		
+		assertNotSame("Final aggregator tags", finalAggregatorTags, referenceAggregatorTags) ;
+		assertEquals("Final aggregator tag count", 1, finalAggregatorTags.size()) ;
+		assertEquals("Reference aggregator tag count", 1, referenceAggregatorTags.size()) ;
+		
+		final String finalAggregatorTag = finalAggregatorTags.get(0) ;
+		final String referenceAggregatorTag = referenceAggregatorTags.get(0) ;
+		assertFalse("Aggregator tag equality", finalAggregatorTag.equals(referenceAggregatorTag)) ;
+	}
+}

Deleted: labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/RemoteWsdlLoader.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_7_CP/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/RemoteWsdlLoader.java	2010-08-13 08:26:20 UTC (rev 34695)
+++ labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/RemoteWsdlLoader.java	2010-08-19 17:44:42 UTC (rev 34800)
@@ -1,139 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2006, JBoss Inc., and others contributors as indicated
- * by the @authors tag. All rights reserved.
- * See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- * This copyrighted material is made available to anyone wishing to use,
- * modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU Lesser General Public License, v. 2.1.
- * This program is distributed in the hope that it will be useful, but WITHOUT A
- * 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,
- * v.2.1 along with this distribution; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA  02110-1301, USA.
- *
- * (C) 2005-2006, JBoss Inc.
- */
-package org.jboss.soa.esb.actions.soap;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.Properties;
-
-import org.apache.commons.httpclient.HostConfiguration;
-import org.apache.commons.httpclient.HttpClient;
-import org.apache.commons.httpclient.HttpException;
-import org.apache.commons.httpclient.HttpMethodBase;
-import org.apache.commons.httpclient.HttpStatus;
-import org.apache.log4j.Logger;
-import org.jboss.internal.soa.esb.util.StreamUtils;
-import org.jboss.soa.esb.ConfigurationException;
-import org.jboss.soa.esb.actions.routing.http.HttpMethodFactory;
-import org.jboss.soa.esb.http.HttpClientFactory;
-import org.jboss.soa.esb.util.ClassUtil;
-
-/**
- * {@link HttpClientFactory} based WSLD loader.
- * <p/>
- * We use this in order to support different authentication modes that
- * may be required for WSDL lookup.
- *
- * @author <a href="mailto:tom.fennelly at jboss.com">tom.fennelly at jboss.com</a>
- */
-public class RemoteWsdlLoader {
-
-    private static Logger logger = Logger.getLogger(RemoteWsdlLoader.class);
-    private HttpClient httpClient;
-    private HostConfiguration hostConfig;
-
-    public RemoteWsdlLoader(Properties httpClientProps) throws ConfigurationException {
-        httpClient = HttpClientFactory.createHttpClient(httpClientProps);
-        hostConfig = httpClient.getHostConfiguration();
-        httpClient.setHostConfiguration(new HostConfiguration());
-    }
-
-    public InputStream load(String url, String charsetNameOverride) throws IOException {
-        if (httpClient == null) {
-            throw new IOException("RemoteWsdlLoader already shutdown") ;
-        }
-        
-        InputStream originalStream = null;
-        byte[] originalBytes = null;
-        String charsetNameDetected = null;
-        
-        if(url.startsWith("file")) {
-            originalStream = new URL(url).openStream();
-        } else if(url.startsWith("classpath://")) {
-        	originalStream = ClassUtil.getResource(url.substring(12, url.length()), getClass()).openStream();
-        } else {
-            HttpMethodBase httpMethod;
-            
-            try {
-    			HttpMethodFactory methodFactory = HttpMethodFactory.Factory.getInstance("GET", null, new URL(url));
-    			httpMethod = methodFactory.getInstance(null);
-    		} catch (ConfigurationException ce) {
-    			// should never happen with "GET" method since ConfigTree isn't used with GET - only POST
-    			throw (IOException)(new IOException(ce.getMessage()).initCause(ce));
-    		}
-
-            // Authentication is not being overridden on the method.  It needs
-            // to be present on the supplied HttpClient instance!
-            httpMethod.setDoAuthentication(true);
-
-            try {
-            	int result = httpClient.executeMethod(hostConfig, httpMethod);
-
-                if(result != HttpStatus.SC_OK) {
-                    if(result < 200 || result > 299) {
-                        throw new HttpException("Received status code '" + result + "' on WSDL HTTP (GET) request: '" + url + "'.");
-                    } else {
-                        logger.warn("Received status code '" + result + "' on WSDL HTTP (GET) request: '" + url + "'.");
-                    }
-                }
-                
-                originalBytes = httpMethod.getResponseBody();
-                charsetNameDetected = httpMethod.getResponseCharSet();
-            } finally {
-                httpMethod.releaseConnection();
-            }
-        }
-        
-        String charsetName = (charsetNameOverride != null ? charsetNameOverride : charsetNameDetected);
-        if (charsetName != null) {
-        	charsetName = charsetName.trim().toUpperCase();
-        	if (charsetName.equals("UTF-8") || charsetName.equals("UTF8")) {
-        		// short-circuit conversion; it's already UTF-8
-        		charsetName = null;
-        	}
-        }
-        if (charsetName != null) {
-        	// conversion WILL happen
-        	if (originalStream != null) {
-        		String read = StreamUtils.readStreamString(originalStream, charsetName);
-        		return new ByteArrayInputStream(read.getBytes("UTF-8"));
-        	} else if (originalBytes != null) {
-        		String read = new String(originalBytes, charsetName);
-        		return new ByteArrayInputStream(read.getBytes("UTF-8"));
-        	}
-        } else {
-        	// conversion will NOT happen
-        	if (originalStream != null) {
-        		return originalStream;
-        	} else if (originalBytes != null) {
-        		return new ByteArrayInputStream(originalBytes);
-        	}
-        }
-        throw new IOException("null data; could not load url: " + url + " with charsetName: " + charsetName);
-    }
-    
-    public void shutdown() {
-        HttpClientFactory.shutdown(httpClient);
-        httpClient = null ;
-    }
-}
-

Copied: labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/RemoteWsdlLoader.java (from rev 34799, labs/jbossesb/branches/JBESB_4_7_CP/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/RemoteWsdlLoader.java)
===================================================================
--- labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/RemoteWsdlLoader.java	                        (rev 0)
+++ labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/RemoteWsdlLoader.java	2010-08-19 17:44:42 UTC (rev 34800)
@@ -0,0 +1,156 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, JBoss Inc., and others contributors as indicated
+ * by the @authors tag. All rights reserved.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * 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,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA  02110-1301, USA.
+ *
+ * (C) 2005-2006, JBoss Inc.
+ */
+package org.jboss.soa.esb.actions.soap;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.Set;
+
+import org.apache.commons.httpclient.HostConfiguration;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.HttpException;
+import org.apache.commons.httpclient.HttpMethodBase;
+import org.apache.commons.httpclient.HttpStatus;
+import org.apache.log4j.Logger;
+import org.jboss.internal.soa.esb.util.StreamUtils;
+import org.jboss.soa.esb.ConfigurationException;
+import org.jboss.soa.esb.actions.routing.http.HttpMethodFactory;
+import org.jboss.soa.esb.helpers.ConfigTree;
+import org.jboss.soa.esb.http.HttpClientFactory;
+import org.jboss.soa.esb.util.ClassUtil;
+
+/**
+ * {@link HttpClientFactory} based WSLD loader.
+ * <p/>
+ * We use this in order to support different authentication modes that
+ * may be required for WSDL lookup.
+ *
+ * @author <a href="mailto:tom.fennelly at jboss.com">tom.fennelly at jboss.com</a>
+ */
+public class RemoteWsdlLoader {
+
+    private static Logger logger = Logger.getLogger(RemoteWsdlLoader.class);
+    private HttpClient httpClient;
+    private HostConfiguration hostConfig;
+    private ConfigTree config;
+
+    public RemoteWsdlLoader(Properties httpClientProps) throws ConfigurationException {
+        httpClient = HttpClientFactory.createHttpClient(httpClientProps);
+        hostConfig = httpClient.getHostConfiguration();
+        httpClient.setHostConfiguration(new HostConfiguration());
+        this.config = generateConfig(httpClientProps);
+    }
+
+    public InputStream load(String url, String charsetNameOverride) throws IOException {
+        if (httpClient == null) {
+            throw new IOException("RemoteWsdlLoader already shutdown") ;
+        }
+        
+        InputStream originalStream = null;
+        byte[] originalBytes = null;
+        String charsetNameDetected = null;
+        
+        if(url.startsWith("file")) {
+            originalStream = new URL(url).openStream();
+        } else if(url.startsWith("classpath://")) {
+        	originalStream = ClassUtil.getResource(url.substring(12, url.length()), getClass()).openStream();
+        } else {
+            HttpMethodBase httpMethod;
+            
+            try {
+    			HttpMethodFactory methodFactory = HttpMethodFactory.Factory.getInstance("GET", config, new URL(url));
+    			httpMethod = methodFactory.getInstance(null);
+    		} catch (ConfigurationException ce) {
+    			throw (IOException)(new IOException(ce.getMessage()).initCause(ce));
+    		}
+
+            // Authentication is not being overridden on the method.  It needs
+            // to be present on the supplied HttpClient instance!
+            httpMethod.setDoAuthentication(true);
+
+            try {
+            	int result = httpClient.executeMethod(hostConfig, httpMethod);
+
+                if(result != HttpStatus.SC_OK) {
+                    if(result < 200 || result > 299) {
+                        throw new HttpException("Received status code '" + result + "' on WSDL HTTP (GET) request: '" + url + "'.");
+                    } else {
+                        logger.warn("Received status code '" + result + "' on WSDL HTTP (GET) request: '" + url + "'.");
+                    }
+                }
+                
+                originalBytes = httpMethod.getResponseBody();
+                charsetNameDetected = httpMethod.getResponseCharSet();
+            } finally {
+                httpMethod.releaseConnection();
+            }
+        }
+        
+        String charsetName = (charsetNameOverride != null ? charsetNameOverride : charsetNameDetected);
+        if (charsetName != null) {
+        	charsetName = charsetName.trim().toUpperCase();
+        	if (charsetName.equals("UTF-8") || charsetName.equals("UTF8")) {
+        		// short-circuit conversion; it's already UTF-8
+        		charsetName = null;
+        	}
+        }
+        if (charsetName != null) {
+        	// conversion WILL happen
+        	if (originalStream != null) {
+        		String read = StreamUtils.readStreamString(originalStream, charsetName);
+        		return new ByteArrayInputStream(read.getBytes("UTF-8"));
+        	} else if (originalBytes != null) {
+        		String read = new String(originalBytes, charsetName);
+        		return new ByteArrayInputStream(read.getBytes("UTF-8"));
+        	}
+        } else {
+        	// conversion will NOT happen
+        	if (originalStream != null) {
+        		return originalStream;
+        	} else if (originalBytes != null) {
+        		return new ByteArrayInputStream(originalBytes);
+        	}
+        }
+        throw new IOException("null data; could not load url: " + url + " with charsetName: " + charsetName);
+    }
+    
+    public void shutdown() {
+        HttpClientFactory.shutdown(httpClient);
+        httpClient = null ;
+    }
+    
+    private static ConfigTree generateConfig(final Properties properties) {
+        final ConfigTree config = new ConfigTree("RemoteWsdlLoader");
+        final Set<Entry<Object, Object>> entrySet = properties.entrySet();
+        for (Entry<Object, Object> entry: entrySet) {
+            final Object key = entry.getKey();
+            final Object value = entry.getValue();
+            if ((key != null) && (value!=null)) {
+                config.setAttribute(key.toString(), value.toString());
+            }
+        }
+        return config;
+    }
+}
+

Deleted: labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/proxy/SOAPProxy.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_7_CP/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/proxy/SOAPProxy.java	2010-08-13 08:26:20 UTC (rev 34695)
+++ labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/proxy/SOAPProxy.java	2010-08-19 17:44:42 UTC (rev 34800)
@@ -1,407 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2006, JBoss Inc., and others contributors as indicated 
- * by the @authors tag. All rights reserved. 
- * See the copyright.txt in the distribution for a
- * full listing of individual contributors. 
- * This copyrighted material is made available to anyone wishing to use,
- * modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU Lesser General Public License, v. 2.1.
- * This program is distributed in the hope that it will be useful, but WITHOUT A 
- * 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,
- * v.2.1 along with this distribution; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
- * MA  02110-1301, USA.
- * 
- * (C) 2005-2009
- */
-package org.jboss.soa.esb.actions.soap.proxy;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.StringReader;
-import java.net.URL;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.xml.namespace.QName;
-
-import org.apache.log4j.Level;
-import org.apache.log4j.Logger;
-import org.jboss.internal.soa.esb.publish.Publish;
-import org.jboss.soa.esb.ConfigurationException;
-import org.jboss.soa.esb.actions.AbstractActionPipelineProcessor;
-import org.jboss.soa.esb.actions.ActionLifecycleException;
-import org.jboss.soa.esb.actions.ActionProcessingException;
-import org.jboss.soa.esb.helpers.ConfigTree;
-import org.jboss.soa.esb.http.HttpRequest;
-import org.jboss.soa.esb.listeners.message.MessageDeliverException;
-import org.jboss.soa.esb.message.Message;
-import org.jboss.soa.esb.message.MessagePayloadProxy;
-import org.jboss.ws.metadata.wsdl.WSDLBinding;
-import org.jboss.ws.metadata.wsdl.WSDLBindingOperation;
-import org.jboss.ws.metadata.wsdl.WSDLDefinitions;
-import org.jboss.ws.metadata.wsdl.WSDLEndpoint;
-import org.jboss.ws.metadata.wsdl.WSDLService;
-import org.jboss.ws.tools.wsdl.WSDLDefinitionsFactory;
-import org.xml.sax.Attributes;
-import org.xml.sax.ContentHandler;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.XMLReader;
-import org.xml.sax.helpers.DefaultHandler;
-import org.xml.sax.helpers.XMLReaderFactory;
-
-/**
- * A SOAPProxy focuses on the consumption of an external WS endpoint (e.g. hosted on .NET, another external Java-based AS, LAMP)
- * and re-publication of a WS endpoint via the ESB.  The ESB sits between the ultimate consumer/client (e.g. .NET WinForm
- * application) and the ultimate producer (e.g. RoR-hosted WS).  The purpose of this intermediary is to provide an abstraction
- * layer that solves the following problems:
- * <ul>
- * <li>Provides for more loose coupling between the client &amp; service; they are both completely unaware of each other.</li>
- * <li>The client no longer has a direct connection to the remote service's hostname/IP address.</li>
- * <li>The client will see modified WSDL that changes the inbound/outbound parameters. At a minimum, the WSDL must be tweaked so that the client is pointed to the ESB's exposed endpoint instead of the original, now proxied endpoint.</li>
- * <li>A transformation of the SOAP envelope/body can be introduced via the ESB action chain both for the inbound request and outbound response.  (see XsltAction or SmooksAction)</li>
- * <li>Service versioning is possible since clients can connect to 2 or more proxy endpoints on the ESB, each with its own WSDL and/or transformations and routing requirements, and the ESB will send the appropriate message to the appropriate endpoint and provide an ultimate response.</li>
- * <li>Complex context-based routing via ContentBasedRouter.</li>
- * </ul>
- * 
- * Other mechanisms of doing this are inappropriate or inadequate:
- * <ul>
- * <li>SOAPClient is used to invoke external web services, not mirror them.</li>
- * <li>SOAPProducer only executes internally-deployed JBoss WS services.</li>
- * <li>HttpRouter requires too much by-hand configuration for easy WS proxying.</li>
- * <li>EBWS strips out the SOAP Envelope and only passes along the body.</li>
- * </ul>
- * 
- * With a SOAPProxy action:
- * <ul>
- * <li>It is both a producer and consumer of web services.</li>
- * <li>All that is required is a property pointing to the external wsdl.</li>
- * <li>The wsdl can be automatically transformed via the optional wsdlTransform property.</li>
- * <li>It is understood that SOAP is not tied to http.  The wsdl is read, and if an http transport is defined, that will be used.  Other transports (jms) will need future consideration.</li>
- * <li>If using http, any of the HttpRouter properties can also optionally be applied to as overrides.</li>
- * </ul>
- * 
- * <i>Configuration Properties</i><br/>
- * <ul>
- * <li><b>wsdl</b> (required): The original wsdl {@link URL url} whose WS endpoint will get re-written and exposed as new wsdl from
- * the ESB.  Depending upon the &lt;definitions&gt;&lt;service&gt;&lt;port&gt;&lt;soap:address location attribute's protocol (for
- * example "http"), a protocol-specific {@link SOAPProxyTransport} implementation is used.  The value can reference a location based on
- * five different schemes:<br/>
- * <ul>
- * <li><b>http://</b><br/>
- * <ul>
- * <li>Usage: When you want to pull wsdl from an external web server.</li>
- * <li>Example: http://host/foo/HelloWorldWS?wsdl</li>
- * </ul></li>
- * <li><b>https://</b><br/>
- * <ul>
- * <li>Usage: When you want to pull wsdl from an external web server over SSL.</li>
- * <li>Example: https://host/foo/HelloWorldWS?wsdl</li>
- * </ul></li>
- * <li><b>file://</b><br/>
- * <ul>
- * <li>Usage: When your wsdl is located on disk, accessible by the ESB JVM.</li>
- * <li>Example: file:///tmp/HelloWorldWS.wsdl</li>
- * <li><i>Note: <b>3</b> slashes in the example above. This is so we can specify an absolute vs. relative file path.</i></li>
- * </ul></li>
- * <li><b>classpath://</b><br/>
- * <ul>
- * <li>Usage: When you want to package your wsdl inside your ESB archive.</li>
- * <li>Example: classpath:///META-INF/HelloWorldWS.wsdl</li>
- * <li><i>Note: <b>3</b> slashes in the example above. This is so we can specify an absolute vs. relative classloader resource path.</i></li>
- * </ul></li>
- * <li><b>internal://</b><br/>
- * <ul>
- * <li>Usage: When the wsdl is being provided by a JBossWS web service <b>inside the same JVM</b> as this ESB deployment.</li>
- * <li>Example: internal://jboss.ws:context=foo,endpoint=HelloWorldWS</li>
- * <li><i>Note: This scheme should be used instead of http or https in the usage described above. This is because on server restart, Tomcat may not yet be accepting incoming http/s requests, and thus cannot serve the wsdl.</i></li>
- * </ul></li>
- * </ul></li>
- * <li><b>wsdlTransform</b> (optional): A &lt;smooks-resource-list&gt; xml config file allowing for flexible wsdl transformation.</li>
- * <li><b>wsdlCharset</b> (optional): The character set the original wsdl (and imported resources) is encoded in, if not UTF-8.  It will be transformed to
- * UTF-8 if it is a <a href="http://java.sun.com/javase/6/docs/technotes/guides/intl/encoding.doc.html">supported encoding</a> by the underlying platform.</li>
- * <li><b>*</b> (optional): Any of the HttpRouter properties can be applied, if the wsdl specifies an http transport.</li>
- * <li><b>endpointUrl</b> (optional): Example of an HttpRouter property, but useful when domain name matching is important for SSL certs.</li>
- * <li><b>file</b> (optional): Apache Commons HTTPClient properties file, useful when proxying to a web service via SSL</li>
- * <li><b>clientCredentialsRequired</b> (optional; default is "true"): Whether the Basic Auth credentials are required to come from the end
- * client, or if the credentials specified inside <b>file</b> can be used instead.</li>
- * </ul>
- * <b>*</b> For other possible configuration properties, see the specific {@link SOAPProxyTransport} implementations themselves.<p/>
- * 
- * <i>Example of a straightforward scenario:</i><br/>
- * <pre>
- * &lt;action name="proxy" class="org.jboss.soa.esb.actions.soap.proxy.SOAPProxy"&gt;
- * &nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="wsdl" value="http://host/foo/HelloWorldWS?wsdl"/&gt;
- * &lt;/action&gt;
- * </pre>
- * <i>Example of a basic auth + ssl scenario:</i><br/>
- * <pre>
- * &lt;action name="proxy" class="org.jboss.soa.esb.actions.soap.proxy.SOAPProxy"&gt;
- * &nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="wsdl" value="https://host/foo/HelloWorldWS?wsdl"/&gt;
- * &nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="endpointUrl" value="https://host/foo/HelloWorldWS"/&gt;
- * &nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="file" value="/META-INF/httpclient-8443.properties"/&gt;
- * &nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="clientCredentialsRequired" value="true"/&gt;
- * &lt;/action&gt;
- * </pre>
- * 
- * @author dward at jboss.org
- */
- at Publish(SOAPProxyWsdlContractPublisher.class)
-public class SOAPProxy extends AbstractActionPipelineProcessor
-{
-	
-	private static Logger logger = Logger.getLogger(SOAPProxy.class);
-	
-	private MessagePayloadProxy payloadProxy;
-	
-	private Map<String,QName> soapaction_to_binding = new HashMap<String,QName>();
-	private Map<QName,QName> operation_to_binding = new HashMap<QName,QName>();
-	private Map<QName,SOAPProxyTransport> binding_to_transport = new HashMap<QName,SOAPProxyTransport>();
-	
-	public SOAPProxy(ConfigTree config) throws ConfigurationException
-	{
-		payloadProxy = new MessagePayloadProxy(config);
-		SOAPProxyWsdlLoader wsdl_loader = SOAPProxyWsdlLoader.newLoader(config);
-		WSDLDefinitions wsdl_def;
-		try
-		{
-			wsdl_loader.load(false);
-			URL wsdl_url = wsdl_loader.getURL();
-			wsdl_def = WSDLDefinitionsFactory.newInstance().parse(wsdl_url);
-		}
-		catch (IOException ioe)
-		{
-			throw new ConfigurationException(ioe);
-		}
-		finally
-		{
-			wsdl_loader.cleanup();
-		}
-		for ( WSDLBinding wsdl_bind : wsdl_def.getBindings() )
-		{
-			for ( WSDLBindingOperation wsdl_bind_oper : wsdl_bind.getOperations() )
-			{
-				QName binding = wsdl_bind.getName();
-				if (binding != null)
-				{
-					// http://www.w3.org/TR/2000/NOTE-SOAP-20000508/#_Toc478383528
-					// http://www.ws-i.org/Profiles/BasicProfile-1.1.html#SOAPAction_HTTP_Header
-					String soapaction = wsdl_bind_oper.getSOAPAction();
-					if (soapaction != null)
-					{
-						if ( !soapaction.startsWith("\"") && !soapaction.endsWith("\"") )
-						{
-							soapaction = '"' + soapaction + '"';
-						}
-						if ( !soapaction_to_binding.containsKey(soapaction) )
-						{
-							soapaction_to_binding.put(soapaction, binding);
-							if ( logger.isInfoEnabled() )
-							{
-								logger.info("mapped soapaction [" + soapaction + "] to binding [" + binding + "]");
-							}
-						}
-					}
-					QName operation = wsdl_bind_oper.getRef();
-					if ( operation != null && !operation_to_binding.containsKey(operation) )
-					{
-						operation_to_binding.put(operation, binding);
-						if ( logger.isInfoEnabled() )
-						{
-							logger.info("mapped operation [" + operation + "] to binding [" + binding + "]");
-						}
-					}
-				}
-			}
-		}
-		for ( WSDLService wsdl_svc : wsdl_def.getServices() )
-		{
-			for ( WSDLEndpoint wsdl_end : wsdl_svc.getEndpoints() )
-			{
-				QName binding = wsdl_end.getBinding();
-				SOAPProxyTransport transport = null;
-				String endpointAddress = wsdl_end.getAddress();
-				if ( endpointAddress.toLowerCase().startsWith("http") )
-				{
-					transport = new HttpSOAPProxyTransport(config, payloadProxy, endpointAddress);
-				}
-				// else if jms ...
-				if (transport != null)
-				{
-					if ( !binding_to_transport.containsKey(binding) )
-					{
-						binding_to_transport.put(binding, transport);
-						if ( logger.isInfoEnabled() )
-						{
-							logger.info("mapped binding [" + binding + "] to transport [" + transport.getClass().getName() + "] with endpoint address: [" + transport.getEndpointAddress() + "]");
-						}
-					}
-				}
-				else
-				{
-					if ( logger.isEnabledFor(Level.WARN) )
-					{
-						logger.warn("could not map binding [" + binding + "] to transport with endpoint address: [" + endpointAddress + "]");
-					}
-				}
-			}
-		}
-	}
-	
-	public void initialise() throws ActionLifecycleException
-	{
-		for ( SOAPProxyTransport transport : binding_to_transport.values() )
-		{
-			transport.initialise();
-		}
-	}
-	
-	public Message process(Message message) throws ActionProcessingException
-	{
-		String soapaction = null;
-		HttpRequest request = HttpRequest.getRequest(message);
-		if (request != null)
-		{
-			soapaction = request.getHeaderValue("soapaction");
-		}
-		if (soapaction == null)
-		{
-			soapaction = (String)message.getProperties().getProperty("soapaction");
-		}
-		QName binding = (soapaction != null) ? soapaction_to_binding.get(soapaction) : null;
-		QName operation = null;
-		if (binding == null)
-		{
-			if ( logger.isEnabledFor(Level.WARN) )
-			{
-				logger.warn("null binding for soapaction [" + soapaction + "]; parsing envelope to discover operation...");
-			}
-			operation = getOperation(message);
-			binding = (operation != null) ? operation_to_binding.get(operation) : null;
-			if ( binding == null  && logger.isEnabledFor(Level.ERROR) )
-			{
-				logger.error("null binding for operation [" + operation + "] in addition to soapaction [" + soapaction + "]");
-			}
-		}
-		SOAPProxyTransport transport = (binding != null) ? binding_to_transport.get(binding) : null;
-		if (transport == null)
-		{
-			throw new ActionProcessingException("null transport for soapaction [" + soapaction + "], operation [" + operation + "], binding [" + binding + "]");
-		}
-		if ( logger.isDebugEnabled() )
-		{
-			logger.debug("using transport [" + transport.getClass().getName() + "] with endpoint address: [" + transport.getEndpointAddress() + "] for binding [" + binding + "]");
-		}
-		return transport.process(message);
-	}
-	
-	public void destroy() throws ActionLifecycleException
-	{
-		for ( SOAPProxyTransport transport : binding_to_transport.values() )
-		{
-			transport.destroy();
-		}
-	}
-	
-	// This is a best guess (and potentially expensive)!  See logger.warn(String) warning in process(Message) above.
-	private QName getOperation(Message message) throws ActionProcessingException
-	{
-		Object payload;
-		try
-		{
-			payload = payloadProxy.getPayload(message);
-		}
-		catch (MessageDeliverException mde)
-		{
-			throw new ActionProcessingException(mde);
-		}
-		InputSource is = null;
-		if (payload instanceof byte[])
-		{
-			byte[] byte_payload = (byte[])payload;
-			if (byte_payload.length == 0)
-			{
-				throw new ActionProcessingException("message contains zero-length byte[] payload");
-			}
-			is = new InputSource( new ByteArrayInputStream(byte_payload) );
-		}
-		else if (payload instanceof String)
-		{
-			String string_payload = (String)payload;
-			if (string_payload.length() == 0)
-			{
-				throw new ActionProcessingException("message contains zero-length String payload");
-			}
-			is = new InputSource( new StringReader(string_payload) );
-		}
-		else
-		{
-			throw new ActionProcessingException( "unsupported payload type: " + payload.getClass().getName() );
-		}
-		QName operation = null;
-		ContentHandler ch = new OperationFinder();
-		try
-		{
-			XMLReader xr = XMLReaderFactory.createXMLReader();
-			xr.setContentHandler(ch);
-			xr.parse(is);
-		}
-		catch (SAXException saxe)
-		{
-			throw new ActionProcessingException(saxe);
-		}
-		catch (IOException ioe)
-		{
-			throw new ActionProcessingException(ioe);
-		}
-		catch (OperationFinder.OperationFound of)
-		{
-			operation = of.operation;
-		}
-		return operation;
-	}
-	
-	private static class OperationFinder extends DefaultHandler
-	{
-		
-		private boolean insideEnvelope = false;
-		private boolean insideBody = false;
-		
-		@Override
-		public void startElement(String uri, String localName, String qName, Attributes atts)
-		{
-			if ( localName.equals("Envelope") )
-			{
-				insideEnvelope = true;
-			}
-			else if ( localName.equals("Body") )
-			{
-				insideBody = true;
-			}
-			else if (insideEnvelope && insideBody)
-			{
-				// stop parsing as soon as possible!
-				throw new OperationFound( new QName(uri, localName) );
-			}
-		}
-		
-		@SuppressWarnings("serial")
-		private static class OperationFound extends RuntimeException
-		{
-			
-			private QName operation;
-			
-			private OperationFound(QName operation)
-			{
-				this.operation = operation;
-			}
-			
-		}
-		
-	}
-
-}

Copied: labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/proxy/SOAPProxy.java (from rev 34799, labs/jbossesb/branches/JBESB_4_7_CP/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/proxy/SOAPProxy.java)
===================================================================
--- labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/proxy/SOAPProxy.java	                        (rev 0)
+++ labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/proxy/SOAPProxy.java	2010-08-19 17:44:42 UTC (rev 34800)
@@ -0,0 +1,443 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, JBoss Inc., and others contributors as indicated 
+ * by the @authors tag. All rights reserved. 
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors. 
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A 
+ * 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,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+ * MA  02110-1301, USA.
+ * 
+ * (C) 2005-2009
+ */
+package org.jboss.soa.esb.actions.soap.proxy;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.StringReader;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.jboss.internal.soa.esb.publish.ContractProvider;
+import org.jboss.internal.soa.esb.publish.ContractProviderLifecycleResource;
+import org.jboss.internal.soa.esb.publish.Publish;
+import org.jboss.soa.esb.Configurable;
+import org.jboss.soa.esb.ConfigurationException;
+import org.jboss.soa.esb.actions.AbstractActionPipelineProcessor;
+import org.jboss.soa.esb.actions.ActionLifecycleException;
+import org.jboss.soa.esb.actions.ActionProcessingException;
+import org.jboss.soa.esb.helpers.ConfigTree;
+import org.jboss.soa.esb.http.HttpRequest;
+import org.jboss.soa.esb.lifecycle.LifecycleResourceException;
+import org.jboss.soa.esb.listeners.ListenerTagNames;
+import org.jboss.soa.esb.listeners.message.MessageDeliverException;
+import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.message.MessagePayloadProxy;
+import org.jboss.ws.metadata.wsdl.WSDLBinding;
+import org.jboss.ws.metadata.wsdl.WSDLBindingOperation;
+import org.jboss.ws.metadata.wsdl.WSDLDefinitions;
+import org.jboss.ws.metadata.wsdl.WSDLEndpoint;
+import org.jboss.ws.metadata.wsdl.WSDLService;
+import org.jboss.ws.tools.wsdl.WSDLDefinitionsFactory;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.DefaultHandler;
+import org.xml.sax.helpers.XMLReaderFactory;
+
+/**
+ * A SOAPProxy focuses on the consumption of an external WS endpoint (e.g. hosted on .NET, another external Java-based AS, LAMP)
+ * and re-publication of a WS endpoint via the ESB.  The ESB sits between the ultimate consumer/client (e.g. .NET WinForm
+ * application) and the ultimate producer (e.g. RoR-hosted WS).  The purpose of this intermediary is to provide an abstraction
+ * layer that solves the following problems:
+ * <ul>
+ * <li>Provides for more loose coupling between the client &amp; service; they are both completely unaware of each other.</li>
+ * <li>The client no longer has a direct connection to the remote service's hostname/IP address.</li>
+ * <li>The client will see modified WSDL that changes the inbound/outbound parameters. At a minimum, the WSDL must be tweaked so that the client is pointed to the ESB's exposed endpoint instead of the original, now proxied endpoint.</li>
+ * <li>A transformation of the SOAP envelope/body can be introduced via the ESB action chain both for the inbound request and outbound response.  (see XsltAction or SmooksAction)</li>
+ * <li>Service versioning is possible since clients can connect to 2 or more proxy endpoints on the ESB, each with its own WSDL and/or transformations and routing requirements, and the ESB will send the appropriate message to the appropriate endpoint and provide an ultimate response.</li>
+ * <li>Complex context-based routing via ContentBasedRouter.</li>
+ * </ul>
+ * 
+ * Other mechanisms of doing this are inappropriate or inadequate:
+ * <ul>
+ * <li>SOAPClient is used to invoke external web services, not mirror them.</li>
+ * <li>SOAPProducer only executes internally-deployed JBoss WS services.</li>
+ * <li>HttpRouter requires too much by-hand configuration for easy WS proxying.</li>
+ * <li>EBWS strips out the SOAP Envelope and only passes along the body.</li>
+ * </ul>
+ * 
+ * With a SOAPProxy action:
+ * <ul>
+ * <li>It is both a producer and consumer of web services.</li>
+ * <li>All that is required is a property pointing to the external wsdl.</li>
+ * <li>The wsdl can be automatically transformed via the optional wsdlTransform property.</li>
+ * <li>It is understood that SOAP is not tied to http.  The wsdl is read, and if an http transport is defined, that will be used.  Other transports (jms) will need future consideration.</li>
+ * <li>If using http, any of the HttpRouter properties can also optionally be applied to as overrides.</li>
+ * </ul>
+ * 
+ * <i>Configuration Properties</i><br/>
+ * <ul>
+ * <li><b>wsdl</b> (required): The original wsdl {@link URL url} whose WS endpoint will get re-written and exposed as new wsdl from
+ * the ESB.  Depending upon the &lt;definitions&gt;&lt;service&gt;&lt;port&gt;&lt;soap:address location attribute's protocol (for
+ * example "http"), a protocol-specific {@link SOAPProxyTransport} implementation is used.  The value can reference a location based on
+ * five different schemes:<br/>
+ * <ul>
+ * <li><b>http://</b><br/>
+ * <ul>
+ * <li>Usage: When you want to pull wsdl from an external web server.</li>
+ * <li>Example: http://host/foo/HelloWorldWS?wsdl</li>
+ * </ul></li>
+ * <li><b>https://</b><br/>
+ * <ul>
+ * <li>Usage: When you want to pull wsdl from an external web server over SSL.</li>
+ * <li>Example: https://host/foo/HelloWorldWS?wsdl</li>
+ * </ul></li>
+ * <li><b>file://</b><br/>
+ * <ul>
+ * <li>Usage: When your wsdl is located on disk, accessible by the ESB JVM.</li>
+ * <li>Example: file:///tmp/HelloWorldWS.wsdl</li>
+ * <li><i>Note: <b>3</b> slashes in the example above. This is so we can specify an absolute vs. relative file path.</i></li>
+ * </ul></li>
+ * <li><b>classpath://</b><br/>
+ * <ul>
+ * <li>Usage: When you want to package your wsdl inside your ESB archive.</li>
+ * <li>Example: classpath:///META-INF/HelloWorldWS.wsdl</li>
+ * <li><i>Note: <b>3</b> slashes in the example above. This is so we can specify an absolute vs. relative classloader resource path.</i></li>
+ * </ul></li>
+ * <li><b>internal://</b><br/>
+ * <ul>
+ * <li>Usage: When the wsdl is being provided by a JBossWS web service <b>inside the same JVM</b> as this ESB deployment.</li>
+ * <li>Example: internal://jboss.ws:context=foo,endpoint=HelloWorldWS</li>
+ * <li><i>Note: This scheme should be used instead of http or https in the usage described above. This is because on server restart, Tomcat may not yet be accepting incoming http/s requests, and thus cannot serve the wsdl.</i></li>
+ * </ul></li>
+ * </ul></li>
+ * <li><b>wsdlTransform</b> (optional): A &lt;smooks-resource-list&gt; xml config file allowing for flexible wsdl transformation.</li>
+ * <li><b>wsdlCharset</b> (optional): The character set the original wsdl (and imported resources) is encoded in, if not UTF-8.  It will be transformed to
+ * UTF-8 if it is a <a href="http://java.sun.com/javase/6/docs/technotes/guides/intl/encoding.doc.html">supported encoding</a> by the underlying platform.</li>
+ * <li><b>*</b> (optional): Any of the HttpRouter properties can be applied, if the wsdl specifies an http transport.</li>
+ * <li><b>endpointUrl</b> (optional): Example of an HttpRouter property, but useful when domain name matching is important for SSL certs.</li>
+ * <li><b>file</b> (optional): Apache Commons HTTPClient properties file, useful when proxying to a web service via SSL</li>
+ * <li><b>clientCredentialsRequired</b> (optional; default is "true"): Whether the Basic Auth credentials are required to come from the end
+ * client, or if the credentials specified inside <b>file</b> can be used instead.</li>
+ * <li><b>wsdlUseHttpClientProperties</b> (optional): if true then WSDL retrieval will use the same http-client-property as main webservice, otherwise will use wsdl-http-client-property entries.
+ * </ul>
+ * <b>*</b> For other possible configuration properties, see the specific {@link SOAPProxyTransport} implementations themselves.<p/>
+ * 
+ * <i>Example of a straightforward scenario:</i><br/>
+ * <pre>
+ * &lt;action name="proxy" class="org.jboss.soa.esb.actions.soap.proxy.SOAPProxy"&gt;
+ * &nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="wsdl" value="http://host/foo/HelloWorldWS?wsdl"/&gt;
+ * &lt;/action&gt;
+ * </pre>
+ * <i>Example of a basic auth + ssl scenario:</i><br/>
+ * <pre>
+ * &lt;action name="proxy" class="org.jboss.soa.esb.actions.soap.proxy.SOAPProxy"&gt;
+ * &nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="wsdl" value="https://host/foo/HelloWorldWS?wsdl"/&gt;
+ * &nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="endpointUrl" value="https://host/foo/HelloWorldWS"/&gt;
+ * &nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="file" value="/META-INF/httpclient-8443.properties"/&gt;
+ * &nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="clientCredentialsRequired" value="true"/&gt;
+ * &lt;/action&gt;
+ * </pre>
+ * 
+ * @author dward at jboss.org
+ */
+ at Publish(SOAPProxyWsdlContractPublisher.class)
+public class SOAPProxy extends AbstractActionPipelineProcessor
+{
+	
+	private static Logger logger = Logger.getLogger(SOAPProxy.class);
+	
+	private MessagePayloadProxy payloadProxy;
+	
+	private Map<String,QName> soapaction_to_binding = new HashMap<String,QName>();
+	private Map<QName,QName> operation_to_binding = new HashMap<QName,QName>();
+	private Map<QName,SOAPProxyTransport> binding_to_transport = new HashMap<QName,SOAPProxyTransport>();
+	
+	public SOAPProxy(ConfigTree config) throws ConfigurationException
+	{
+		payloadProxy = new MessagePayloadProxy(config);
+		initialiseContractPublisher(config);
+		SOAPProxyWsdlLoader wsdl_loader = SOAPProxyWsdlLoader.newLoader(config);
+		WSDLDefinitions wsdl_def;
+		try
+		{
+			wsdl_loader.load(false);
+			URL wsdl_url = wsdl_loader.getURL();
+			wsdl_def = WSDLDefinitionsFactory.newInstance().parse(wsdl_url);
+		}
+		catch (IOException ioe)
+		{
+			throw new ConfigurationException(ioe);
+		}
+		finally
+		{
+			wsdl_loader.cleanup();
+		}
+		for ( WSDLBinding wsdl_bind : wsdl_def.getBindings() )
+		{
+			for ( WSDLBindingOperation wsdl_bind_oper : wsdl_bind.getOperations() )
+			{
+				QName binding = wsdl_bind.getName();
+				if (binding != null)
+				{
+					// http://www.w3.org/TR/2000/NOTE-SOAP-20000508/#_Toc478383528
+					// http://www.ws-i.org/Profiles/BasicProfile-1.1.html#SOAPAction_HTTP_Header
+					String soapaction = wsdl_bind_oper.getSOAPAction();
+					if (soapaction != null)
+					{
+						if ( !soapaction.startsWith("\"") && !soapaction.endsWith("\"") )
+						{
+							soapaction = '"' + soapaction + '"';
+						}
+						if ( !soapaction_to_binding.containsKey(soapaction) )
+						{
+							soapaction_to_binding.put(soapaction, binding);
+							if ( logger.isInfoEnabled() )
+							{
+								logger.info("mapped soapaction [" + soapaction + "] to binding [" + binding + "]");
+							}
+						}
+					}
+					QName operation = wsdl_bind_oper.getRef();
+					if ( operation != null && !operation_to_binding.containsKey(operation) )
+					{
+						operation_to_binding.put(operation, binding);
+						if ( logger.isInfoEnabled() )
+						{
+							logger.info("mapped operation [" + operation + "] to binding [" + binding + "]");
+						}
+					}
+				}
+			}
+		}
+		for ( WSDLService wsdl_svc : wsdl_def.getServices() )
+		{
+			for ( WSDLEndpoint wsdl_end : wsdl_svc.getEndpoints() )
+			{
+				QName binding = wsdl_end.getBinding();
+				SOAPProxyTransport transport = null;
+				String endpointAddress = wsdl_end.getAddress();
+				if ( endpointAddress.toLowerCase().startsWith("http") )
+				{
+					transport = new HttpSOAPProxyTransport(config, payloadProxy, endpointAddress);
+				}
+				// else if jms ...
+				if (transport != null)
+				{
+					if ( !binding_to_transport.containsKey(binding) )
+					{
+						binding_to_transport.put(binding, transport);
+						if ( logger.isInfoEnabled() )
+						{
+							logger.info("mapped binding [" + binding + "] to transport [" + transport.getClass().getName() + "] with endpoint address: [" + transport.getEndpointAddress() + "]");
+						}
+					}
+				}
+				else
+				{
+					if ( logger.isEnabledFor(Level.WARN) )
+					{
+						logger.warn("could not map binding [" + binding + "] to transport with endpoint address: [" + endpointAddress + "]");
+					}
+				}
+			}
+		}
+	}
+	
+	private void initialiseContractPublisher(final ConfigTree config)
+		throws ConfigurationException
+	{
+		final ConfigTree parent = config.getParent();
+		if (parent != null)
+		{
+			final String category = parent.getAttribute(ListenerTagNames.SERVICE_CATEGORY_NAME_TAG);
+			final String name = parent.getAttribute(ListenerTagNames.SERVICE_NAME_TAG);
+			if ((category != null) && (name != null))
+			{
+				final ContractProvider provider ;
+				try
+				{
+					provider = ContractProviderLifecycleResource.getContractProvider(category, name);
+				}
+				catch (final LifecycleResourceException lre)
+				{
+					throw new ConfigurationException("Unexpected exception querying contract provider", lre);
+				}
+				
+				if ((provider != null) && (provider instanceof Configurable))
+				{
+					final Configurable configurable = Configurable.class.cast(provider) ;
+					configurable.setConfiguration(config);
+				}
+			}
+		}
+	}
+	
+	public void initialise() throws ActionLifecycleException
+	{
+		for ( SOAPProxyTransport transport : binding_to_transport.values() )
+		{
+			transport.initialise();
+		}
+	}
+	
+	public Message process(Message message) throws ActionProcessingException
+	{
+		String soapaction = null;
+		HttpRequest request = HttpRequest.getRequest(message);
+		if (request != null)
+		{
+			soapaction = request.getHeaderValue("soapaction");
+		}
+		if (soapaction == null)
+		{
+			soapaction = (String)message.getProperties().getProperty("soapaction");
+		}
+		QName binding = (soapaction != null) ? soapaction_to_binding.get(soapaction) : null;
+		QName operation = null;
+		if (binding == null)
+		{
+			if ( logger.isEnabledFor(Level.WARN) )
+			{
+				logger.warn("null binding for soapaction [" + soapaction + "]; parsing envelope to discover operation...");
+			}
+			operation = getOperation(message);
+			binding = (operation != null) ? operation_to_binding.get(operation) : null;
+			if ( binding == null  && logger.isEnabledFor(Level.ERROR) )
+			{
+				logger.error("null binding for operation [" + operation + "] in addition to soapaction [" + soapaction + "]");
+			}
+		}
+		SOAPProxyTransport transport = (binding != null) ? binding_to_transport.get(binding) : null;
+		if (transport == null)
+		{
+			throw new ActionProcessingException("null transport for soapaction [" + soapaction + "], operation [" + operation + "], binding [" + binding + "]");
+		}
+		if ( logger.isDebugEnabled() )
+		{
+			logger.debug("using transport [" + transport.getClass().getName() + "] with endpoint address: [" + transport.getEndpointAddress() + "] for binding [" + binding + "]");
+		}
+		return transport.process(message);
+	}
+	
+	public void destroy() throws ActionLifecycleException
+	{
+		for ( SOAPProxyTransport transport : binding_to_transport.values() )
+		{
+			transport.destroy();
+		}
+	}
+	
+	// This is a best guess (and potentially expensive)!  See logger.warn(String) warning in process(Message) above.
+	private QName getOperation(Message message) throws ActionProcessingException
+	{
+		Object payload;
+		try
+		{
+			payload = payloadProxy.getPayload(message);
+		}
+		catch (MessageDeliverException mde)
+		{
+			throw new ActionProcessingException(mde);
+		}
+		InputSource is = null;
+		if (payload instanceof byte[])
+		{
+			byte[] byte_payload = (byte[])payload;
+			if (byte_payload.length == 0)
+			{
+				throw new ActionProcessingException("message contains zero-length byte[] payload");
+			}
+			is = new InputSource( new ByteArrayInputStream(byte_payload) );
+		}
+		else if (payload instanceof String)
+		{
+			String string_payload = (String)payload;
+			if (string_payload.length() == 0)
+			{
+				throw new ActionProcessingException("message contains zero-length String payload");
+			}
+			is = new InputSource( new StringReader(string_payload) );
+		}
+		else
+		{
+			throw new ActionProcessingException( "unsupported payload type: " + payload.getClass().getName() );
+		}
+		QName operation = null;
+		ContentHandler ch = new OperationFinder();
+		try
+		{
+			XMLReader xr = XMLReaderFactory.createXMLReader();
+			xr.setContentHandler(ch);
+			xr.parse(is);
+		}
+		catch (SAXException saxe)
+		{
+			throw new ActionProcessingException(saxe);
+		}
+		catch (IOException ioe)
+		{
+			throw new ActionProcessingException(ioe);
+		}
+		catch (OperationFinder.OperationFound of)
+		{
+			operation = of.operation;
+		}
+		return operation;
+	}
+	
+	private static class OperationFinder extends DefaultHandler
+	{
+		
+		private boolean insideEnvelope = false;
+		private boolean insideBody = false;
+		
+		@Override
+		public void startElement(String uri, String localName, String qName, Attributes atts)
+		{
+			if ( localName.equals("Envelope") )
+			{
+				insideEnvelope = true;
+			}
+			else if ( localName.equals("Body") )
+			{
+				insideBody = true;
+			}
+			else if (insideEnvelope && insideBody)
+			{
+				// stop parsing as soon as possible!
+				throw new OperationFound( new QName(uri, localName) );
+			}
+		}
+		
+		@SuppressWarnings("serial")
+		private static class OperationFound extends RuntimeException
+		{
+			
+			private QName operation;
+			
+			private OperationFound(QName operation)
+			{
+				this.operation = operation;
+			}
+			
+		}
+		
+	}
+
+}

Deleted: labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/proxy/SOAPProxyWsdlContractPublisher.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_7_CP/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/proxy/SOAPProxyWsdlContractPublisher.java	2010-08-13 08:26:20 UTC (rev 34695)
+++ labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/proxy/SOAPProxyWsdlContractPublisher.java	2010-08-19 17:44:42 UTC (rev 34800)
@@ -1,118 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2006, JBoss Inc., and others contributors as indicated 
- * by the @authors tag. All rights reserved. 
- * See the copyright.txt in the distribution for a
- * full listing of individual contributors. 
- * This copyrighted material is made available to anyone wishing to use,
- * modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU Lesser General Public License, v. 2.1.
- * This program is distributed in the hope that it will be useful, but WITHOUT A 
- * 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,
- * v.2.1 along with this distribution; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
- * MA  02110-1301, USA.
- * 
- * (C) 2005-2009
- */
-package org.jboss.soa.esb.actions.soap.proxy;
-
-import java.io.IOException;
-import java.net.URI;
-import java.util.Properties;
-
-import org.jboss.internal.soa.esb.publish.ContractInfo;
-import org.jboss.internal.soa.esb.publish.ContractProvider;
-import org.jboss.soa.esb.ConfigurationException;
-import org.jboss.soa.esb.Service;
-import org.jboss.soa.esb.actions.soap.AuthBASICWsdlContractPublisher;
-import org.jboss.soa.esb.addressing.EPR;
-import org.jboss.soa.esb.helpers.ConfigTree;
-import org.jboss.soa.esb.listeners.ListenerTagNames;
-
-/**
- * SOAPProxy wsdl contract publisher.
- * 
- * @author dward at jboss.org
- */
-public class SOAPProxyWsdlContractPublisher extends AuthBASICWsdlContractPublisher implements ContractProvider
-{
-	
-	@Override
-	public ContractInfo getContractInfo(Service service, String wsdlAddress) throws IOException
-	{
-		Properties properties = getActionProperties();
-		ConfigTree config;
-		if (service != null)
-		{
-			ConfigTree parent_config = new ConfigTree("parent_config");
-			parent_config.setAttribute( ListenerTagNames.SERVICE_CATEGORY_NAME_TAG, service.getCategory() );
-			parent_config.setAttribute( ListenerTagNames.SERVICE_NAME_TAG, service.getName() );
-			config = new ConfigTree("config", parent_config);
-		}
-		else
-		{
-			config = new ConfigTree("config");
-		}
-		for ( Object key : properties.keySet() )
-		{
-			String name = (String)key;
-			String value = properties.getProperty(name);
-			config.setAttribute(name, value);
-		}
-		SOAPProxyWsdlLoader wsdl_loader;
-		try
-		{
-			wsdl_loader = SOAPProxyWsdlLoader.newLoader(config);
-		}
-		catch (ConfigurationException ce)
-		{
-			throw (IOException)(new IOException(ce.getMessage()).initCause(ce));
-		}
-		try
-		{
-			return wsdl_loader.load(true);
-		}
-		finally
-		{
-			wsdl_loader.cleanup();
-		}
-	}
-	
-	public void setContractProperties(Properties contractProperties)
-	{
-		setActionProperties(contractProperties);
-	}
-	
-	public ContractInfo provideContract(Service service) throws IOException
-	{
-		return provideContract(service, null);
-	}
-	
-	public ContractInfo provideContract(Service service, String endpointAddressOverride) throws IOException
-	{
-		ContractInfo contract;
-		if (endpointAddressOverride != null)
-		{
-			try
-			{
-				initializeTransformer();
-			}
-			catch (ConfigurationException ce)
-			{
-				throw new IOException( ce.getMessage() );
-			}
-			contract = getContractInfo( new EPR(URI.create(endpointAddressOverride)) );
-		}
-		else
-		{
-			// !!! *HAS* TO BE THE *SUPER* CLASS' IMPLEMENTATION !!!
-			// --> AbstractWsdlContractPublisher.getContractInfo(String) <--
-			contract = super.getContractInfo( service, getWsdlAddress() );
-		}
-		return contract; 
-	}
-	
-}

Copied: labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/proxy/SOAPProxyWsdlContractPublisher.java (from rev 34799, labs/jbossesb/branches/JBESB_4_7_CP/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/proxy/SOAPProxyWsdlContractPublisher.java)
===================================================================
--- labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/proxy/SOAPProxyWsdlContractPublisher.java	                        (rev 0)
+++ labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/proxy/SOAPProxyWsdlContractPublisher.java	2010-08-19 17:44:42 UTC (rev 34800)
@@ -0,0 +1,133 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, JBoss Inc., and others contributors as indicated 
+ * by the @authors tag. All rights reserved. 
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors. 
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A 
+ * 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,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+ * MA  02110-1301, USA.
+ * 
+ * (C) 2005-2009
+ */
+package org.jboss.soa.esb.actions.soap.proxy;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.Properties;
+
+import org.jboss.internal.soa.esb.publish.ContractInfo;
+import org.jboss.internal.soa.esb.publish.ContractProvider;
+import org.jboss.soa.esb.Configurable;
+import org.jboss.soa.esb.ConfigurationException;
+import org.jboss.soa.esb.Service;
+import org.jboss.soa.esb.actions.soap.AuthBASICWsdlContractPublisher;
+import org.jboss.soa.esb.addressing.EPR;
+import org.jboss.soa.esb.helpers.ConfigTree;
+import org.jboss.soa.esb.listeners.ListenerTagNames;
+
+/**
+ * SOAPProxy wsdl contract publisher.
+ * 
+ * @author dward at jboss.org
+ */
+public class SOAPProxyWsdlContractPublisher extends AuthBASICWsdlContractPublisher implements ContractProvider, Configurable
+{
+	private ConfigTree actionConfig;
+	
+	@Override
+	public ContractInfo getContractInfo(Service service, String wsdlAddress) throws IOException
+	{
+		final ConfigTree config;
+		if ((wsdlAddress != null) && wsdlAddress.startsWith("http"))
+		{
+			config = actionConfig ;
+		}
+		else
+		{
+			Properties properties = getActionProperties();
+			if (service != null)
+			{
+				ConfigTree parent_config = new ConfigTree("parent_config");
+				parent_config.setAttribute( ListenerTagNames.SERVICE_CATEGORY_NAME_TAG, service.getCategory() );
+				parent_config.setAttribute( ListenerTagNames.SERVICE_NAME_TAG, service.getName() );
+				config = new ConfigTree("config", parent_config);
+			}
+			else
+			{
+				config = new ConfigTree("config");
+			}
+			for ( Object key : properties.keySet() )
+			{
+				String name = (String)key;
+				String value = properties.getProperty(name);
+				config.setAttribute(name, value);
+			}
+		}
+		SOAPProxyWsdlLoader wsdl_loader;
+		try
+		{
+			wsdl_loader = SOAPProxyWsdlLoader.newLoader(config);
+		}
+		catch (ConfigurationException ce)
+		{
+			throw (IOException)(new IOException(ce.getMessage()).initCause(ce));
+		}
+		try
+		{
+			return wsdl_loader.load(true);
+		}
+		finally
+		{
+			wsdl_loader.cleanup();
+		}
+	}
+	
+	public void setContractProperties(Properties contractProperties)
+	{
+		setActionProperties(contractProperties);
+	}
+	
+	public ContractInfo provideContract(Service service) throws IOException
+	{
+		return provideContract(service, null);
+	}
+	
+	public ContractInfo provideContract(Service service, String endpointAddressOverride) throws IOException
+	{
+		ContractInfo contract;
+		if (endpointAddressOverride != null)
+		{
+			try
+			{
+				initializeTransformer();
+			}
+			catch (ConfigurationException ce)
+			{
+				throw new IOException( ce.getMessage() );
+			}
+			contract = getContractInfo( new EPR(URI.create(endpointAddressOverride)) );
+		}
+		else
+		{
+			// !!! *HAS* TO BE THE *SUPER* CLASS' IMPLEMENTATION !!!
+			// --> AbstractWsdlContractPublisher.getContractInfo(String) <--
+			contract = super.getContractInfo( service, getWsdlAddress() );
+		}
+		return contract; 
+	}
+
+	public void setConfiguration(final ConfigTree config) throws ConfigurationException {
+	    if (actionConfig == null) {
+	        actionConfig = config;
+	    }
+	}
+	
+}

Deleted: labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/proxy/SOAPProxyWsdlLoader.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_7_CP/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/proxy/SOAPProxyWsdlLoader.java	2010-08-13 08:26:20 UTC (rev 34695)
+++ labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/proxy/SOAPProxyWsdlLoader.java	2010-08-19 17:44:42 UTC (rev 34800)
@@ -1,520 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2006, JBoss Inc., and others contributors as indicated 
- * by the @authors tag. All rights reserved. 
- * See the copyright.txt in the distribution for a
- * full listing of individual contributors. 
- * This copyrighted material is made available to anyone wishing to use,
- * modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU Lesser General Public License, v. 2.1.
- * This program is distributed in the hope that it will be useful, but WITHOUT A 
- * 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,
- * v.2.1 along with this distribution; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
- * MA  02110-1301, USA.
- * 
- * (C) 2005-2009
- */
-package org.jboss.soa.esb.actions.soap.proxy;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.BufferedReader;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.Reader;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Map.Entry;
-
-import javax.management.JMException;
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-
-import org.jboss.internal.soa.esb.publish.ContractInfo;
-import org.jboss.internal.soa.esb.util.StreamUtils;
-import org.jboss.mx.util.MBeanServerLocator;
-import org.jboss.soa.esb.ConfigurationException;
-import org.jboss.soa.esb.actions.soap.AuthBASICWsdlContractPublisher;
-import org.jboss.soa.esb.helpers.ConfigTree;
-import org.jboss.soa.esb.listeners.ListenerTagNames;
-import org.jboss.util.xml.DOMUtils;
-import org.jboss.util.xml.DOMWriter;
-import org.jboss.ws.metadata.umdm.ServerEndpointMetaData;
-import org.jboss.wsf.spi.SPIProvider;
-import org.jboss.wsf.spi.SPIProviderResolver;
-import org.jboss.wsf.spi.deployment.Endpoint;
-import org.jboss.wsf.spi.management.EndpointRegistry;
-import org.jboss.wsf.spi.management.EndpointRegistryFactory;
-import org.w3c.dom.Attr;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-/**
- * SOAPProxy WSDL loader.
- * 
- * @author dward at jboss.org
- */
-public abstract class SOAPProxyWsdlLoader
-{
-	
-	private ConfigTree config;
-	private String address;
-	private boolean rewriteHost;
-	private String serviceCat;
-	private String serviceName;
-	private Puller puller = null;
-	private File tempDir = null;
-	
-	private ContractInfo contract;
-	private boolean rewriteLocation;
-	private File primary_file;
-	private List<File> cleanup_files = new ArrayList<File>();
-	
-	protected SOAPProxyWsdlLoader(ConfigTree config, String address, boolean rewriteHost)
-	{
-		this.config = config;
-		this.address = address;
-		this.rewriteHost = rewriteHost;
-		ConfigTree parent_config = config.getParent();
-		serviceCat = (parent_config != null ? parent_config.getAttribute(ListenerTagNames.SERVICE_CATEGORY_NAME_TAG) : null);
-		serviceName = (parent_config != null ? parent_config.getAttribute(ListenerTagNames.SERVICE_NAME_TAG) : null);
-	}
-	
-	public String getAddress()
-	{
-		return address;
-	}
-	
-	public synchronized Puller getPuller()
-	{
-		if (puller == null)
-		{
-			puller = new Puller(config);
-		}
-		return puller;
-	}
-	
-	private File getTempDir() throws IOException
-	{
-		if (tempDir == null)
-		{
-			synchronized (SOAPProxyWsdlLoader.class)
-			{
-				if (tempDir == null)
-				{
-					MBeanServer mbeanServer = MBeanServerLocator.locateJBoss();
-					try
-					{
-						tempDir = (File)mbeanServer.getAttribute(new ObjectName("jboss.system:type=ServerConfig"), "ServerTempDir");
-					}
-					catch (JMException ignored) {}
-					String tempName = SOAPProxyWsdlLoader.class.getSimpleName();
-					if ( tempDir == null || !tempDir.exists() )
-					{
-						File tempFile = File.createTempFile(tempName + "-", ".tmp");
-						tempDir = tempFile.getParentFile();
-						tempFile.delete();
-					}
-					tempDir = new File(tempDir, tempName);
-					tempDir.mkdirs();
-				}
-			}
-		}
-		return tempDir;
-	}
-	
-	public File createTempFile(String prefix, String suffix) throws IOException
-	{
-		File file = File.createTempFile( prefix + "-", suffix, getTempDir() );
-		cleanup_files.add(file);
-		return file;
-	}
-	
-	public ContractInfo load(boolean rewriteLocation) throws IOException
-	{
-		contract = new ContractInfo();
-		this.rewriteLocation = rewriteLocation;
-		String address = getAddress();
-		String protocol = URI.create(address).getScheme();
-		primary_file = createTempFile(protocol, ".wsdl");
-		getPuller().pull(address, primary_file);
-		Map<String,File> fileMap = new LinkedHashMap<String,File>();
-		fileMap.put(address, primary_file);
-		pullLocations(primary_file, address, protocol, fileMap);
-		for ( Entry<String,File> entry : fileMap.entrySet() )
-		{
-			editLocations(entry.getValue(), entry.getKey(), protocol, fileMap);
-		}
-		// populate the primary member variables (mimeType + data)
-		String mimeType = "text/xml";
-		String data = null;
-		InputStream is = null;
-		try
-		{
-			URL url = getURL();
-			if (url != null)
-			{
-				is = new BufferedInputStream( url.openStream() );
-				data = StreamUtils.readStreamString(is, "UTF-8");
-			}
-		}
-		finally
-		{
-			try { if (is != null) is.close(); } catch (Throwable t) {}
-		}
-		contract.setMimeType(mimeType);
-		contract.setData(data);
-		return contract;
-	}
-	
-	private void pullLocations(File file, String address, String protocol, Map<String,File> fileMap) throws IOException
-	{
-		InputStream is = null;
-		Element parentElement;
-		try
-		{
-			is = new BufferedInputStream( new FileInputStream(file) );
-			parentElement = DOMUtils.parse(is);
-		}
-		finally
-		{
-			try { if (is != null) is.close(); } catch (Throwable t) {}
-		}
-		pullLocations(parentElement, address, protocol, fileMap);
-	}
-	
-	private void pullLocations(Element parentElement, String address, String protocol, Map<String,File> fileMap) throws IOException
-	{
-		NodeList nlist = parentElement.getChildNodes();
-		for (int i = 0; i < nlist.getLength(); i++)
-		{
-			Node childNode = nlist.item(i);
-			if (childNode.getNodeType() == Node.ELEMENT_NODE)
-			{
-				Element childElement = (Element)childNode;
-				String nodeName = childElement.getLocalName();
-				if ( "import".equals(nodeName) || "include".equals(nodeName) )
-				{
-					Attr locationAttr = childElement.getAttributeNode("schemaLocation");
-					if (locationAttr == null)
-					{
-						locationAttr = childElement.getAttributeNode("location");
-					}
-					if (locationAttr != null)
-					{
-						String location = fixRelative( address, locationAttr.getNodeValue() );
-						if ( !fileMap.containsKey(location) )
-						{
-							File locationFile = createTempFile(protocol, ".tmp");
-							getPuller().pull(location, locationFile);
-							fileMap.put(location, locationFile);
-							pullLocations(locationFile, location, protocol, fileMap);
-						}
-					}
-				}
-				pullLocations(childElement, address, protocol, fileMap);
-			}
-		}
-	}
-	
-	private void editLocations(File file, String address, String protocol, Map<String,File> fileMap) throws IOException
-	{
-		InputStream is = null;
-		Element parentElement;
-		try
-		{
-			is = new BufferedInputStream( new FileInputStream(file) );
-			parentElement = DOMUtils.parse(is);
-		}
-		finally
-		{
-			try { if (is != null) is.close(); } catch (Throwable t) {}
-		}
-		if ( editLocations(parentElement, address, protocol, fileMap) )
-		{
-			OutputStream os1 = new BufferedOutputStream( new FileOutputStream(file) );
-			ByteArrayOutputStream os2 = new ByteArrayOutputStream();
-			for (OutputStream os : new OutputStream[]{os1, os2})
-			{
-				try
-				{
-					DOMWriter writer = new DOMWriter(os);
-					writer.setPrettyprint(true);
-					writer.print(parentElement);
-				}
-				finally
-				{
-					try { if (os != null) os.close(); } catch (Throwable t) {}
-				}
-			}
-			contract.putResource( file.getName(), os2.toString("UTF-8") );
-		}
-		else
-		{
-			contract.putResource( file.getName(), getPuller().pull(file) );
-		}
-	}
-	
-	private boolean editLocations(Element parentElement, String address, String protocol, Map<String,File> fileMap) throws IOException
-	{
-		boolean rewrite = false;
-		NodeList nlist = parentElement.getChildNodes();
-		for (int i = 0; i < nlist.getLength(); i++)
-		{
-			Node childNode = nlist.item(i);
-			if (childNode.getNodeType() == Node.ELEMENT_NODE)
-			{
-				Element childElement = (Element)childNode;
-				String nodeName = childElement.getLocalName();
-				if ( "import".equals(nodeName) || "include".equals(nodeName) )
-				{
-					Attr locationAttr = childElement.getAttributeNode("schemaLocation");
-					if (locationAttr == null)
-					{
-						locationAttr = childElement.getAttributeNode("location");
-					}
-					if (locationAttr != null)
-					{
-						String location = fixRelative( address, locationAttr.getNodeValue() );
-						File locationFile = fileMap.get(location);
-						String locationFileName = locationFile.getName();
-						if (rewriteLocation)
-						{
-							StringBuilder locationBuilder = new StringBuilder("@REQUEST_URL@?wsdl");
-							locationBuilder.append("&resource=").append(locationFileName);
-							if (serviceCat != null)
-							{
-								locationBuilder.append("&serviceCat=").append(serviceCat);
-							}
-							if (serviceName != null)
-							{
-								locationBuilder.append("&serviceName=").append(serviceName);
-							}
-							String contractProtocol = (!protocol.toLowerCase().equals("https") ? "http" : "https");
-							locationBuilder.append("&protocol=").append(contractProtocol);
-							locationAttr.setNodeValue( locationBuilder.toString() );
-						}
-						else
-						{
-							locationAttr.setNodeValue(locationFileName);		
-						}
-						rewrite = true;
-					}
-				}
-				if ( editLocations(childElement, address, protocol, fileMap) )
-				{
-					rewrite = true;
-				}
-			}
-		}
-		return rewrite;
-	}
-	
-	String fixRelative(String base_url, String location)
-	{
-		location = location.replaceAll("/./", "/");
-		if ( !location.startsWith("http://") && !location.startsWith("https://") )
-		{
-			while ( location.startsWith("./") )
-			{
-				location = location.substring( 2, location.length() );
-			}
-			if ( location.startsWith("/") )
-			{
-				if (rewriteHost)
-				{
-					String base_host = base_url.substring( 0, base_url.indexOf("/", base_url.indexOf("://")+3) );
-					location = base_host + location;
-				}
-			}
-			else
-			{
-				int count = 0;
-				while ( location.startsWith("../") )
-				{
-					location = location.substring( 3, location.length() );
-					count++;
-				}
-				String newLocation = base_url.substring( 0, base_url.lastIndexOf("/") );
-				for (int c = 0; c < count; c++)
-				{
-					newLocation = newLocation.substring( 0, newLocation.lastIndexOf("/") );
-				}
-				location = newLocation + "/" + location;
-			}
-		}
-		return location;
-	}
-	
-	public URL getURL() throws MalformedURLException
-	{
-		return primary_file.toURI().toURL();
-	}
-	
-	public void cleanup()
-	{
-		for (File file : cleanup_files)
-		{
-			file.delete();
-		}
-	}
-	
-	public static SOAPProxyWsdlLoader newLoader(ConfigTree config) throws ConfigurationException
-	{
-		SOAPProxyWsdlLoader loader;
-		String address = config.getRequiredAttribute("wsdl");
-		if ( address.startsWith("http://") || address.startsWith("https://") )
-		{
-			loader = new DefaultSOAPProxyWsdlLoader(config, address, true);
-		}
-		else if ( address.startsWith("file://") || address.startsWith("classpath://") )
-		{
-			loader = new DefaultSOAPProxyWsdlLoader(config, address, false);
-		}
-		else if ( address.startsWith("internal://") )
-		{
-			loader = new InternalSOAPProxyWsdlLoader(config, address);
-		}
-		else
-		{
-			throw new ConfigurationException("unrecognized wsdl address: " + address);
-		}
-		return loader;
-	}
-	
-	static class DefaultSOAPProxyWsdlLoader extends SOAPProxyWsdlLoader
-	{
-		
-		public DefaultSOAPProxyWsdlLoader(ConfigTree config, String address, boolean rewriteHost)
-		{
-			super(config, address, rewriteHost);
-		}
-		
-	}
-	
-	private static class InternalSOAPProxyWsdlLoader extends SOAPProxyWsdlLoader
-	{
-		
-		public InternalSOAPProxyWsdlLoader(ConfigTree config, String address)
-		{
-			super(config, address, true);
-		}
-		
-		@Override
-		public String getAddress()
-		{
-			String end_addr = super.getAddress();
-			String end_name = end_addr.substring( 11, end_addr.length() );
-			SPIProvider spi_prov = SPIProviderResolver.getInstance().getProvider();
-			EndpointRegistryFactory end_reg_fact = spi_prov.getSPI(EndpointRegistryFactory.class);
-			EndpointRegistry end_reg = end_reg_fact.getEndpointRegistry();
-			Endpoint end = null;
-			for ( ObjectName obj_name : end_reg.getEndpoints() )
-			{
-				//if ( end_name.equals(obj_name.getKeyProperty(Endpoint.SEPID_PROPERTY_ENDPOINT)) )
-				if ( obj_name.toString().equals(end_name) )
-				{
-					end = end_reg.getEndpoint(obj_name);
-					break;
-				}
-			}
-			if (end != null)
-			{
-				ServerEndpointMetaData end_meta = end.getAttachment(ServerEndpointMetaData.class);
-				if (end_meta == null)
-				{
-					throw new RuntimeException("cannot obtain metadata for internal endpoint: " + end_name);
-				}
-				return end_meta.getServiceMetaData().getWsdlLocation().toString();
-			}
-			else
-			{
-				throw new RuntimeException("unrecognized internal endpoint: " + end_name);
-			}
-		}
-		
-	}
-	
-	private static class Puller extends AuthBASICWsdlContractPublisher
-	{
-		
-		private ConfigTree config;
-		
-		public Puller(ConfigTree config)
-		{
-			this.config = config;
-		}
-		
-		@Override
-		public Properties getActionProperties()
-		{
-			Properties props = new Properties();
-			for ( String key : config.getAttributeNames() )
-			{
-				String value = config.getAttribute(key);
-				if (value != null)
-				{
-					props.setProperty(key, value);
-				}
-			}
-			return props;
-		}
-		
-		public void pull(String url, File file) throws IOException
-		{
-			BufferedInputStream bis = null;
-			BufferedOutputStream bos = null;
-			try
-			{
-				// re-using the HTTPClient and AuthBASIC stuff...
-				String data = getWsdl( url, config.getAttribute("wsdlCharset") );
-				bis = new BufferedInputStream( new ByteArrayInputStream(data.getBytes()) );
-				bos = new BufferedOutputStream( new FileOutputStream(file) );
-				byte[] buf = new byte[1024];
-				int read = 0;
-				while ( (read = bis.read(buf)) != -1 )
-				{
-					bos.write(buf, 0, read);
-				}
-				bos.flush();
-			}
-			finally
-			{	
-				try { if (bos != null) bos.close(); } catch (Throwable t) {}
-				try { if (bis != null) bis.close(); } catch (Throwable t) {}
-			}
-		}
-		
-		public String pull(File file) throws IOException
-		{
-			Reader reader = new BufferedReader( new FileReader(file) );
-			try
-			{
-				return StreamUtils.readReader(reader);
-			}
-			finally
-			{
-				reader.close();
-			}
-		}
-		
-	}
-
-}

Copied: labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/proxy/SOAPProxyWsdlLoader.java (from rev 34799, labs/jbossesb/branches/JBESB_4_7_CP/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/proxy/SOAPProxyWsdlLoader.java)
===================================================================
--- labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/proxy/SOAPProxyWsdlLoader.java	                        (rev 0)
+++ labs/jbossesb/tags/JBESB_4_7_CP2_SOA_2210_3/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/proxy/SOAPProxyWsdlLoader.java	2010-08-19 17:44:42 UTC (rev 34800)
@@ -0,0 +1,574 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, JBoss Inc., and others contributors as indicated 
+ * by the @authors tag. All rights reserved. 
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors. 
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A 
+ * 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,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+ * MA  02110-1301, USA.
+ * 
+ * (C) 2005-2009
+ */
+package org.jboss.soa.esb.actions.soap.proxy;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import javax.management.JMException;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
+import org.jboss.internal.soa.esb.publish.ContractInfo;
+import org.jboss.internal.soa.esb.util.StreamUtils;
+import org.jboss.mx.util.MBeanServerLocator;
+import org.jboss.soa.esb.ConfigurationException;
+import org.jboss.soa.esb.actions.soap.AuthBASICWsdlContractPublisher;
+import org.jboss.soa.esb.helpers.ConfigTree;
+import org.jboss.soa.esb.http.HttpClientFactory;
+import org.jboss.soa.esb.http.configurators.Connection;
+import org.jboss.soa.esb.listeners.ListenerTagNames;
+import org.jboss.util.xml.DOMUtils;
+import org.jboss.util.xml.DOMWriter;
+import org.jboss.ws.metadata.umdm.ServerEndpointMetaData;
+import org.jboss.wsf.spi.SPIProvider;
+import org.jboss.wsf.spi.SPIProviderResolver;
+import org.jboss.wsf.spi.deployment.Endpoint;
+import org.jboss.wsf.spi.management.EndpointRegistry;
+import org.jboss.wsf.spi.management.EndpointRegistryFactory;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * SOAPProxy WSDL loader.
+ * 
+ * @author dward at jboss.org
+ */
+public abstract class SOAPProxyWsdlLoader
+{
+	
+	private ConfigTree config;
+	private String address;
+	private boolean rewriteHost;
+	private String serviceCat;
+	private String serviceName;
+	private Puller puller = null;
+	private File tempDir = null;
+	
+	private ContractInfo contract;
+	private boolean rewriteLocation;
+	private File primary_file;
+	private List<File> cleanup_files = new ArrayList<File>();
+	
+	protected SOAPProxyWsdlLoader(ConfigTree config, String address, boolean rewriteHost)
+	{
+		this.config = config;
+		this.address = address;
+		this.rewriteHost = rewriteHost;
+		ConfigTree parent_config = config.getParent();
+		serviceCat = (parent_config != null ? parent_config.getAttribute(ListenerTagNames.SERVICE_CATEGORY_NAME_TAG) : null);
+		serviceName = (parent_config != null ? parent_config.getAttribute(ListenerTagNames.SERVICE_NAME_TAG) : null);
+	}
+	
+	public String getAddress()
+	{
+		return address;
+	}
+	
+	public synchronized Puller getPuller()
+	{
+		if (puller == null)
+		{
+			puller = new Puller(config);
+		}
+		return puller;
+	}
+	
+	private File getTempDir() throws IOException
+	{
+		if (tempDir == null)
+		{
+			synchronized (SOAPProxyWsdlLoader.class)
+			{
+				if (tempDir == null)
+				{
+					MBeanServer mbeanServer = MBeanServerLocator.locateJBoss();
+					try
+					{
+						tempDir = (File)mbeanServer.getAttribute(new ObjectName("jboss.system:type=ServerConfig"), "ServerTempDir");
+					}
+					catch (JMException ignored) {}
+					String tempName = SOAPProxyWsdlLoader.class.getSimpleName();
+					if ( tempDir == null || !tempDir.exists() )
+					{
+						File tempFile = File.createTempFile(tempName + "-", ".tmp");
+						tempDir = tempFile.getParentFile();
+						tempFile.delete();
+					}
+					tempDir = new File(tempDir, tempName);
+					tempDir.mkdirs();
+				}
+			}
+		}
+		return tempDir;
+	}
+	
+	public File createTempFile(String prefix, String suffix) throws IOException
+	{
+		File file = File.createTempFile( prefix + "-", suffix, getTempDir() );
+		cleanup_files.add(file);
+		return file;
+	}
+	
+	public ContractInfo load(boolean rewriteLocation) throws IOException
+	{
+		contract = new ContractInfo();
+		this.rewriteLocation = rewriteLocation;
+		String address = getAddress();
+		String protocol = URI.create(address).getScheme();
+		primary_file = createTempFile(protocol, ".wsdl");
+		getPuller().pull(address, primary_file);
+		Map<String,File> fileMap = new LinkedHashMap<String,File>();
+		fileMap.put(address, primary_file);
+		pullLocations(primary_file, address, protocol, fileMap);
+		for ( Entry<String,File> entry : fileMap.entrySet() )
+		{
+			editLocations(entry.getValue(), entry.getKey(), protocol, fileMap);
+		}
+		// populate the primary member variables (mimeType + data)
+		String mimeType = "text/xml";
+		String data = null;
+		InputStream is = null;
+		try
+		{
+			URL url = getURL();
+			if (url != null)
+			{
+				is = new BufferedInputStream( url.openStream() );
+				data = StreamUtils.readStreamString(is, "UTF-8");
+			}
+		}
+		finally
+		{
+			try { if (is != null) is.close(); } catch (Throwable t) {}
+		}
+		contract.setMimeType(mimeType);
+		contract.setData(data);
+		return contract;
+	}
+	
+	private void pullLocations(File file, String address, String protocol, Map<String,File> fileMap) throws IOException
+	{
+		InputStream is = null;
+		Element parentElement;
+		try
+		{
+			is = new BufferedInputStream( new FileInputStream(file) );
+			parentElement = DOMUtils.parse(is);
+		}
+		finally
+		{
+			try { if (is != null) is.close(); } catch (Throwable t) {}
+		}
+		pullLocations(parentElement, address, protocol, fileMap);
+	}
+	
+	private void pullLocations(Element parentElement, String address, String protocol, Map<String,File> fileMap) throws IOException
+	{
+		NodeList nlist = parentElement.getChildNodes();
+		for (int i = 0; i < nlist.getLength(); i++)
+		{
+			Node childNode = nlist.item(i);
+			if (childNode.getNodeType() == Node.ELEMENT_NODE)
+			{
+				Element childElement = (Element)childNode;
+				String nodeName = childElement.getLocalName();
+				if ( "import".equals(nodeName) || "include".equals(nodeName) )
+				{
+					Attr locationAttr = childElement.getAttributeNode("schemaLocation");
+					if (locationAttr == null)
+					{
+						locationAttr = childElement.getAttributeNode("location");
+					}
+					if (locationAttr != null)
+					{
+						String location = fixRelative( address, locationAttr.getNodeValue() );
+						if ( !fileMap.containsKey(location) )
+						{
+							File locationFile = createTempFile(protocol, ".tmp");
+							getPuller().pull(location, locationFile);
+							fileMap.put(location, locationFile);
+							pullLocations(locationFile, location, protocol, fileMap);
+						}
+					}
+				}
+				pullLocations(childElement, address, protocol, fileMap);
+			}
+		}
+	}
+	
+	private void editLocations(File file, String address, String protocol, Map<String,File> fileMap) throws IOException
+	{
+		InputStream is = null;
+		Element parentElement;
+		try
+		{
+			is = new BufferedInputStream( new FileInputStream(file) );
+			parentElement = DOMUtils.parse(is);
+		}
+		finally
+		{
+			try { if (is != null) is.close(); } catch (Throwable t) {}
+		}
+		if ( editLocations(parentElement, address, protocol, fileMap) )
+		{
+			OutputStream os1 = new BufferedOutputStream( new FileOutputStream(file) );
+			ByteArrayOutputStream os2 = new ByteArrayOutputStream();
+			for (OutputStream os : new OutputStream[]{os1, os2})
+			{
+				try
+				{
+					DOMWriter writer = new DOMWriter(os);
+					writer.setPrettyprint(true);
+					writer.print(parentElement);
+				}
+				finally
+				{
+					try { if (os != null) os.close(); } catch (Throwable t) {}
+				}
+			}
+			contract.putResource( file.getName(), os2.toString("UTF-8") );
+		}
+		else
+		{
+			contract.putResource( file.getName(), getPuller().pull(file) );
+		}
+	}
+	
+	private boolean editLocations(Element parentElement, String address, String protocol, Map<String,File> fileMap) throws IOException
+	{
+		boolean rewrite = false;
+		NodeList nlist = parentElement.getChildNodes();
+		for (int i = 0; i < nlist.getLength(); i++)
+		{
+			Node childNode = nlist.item(i);
+			if (childNode.getNodeType() == Node.ELEMENT_NODE)
+			{
+				Element childElement = (Element)childNode;
+				String nodeName = childElement.getLocalName();
+				if ( "import".equals(nodeName) || "include".equals(nodeName) )
+				{
+					Attr locationAttr = childElement.getAttributeNode("schemaLocation");
+					if (locationAttr == null)
+					{
+						locationAttr = childElement.getAttributeNode("location");
+					}
+					if (locationAttr != null)
+					{
+						String location = fixRelative( address, locationAttr.getNodeValue() );
+						File locationFile = fileMap.get(location);
+						String locationFileName = locationFile.getName();
+						if (rewriteLocation)
+						{
+							StringBuilder locationBuilder = new StringBuilder("@REQUEST_URL@?wsdl");
+							locationBuilder.append("&resource=").append(locationFileName);
+							if (serviceCat != null)
+							{
+								locationBuilder.append("&serviceCat=").append(serviceCat);
+							}
+							if (serviceName != null)
+							{
+								locationBuilder.append("&serviceName=").append(serviceName);
+							}
+							String contractProtocol = (!protocol.toLowerCase().equals("https") ? "http" : "https");
+							locationBuilder.append("&protocol=").append(contractProtocol);
+							locationAttr.setNodeValue( locationBuilder.toString() );
+						}
+						else
+						{
+							locationAttr.setNodeValue(locationFileName);		
+						}
+						rewrite = true;
+					}
+				}
+				if ( editLocations(childElement, address, protocol, fileMap) )
+				{
+					rewrite = true;
+				}
+			}
+		}
+		return rewrite;
+	}
+	
+	String fixRelative(String base_url, String location)
+	{
+		location = location.replaceAll("/./", "/");
+		if ( !location.startsWith("http://") && !location.startsWith("https://") )
+		{
+			while ( location.startsWith("./") )
+			{
+				location = location.substring( 2, location.length() );
+			}
+			if ( location.startsWith("/") )
+			{
+				if (rewriteHost)
+				{
+					String base_host = base_url.substring( 0, base_url.indexOf("/", base_url.indexOf("://")+3) );
+					location = base_host + location;
+				}
+			}
+			else
+			{
+				int count = 0;
+				while ( location.startsWith("../") )
+				{
+					location = location.substring( 3, location.length() );
+					count++;
+				}
+				String newLocation = base_url.substring( 0, base_url.lastIndexOf("/") );
+				for (int c = 0; c < count; c++)
+				{
+					newLocation = newLocation.substring( 0, newLocation.lastIndexOf("/") );
+				}
+				location = newLocation + "/" + location;
+			}
+		}
+		return location;
+	}
+	
+	public URL getURL() throws MalformedURLException
+	{
+		return primary_file.toURI().toURL();
+	}
+	
+	public void cleanup()
+	{
+		for (File file : cleanup_files)
+		{
+			file.delete();
+		}
+	}
+	
+	public static SOAPProxyWsdlLoader newLoader(ConfigTree config) throws ConfigurationException
+	{
+		SOAPProxyWsdlLoader loader;
+		String address = config.getRequiredAttribute("wsdl");
+		if ( address.startsWith("http://") || address.startsWith("https://") )
+		{
+			final ConfigTree httpClientProps = extractHttpClientConfig(config, address) ;
+			loader = new DefaultSOAPProxyWsdlLoader(httpClientProps, address, true);
+		}
+		else if ( address.startsWith("file://") || address.startsWith("classpath://") )
+		{
+			loader = new DefaultSOAPProxyWsdlLoader(config, address, false);
+		}
+		else if ( address.startsWith("internal://") )
+		{
+			loader = new InternalSOAPProxyWsdlLoader(config, address);
+		}
+		else
+		{
+			throw new ConfigurationException("unrecognized wsdl address: " + address);
+		}
+		return loader;
+	}
+	
+	private static ConfigTree extractHttpClientConfig(final ConfigTree config, final String address)
+	{
+		final ConfigTree newParent = new ConfigTree("http-client-parent");
+		final ConfigTree newConfig = new ConfigTree("http-client-config", newParent);
+		
+		if (config.getBooleanAttribute("wsdlUseHttpClientProperties", false)) {
+			extractHttpClientAttributes(newConfig, config.getChildren("http-client-property"));
+		}
+		final ConfigTree[] wsdlHttpClientConfigTrees = config.getChildren("wsdl-http-client-property");
+		if (wsdlHttpClientConfigTrees.length > 0) {
+			extractHttpClientAttributes(newConfig, wsdlHttpClientConfigTrees);
+		}
+		
+		final Set<String> attributeNames = config.getAttributeNames();
+		for(String name: attributeNames) {
+			final String value = config.getAttribute(name);
+			if (value != null) {
+				newConfig.setAttribute(name, value);
+			}
+		}
+		newConfig.setAttribute(HttpClientFactory.TARGET_HOST_URL, address);
+		newConfig.setAttribute(Connection.MAX_TOTAL_CONNECTIONS, "1");
+		newConfig.setAttribute(Connection.MAX_CONNECTIONS_PER_HOST, "1");
+		
+		final ConfigTree parent = config.getParent();
+		if (parent != null) {
+			final String serviceCat = parent.getAttribute(ListenerTagNames.SERVICE_CATEGORY_NAME_TAG);
+			if (serviceCat != null) {
+				newParent.setAttribute(ListenerTagNames.SERVICE_CATEGORY_NAME_TAG, serviceCat) ;
+			}
+			final String serviceName = parent.getAttribute(ListenerTagNames.SERVICE_NAME_TAG);
+			if (serviceName != null) {
+				newParent.setAttribute(ListenerTagNames.SERVICE_NAME_TAG, serviceName) ;
+			}
+		}
+		
+		return newConfig;
+	}
+	
+	private static void extractHttpClientAttributes(final ConfigTree configTree, final ConfigTree[] httpClientChildren)
+	{
+		for(ConfigTree httpClientChild : httpClientChildren) {
+			final String name = httpClientChild.getAttribute("name");
+			final String value = httpClientChild.getAttribute("value");
+			if ((name != null) && (value != null)) {
+				configTree.setAttribute(name, value);
+			}
+		}
+	}
+	
+	static class DefaultSOAPProxyWsdlLoader extends SOAPProxyWsdlLoader
+	{
+		
+		public DefaultSOAPProxyWsdlLoader(ConfigTree config, String address, boolean rewriteHost)
+		{
+			super(config, address, rewriteHost);
+		}
+		
+	}
+	
+	private static class InternalSOAPProxyWsdlLoader extends SOAPProxyWsdlLoader
+	{
+		
+		public InternalSOAPProxyWsdlLoader(ConfigTree config, String address)
+		{
+			super(config, address, true);
+		}
+		
+		@Override
+		public String getAddress()
+		{
+			String end_addr = super.getAddress();
+			String end_name = end_addr.substring( 11, end_addr.length() );
+			SPIProvider spi_prov = SPIProviderResolver.getInstance().getProvider();
+			EndpointRegistryFactory end_reg_fact = spi_prov.getSPI(EndpointRegistryFactory.class);
+			EndpointRegistry end_reg = end_reg_fact.getEndpointRegistry();
+			Endpoint end = null;
+			for ( ObjectName obj_name : end_reg.getEndpoints() )
+			{
+				//if ( end_name.equals(obj_name.getKeyProperty(Endpoint.SEPID_PROPERTY_ENDPOINT)) )
+				if ( obj_name.toString().equals(end_name) )
+				{
+					end = end_reg.getEndpoint(obj_name);
+					break;
+				}
+			}
+			if (end != null)
+			{
+				ServerEndpointMetaData end_meta = end.getAttachment(ServerEndpointMetaData.class);
+				if (end_meta == null)
+				{
+					throw new RuntimeException("cannot obtain metadata for internal endpoint: " + end_name);
+				}
+				return end_meta.getServiceMetaData().getWsdlLocation().toString();
+			}
+			else
+			{
+				throw new RuntimeException("unrecognized internal endpoint: " + end_name);
+			}
+		}
+		
+	}
+	
+	private static class Puller extends AuthBASICWsdlContractPublisher
+	{
+		
+		private ConfigTree config;
+		
+		public Puller(ConfigTree config)
+		{
+			this.config = config;
+		}
+		
+		@Override
+		public Properties getActionProperties()
+		{
+			Properties props = new Properties();
+			for ( String key : config.getAttributeNames() )
+			{
+				String value = config.getAttribute(key);
+				if (value != null)
+				{
+					props.setProperty(key, value);
+				}
+			}
+			return props;
+		}
+		
+		public void pull(String url, File file) throws IOException
+		{
+			BufferedInputStream bis = null;
+			BufferedOutputStream bos = null;
+			try
+			{
+				// re-using the HTTPClient and AuthBASIC stuff...
+				String data = getWsdl( url, config.getAttribute("wsdlCharset") );
+				bis = new BufferedInputStream( new ByteArrayInputStream(data.getBytes()) );
+				bos = new BufferedOutputStream( new FileOutputStream(file) );
+				byte[] buf = new byte[1024];
+				int read = 0;
+				while ( (read = bis.read(buf)) != -1 )
+				{
+					bos.write(buf, 0, read);
+				}
+				bos.flush();
+			}
+			finally
+			{	
+				try { if (bos != null) bos.close(); } catch (Throwable t) {}
+				try { if (bis != null) bis.close(); } catch (Throwable t) {}
+			}
+		}
+		
+		public String pull(File file) throws IOException
+		{
+			Reader reader = new BufferedReader( new FileReader(file) );
+			try
+			{
+				return StreamUtils.readReader(reader);
+			}
+			finally
+			{
+				reader.close();
+			}
+		}
+		
+	}
+
+}



More information about the jboss-svn-commits mailing list