package org.jboss.webservice.metadata;
import org.jboss.logging.Logger;
import org.jboss.webservice.ServiceDeployer;
import org.jboss.webservice.WSDLDefinitionFactory;
import org.jboss.webservice.metadata.jaxrpcmapping.JavaWsdlMapping;
import org.jboss.webservice.metadata.jaxrpcmapping.JavaWsdlMappingFactory;
import javax.wsdl.Definition;
import javax.wsdl.Port;
import javax.wsdl.Service;
import javax.wsdl.WSDLException;
import javax.wsdl.extensions.soap.SOAPAddress;
import javax.xml.rpc.JAXRPCException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
public class WebserviceDescriptionMetaData
{
private static final Logger log = Logger.getLogger(WebserviceDescriptionMetaData.class);
private WebservicesMetaData webservices;
private String webserviceDescriptionName;
private String wsdlFile;
private String jaxrpcMappingFile;
private ArrayList portComponents = new ArrayList();
private String wsdlPublishLocation;
public WebserviceDescriptionMetaData(WebservicesMetaData webservices)
{
this.webservices = webservices;
}
public WebservicesMetaData getWebservices()
{
return webservices;
}
public void addPortComponent(PortComponentMetaData portComponent)
{
portComponents.add(portComponent);
}
public PortComponentMetaData[] getPortComponents()
{
PortComponentMetaData[] array = new PortComponentMetaData[portComponents.size()];
portComponents.toArray(array);
return array;
}
public PortComponentMetaData getPortComponentByWsdlPort(String name)
{
ArrayList pcNames = new ArrayList();
Iterator it = portComponents.iterator();
while (it.hasNext())
{
PortComponentMetaData pc = (PortComponentMetaData)it.next();
String wsdlPortName = pc.getWsdlPort().getLocalPart();
if (wsdlPortName.equals(name))
{
return pc;
}
pcNames.add(wsdlPortName);
}
log.error("Cannot get port component name '" + name + "', we have: " + pcNames);
return null;
}
public PortComponentMetaData getPortComponentByName(String name)
{
ArrayList pcNames = new ArrayList();
Iterator it = portComponents.iterator();
while (it.hasNext())
{
PortComponentMetaData pc = (PortComponentMetaData)it.next();
String portName = pc.getPortComponentName();
if (portName.equals(name))
{
return pc;
}
pcNames.add(portName);
}
log.error("Cannot get port component name '" + name + "', we have: " + pcNames);
return null;
}
public String getWebserviceDescriptionName()
{
return webserviceDescriptionName;
}
public void setWebserviceDescriptionName(String webserviceDescriptionName)
{
this.webserviceDescriptionName = webserviceDescriptionName;
}
public String getWsdlFile()
{
return wsdlFile;
}
public void setWsdlFile(String wsdlFile)
{
this.wsdlFile = wsdlFile;
}
public String getWsdlPublishLocation()
{
return wsdlPublishLocation;
}
public void setWsdlPublishLocation(String wsdlPublishLocation)
{
this.wsdlPublishLocation = wsdlPublishLocation;
}
public String getJaxrpcMappingFile()
{
return jaxrpcMappingFile;
}
public JavaWsdlMapping getJavaWsdlMapping()
{
JavaWsdlMapping javaWsdlMapping = (JavaWsdlMapping)webservices.jaxrpcMappingFileMap.get(jaxrpcMappingFile);
if (javaWsdlMapping == null)
{
try
{
URL location = webservices.getResourceLoader().findResource(jaxrpcMappingFile);
JavaWsdlMappingFactory mappingFactory = JavaWsdlMappingFactory.newInstance();
javaWsdlMapping = mappingFactory.parse(location);
webservices.jaxrpcMappingFileMap.put(jaxrpcMappingFile, javaWsdlMapping);
}
catch (Exception e)
{
throw new JAXRPCException("Cannot unmarshal jaxrpc-mapping-file: " + jaxrpcMappingFile, e);
}
}
return javaWsdlMapping;
}
public void setJaxrpcMappingFile(String jaxrpcMappingFile)
{
this.jaxrpcMappingFile = jaxrpcMappingFile;
}
public Definition getWsdlDefinition()
{
WSDLMapEntry wsdlEntry = (WSDLMapEntry)webservices.wsdlFileMap.get(wsdlFile);
if (wsdlEntry == null)
{
try
{
URL wsdlLocation = webservices.getResourceLoader().findResource(wsdlFile);
if (wsdlLocation == null)
throw new IllegalArgumentException("Cannot find wsdl in deployment: " + wsdlFile);
WSDLDefinitionFactory factory = WSDLDefinitionFactory.newInstance();
Definition wsdlDefinition = factory.parse(wsdlLocation);
wsdlEntry = new WSDLMapEntry(wsdlDefinition);
webservices.wsdlFileMap.put(wsdlFile, wsdlEntry);
}
catch (WSDLException e)
{
throw new IllegalStateException("Cannot obtain WSDL definition, cause: " + e.toString());
}
}
return wsdlEntry.wsdlDefinition;
}
public static boolean isValidServiceUrl(String url)
{
URI uri;
try
{
uri = new URI(url);
}
catch (URISyntaxException e)
{
return false;
}
String scheme = uri.getScheme();
if (! "http".equals(scheme) && ! "https".equals(scheme))
return false;
if (uri.getHost() == null)
return false;
return true;
}
public void updateServiceAddress(ServiceDeployer.ServiceLocationResolver locationResolver)
{
Definition wsdlDefinition = getWsdlDefinition();
WSDLMapEntry wsdlEntry = (WSDLMapEntry)webservices.wsdlFileMap.get(wsdlFile);
if (wsdlEntry.locationReplaced == false)
{
replaceAddressLocations(wsdlDefinition, locationResolver);
wsdlEntry.locationReplaced = true;
}
}
private void replaceAddressLocations(Definition wsdlDefinition, ServiceDeployer.ServiceLocationResolver locationResolver)
{
WebserviceDescriptionMetaData[] wsdArr = webservices.getWebserviceDescriptions();
for (int i = 0; i < wsdArr.length; i++)
{
WebserviceDescriptionMetaData wsdMetaData = wsdArr[i];
if (wsdlFile.equals(wsdMetaData.wsdlFile))
{
PortComponentMetaData[] pcarr = wsdMetaData.getPortComponents();
for (int pcIndex = 0; pcIndex < pcarr.length; pcIndex++)
{
PortComponentMetaData portComponent = pcarr[pcIndex];
String pcWsdlPortName = portComponent.getWsdlPort().getLocalPart();
Port wsdlPort = null;
Iterator itServices = wsdlDefinition.getServices().values().iterator();
while (wsdlPort == null && itServices.hasNext())
{
Service wsdlService = (Service)itServices.next();
Map wsdlPorts = wsdlService.getPorts();
Iterator itPorts = wsdlPorts.keySet().iterator();
while (wsdlPort == null && itPorts.hasNext())
{
String wsdlPortName = (String)itPorts.next();
if (wsdlPortName.equals(pcWsdlPortName))
{
wsdlPort = (Port)wsdlPorts.get(wsdlPortName);
Iterator itElements = wsdlPort.getExtensibilityElements().iterator();
while (itElements.hasNext())
{
Object obj = itElements.next();
if (obj instanceof SOAPAddress)
{
SOAPAddress address = (SOAPAddress)obj;
String wsdlURI = address.getLocationURI();
String addressUrl = null;
String schema = null;
if (wsdlURI.startsWith("http://") || wsdlURI.startsWith("https://"))
schema = wsdlURI.substring(0, wsdlURI.indexOf("://") + 3);
String endpointUrl = locationResolver.getServiceLocation(schema, portComponent);
if (isValidServiceUrl(wsdlURI) && ! locationResolver.alwaysResolve())
addressUrl = wsdlURI;
else
addressUrl = endpointUrl;
try
{
portComponent.setServiceEndpointURL(new URL(endpointUrl));
log.debug("Replace port location '" + wsdlURI + "' with '" + addressUrl + "'");
address.setLocationURI(addressUrl);
}
catch (MalformedURLException e)
{
log.error("Invalid service URL: " + endpointUrl);
}
}
}
}
}
}
if (wsdlPort == null)
throw new IllegalArgumentException("Cannot find port with name '" + pcWsdlPortName + "' in wsdl document");
}
}
}
}
class WSDLMapEntry
{
Definition wsdlDefinition;
boolean locationReplaced;
public WSDLMapEntry(Definition wsdlDefinition)
{
this.wsdlDefinition = wsdlDefinition;
}
}
}