src/share/jaxws_classes/com/sun/xml/internal/ws/api/WSService.java

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

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

merge

     1 /*
     2  * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    26 package com.sun.xml.internal.ws.api;
    28 import com.sun.istack.internal.NotNull;
    29 import com.sun.istack.internal.Nullable;
    30 import com.sun.xml.internal.ws.api.addressing.WSEndpointReference;
    31 import com.sun.xml.internal.ws.api.server.Container;
    32 import com.sun.xml.internal.ws.api.server.ContainerResolver;
    33 import com.sun.xml.internal.ws.api.server.WSEndpoint;
    34 import com.sun.xml.internal.ws.client.WSServiceDelegate;
    36 import javax.xml.bind.JAXBContext;
    37 import javax.xml.namespace.QName;
    38 import javax.xml.ws.Dispatch;
    39 import javax.xml.ws.EndpointReference;
    40 import javax.xml.ws.Service;
    41 import javax.xml.ws.Service.Mode;
    42 import javax.xml.ws.WebServiceException;
    43 import javax.xml.ws.WebServiceFeature;
    44 import javax.xml.ws.spi.ServiceDelegate;
    45 import java.lang.reflect.Field;
    46 import java.net.URL;
    47 import java.security.AccessController;
    48 import java.security.PrivilegedAction;
    49 import java.util.HashSet;
    50 import java.util.Set;
    51 import java.util.concurrent.CopyOnWriteArraySet;
    53 /**
    54  * JAX-WS implementation of {@link ServiceDelegate}.
    55  *
    56  * <p>
    57  * This abstract class is used only to improve the static type safety
    58  * of the JAX-WS internal API.
    59  *
    60  * <p>
    61  * The class name intentionally doesn't include "Delegate",
    62  * because the fact that it's a delegate is a detail of
    63  * the JSR-224 API, and for the layers above us this object
    64  * nevertheless represents {@link Service}. We want them
    65  * to think of this as an internal representation of a service.
    66  *
    67  * <p>
    68  * Only JAX-WS internal code may downcast this to {@link WSServiceDelegate}.
    69  *
    70  * @author Kohsuke Kawaguchi
    71  */
    72 public abstract class WSService extends ServiceDelegate implements ComponentRegistry {
    73         private final Set<Component> components = new CopyOnWriteArraySet<Component>();
    75         protected WSService() {
    76     }
    78     /**
    79      * Works like {@link #getPort(EndpointReference, Class, WebServiceFeature...)}
    80      * but takes {@link WSEndpointReference}.
    81      */
    82     public abstract <T> T getPort(WSEndpointReference epr, Class<T> portInterface, WebServiceFeature... features);
    84     /**
    85      * Works like {@link #createDispatch(javax.xml.ws.EndpointReference, java.lang.Class, javax.xml.ws.Service.Mode, javax.xml.ws.WebServiceFeature[])}
    86      * but it takes the port name separately, so that EPR without embedded metadata can be used.
    87      */
    88     public abstract <T> Dispatch<T> createDispatch(QName portName, WSEndpointReference wsepr, Class<T> aClass, Service.Mode mode, WebServiceFeature... features);
    90     /**
    91      * Works like {@link #createDispatch(javax.xml.ws.EndpointReference, javax.xml.bind.JAXBContext, javax.xml.ws.Service.Mode, javax.xml.ws.WebServiceFeature[])}
    92      * but it takes the port name separately, so that EPR without embedded metadata can be used.
    93      */
    94     public abstract Dispatch<Object> createDispatch(QName portName, WSEndpointReference wsepr, JAXBContext jaxbContext, Service.Mode mode, WebServiceFeature... features);
    96     /**
    97      * Gets the {@link Container} object.
    98      *
    99      * <p>
   100      * The components inside {@link WSEndpoint} uses this reference
   101      * to communicate with the hosting environment.
   102      *
   103      * @return
   104      *      always same object. If no "real" {@link Container} instance
   105      *      is given, {@link Container#NONE} will be returned.
   106      */
   107     public abstract @NotNull Container getContainer();
   109     public @Nullable <S> S getSPI(@NotNull Class<S> spiType) {
   110         for (Component c : components) {
   111                 S s = c.getSPI(spiType);
   112                 if (s != null)
   113                         return s;
   114         }
   116         return getContainer().getSPI(spiType);
   117     }
   119     public @NotNull Set<Component> getComponents() {
   120         return components;
   121     }
   123     /**
   124      * Create a <code>Service</code> instance.
   125      *
   126      * The specified WSDL document location and service qualified name MUST
   127      * uniquely identify a <code>wsdl:service</code> element.
   128      *
   129      * @param wsdlDocumentLocation URL for the WSDL document location
   130      *                             for the service
   131      * @param serviceName QName for the service
   132      * @throws WebServiceException If any error in creation of the
   133      *                    specified service.
   134      **/
   135     public static WSService create( URL wsdlDocumentLocation, QName serviceName) {
   136         return new WSServiceDelegate(wsdlDocumentLocation,serviceName,Service.class);
   137     }
   139     /**
   140      * Create a <code>Service</code> instance.
   141      *
   142      * @param serviceName QName for the service
   143      * @throws WebServiceException If any error in creation of the
   144      *                    specified service
   145      */
   146     public static WSService create(QName serviceName) {
   147         return create(null,serviceName);
   148     }
   150     /**
   151      * Creates a service with a dummy service name.
   152      */
   153     public static WSService create() {
   154         return create(null,new QName(WSService.class.getName(),"dummy"));
   155     }
   157     /**
   158      * Typed parameter bag used by {@link WSService#create(URL, QName, InitParams)}
   159      *
   160      * @since 2.1.3
   161      */
   162     public static final class InitParams {
   163         private Container container;
   164         /**
   165          * Sets the {@link Container} object used by the created service.
   166          * This allows the client to use a specific {@link Container} instance
   167          * as opposed to the one obtained by {@link ContainerResolver}.
   168          */
   169         public void setContainer(Container c) {
   170             this.container = c;
   171         }
   172         public Container getContainer() {
   173             return container;
   174         }
   175     }
   177     /**
   178      * To create a {@link Service}, we need to go through the API that doesn't let us
   179      * pass parameters, so as a hack we use thread local.
   180      */
   181     protected static final ThreadLocal<InitParams> INIT_PARAMS = new ThreadLocal<InitParams>();
   183     /**
   184      * Used as a immutable constant so that we can avoid null check.
   185      */
   186     protected static final InitParams EMPTY_PARAMS = new InitParams();
   188     /**
   189      * Creates a {@link Service} instance.
   190      *
   191      * <p>
   192      * This method works really like {@link Service#create(URL, QName)}
   193      * except it takes one more RI specific parameter.
   194      *
   195      * @param wsdlDocumentLocation
   196      *          {@code URL} for the WSDL document location for the service.
   197      *          Can be null, in which case WSDL is not loaded.
   198      * @param serviceName
   199      *          {@code QName} for the service.
   200      * @param properties
   201      *          Additional RI specific initialization parameters. Can be null.
   202      * @throws WebServiceException
   203      *          If any error in creation of the specified service.
   204      **/
   205     public static Service create( URL wsdlDocumentLocation, QName serviceName, InitParams properties) {
   206         if(INIT_PARAMS.get()!=null)
   207             throw new IllegalStateException("someone left non-null InitParams");
   208         INIT_PARAMS.set(properties);
   209         try {
   210             Service svc = Service.create(wsdlDocumentLocation, serviceName);
   211             if(INIT_PARAMS.get()!=null)
   212                 throw new IllegalStateException("Service "+svc+" didn't recognize InitParams");
   213             return svc;
   214         } finally {
   215             // even in case of an exception still reset INIT_PARAMS
   216             INIT_PARAMS.set(null);
   217         }
   218     }
   220     /**
   221      * Obtains the {@link WSService} that's encapsulated inside a {@link Service}.
   222      *
   223      * @throws IllegalArgumentException
   224      *      if the given service object is not from the JAX-WS RI.
   225      */
   226     public static WSService unwrap(final Service svc) {
   227         return AccessController.doPrivileged(new PrivilegedAction<WSService>() {
   228             public WSService run() {
   229                 try {
   230                     Field f = svc.getClass().getField("delegate");
   231                     f.setAccessible(true);
   232                     Object delegate = f.get(svc);
   233                     if(!(delegate instanceof WSService))
   234                         throw new IllegalArgumentException();
   235                     return (WSService) delegate;
   236                 } catch (NoSuchFieldException e) {
   237                     AssertionError x = new AssertionError("Unexpected service API implementation");
   238                     x.initCause(e);
   239                     throw x;
   240                 } catch (IllegalAccessException e) {
   241                     IllegalAccessError x = new IllegalAccessError(e.getMessage());
   242                     x.initCause(e);
   243                     throw x;
   244                 }
   245             }
   246         });
   247     }
   248 }

mercurial