src/share/jaxws_classes/com/sun/xml/internal/ws/client/WSServiceDelegate.java

Tue, 09 Apr 2013 14:51:13 +0100

author
alanb
date
Tue, 09 Apr 2013 14:51:13 +0100
changeset 368
0989ad8c0860
parent 286
f50545b5e2f1
child 384
8f2986ff0235
permissions
-rw-r--r--

8010393: Update JAX-WS RI to 2.2.9-b12941
Reviewed-by: alanb, erikj
Contributed-by: miroslav.kos@oracle.com, martin.grebac@oracle.com

ohair@286 1 /*
alanb@368 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
ohair@286 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
ohair@286 4 *
ohair@286 5 * This code is free software; you can redistribute it and/or modify it
ohair@286 6 * under the terms of the GNU General Public License version 2 only, as
ohair@286 7 * published by the Free Software Foundation. Oracle designates this
ohair@286 8 * particular file as subject to the "Classpath" exception as provided
ohair@286 9 * by Oracle in the LICENSE file that accompanied this code.
ohair@286 10 *
ohair@286 11 * This code is distributed in the hope that it will be useful, but WITHOUT
ohair@286 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
ohair@286 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
ohair@286 14 * version 2 for more details (a copy is included in the LICENSE file that
ohair@286 15 * accompanied this code).
ohair@286 16 *
ohair@286 17 * You should have received a copy of the GNU General Public License version
ohair@286 18 * 2 along with this work; if not, write to the Free Software Foundation,
ohair@286 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
ohair@286 20 *
ohair@286 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ohair@286 22 * or visit www.oracle.com if you need additional information or have any
ohair@286 23 * questions.
ohair@286 24 */
ohair@286 25
ohair@286 26 package com.sun.xml.internal.ws.client;
ohair@286 27
ohair@286 28 import com.sun.istack.internal.NotNull;
ohair@286 29 import com.sun.istack.internal.Nullable;
ohair@286 30 import com.sun.xml.internal.ws.Closeable;
ohair@286 31 import com.sun.xml.internal.ws.api.BindingID;
ohair@286 32 import com.sun.xml.internal.ws.api.ComponentFeature;
alanb@368 33 import com.sun.xml.internal.ws.api.ComponentsFeature;
ohair@286 34 import com.sun.xml.internal.ws.api.ComponentFeature.Target;
ohair@286 35 import com.sun.xml.internal.ws.api.EndpointAddress;
ohair@286 36 import com.sun.xml.internal.ws.api.WSService;
ohair@286 37 import com.sun.xml.internal.ws.api.addressing.WSEndpointReference;
ohair@286 38 import com.sun.xml.internal.ws.api.client.ServiceInterceptor;
ohair@286 39 import com.sun.xml.internal.ws.api.client.ServiceInterceptorFactory;
alanb@368 40 import com.sun.xml.internal.ws.api.databinding.DatabindingConfig;
ohair@286 41 import com.sun.xml.internal.ws.api.databinding.DatabindingFactory;
alanb@368 42 import com.sun.xml.internal.ws.api.databinding.MetadataReader;
ohair@286 43 import com.sun.xml.internal.ws.api.model.SEIModel;
ohair@286 44 import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort;
alanb@368 45 import com.sun.xml.internal.ws.api.pipe.Stubs;
ohair@286 46 import com.sun.xml.internal.ws.api.server.Container;
ohair@286 47 import com.sun.xml.internal.ws.api.server.ContainerResolver;
ohair@286 48 import com.sun.xml.internal.ws.api.wsdl.parser.WSDLParserExtension;
ohair@286 49 import com.sun.xml.internal.ws.binding.BindingImpl;
ohair@286 50 import com.sun.xml.internal.ws.binding.WebServiceFeatureList;
ohair@286 51 import com.sun.xml.internal.ws.client.HandlerConfigurator.AnnotationConfigurator;
ohair@286 52 import com.sun.xml.internal.ws.client.HandlerConfigurator.HandlerResolverImpl;
ohair@286 53 import com.sun.xml.internal.ws.client.sei.SEIStub;
alanb@368 54
ohair@286 55 import com.sun.xml.internal.ws.developer.MemberSubmissionAddressingFeature;
alanb@368 56 import com.sun.xml.internal.ws.developer.UsesJAXBContextFeature;
ohair@286 57 import com.sun.xml.internal.ws.developer.WSBindingProvider;
ohair@286 58 import com.sun.xml.internal.ws.model.RuntimeModeler;
ohair@286 59 import com.sun.xml.internal.ws.model.SOAPSEIModel;
ohair@286 60 import com.sun.xml.internal.ws.model.wsdl.WSDLModelImpl;
ohair@286 61 import com.sun.xml.internal.ws.model.wsdl.WSDLPortImpl;
ohair@286 62 import com.sun.xml.internal.ws.model.wsdl.WSDLServiceImpl;
ohair@286 63 import com.sun.xml.internal.ws.resources.ClientMessages;
ohair@286 64 import com.sun.xml.internal.ws.resources.DispatchMessages;
ohair@286 65 import com.sun.xml.internal.ws.resources.ProviderApiMessages;
ohair@286 66 import com.sun.xml.internal.ws.util.JAXWSUtils;
ohair@286 67 import com.sun.xml.internal.ws.util.ServiceConfigurationError;
ohair@286 68 import com.sun.xml.internal.ws.util.ServiceFinder;
ohair@286 69 import com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser;
ohair@286 70 import org.xml.sax.EntityResolver;
ohair@286 71 import org.xml.sax.SAXException;
ohair@286 72
ohair@286 73 import javax.jws.HandlerChain;
ohair@286 74 import javax.jws.WebService;
ohair@286 75 import javax.xml.bind.JAXBContext;
ohair@286 76 import javax.xml.namespace.QName;
ohair@286 77 import javax.xml.stream.XMLStreamException;
ohair@286 78 import javax.xml.transform.Source;
ohair@286 79 import javax.xml.transform.stream.StreamSource;
alanb@368 80 import javax.xml.ws.BindingProvider;
alanb@368 81 import javax.xml.ws.Dispatch;
alanb@368 82 import javax.xml.ws.EndpointReference;
alanb@368 83 import javax.xml.ws.Service;
alanb@368 84 import javax.xml.ws.WebServiceClient;
alanb@368 85 import javax.xml.ws.WebServiceException;
alanb@368 86 import javax.xml.ws.WebServiceFeature;
ohair@286 87 import javax.xml.ws.handler.HandlerResolver;
ohair@286 88 import javax.xml.ws.soap.AddressingFeature;
ohair@286 89 import java.io.IOException;
ohair@286 90 import java.lang.reflect.InvocationHandler;
ohair@286 91 import java.lang.reflect.Proxy;
ohair@286 92 import java.net.MalformedURLException;
ohair@286 93 import java.net.URL;
ohair@286 94 import java.security.AccessController;
ohair@286 95 import java.security.PrivilegedAction;
alanb@368 96 import java.util.Collection;
alanb@368 97 import java.util.HashMap;
alanb@368 98 import java.util.HashSet;
alanb@368 99 import java.util.Iterator;
alanb@368 100 import java.util.Map;
alanb@368 101 import java.util.Set;
ohair@286 102 import java.util.concurrent.Executor;
ohair@286 103 import java.util.concurrent.ThreadFactory;
ohair@286 104
alanb@368 105 import static com.sun.xml.internal.ws.util.xml.XmlUtil.createDefaultCatalogResolver;
alanb@368 106
ohair@286 107 /**
ohair@286 108 * <code>Service</code> objects provide the client view of a Web service.
ohair@286 109 *
ohair@286 110 * <p><code>Service</code> acts as a factory of the following:
ohair@286 111 * <ul>
ohair@286 112 * <li>Proxies for a target service endpoint.
ohair@286 113 * <li>Instances of <code>javax.xml.ws.Dispatch</code> for
ohair@286 114 * dynamic message-oriented invocation of a remote
ohair@286 115 * operation.
ohair@286 116 * </li>
ohair@286 117 *
ohair@286 118 * <p>The ports available on a service can be enumerated using the
ohair@286 119 * <code>getPorts</code> method. Alternatively, you can pass a
ohair@286 120 * service endpoint interface to the unary <code>getPort</code> method
ohair@286 121 * and let the runtime select a compatible port.
ohair@286 122 *
ohair@286 123 * <p>Handler chains for all the objects created by a <code>Service</code>
ohair@286 124 * can be set by means of the provided <code>HandlerRegistry</code>.
ohair@286 125 *
ohair@286 126 * <p>An <code>Executor</code> may be set on the service in order
ohair@286 127 * to gain better control over the threads used to dispatch asynchronous
ohair@286 128 * callbacks. For instance, thread pooling with certain parameters
ohair@286 129 * can be enabled by creating a <code>ThreadPoolExecutor</code> and
ohair@286 130 * registering it with the service.
ohair@286 131 *
ohair@286 132 * @author WS Development Team
ohair@286 133 * @see Executor
ohair@286 134 * @since JAX-WS 2.0
ohair@286 135 */
ohair@286 136 public class WSServiceDelegate extends WSService {
ohair@286 137 /**
ohair@286 138 * All ports.
ohair@286 139 * <p>
ohair@286 140 * This includes ports statically known to WSDL, as well as
ohair@286 141 * ones that are dynamically added
ohair@286 142 * through {@link #addPort(QName, String, String)}.
ohair@286 143 * <p>
ohair@286 144 * For statically known ports we'll have {@link SEIPortInfo}.
ohair@286 145 * For dynamically added ones we'll have {@link PortInfo}.
ohair@286 146 */
ohair@286 147 private final Map<QName, PortInfo> ports = new HashMap<QName, PortInfo>();
ohair@286 148 // For monitoring
ohair@286 149 protected Map<QName, PortInfo> getQNameToPortInfoMap() { return ports; }
ohair@286 150
ohair@286 151 /**
ohair@286 152 * Whenever we create {@link BindingProvider}, we use this to configure handlers.
ohair@286 153 */
ohair@286 154 private @NotNull HandlerConfigurator handlerConfigurator = new HandlerResolverImpl(null);
ohair@286 155
ohair@286 156 private final Class<? extends Service> serviceClass;
ohair@286 157
ohair@286 158 private final WebServiceFeatureList features;
ohair@286 159
ohair@286 160 /**
ohair@286 161 * Name of the service for which this {@link WSServiceDelegate} is created for.
ohair@286 162 */
ohair@286 163 private final @NotNull QName serviceName;
ohair@286 164
ohair@286 165 /**
ohair@286 166 * Information about SEI, keyed by their interface type.
ohair@286 167 */
ohair@286 168 // private final Map<Class,SEIPortInfo> seiContext = new HashMap<Class,SEIPortInfo>();
ohair@286 169 private final Map<QName,SEIPortInfo> seiContext = new HashMap<QName,SEIPortInfo>();
ohair@286 170
ohair@286 171 // This executor is used for all the async invocations for all proxies
ohair@286 172 // created from this service. But once the proxy is created, then changing
ohair@286 173 // this executor doesn't affect the already created proxies.
ohair@286 174 private volatile Executor executor;
ohair@286 175
ohair@286 176 /**
ohair@286 177 * The WSDL service that this {@link Service} object represents.
ohair@286 178 * <p>
ohair@286 179 * This field is null iff no WSDL is given to {@link Service}.
ohair@286 180 * This fiels can be be null if the service is created without wsdl but later
ohair@286 181 * the epr supplies a wsdl that can be parsed.
ohair@286 182 */
ohair@286 183 private @Nullable WSDLServiceImpl wsdlService;
ohair@286 184
ohair@286 185 private final Container container;
ohair@286 186 /**
ohair@286 187 * Multiple {@link ServiceInterceptor}s are aggregated into one.
ohair@286 188 */
ohair@286 189 /*package*/ final @NotNull ServiceInterceptor serviceInterceptor;
ohair@286 190
ohair@286 191
ohair@286 192 public WSServiceDelegate(URL wsdlDocumentLocation, QName serviceName, Class<? extends Service> serviceClass, WebServiceFeature... features) {
alanb@368 193 this(wsdlDocumentLocation, serviceName, serviceClass, new WebServiceFeatureList(features));
alanb@368 194 }
alanb@368 195
alanb@368 196 protected WSServiceDelegate(URL wsdlDocumentLocation, QName serviceName, Class<? extends Service> serviceClass, WebServiceFeatureList features) {
ohair@286 197 this(
ohair@286 198 wsdlDocumentLocation==null ? null : new StreamSource(wsdlDocumentLocation.toExternalForm()),
ohair@286 199 serviceName,serviceClass, features);
ohair@286 200 }
ohair@286 201
ohair@286 202 /**
ohair@286 203 * @param serviceClass
ohair@286 204 * Either {@link Service}.class or other generated service-derived classes.
ohair@286 205 */
ohair@286 206 public WSServiceDelegate(@Nullable Source wsdl, @NotNull QName serviceName, @NotNull final Class<? extends Service> serviceClass, WebServiceFeature... features) {
alanb@368 207 this(wsdl, serviceName, serviceClass, new WebServiceFeatureList(features));
alanb@368 208 }
alanb@368 209
alanb@368 210 /**
alanb@368 211 * @param serviceClass
alanb@368 212 * Either {@link Service}.class or other generated service-derived classes.
alanb@368 213 */
alanb@368 214 protected WSServiceDelegate(@Nullable Source wsdl, @NotNull QName serviceName, @NotNull final Class<? extends Service> serviceClass, WebServiceFeatureList features) {
ohair@286 215 this(wsdl, null, serviceName, serviceClass, features);
ohair@286 216 }
ohair@286 217
ohair@286 218 /**
ohair@286 219 * @param serviceClass
ohair@286 220 * Either {@link Service}.class or other generated service-derived classes.
ohair@286 221 */
ohair@286 222 public WSServiceDelegate(@Nullable Source wsdl, @Nullable WSDLServiceImpl service, @NotNull QName serviceName, @NotNull final Class<? extends Service> serviceClass, WebServiceFeature... features) {
alanb@368 223 this(wsdl, service, serviceName, serviceClass, new WebServiceFeatureList(features));
alanb@368 224 }
alanb@368 225
alanb@368 226 /**
alanb@368 227 * @param serviceClass
alanb@368 228 * Either {@link Service}.class or other generated service-derived classes.
alanb@368 229 */
alanb@368 230 public WSServiceDelegate(@Nullable Source wsdl, @Nullable WSDLServiceImpl service, @NotNull QName serviceName, @NotNull final Class<? extends Service> serviceClass, WebServiceFeatureList features) {
ohair@286 231 //we cant create a Service without serviceName
alanb@368 232 if (serviceName == null) {
alanb@368 233 throw new WebServiceException(ClientMessages.INVALID_SERVICE_NAME_NULL(null));
alanb@368 234 }
ohair@286 235
alanb@368 236 this.features = features;
ohair@286 237
ohair@286 238 InitParams initParams = INIT_PARAMS.get();
ohair@286 239 INIT_PARAMS.set(null); // mark it as consumed
alanb@368 240 if(initParams==null) {
alanb@368 241 initParams = EMPTY_PARAMS;
alanb@368 242 }
ohair@286 243
ohair@286 244 this.serviceName = serviceName;
ohair@286 245 this.serviceClass = serviceClass;
ohair@286 246 Container tContainer = initParams.getContainer()!=null ? initParams.getContainer() : ContainerResolver.getInstance().getContainer();
ohair@286 247 if (tContainer == Container.NONE) {
ohair@286 248 tContainer = new ClientContainer();
ohair@286 249 }
ohair@286 250 this.container = tContainer;
ohair@286 251
ohair@286 252 ComponentFeature cf = this.features.get(ComponentFeature.class);
ohair@286 253 if (cf != null) {
ohair@286 254 switch(cf.getTarget()) {
ohair@286 255 case SERVICE:
ohair@286 256 getComponents().add(cf.getComponent());
ohair@286 257 break;
ohair@286 258 case CONTAINER:
ohair@286 259 this.container.getComponents().add(cf.getComponent());
alanb@368 260 break;
ohair@286 261 default:
ohair@286 262 throw new IllegalArgumentException();
ohair@286 263 }
ohair@286 264 }
alanb@368 265 ComponentsFeature csf = this.features.get(ComponentsFeature.class);
alanb@368 266 if (csf != null) {
alanb@368 267 for (ComponentFeature cfi : csf.getComponentFeatures()) {
alanb@368 268 switch(cfi.getTarget()) {
alanb@368 269 case SERVICE:
alanb@368 270 getComponents().add(cfi.getComponent());
alanb@368 271 break;
alanb@368 272 case CONTAINER:
alanb@368 273 this.container.getComponents().add(cfi.getComponent());
alanb@368 274 break;
alanb@368 275 default:
alanb@368 276 throw new IllegalArgumentException();
alanb@368 277 }
alanb@368 278 }
alanb@368 279 }
ohair@286 280
ohair@286 281 // load interceptor
ohair@286 282 ServiceInterceptor interceptor = ServiceInterceptorFactory.load(this, Thread.currentThread().getContextClassLoader());
ohair@286 283 ServiceInterceptor si = container.getSPI(ServiceInterceptor.class);
ohair@286 284 if (si != null) {
ohair@286 285 interceptor = ServiceInterceptor.aggregate(interceptor, si);
ohair@286 286 }
ohair@286 287 this.serviceInterceptor = interceptor;
ohair@286 288
ohair@286 289 if (service == null) {
ohair@286 290 //if wsdl is null, try and get it from the WebServiceClient.wsdlLocation
ohair@286 291 if(wsdl == null){
ohair@286 292 if(serviceClass != Service.class){
ohair@286 293 WebServiceClient wsClient = AccessController.doPrivileged(new PrivilegedAction<WebServiceClient>() {
ohair@286 294 public WebServiceClient run() {
ohair@286 295 return serviceClass.getAnnotation(WebServiceClient.class);
ohair@286 296 }
ohair@286 297 });
ohair@286 298 String wsdlLocation = wsClient.wsdlLocation();
ohair@286 299 wsdlLocation = JAXWSUtils.absolutize(JAXWSUtils.getFileOrURLName(wsdlLocation));
ohair@286 300 wsdl = new StreamSource(wsdlLocation);
ohair@286 301 }
ohair@286 302 }
ohair@286 303 if (wsdl != null) {
ohair@286 304 try {
ohair@286 305 URL url = wsdl.getSystemId()==null ? null : JAXWSUtils.getEncodedURL(wsdl.getSystemId());
ohair@286 306 WSDLModelImpl model = parseWSDL(url, wsdl, serviceClass);
ohair@286 307 service = model.getService(this.serviceName);
ohair@286 308 if (service == null)
ohair@286 309 throw new WebServiceException(
ohair@286 310 ClientMessages.INVALID_SERVICE_NAME(this.serviceName,
ohair@286 311 buildNameList(model.getServices().keySet())));
ohair@286 312 // fill in statically known ports
ohair@286 313 for (WSDLPort port : service.getPorts())
ohair@286 314 ports.put(port.getName(), new PortInfo(this, port));
ohair@286 315 } catch (MalformedURLException e) {
ohair@286 316 throw new WebServiceException(ClientMessages.INVALID_WSDL_URL(wsdl.getSystemId()));
ohair@286 317 }
ohair@286 318 }
ohair@286 319 }
ohair@286 320 this.wsdlService = service;
ohair@286 321
ohair@286 322 if (serviceClass != Service.class) {
ohair@286 323 //if @HandlerChain present, set HandlerResolver on service context
ohair@286 324 HandlerChain handlerChain =
ohair@286 325 AccessController.doPrivileged(new PrivilegedAction<HandlerChain>() {
ohair@286 326 public HandlerChain run() {
ohair@286 327 return serviceClass.getAnnotation(HandlerChain.class);
ohair@286 328 }
ohair@286 329 });
ohair@286 330 if (handlerChain != null)
ohair@286 331 handlerConfigurator = new AnnotationConfigurator(this);
ohair@286 332 }
ohair@286 333
ohair@286 334 }
ohair@286 335
ohair@286 336 /**
ohair@286 337 * Parses the WSDL and builds {@link com.sun.xml.internal.ws.api.model.wsdl.WSDLModel}.
ohair@286 338 * @param wsdlDocumentLocation
ohair@286 339 * Either this or <tt>wsdl</tt> parameter must be given.
ohair@286 340 * Null location means the system won't be able to resolve relative references in the WSDL,
ohair@286 341 */
ohair@286 342 private WSDLModelImpl parseWSDL(URL wsdlDocumentLocation, Source wsdlSource, Class serviceClass) {
ohair@286 343 try {
ohair@286 344 return RuntimeWSDLParser.parse(wsdlDocumentLocation, wsdlSource, createCatalogResolver(),
ohair@286 345 true, getContainer(), serviceClass, ServiceFinder.find(WSDLParserExtension.class).toArray());
ohair@286 346 } catch (IOException e) {
ohair@286 347 throw new WebServiceException(e);
ohair@286 348 } catch (XMLStreamException e) {
ohair@286 349 throw new WebServiceException(e);
ohair@286 350 } catch (SAXException e) {
ohair@286 351 throw new WebServiceException(e);
ohair@286 352 } catch (ServiceConfigurationError e) {
ohair@286 353 throw new WebServiceException(e);
ohair@286 354 }
ohair@286 355 }
ohair@286 356
ohair@286 357 protected EntityResolver createCatalogResolver() {
ohair@286 358 return createDefaultCatalogResolver();
ohair@286 359 }
ohair@286 360
ohair@286 361 public Executor getExecutor() {
ohair@286 362 return executor;
ohair@286 363 }
ohair@286 364
ohair@286 365 public void setExecutor(Executor executor) {
ohair@286 366 this.executor = executor;
ohair@286 367 }
ohair@286 368
ohair@286 369 public HandlerResolver getHandlerResolver() {
ohair@286 370 return handlerConfigurator.getResolver();
ohair@286 371 }
ohair@286 372
ohair@286 373 /*package*/ final HandlerConfigurator getHandlerConfigurator() {
ohair@286 374 return handlerConfigurator;
ohair@286 375 }
ohair@286 376
ohair@286 377 public void setHandlerResolver(HandlerResolver resolver) {
ohair@286 378 handlerConfigurator = new HandlerResolverImpl(resolver);
ohair@286 379 }
ohair@286 380
ohair@286 381 public <T> T getPort(QName portName, Class<T> portInterface) throws WebServiceException {
ohair@286 382 return getPort(portName, portInterface, EMPTY_FEATURES);
ohair@286 383 }
ohair@286 384
ohair@286 385 public <T> T getPort(QName portName, Class<T> portInterface, WebServiceFeature... features) {
ohair@286 386 if (portName == null || portInterface == null)
ohair@286 387 throw new IllegalArgumentException();
ohair@286 388 WSDLServiceImpl tWsdlService = this.wsdlService;
ohair@286 389 if (tWsdlService == null) {
ohair@286 390 // assigning it to local variable and not setting it back to this.wsdlService intentionally
ohair@286 391 // as we don't want to include the service instance with information gathered from sei
ohair@286 392 tWsdlService = getWSDLModelfromSEI(portInterface);
ohair@286 393 //still null? throw error need wsdl metadata to create a proxy
ohair@286 394 if (tWsdlService == null) {
ohair@286 395 throw new WebServiceException(ProviderApiMessages.NO_WSDL_NO_PORT(portInterface.getName()));
ohair@286 396 }
ohair@286 397
ohair@286 398 }
ohair@286 399 WSDLPortImpl portModel = getPortModel(tWsdlService, portName);
ohair@286 400 return getPort(portModel.getEPR(), portName, portInterface, new WebServiceFeatureList(features));
ohair@286 401 }
ohair@286 402
ohair@286 403 public <T> T getPort(EndpointReference epr, Class<T> portInterface, WebServiceFeature... features) {
ohair@286 404 return getPort(WSEndpointReference.create(epr),portInterface,features);
ohair@286 405 }
ohair@286 406
ohair@286 407 public <T> T getPort(WSEndpointReference wsepr, Class<T> portInterface, WebServiceFeature... features) {
ohair@286 408 //get the portType from SEI, so that it can be used if EPR does n't have endpointName
alanb@368 409 WebServiceFeatureList featureList = new WebServiceFeatureList(features);
alanb@368 410 QName portTypeName = RuntimeModeler.getPortTypeName(portInterface, getMetadadaReader(featureList, portInterface.getClassLoader()));
ohair@286 411 //if port name is not specified in EPR, it will use portTypeName to get it from the WSDL model.
ohair@286 412 QName portName = getPortNameFromEPR(wsepr, portTypeName);
alanb@368 413 return getPort(wsepr,portName,portInterface, featureList);
ohair@286 414 }
ohair@286 415
ohair@286 416 protected <T> T getPort(WSEndpointReference wsepr, QName portName, Class<T> portInterface,
ohair@286 417 WebServiceFeatureList features) {
ohair@286 418 ComponentFeature cf = features.get(ComponentFeature.class);
ohair@286 419 if (cf != null && !Target.STUB.equals(cf.getTarget())) {
ohair@286 420 throw new IllegalArgumentException();
ohair@286 421 }
alanb@368 422 ComponentsFeature csf = features.get(ComponentsFeature.class);
alanb@368 423 if (csf != null) {
alanb@368 424 for (ComponentFeature cfi : csf.getComponentFeatures()) {
alanb@368 425 if (!Target.STUB.equals(cfi.getTarget()))
alanb@368 426 throw new IllegalArgumentException();
alanb@368 427 }
alanb@368 428 }
ohair@286 429 features.addAll(this.features);
ohair@286 430
ohair@286 431 SEIPortInfo spi = addSEI(portName, portInterface, features);
ohair@286 432 return createEndpointIFBaseProxy(wsepr,portName,portInterface,features, spi);
ohair@286 433 }
ohair@286 434
alanb@368 435 @Override
ohair@286 436 public <T> T getPort(Class<T> portInterface, WebServiceFeature... features) {
ohair@286 437 //get the portType from SEI
alanb@368 438 QName portTypeName = RuntimeModeler.getPortTypeName(portInterface, getMetadadaReader(new WebServiceFeatureList(features), portInterface.getClassLoader()));
alanb@368 439 WSDLServiceImpl tmpWsdlService = this.wsdlService;
alanb@368 440 if (tmpWsdlService == null) {
ohair@286 441 // assigning it to local variable and not setting it back to this.wsdlService intentionally
ohair@286 442 // as we don't want to include the service instance with information gathered from sei
alanb@368 443 tmpWsdlService = getWSDLModelfromSEI(portInterface);
ohair@286 444 //still null? throw error need wsdl metadata to create a proxy
alanb@368 445 if(tmpWsdlService == null) {
ohair@286 446 throw new WebServiceException(ProviderApiMessages.NO_WSDL_NO_PORT(portInterface.getName()));
ohair@286 447 }
ohair@286 448 }
ohair@286 449 //get the first port corresponding to the SEI
alanb@368 450 WSDLPortImpl port = tmpWsdlService.getMatchingPort(portTypeName);
alanb@368 451 if (port == null) {
alanb@368 452 throw new WebServiceException(ClientMessages.UNDEFINED_PORT_TYPE(portTypeName));
alanb@368 453 }
ohair@286 454 QName portName = port.getName();
ohair@286 455 return getPort(portName, portInterface,features);
ohair@286 456 }
ohair@286 457
ohair@286 458 public <T> T getPort(Class<T> portInterface) throws WebServiceException {
ohair@286 459 return getPort(portInterface, EMPTY_FEATURES);
ohair@286 460 }
ohair@286 461
ohair@286 462 public void addPort(QName portName, String bindingId, String endpointAddress) throws WebServiceException {
ohair@286 463 if (!ports.containsKey(portName)) {
ohair@286 464 BindingID bid = (bindingId == null) ? BindingID.SOAP11_HTTP : BindingID.parse(bindingId);
ohair@286 465 ports.put(portName,
ohair@286 466 new PortInfo(this, (endpointAddress == null) ? null :
ohair@286 467 EndpointAddress.create(endpointAddress), portName, bid));
ohair@286 468 } else
ohair@286 469 throw new WebServiceException(DispatchMessages.DUPLICATE_PORT(portName.toString()));
ohair@286 470 }
ohair@286 471
ohair@286 472
ohair@286 473 public <T> Dispatch<T> createDispatch(QName portName, Class<T> aClass, Service.Mode mode) throws WebServiceException {
ohair@286 474 return createDispatch(portName, aClass, mode, EMPTY_FEATURES);
ohair@286 475 }
ohair@286 476
ohair@286 477 @Override
ohair@286 478 public <T> Dispatch<T> createDispatch(QName portName, WSEndpointReference wsepr, Class<T> aClass, Service.Mode mode, WebServiceFeature... features) {
ohair@286 479 return createDispatch(portName, wsepr, aClass, mode, new WebServiceFeatureList(features));
ohair@286 480 }
ohair@286 481
ohair@286 482 public <T> Dispatch<T> createDispatch(QName portName, WSEndpointReference wsepr, Class<T> aClass, Service.Mode mode, WebServiceFeatureList features) {
ohair@286 483 PortInfo port = safeGetPort(portName);
ohair@286 484
ohair@286 485 ComponentFeature cf = features.get(ComponentFeature.class);
ohair@286 486 if (cf != null && !Target.STUB.equals(cf.getTarget())) {
ohair@286 487 throw new IllegalArgumentException();
ohair@286 488 }
alanb@368 489 ComponentsFeature csf = features.get(ComponentsFeature.class);
alanb@368 490 if (csf != null) {
alanb@368 491 for (ComponentFeature cfi : csf.getComponentFeatures()) {
alanb@368 492 if (!Target.STUB.equals(cfi.getTarget()))
alanb@368 493 throw new IllegalArgumentException();
alanb@368 494 }
alanb@368 495 }
ohair@286 496 features.addAll(this.features);
ohair@286 497
ohair@286 498 BindingImpl binding = port.createBinding(features, null, null);
ohair@286 499 binding.setMode(mode);
ohair@286 500 Dispatch<T> dispatch = Stubs.createDispatch(port, this, binding, aClass, mode, wsepr);
ohair@286 501 serviceInterceptor.postCreateDispatch((WSBindingProvider) dispatch);
ohair@286 502 return dispatch;
ohair@286 503 }
ohair@286 504
ohair@286 505 public <T> Dispatch<T> createDispatch(QName portName, Class<T> aClass, Service.Mode mode, WebServiceFeature... features) {
ohair@286 506 return createDispatch(portName, aClass, mode, new WebServiceFeatureList(features));
ohair@286 507 }
ohair@286 508
ohair@286 509 public <T> Dispatch<T> createDispatch(QName portName, Class<T> aClass, Service.Mode mode, WebServiceFeatureList features) {
ohair@286 510 WSEndpointReference wsepr = null;
ohair@286 511 boolean isAddressingEnabled = false;
ohair@286 512 AddressingFeature af = features.get(AddressingFeature.class);
ohair@286 513 if (af == null) {
ohair@286 514 af = this.features.get(AddressingFeature.class);
ohair@286 515 }
ohair@286 516 if (af != null && af.isEnabled())
ohair@286 517 isAddressingEnabled = true;
ohair@286 518 MemberSubmissionAddressingFeature msa = features.get(MemberSubmissionAddressingFeature.class);
ohair@286 519 if (msa == null) {
ohair@286 520 msa = this.features.get(MemberSubmissionAddressingFeature.class);
ohair@286 521 }
ohair@286 522 if (msa != null && msa.isEnabled())
ohair@286 523 isAddressingEnabled = true;
ohair@286 524 if(isAddressingEnabled && wsdlService != null && wsdlService.get(portName) != null) {
ohair@286 525 wsepr = wsdlService.get(portName).getEPR();
ohair@286 526 }
ohair@286 527 return createDispatch(portName, wsepr, aClass, mode, features);
ohair@286 528 }
ohair@286 529
ohair@286 530 public <T> Dispatch<T> createDispatch(EndpointReference endpointReference, Class<T> type, Service.Mode mode, WebServiceFeature... features) {
ohair@286 531 WSEndpointReference wsepr = new WSEndpointReference(endpointReference);
ohair@286 532 QName portName = addPortEpr(wsepr);
ohair@286 533 return createDispatch(portName, wsepr, type, mode, features);
ohair@286 534 }
ohair@286 535
ohair@286 536 /**
ohair@286 537 * Obtains {@link PortInfo} for the given name, with error check.
ohair@286 538 */
ohair@286 539 public
ohair@286 540 @NotNull
ohair@286 541 PortInfo safeGetPort(QName portName) {
ohair@286 542 PortInfo port = ports.get(portName);
ohair@286 543 if (port == null) {
ohair@286 544 throw new WebServiceException(ClientMessages.INVALID_PORT_NAME(portName, buildNameList(ports.keySet())));
ohair@286 545 }
ohair@286 546 return port;
ohair@286 547 }
ohair@286 548
ohair@286 549 private StringBuilder buildNameList(Collection<QName> names) {
ohair@286 550 StringBuilder sb = new StringBuilder();
ohair@286 551 for (QName qn : names) {
ohair@286 552 if (sb.length() > 0) sb.append(',');
ohair@286 553 sb.append(qn);
ohair@286 554 }
ohair@286 555 return sb;
ohair@286 556 }
ohair@286 557
ohair@286 558 public EndpointAddress getEndpointAddress(QName qName) {
ohair@286 559 PortInfo p = ports.get(qName);
ohair@286 560 return p != null ? p.targetEndpoint : null;
ohair@286 561 }
ohair@286 562
ohair@286 563 public Dispatch<Object> createDispatch(QName portName, JAXBContext jaxbContext, Service.Mode mode) throws WebServiceException {
ohair@286 564 return createDispatch(portName, jaxbContext, mode, EMPTY_FEATURES);
ohair@286 565 }
ohair@286 566
ohair@286 567 @Override
ohair@286 568 public Dispatch<Object> createDispatch(QName portName, WSEndpointReference wsepr, JAXBContext jaxbContext, Service.Mode mode, WebServiceFeature... features) {
ohair@286 569 return createDispatch(portName, wsepr, jaxbContext, mode, new WebServiceFeatureList(features));
ohair@286 570 }
ohair@286 571
ohair@286 572 protected Dispatch<Object> createDispatch(QName portName, WSEndpointReference wsepr, JAXBContext jaxbContext, Service.Mode mode, WebServiceFeatureList features) {
ohair@286 573 PortInfo port = safeGetPort(portName);
ohair@286 574
ohair@286 575 ComponentFeature cf = features.get(ComponentFeature.class);
ohair@286 576 if (cf != null && !Target.STUB.equals(cf.getTarget())) {
ohair@286 577 throw new IllegalArgumentException();
ohair@286 578 }
alanb@368 579 ComponentsFeature csf = features.get(ComponentsFeature.class);
alanb@368 580 if (csf != null) {
alanb@368 581 for (ComponentFeature cfi : csf.getComponentFeatures()) {
alanb@368 582 if (!Target.STUB.equals(cfi.getTarget()))
alanb@368 583 throw new IllegalArgumentException();
alanb@368 584 }
alanb@368 585 }
ohair@286 586 features.addAll(this.features);
ohair@286 587
ohair@286 588 BindingImpl binding = port.createBinding(features, null, null);
ohair@286 589 binding.setMode(mode);
ohair@286 590 Dispatch<Object> dispatch = Stubs.createJAXBDispatch(
ohair@286 591 port, binding, jaxbContext, mode,wsepr);
ohair@286 592 serviceInterceptor.postCreateDispatch((WSBindingProvider)dispatch);
ohair@286 593 return dispatch;
ohair@286 594 }
ohair@286 595
ohair@286 596 @Override
ohair@286 597 public @NotNull Container getContainer() {
ohair@286 598 return container;
ohair@286 599 }
ohair@286 600
ohair@286 601 public Dispatch<Object> createDispatch(QName portName, JAXBContext jaxbContext, Service.Mode mode, WebServiceFeature... webServiceFeatures) {
ohair@286 602 return createDispatch(portName, jaxbContext, mode, new WebServiceFeatureList(webServiceFeatures));
ohair@286 603 }
ohair@286 604
ohair@286 605 protected Dispatch<Object> createDispatch(QName portName, JAXBContext jaxbContext, Service.Mode mode, WebServiceFeatureList features) {
ohair@286 606 WSEndpointReference wsepr = null;
ohair@286 607 boolean isAddressingEnabled = false;
ohair@286 608 AddressingFeature af = features.get(AddressingFeature.class);
ohair@286 609 if (af == null) {
ohair@286 610 af = this.features.get(AddressingFeature.class);
ohair@286 611 }
ohair@286 612 if (af != null && af.isEnabled())
ohair@286 613 isAddressingEnabled = true;
ohair@286 614 MemberSubmissionAddressingFeature msa = features.get(MemberSubmissionAddressingFeature.class);
ohair@286 615 if (msa == null) {
ohair@286 616 msa = this.features.get(MemberSubmissionAddressingFeature.class);
ohair@286 617 }
ohair@286 618 if (msa != null && msa.isEnabled())
ohair@286 619 isAddressingEnabled = true;
ohair@286 620 if(isAddressingEnabled && wsdlService != null && wsdlService.get(portName) != null) {
ohair@286 621 wsepr = wsdlService.get(portName).getEPR();
ohair@286 622 }
ohair@286 623 return createDispatch(portName, wsepr, jaxbContext, mode, features);
ohair@286 624 }
ohair@286 625
ohair@286 626 public Dispatch<Object> createDispatch(EndpointReference endpointReference, JAXBContext context, Service.Mode mode, WebServiceFeature... features) {
ohair@286 627 WSEndpointReference wsepr = new WSEndpointReference(endpointReference);
ohair@286 628 QName portName = addPortEpr(wsepr);
ohair@286 629 return createDispatch(portName, wsepr, context, mode, features);
ohair@286 630 }
ohair@286 631
ohair@286 632 private QName addPortEpr(WSEndpointReference wsepr) {
ohair@286 633 if (wsepr == null)
ohair@286 634 throw new WebServiceException(ProviderApiMessages.NULL_EPR());
ohair@286 635 QName eprPortName = getPortNameFromEPR(wsepr, null);
ohair@286 636 //add Port, if it does n't exist;
ohair@286 637 // TODO: what if it has different epr address?
ohair@286 638 {
ohair@286 639 PortInfo portInfo = new PortInfo(this, (wsepr.getAddress() == null) ? null : EndpointAddress.create(wsepr.getAddress()), eprPortName,
ohair@286 640 getPortModel(wsdlService, eprPortName).getBinding().getBindingId());
ohair@286 641 if (!ports.containsKey(eprPortName)) {
ohair@286 642 ports.put(eprPortName, portInfo);
ohair@286 643 }
ohair@286 644 }
ohair@286 645 return eprPortName;
ohair@286 646 }
ohair@286 647
ohair@286 648 /**
ohair@286 649 *
ohair@286 650 * @param wsepr EndpointReference from which portName will be extracted.
ohair@286 651 * If EndpointName ( port name) is null in EPR, then it will try to get if from WSDLModel using portType QName
ohair@286 652 * @param portTypeName
ohair@286 653 * should be null in dispatch case
ohair@286 654 * should be non null in SEI case
ohair@286 655 * @return
ohair@286 656 * port name from EPR after validating various metadat elements.
ohair@286 657 * Also if service instance does n't have wsdl,
ohair@286 658 * then it gets the WSDL metadata from EPR and builds wsdl model.
ohair@286 659 */
ohair@286 660 private QName getPortNameFromEPR(@NotNull WSEndpointReference wsepr, @Nullable QName portTypeName) {
ohair@286 661 QName portName;
ohair@286 662 WSEndpointReference.Metadata metadata = wsepr.getMetaData();
ohair@286 663 QName eprServiceName = metadata.getServiceName();
ohair@286 664 QName eprPortName = metadata.getPortName();
ohair@286 665 if ((eprServiceName != null ) && !eprServiceName.equals(serviceName)) {
ohair@286 666 throw new WebServiceException("EndpointReference WSDL ServiceName differs from Service Instance WSDL Service QName.\n"
ohair@286 667 + " The two Service QNames must match");
ohair@286 668 }
ohair@286 669 if (wsdlService == null) {
ohair@286 670 Source eprWsdlSource = metadata.getWsdlSource();
ohair@286 671 if (eprWsdlSource == null) {
ohair@286 672 throw new WebServiceException(ProviderApiMessages.NULL_WSDL());
ohair@286 673 }
ohair@286 674 try {
ohair@286 675 WSDLModelImpl eprWsdlMdl = parseWSDL(new URL(wsepr.getAddress()), eprWsdlSource, null);
ohair@286 676 wsdlService = eprWsdlMdl.getService(serviceName);
ohair@286 677 if (wsdlService == null)
ohair@286 678 throw new WebServiceException(ClientMessages.INVALID_SERVICE_NAME(serviceName,
ohair@286 679 buildNameList(eprWsdlMdl.getServices().keySet())));
ohair@286 680 } catch (MalformedURLException e) {
ohair@286 681 throw new WebServiceException(ClientMessages.INVALID_ADDRESS(wsepr.getAddress()));
ohair@286 682 }
ohair@286 683 }
ohair@286 684 portName = eprPortName;
ohair@286 685
ohair@286 686 if (portName == null && portTypeName != null) {
ohair@286 687 //get the first port corresponding to the SEI
ohair@286 688 WSDLPortImpl port = wsdlService.getMatchingPort(portTypeName);
ohair@286 689 if (port == null)
ohair@286 690 throw new WebServiceException(ClientMessages.UNDEFINED_PORT_TYPE(portTypeName));
ohair@286 691 portName = port.getName();
ohair@286 692 }
ohair@286 693 if (portName == null)
ohair@286 694 throw new WebServiceException(ProviderApiMessages.NULL_PORTNAME());
ohair@286 695 if (wsdlService.get(portName) == null)
ohair@286 696 throw new WebServiceException(ClientMessages.INVALID_EPR_PORT_NAME(portName, buildWsdlPortNames()));
ohair@286 697
ohair@286 698 return portName;
ohair@286 699
ohair@286 700 }
ohair@286 701
ohair@286 702 private WSDLServiceImpl getWSDLModelfromSEI(final Class sei) {
ohair@286 703 WebService ws = AccessController.doPrivileged(new PrivilegedAction<WebService>() {
ohair@286 704 public WebService run() {
ohair@286 705 return (WebService) sei.getAnnotation(WebService.class);
ohair@286 706 }
ohair@286 707 });
ohair@286 708 if (ws == null || ws.wsdlLocation().equals(""))
ohair@286 709 return null;
ohair@286 710 String wsdlLocation = ws.wsdlLocation();
ohair@286 711 wsdlLocation = JAXWSUtils.absolutize(JAXWSUtils.getFileOrURLName(wsdlLocation));
ohair@286 712 Source wsdl = new StreamSource(wsdlLocation);
ohair@286 713 WSDLServiceImpl service = null;
ohair@286 714
ohair@286 715 try {
ohair@286 716 URL url = wsdl.getSystemId() == null ? null : new URL(wsdl.getSystemId());
ohair@286 717 WSDLModelImpl model = parseWSDL(url, wsdl, sei);
ohair@286 718 service = model.getService(this.serviceName);
ohair@286 719 if (service == null)
ohair@286 720 throw new WebServiceException(
ohair@286 721 ClientMessages.INVALID_SERVICE_NAME(this.serviceName,
ohair@286 722 buildNameList(model.getServices().keySet())));
ohair@286 723 } catch (MalformedURLException e) {
ohair@286 724 throw new WebServiceException(ClientMessages.INVALID_WSDL_URL(wsdl.getSystemId()));
ohair@286 725 }
ohair@286 726 return service;
ohair@286 727 }
ohair@286 728
ohair@286 729 public QName getServiceName() {
ohair@286 730 return serviceName;
ohair@286 731 }
ohair@286 732
ohair@286 733 public Class getServiceClass() {
ohair@286 734 return serviceClass;
ohair@286 735 }
ohair@286 736
ohair@286 737 public Iterator<QName> getPorts() throws WebServiceException {
ohair@286 738 // KK: the spec seems to be ambigous about whether
ohair@286 739 // this returns ports that are dynamically added or not.
ohair@286 740 return ports.keySet().iterator();
ohair@286 741 }
ohair@286 742
alanb@368 743 @Override
ohair@286 744 public URL getWSDLDocumentLocation() {
ohair@286 745 if(wsdlService==null) return null;
ohair@286 746 try {
ohair@286 747 return new URL(wsdlService.getParent().getLocation().getSystemId());
ohair@286 748 } catch (MalformedURLException e) {
ohair@286 749 throw new AssertionError(e); // impossible
ohair@286 750 }
ohair@286 751 }
ohair@286 752
ohair@286 753 private <T> T createEndpointIFBaseProxy(@Nullable WSEndpointReference epr,QName portName, Class<T> portInterface,
ohair@286 754 WebServiceFeatureList webServiceFeatures, SEIPortInfo eif) {
ohair@286 755 //fail if service doesnt have WSDL
alanb@368 756 if (wsdlService == null) {
ohair@286 757 throw new WebServiceException(ClientMessages.INVALID_SERVICE_NO_WSDL(serviceName));
alanb@368 758 }
ohair@286 759
ohair@286 760 if (wsdlService.get(portName)==null) {
ohair@286 761 throw new WebServiceException(
ohair@286 762 ClientMessages.INVALID_PORT_NAME(portName,buildWsdlPortNames()));
ohair@286 763 }
ohair@286 764
ohair@286 765 BindingImpl binding = eif.createBinding(webServiceFeatures,portInterface);
ohair@286 766 InvocationHandler pis = getStubHandler(binding, eif, epr);
ohair@286 767
ohair@286 768 // When creating the proxy, use a ClassLoader that can load classes
ohair@286 769 // from both the interface class and also from this classes
ohair@286 770 // classloader. This is necessary when this code is used in systems
ohair@286 771 // such as OSGi where the class loader for the interface class may
ohair@286 772 // not be able to load internal JAX-WS classes like
ohair@286 773 // "WSBindingProvider", but the class loader for this class may not
ohair@286 774 // be able to load the interface class.
ohair@286 775 ClassLoader loader =
ohair@286 776 getDelegatingLoader(portInterface.getClassLoader(),
ohair@286 777 WSServiceDelegate.class.getClassLoader());
ohair@286 778 T proxy = portInterface.cast(Proxy.newProxyInstance(loader,
ohair@286 779 new Class[]{portInterface, WSBindingProvider.class, Closeable.class}, pis));
ohair@286 780 if (serviceInterceptor != null) {
ohair@286 781 serviceInterceptor.postCreateProxy((WSBindingProvider)proxy, portInterface);
ohair@286 782 }
ohair@286 783 return proxy;
ohair@286 784 }
ohair@286 785
ohair@286 786 protected InvocationHandler getStubHandler(BindingImpl binding, SEIPortInfo eif, @Nullable WSEndpointReference epr) {
ohair@286 787 return new SEIStub(eif, binding, eif.model, epr);
ohair@286 788 }
ohair@286 789
ohair@286 790 /**
ohair@286 791 * Lists up the port names in WSDL. For error diagnostics.
ohair@286 792 */
ohair@286 793 private StringBuilder buildWsdlPortNames() {
ohair@286 794 Set<QName> wsdlPortNames = new HashSet<QName>();
alanb@368 795 for (WSDLPortImpl port : wsdlService.getPorts()) {
ohair@286 796 wsdlPortNames.add(port.getName());
alanb@368 797 }
ohair@286 798 return buildNameList(wsdlPortNames);
ohair@286 799 }
ohair@286 800
ohair@286 801 /**
ohair@286 802 * Obtains a {@link WSDLPortImpl} with error check.
ohair@286 803 *
ohair@286 804 * @return guaranteed to be non-null.
ohair@286 805 */
ohair@286 806 public @NotNull WSDLPortImpl getPortModel(WSDLServiceImpl wsdlService, QName portName) {
ohair@286 807 WSDLPortImpl port = wsdlService.get(portName);
ohair@286 808 if (port == null)
ohair@286 809 throw new WebServiceException(
ohair@286 810 ClientMessages.INVALID_PORT_NAME(portName,buildWsdlPortNames()));
ohair@286 811 return port;
ohair@286 812 }
ohair@286 813
ohair@286 814 /**
ohair@286 815 * Contributes to the construction of {@link WSServiceDelegate} by filling in
ohair@286 816 * {@link SEIPortInfo} about a given SEI (linked from the {@link Service}-derived class.)
ohair@286 817 */
ohair@286 818 //todo: valid port in wsdl
ohair@286 819 private SEIPortInfo addSEI(QName portName, Class portInterface, WebServiceFeatureList features) throws WebServiceException {
ohair@286 820 boolean ownModel = useOwnSEIModel(features);
ohair@286 821 if (ownModel) {
ohair@286 822 // Create a new model and do not cache it
ohair@286 823 return createSEIPortInfo(portName, portInterface, features);
ohair@286 824 }
ohair@286 825
ohair@286 826 SEIPortInfo spi = seiContext.get(portName);
ohair@286 827 if (spi == null) {
ohair@286 828 spi = createSEIPortInfo(portName, portInterface, features);
ohair@286 829 seiContext.put(spi.portName, spi);
ohair@286 830 ports.put(spi.portName, spi);
ohair@286 831 }
ohair@286 832 return spi;
ohair@286 833 }
ohair@286 834
ohair@286 835 public SEIModel buildRuntimeModel(QName serviceName, QName portName, Class portInterface, WSDLPort wsdlPort, WebServiceFeatureList features) {
ohair@286 836 DatabindingFactory fac = DatabindingFactory.newInstance();
ohair@286 837 DatabindingConfig config = new DatabindingConfig();
ohair@286 838 config.setContractClass(portInterface);
ohair@286 839 config.getMappingInfo().setServiceName(serviceName);
ohair@286 840 config.setWsdlPort(wsdlPort);
ohair@286 841 config.setFeatures(features);
ohair@286 842 config.setClassLoader(portInterface.getClassLoader());
ohair@286 843 config.getMappingInfo().setPortName(portName);
ohair@286 844
alanb@368 845 // if ExternalMetadataFeature present, ExternalMetadataReader will be created ...
alanb@368 846 config.setMetadataReader(getMetadadaReader(features, portInterface.getClassLoader()));
alanb@368 847
ohair@286 848 com.sun.xml.internal.ws.db.DatabindingImpl rt = (com.sun.xml.internal.ws.db.DatabindingImpl)fac.createRuntime(config);
ohair@286 849
ohair@286 850 return rt.getModel();
ohair@286 851 }
ohair@286 852
alanb@368 853 private MetadataReader getMetadadaReader(WebServiceFeatureList features, ClassLoader classLoader) {
alanb@368 854 if (features == null) return null;
alanb@368 855 com.oracle.webservices.internal.api.databinding.ExternalMetadataFeature ef =
alanb@368 856 features.get(com.oracle.webservices.internal.api.databinding.ExternalMetadataFeature.class);
alanb@368 857 // TODO-Miran: would it be necessary to disable secure xml processing?
alanb@368 858 if (ef != null)
alanb@368 859 return ef.getMetadataReader(classLoader, false);
alanb@368 860 return null;
alanb@368 861 }
alanb@368 862
ohair@286 863 private SEIPortInfo createSEIPortInfo(QName portName, Class portInterface, WebServiceFeatureList features) {
ohair@286 864 WSDLPortImpl wsdlPort = getPortModel(wsdlService, portName);
ohair@286 865 SEIModel model = buildRuntimeModel(serviceName, portName, portInterface, wsdlPort, features);
ohair@286 866
ohair@286 867 return new SEIPortInfo(this, portInterface, (SOAPSEIModel) model, wsdlPort);
ohair@286 868 }
ohair@286 869
ohair@286 870 private boolean useOwnSEIModel(WebServiceFeatureList features) {
ohair@286 871 return features.contains(UsesJAXBContextFeature.class);
ohair@286 872 }
ohair@286 873
ohair@286 874 public WSDLServiceImpl getWsdlService() {
ohair@286 875 return wsdlService;
ohair@286 876 }
ohair@286 877
alanb@368 878 static class DaemonThreadFactory implements ThreadFactory {
alanb@368 879 @Override
ohair@286 880 public Thread newThread(Runnable r) {
ohair@286 881 Thread daemonThread = new Thread(r);
ohair@286 882 daemonThread.setDaemon(Boolean.TRUE);
ohair@286 883 return daemonThread;
ohair@286 884 }
ohair@286 885 }
ohair@286 886
ohair@286 887 protected static final WebServiceFeature[] EMPTY_FEATURES = new WebServiceFeature[0];
ohair@286 888
ohair@286 889 private static ClassLoader getDelegatingLoader(ClassLoader loader1, ClassLoader loader2) {
ohair@286 890 if (loader1 == null) return loader2;
ohair@286 891 if (loader2 == null) return loader1;
ohair@286 892 return new DelegatingLoader(loader1, loader2);
ohair@286 893 }
ohair@286 894
alanb@368 895 private static final class DelegatingLoader extends ClassLoader {
alanb@368 896 private final ClassLoader loader;
ohair@286 897
alanb@368 898 @Override
alanb@368 899 public int hashCode() {
alanb@368 900 final int prime = 31;
alanb@368 901 int result = 1;
alanb@368 902 result = prime * result
alanb@368 903 + ((loader == null) ? 0 : loader.hashCode());
alanb@368 904 result = prime * result
alanb@368 905 + ((getParent() == null) ? 0 : getParent().hashCode());
alanb@368 906 return result;
alanb@368 907 }
ohair@286 908
alanb@368 909 @Override
alanb@368 910 public boolean equals(Object obj) {
alanb@368 911 if (this == obj)
alanb@368 912 return true;
alanb@368 913 if (obj == null)
alanb@368 914 return false;
alanb@368 915 if (getClass() != obj.getClass())
alanb@368 916 return false;
alanb@368 917 DelegatingLoader other = (DelegatingLoader) obj;
alanb@368 918 if (loader == null) {
alanb@368 919 if (other.loader != null)
alanb@368 920 return false;
alanb@368 921 } else if (!loader.equals(other.loader))
alanb@368 922 return false;
alanb@368 923 if (getParent() == null) {
alanb@368 924 if (other.getParent() != null)
alanb@368 925 return false;
alanb@368 926 } else if (!getParent().equals(other.getParent()))
alanb@368 927 return false;
alanb@368 928 return true;
alanb@368 929 }
ohair@286 930
alanb@368 931 DelegatingLoader(ClassLoader loader1, ClassLoader loader2) {
alanb@368 932 super(loader2);
alanb@368 933 this.loader = loader1;
alanb@368 934 }
alanb@368 935
alanb@368 936 protected Class findClass(String name) throws ClassNotFoundException {
alanb@368 937 return loader.loadClass(name);
alanb@368 938 }
alanb@368 939
alanb@368 940 protected URL findResource(String name) {
alanb@368 941 return loader.getResource(name);
alanb@368 942 }
ohair@286 943 }
ohair@286 944 }

mercurial