001: package org.objectweb.celtix.routing;
002:
003: import java.lang.reflect.InvocationHandler;
004: import java.lang.reflect.Method;
005: import java.lang.reflect.Proxy;
006: import java.lang.reflect.UndeclaredThrowableException;
007: import java.net.MalformedURLException;
008: import java.net.URL;
009: import java.util.ArrayList;
010: import java.util.List;
011: import java.util.Map;
012: import java.util.logging.Level;
013: import java.util.logging.Logger;
014:
015: import javax.annotation.Resource;
016: import javax.wsdl.Definition;
017: import javax.wsdl.Port;
018: import javax.xml.namespace.QName;
019: import javax.xml.ws.BindingProvider;
020: import javax.xml.ws.ProtocolException;
021: import javax.xml.ws.Service;
022: import javax.xml.ws.WebServiceContext;
023: import javax.xml.ws.WebServiceException;
024: import javax.xml.ws.handler.MessageContext;
025:
026: import org.objectweb.celtix.common.i18n.Message;
027: import org.objectweb.celtix.common.logging.LogUtils;
028: import org.objectweb.celtix.routing.configuration.DestinationType;
029: import org.objectweb.celtix.routing.configuration.RouteType;
030:
031: public class SEIImplHandler implements InvocationHandler {
032: private static final Logger LOG = LogUtils
033: .getL7dLogger(SEIImplHandler.class);
034: protected List<Object> proxyList;
035: private final Definition wsdlModel;
036: private final RouteType route;
037: private final URL wsdlLocation;
038: private boolean doInit;
039: /**
040: * Injectable context.
041: */
042: @Resource
043: private WebServiceContext wsCtx;
044:
045: public SEIImplHandler(Definition model, RouteType rt) {
046: wsdlModel = model;
047: route = rt;
048: try {
049: wsdlLocation = new URL(wsdlModel.getDocumentBaseURI());
050: } catch (MalformedURLException mue) {
051: throw new WebServiceException("Invalid wsdl url", mue);
052: }
053: doInit = true;
054: }
055:
056: @Resource
057: public void setContext(WebServiceContext ctx) {
058: wsCtx = ctx;
059: }
060:
061: public WebServiceContext getContext() {
062: return wsCtx;
063: }
064:
065: public Object invoke(Object proxy, Method method, Object[] args)
066: throws Exception {
067: if (doInit) {
068: init(method.getDeclaringClass());
069: }
070:
071: //TODO Iterate over the list for fanin/fanout
072: Object clientProxy = proxyList.get(0);
073: Object ret = null;
074: if (Proxy.isProxyClass(clientProxy.getClass())
075: && BindingProvider.class.isAssignableFrom(clientProxy
076: .getClass())) {
077: //Proxy instance inherits out of BindingProvider Interface
078: //as per JAXWS spec 4.2.3
079: BindingProvider bp = (BindingProvider) clientProxy;
080: Exception ex = null;
081:
082: //Synchrnization will not be required if the client proxies are thread safe.
083: synchronized (this ) {
084: updateRequestContext(bp.getRequestContext());
085:
086: InvocationHandler proxyHandler = Proxy
087: .getInvocationHandler(clientProxy);
088: try {
089: ret = proxyHandler
090: .invoke(clientProxy, method, args);
091: } catch (UndeclaredThrowableException ute) {
092: LOG.log(Level.SEVERE,
093: "PROXY_INVOKE_UNDECLEXCEPTION", method
094: .toString());
095: ex = new ProtocolException(new Message(
096: "PROXY_INVOKE_UNDECLEXCEPTION", LOG, method
097: .toString()).toString(), ute
098: .getCause());
099: } catch (Error error) {
100: LOG.log(Level.SEVERE, "PROXY_INVOKE_ERROR", method
101: .toString());
102: ex = new ProtocolException(new Message(
103: "PROXY_INVOKE_UNDECLEXCEPTION", LOG, method
104: .toString()).toString(), error);
105: } catch (Throwable t) {
106: LOG.log(Level.WARNING, "PROXY_INVOKE_EXCEPTION",
107: method.toString());
108: ex = (Exception) t;
109: }
110:
111: updateWebServiceContext(bp.getResponseContext());
112: }
113:
114: if (null != ex) {
115: throw ex;
116: }
117: }
118:
119: return ret;
120: }
121:
122: protected synchronized void init(Class<?> seiClass) {
123: if (doInit) {
124: List<DestinationType> dtList = route.getDestination();
125: if (null == proxyList) {
126: proxyList = new ArrayList<Object>(dtList.size());
127: }
128:
129: for (DestinationType dt : dtList) {
130: Service dtService = createService(wsdlLocation, dt
131: .getService());
132: QName portName;
133: if (dt.isSetPort()) {
134: portName = new QName(dt.getService()
135: .getNamespaceURI(), dt.getPort());
136: } else {
137: javax.wsdl.Service destService = wsdlModel
138: .getService(dt.getService());
139: String name = ((Port) destService.getPorts()
140: .values().iterator()).getName();
141: portName = new QName(dt.getService()
142: .getNamespaceURI(), name);
143: }
144:
145: Object proxy = dtService.getPort(portName, seiClass);
146: if (null == proxy) {
147: LOG.log(Level.SEVERE, "GETPORT_FAILURE",
148: new Object[] { dt.getService(),
149: portName.toString() });
150: throw new WebServiceException(new Message(
151: "GETPORT_FAILURE", LOG, dt.getService(),
152: portName).toString());
153: }
154: proxyList.add(proxy);
155: }
156: doInit = false;
157: }
158: }
159:
160: protected Service createService(URL wsdlUrl, QName serviceName) {
161: //TODO Set Executor used by the Source Endpoint onto Service
162: //Currently destination service uses bus workqueue.
163: return Service.create(wsdlUrl, serviceName);
164: }
165:
166: private void updateRequestContext(Map<String, Object> reqCtx) {
167: if (null != getContext()) {
168: MessageContext sourceMsgCtx = getContext()
169: .getMessageContext();
170: reqCtx.put(BindingProvider.USERNAME_PROPERTY, sourceMsgCtx
171: .get(BindingProvider.USERNAME_PROPERTY));
172: reqCtx.put(BindingProvider.PASSWORD_PROPERTY, sourceMsgCtx
173: .get(BindingProvider.PASSWORD_PROPERTY));
174: }
175: }
176:
177: private void updateWebServiceContext(Map<String, Object> respCtx) {
178: //TODO
179: }
180: }
|