Save This Page
Home » Open-JDK-6.b17-src » com.sun.xml.internal » ws » transport » http » server » [javadoc | source]
    1   /*
    2    * Copyright 2005-2006 Sun Microsystems, Inc.  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.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   
   26   package com.sun.xml.internal.ws.transport.http.server;
   27   
   28   import com.sun.istack.internal.Nullable;
   29   import com.sun.xml.internal.stream.buffer.XMLStreamBufferResult;
   30   import com.sun.xml.internal.ws.api.WSBinding;
   31   import com.sun.xml.internal.ws.api.BindingID;
   32   import com.sun.xml.internal.ws.api.server.WSEndpoint;
   33   import com.sun.xml.internal.ws.binding.BindingImpl;
   34   import com.sun.xml.internal.ws.api.server.InstanceResolver;
   35   import com.sun.xml.internal.ws.api.server.SDDocumentSource;
   36   import com.sun.xml.internal.ws.server.EndpointFactory;
   37   import com.sun.xml.internal.ws.server.ServerRtException;
   38   import com.sun.xml.internal.ws.util.xml.XmlUtil;
   39   import com.sun.istack.internal.NotNull;
   40   
   41   import java.net.MalformedURLException;
   42   
   43   import javax.xml.namespace.QName;
   44   import javax.xml.transform.Source;
   45   import javax.xml.transform.Transformer;
   46   import javax.xml.transform.TransformerException;
   47   import javax.xml.ws;
   48   import javax.xml.ws.wsaddressing.W3CEndpointReference;
   49   import javax.xml.parsers.ParserConfigurationException;
   50   
   51   import java.io.IOException;
   52   import java.net.URL;
   53   import java.util.ArrayList;
   54   import java.util.Collections;
   55   import java.util.HashMap;
   56   import java.util.List;
   57   import java.util.Map;
   58   import java.util.concurrent.Executor;
   59   
   60   import org.xml.sax.EntityResolver;
   61   import org.xml.sax.SAXException;
   62   import org.w3c.dom.Element;
   63   
   64   
   65   /**
   66    * Implements {@link Endpoint}.
   67    * <p/>
   68    * <p/>
   69    * This class accumulates the information necessary to create
   70    * {@link WSEndpoint}, and then when {@link #publish} method
   71    * is called it will be created.
   72    * <p/>
   73    * <p/>
   74    * This object also allows accumulated information to be retrieved.
   75    *
   76    * @author Jitendra Kotamraju
   77    */
   78   public class EndpointImpl extends Endpoint {
   79   
   80       private static final WebServicePermission ENDPOINT_PUBLISH_PERMISSION =
   81               new WebServicePermission("publishEndpoint");
   82   
   83       /**
   84        * Once the service is published, this field will
   85        * be set to the {@link HttpEndpoint} instance.
   86        * <p/>
   87        * But don't declare the type as {@link HttpEndpoint}
   88        * to avoid static type dependency that cause the class loading to
   89        * fail if the LW HTTP server doesn't exist.
   90        */
   91       private Object actualEndpoint;
   92   
   93       // information accumulated for creating WSEndpoint
   94       private final WSBinding binding;
   95       private final Object implementor;
   96       private List<Source> metadata;
   97       private Executor executor;
   98       private Map<String, Object> properties = Collections.emptyMap(); // always non-null
   99       private boolean stopped;
  100   
  101   
  102       public EndpointImpl(@NotNull BindingID bindingId, @NotNull Object impl) {
  103           binding = BindingImpl.create(bindingId);
  104           implementor = impl;
  105       }
  106   
  107       /**
  108        * Wraps an already created {@link WSEndpoint} into an {@link EndpointImpl},
  109        * and immediately publishes it with the given context.
  110        *
  111        * @deprecated This is a backdoor method. Don't use it unless you know what you are doing.
  112        */
  113       public EndpointImpl(WSEndpoint wse, Object serverContext) {
  114           actualEndpoint = new HttpEndpoint(wse, executor);
  115           ((HttpEndpoint) actualEndpoint).publish(serverContext);
  116           binding = wse.getBinding();
  117           implementor = null; // this violates the semantics, but hey, this is a backdoor.
  118       }
  119   
  120       public Binding getBinding() {
  121           return binding;
  122       }
  123   
  124       public Object getImplementor() {
  125           return implementor;
  126       }
  127   
  128       public void publish(String address) {
  129           canPublish();
  130           URL url;
  131           try {
  132               url = new URL(address);
  133           } catch (MalformedURLException ex) {
  134               throw new IllegalArgumentException("Cannot create URL for this address " + address);
  135           }
  136           if (!url.getProtocol().equals("http")) {
  137               throw new IllegalArgumentException(url.getProtocol() + " protocol based address is not supported");
  138           }
  139           if (!url.getPath().startsWith("/")) {
  140               throw new IllegalArgumentException("Incorrect WebService address=" + address +
  141                       ". The address's path should start with /");
  142           }
  143           createEndpoint();
  144           ((HttpEndpoint) actualEndpoint).publish(address);
  145       }
  146   
  147       public void publish(Object serverContext) {
  148           canPublish();
  149           if (!com.sun.net.httpserver.HttpContext.class.isAssignableFrom(serverContext.getClass())) {
  150               throw new IllegalArgumentException(serverContext.getClass() + " is not a supported context.");
  151           }
  152           createEndpoint();
  153           ((HttpEndpoint) actualEndpoint).publish(serverContext);
  154       }
  155   
  156       public void stop() {
  157           if (isPublished()) {
  158               ((HttpEndpoint) actualEndpoint).stop();
  159               actualEndpoint = null;
  160               stopped = true;
  161           }
  162       }
  163   
  164       public boolean isPublished() {
  165           return actualEndpoint != null;
  166       }
  167   
  168       public List<Source> getMetadata() {
  169           return metadata;
  170       }
  171   
  172       public void setMetadata(java.util.List<Source> metadata) {
  173           if (isPublished()) {
  174               throw new IllegalStateException("Cannot set Metadata. Endpoint is already published");
  175           }
  176           this.metadata = metadata;
  177       }
  178   
  179       public Executor getExecutor() {
  180           return executor;
  181       }
  182   
  183       public void setExecutor(Executor executor) {
  184           this.executor = executor;
  185       }
  186   
  187       public Map<String, Object> getProperties() {
  188           return new HashMap<String, Object>(properties);
  189       }
  190   
  191       public void setProperties(Map<String, Object> map) {
  192           this.properties = new HashMap<String, Object>(map);
  193       }
  194   
  195       /*
  196       * Checks the permission of "publishEndpoint" before accessing HTTP classes.
  197       * Also it checks if there is an available HTTP server implementation.
  198       */
  199       private void createEndpoint() {
  200           // Checks permission for "publishEndpoint"
  201           SecurityManager sm = System.getSecurityManager();
  202           if (sm != null) {
  203               sm.checkPermission(ENDPOINT_PUBLISH_PERMISSION);
  204           }
  205   
  206           // See if HttpServer implementation is available
  207           try {
  208               Class.forName("com.sun.net.httpserver.HttpServer");
  209           } catch (Exception e) {
  210               throw new UnsupportedOperationException("Couldn't load light weight http server", e);
  211           }
  212   
  213           WSEndpoint wse = WSEndpoint.create(
  214                   (Class<?>) implementor.getClass(), true,
  215                   InstanceResolver.createSingleton(implementor).createInvoker(),
  216                   getProperty(QName.class, Endpoint.WSDL_SERVICE),
  217                   getProperty(QName.class, Endpoint.WSDL_PORT),
  218                   null /* no container */,
  219                   binding,
  220                   getPrimaryWsdl(),
  221                   buildDocList(),
  222                   (EntityResolver) null
  223           );
  224           // Don't load HttpEndpoint class before as it may load HttpServer classes
  225           actualEndpoint = new HttpEndpoint(wse, executor);
  226       }
  227   
  228       private <T> T getProperty(Class<T> type, String key) {
  229           Object o = properties.get(key);
  230           if (o == null) return null;
  231           if (type.isInstance(o))
  232               return type.cast(o);
  233           else
  234               throw new IllegalArgumentException("Property " + key + " has to be of type " + type);   // i18n
  235       }
  236   
  237       /**
  238        * Convert metadata sources using identity transform. So that we can
  239        * reuse the Source object multiple times.
  240        */
  241       private List<SDDocumentSource> buildDocList() {
  242           List<SDDocumentSource> r = new ArrayList<SDDocumentSource>();
  243   
  244           if (metadata != null) {
  245               Transformer transformer = XmlUtil.newTransformer();
  246               for (Source source : metadata) {
  247                   try {
  248                       XMLStreamBufferResult xsbr = XmlUtil.identityTransform(source, new XMLStreamBufferResult());
  249                       String systemId = source.getSystemId();
  250   
  251                       r.add(SDDocumentSource.create(new URL(systemId), xsbr.getXMLStreamBuffer()));
  252                   } catch (TransformerException te) {
  253                       throw new ServerRtException("server.rt.err", te);
  254                   } catch (IOException te) {
  255                       throw new ServerRtException("server.rt.err", te);
  256                   } catch (SAXException e) {
  257                       throw new ServerRtException("server.rt.err", e);
  258                   } catch (ParserConfigurationException e) {
  259                       throw new ServerRtException("server.rt.err", e);
  260                   }
  261               }
  262           }
  263   
  264           return r;
  265       }
  266   
  267       /**
  268        * Gets wsdl from @WebService or @WebServiceProvider
  269        */
  270       private @Nullable SDDocumentSource getPrimaryWsdl() {
  271           Class implType = implementor.getClass();
  272           // Takes care of @WebService, @WebServiceProvider's wsdlLocation
  273           EndpointFactory.verifyImplementorClass(implType);
  274           String wsdlLocation = EndpointFactory.getWsdlLocation(implType);
  275           if (wsdlLocation != null) {
  276               ClassLoader cl = implType.getClassLoader();
  277               URL url = cl.getResource(wsdlLocation);
  278               if (url != null) {
  279                   return SDDocumentSource.create(url);
  280               }
  281               throw new ServerRtException("cannot.load.wsdl", wsdlLocation);
  282           }
  283           return null;
  284       }
  285   
  286       private void canPublish() {
  287           if (isPublished()) {
  288               throw new IllegalStateException(
  289                       "Cannot publish this endpoint. Endpoint has been already published.");
  290           }
  291           if (stopped) {
  292               throw new IllegalStateException(
  293                       "Cannot publish this endpoint. Endpoint has been already stopped.");
  294           }
  295       }
  296   
  297       public EndpointReference getEndpointReference(Element...referenceParameters) {
  298           return getEndpointReference(W3CEndpointReference.class, referenceParameters);
  299       }
  300   
  301       public <T extends EndpointReference> T getEndpointReference(Class<T> clazz, Element...referenceParameters) {
  302           if (!isPublished()) {
  303               throw new WebServiceException("Endpoint is not published yet");
  304           }
  305           return ((HttpEndpoint)actualEndpoint).getEndpointReference(clazz,referenceParameters);
  306       }
  307   }

Save This Page
Home » Open-JDK-6.b17-src » com.sun.xml.internal » ws » transport » http » server » [javadoc | source]