blob: 8a7e71801e8dc109a7e1fecf0eee73d60ea613c1 [file] [log] [blame]
/*
* Copyright 2004,2005 The Apache Software Foundation.
* Copyright 2006 International Business Machines Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.axis2.jaxws.client.proxy;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Hashtable;
import java.util.Map;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
import javax.xml.ws.AsyncHandler;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.Response;
import javax.xml.ws.ResponseWrapper;
import org.apache.axis2.jaxws.ExceptionFactory;
import org.apache.axis2.jaxws.description.EndpointDescription;
import org.apache.axis2.jaxws.description.OperationDescription;
import org.apache.axis2.jaxws.description.ServiceDescription;
import org.apache.axis2.jaxws.handler.PortData;
import org.apache.axis2.jaxws.i18n.Messages;
/**
* ProxyDescriptor is instantiated from ProxyHandler using the Method argument.
* ProxyDescriptor will provide all the annotation details like RequestWrapper class
* ResponseWrapper Class, WebParam name etc...
*
*/
public class ProxyDescriptor {
private Class seiClazz = null;
private Method seiMethod = null;
private PortData port = null;
private ServiceDescription serviceDescription= null;
private OperationDescription operationDescription= null;
private EndpointDescription endpointDescription = null;
public ServiceDescription getServiceDescription() {
return serviceDescription;
}
public OperationDescription getOperationDescription() {
return operationDescription;
}
public EndpointDescription getEndpointDescription() {
return endpointDescription;
}
//TODO Need to put validation to check if seiMethod is null;
public ProxyDescriptor(Class seiClazz, ServiceDescription serviceDescription){
this.seiClazz = seiClazz;
this.serviceDescription = serviceDescription;
// FIXME: This probably needs to be more robust; can there be > 1 endpoints; if so, how choose which one?
this.endpointDescription = serviceDescription.getEndpointDescription(seiClazz)[0];
}
public Class getRequestWrapperClass(boolean isAsync) throws ClassNotFoundException{
String className = operationDescription.getRequestWrapperClassName();
return Class.forName(className, true, Thread.currentThread().getContextClassLoader());
}
public String getRequestWrapperClassName(){
return operationDescription.getRequestWrapperClassName();
}
public String getRequestWrapperLocalName(){
return operationDescription.getRequestWrapperLocalName();
}
public Class getResponseWrapperClass(boolean isAsync) throws ClassNotFoundException{
//TODO: Move this logic to OperationDescription. This is a hack right now.
if(isAsync){
return getReturnType(isAsync);
}
String className = operationDescription.getResponseWrapperClassName();
return Class.forName(className, true, Thread.currentThread().getContextClassLoader());
}
public String getResponseWrapperLocalName(){
return operationDescription.getResponseWrapperLocalName();
}
public String getWebResultName(boolean isAsync){
return operationDescription.getWebResultName();
}
// TODO: Move to OperationDescription?
public ArrayList<String> getParamNames(){
return new ArrayList<String>(Arrays.asList(operationDescription.getWebParamNames()));
}
public ArrayList<String> getParamtns(){
return new ArrayList<String>(Arrays.asList(operationDescription.getWebParamTNS()));
}
public String getParamtns(String name){
return operationDescription.getWebParamTNS(name);
}
public PortData getPort() {
return port;
}
public void setPort(PortData port) {
this.port = port;
}
public Method getSeiMethod() {
return seiMethod;
}
public void setSeiMethod(Method seiMethod) {
this.seiMethod = seiMethod;
operationDescription = endpointDescription.getEndpointInterfaceDescription().getOperation(seiMethod);
}
/*
* This method looks at @SOAPBindingAnnotation on clazz to look for Parameter Style
*/
public boolean isClazzDocLitBare(){
SOAPBinding.ParameterStyle style = endpointDescription.getEndpointInterfaceDescription().getSoapBindingParameterStyle();
return style == SOAPBinding.ParameterStyle.BARE;
}
public boolean isClazzDocLitWrapped(){
SOAPBinding.ParameterStyle style = endpointDescription.getEndpointInterfaceDescription().getSoapBindingParameterStyle();
return style == SOAPBinding.ParameterStyle.WRAPPED;
}
//TODO read soap binding on method too, make sure if Binding style is different from binding style in Clazz throw Exception.
public Style getBindingStyle(){
return endpointDescription.getEndpointInterfaceDescription().getSoapBindingStyle();
}
public Class getSeiClazz() {
return seiClazz;
}
public void setSeiClazz(Class seiClazz) {
this.seiClazz = seiClazz;
}
public boolean isOneWay(){
return operationDescription.isOneWay();
}
public String filterAsync(String method){
if(method.endsWith("Async")){
int index =method.lastIndexOf("Async");
return method.substring(0,index);
}
else{
return method;
}
}
/**
* In this method I am trying get the return type of the method.
* if SEI method is Async pooling implmentation then return type is actual type in Generic Response, example Response<ClassName>.
* if SEI method is Async Callback implementation then return type is actual type of method parameter type AsyncHandler, example AsyncHandler<ClassName>
* I use java reflection to get the return type.
* @param isAsync
* @return
*/
public Class getReturnType(boolean isAsync){
Class returnType = seiMethod.getReturnType();
if(isAsync){
//pooling implementation
if(Response.class.isAssignableFrom(returnType)){
Type type = seiMethod.getGenericReturnType();
ParameterizedType pType = (ParameterizedType) type;
return (Class)pType.getActualTypeArguments()[0];
}
//Callback Implementation
else{
Type[] type = seiMethod.getGenericParameterTypes();
Class parameters[]= seiMethod.getParameterTypes();
int i=0;
for(Class param:parameters){
if(AsyncHandler.class.isAssignableFrom(param)){
ParameterizedType pType = (ParameterizedType)type[i];
return (Class)pType.getActualTypeArguments()[0];
}
i++;
}
}
}
return returnType;
}
}