001: package org.objectweb.celtix.bus.jaxws;
002:
003: import java.lang.reflect.InvocationHandler;
004: import java.lang.reflect.InvocationTargetException;
005: import java.lang.reflect.Method;
006: import java.util.concurrent.Future;
007: import java.util.logging.Level;
008: import java.util.logging.Logger;
009:
010: import javax.jws.Oneway;
011: import javax.xml.bind.JAXBContext;
012: import javax.xml.bind.JAXBException;
013: import javax.xml.validation.Schema;
014: import javax.xml.ws.AsyncHandler;
015: import javax.xml.ws.ProtocolException;
016: import javax.xml.ws.Response;
017: import javax.xml.ws.WebServiceException;
018: import javax.xml.ws.spi.ServiceDelegate;
019:
020: import org.objectweb.celtix.Bus;
021: import org.objectweb.celtix.bindings.BindingFactory;
022: import org.objectweb.celtix.bindings.ClientBinding;
023: import org.objectweb.celtix.bindings.DataBindingCallback;
024: import org.objectweb.celtix.common.logging.LogUtils;
025: import org.objectweb.celtix.configuration.Configuration;
026: import org.objectweb.celtix.context.ObjectMessageContext;
027: import org.objectweb.celtix.ws.addressing.EndpointReferenceType;
028: import org.objectweb.celtix.wsdl.EndpointReferenceUtils;
029:
030: public final class EndpointInvocationHandler extends
031: BindingProviderImpl implements InvocationHandler {
032: private static final Logger LOG = LogUtils
033: .getL7dLogger(EndpointInvocationHandler.class);
034: private static final String METHOD = EndpointInvocationHandler.class
035: .getName()
036: + ".METHOD";
037:
038: private final ClientBinding clientBinding;
039: private final Class<?> portTypeInterface;
040: private final Bus bus;
041: private JAXBContext context;
042: private Schema schema;
043: private final ServiceDelegate service;
044:
045: public EndpointInvocationHandler(Bus b,
046: EndpointReferenceType reference, ServiceDelegate s,
047: Configuration configuration, Class<?> portSEI) {
048: bus = b;
049: service = s;
050: portTypeInterface = portSEI;
051: clientBinding = createBinding(reference, configuration);
052: setBinding(clientBinding.getBinding());
053: try {
054: context = JAXBEncoderDecoder
055: .createJAXBContextForClass(portSEI);
056:
057: Boolean enableSchemaValidation = configuration.getObject(
058: Boolean.class, "enableSchemaValidation");
059: if (enableSchemaValidation != null
060: && enableSchemaValidation.booleanValue()) {
061: LOG.fine("port schema validation enabled");
062: schema = EndpointReferenceUtils.getSchema(b
063: .getWSDLManager(), reference);
064: }
065: } catch (JAXBException ex1) {
066: // TODO Auto-generated catch block
067: ex1.printStackTrace();
068: context = null;
069: }
070: }
071:
072: public Object invoke(Object proxy, Method method, Object args[])
073: throws Exception {
074:
075: LOG.info("EndpointInvocationHandler: invoke");
076:
077: if (portTypeInterface.equals(method.getDeclaringClass())) {
078: return invokeSEIMethod(proxy, method, args);
079: }
080:
081: try {
082: return method.invoke(this , args);
083: } catch (InvocationTargetException ite) {
084: LOG.log(Level.SEVERE, "BINDING_PROVIDER_METHOD_EXC", method
085: .getName());
086: if (WebServiceException.class.isAssignableFrom(ite
087: .getCause().getClass())) {
088: throw (WebServiceException) ite.getCause();
089: }
090: throw new WebServiceException(ite.getCause());
091: } catch (Exception ex) {
092: LOG.log(Level.SEVERE, "BINDING_PROVIDER_METHOD_EXC", method
093: .getName());
094: throw new WebServiceException(ex);
095: }
096: }
097:
098: private Object invokeSEIMethod(Object proxy, Method method,
099: Object parameters[]) throws Exception {
100:
101: ObjectMessageContext objMsgContext = clientBinding
102: .createObjectContext();
103: objMsgContext.putAll(getRequestContext());
104:
105: objMsgContext.put(ObjectMessageContext.REQUEST_PROXY, proxy);
106:
107: objMsgContext.setMessageObjects(parameters);
108: objMsgContext.put(METHOD, method);
109: objMsgContext.put(ObjectMessageContext.METHOD_OBJ, method);
110:
111: boolean isOneway = (method.getAnnotation(Oneway.class) != null) ? true
112: : false;
113: boolean isAsync = method.getName().endsWith("Async");
114:
115: if (isOneway) {
116: clientBinding.invokeOneWay(objMsgContext,
117: new JAXBDataBindingCallback(method,
118: DataBindingCallback.Mode.PARTS, context,
119: schema));
120: } else if (isAsync) {
121: Future<ObjectMessageContext> objMsgContextAsynch = clientBinding
122: .invokeAsync(objMsgContext,
123: new JAXBDataBindingCallback(method,
124: DataBindingCallback.Mode.PARTS,
125: context, schema), service
126: .getExecutor());
127:
128: Response<?> r = new AsyncResponse<Object>(
129: objMsgContextAsynch, Object.class);
130: if (parameters.length > 0
131: && parameters[parameters.length - 1] instanceof AsyncHandler) {
132: // callback style
133: AsyncCallbackFuture f = new AsyncCallbackFuture(
134: r,
135: (AsyncHandler) parameters[parameters.length - 1]);
136: // service must always have an executor associated with it
137: service.getExecutor().execute(f);
138: return f;
139:
140: } else {
141: return r;
142: }
143:
144: } else {
145: objMsgContext = clientBinding.invoke(objMsgContext,
146: new JAXBDataBindingCallback(method,
147: DataBindingCallback.Mode.PARTS, context,
148: schema));
149: }
150:
151: populateResponseContext(objMsgContext);
152:
153: if (objMsgContext.getException() != null) {
154: LOG.log(Level.INFO, "ENDPOINT_INVOCATION_FAILED", method
155: .getName());
156: if (isValidException(objMsgContext)) {
157: throw (Exception) objMsgContext.getException();
158: } else {
159: throw new ProtocolException(objMsgContext
160: .getException());
161: }
162: }
163:
164: return objMsgContext.getReturn();
165: }
166:
167: protected ClientBinding createBinding(EndpointReferenceType ref,
168: Configuration c) {
169:
170: ClientBinding binding = null;
171: try {
172:
173: String bindingId = c.getString("bindingId");
174: BindingFactory factory = bus.getBindingManager()
175: .getBindingFactory(bindingId);
176: assert factory != null : "unable to find binding factory for "
177: + bindingId;
178: binding = factory.createClientBinding(ref);
179: } catch (Exception ex) {
180: throw new WebServiceException(ex);
181: }
182:
183: binding.configureSystemHandlers(c);
184: return binding;
185: }
186:
187: private boolean isValidException(ObjectMessageContext objContext) {
188: Method method = (Method) objContext.get(METHOD);
189: Throwable t = objContext.getException();
190:
191: boolean val = ProtocolException.class.isAssignableFrom(t
192: .getClass())
193: || WebServiceException.class.isAssignableFrom(t
194: .getClass());
195:
196: if (!val) {
197: for (Class<?> clazz : method.getExceptionTypes()) {
198: if (clazz.isAssignableFrom(t.getClass())) {
199: val = true;
200: break;
201: }
202: }
203: }
204:
205: return val;
206: }
207: }
|