// SOAP binding (doc/lit/wrapped|bare or rpc/lit)
SOAPBinding soapBinding = clazz.getAnnotation(SOAPBinding.class);
for (Iterator<Operation> it = contract.getOperations().iterator(); it.hasNext();) {
final JavaOperation operation = (JavaOperation)it.next();
final Method method = operation.getJavaMethod();
introspectFaultTypes(operation);
// SOAP binding (doc/lit/wrapped|bare or rpc/lit)
SOAPBinding methodSOAPBinding = method.getAnnotation(SOAPBinding.class);
if (methodSOAPBinding == null) {
methodSOAPBinding = soapBinding;
}
boolean documentStyle = true;
boolean bare = false;
if (methodSOAPBinding != null) {
bare = methodSOAPBinding.parameterStyle() == SOAPBinding.ParameterStyle.BARE;
if(bare) {
// For BARE parameter style, the data won't be unwrapped
// The wrapper should be null
operation.setWrapperStyle(false);
}
documentStyle = methodSOAPBinding.style() == Style.DOCUMENT;
}
String operationName = operation.getName();
// WebMethod
WebMethod webMethod = method.getAnnotation(WebMethod.class);
if (webMethod != null) {
if (webMethod.exclude()) {
// Exclude the method
it.remove();
continue;
}
operationName = getValue(webMethod.operationName(), operationName);
operation.setName(operationName);
operation.setAction(webMethod.action());
}
// Is one way?
Oneway oneway = method.getAnnotation(Oneway.class);
if (oneway != null) {
// JSR 181
assert method.getReturnType() == void.class;
operation.setNonBlocking(true);
}
// Handle BARE mapping
if (bare) {
for (int i = 0; i < method.getParameterTypes().length; i++) {
WebParam param = getAnnotation(method, i, WebParam.class);
if (param != null) {
String ns = getValue(param.targetNamespace(), tns);
// Default to <operationName> for doc-bare
String name = getValue(param.name(), documentStyle ? operationName : "arg" + i);
QName element = new QName(ns, name);
Object logical = operation.getInputType().getLogical().get(i).getLogical();
if (logical instanceof XMLType) {
((XMLType)logical).setElementName(element);
}
operation.getParameterModes().set(i, getParameterMode(param.mode()));
}
ParameterMode mode = operation.getParameterModes().get(i);
}
WebResult result = method.getAnnotation(WebResult.class);
if (result != null) {
String ns = getValue(result.targetNamespace(), tns);
// Default to <operationName>Response for doc-bare
String name = getValue(result.name(), documentStyle ? operationName + "Response" : "return");
QName element = new QName(ns, name);
if (!operation.hasReturnTypeVoid()) {
List<DataType> outputDataTypes = operation.getOutputType().getLogical();
DataType returnDataType = outputDataTypes.get(0);
if (returnDataType instanceof XMLType) {
((XMLType)returnDataType).setElementName(element);
}
}
}
// Rather than relying on null wrapper, we use a flag with a clearer meaning.
operation.setNotSubjectToWrapping(true);
} else {
RequestWrapper requestWrapper = method.getAnnotation(RequestWrapper.class);
String ns = requestWrapper == null ? tns : getValue(requestWrapper.targetNamespace(), tns);
String name =
requestWrapper == null ? operationName : getValue(requestWrapper.localName(), operationName);
String wrapperBeanName = requestWrapper == null ? "" : requestWrapper.className();
if ("".equals(wrapperBeanName)) {
wrapperBeanName = CodeGenerationHelper.getPackagePrefix(clazz) + capitalize(method.getName());
}
DataType<XMLType> inputWrapperDT = null;
final String inputWrapperClassName = wrapperBeanName;
final String inputNS = ns;
final String inputName = name;
inputWrapperDT = AccessController.doPrivileged(new PrivilegedAction<DataType<XMLType>>() {
public DataType<XMLType> run() {
try {
Class<?> wrapperClass = Class.forName(inputWrapperClassName, false, clazz.getClassLoader());
QName qname = new QName(inputNS, inputName);
DataType dt = new DataTypeImpl<XMLType>(wrapperClass, new XMLType(qname, qname));
dataBindingExtensionPoint.introspectType(dt, operation);
// TUSCANY-2505
if (dt.getLogical() instanceof XMLType) {
XMLType xmlType = (XMLType)dt.getLogical();
xmlType.setElementName(qname);
}
return dt;
} catch (ClassNotFoundException e) {
GeneratedClassLoader cl = new GeneratedClassLoader(clazz.getClassLoader());
return new GeneratedDataTypeImpl(xmlAdapterExtensionPoint, method, inputWrapperClassName, inputNS, inputName, true,
cl);
}
}
});
QName inputWrapper = inputWrapperDT.getLogical().getElementName();
ResponseWrapper responseWrapper = method.getAnnotation(ResponseWrapper.class);
ns = responseWrapper == null ? tns : getValue(responseWrapper.targetNamespace(), tns);
name =
responseWrapper == null ? operationName + "Response" : getValue(responseWrapper.localName(),
operationName + "Response");
wrapperBeanName = responseWrapper == null ? "" : responseWrapper.className();
if ("".equals(wrapperBeanName)) {
wrapperBeanName =
CodeGenerationHelper.getPackagePrefix(clazz) + capitalize(method.getName()) + "Response";
}
DataType<XMLType> outputWrapperDT = null;
final String outputWrapperClassName = wrapperBeanName;
final String outputNS = ns;
final String outputName = name;
outputWrapperDT = AccessController.doPrivileged(new PrivilegedAction<DataType<XMLType>>() {
public DataType<XMLType> run() {
try {
Class<?> wrapperClass =
Class.forName(outputWrapperClassName, false, clazz.getClassLoader());
QName qname = new QName(outputNS, outputName);
DataType dt = new DataTypeImpl<XMLType>(wrapperClass, new XMLType(qname, qname));
dataBindingExtensionPoint.introspectType(dt, operation);
// TUSCANY-2505
if (dt.getLogical() instanceof XMLType) {
XMLType xmlType = (XMLType)dt.getLogical();
xmlType.setElementName(qname);
}
return dt;
} catch (ClassNotFoundException e) {
GeneratedClassLoader cl = new GeneratedClassLoader(clazz.getClassLoader());
return new GeneratedDataTypeImpl(xmlAdapterExtensionPoint, method, outputWrapperClassName, outputNS, outputName,
false, cl);
}
}
});
QName outputWrapper = outputWrapperDT.getLogical().getElementName();
//
// Since JAX-WS specifies that the output wrapper bean consists of the return type output first followed
// by any other outputs carried in Holder(s), let's look at the output first.
//
List<ElementInfo> outputElements = new ArrayList<ElementInfo>();
WebResult result = method.getAnnotation(WebResult.class);
// Default to "" for doc-lit-wrapped && non-header
ns = result != null ? result.targetNamespace() : "";
ns = getValue(ns, documentStyle && (result == null || !result.header()) ? "" : tns);
name = result != null ? result.name() : "";
name = getValue(name, "return");
QName element = new QName(ns, name);
if (!operation.hasReturnTypeVoid()) {
Object logical = operation.getOutputType().getLogical().get(0).getLogical();
QName type = null;
if (logical instanceof XMLType) {
((XMLType)logical).setElementName(element);
type = ((XMLType)logical).getTypeName();
}
outputElements.add(new ElementInfo(element, new TypeInfo(type, false, null)));
}
List<ElementInfo> inputElements = new ArrayList<ElementInfo>();
for (int i = 0; i < method.getParameterTypes().length; i++) {
WebParam param = getAnnotation(method, i, WebParam.class);
ns = param != null ? param.targetNamespace() : "";
// Default to "" for doc-lit-wrapped && non-header
ns = getValue(ns, documentStyle && (param == null || !param.header()) ? "" : tns);
name = param != null ? param.name() : "";
name = getValue(name, "arg" + i);
element = new QName(ns, name);
Object logical = operation.getInputType().getLogical().get(i).getLogical();
QName type = null;
if (logical instanceof XMLType) {
((XMLType)logical).setElementName(element);
type = ((XMLType)logical).getTypeName();
}
if (param != null) {
ParameterMode mode = getParameterMode(param.mode());
operation.getParameterModes().set(i, mode);
}
ParameterMode mode = operation.getParameterModes().get(i);
if (mode.equals(ParameterMode.INOUT)) {
inputElements.add(new ElementInfo(element, new TypeInfo(type, false, null)));
outputElements.add(new ElementInfo(element, new TypeInfo(type, false, null)));
} else if (mode.equals(ParameterMode.OUT)) {
outputElements.add(new ElementInfo(element, new TypeInfo(type, false, null)));
} else {
inputElements.add(new ElementInfo(element, new TypeInfo(type, false, null)));
}
}
String db = inputWrapperDT != null ? inputWrapperDT.getDataBinding() : JAXB_DATABINDING;
WrapperInfo wrapperInfo =
new WrapperInfo(db, new ElementInfo(inputWrapper, null), new ElementInfo(outputWrapper, null),
inputElements, outputElements);
wrapperInfo.setInputWrapperType(inputWrapperDT);
wrapperInfo.setOutputWrapperType(outputWrapperDT);
operation.setWrapper(wrapperInfo);
}
// In both bare and wrapped cases, remove OUT-only parameters from input DataType.
// This is a key point then because it's the last time in which the number of parameters in
// Java matches the number of logical inputs. After this, things will be out of synch, for
// example the number of parameter modes won't match the number of inputs.
List<ParameterMode> parmModes = operation.getParameterModes();
List<DataType> inputDTs = operation.getInputType().getLogical();
for (int i = parmModes.size() - 1; i>=0; i--) {
if (parmModes.get(i).equals(ParameterMode.OUT)) {
inputDTs.remove(i);
}
}