Methods Summary |
---|
public void | addOperationDesc(OperationDesc operation)
operations.add(operation);
operation.setParent(this);
if (name2OperationsMap == null) {
name2OperationsMap = new HashMap();
}
// Add name to name2Operations Map
String name = operation.getName();
ArrayList overloads = (ArrayList)name2OperationsMap.get(name);
if (overloads == null) {
overloads = new ArrayList();
name2OperationsMap.put(name, overloads);
} else if (JavaUtils.isTrue(
AxisProperties.getProperty(Constants.WSIBP11_COMPAT_PROPERTY)) &&
overloads.size() > 0) {
throw new RuntimeException(Messages.getMessage("noOverloadedOperations", name));
}
overloads.add(operation);
|
private int | checkMessageMethod(java.lang.reflect.Method method)
// Collect the types so we know what we're dealing with in the target
// 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] == SOAPBodyElement[].class) &&
(method.getReturnType() == SOAPBodyElement[].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] == SOAPEnvelope.class) &&
(params[1] == SOAPEnvelope.class)) ||
((params[0] == javax.xml.soap.SOAPEnvelope.class) &&
(params[1] == javax.xml.soap.SOAPEnvelope.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;
|
private void | createFaultMetadata(java.lang.reflect.Method method, OperationDesc operation)
// Create Exception Types
Class[] exceptionTypes = method.getExceptionTypes();
for (int i=0; i < exceptionTypes.length; i++) {
// Every remote method declares a java.rmi.RemoteException
// Only interested in application specific exceptions.
// Ignore java and javax package exceptions.
Class ex = exceptionTypes[i];
if (ex != java.rmi.RemoteException.class &&
ex != org.apache.axis.AxisFault.class &&
!ex.getName().startsWith("java.") &&
!ex.getName().startsWith("javax.")) {
// For JSR 101 v.1.0, there is a simple fault mapping
// and a complexType fault mapping...both mappings
// generate a class that extends (directly or indirectly)
// Exception.
// When converting java back to wsdl it is not possible
// to determine which way to do the mapping,
// so it is always mapped back using the complexType
// fault mapping because it is more useful (i.e. it
// establishes a hierarchy of exceptions). Note that this
// will not cause any roundtripping problems.
// Rich
/* Old Simple Type Mode
Field[] f = ex.getDeclaredFields();
ArrayList exceptionParams = new ArrayList();
for (int j = 0; j < f.length; j++) {
int mod = f[j].getModifiers();
if (Modifier.isPublic(mod) &&
!Modifier.isStatic(mod)) {
QName qname = new QName("", f[j].getName());
QName typeQName = tm.getTypeQName(f[j].getType());
ParameterDesc param = new ParameterDesc(qname,
ParameterDesc.IN,
typeQName);
param.setJavaType(f[j].getType());
exceptionParams.add(param);
}
}
String pkgAndClsName = ex.getName();
FaultDesc fault = new FaultDesc();
fault.setName(pkgAndClsName);
fault.setParameters(exceptionParams);
operation.addFault(fault);
*/
FaultDesc fault = operation.getFaultByClass(ex, false);
boolean isNew;
// If we didn't find one, create a new one
if (fault == null) {
fault = new FaultDesc();
isNew = true;
} else {
isNew = false;
}
// Try to fil in any parts of the faultDesc that aren't there
// XMLType
QName xmlType = fault.getXmlType();
if (xmlType == null) {
fault.setXmlType(getTypeMapping().getTypeQName(ex));
}
// Name and Class Name
String pkgAndClsName = ex.getName();
if (fault.getClassName() == null) {
fault.setClassName(pkgAndClsName);
}
if (fault.getName() == null) {
String name = pkgAndClsName.substring(
pkgAndClsName.lastIndexOf('.") + 1,
pkgAndClsName.length());
fault.setName(name);
}
// Parameters
// We add a single parameter which points to the type
if (fault.getParameters() == null) {
if (xmlType == null) {
xmlType = getTypeMapping().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);
}
// QName
if (fault.getQName() == null) {
fault.setQName(new QName(pkgAndClsName));
}
if (isNew) {
// Add the fault to the operation
operation.addFault(fault);
}
}
}
|
private void | createOperationForMethod(java.lang.reflect.Method method)Make an OperationDesc from a Java method.
In the absence of deployment metadata, this code will introspect a
Method and create an appropriate OperationDesc. If the class
implements the Skeleton interface, we will use the metadata from there
in constructing the OperationDesc. If not, we use parameter names
from the bytecode debugging info if available, or "in0", "in1", etc.
if not.
// If we've already got it, never mind
if (method2OperationMap.get(method) != null) {
return;
}
Class [] paramTypes = method.getParameterTypes();
// And if we've already got an exact match (i.e. an override),
// never mind
ArrayList overloads = name2OperationsMap == null ? null :
(ArrayList)name2OperationsMap.get(method.getName());
if (overloads != null && !overloads.isEmpty()) {
// Search each OperationDesc that already has a Method
// associated with it, and check for parameter type equivalence.
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 we got all the way through, we have a match.
if (j == others.length)
return;
}
}
}
}
boolean isWSICompliant = JavaUtils.isTrue(
AxisProperties.getProperty(Constants.WSIBP11_COMPAT_PROPERTY));
// Make an OperationDesc, fill in common stuff
OperationDesc operation = new OperationDesc();
// If we're WS-I compliant, we can't have overloaded operation names.
// If we find duplicates, we generate unique names for them and map
// those names to the correct Method.
String name = method.getName();
if (isWSICompliant && name2OperationsMap != null) {
Collection methodNames = name2OperationsMap.keySet();
name = JavaUtils.getUniqueValue(methodNames, name);
}
operation.setName(name);
String defaultNS = "";
if (namespaceMappings != null && !namespaceMappings.isEmpty()) {
// If we have a default namespace mapping, require callers to
// use that namespace.
defaultNS = (String)namespaceMappings.get(0);
}
if(defaultNS.length() == 0) {
defaultNS = Namespaces.makeNamespace(method.getDeclaringClass().getName());
}
operation.setElementQName(new QName(defaultNS, name));
operation.setMethod(method);
// If this is a MESSAGE style service, set up the OperationDesc
// appropriately.
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 {
// For other styles, continue here.
Class retClass = method.getReturnType();
operation.setReturnClass(retClass);
QName typeQName = getTypeQName(retClass);
operation.setReturnType(typeQName);
String [] paramNames = getParamNames(method);
for (int k = 0; k < paramTypes.length; k++) {
Class type = paramTypes[k];
ParameterDesc paramDesc = new ParameterDesc();
// param should be unqualified if we're using rpc style,
// or should use the operation's namespace if its document style
String paramNamespace = (this.style == Style.RPC ? "" : operation.getElementQName().getNamespaceURI());
// If we have a name for this param, use it, otherwise call
// it "in*"
if (paramNames != null && paramNames[k] != null &&
paramNames[k].length()>0) {
paramDesc.setQName(new QName(paramNamespace, paramNames[k]));
} else {
paramDesc.setQName(new QName(paramNamespace, "in" + k));
}
// If it's a Holder, mark it INOUT, and set the XML type QName
// to the held type. Otherwise it's IN.
Class heldClass = JavaUtils.getHolderValueType(type);
if (heldClass != null) {
paramDesc.setMode(ParameterDesc.INOUT);
paramDesc.setTypeQName(getTypeQName(heldClass));
} else {
paramDesc.setMode(ParameterDesc.IN);
paramDesc.setTypeQName(getTypeQName(type));
}
paramDesc.setJavaType(type);
operation.addParameter(paramDesc);
}
}
createFaultMetadata(method, operation);
addOperationDesc(operation);
method2OperationMap.put(method, operation);
|
private void | createOperationsForName(java.lang.Class implClass, java.lang.String methodName)Look for methods matching this name, and for each one, create an
OperationDesc (if it's not already in our list).
TODO: Make this more efficient
// If we're a Skeleton deployment, skip the statics.
if (isSkeletonClass) {
if (methodName.equals("getOperationDescByName") ||
methodName.equals("getOperationDescs"))
return;
}
Method [] methods = getMethods(implClass);
for (int i = 0; i < methods.length; i++) {
Method method = methods[i];
if (Modifier.isPublic(method.getModifiers()) &&
method.getName().equals(methodName) &&
!isServiceLifeCycleMethod(implClass, method)) {
createOperationForMethod(method);
}
}
Class superClass = implClass.getSuperclass();
if (superClass != null &&
!superClass.getName().startsWith("java.") &&
!superClass.getName().startsWith("javax.") &&
(stopClasses == null ||
!stopClasses.contains(superClass.getName()))) {
createOperationsForName(superClass, methodName);
}
|
public java.util.List | getAllowedMethods()
return allowedMethods;
|
public java.lang.String | getDefaultNamespace()
if (namespaceMappings == null || namespaceMappings.isEmpty())
return null;
return (String)namespaceMappings.get(0);
|
public java.util.List | getDisallowedMethods()
return disallowedMethods;
|
public java.lang.String | getDocumentation()get the documentation for the service
return documentation;
|
public java.lang.String | getEndpointURL()
return endpointURL;
|
public java.lang.Class | getImplClass()
return implClass;
|
private java.lang.reflect.Method[] | getMethods(java.lang.Class implClass)
if (implClass.isInterface()){
// only return methods that are not part of start classes
List methodsList = new ArrayList();
Method[] methods = implClass.getMethods();
if (methods != null) {
for (int i = 0; i < methods.length; i++) {
String declaringClass = methods[i].getDeclaringClass().getName();
if (!declaringClass.startsWith("java.") &&
!declaringClass.startsWith("javax.")) {
methodsList.add(methods[i]);
}
}
}
return (Method[])methodsList.toArray(new Method[]{});
} else {
return implClass.getDeclaredMethods();
}
|
public java.lang.String | getName()the name of the service
return name;
|
public OperationDesc | getOperationByElementQName(javax.xml.namespace.QName qname)Map an XML QName to an operation. Returns the first one it finds
in the case of mulitple matches.
OperationDesc [] overloads = getOperationsByQName(qname);
// Return the first one....
if ((overloads != null) && overloads.length > 0)
return overloads[0];
return null;
|
public OperationDesc | getOperationByName(java.lang.String methodName)Return an operation matching the given method name. Note that if we
have multiple overloads for this method, we will return the first one.
// If we need to load up operations from introspection data, do it.
// This returns fast if we don't need to do anything, so it's not very
// expensive.
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 java.util.ArrayList | getOperations()get all the operations as a list of OperationDescs.
this method triggers an evaluation of the valid operations by
introspection, so use sparingly
loadServiceDescByIntrospection(); // Just in case...
return operations;
|
public OperationDesc[] | getOperationsByName(java.lang.String methodName)get all overloaded operations by name
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[] | getOperationsByQName(javax.xml.namespace.QName qname)Return all operations which match this QName (i.e. get all the
overloads)
// Look in our mapping of QNames -> operations.
// But first, let's make sure we've initialized said mapping....
initQNameMap();
ArrayList overloads = (ArrayList)qname2OperationsMap.get(qname);
if (overloads == null) {
// Nothing specifically matching this QName.
if (name2OperationsMap != null) {
if ((isWrapped() ||
((style == Style.MESSAGE) &&
(getDefaultNamespace() == null)))) {
// Try ignoring the namespace....?
overloads = (ArrayList) name2OperationsMap.get(qname.getLocalPart());
} else {
// TODO the above code is weird: a JavaServiceDesc can be document or rpc and
// still define a WSDL operation using a wrapper style mapping.
// The following code handles this case.
Object ops = name2OperationsMap.get(qname.getLocalPart());
if (ops != null) {
overloads = new ArrayList((Collection) ops);
for (Iterator iter = overloads.iterator(); iter.hasNext();) {
OperationDesc operationDesc = (OperationDesc) iter.next();
if (Style.WRAPPED != operationDesc.getStyle()) {
iter.remove();
}
}
}
}
}
// Handle the case where a single Message-style operation wants
// to accept anything.
if ((style == Style.MESSAGE) && (messageServiceDefaultOp != null))
return new OperationDesc [] { messageServiceDefaultOp };
if (overloads == null)
return null;
}
getSyncedOperationsForName(implClass,
((OperationDesc)overloads.get(0)).getName());
// Sort the overloads by number of arguments - prevents us calling methods
// with more parameters than supplied in the request (with missing parameters
// defaulted to null) when a perfectly good method exists with exactly the
// supplied parameters.
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 java.lang.String[] | getParamNames(java.lang.reflect.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 java.lang.Object | getProperty(java.lang.String name)
if (properties == null)
return null;
return properties.get(name);
|
public java.util.ArrayList | getStopClasses()
return stopClasses;
|
public org.apache.axis.constants.Style | getStyle()What kind of service is this?
return style;
|
private void | getSyncedOperationsForName(java.lang.Class implClass, java.lang.String methodName)Makes sure we have completely synchronized OperationDescs with
the implementation class.
// If we're a Skeleton deployment, skip the statics.
if (isSkeletonClass) {
if (methodName.equals("getOperationDescByName") ||
methodName.equals("getOperationDescs"))
return;
}
// If we have no implementation class, don't worry about it (we're
// probably on the client)
if (implClass == null)
return;
// If we're done introspecting, or have completed this method, return
if (completedNames == null || completedNames.contains(methodName))
return;
// Skip it if it's not a sanctioned method name
if ((allowedMethods != null) &&
!allowedMethods.contains(methodName))
return;
if ((disallowedMethods != null) &&
disallowedMethods.contains(methodName))
return;
// If we're a skeleton class, make sure we don't already have any
// OperationDescs for this name (as that might cause conflicts),
// then load them up from the Skeleton class.
if (isSkeletonClass && !haveAllSkeletonMethods) {
// FIXME : Check for existing ones and fault if found
if (skelMethod == null) {
// Grab metadata from the Skeleton for parameter info
try {
skelMethod = implClass.getDeclaredMethod(
"getOperationDescByName",
new Class [] { String.class });
} catch (NoSuchMethodException e) {
} catch (SecurityException e) {
}
if (skelMethod == null) {
// FIXME : Throw an error?
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) {
if(log.isDebugEnabled()) {
log.debug(Messages.getMessage("exception00"), e);
}
return;
} catch (IllegalArgumentException e) {
if(log.isDebugEnabled()) {
log.debug(Messages.getMessage("exception00"), e);
}
return;
} catch (InvocationTargetException e) {
if(log.isDebugEnabled()) {
log.debug(Messages.getMessage("exception00"), e);
}
return;
}
}
// OK, go find any current OperationDescs for this method name and
// make sure they're synced with the actual class.
if (name2OperationsMap != null) {
ArrayList currentOverloads =
(ArrayList)name2OperationsMap.get(methodName);
if (currentOverloads != null) {
// For each one, sync it to the implementation class' methods
for (Iterator i = currentOverloads.iterator(); i.hasNext();) {
OperationDesc oper = (OperationDesc) i.next();
if (oper.getMethod() == null) {
syncOperationToClass(oper, implClass);
}
}
}
}
// Now all OperationDescs from deployment data have been completely
// filled in. So we now make new OperationDescs for any method
// overloads which were not covered above.
// NOTE : This is the "lenient" approach, which allows you to
// specify one overload and still get the others by introspection.
// We could equally well return above if we found OperationDescs,
// and have a rule that if you specify any overloads, you must specify
// all the ones you want accessible.
createOperationsForName(implClass, methodName);
// Note that we never have to look at this method name again.
completedNames.add(methodName);
|
public TypeMapping | getTypeMapping()
if(tm == null) {
return DefaultTypeMappingImpl.getSingletonDelegate();
// throw new RuntimeException(Messages.getMessage("noDefaultTypeMapping00"));
}
return tm;
|
public TypeMappingRegistry | getTypeMappingRegistry()
if (tmr == null) {
tmr = new TypeMappingRegistryImpl(false);
}
return tmr;
|
private javax.xml.namespace.QName | getTypeQName(java.lang.Class javaClass)
QName typeQName;
TypeMapping tm = getTypeMapping();
if (style == Style.RPC) {
typeQName = tm.getTypeQName(javaClass);
} else {
typeQName = tm.getTypeQNameExact(javaClass);
if (typeQName == null && javaClass.isArray()) {
typeQName = tm.getTypeQName(javaClass.getComponentType());
} else {
typeQName = tm.getTypeQName(javaClass);
}
}
return typeQName;
|
private java.lang.String | getUniqueOperationName(java.lang.String name)
int i = 1;
String candidate;
do {
candidate = name + i++;
} while (name2OperationsMap.get(candidate) != null);
return candidate;
|
public org.apache.axis.constants.Use | getUse()What kind of use is this?
return use;
|
public java.lang.String | getWSDLFile()the wsdl file of the service.
When null, it means that the wsdl should be autogenerated
return wsdlFileName;
|
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);
}
}
|
public boolean | isInitialized()
return implClass != null;
|
private boolean | isServiceLifeCycleMethod(java.lang.Class implClass, java.lang.reflect.Method m)Is this method from ServiceLifeCycle interface?
if(javax.xml.rpc.server.ServiceLifecycle.class.isAssignableFrom(implClass)) {
String methodName = m.getName();
if(methodName.equals("init")) {
// Check if the method signature is
// "public abstract void init(Object context) throws ServiceException;"
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")){
// Check if the method signature is
// "public abstract void destroy();"
Class[] classes = m.getParameterTypes();
if(classes != null &&
classes.length == 0 &&
m.getReturnType() == Void.TYPE) {
return true;
}
}
}
return false;
|
public boolean | isWrapped()Determine whether or not this is a "wrapped" invocation, i.e. whether
the outermost XML element of the "main" body element represents a
method call, with the immediate children of that element representing
arguments to the method.
return ((style == Style.RPC) ||
(style == Style.WRAPPED));
|
public void | loadServiceDescByIntrospection()Fill in a service description by introspecting the implementation
class.
loadServiceDescByIntrospection(implClass);
// Setting this to null means there is nothing more to do, and it
// avoids future string compares.
completedNames = null;
|
public void | loadServiceDescByIntrospection(java.lang.Class implClass)Fill in a service description by introspecting the implementation
class.
if (introspectionComplete || implClass == null) {
return;
}
// set the implementation class for the service description
this.implClass = implClass;
if (Skeleton.class.isAssignableFrom(implClass)) {
isSkeletonClass = true;
loadSkeletonOperations();
}
/** If the class knows what it should be exporting,
* respect its wishes.
*/
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) {
// No problem, just continue without...
}
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);
// All operations should now be synchronized. Check it.
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;
|
public void | loadServiceDescByIntrospection(java.lang.Class cls, TypeMapping tm)Fill in a service description by introspecting the implementation
class. This version takes the implementation class and the in-scope
TypeMapping.
// Should we complain if the implClass changes???
implClass = cls;
this.tm = tm;
if (Skeleton.class.isAssignableFrom(implClass)) {
isSkeletonClass = true;
loadSkeletonOperations();
}
loadServiceDescByIntrospection();
|
private void | loadServiceDescByIntrospectionRecursive(java.lang.Class implClass)Recursive helper class for loadServiceDescByIntrospection
if (Skeleton.class.equals(implClass)) {
return;
}
Method [] methods = getMethods(implClass);
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);
}
}
|
private void | loadSkeletonOperations()
Method method = null;
try {
method = implClass.getDeclaredMethod("getOperationDescs",
new Class [] {});
} catch (NoSuchMethodException e) {
} catch (SecurityException e) {
}
if (method == null) {
// FIXME : Throw an error?
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) {
if(log.isDebugEnabled()) {
log.debug(Messages.getMessage("exception00"), e);
}
return;
} catch (IllegalArgumentException e) {
if(log.isDebugEnabled()) {
log.debug(Messages.getMessage("exception00"), e);
}
return;
} catch (InvocationTargetException e) {
if(log.isDebugEnabled()) {
log.debug(Messages.getMessage("exception00"), e);
}
return;
}
haveAllSkeletonMethods = true;
|
public void | removeOperationDesc(OperationDesc operation)
operations.remove(operation);
operation.setParent(null);
if (name2OperationsMap != null) {
String name = operation.getName();
ArrayList overloads = (ArrayList)name2OperationsMap.get(name);
if (overloads != null) {
overloads.remove(operation);
if (overloads.size() == 0) {
name2OperationsMap.remove(name);
}
}
}
if (qname2OperationsMap != null) {
QName qname = operation.getElementQName();
ArrayList list = (ArrayList)qname2OperationsMap.get(qname);
if (list != null) {
list.remove(operation);
}
}
if (method2OperationMap != null) {
Method method = operation.getMethod();
if (method != null) {
method2OperationMap.remove(method);
}
}
|
public void | setAllowedMethods(java.util.List allowedMethods)
this.allowedMethods = allowedMethods;
|
public void | setDefaultNamespace(java.lang.String namespace)
if (namespaceMappings == null)
namespaceMappings = new ArrayList();
namespaceMappings.add(0, namespace);
|
public void | setDisallowedMethods(java.util.List disallowedMethods)
this.disallowedMethods = disallowedMethods;
|
public void | setDocumentation(java.lang.String documentation)set the documentation for the service
this.documentation = documentation;
|
public void | setEndpointURL(java.lang.String endpointURL)
this.endpointURL = endpointURL;
|
public void | setImplClass(java.lang.Class implClass)set the implementation class
Warning: You cannot call getInitializedServiceDesc() after setting this
as it uses this to indicate its work has already been done.
if (this.implClass != null)
throw new IllegalArgumentException(
Messages.getMessage("implAlreadySet"));
this.implClass = implClass;
if (Skeleton.class.isAssignableFrom(implClass)) {
isSkeletonClass = true;
loadSkeletonOperations();
}
|
public void | setName(java.lang.String name)the name of the service
this.name = name;
|
public void | setNamespaceMappings(java.util.List namespaces)
namespaceMappings = namespaces;
|
public void | setProperty(java.lang.String name, java.lang.Object value)
if (properties == null) {
properties = new HashMap();
}
properties.put(name, value);
|
public void | setStopClasses(java.util.ArrayList stopClasses)
this.stopClasses = stopClasses;
|
public void | setStyle(org.apache.axis.constants.Style style)
this.style = style;
if (!useSet) {
// Use hasn't been explicitly set, so track style
use = style == Style.RPC ? Use.ENCODED : Use.LITERAL;
}
|
public void | setTypeMapping(TypeMapping tm)
this.tm = tm;
|
public void | setTypeMappingRegistry(TypeMappingRegistry tmr)
this.tmr = tmr;
|
public void | setUse(org.apache.axis.constants.Use use)
useSet = true;
this.use = use;
|
public void | setWSDLFile(java.lang.String wsdlFileName)set the wsdl file of the service; this causes the named
file to be returned on a ?wsdl, probe, not introspection
generated wsdl.
this.wsdlFileName = wsdlFileName;
|
private void | syncOperationToClass(OperationDesc oper, java.lang.Class implClass)Synchronize an existing OperationDesc to a java.lang.Method.
This method is used when the deployer has specified operation metadata
and we want to match that up with a real java Method so that the
Operation-level dispatch carries us all the way to the implementation.
Search the declared methods on the implementation class to find one
with an argument list which matches our parameter list.
// ------------------------------------------------
// Developer Note:
//
// The goal of the sync code is to associate
// the OperationDesc/ParamterDesc with the
// target Method. There are a number of ways to get to this
// point depending on what information
// is available. Here are the main scenarios:
//
// A) Deployment with wsdd (non-skeleton):
// * OperationDesc/ParameterDesc loaded from deploy.wsdd
// * Loaded ParameterDesc does not have javaType,
// so it is discovered using the TypeMappingRegistry
// (also loaded via deploy.wsdd) and the
// typeQName specified by the ParameterDesc.
// * Sync occurs using the discovered
// javaTypes and the javaTypes of the Method
// parameters
//
// B) Deployment with no wsdd OperationDesc info (non-skeleton):
// * Implementation Class introspected to build
// OperationDesc/ParameterDesc.
// * ParameterDesc is known via introspection.
// * ParameterDesc are discovered using javaType
// and TypeMappingRegistry.
// * Sync occurs using the introspected
// javaTypes and the javaTypes of the Method
// parameters
//
// C) Deployment with wsdd (skeleton):
// * OperationDesc/ParameterDesc loaded from the Skeleton
// * In this scenario the ParameterDescs' already
// have javaTypes (see E below).
// * Sync occurs using the ParameterDesc
// javaTypes and the javaTypes of the Method
// parameters.
//
// D) Commandline Java2WSDL loading non-Skeleton Class/Interface
// * Class/Interface introspected to build
// OperationDesc/ParameterDesc.
// * The javaTypes of the ParameterDesc are set using introspection.
// * typeQNames are determined for built-in types using
// from the default TypeMappingRegistry. Other
// typeQNames are guessed from the javaType. Note
// that there is no loaded TypeMappingRegistry.
// * Sync occurs using the ParameterDesc
// javaTypes and the javaTypes of the Method
// parameters.
//
// E) Commandline Java2WSDL loading Skeleton Class
// * OperationDesc/ParameterDesc loaded from Skeleton
// * Each ParameterDesc has an appropriate typeQName
// * Each ParameterDesc also has a javaType, which is
// essential for sync'ing up with the
// method since there is no loaded TypeMappingRegistry.
// * Syncronization occurs using the ParameterDesc
// javaTypes and the javaTypes of the Method
// parameters.
//
// So in each scenario, the ultimate sync'ing occurs
// using the javaTypes of the ParameterDescs and the
// javaTypes of the Method parameters.
//
// ------------------------------------------------
// If we're already mapped to a Java method, no need to do anything.
if (oper.getMethod() != null)
return;
// Find the method. We do this once for each Operation.
Method[] methods = getMethods(implClass);
// A place to keep track of possible matches
Method possibleMatch = null;
for (int i = 0; i < methods.length; i++) {
Method method = methods[i];
if (Modifier.isPublic(method.getModifiers()) &&
method.getName().equals(oper.getName()) &&
method2OperationMap.get(method) == null) {
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!");
}
oper.setMessageOperationStyle(messageOperType);
// Don't bother checking params if we're message style
possibleMatch = method;
break;
}
// Check params
Class [] paramTypes = method.getParameterTypes();
if (paramTypes.length != oper.getNumParams())
continue;
int j;
boolean conversionNecessary = false;
for (j = 0; j < paramTypes.length; j++) {
Class type = paramTypes[j];
Class actualType = type;
if (Holder.class.isAssignableFrom(type)) {
actualType = JavaUtils.getHolderValueType(type);
}
ParameterDesc param = oper.getParameter(j);
QName typeQName = param.getTypeQName();
if (typeQName == null) {
// No typeQName is available. Set it using
// information from the actual type.
// (Scenarios B and D)
// There is no need to try and match with
// the Method parameter javaType because
// the ParameterDesc is being constructed
// by introspecting the Method.
typeQName = getTypeMapping().getTypeQName(actualType);
param.setTypeQName(typeQName);
} else {
// A type qname is available.
// Ensure that the ParameterDesc javaType
// is convertable to the Method parameter type
//
// Use the available javaType (Scenarios C and E)
// or get one from the TMR (Scenario A).
Class paramClass = param.getJavaType();
if (paramClass != null &&
JavaUtils.getHolderValueType(paramClass) != null) {
paramClass = JavaUtils.getHolderValueType(paramClass);
}
if (paramClass == null) {
paramClass = getTypeMapping().getClassForQName(param.getTypeQName(),
type);
}
if (paramClass != null) {
// This is a match if the paramClass is somehow
// convertable to the "real" parameter type. If not,
// break out of this loop.
if (!JavaUtils.isConvertable(paramClass, actualType)) {
break;
}
if (!actualType.isAssignableFrom(paramClass)) {
// This doesn't fit without conversion
conversionNecessary = true;
}
}
}
// In all scenarios the ParameterDesc javaType is set to
// match the javaType in the corresponding parameter.
// This is essential.
param.setJavaType(type);
}
if (j != paramTypes.length) {
// failed.
continue;
}
// This is our latest possibility
possibleMatch = method;
// If this is exactly it, stop now. Otherwise keep looking
// just in case we find a better match.
if (!conversionNecessary) {
break;
}
}
}
// At this point, we may or may not have a possible match.
// FIXME : Should we prefer an exact match from a base class over
// a with-conversion match from the target class? If so,
// we'll need to change the logic below.
if (possibleMatch != null) {
Class returnClass = possibleMatch.getReturnType();
oper.setReturnClass(returnClass);
QName returnType = oper.getReturnType();
if (returnType == null) {
oper.setReturnType(getTypeMapping().getTypeQName(returnClass));
}
// Do the faults
createFaultMetadata(possibleMatch, oper);
oper.setMethod(possibleMatch);
method2OperationMap.put(possibleMatch, oper);
return;
}
// Didn't find a match. Try the superclass, if appropriate
Class superClass = implClass.getSuperclass();
if (superClass != null &&
!superClass.getName().startsWith("java.") &&
!superClass.getName().startsWith("javax.") &&
(stopClasses == null ||
!stopClasses.contains(superClass.getName()))) {
syncOperationToClass(oper, superClass);
}
// Exception if sync fails to find method for operation
if (oper.getMethod() == null) {
InternalException ie =
new InternalException(Messages.getMessage("serviceDescOperSync00",
oper.getName(),
implClass.getName()));
throw ie;
}
|