package org.jboss.webservice.util;
import org.jboss.logging.Logger;
import org.jboss.webservice.metadata.jaxrpcmapping.JavaWsdlMapping;
import org.jboss.webservice.metadata.jaxrpcmapping.ServiceEndpointInterfaceMapping;
import org.jboss.webservice.metadata.jaxrpcmapping.ServiceEndpointMethodMapping;
import javax.wsdl.Definition;
import javax.wsdl.Import;
import javax.wsdl.Operation;
import javax.wsdl.Port;
import javax.wsdl.PortType;
import javax.wsdl.Service;
import javax.wsdl.extensions.soap.SOAPAddress;
import javax.xml.rpc.ServiceException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public final class WSDLUtilities
{
private static final Logger log = Logger.getLogger(WSDLUtilities.class);
public static final String WSDL_NAMESPACE_URI = "http://schemas.xmlsoap.org/wsdl/".intern();
public static final String XSD_NAMESPACE_URI = "http://www.w3.org/2001/XMLSchema".intern();
private WSDLUtilities()
{
}
public static void endorseServiceEndpointInterface(Definition wsdlDefinition, Class seiClass, JavaWsdlMapping jaxrpcMapping)
throws ServiceException
{
if (wsdlDefinition == null)
throw new IllegalArgumentException("WSDL definition cannot be null");
if (seiClass == null)
throw new IllegalArgumentException("Service endpoint interface cannot be null");
if (jaxrpcMapping == null)
throw new IllegalArgumentException("JavaWsdlMapping cannot be null");
if (java.rmi.Remote.class.isAssignableFrom(seiClass) == false)
throw new IllegalArgumentException("The service endpoint interface does not implement java.rmi.Remote: " + seiClass.getName());
List seiMethodNames = new ArrayList();
Method[] seiMethods = seiClass.getDeclaredMethods();
for (int i = 0; i < seiMethods.length; i++)
{
Method method = seiMethods[i];
seiMethodNames.add(method.getName());
}
Map semMap = new HashMap();
ServiceEndpointInterfaceMapping[] seiMappings = jaxrpcMapping.getServiceEndpointInterfaceMappings();
for (int i = 0; i < seiMappings.length; i++)
{
ServiceEndpointInterfaceMapping seiMapping = seiMappings[i];
if (seiClass.getName().equals(seiMapping.getServiceEndpointInterface()))
{
ServiceEndpointMethodMapping[] semMappings = seiMapping.getServiceEndpointMethodMappings();
for (int j = 0; j < semMappings.length; j++)
{
ServiceEndpointMethodMapping semMapping = semMappings[j];
semMap.put(semMapping.getWsdlOperation(), semMapping.getJavaMethodName());
}
}
}
Map portTypeOperationsMap = new HashMap();
Iterator itPortType = getPortTypesWithImport(wsdlDefinition).iterator();
while (itPortType.hasNext())
{
List ptMethods = new ArrayList();
PortType portType = (PortType)itPortType.next();
Iterator itop = portType.getOperations().iterator();
while (itop.hasNext())
{
String wsdlOp = ((Operation)itop.next()).getName();
String javaOp = (String)semMap.get(wsdlOp);
ptMethods.add(javaOp != null ? javaOp : wsdlOp);
}
portTypeOperationsMap.put(portType.getQName(), ptMethods);
}
boolean portTypeFound = false;
Iterator it = portTypeOperationsMap.values().iterator();
while (it.hasNext())
{
boolean seiOpInPortType = true;
List opList = (List)it.next();
for (int i = 0; i < seiMethods.length; i++)
{
Method seiMethod = seiMethods[i];
seiOpInPortType &= opList.contains(seiMethod.getName());
}
if (seiOpInPortType == true)
{
portTypeFound = true;
break;
}
}
if (portTypeFound == false)
throw new ServiceException("Cannot find SEI operations " + seiMethodNames + " in any wsdl port type, we have " + portTypeOperationsMap);
}
private static List getPortTypesWithImport(Definition wsdl)
{
ArrayList pTypes = new ArrayList(wsdl.getPortTypes().values());
Iterator it = wsdl.getImports().values().iterator();
while (it.hasNext())
{
List imports = (List)it.next();
for (int i = 0; i < imports.size(); i++)
{
Import imp = (Import)imports.get(i);
Definition subdef = imp.getDefinition();
pTypes.addAll(subdef.getPortTypes().values());
pTypes.addAll(getPortTypesWithImport(subdef));
}
}
return pTypes;
}
public static String[] getServiceLocations(Definition wsdlDefinition)
{
ArrayList locations = new ArrayList();
Service wsdlService = (Service)wsdlDefinition.getServices().values().iterator().next();
Map wsdlPorts = wsdlService.getPorts();
Iterator it = wsdlPorts.values().iterator();
while (it.hasNext())
{
Port wsdlPort = (Port)it.next();
Iterator itElements = wsdlPort.getExtensibilityElements().iterator();
while (itElements.hasNext())
{
Object obj = itElements.next();
if (obj instanceof SOAPAddress)
{
SOAPAddress address = (SOAPAddress)obj;
String wsdlURI = address.getLocationURI();
locations.add(wsdlURI);
}
}
}
String[] arr = new String[locations.size()];
locations.toArray(arr);
return arr;
}
}