src/share/jaxws_classes/com/sun/xml/internal/ws/server/EndpointFactory.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

     1 /*
     2  * Copyright (c) 1997, 2013, 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.server;
    28 import com.sun.istack.internal.NotNull;
    29 import com.sun.istack.internal.Nullable;
    30 import com.sun.xml.internal.stream.buffer.MutableXMLStreamBuffer;
    31 import com.sun.xml.internal.ws.api.BindingID;
    32 import com.sun.xml.internal.ws.api.WSBinding;
    33 import com.sun.xml.internal.ws.api.WSFeatureList;
    34 import com.sun.xml.internal.ws.api.databinding.DatabindingConfig;
    35 import com.sun.xml.internal.ws.api.databinding.DatabindingFactory;
    36 import com.sun.xml.internal.ws.api.databinding.MetadataReader;
    37 import com.sun.xml.internal.ws.api.databinding.WSDLGenInfo;
    38 import com.sun.xml.internal.ws.api.model.SEIModel;
    39 import com.sun.xml.internal.ws.api.model.wsdl.WSDLModel;
    40 import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort;
    41 import com.sun.xml.internal.ws.api.model.wsdl.WSDLService;
    42 import com.sun.xml.internal.ws.api.policy.PolicyResolver;
    43 import com.sun.xml.internal.ws.api.policy.PolicyResolverFactory;
    44 import com.sun.xml.internal.ws.api.server.AsyncProvider;
    45 import com.sun.xml.internal.ws.api.server.Container;
    46 import com.sun.xml.internal.ws.api.server.ContainerResolver;
    47 import com.sun.xml.internal.ws.api.server.InstanceResolver;
    48 import com.sun.xml.internal.ws.api.server.Invoker;
    49 import com.sun.xml.internal.ws.api.server.SDDocument;
    50 import com.sun.xml.internal.ws.api.server.SDDocumentSource;
    51 import com.sun.xml.internal.ws.api.server.WSEndpoint;
    52 import com.sun.xml.internal.ws.api.streaming.XMLStreamReaderFactory;
    53 import com.sun.xml.internal.ws.api.wsdl.parser.WSDLParserExtension;
    54 import com.sun.xml.internal.ws.api.wsdl.parser.XMLEntityResolver;
    55 import com.sun.xml.internal.ws.api.wsdl.parser.XMLEntityResolver.Parser;
    56 import com.sun.xml.internal.ws.api.wsdl.writer.WSDLGeneratorExtension;
    57 import com.sun.xml.internal.ws.binding.BindingImpl;
    58 import com.sun.xml.internal.ws.binding.SOAPBindingImpl;
    59 import com.sun.xml.internal.ws.binding.WebServiceFeatureList;
    60 import com.sun.xml.internal.ws.model.AbstractSEIModelImpl;
    61 import com.sun.xml.internal.ws.model.ReflectAnnotationReader;
    62 import com.sun.xml.internal.ws.model.RuntimeModeler;
    63 import com.sun.xml.internal.ws.model.SOAPSEIModel;
    64 import com.sun.xml.internal.ws.policy.PolicyMap;
    65 import com.sun.xml.internal.ws.policy.jaxws.PolicyUtil;
    66 import com.sun.xml.internal.ws.resources.ServerMessages;
    67 import com.sun.xml.internal.ws.server.provider.ProviderInvokerTube;
    68 import com.sun.xml.internal.ws.server.sei.SEIInvokerTube;
    69 import com.sun.xml.internal.ws.util.HandlerAnnotationInfo;
    70 import com.sun.xml.internal.ws.util.HandlerAnnotationProcessor;
    71 import com.sun.xml.internal.ws.util.ServiceConfigurationError;
    72 import com.sun.xml.internal.ws.util.ServiceFinder;
    73 import com.sun.xml.internal.ws.util.xml.XmlUtil;
    74 import com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser;
    76 import org.xml.sax.EntityResolver;
    77 import org.xml.sax.InputSource;
    78 import org.xml.sax.SAXException;
    80 import javax.jws.WebService;
    81 import javax.xml.namespace.QName;
    82 import javax.xml.stream.XMLStreamException;
    83 import javax.xml.stream.XMLStreamReader;
    84 import javax.xml.ws.Provider;
    85 import javax.xml.ws.WebServiceException;
    86 import javax.xml.ws.WebServiceFeature;
    87 import javax.xml.ws.WebServiceProvider;
    88 import javax.xml.ws.soap.SOAPBinding;
    90 import java.io.IOException;
    91 import java.net.URL;
    92 import java.util.ArrayList;
    93 import java.util.Collection;
    94 import java.util.HashMap;
    95 import java.util.List;
    96 import java.util.Map;
    97 import java.util.logging.Logger;
    99 /**
   100  * Entry point to the JAX-WS RI server-side runtime.
   101  *
   102  * @author Kohsuke Kawaguchi
   103  * @author Jitendra Kotamraju
   104  */
   105 public class EndpointFactory {
   106         private static final EndpointFactory instance = new EndpointFactory();
   108         public static EndpointFactory getInstance() {
   109                 return instance;
   110         }
   112     /**
   113      * Implements {@link WSEndpoint#create}.
   114      *
   115      * No need to take WebServiceContext implementation. When InvokerPipe is
   116      * instantiated, it calls InstanceResolver to set up a WebServiceContext.
   117      * We shall only take delegate to getUserPrincipal and isUserInRole from adapter.
   118      *
   119      * <p>
   120      * Nobody else should be calling this method.
   121      */
   122     public static <T> WSEndpoint<T> createEndpoint(
   123         Class<T> implType, boolean processHandlerAnnotation, @Nullable Invoker invoker,
   124         @Nullable QName serviceName, @Nullable QName portName,
   125         @Nullable Container container, @Nullable WSBinding binding,
   126         @Nullable SDDocumentSource primaryWsdl,
   127         @Nullable Collection<? extends SDDocumentSource> metadata,
   128         EntityResolver resolver, boolean isTransportSynchronous) {
   129         return createEndpoint(implType, processHandlerAnnotation, invoker, serviceName,
   130                         portName, container, binding, primaryWsdl, metadata, resolver, isTransportSynchronous, true);
   131     }
   133     public static <T> WSEndpoint<T> createEndpoint(
   134             Class<T> implType, boolean processHandlerAnnotation, @Nullable Invoker invoker,
   135             @Nullable QName serviceName, @Nullable QName portName,
   136             @Nullable Container container, @Nullable WSBinding binding,
   137             @Nullable SDDocumentSource primaryWsdl,
   138             @Nullable Collection<? extends SDDocumentSource> metadata,
   139             EntityResolver resolver, boolean isTransportSynchronous, boolean isStandard) {
   140         EndpointFactory factory = container != null ? container.getSPI(EndpointFactory.class) : null;
   141         if (factory == null)
   142                 factory = EndpointFactory.getInstance();
   144         return factory.create(
   145                 implType,processHandlerAnnotation, invoker,serviceName,portName,container,binding,primaryWsdl,metadata,resolver,isTransportSynchronous,isStandard);
   146     }
   148     /**
   149      * Implements {@link WSEndpoint#create}.
   150      *
   151      * No need to take WebServiceContext implementation. When InvokerPipe is
   152      * instantiated, it calls InstanceResolver to set up a WebServiceContext.
   153      * We shall only take delegate to getUserPrincipal and isUserInRole from adapter.
   154      *
   155      * <p>
   156      * Nobody else should be calling this method.
   157      */
   158     public <T> WSEndpoint<T> create(
   159             Class<T> implType, boolean processHandlerAnnotation, @Nullable Invoker invoker,
   160             @Nullable QName serviceName, @Nullable QName portName,
   161             @Nullable Container container, @Nullable WSBinding binding,
   162             @Nullable SDDocumentSource primaryWsdl,
   163             @Nullable Collection<? extends SDDocumentSource> metadata,
   164             EntityResolver resolver, boolean isTransportSynchronous) {
   165         return create(implType, processHandlerAnnotation, invoker, serviceName,
   166                         portName, container, binding, primaryWsdl, metadata, resolver, isTransportSynchronous,
   167                         true);
   169     }
   171     public <T> WSEndpoint<T> create(
   172         Class<T> implType, boolean processHandlerAnnotation, @Nullable Invoker invoker,
   173         @Nullable QName serviceName, @Nullable QName portName,
   174         @Nullable Container container, @Nullable WSBinding binding,
   175         @Nullable SDDocumentSource primaryWsdl,
   176         @Nullable Collection<? extends SDDocumentSource> metadata,
   177         EntityResolver resolver, boolean isTransportSynchronous, boolean isStandard) {
   179         if(implType ==null)
   180             throw new IllegalArgumentException();
   182         MetadataReader metadataReader = getExternalMetadatReader(implType, binding);
   184         if (isStandard) {
   185             verifyImplementorClass(implType, metadataReader);
   186         }
   188         if (invoker == null) {
   189             invoker = InstanceResolver.createDefault(implType).createInvoker();
   190         }
   192         List<SDDocumentSource> md = new ArrayList<SDDocumentSource>();
   193         if(metadata!=null)
   194             md.addAll(metadata);
   196         if(primaryWsdl!=null && !md.contains(primaryWsdl))
   197             md.add(primaryWsdl);
   199         if(container==null)
   200             container = ContainerResolver.getInstance().getContainer();
   202         if(serviceName==null)
   203             serviceName = getDefaultServiceName(implType, metadataReader);
   205         if(portName==null)
   206             portName = getDefaultPortName(serviceName,implType, metadataReader);
   208         {// error check
   209             String serviceNS = serviceName.getNamespaceURI();
   210             String portNS = portName.getNamespaceURI();
   211             if (!serviceNS.equals(portNS)) {
   212                 throw new ServerRtException("wrong.tns.for.port",portNS, serviceNS);
   213             }
   214         }
   216         // setting a default binding
   217         if (binding == null)
   218             binding = BindingImpl.create(BindingID.parse(implType));
   220         if ( isStandard && primaryWsdl != null) {
   221             verifyPrimaryWSDL(primaryWsdl, serviceName);
   222         }
   224         QName portTypeName = null;
   225         if (isStandard && implType.getAnnotation(WebServiceProvider.class)==null) {
   226             portTypeName = RuntimeModeler.getPortTypeName(implType, metadataReader);
   227         }
   229         // Categorises the documents as WSDL, Schema etc
   230         List<SDDocumentImpl> docList = categoriseMetadata(md, serviceName, portTypeName);
   231         // Finds the primary WSDL and makes sure that metadata doesn't have
   232         // two concrete or abstract WSDLs
   233         SDDocumentImpl primaryDoc = primaryWsdl != null ? SDDocumentImpl.create(primaryWsdl,serviceName,portTypeName) : findPrimary(docList);
   235         EndpointAwareTube terminal;
   236         WSDLPort wsdlPort = null;
   237         AbstractSEIModelImpl seiModel = null;
   238         // create WSDL model
   239         if (primaryDoc != null) {
   240             wsdlPort = getWSDLPort(primaryDoc, docList, serviceName, portName, container, resolver);
   241         }
   243         WebServiceFeatureList features=((BindingImpl)binding).getFeatures();
   244         if (isStandard) {
   245                 features.parseAnnotations(implType);
   246         }
   247         PolicyMap policyMap = null;
   248         // create terminal pipe that invokes the application
   249         if (isUseProviderTube(implType, isStandard)) {
   250             //TODO incase of Provider, provide a way to User for complete control of the message processing by giving
   251             // ability to turn off the WSDL/Policy based features and its associated tubes.
   253             //Even in case of Provider, merge all features configured via WSDL/Policy or deployment configuration
   254             Iterable<WebServiceFeature> configFtrs;
   255             if(wsdlPort != null) {
   256                  policyMap = wsdlPort.getOwner().getParent().getPolicyMap();
   257                  //Merge features from WSDL and other policy configuration
   258                 configFtrs = wsdlPort.getFeatures();
   259             } else {
   260                 //No WSDL, so try to merge features from Policy configuration
   261                 policyMap = PolicyResolverFactory.create().resolve(
   262                         new PolicyResolver.ServerContext(null, container, implType, false));
   263                 configFtrs = PolicyUtil.getPortScopedFeatures(policyMap,serviceName,portName);
   264             }
   265             features.mergeFeatures(configFtrs, true);
   266             terminal = createProviderInvokerTube(implType, binding, invoker, container);
   267         } else {
   268             // Create runtime model for non Provider endpoints
   269             seiModel = createSEIModel(wsdlPort, implType, serviceName, portName, binding, primaryDoc);
   270             if(binding instanceof SOAPBindingImpl){
   271                 //set portKnownHeaders on Binding, so that they can be used for MU processing
   272                 ((SOAPBindingImpl)binding).setPortKnownHeaders(
   273                         ((SOAPSEIModel)seiModel).getKnownHeaders());
   274             }
   275             // Generate WSDL for SEI endpoints(not for Provider endpoints)
   276             if (primaryDoc == null) {
   277                 primaryDoc = generateWSDL(binding, seiModel, docList, container, implType);
   278                 // create WSDL model
   279                 wsdlPort = getWSDLPort(primaryDoc, docList, serviceName, portName, container, resolver);
   280                 seiModel.freeze(wsdlPort);
   281             }
   282             policyMap = wsdlPort.getOwner().getParent().getPolicyMap();
   283             // New Features might have been added in WSDL through Policy.
   284             //Merge features from WSDL and other policy configuration
   285             // This sets only the wsdl features that are not already set(enabled/disabled)
   286             features.mergeFeatures(wsdlPort.getFeatures(), true);
   287             terminal = createSEIInvokerTube(seiModel,invoker,binding);
   288         }
   290         // Process @HandlerChain, if handler-chain is not set via Deployment Descriptor
   291         if (processHandlerAnnotation) {
   292             processHandlerAnnotation(binding, implType, serviceName, portName);
   293         }
   294         // Selects only required metadata for this endpoint from the passed-in metadata
   295         if (primaryDoc != null) {
   296             docList = findMetadataClosure(primaryDoc, docList, resolver);
   297         }
   299         ServiceDefinitionImpl serviceDefiniton = (primaryDoc != null) ? new ServiceDefinitionImpl(docList, primaryDoc) : null;
   301         return create(serviceName, portName, binding, container, seiModel, wsdlPort, implType, serviceDefiniton,
   302                         terminal, isTransportSynchronous, policyMap);
   303     }
   305     protected <T> WSEndpoint<T> create(QName serviceName, QName portName, WSBinding binding, Container container, SEIModel seiModel, WSDLPort wsdlPort, Class<T> implType, ServiceDefinitionImpl serviceDefinition, EndpointAwareTube terminal, boolean isTransportSynchronous, PolicyMap policyMap) {
   306         return new WSEndpointImpl<T>(serviceName, portName, binding, container, seiModel,
   307                         wsdlPort, implType, serviceDefinition, terminal, isTransportSynchronous, policyMap);
   308     }
   310     protected boolean isUseProviderTube(Class<?> implType, boolean isStandard) {
   311         return !isStandard || implType.getAnnotation(WebServiceProvider.class)!=null;
   312     }
   314     protected EndpointAwareTube createSEIInvokerTube(AbstractSEIModelImpl seiModel, Invoker invoker, WSBinding binding) {
   315         return new SEIInvokerTube(seiModel,invoker,binding);
   316     }
   318     protected <T> EndpointAwareTube createProviderInvokerTube(final Class<T> implType, final WSBinding binding,
   319                                                               final Invoker invoker, final Container container) {
   320         return ProviderInvokerTube.create(implType, binding, invoker, container);
   321     }
   322     /**
   323      * Goes through the original metadata documents and collects the required ones.
   324      * This done traversing from primary WSDL and its imports until it builds a
   325      * complete set of documents(transitive closure) for the endpoint.
   326      *
   327      * @param primaryDoc primary WSDL doc
   328      * @param docList complete metadata
   329      * @return new metadata that doesn't contain extraneous documnets.
   330      */
   331     private static List<SDDocumentImpl> findMetadataClosure(SDDocumentImpl primaryDoc, List<SDDocumentImpl> docList, EntityResolver resolver) {
   332         // create a map for old metadata
   333         Map<String, SDDocumentImpl> oldMap = new HashMap<String, SDDocumentImpl>();
   334         for(SDDocumentImpl doc : docList) {
   335             oldMap.put(doc.getSystemId().toString(), doc);
   336         }
   337         // create a map for new metadata
   338         Map<String, SDDocumentImpl> newMap = new HashMap<String, SDDocumentImpl>();
   339         newMap.put(primaryDoc.getSystemId().toString(), primaryDoc);
   341         List<String> remaining = new ArrayList<String>();
   342         remaining.addAll(primaryDoc.getImports());
   343         while(!remaining.isEmpty()) {
   344             String url = remaining.remove(0);
   345             SDDocumentImpl doc = oldMap.get(url);
   346             if (doc == null) {
   347                 // old metadata doesn't have this imported doc, may be external
   348                 if (resolver != null) {
   349                         try {
   350                                 InputSource source = resolver.resolveEntity(null, url);
   351                                 if (source != null) {
   352                                         MutableXMLStreamBuffer xsb = new MutableXMLStreamBuffer();
   353                                         XMLStreamReader reader = XmlUtil.newXMLInputFactory(true).createXMLStreamReader(source.getByteStream());
   354                                         xsb.createFromXMLStreamReader(reader);
   356                                         SDDocumentSource sdocSource = SDDocumentImpl.create(new URL(url), xsb);
   357                                         doc = SDDocumentImpl.create(sdocSource, null, null);
   358                                 }
   359                         } catch (Exception ex) {
   360                                 ex.printStackTrace();
   361                         }
   362                 }
   363             }
   364             // Check if new metadata already contains this doc
   365             if (doc != null && !newMap.containsKey(url)) {
   366                 newMap.put(url, doc);
   367                 remaining.addAll(doc.getImports());
   368             }
   369         }
   370         List<SDDocumentImpl> newMetadata = new ArrayList<SDDocumentImpl>();
   371         newMetadata.addAll(newMap.values());
   372         return newMetadata;
   373     }
   375     private static <T> void processHandlerAnnotation(WSBinding binding, Class<T> implType, QName serviceName, QName portName) {
   376         HandlerAnnotationInfo chainInfo =
   377                 HandlerAnnotationProcessor.buildHandlerInfo(
   378                         implType, serviceName, portName, binding);
   379         if (chainInfo != null) {
   380             binding.setHandlerChain(chainInfo.getHandlers());
   381             if (binding instanceof SOAPBinding) {
   382                 ((SOAPBinding) binding).setRoles(chainInfo.getRoles());
   383             }
   384         }
   386     }
   388     /**
   389      * Verifies if the endpoint implementor class has @WebService or @WebServiceProvider
   390      * annotation
   391      *
   392      * @return
   393      *       true if it is a Provider or AsyncProvider endpoint
   394      *       false otherwise
   395      * @throws java.lang.IllegalArgumentException
   396      *      If it doesn't have any one of @WebService or @WebServiceProvider
   397      *      If it has both @WebService and @WebServiceProvider annotations
   398      */
   399     public static boolean verifyImplementorClass(Class<?> clz) {
   400         return verifyImplementorClass(clz, null);
   401     }
   403     /**
   404      * Verifies if the endpoint implementor class has @WebService or @WebServiceProvider
   405      * annotation; passing MetadataReader instance allows to read annotations from
   406      * xml descriptor instead of class's annotations
   407      *
   408      * @return
   409      *       true if it is a Provider or AsyncProvider endpoint
   410      *       false otherwise
   411      * @throws java.lang.IllegalArgumentException
   412      *      If it doesn't have any one of @WebService or @WebServiceProvider
   413      *      If it has both @WebService and @WebServiceProvider annotations
   414      */
   415     public static boolean verifyImplementorClass(Class<?> clz, MetadataReader metadataReader) {
   417         if (metadataReader == null) {
   418             metadataReader = new ReflectAnnotationReader();
   419         }
   421         WebServiceProvider wsProvider = metadataReader.getAnnotation(WebServiceProvider.class, clz);
   422         WebService ws = metadataReader.getAnnotation(WebService.class, clz);
   423         if (wsProvider == null && ws == null) {
   424             throw new IllegalArgumentException(clz +" has neither @WebService nor @WebServiceProvider annotation");
   425         }
   426         if (wsProvider != null && ws != null) {
   427             throw new IllegalArgumentException(clz +" has both @WebService and @WebServiceProvider annotations");
   428         }
   429         if (wsProvider != null) {
   430             if (Provider.class.isAssignableFrom(clz) || AsyncProvider.class.isAssignableFrom(clz)) {
   431                 return true;
   432             }
   433             throw new IllegalArgumentException(clz +" doesn't implement Provider or AsyncProvider interface");
   434         }
   435         return false;
   436     }
   439     private static AbstractSEIModelImpl createSEIModel(WSDLPort wsdlPort,
   440                                                        Class<?> implType, @NotNull QName serviceName, @NotNull QName portName, WSBinding binding,
   441                                                        SDDocumentSource primaryWsdl) {
   442                 DatabindingFactory fac = DatabindingFactory.newInstance();
   443                 DatabindingConfig config = new DatabindingConfig();
   444                 config.setEndpointClass(implType);
   445                 config.getMappingInfo().setServiceName(serviceName);
   446                 config.setWsdlPort(wsdlPort);
   447                 config.setWSBinding(binding);
   448                 config.setClassLoader(implType.getClassLoader());
   449                 config.getMappingInfo().setPortName(portName);
   450                 if (primaryWsdl != null) config.setWsdlURL(primaryWsdl.getSystemId());
   451         config.setMetadataReader(getExternalMetadatReader(implType, binding));
   453                 com.sun.xml.internal.ws.db.DatabindingImpl rt = (com.sun.xml.internal.ws.db.DatabindingImpl)fac.createRuntime(config);
   454                 return (AbstractSEIModelImpl) rt.getModel();
   455     }
   457     public static MetadataReader getExternalMetadatReader(Class<?> implType, WSBinding binding) {
   458         com.oracle.webservices.internal.api.databinding.ExternalMetadataFeature ef = binding.getFeature(
   459                 com.oracle.webservices.internal.api.databinding.ExternalMetadataFeature.class);
   460         // TODO-Miran: would it be necessary to disable secure xml processing?
   461         if (ef != null)
   462             return ef.getMetadataReader(implType.getClassLoader(), false);
   463         return null;
   464     }
   466     /**
   467      *Set the mtom enable setting from wsdl model (mtom policy assertion) on to @link WSBinding} if DD has
   468      * not already set it on BindingID. Also check conflicts.
   469      */
   470     /*
   471     private static void applyEffectiveMtomSetting(WSDLBoundPortType wsdlBinding, WSBinding binding){
   472         if(wsdlBinding.isMTOMEnabled()){
   473             BindingID bindingId = binding.getBindingId();
   474             if(bindingId.isMTOMEnabled() == null){
   475                 binding.setMTOMEnabled(true);
   476             }else if (bindingId.isMTOMEnabled() != null && bindingId.isMTOMEnabled() == Boolean.FALSE){
   477                 //TODO: i18N
   478                 throw new ServerRtException("Deployment failed! Mtom policy assertion in WSDL is enabled whereas the deplyment descriptor setting wants to disable it!");
   479             }
   480         }
   481     }
   482     */
   483     /**
   484      * If service name is not already set via DD or programmatically, it uses
   485      * annotations {@link WebServiceProvider}, {@link WebService} on implementorClass to get PortName.
   486      *
   487      * @return non-null service name
   488      */
   489     public static @NotNull QName getDefaultServiceName(Class<?> implType) {
   490         return getDefaultServiceName(implType, null);
   491     }
   493     public static @NotNull QName getDefaultServiceName(Class<?> implType, MetadataReader metadataReader) {
   494         return getDefaultServiceName(implType, true, metadataReader);
   495     }
   497     public static @NotNull QName getDefaultServiceName(Class<?> implType, boolean isStandard) {
   498         return getDefaultServiceName(implType, isStandard, null);
   499     }
   501     public static @NotNull QName getDefaultServiceName(Class<?> implType, boolean isStandard, MetadataReader metadataReader) {
   502         if (metadataReader == null) {
   503             metadataReader = new ReflectAnnotationReader();
   504         }
   505         QName serviceName;
   506         WebServiceProvider wsProvider = metadataReader.getAnnotation(WebServiceProvider.class, implType);
   507         if (wsProvider!=null) {
   508             String tns = wsProvider.targetNamespace();
   509             String local = wsProvider.serviceName();
   510             serviceName = new QName(tns, local);
   511         } else {
   512             serviceName = RuntimeModeler.getServiceName(implType, metadataReader, isStandard);
   513         }
   514         assert serviceName != null;
   515         return serviceName;
   516     }
   518     /**
   519      * If portName is not already set via DD or programmatically, it uses
   520      * annotations on implementorClass to get PortName.
   521      *
   522      * @return non-null port name
   523      */
   524     public static @NotNull QName getDefaultPortName(QName serviceName, Class<?> implType) {
   525         return getDefaultPortName(serviceName, implType, null);
   526     }
   528     public static @NotNull QName getDefaultPortName(QName serviceName, Class<?> implType, MetadataReader metadataReader) {
   529         return getDefaultPortName(serviceName, implType, true, metadataReader);
   530     }
   532     public static @NotNull QName getDefaultPortName(QName serviceName, Class<?> implType, boolean isStandard) {
   533         return getDefaultPortName(serviceName, implType, isStandard, null);
   534     }
   536     public static @NotNull QName getDefaultPortName(QName serviceName, Class<?> implType, boolean isStandard, MetadataReader metadataReader) {
   537         if (metadataReader == null) {
   538             metadataReader = new ReflectAnnotationReader();
   539         }
   540         QName portName;
   541         WebServiceProvider wsProvider = metadataReader.getAnnotation(WebServiceProvider.class, implType);
   542         if (wsProvider!=null) {
   543             String tns = wsProvider.targetNamespace();
   544             String local = wsProvider.portName();
   545             portName = new QName(tns, local);
   546         } else {
   547             portName = RuntimeModeler.getPortName(implType, metadataReader, serviceName.getNamespaceURI(), isStandard);
   548         }
   549         assert portName != null;
   550         return portName;
   551     }
   553     /**
   554      * Returns the wsdl from @WebService, or @WebServiceProvider annotation using
   555      * wsdlLocation element.
   556      *
   557      * @param implType
   558      *      endpoint implementation class
   559      *      make sure that you called {@link #verifyImplementorClass} on it.
   560      * @return wsdl if there is wsdlLocation, else null
   561      */
   562     public static @Nullable String getWsdlLocation(Class<?> implType) {
   563         return getWsdlLocation(implType, new ReflectAnnotationReader());
   564     }
   566     /**
   567      * Returns the wsdl from @WebService, or @WebServiceProvider annotation using
   568      * wsdlLocation element.
   569      *
   570      * @param implType
   571      *      endpoint implementation class
   572      *      make sure that you called {@link #verifyImplementorClass} on it.
   573      * @return wsdl if there is wsdlLocation, else null
   574      */
   575     public static @Nullable String getWsdlLocation(Class<?> implType, MetadataReader metadataReader) {
   577         if (metadataReader == null) {
   578             metadataReader = new ReflectAnnotationReader();
   579         }
   581         WebService ws = metadataReader.getAnnotation(WebService.class, implType);
   582         if (ws != null) {
   583             return nullIfEmpty(ws.wsdlLocation());
   584         } else {
   585             WebServiceProvider wsProvider = implType.getAnnotation(WebServiceProvider.class);
   586             assert wsProvider != null;
   587             return nullIfEmpty(wsProvider.wsdlLocation());
   588         }
   589     }
   591     private static String nullIfEmpty(String string) {
   592         if (string.length() < 1) {
   593             string = null;
   594         }
   595         return string;
   596     }
   598     /**
   599      * Generates the WSDL and XML Schema for the endpoint if necessary
   600      * It generates WSDL only for SOAP1.1, and for XSOAP1.2 bindings
   601      */
   602     private static SDDocumentImpl generateWSDL(WSBinding binding, AbstractSEIModelImpl seiModel, List<SDDocumentImpl> docs,
   603                                                Container container, Class implType) {
   604         BindingID bindingId = binding.getBindingId();
   605         if (!bindingId.canGenerateWSDL()) {
   606             throw new ServerRtException("can.not.generate.wsdl", bindingId);
   607         }
   609         if (bindingId.toString().equals(SOAPBindingImpl.X_SOAP12HTTP_BINDING)) {
   610             String msg = ServerMessages.GENERATE_NON_STANDARD_WSDL();
   611             logger.warning(msg);
   612         }
   614         // Generate WSDL and schema documents using runtime model
   615         WSDLGenResolver wsdlResolver = new WSDLGenResolver(docs,seiModel.getServiceQName(),seiModel.getPortTypeName());
   616         WSDLGenInfo wsdlGenInfo = new WSDLGenInfo();
   617         wsdlGenInfo.setWsdlResolver(wsdlResolver);
   618         wsdlGenInfo.setContainer(container);
   619         wsdlGenInfo.setExtensions(ServiceFinder.find(WSDLGeneratorExtension.class).toArray());
   620         wsdlGenInfo.setInlineSchemas(false);
   621         wsdlGenInfo.setSecureXmlProcessingDisabled(isSecureXmlProcessingDisabled(binding.getFeatures()));
   622         seiModel.getDatabinding().generateWSDL(wsdlGenInfo);
   623 //        WSDLGenerator wsdlGen = new WSDLGenerator(seiModel, wsdlResolver, binding, container, implType, false,
   624 //                ServiceFinder.find(WSDLGeneratorExtension.class).toArray());
   625 //        wsdlGen.doGeneration();
   626         return wsdlResolver.updateDocs();
   627     }
   629     private static boolean isSecureXmlProcessingDisabled(WSFeatureList featureList) {
   630         // TODO-Miran: would it be necessary to disable secure xml processing?
   631         return false;
   632     }
   634     /**
   635      * Builds {@link SDDocumentImpl} from {@link SDDocumentSource}.
   636      */
   637     private static List<SDDocumentImpl> categoriseMetadata(
   638         List<SDDocumentSource> src, QName serviceName, QName portTypeName) {
   640         List<SDDocumentImpl> r = new ArrayList<SDDocumentImpl>(src.size());
   641         for (SDDocumentSource doc : src) {
   642             r.add(SDDocumentImpl.create(doc,serviceName,portTypeName));
   643         }
   644         return r;
   645     }
   647     /**
   648      * Verifies whether the given primaryWsdl contains the given serviceName.
   649      * If the WSDL doesn't have the service, it throws an WebServiceException.
   650      */
   651     private static void verifyPrimaryWSDL(@NotNull SDDocumentSource primaryWsdl, @NotNull QName serviceName) {
   652         SDDocumentImpl primaryDoc = SDDocumentImpl.create(primaryWsdl,serviceName,null);
   653         if (!(primaryDoc instanceof SDDocument.WSDL)) {
   654             throw new WebServiceException(primaryWsdl.getSystemId()+
   655                     " is not a WSDL. But it is passed as a primary WSDL");
   656         }
   657         SDDocument.WSDL wsdlDoc = (SDDocument.WSDL)primaryDoc;
   658         if (!wsdlDoc.hasService()) {
   659             if(wsdlDoc.getAllServices().isEmpty())
   660                 throw new WebServiceException("Not a primary WSDL="+primaryWsdl.getSystemId()+
   661                         " since it doesn't have Service "+serviceName);
   662             else
   663                 throw new WebServiceException("WSDL "+primaryDoc.getSystemId()
   664                         +" has the following services "+wsdlDoc.getAllServices()
   665                         +" but not "+serviceName+". Maybe you forgot to specify a serviceName and/or targetNamespace in @WebService/@WebServiceProvider?");
   666         }
   667     }
   669     /**
   670      * Finds the primary WSDL document from the list of metadata documents. If
   671      * there are two metadata documents that qualify for primary, it throws an
   672      * exception. If there are two metadata documents that qualify for porttype,
   673      * it throws an exception.
   674      *
   675      * @return primay wsdl document, null if is not there in the docList
   676      *
   677      */
   678     private static @Nullable SDDocumentImpl findPrimary(@NotNull List<SDDocumentImpl> docList) {
   679         SDDocumentImpl primaryDoc = null;
   680         boolean foundConcrete = false;
   681         boolean foundAbstract = false;
   682         for(SDDocumentImpl doc : docList) {
   683             if (doc instanceof SDDocument.WSDL) {
   684                 SDDocument.WSDL wsdlDoc = (SDDocument.WSDL)doc;
   685                 if (wsdlDoc.hasService()) {
   686                     primaryDoc = doc;
   687                     if (foundConcrete) {
   688                         throw new ServerRtException("duplicate.primary.wsdl", doc.getSystemId() );
   689                     }
   690                     foundConcrete = true;
   691                 }
   692                 if (wsdlDoc.hasPortType()) {
   693                     if (foundAbstract) {
   694                         throw new ServerRtException("duplicate.abstract.wsdl", doc.getSystemId());
   695                     }
   696                     foundAbstract = true;
   697                 }
   698             }
   699         }
   700         return primaryDoc;
   701     }
   703     /**
   704      * Parses the primary WSDL and returns the {@link WSDLPort} for the given service and port names
   705      *
   706      * @param primaryWsdl Primary WSDL
   707      * @param metadata it may contain imported WSDL and schema documents
   708      * @param serviceName service name in wsdl
   709      * @param portName port name in WSDL
   710      * @param container container in which this service is running
   711      * @return non-null wsdl port object
   712      */
   713     private static @NotNull WSDLPort getWSDLPort(SDDocumentSource primaryWsdl, List<? extends SDDocumentSource> metadata,
   714                                                      @NotNull QName serviceName, @NotNull QName portName, Container container,
   715                                                      EntityResolver resolver) {
   716         URL wsdlUrl = primaryWsdl.getSystemId();
   717         try {
   718             // TODO: delegate to another entity resolver
   719             WSDLModel wsdlDoc = RuntimeWSDLParser.parse(
   720                 new Parser(primaryWsdl), new EntityResolverImpl(metadata, resolver),
   721                     false, container, ServiceFinder.find(WSDLParserExtension.class).toArray());
   722             if(wsdlDoc.getServices().size() == 0) {
   723                 throw new ServerRtException(ServerMessages.localizableRUNTIME_PARSER_WSDL_NOSERVICE_IN_WSDLMODEL(wsdlUrl));
   724             }
   725             WSDLService wsdlService = wsdlDoc.getService(serviceName);
   726             if (wsdlService == null) {
   727                 throw new ServerRtException(ServerMessages.localizableRUNTIME_PARSER_WSDL_INCORRECTSERVICE(serviceName,wsdlUrl));
   728             }
   729             WSDLPort wsdlPort = wsdlService.get(portName);
   730             if (wsdlPort == null) {
   731                 throw new ServerRtException(ServerMessages.localizableRUNTIME_PARSER_WSDL_INCORRECTSERVICEPORT(serviceName, portName, wsdlUrl));
   732             }
   733             return wsdlPort;
   734         } catch (IOException e) {
   735             throw new ServerRtException("runtime.parser.wsdl", wsdlUrl,e);
   736         } catch (XMLStreamException e) {
   737             throw new ServerRtException("runtime.saxparser.exception", e.getMessage(), e.getLocation(), e);
   738         } catch (SAXException e) {
   739             throw new ServerRtException("runtime.parser.wsdl", wsdlUrl,e);
   740         } catch (ServiceConfigurationError e) {
   741             throw new ServerRtException("runtime.parser.wsdl", wsdlUrl,e);
   742         }
   743     }
   745     /**
   746      * {@link XMLEntityResolver} that can resolve to {@link SDDocumentSource}s.
   747      */
   748     private static final class EntityResolverImpl implements XMLEntityResolver {
   749         private Map<String,SDDocumentSource> metadata = new HashMap<String,SDDocumentSource>();
   750         private EntityResolver resolver;
   752         public EntityResolverImpl(List<? extends SDDocumentSource> metadata, EntityResolver resolver) {
   753             for (SDDocumentSource doc : metadata) {
   754                 this.metadata.put(doc.getSystemId().toExternalForm(),doc);
   755             }
   756             this.resolver = resolver;
   757         }
   759         public Parser resolveEntity (String publicId, String systemId) throws IOException, XMLStreamException {
   760             if (systemId != null) {
   761                 SDDocumentSource doc = metadata.get(systemId);
   762                 if (doc != null)
   763                     return new Parser(doc);
   764             }
   765             if (resolver != null) {
   766                 try {
   767                     InputSource source = resolver.resolveEntity(publicId, systemId);
   768                     if (source != null) {
   769                         Parser p = new Parser(null, XMLStreamReaderFactory.create(source, true));
   770                         return p;
   771                     }
   772                 } catch (SAXException e) {
   773                     throw new XMLStreamException(e);
   774                 }
   775             }
   776             return null;
   777         }
   779     }
   781     private static final Logger logger = Logger.getLogger(
   782         com.sun.xml.internal.ws.util.Constants.LoggingDomain + ".server.endpoint");
   783 }

mercurial