001: package org.objectweb.celtix.bus.jaxws;
002:
003: import java.util.concurrent.Executor;
004: import java.util.concurrent.Future;
005: import java.util.logging.Level;
006: import java.util.logging.Logger;
007:
008: import javax.xml.bind.JAXBContext;
009: import javax.xml.ws.AsyncHandler;
010: import javax.xml.ws.Dispatch;
011: import javax.xml.ws.ProtocolException;
012: import javax.xml.ws.Response;
013: import javax.xml.ws.Service;
014: import javax.xml.ws.WebServiceException;
015:
016: import org.objectweb.celtix.Bus;
017:
018: import org.objectweb.celtix.bindings.BindingFactory;
019: import org.objectweb.celtix.bindings.ClientBinding;
020: import org.objectweb.celtix.bindings.DataBindingCallback.Mode;
021: import org.objectweb.celtix.common.logging.LogUtils;
022: import org.objectweb.celtix.context.ObjectMessageContext;
023: import org.objectweb.celtix.ws.addressing.EndpointReferenceType;
024:
025: public class DispatchImpl<T> extends BindingProviderImpl implements
026: Dispatch<T> {
027: private static final Logger LOG = LogUtils
028: .getL7dLogger(EndpointInvocationHandler.class);
029:
030: protected ClientBinding cb;
031: protected DynamicDataBindingCallback callback;
032:
033: private Bus bus;
034: private EndpointReferenceType ref;
035: private Mode mode;
036: private Class<T> cl;
037: private Executor executor;
038: private JAXBContext context;
039: private boolean initialised;
040:
041: DispatchImpl(Bus b, EndpointReferenceType r, Service.Mode m,
042: Class<T> clazz, Executor e) {
043: bus = b;
044: ref = r;
045: mode = Mode.fromServiceMode(m);
046: cl = clazz;
047: cb = null;
048: callback = null;
049: executor = e;
050: context = null;
051: initialised = false;
052: }
053:
054: DispatchImpl(Bus b, EndpointReferenceType r, Service.Mode m,
055: JAXBContext ctx, Class<T> clazz, Executor e) {
056: bus = b;
057: ref = r;
058: mode = Mode.fromServiceMode(m);
059: cb = null;
060: callback = null;
061: executor = e;
062: context = ctx;
063: cl = clazz;
064: initialised = false;
065: }
066:
067: protected void init() {
068: cb = createClientBinding();
069: setBinding(cb.getBinding());
070: if (context == null) {
071: callback = new DynamicDataBindingCallback(cl, mode);
072: } else {
073: callback = new DynamicDataBindingCallback(context, mode);
074: }
075: initialised = true;
076: }
077:
078: public T invoke(T obj) {
079:
080: if (LOG.isLoggable(Level.INFO)) {
081: LOG.info("Dispatch: invoke called");
082: }
083:
084: if (!initialised) {
085: init();
086: }
087:
088: ObjectMessageContext objMsgContext = cb.createObjectContext();
089: // TODO
090: // RequestConetxts needed to be populated based on JAX-WS mandatory
091: // properties
092: // Further copied into ObjectMessageContext so as to decouple context
093: // across invocations
094: objMsgContext.putAll(getRequestContext());
095: objMsgContext.setMessageObjects(obj);
096:
097: try {
098: objMsgContext = cb.invoke(objMsgContext, callback);
099: } catch (Exception ex) {
100: throwWebServiceException(ex);
101: } finally {
102: //Update Response Context
103: throwProtocolException(objMsgContext.getException());
104: }
105:
106: populateResponseContext(objMsgContext);
107:
108: return cl.cast(objMsgContext.getReturn());
109: }
110:
111: public Future<?> invokeAsync(T obj, AsyncHandler<T> asyncHandler) {
112:
113: if (LOG.isLoggable(Level.INFO)) {
114: LOG.info("Dispatch: callback invokeAsync called");
115: }
116:
117: if (!initialised) {
118: init();
119: }
120:
121: ObjectMessageContext objMsgContext = cb.createObjectContext();
122: objMsgContext.putAll(getRequestContext());
123: objMsgContext.setMessageObjects(obj);
124:
125: AsyncCallbackFuture future = null;
126:
127: try {
128: Future<ObjectMessageContext> objMsgContextAsynch = cb
129: .invokeAsync(objMsgContext, callback, executor);
130: Response<T> r = new AsyncResponse<T>(objMsgContextAsynch,
131: cl);
132: future = new AsyncCallbackFuture(r, asyncHandler);
133: executor.execute(future);
134: } catch (Exception ex) {
135: throwWebServiceException(ex);
136: }
137:
138: return future;
139:
140: }
141:
142: public Response<T> invokeAsync(T obj) {
143:
144: if (LOG.isLoggable(Level.INFO)) {
145: LOG.info("Dispatch: polling invokeAsync called");
146: }
147:
148: if (!initialised) {
149: init();
150: }
151:
152: ObjectMessageContext objMsgContext = cb.createObjectContext();
153: objMsgContext.putAll(getRequestContext());
154: objMsgContext.setMessageObjects(obj);
155:
156: Response<T> response = null;
157:
158: try {
159: Future<ObjectMessageContext> objMsgContextAsynch = cb
160: .invokeAsync(objMsgContext, callback, executor);
161: response = new AsyncResponse<T>(objMsgContextAsynch, cl);
162: } catch (Exception ex) {
163: throwWebServiceException(ex);
164: }
165:
166: return response;
167: }
168:
169: public void invokeOneWay(T obj) {
170:
171: if (LOG.isLoggable(Level.INFO)) {
172: LOG.info("Dispatch: invokeOneWay called");
173: }
174:
175: if (!initialised) {
176: init();
177: }
178:
179: ObjectMessageContext objMsgContext = cb.createObjectContext();
180: objMsgContext.putAll(getRequestContext());
181: objMsgContext.setMessageObjects(obj);
182:
183: try {
184: cb.invokeOneWay(objMsgContext, callback);
185: } catch (Exception ex) {
186: throwWebServiceException(ex);
187: }
188:
189: }
190:
191: private ClientBinding createClientBinding() {
192: // TODO: Get bindingId from wsdl via the ref
193: String bindingId = "http://schemas.xmlsoap.org/wsdl/soap/";
194: ClientBinding binding = null;
195: try {
196: BindingFactory factory = bus.getBindingManager()
197: .getBindingFactory(bindingId);
198: assert factory != null : "unable to find binding factory for "
199: + bindingId;
200: binding = factory.createClientBinding(ref);
201: } catch (Exception ex) {
202: throw new WebServiceException(ex);
203: }
204: return binding;
205: }
206:
207: private void throwWebServiceException(Throwable t) {
208: if (null != t) {
209: LOG.log(Level.SEVERE, "DISPATCH_INVOKE_EXC", cl
210: .getSimpleName());
211: throw isJAXWSException(t) ? (WebServiceException) t
212: : new WebServiceException(t);
213: }
214: }
215:
216: private void throwProtocolException(Throwable t) {
217: if (null != t) {
218: LOG.log(Level.INFO, "DISPATCH_INVOKE_EXC", cl
219: .getSimpleName());
220: throw isJAXWSException(t) ? (WebServiceException) t
221: : new ProtocolException(t);
222: }
223: }
224:
225: private boolean isJAXWSException(Throwable t) {
226: return ProtocolException.class.isAssignableFrom(t.getClass())
227: || WebServiceException.class.isAssignableFrom(t
228: .getClass());
229: }
230:
231: }
|