package org.jboss.axis.description;
import org.jboss.axis.AxisServiceConfig;
import org.jboss.axis.Constants;
import org.jboss.axis.InternalException;
import org.jboss.axis.encoding.DefaultTypeMappingImpl;
import org.jboss.axis.encoding.TypeMapping;
import org.jboss.axis.encoding.TypeMappingRegistry;
import org.jboss.axis.encoding.TypeMappingRegistryImpl;
import org.jboss.axis.enums.Style;
import org.jboss.axis.enums.Use;
import org.jboss.axis.message.SOAPBodyElementAxisImpl;
import org.jboss.axis.message.SOAPEnvelopeAxisImpl;
import org.jboss.axis.utils.JavaUtils;
import org.jboss.axis.utils.Messages;
import org.jboss.axis.utils.bytecode.ParamNameExtractor;
import org.jboss.axis.wsdl.Skeleton;
import org.jboss.axis.wsdl.fromJava.Namespaces;
import org.jboss.logging.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import javax.xml.namespace.QName;
import javax.xml.rpc.holders.Holder;
import javax.xml.rpc.server.ServiceLifecycle;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
public class ServiceDesc
{
private static Logger log = Logger.getLogger(ServiceDesc.class.getName());
private String name = null;
private List allowedMethods = null;
private List disallowedMethods = null;
private Style style = Style.RPC;
private Use use = Use.ENCODED;
private boolean useSet = false;
private Class implClass = null;
private ArrayList operations = new ArrayList();
private List namespaceMappings = null;
private String wsdlFileName = null;
private String endpointURL = null;
private HashMap properties = null;
private boolean isSkeletonClass = false;
private Method skelMethod = null;
private ArrayList stopClasses = null;
private HashMap name2OperationsMap = null;
private HashMap qname2OperationsMap = null;
private HashMap method2OperationMap = new HashMap();
private HashMap method2ParamsMap = new HashMap();
private OperationDesc messageServiceDefaultOp = null;
private ArrayList completedNames = new ArrayList();
private TypeMapping tm = DefaultTypeMappingImpl.getSingleton();
private TypeMappingRegistry tmr = null;
private boolean haveAllSkeletonMethods = false;
private boolean introspectionComplete = false;
public ServiceDesc()
{
}
public Style getStyle()
{
return style;
}
public void setStyle(Style style)
{
this.style = style;
if (!useSet)
{
use = style == Style.RPC ? Use.ENCODED : Use.LITERAL;
}
}
public Use getUse()
{
return use;
}
public void setUse(Use use)
{
useSet = true;
this.use = use;
}
public boolean isWrapped()
{
return ((style == Style.RPC) ||
(style == Style.WRAPPED));
}
public String getWSDLFile()
{
return wsdlFileName;
}
public void setWSDLFile(String wsdlFileName)
{
this.wsdlFileName = wsdlFileName;
}
public List getAllowedMethods()
{
return allowedMethods;
}
public void setAllowedMethods(List allowedMethods)
{
this.allowedMethods = allowedMethods;
}
public Class getImplClass()
{
return implClass;
}
public void setImplClass(Class implClass)
{
if (this.implClass != null)
throw new IllegalArgumentException(Messages.getMessage("implAlreadySet"));
this.implClass = implClass;
if (Skeleton.class.isAssignableFrom(implClass))
{
isSkeletonClass = true;
loadSkeletonOperations();
}
}
private void loadSkeletonOperations()
{
Method method = null;
try
{
method = implClass.getDeclaredMethod("getOperationDescs",
new Class[]{});
}
catch (NoSuchMethodException e)
{
}
catch (SecurityException e)
{
}
if (method == null)
{
return;
}
try
{
Collection opers = (Collection)method.invoke(implClass, null);
for (Iterator i = opers.iterator(); i.hasNext();)
{
OperationDesc skelDesc = (OperationDesc)i.next();
addOperationDesc(skelDesc);
}
}
catch (IllegalAccessException e)
{
return;
}
catch (IllegalArgumentException e)
{
return;
}
catch (InvocationTargetException e)
{
return;
}
haveAllSkeletonMethods = true;
}
public TypeMapping getTypeMapping()
{
return tm;
}
public void setTypeMapping(TypeMapping tm)
{
this.tm = tm;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public ArrayList getStopClasses()
{
return stopClasses;
}
public void setStopClasses(ArrayList stopClasses)
{
this.stopClasses = stopClasses;
}
public List getDisallowedMethods()
{
return disallowedMethods;
}
public void setDisallowedMethods(List disallowedMethods)
{
this.disallowedMethods = disallowedMethods;
}
public void addOperationDesc(OperationDesc operation)
{
operations.add(operation);
operation.setParent(this);
if (name2OperationsMap == null)
{
name2OperationsMap = new HashMap();
}
String name = operation.getName();
ArrayList overloads = (ArrayList)name2OperationsMap.get(name);
if (overloads == null)
{
overloads = new ArrayList();
name2OperationsMap.put(name, overloads);
}
overloads.add(operation);
}
public ArrayList getOperations()
{
loadServiceDescByIntrospection(); return operations;
}
public OperationDesc[] getOperationsByName(String methodName)
{
getSyncedOperationsForName(implClass, methodName);
if (name2OperationsMap == null)
return null;
ArrayList overloads = (ArrayList)name2OperationsMap.get(methodName);
if (overloads == null)
{
return null;
}
OperationDesc[] array = new OperationDesc[overloads.size()];
return (OperationDesc[])overloads.toArray(array);
}
public OperationDesc getOperationByName(String methodName)
{
getSyncedOperationsForName(implClass, methodName);
if (name2OperationsMap == null)
return null;
ArrayList overloads = (ArrayList)name2OperationsMap.get(methodName);
if (overloads == null)
{
return null;
}
return (OperationDesc)overloads.get(0);
}
public OperationDesc getOperationByElementQName(QName qname)
{
OperationDesc[] overloads = getOperationsByQName(qname);
if ((overloads != null) && overloads.length > 0)
return overloads[0];
return null;
}
public OperationDesc[] getOperationsByQName(QName qname)
{
initQNameMap();
ArrayList overloads = (ArrayList)qname2OperationsMap.get(qname);
if (overloads == null)
{
if ((isWrapped() ||
((style == Style.MESSAGE) &&
(getDefaultNamespace() == null))) &&
(name2OperationsMap != null))
{
overloads = (ArrayList)name2OperationsMap.get(qname.getLocalPart());
}
if ((style == Style.MESSAGE) && (messageServiceDefaultOp != null))
return new OperationDesc[]{messageServiceDefaultOp};
if (overloads == null)
return null;
}
getSyncedOperationsForName(implClass,
((OperationDesc)overloads.get(0)).getName());
Collections.sort(overloads,
new Comparator()
{
public int compare(Object o1, Object o2)
{
Method meth1 = ((OperationDesc)o1).getMethod();
Method meth2 = ((OperationDesc)o2).getMethod();
return (meth1.getParameterTypes().length -
meth2.getParameterTypes().length);
}
});
OperationDesc[] array = new OperationDesc[overloads.size()];
return (OperationDesc[])overloads.toArray(array);
}
private synchronized void initQNameMap()
{
if (qname2OperationsMap == null)
{
loadServiceDescByIntrospection();
qname2OperationsMap = new HashMap();
for (Iterator i = operations.iterator(); i.hasNext();)
{
OperationDesc operationDesc = (OperationDesc)i.next();
QName qname = operationDesc.getElementQName();
ArrayList list = (ArrayList)qname2OperationsMap.get(qname);
if (list == null)
{
list = new ArrayList();
qname2OperationsMap.put(qname, list);
}
list.add(operationDesc);
}
}
}
private void syncOperationToClass(OperationDesc opDesc, Class implClass)
{
log.debug("Enter: syncOperationToClass " + opDesc);
if (opDesc.getMethod() != null)
return;
Method[] methods = implClass.getDeclaredMethods();
Method possibleMatch = null;
for (int i = 0; i < methods.length; i++)
{
Method method = methods[i];
if (Modifier.isPublic(method.getModifiers()) &&
method.getName().equals(opDesc.getName()) &&
method2OperationMap.get(method) == null)
{
log.debug("Sync method: " + method);
if (style == Style.MESSAGE)
{
int messageOperType = checkMessageMethod(method);
if (messageOperType == OperationDesc.MSG_METHOD_NONCONFORMING) continue;
if (messageOperType == -1)
{
throw new InternalException("Couldn't match method to any of the allowable message-style patterns!");
}
opDesc.setMessageOperationStyle(messageOperType);
}
Class[] paramTypes = method.getParameterTypes();
if (paramTypes.length != opDesc.getNumParams())
{
log.debug("Number of parameters don't match");
continue;
}
int j;
boolean conversionNecessary = false;
for (j = 0; j < paramTypes.length; j++)
{
Class type = paramTypes[j];
Class actualType = type;
log.debug("Converting param: " + type);
if (Holder.class.isAssignableFrom(type))
actualType = JavaUtils.getHolderValueType(type);
ParameterDesc param = opDesc.getParameter(j);
Class paramClass = param.getJavaType();
QName typeQName = param.getTypeQName();
if (typeQName == null)
{
typeQName = tm.getTypeQName(type);
param.setTypeQName(typeQName);
log.debug("Setting param TypeQName: " + typeQName);
}
else
{
if (paramClass != null && JavaUtils.getHolderValueType(paramClass) != null)
{
paramClass = JavaUtils.getHolderValueType(paramClass);
log.debug("Setting param class to holder type: " + paramClass);
}
if (paramClass == null)
{
paramClass = tm.getClassForQName(param.getTypeQName());
log.debug("Setting param class from TypeQName: " + paramClass);
}
if (paramClass != null)
{
if (!JavaUtils.isConvertable(paramClass, actualType))
{
log.debug("Param class is not convertible: [param=" + paramClass + ",actual=" + actualType + "]");
break;
}
if (!actualType.isAssignableFrom(paramClass))
{
conversionNecessary = true;
log.debug("Actual type is not assignable from param class: [param=" + paramClass + ",actual=" + actualType + "]");
}
}
}
param.setJavaType(type);
log.debug("Setting param java type: " + type);
}
if (j != paramTypes.length)
{
continue;
}
possibleMatch = method;
log.debug("Possible match: " + possibleMatch);
if (!conversionNecessary)
{
break;
}
log.debug("Conversion still necessary");
}
}
if (possibleMatch != null)
{
ParameterDesc retParamDesc = opDesc.getReturnParamDesc();
QName retTypeQName = retParamDesc.getTypeQName();
Class retType = retParamDesc.getJavaType();
if (retTypeQName != null && retType == null)
retType = tm.getClassForQName(retTypeQName);
if (retType != null)
{
Class seiReturnType = possibleMatch.getReturnType();
if (JavaUtils.isConvertable(retType, seiReturnType))
{
opDesc.setReturnClass(seiReturnType);
log.debug("Setting return type: " + seiReturnType);
}
else
{
log.warn("Return type is not convertible to: " + retType);
}
}
if (possibleMatch != null)
{
createFaultMetadata(possibleMatch, opDesc);
opDesc.setMethod(possibleMatch);
method2OperationMap.put(possibleMatch, opDesc);
log.debug("Setting operation method: " + possibleMatch);
}
}
if (opDesc.getMethod() == null)
{
Class superClass = implClass.getSuperclass();
if (superClass != null &&
!superClass.getName().startsWith("java.") &&
!superClass.getName().startsWith("javax.") &&
(stopClasses == null ||
!stopClasses.contains(superClass.getName())))
{
log.debug("No match found, trying super class");
syncOperationToClass(opDesc, superClass);
}
}
if (opDesc.getMethod() == null)
{
InternalException ie =
new InternalException(Messages.getMessage("serviceDescOperSync00",
opDesc.getName(),
implClass.getName()));
throw ie;
}
}
private int checkMessageMethod(Method method)
{
Class[] params = method.getParameterTypes();
if (params.length == 1)
{
if ((params[0] == Element[].class) &&
(method.getReturnType() == Element[].class))
{
return OperationDesc.MSG_METHOD_ELEMENTARRAY;
}
if ((params[0] == SOAPBodyElementAxisImpl[].class) &&
(method.getReturnType() == SOAPBodyElementAxisImpl[].class))
{
return OperationDesc.MSG_METHOD_BODYARRAY;
}
if ((params[0] == Document.class) &&
(method.getReturnType() == Document.class))
{
return OperationDesc.MSG_METHOD_DOCUMENT;
}
}
else if (params.length == 2)
{
if ((params[0] == SOAPEnvelopeAxisImpl.class) &&
(params[1] == SOAPEnvelopeAxisImpl.class) &&
(method.getReturnType() == void.class))
{
return OperationDesc.MSG_METHOD_SOAPENVELOPE;
}
}
if (null != allowedMethods && !allowedMethods.isEmpty())
throw new InternalException(Messages.getMessage("badMsgMethodParams",
method.getName()));
return OperationDesc.MSG_METHOD_NONCONFORMING;
}
public void loadServiceDescByIntrospection()
{
loadServiceDescByIntrospection(implClass);
completedNames = null;
}
public void loadServiceDescByIntrospection(Class implClass)
{
if (introspectionComplete || implClass == null)
{
return;
}
this.implClass = implClass;
if (Skeleton.class.isAssignableFrom(implClass))
{
isSkeletonClass = true;
loadSkeletonOperations();
}
AxisServiceConfig axisConfig = null;
try
{
Method method = implClass.getDeclaredMethod("getAxisServiceConfig", new Class[]{});
if (method != null && Modifier.isStatic(method.getModifiers()))
{
axisConfig = (AxisServiceConfig)method.invoke(null, null);
}
}
catch (Exception e)
{
}
if (axisConfig != null)
{
String allowedMethodsStr = axisConfig.getAllowedMethods();
if (allowedMethodsStr != null && !"*".equals(allowedMethodsStr))
{
ArrayList methodList = new ArrayList();
StringTokenizer tokenizer =
new StringTokenizer(allowedMethodsStr, " ,");
while (tokenizer.hasMoreTokens())
{
methodList.add(tokenizer.nextToken());
}
setAllowedMethods(methodList);
}
}
loadServiceDescByIntrospectionRecursive(implClass);
for (Iterator iterator = operations.iterator(); iterator.hasNext();)
{
OperationDesc operation = (OperationDesc)iterator.next();
if (operation.getMethod() == null)
{
throw new InternalException(Messages.getMessage("badWSDDOperation",
operation.getName(),
"" + operation.getNumParams()));
}
}
if ((style == Style.MESSAGE) && operations.size() == 1)
{
messageServiceDefaultOp = (OperationDesc)operations.get(0);
}
introspectionComplete = true;
}
private boolean isServiceLifeCycleMethod(Class implClass, Method m)
{
if (ServiceLifecycle.class.isAssignableFrom(implClass))
{
String methodName = m.getName();
if (methodName.equals("init"))
{
Class[] classes = m.getParameterTypes();
if (classes != null &&
classes.length == 1 &&
classes[0] == Object.class &&
m.getReturnType() == Void.TYPE)
{
return true;
}
}
else if (methodName.equals("destroy"))
{
Class[] classes = m.getParameterTypes();
if (classes != null &&
classes.length == 0 &&
m.getReturnType() == Void.TYPE)
{
return true;
}
}
}
return false;
}
private void loadServiceDescByIntrospectionRecursive(Class implClass)
{
if (Skeleton.class.equals(implClass))
{
return;
}
Method[] methods = implClass.getDeclaredMethods();
for (int i = 0; i < methods.length; i++)
{
if (Modifier.isPublic(methods[i].getModifiers()) && !isServiceLifeCycleMethod(implClass, methods[i]))
{
getSyncedOperationsForName(implClass, methods[i].getName());
}
}
if (implClass.isInterface())
{
Class[] superClasses = implClass.getInterfaces();
for (int i = 0; i < superClasses.length; i++)
{
Class superClass = superClasses[i];
if (!superClass.getName().startsWith("java.") &&
!superClass.getName().startsWith("javax.") &&
(stopClasses == null ||
!stopClasses.contains(superClass.getName())))
{
loadServiceDescByIntrospectionRecursive(superClass);
}
}
}
else
{
Class superClass = implClass.getSuperclass();
if (superClass != null &&
!superClass.getName().startsWith("java.") &&
!superClass.getName().startsWith("javax.") &&
(stopClasses == null ||
!stopClasses.contains(superClass.getName())))
{
loadServiceDescByIntrospectionRecursive(superClass);
}
}
}
public void loadServiceDescByIntrospection(Class cls, TypeMapping tm)
{
implClass = cls;
this.tm = tm;
if (Skeleton.class.isAssignableFrom(implClass))
{
isSkeletonClass = true;
loadSkeletonOperations();
}
loadServiceDescByIntrospection();
}
private void getSyncedOperationsForName(Class implClass, String methodName)
{
if (isSkeletonClass)
{
if (methodName.equals("getOperationDescByName") ||
methodName.equals("getOperationDescs"))
return;
}
if (implClass == null)
return;
if (completedNames == null || completedNames.contains(methodName))
return;
if ((allowedMethods != null) &&
!allowedMethods.contains(methodName))
return;
if ((disallowedMethods != null) &&
disallowedMethods.contains(methodName))
return;
if (isSkeletonClass && !haveAllSkeletonMethods)
{
if (skelMethod == null)
{
try
{
skelMethod = implClass.getDeclaredMethod("getOperationDescByName",
new Class[]{String.class});
}
catch (NoSuchMethodException e)
{
}
catch (SecurityException e)
{
}
if (skelMethod == null)
{
return;
}
}
try
{
List skelList =
(List)skelMethod.invoke(implClass,
new Object[]{methodName});
if (skelList != null)
{
Iterator i = skelList.iterator();
while (i.hasNext())
{
addOperationDesc((OperationDesc)i.next());
}
}
}
catch (IllegalAccessException e)
{
return;
}
catch (IllegalArgumentException e)
{
return;
}
catch (InvocationTargetException e)
{
return;
}
}
if (name2OperationsMap != null)
{
ArrayList currentOverloads =
(ArrayList)name2OperationsMap.get(methodName);
if (currentOverloads != null)
{
for (Iterator i = currentOverloads.iterator(); i.hasNext();)
{
OperationDesc oper = (OperationDesc)i.next();
if (oper.getMethod() == null)
{
syncOperationToClass(oper, implClass);
}
}
}
}
createOperationsForName(implClass, methodName);
completedNames.add(methodName);
}
private void createOperationsForName(Class implClass, String methodName)
{
if (isSkeletonClass)
{
if (methodName.equals("getOperationDescByName") ||
methodName.equals("getOperationDescs"))
return;
}
Method[] methods = implClass.getDeclaredMethods();
for (int i = 0; i < methods.length; i++)
{
Method method = methods[i];
if (Modifier.isPublic(method.getModifiers()) &&
method.getName().equals(methodName))
{
createOperationForMethod(method);
}
}
Class superClass = implClass.getSuperclass();
if (superClass != null &&
!superClass.getName().startsWith("java.") &&
!superClass.getName().startsWith("javax."))
{
createOperationsForName(superClass, methodName);
}
}
private void createOperationForMethod(Method method)
{
if (method2OperationMap.get(method) != null)
{
return;
}
Class[] paramTypes = method.getParameterTypes();
ArrayList overloads = name2OperationsMap == null ? null :
(ArrayList)name2OperationsMap.get(method.getName());
if (overloads != null && !overloads.isEmpty())
{
for (int i = 0; i < overloads.size(); i++)
{
OperationDesc op = (OperationDesc)overloads.get(i);
Method checkMethod = op.getMethod();
if (checkMethod != null)
{
Class[] others = checkMethod.getParameterTypes();
if (paramTypes.length == others.length)
{
int j = 0;
for (; j < others.length; j++)
{
if (!others[j].equals(paramTypes[j]))
break;
}
if (j == others.length)
return;
}
}
}
}
OperationDesc operation = new OperationDesc();
operation.setName(method.getName());
String defaultNS = "";
if (namespaceMappings != null && !namespaceMappings.isEmpty())
{
defaultNS = (String)namespaceMappings.get(0);
}
if (defaultNS.length() == 0)
{
defaultNS = Namespaces.makeNamespace(method.getDeclaringClass().getName());
}
operation.setElementQName(new QName(defaultNS, method.getName()));
operation.setMethod(method);
if (style == Style.MESSAGE)
{
int messageOperType = checkMessageMethod(method);
if (messageOperType == OperationDesc.MSG_METHOD_NONCONFORMING) return;
if (messageOperType == -1)
{
throw new InternalException("Couldn't match method to any of the allowable message-style patterns!");
}
operation.setMessageOperationStyle(messageOperType);
operation.setReturnClass(Object.class);
operation.setReturnType(Constants.XSD_ANYTYPE);
}
else
{
Class retClass = method.getReturnType();
operation.setReturnClass(retClass);
operation.setReturnType(tm.getTypeQName(method.getReturnType()));
String[] paramNames = getParamNames(method);
for (int k = 0; k < paramTypes.length; k++)
{
Class type = paramTypes[k];
ParameterDesc paramDesc = new ParameterDesc();
String opNamespace = operation.getElementQName().getNamespaceURI();
if (paramNames != null && paramNames[k] != null &&
paramNames[k].length() > 0)
{
paramDesc.setQName(new QName(opNamespace, paramNames[k]));
}
else
{
paramDesc.setQName(new QName(opNamespace, "in" + k));
}
Class heldClass = JavaUtils.getHolderValueType(type);
if (heldClass != null)
{
paramDesc.setMode(ParameterDesc.INOUT);
paramDesc.setTypeQName(tm.getTypeQName(heldClass));
}
else
{
paramDesc.setMode(ParameterDesc.IN);
paramDesc.setTypeQName(tm.getTypeQName(type));
}
paramDesc.setJavaType(type);
operation.addParameter(paramDesc);
}
}
createFaultMetadata(method, operation);
addOperationDesc(operation);
method2OperationMap.put(method, operation);
}
private void createFaultMetadata(Method method, OperationDesc operation)
{
Class[] exceptionTypes = new Class[method.getExceptionTypes().length];
exceptionTypes = method.getExceptionTypes();
for (int i = 0; i < exceptionTypes.length; i++)
{
Class ex = exceptionTypes[i];
if (ex != java.rmi.RemoteException.class &&
ex != org.jboss.axis.AxisFault.class &&
!ex.getName().startsWith("java.") &&
!ex.getName().startsWith("javax."))
{
log.debug("Enter: createFaultMetadata: " + ex);
FaultDesc fault = operation.getFaultByClass(ex);
if (fault == null)
{
fault = new FaultDesc();
log.debug("Creating new fault desc: " + fault);
}
QName xmlType = fault.getXmlType();
if (xmlType == null)
{
QName typeQName = tm.getTypeQName(ex);
fault.setXmlType(typeQName);
log.debug("Setting XMLType: " + typeQName);
}
String pkgAndClsName = ex.getName();
if (fault.getClassName() == null)
{
fault.setClassName(pkgAndClsName);
log.debug("Setting ClassName: " + pkgAndClsName);
}
if (fault.getName() == null)
{
String name = pkgAndClsName.substring(pkgAndClsName.lastIndexOf('.') + 1,
pkgAndClsName.length());
fault.setName(name);
log.debug("Setting Name: " + name);
}
if (fault.getParameters() == null)
{
if (xmlType == null)
{
xmlType = tm.getTypeQName(ex);
}
QName qname = fault.getQName();
if (qname == null)
{
qname = new QName("", "fault");
}
ParameterDesc param = new ParameterDesc(qname, ParameterDesc.IN, xmlType);
param.setJavaType(ex);
ArrayList exceptionParams = new ArrayList();
exceptionParams.add(param);
fault.setParameters(exceptionParams);
log.debug("Setting Parameters: " + exceptionParams);
}
if (fault.getQName() == null)
{
fault.setQName(new QName(pkgAndClsName));
}
operation.addFault(fault);
log.debug("Adding fault: " + fault);
}
}
}
private String[] getParamNames(Method method)
{
synchronized (method2ParamsMap)
{
String[] paramNames = (String[])method2ParamsMap.get(method);
if (paramNames != null)
return paramNames;
paramNames = ParamNameExtractor.getParameterNamesFromDebugInfo(method);
method2ParamsMap.put(method, paramNames);
return paramNames;
}
}
public void setNamespaceMappings(List namespaces)
{
namespaceMappings = namespaces;
}
public String getDefaultNamespace()
{
if (namespaceMappings == null || namespaceMappings.isEmpty())
return null;
return (String)namespaceMappings.get(0);
}
public void setDefaultNamespace(String namespace)
{
if (namespaceMappings == null)
namespaceMappings = new ArrayList();
namespaceMappings.add(0, namespace);
}
public void setProperty(String name, Object value)
{
if (properties == null)
{
properties = new HashMap();
}
properties.put(name, value);
}
public Object getProperty(String name)
{
if (properties == null)
return null;
return properties.get(name);
}
public String getEndpointURL()
{
return endpointURL;
}
public void setEndpointURL(String endpointURL)
{
this.endpointURL = endpointURL;
}
public TypeMappingRegistry getTypeMappingRegistry()
{
if (tmr == null)
{
tmr = new TypeMappingRegistryImpl();
}
return tmr;
}
public void setTypeMappingRegistry(TypeMappingRegistry tmr)
{
this.tmr = tmr;
}
}