/*
* JBoss, Home of Professional Open Source
* Copyright 2005, 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.ws.metadata.wsdl;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import java.util.StringTokenizer;
import javax.ejb.SessionBean;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.xml.namespace.QName;
import javax.xml.rpc.holders.BigDecimalHolder;
import javax.xml.rpc.holders.BigIntegerHolder;
import javax.xml.rpc.holders.BooleanHolder;
import javax.xml.rpc.holders.BooleanWrapperHolder;
import javax.xml.rpc.holders.ByteArrayHolder;
import javax.xml.rpc.holders.ByteHolder;
import javax.xml.rpc.holders.ByteWrapperHolder;
import javax.xml.rpc.holders.CalendarHolder;
import javax.xml.rpc.holders.DoubleHolder;
import javax.xml.rpc.holders.DoubleWrapperHolder;
import javax.xml.rpc.holders.FloatHolder;
import javax.xml.rpc.holders.FloatWrapperHolder;
import javax.xml.rpc.holders.Holder;
import javax.xml.rpc.holders.IntHolder;
import javax.xml.rpc.holders.IntegerWrapperHolder;
import javax.xml.rpc.holders.LongHolder;
import javax.xml.rpc.holders.LongWrapperHolder;
import javax.xml.rpc.holders.ObjectHolder;
import javax.xml.rpc.holders.QNameHolder;
import javax.xml.rpc.holders.ShortHolder;
import javax.xml.rpc.holders.ShortWrapperHolder;
import javax.xml.rpc.holders.StringHolder;
import org.apache.xerces.xs.XSComplexTypeDefinition;
import org.apache.xerces.xs.XSTypeDefinition;
import org.jboss.ws.Constants;
import org.jboss.ws.WSException;
import org.jboss.ws.core.jaxrpc.ParameterWrapping;
import org.jboss.ws.core.utils.HolderUtils;
import org.jboss.ws.metadata.wsdl.xmlschema.JBossXSModel;
import org.jboss.wsf.common.JavaUtils;
import org.jboss.xb.binding.Util;
/**
* Singleton utils class used for Java2WSDL and WSDL2Java operations
*
* @author <mailto:Anil.Saldhana@jboss.org>Anil Saldhana
* @since Nov 3, 2004
*/
public class WSDLUtils
{
private String newline = "\n";
private static WSDLUtils instance = new WSDLUtils();
private List wrapperlist = null;
private List primlist = null;
private final Map primitiveMap = new HashMap();
private final static Map<String, Class> schemaBasicTypes = new HashMap<String, Class>();
private final static Map<Class, Class> holderTypes = new HashMap<Class, Class>();
private final static Map<Class, Class> reverseHolderTypes = new HashMap<Class, Class>();
// Skip these methods when generating wsdl operations
private List<String> ignoredMethods;
static
{
schemaBasicTypes.put("anyURI", java.net.URI.class);
schemaBasicTypes.put("boolean", Boolean.TYPE);
schemaBasicTypes.put("byte", Byte.TYPE);
schemaBasicTypes.put("decimal", java.math.BigDecimal.class);
schemaBasicTypes.put("double", Double.TYPE);
schemaBasicTypes.put("dateTime", Calendar.class);
schemaBasicTypes.put("float", Float.TYPE);
schemaBasicTypes.put("int", Integer.TYPE);
schemaBasicTypes.put("integer", BigInteger.class);
schemaBasicTypes.put("long", Long.TYPE);
schemaBasicTypes.put("QName", QName.class);
schemaBasicTypes.put("short", Short.TYPE);
schemaBasicTypes.put("String", String.class);
}
static
{
holderTypes.put(BigDecimal.class, BigDecimalHolder.class);
holderTypes.put(BigInteger.class, BigIntegerHolder.class);
holderTypes.put(boolean.class, BooleanHolder.class);
holderTypes.put(Boolean.class, BooleanWrapperHolder.class);
holderTypes.put(byte.class, ByteHolder.class);
holderTypes.put(Byte.class, ByteWrapperHolder.class);
holderTypes.put(Byte[].class, ByteArrayHolder.class);
holderTypes.put(Calendar.class, CalendarHolder.class);
holderTypes.put(double.class, DoubleHolder.class);
holderTypes.put(Double.class, DoubleWrapperHolder.class);
holderTypes.put(float.class, FloatHolder.class);
holderTypes.put(Float.class, FloatWrapperHolder.class);
holderTypes.put(int.class, IntHolder.class);
holderTypes.put(Integer.class, IntegerWrapperHolder.class);
holderTypes.put(long.class, LongHolder.class);
holderTypes.put(Long.class, LongWrapperHolder.class);
holderTypes.put(Object.class, ObjectHolder.class);
holderTypes.put(QName.class, QNameHolder.class);
holderTypes.put(short.class, ShortHolder.class);
holderTypes.put(Short.class, ShortWrapperHolder.class);
holderTypes.put(String.class, StringHolder.class);
}
static
{
reverseHolderTypes.put(BigDecimalHolder.class, BigDecimal.class);
reverseHolderTypes.put(BigIntegerHolder.class, BigInteger.class);
reverseHolderTypes.put(BooleanHolder.class, boolean.class);
reverseHolderTypes.put(BooleanWrapperHolder.class, Boolean.class);
reverseHolderTypes.put(ByteArrayHolder.class, Byte[].class);
reverseHolderTypes.put(ByteHolder.class, byte.class);
reverseHolderTypes.put(ByteWrapperHolder.class, Byte.class);
reverseHolderTypes.put(CalendarHolder.class, Calendar.class);
reverseHolderTypes.put(DoubleHolder.class, double.class);
reverseHolderTypes.put(DoubleWrapperHolder.class, Double.class);
reverseHolderTypes.put(FloatHolder.class, float.class);
reverseHolderTypes.put(FloatWrapperHolder.class, Float.class);
reverseHolderTypes.put(IntHolder.class, int.class);
reverseHolderTypes.put(IntegerWrapperHolder.class, Integer.class);
reverseHolderTypes.put(LongHolder.class, long.class);
reverseHolderTypes.put(LongWrapperHolder.class, Long.class);
reverseHolderTypes.put(ObjectHolder.class, Object.class);
reverseHolderTypes.put(QNameHolder.class, QName.class);
reverseHolderTypes.put(ShortHolder.class, short.class);
reverseHolderTypes.put(ShortWrapperHolder.class, Short.class);
reverseHolderTypes.put(StringHolder.class, String.class);
}
/**
* Singleton - Only way to get an instance
* @return
*/
public static WSDLUtils getInstance()
{
return instance;
}
private WSDLUtils()
{
wrapperlist = new ArrayList();
primlist = new ArrayList();
populatePrimList();
populateWrapperList();
createPrimitiveMap();
}
/**
* Check if it is of Primitive Type
* @param str
* @return
*/
public boolean isPrimitive(String str)
{
return primlist.contains(str);
}
/**
* Check if it is of Wrapper Type
* @param str
* @return
*/
public boolean isWrapper(String str)
{
return wrapperlist.contains(str);
}
/**
* For the given complex type, check if its base type is the regular xsd type (xsd:anyType)
* which can be ignored
* @param baseType
* @param t ComplexTypeDefinition
* @return true:ignorable, false-otherwise(user defined base type)
*/
public boolean isBaseTypeIgnorable(XSTypeDefinition baseType, XSComplexTypeDefinition t)
{
boolean bool = false;
//Check baseType is xsd:anyType
if (baseType != null)
{
if (baseType.getNamespace() == Constants.NS_SCHEMA_XSD && baseType.getName().equals("anyType"))
bool = true; //Ignore this baseType
}
if (XSComplexTypeDefinition.CONTENTTYPE_SIMPLE == t.getContentType())
{
bool = true; //ComplexType has a simplecontent
}
return bool;
}
/**
* Check if the class is a Java standard class
* @param cls
* @return true if class belongs to java.* or javax.* package
*/
public boolean checkIgnoreClass(Class cls)
{
if (cls == null)
throw new IllegalArgumentException("Illegal null argument:cls");
//if (cls.isArray()) cls = cls.getComponentType();
if (!cls.isArray())
{
String pkgname = cls.getPackage() != null ? cls.getPackage().getName() : null;
if (pkgname != null && pkgname.startsWith("java"))
return true;
if (ParameterWrapping.WrapperType.class.isAssignableFrom(cls))
return true;
}
return false;
}
/** Check if this method should be ignored
*/
public boolean checkIgnoreMethod(Method method)
{
String methodname = method.getName();
if (ignoredMethods == null)
{
ignoredMethods = new ArrayList<String>();
Method[] objMethods = Object.class.getMethods();
for (int i = 0; i < objMethods.length; i++)
{
ignoredMethods.add(objMethods[i].getName());
}
//Add the SessionBean Methods to the ignore list
Method[] sbMethods = SessionBean.class.getMethods();
for (int i = 0; i < sbMethods.length; i++)
{
ignoredMethods.add(sbMethods[i].getName());
}
}
boolean ignoreMethod = ignoredMethods.contains(methodname);
// FIXME: This code is a duplicate, it should read from the UMDM
if (method.getDeclaringClass().isAnnotationPresent(WebService.class) && method.isAnnotationPresent(WebMethod.class) == false)
ignoreMethod = true;
return ignoreMethod;
}
/**
* Chop "PortType" at the end of the String
* @param name
* @return
*/
public String chopPortType(String name)
{
int index = name.lastIndexOf("PortType");
if (index > 0)
return name.substring(0, index);
return name;
}
/**
* Chop chopstr at the end of the String
* @param name
* @param chopstr the string that is the key Eg: Fault
* @return
*/
public String chop(String name, String chopstr)
{
int index = name.lastIndexOf(chopstr);
if (index > 0)
return name.substring(0, index);
return name;
}
/**
* Given a packageName, start creating the package structure
* @param packageName
*/
public File createPackage(String path, String packageName)
{
if (packageName == null)
throw new IllegalArgumentException("Illegal Null Argument: packageName");
if (path == null)
throw new IllegalArgumentException("Illegal Null Argument: path");
String pac = packageName.replace('.', '/');
File dir = new File(path + "/" + pac);
dir.mkdirs();
return dir;
}
/**
* Create a file on the disk
* @param loc Location where the file has to be created
* @param fname File Name to which '.java' will be appended
* @return
* @throws IOException Problem creating the file
*/
public File createPhysicalFile(File loc, String fname) throws IOException
{
if (loc == null)
throw new IllegalArgumentException("Illegal Null Argument: loc");
if (fname == null)
throw new IllegalArgumentException("Illegal Null Argument: fname");
File javaFile = new File(loc.getAbsolutePath() + "/" + fname + ".java");
//Delete the javaFile if already exists
if (javaFile.exists())
javaFile.delete();
boolean boolCreate = javaFile.createNewFile();
if (!boolCreate)
throw new WSException(fname + ".java cannot be created");
return javaFile;
}
/**
* Create the basic template of a class
* @param pkgname Package Name
* @param fname File Name to which '.java' will be appended
* @param type XSDType to obtain base class info (if Complex Type)
* @param importList Strings representing imports
* @return
*/
public StringBuilder createClassBasicStructure(String pkgname, String fname, XSTypeDefinition type, List importList, String baseName)
{
StringBuilder buf = new StringBuilder();
writeJbossHeader(buf);
buf.append(newline);
buf.append("package " + pkgname + ";");
buf.append(newline);
buf.append(newline);
if (importList != null)
{
Iterator iter = importList.iterator();
while (iter.hasNext())
{
buf.append("import " + (String)iter.next() + ";");
buf.append(newline);
}
}
buf.append(newline);
XSTypeDefinition baseType = null;
if (type instanceof XSComplexTypeDefinition)
{
XSComplexTypeDefinition t = (XSComplexTypeDefinition)type;
baseType = t.getBaseType();
//Check baseType is xsd:anyType
if (baseType != null)
{
if (baseType.getNamespace() == Constants.NS_SCHEMA_XSD && baseType.getName().equals("anyType"))
baseType = null; //Ignore this baseType
}
if (XSComplexTypeDefinition.CONTENTTYPE_SIMPLE == t.getContentType())
{
baseType = null; //ComplexType has a simplecontent
}
}
buf.append("public class " + fname);
if (baseName == null && baseType != null)
baseName = baseType.getName();
if (baseName != null)
buf.append(" extends " + baseName);
buf.append(newline);
buf.append("{");
buf.append(newline);
return buf;
}
/**
* Checks whether there exists a public field with the given name
* @param javaType Class Object
* @param name Field name to check
* @return true - if public field exists, false-otherwise
*/
public boolean doesPublicFieldExist(Class javaType, String name)
{
Field fld = null;
try
{
fld = javaType.getField(name);
}
catch (SecurityException e)
{
throw e;
}
catch (NoSuchFieldException e)
{
return false;
}
int mod = fld.getModifiers();
if ((mod == Modifier.PUBLIC))
return true;
return false;
}
/**
* Ensure that the first alphabet is uppercase
* @param fname
* @return
*/
public String firstLetterUpperCase(String fname)
{
if (fname == "" || fname == null)
throw new WSException("String passed is null");
//Ensure that the first character is uppercase
if (Character.isLowerCase(fname.charAt(0)))
{
char[] chars = fname.toCharArray();
char f = Character.toUpperCase(chars[0]);
chars[0] = f;
fname = new String(chars);
}
return fname;
}
/**
* Get the dimension of an array
* @param arr
* @return dimension of an array
*/
public int getArrayDimension(Class arr)
{
if (arr == null || arr.isArray() == false)
throw new IllegalArgumentException("Illegal null or array arg:arr");
int counter = 0;
while (arr.isArray())
{
counter += 1;
arr = arr.getComponentType();
}
return counter;
}
/**
* Return the Jaxrpc holder that
* represents the class
* @param cls
* @return Jaxrpc Holder object if exists
*/
public Class getHolder(Class cls)
{
return holderTypes.get(cls);
}
/**
* Return the Java class that is represented by
* the Jaxrpc holder
* @param cls The jaxrpc holder type
* @return Jaxrpc Holder object if exists
*/
public Class getJavaTypeForHolder(Class cls)
{
if (Holder.class.isAssignableFrom(cls))
return HolderUtils.getValueType(cls);
else return cls;
//return reverseHolderTypes.get(cls);
}
/**
* An input of "HelloObjArray" is converted into arrayOfHelloObj
* Applied in the input part for WSDL 1.1 Messages
* @param arrayStr
* @return
*/
public String getMessagePartForArray(Class javaType)
{
StringBuilder sb = new StringBuilder();
while (javaType.isArray())
{
sb.append("arrayOf");
javaType = javaType.getComponentType();
}
sb.append(getJustClassName(javaType));
return sb.toString();
}
/**
* Given a class, strip out the package name
*
* @param cls
* @return just the classname
*/
public static String getJustClassName(Class cls)
{
if (cls == null)
return null;
if (cls.isArray())
{
Class c = cls.getComponentType();
return getJustClassName(c.getName());
}
return getJustClassName(cls.getName());
}
/**
* Given a FQN of a class, strip out the package name
*
* @param classname
* @return just the classname
*/
public static String getJustClassName(String classname)
{
int index = classname.lastIndexOf(".");
if (index < 0)
index = 0;
else index = index + 1;
return classname.substring(index);
}
/**
* From the list of fields defined by this class (not superclasses)
* get the fields that are relevant (public)
*/
public Field[] getPublicFields(Class cls)
{
ArrayList list = new ArrayList();
Field[] fld = cls.getDeclaredFields();
for (int i = 0; i < fld.length; i++)
{
Field field = fld[i];
int mod = field.getModifiers();
if ((mod == Modifier.PUBLIC))
list.add(field);
}//end for
Field[] retarr = new Field[list.size()];
list.toArray(retarr);
return retarr;
}
/**
* From the list of fields defined by this class (not superclasses)
* get the fields that are relevant (public/protected)
*
* @param methods
* @return
*/
public Method[] getPublicProtectedMethods(Method[] methods)
{
ArrayList list = new ArrayList();
int len = methods.length;
for (int i = 0; i < len; i++)
{
Method method = methods[i];
int mod = method.getModifiers();
if ((mod == Modifier.PUBLIC || mod == Modifier.PROTECTED))
list.add(method);
}//end for
Method[] retarr = new Method[list.size()];
list.toArray(retarr);
return retarr;
}
/**
* Given the XMLType, we will check if it is of basic schema
* types that are mapped to Java primitives and wrappers
* Jaxrpc 1.1 Section 5.3
* @param xmlType
* @return
*/
public Class getJavaType(QName xmlType)
{
if (xmlType == null)
return null;
String localPart = xmlType.getLocalPart();
return (Class)schemaBasicTypes.get(localPart);
}
/**
* Change the first character to uppercase
* @param str
* @return
*/
public String getMixedCase(String str)
{
if (str == null || str.length() == 0)
throw new IllegalArgumentException("String passed to WSDLUtils.getMixedCase is null");
if (str.length() == 1)
return str.toUpperCase();
char[] charr = str.toCharArray();
charr[0] = Character.toUpperCase(charr[0]);
return new String(charr);
}
/**
* Given a QName, provide a string that is prefix:localpart
* @param qn
* @return formatted string
*/
public String getFormattedString(QName qn)
{
if (qn == null)
throw new IllegalArgumentException(" QName passed is null");
StringBuilder sb = new StringBuilder();
String prefix = qn.getPrefix();
String localpart = qn.getLocalPart();
if (prefix == null || prefix == "")
prefix = Constants.PREFIX_TNS;
sb.append(prefix + ":");
sb.append(localpart);
return sb.toString();
}
/**
* Return a QName given a formatted string
* @param formattedStr string that is prefix:localpart
* @return QName
*/
public QName getQName(String formattedStr)
{
QName qn = null;
int ind = formattedStr.lastIndexOf(":");
if (ind < 0)
throw new IllegalArgumentException("Formatted String is not of format prefix:localpart");
String prefix = formattedStr.substring(0, ind);
String nsuri = null;
if (Constants.PREFIX_XSD.equals(prefix))
nsuri = Constants.NS_SCHEMA_XSD;
if (nsuri == null)
qn = new QName(formattedStr.substring(ind + 1));
else qn = new QName(nsuri, formattedStr.substring(ind + 1), prefix);
return qn;
}
/**
* Return the primitive for a wrapper equivalent (Integer -> int)
* @param str
* @return
*/
public String getPrimitive(String str)
{
return (String)primitiveMap.get(str);
}
/**
* Extracts the package name from the typeNS
* @param typeNS
* @return
*/
public String getPackageName(String typeNS)
{
String pkgname = Util.xmlNamespaceToJavaPackage(typeNS);
return pkgname;
}
public static String getTypeNamespace(Class javaType)
{
return getTypeNamespace(JavaUtils.getPackageName(javaType));
}
/**
* Extracts the typeNS given the package name
* Algorithm is based on the one specified in JAWS v2.0 spec
*/
public static String getTypeNamespace(String packageName)
{
StringBuilder sb = new StringBuilder("http://");
//Generate tokens with '.' as delimiter
StringTokenizer st = new StringTokenizer(packageName, ".");
//Have a LIFO queue for the tokens
Stack<String> stk = new Stack<String>();
while (st != null && st.hasMoreTokens())
{
stk.push(st.nextToken());
}
String next;
while (!stk.isEmpty() && (next = stk.pop()) != null)
{
if (sb.toString().equals("http://") == false)
sb.append(".");
sb.append(next);
}
// trailing slash
sb.append("/");
return sb.toString();
}
/**
* Given WSDLDefinitions, detect the wsdl style
*
* @param wsdl
* @return Constants.RPC_LITERAL or Constants.DOCUMENT_LITERAL
*/
public String getWSDLStyle(WSDLDefinitions wsdl)
{
WSDLInterface wi = wsdl.getInterfaces()[0];
WSDLInterfaceOperation wio = wi.getOperations()[0];
String style = wio.getStyle();
if (style == null || style.equals(Constants.URI_STYLE_RPC) || "rpc".equalsIgnoreCase(style))
return Constants.RPC_LITERAL;
else return Constants.DOCUMENT_LITERAL;
}
public static JBossXSModel getSchemaModel(WSDLTypes types)
{
if (types instanceof XSModelTypes)
return ((XSModelTypes)types).getSchemaModel();
throw new WSException("WSDLTypes is not an XSModelTypes");
}
public static void addSchemaModel(WSDLTypes types, String namespace, JBossXSModel model)
{
if (!(types instanceof XSModelTypes))
throw new WSException("WSDLTypes is not an XSModelTypes");
XSModelTypes modelTypes = (XSModelTypes)types;
modelTypes.addSchemaModel(namespace, model);
}
/**
* Checks whether the class is a standard jaxrpc holder
*
* @param cls a Class object
* @return true: A Standard jaxrpc holder
*/
public boolean isStandardHolder(Class cls)
{
if (Holder.class.isAssignableFrom(cls) == false)
return false; //Not even a holder
//It is a holder. Is it a standard holder?
if (cls.getPackage().getName().startsWith("javax.xml.rpc"))
return true;
return false;
}
/**
* Write the JBoss License Header at the top of generated class source files
* @param buf
*/
public void writeJbossHeader(StringBuilder buf)
{
buf.append("/*").append(newline);
buf.append(" * JBossWS WS-Tools Generated Source").append(newline);
buf.append(" *").append(newline);
buf.append(" * Generation Date: " + new Date() + newline);
buf.append(" *").append(newline);
buf.append(" * This generated source code represents a derivative work of the input to").append(newline);
buf.append(" * the generator that produced it. Consult the input for the copyright and").append(newline);
buf.append(" * terms of use that apply to this source code.").append(newline);
buf.append(" */").append(newline);
}
protected void populatePrimList()
{
primlist.add("int");
primlist.add("boolean");
primlist.add("short");
primlist.add("byte");
primlist.add("long");
primlist.add("float");
primlist.add("double");
}
protected void populateWrapperList()
{
wrapperlist.add("java.lang.Integer");
wrapperlist.add("java.lang.Boolean");
wrapperlist.add("java.lang.Short");
wrapperlist.add("java.lang.Byte");
wrapperlist.add("java.lang.Long");
wrapperlist.add("java.lang.Float");
wrapperlist.add("java.lang.Double");
wrapperlist.add("java.lang.String");
wrapperlist.add("java.math.BigInteger");
wrapperlist.add("java.math.BigDecimal");
wrapperlist.add("java.util.Calendar");
wrapperlist.add("javax.xml.namespace.QName");
}
private void createPrimitiveMap()
{
primitiveMap.put("Integer", "int");
primitiveMap.put("Float", "float");
primitiveMap.put("Long", "long");
primitiveMap.put("Double", "double");
primitiveMap.put("Short", "short");
primitiveMap.put("Boolean", "boolean");
primitiveMap.put("Byte", "byte");
primitiveMap.put("java.lang.Integer", "int");
primitiveMap.put("java.lang.Float", "float");
primitiveMap.put("java.lang.Long", "long");
primitiveMap.put("java.lang.Double", "double");
primitiveMap.put("java.lang.Short", "short");
primitiveMap.put("java.lang.Boolean", "boolean");
primitiveMap.put("java.lang.Byte", "byte");
}
public static WSDLInterfaceOperationOutput getWsdl11Output(WSDLInterfaceOperation operation)
{
WSDLInterfaceOperationOutput[] outputs = operation.getOutputs();
if (outputs == null)
return null;
switch (outputs.length)
{
case 0:
return null;
case 1:
return outputs[0];
}
throw new WSException("Only Request-Only and Request-Response MEPs are allowed");
}
public static WSDLInterfaceOperationInput getWsdl11Input(WSDLInterfaceOperation operation)
{
WSDLInterfaceOperationInput[] inputs = operation.getInputs();
if (inputs == null)
return null;
switch (inputs.length)
{
case 0:
return null;
case 1:
return inputs[0];
}
throw new WSException("Only Request-Only and Request-Response MEPs are allowed");
}
}