Package org.jboss.soa.esb.actions.soap.proxy

Source Code of org.jboss.soa.esb.actions.soap.proxy.SOAPProxyWsdlLoader

/*
* 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.actions.soap.WebServiceUtils;
import org.jboss.soa.esb.actions.soap.adapter.JBossWSFactory;
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.wsf.spi.deployment.Endpoint;
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
* @author <a href="mailto:mageshbk@jboss.com">Magesh Kumar B</a>
*/
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(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() );
      Endpoint end = WebServiceUtils.getDeploymentEndpoint(end_name);
      if (end != null)
      {
        final String wsdlLocation = JBossWSFactory.getFactory().getWsdlLocation(end, end_name);
        if (wsdlLocation != null)
        {
          return wsdlLocation ;
        }
      }
      throw new IllegalStateException("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();
      }
    }
   
  }

}
TOP

Related Classes of org.jboss.soa.esb.actions.soap.proxy.SOAPProxyWsdlLoader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.