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

Thu, 31 Aug 2017 15:18:52 +0800

author
aoqi
date
Thu, 31 Aug 2017 15:18:52 +0800
changeset 637
9c07ef4934dd
parent 408
b0610cd08440
parent 0
373ffda63c9a
permissions
-rw-r--r--

merge

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

mercurial