001: package org.objectweb.celtix.bus.jaxws;
002:
003: import java.lang.reflect.Proxy;
004: import java.net.URI;
005: import java.net.URL;
006: import java.util.Iterator;
007: import java.util.List;
008: import java.util.Vector;
009: import java.util.concurrent.Executor;
010: import java.util.logging.Level;
011: import java.util.logging.Logger;
012:
013: import javax.jws.WebService;
014: import javax.wsdl.Port;
015: import javax.wsdl.WSDLException;
016: import javax.xml.bind.JAXBContext;
017: import javax.xml.namespace.QName;
018: import javax.xml.ws.Binding;
019: import javax.xml.ws.BindingProvider;
020: import javax.xml.ws.Dispatch;
021: import javax.xml.ws.Service;
022: import javax.xml.ws.WebServiceException;
023: import javax.xml.ws.handler.Handler;
024: import javax.xml.ws.handler.HandlerResolver;
025: import javax.xml.ws.spi.ServiceDelegate;
026:
027: import org.objectweb.celtix.Bus;
028: import org.objectweb.celtix.bus.configuration.wsdl.WsdlPortProvider;
029: import org.objectweb.celtix.bus.handlers.AnnotationHandlerChainBuilder;
030: import org.objectweb.celtix.bus.handlers.HandlerResolverImpl;
031: import org.objectweb.celtix.bus.handlers.PortInfoImpl;
032: import org.objectweb.celtix.configuration.Configuration;
033: import org.objectweb.celtix.configuration.ConfigurationBuilder;
034: import org.objectweb.celtix.configuration.ConfigurationBuilderFactory;
035: import org.objectweb.celtix.ws.addressing.EndpointReferenceType;
036: import org.objectweb.celtix.wsdl.EndpointReferenceUtils;
037:
038: public class ServiceImpl extends ServiceDelegate {
039:
040: public static final String SERVICE_CONFIGURATION_URI = "http://celtix.objectweb.org/bus/jaxws/service-config";
041: public static final String PORT_CONFIGURATION_URI = "http://celtix.objectweb.org/bus/jaxws/port-config";
042:
043: private static final Logger LOG = Logger
044: .getLogger(ServiceImpl.class.getName());
045:
046: private URL wsdlLocation;
047: private QName serviceName;
048: private final List<QName> endpointList;
049: private final Bus bus;
050: private HandlerResolver handlerResolver;
051: private Executor executor;
052:
053: /**
054: * Create a new Service.
055: * @throws WebServiceException If there is an exception creating Service.
056: */
057: public ServiceImpl(Bus b, URL location, QName name, Class<?> si) {
058: bus = b;
059: wsdlLocation = location;
060: serviceName = name;
061: endpointList = new Vector<QName>();
062: handlerResolver = new HandlerResolverImpl(bus
063: .getConfiguration(), serviceName);
064: executor = bus.getWorkQueueManager().getAutomaticWorkQueue();
065: }
066:
067: public void createPort(QName portName, URI bindingId,
068: String endpointAddress) {
069: throw new UnsupportedOperationException(
070: "addPort not yet supported");
071: }
072:
073: public <T> T getPort(QName portName,
074: Class<T> serviceEndpointInterface) {
075: if (portName == null) {
076: throw new WebServiceException("No endpoint specified.");
077: }
078:
079: return createPort(portName, serviceEndpointInterface);
080: }
081:
082: public <T> T getPort(Class<T> serviceEndpointInterface) {
083: return createPort(null, serviceEndpointInterface);
084: }
085:
086: public <T> Dispatch<T> createDispatch(QName portName,
087: Class<T> serviceEndpointInterface, Service.Mode mode) {
088: EndpointReferenceType ref = EndpointReferenceUtils
089: .getEndpointReference(wsdlLocation, serviceName,
090: portName.getLocalPart());
091: createPortConfiguration(portName, ref);
092: return new DispatchImpl<T>(bus, ref, mode,
093: serviceEndpointInterface, executor);
094: }
095:
096: public Dispatch<Object> createDispatch(QName portName,
097: JAXBContext context, Service.Mode mode) {
098:
099: EndpointReferenceType ref = EndpointReferenceUtils
100: .getEndpointReference(wsdlLocation, serviceName,
101: portName.getLocalPart());
102: createPortConfiguration(portName, ref);
103:
104: return new DispatchImpl<Object>(bus, ref, mode, context,
105: Object.class, executor);
106: }
107:
108: public QName getServiceName() {
109: return serviceName;
110: }
111:
112: public Iterator<QName> getPorts() {
113: return endpointList.iterator();
114: }
115:
116: public URL getWSDLDocumentLocation() {
117: return wsdlLocation;
118: }
119:
120: protected <T> T createPort(QName portName,
121: Class<T> serviceEndpointInterface) {
122:
123: LOG.log(Level.FINE, "creating port for portName", portName);
124: LOG.log(Level.FINE, "endpoint interface:",
125: serviceEndpointInterface);
126:
127: //Assuming Annotation is Present
128: javax.jws.WebService wsAnnotation = serviceEndpointInterface
129: .getAnnotation(WebService.class);
130:
131: if (wsdlLocation == null) {
132: wsdlLocation = getWsdlLocation(wsAnnotation);
133: }
134:
135: if (wsdlLocation == null) {
136: throw new WebServiceException("No wsdl url specified");
137: }
138:
139: if (serviceName == null) {
140: serviceName = getServiceName(wsAnnotation);
141: }
142:
143: EndpointReferenceType ref = EndpointReferenceUtils
144: .getEndpointReference(wsdlLocation, serviceName,
145: portName.getLocalPart());
146:
147: Configuration portConfiguration = createPortConfiguration(
148: portName, ref);
149:
150: EndpointInvocationHandler endpointHandler = new EndpointInvocationHandler(
151: bus, ref, this , portConfiguration,
152: serviceEndpointInterface);
153:
154: createHandlerChainForBinding(serviceEndpointInterface,
155: portName, endpointHandler.getBinding());
156:
157: Object obj = Proxy.newProxyInstance(serviceEndpointInterface
158: .getClassLoader(), new Class[] {
159: serviceEndpointInterface, BindingProvider.class },
160: endpointHandler);
161:
162: LOG.log(Level.FINE, "created proxy", obj);
163:
164: endpointList.add(portName);
165:
166: return serviceEndpointInterface.cast(obj);
167: }
168:
169: private <T> void createHandlerChainForBinding(
170: Class<T> serviceEndpointInterface, QName portName,
171: Binding binding) {
172: LOG.fine("loading handler chain for service");
173: assert handlerResolver != null;
174: PortInfoImpl portInfo = new PortInfoImpl(serviceName, portName,
175: null);
176: List<Handler> handlers = handlerResolver
177: .getHandlerChain(portInfo);
178: AnnotationHandlerChainBuilder handlerChainBuilder = new AnnotationHandlerChainBuilder();
179: handlers = handlerChainBuilder.buildHandlerChainFor(
180: serviceEndpointInterface, handlers);
181: binding.setHandlerChain(handlers);
182: }
183:
184: private URL getWsdlLocation(WebService wsAnnotation) {
185:
186: URL url = null;
187: if (wsAnnotation != null) {
188: try {
189: url = new URL(wsAnnotation.wsdlLocation());
190: } catch (java.net.MalformedURLException mue) {
191: mue.printStackTrace();
192: }
193: }
194: return url;
195: }
196:
197: private QName getServiceName(WebService wsAnnotation) {
198:
199: QName serviceQName = null;
200: if (wsAnnotation != null) {
201: serviceQName = new QName(wsAnnotation.targetNamespace(),
202: wsAnnotation.serviceName());
203: }
204:
205: return serviceQName;
206: }
207:
208: @Override
209: public void addPort(QName arg0, String arg1, String arg2) {
210: // TODO Auto-generated method stub
211:
212: }
213:
214: @Override
215: public HandlerResolver getHandlerResolver() {
216: return handlerResolver;
217: }
218:
219: @Override
220: public void setHandlerResolver(HandlerResolver hr) {
221: handlerResolver = hr;
222: }
223:
224: public Executor getExecutor() {
225: return executor;
226: }
227:
228: public void setExecutor(Executor e) {
229: executor = e;
230: }
231:
232: //find the configuration for the port as a child of the bus configuration, or have
233: //the builder create it if it does not exist yet
234: private Configuration createPortConfiguration(QName portName,
235: EndpointReferenceType ref) {
236:
237: Configuration portCfg = null;
238: String id = serviceName.toString() + "/"
239: + portName.getLocalPart();
240: ConfigurationBuilder cb = ConfigurationBuilderFactory
241: .getBuilder(null);
242: portCfg = cb.getConfiguration(PORT_CONFIGURATION_URI, id, bus
243: .getConfiguration());
244: if (null == portCfg) {
245: portCfg = cb.buildConfiguration(PORT_CONFIGURATION_URI, id,
246: bus.getConfiguration());
247: }
248:
249: // add the additional provider
250:
251: Port port = null;
252: try {
253: port = EndpointReferenceUtils.getPort(bus.getWSDLManager(),
254: ref);
255: } catch (WSDLException ex) {
256: throw new WebServiceException(
257: "Could not get port from wsdl", ex);
258: }
259: portCfg.getProviders().add(new WsdlPortProvider(port));
260: return portCfg;
261: }
262:
263: }
|