1 package org.objectweb.celtix.bus.jaxws; 2 3 import java.lang.reflect.InvocationHandler ; 4 import java.lang.reflect.InvocationTargetException ; 5 import java.lang.reflect.Method ; 6 import java.util.concurrent.Future ; 7 import java.util.logging.Level ; 8 import java.util.logging.Logger ; 9 10 import javax.jws.Oneway; 11 import javax.xml.bind.JAXBContext; 12 import javax.xml.bind.JAXBException; 13 import javax.xml.validation.Schema ; 14 import javax.xml.ws.AsyncHandler; 15 import javax.xml.ws.ProtocolException; 16 import javax.xml.ws.Response; 17 import javax.xml.ws.WebServiceException; 18 import javax.xml.ws.spi.ServiceDelegate; 19 20 import org.objectweb.celtix.Bus; 21 import org.objectweb.celtix.bindings.BindingFactory; 22 import org.objectweb.celtix.bindings.ClientBinding; 23 import org.objectweb.celtix.bindings.DataBindingCallback; 24 import org.objectweb.celtix.common.logging.LogUtils; 25 import org.objectweb.celtix.configuration.Configuration; 26 import org.objectweb.celtix.context.ObjectMessageContext; 27 import org.objectweb.celtix.ws.addressing.EndpointReferenceType; 28 import org.objectweb.celtix.wsdl.EndpointReferenceUtils; 29 30 public final class EndpointInvocationHandler extends BindingProviderImpl implements InvocationHandler 31 { 32 private static final Logger LOG = LogUtils.getL7dLogger(EndpointInvocationHandler.class); 33 private static final String METHOD = EndpointInvocationHandler.class.getName() + ".METHOD"; 34 35 36 private final ClientBinding clientBinding; 37 private final Class <?> portTypeInterface; 38 private final Bus bus; 39 private JAXBContext context; 40 private Schema schema; 41 private final ServiceDelegate service; 42 43 public EndpointInvocationHandler(Bus b, EndpointReferenceType reference, 44 ServiceDelegate s, Configuration configuration, Class <?> portSEI) { 45 bus = b; 46 service = s; 47 portTypeInterface = portSEI; 48 clientBinding = createBinding(reference, configuration); 49 setBinding(clientBinding.getBinding()); 50 try { 51 context = JAXBEncoderDecoder.createJAXBContextForClass(portSEI); 52 53 Boolean enableSchemaValidation = configuration.getObject(Boolean .class, 54 "enableSchemaValidation"); 55 if (enableSchemaValidation != null && enableSchemaValidation.booleanValue()) { 56 LOG.fine("port schema validation enabled"); 57 schema = EndpointReferenceUtils.getSchema(b.getWSDLManager(), reference); 58 } 59 } catch (JAXBException ex1) { 60 ex1.printStackTrace(); 62 context = null; 63 } 64 } 65 66 public Object invoke(Object proxy, Method method, Object args[]) throws Exception { 67 68 LOG.info("EndpointInvocationHandler: invoke"); 69 70 if (portTypeInterface.equals(method.getDeclaringClass())) { 71 return invokeSEIMethod(proxy, method, args); 72 } 73 74 try { 75 return method.invoke(this, args); 76 } catch (InvocationTargetException ite) { 77 LOG.log(Level.SEVERE, "BINDING_PROVIDER_METHOD_EXC", method.getName()); 78 if (WebServiceException.class.isAssignableFrom(ite.getCause().getClass())) { 79 throw (WebServiceException)ite.getCause(); 80 } 81 throw new WebServiceException(ite.getCause()); 82 } catch (Exception ex) { 83 LOG.log(Level.SEVERE, "BINDING_PROVIDER_METHOD_EXC", method.getName()); 84 throw new WebServiceException(ex); 85 } 86 } 87 88 private Object invokeSEIMethod(Object proxy, Method method, Object parameters[]) 89 throws Exception { 90 91 ObjectMessageContext objMsgContext = clientBinding.createObjectContext(); 92 objMsgContext.putAll(getRequestContext()); 93 94 95 objMsgContext.put(ObjectMessageContext.REQUEST_PROXY, proxy); 96 97 objMsgContext.setMessageObjects(parameters); 98 objMsgContext.put(METHOD, method); 99 objMsgContext.put(ObjectMessageContext.METHOD_OBJ, method); 100 101 boolean isOneway = (method.getAnnotation(Oneway.class) != null) ? true : false; 102 boolean isAsync = method.getName().endsWith("Async"); 103 104 105 if (isOneway) { 106 clientBinding.invokeOneWay(objMsgContext, 107 new JAXBDataBindingCallback(method, 108 DataBindingCallback.Mode.PARTS, 109 context, 110 schema)); 111 } else if (isAsync) { 112 Future <ObjectMessageContext> objMsgContextAsynch = 113 clientBinding.invokeAsync(objMsgContext, 114 new JAXBDataBindingCallback(method, 115 DataBindingCallback.Mode.PARTS, 116 context, 117 schema) 118 , service.getExecutor()); 119 120 Response<?> r = new AsyncResponse<Object >(objMsgContextAsynch, Object .class); 121 if (parameters.length > 0 && parameters[parameters.length - 1] instanceof AsyncHandler) { 122 AsyncCallbackFuture f = new AsyncCallbackFuture(r, 124 (AsyncHandler)parameters[parameters.length - 1]); 125 service.getExecutor().execute(f); 127 return f; 128 129 130 } else { 131 return r; 132 } 133 134 135 } else { 136 objMsgContext = clientBinding.invoke(objMsgContext, 137 new JAXBDataBindingCallback(method, 138 DataBindingCallback.Mode.PARTS, 139 context, 140 schema)); 141 } 142 143 populateResponseContext(objMsgContext); 144 145 if (objMsgContext.getException() != null) { 146 LOG.log(Level.INFO, "ENDPOINT_INVOCATION_FAILED", method.getName()); 147 if (isValidException(objMsgContext)) { 148 throw (Exception )objMsgContext.getException(); 149 } else { 150 throw new ProtocolException(objMsgContext.getException()); 151 } 152 } 153 154 return objMsgContext.getReturn(); 155 } 156 157 protected ClientBinding createBinding(EndpointReferenceType ref, Configuration c) { 158 159 ClientBinding binding = null; 160 try { 161 162 String bindingId = c.getString("bindingId"); 163 BindingFactory factory = bus.getBindingManager().getBindingFactory(bindingId); 164 assert factory != null : "unable to find binding factory for " + bindingId; 165 binding = factory.createClientBinding(ref); 166 } catch (Exception ex) { 167 throw new WebServiceException(ex); 168 } 169 170 binding.configureSystemHandlers(c); 171 return binding; 172 } 173 174 private boolean isValidException(ObjectMessageContext objContext) { 175 Method method = (Method )objContext.get(METHOD); 176 Throwable t = objContext.getException(); 177 178 boolean val = ProtocolException.class.isAssignableFrom(t.getClass()) 179 || WebServiceException.class.isAssignableFrom(t.getClass()); 180 181 if (!val) { 182 for (Class <?> clazz : method.getExceptionTypes()) { 183 if (clazz.isAssignableFrom(t.getClass())) { 184 val = true; 185 break; 186 } 187 } 188 } 189 190 return val; 191 } 192 } 193 | Popular Tags |