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

Fri, 04 Oct 2013 16:21:34 +0100

author
mkos
date
Fri, 04 Oct 2013 16:21:34 +0100
changeset 408
b0610cd08440
parent 384
8f2986ff0235
child 637
9c07ef4934dd
permissions
-rw-r--r--

8025054: Update JAX-WS RI integration to 2.2.9-b130926.1035
Reviewed-by: chegar

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

mercurial