jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/server/EndpointFactory.java
changeset 23782 953bfc3fbe31
parent 20590 b3b34e4344ce
equal deleted inserted replaced
23403:85dbdc227c5e 23782:953bfc3fbe31
     1 /*
     1 /*
     2  * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    87 import javax.xml.ws.WebServiceProvider;
    87 import javax.xml.ws.WebServiceProvider;
    88 import javax.xml.ws.soap.SOAPBinding;
    88 import javax.xml.ws.soap.SOAPBinding;
    89 
    89 
    90 import java.io.IOException;
    90 import java.io.IOException;
    91 import java.net.URL;
    91 import java.net.URL;
       
    92 import java.util.AbstractCollection;
    92 import java.util.ArrayList;
    93 import java.util.ArrayList;
    93 import java.util.Collection;
    94 import java.util.Collection;
       
    95 import java.util.Collections;
    94 import java.util.HashMap;
    96 import java.util.HashMap;
       
    97 import java.util.Iterator;
    95 import java.util.List;
    98 import java.util.List;
    96 import java.util.Map;
    99 import java.util.Map;
       
   100 import java.util.NoSuchElementException;
       
   101 import java.util.concurrent.ConcurrentHashMap;
    97 import java.util.logging.Logger;
   102 import java.util.logging.Logger;
    98 
   103 
    99 /**
   104 /**
   100  * Entry point to the JAX-WS RI server-side runtime.
   105  * Entry point to the JAX-WS RI server-side runtime.
   101  *
   106  *
   187 
   192 
   188         if (invoker == null) {
   193         if (invoker == null) {
   189             invoker = InstanceResolver.createDefault(implType).createInvoker();
   194             invoker = InstanceResolver.createDefault(implType).createInvoker();
   190         }
   195         }
   191 
   196 
   192         List<SDDocumentSource> md = new ArrayList<SDDocumentSource>();
   197         // Performance analysis indicates that reading and parsing imported schemas is
   193         if(metadata!=null)
   198         // a major component of Endpoint creation time.  Therefore, modify SDDocumentSource
       
   199         // handling to delay iterating collection as long as possible.
       
   200         Collection<SDDocumentSource> md = new CollectionCollection<SDDocumentSource>();
       
   201         if(primaryWsdl!=null) {
       
   202             if(metadata!=null) {
       
   203                 Iterator<? extends SDDocumentSource> it = metadata.iterator();
       
   204                 if (it.hasNext() && primaryWsdl.equals(it.next()))
       
   205                     md.addAll(metadata);
       
   206                 else {
       
   207                     md.add(primaryWsdl);
       
   208                     md.addAll(metadata);
       
   209                 }
       
   210             } else
       
   211                 md.add(primaryWsdl);
       
   212         } else if(metadata!=null)
   194             md.addAll(metadata);
   213             md.addAll(metadata);
   195 
       
   196         if(primaryWsdl!=null && !md.contains(primaryWsdl))
       
   197             md.add(primaryWsdl);
       
   198 
   214 
   199         if(container==null)
   215         if(container==null)
   200             container = ContainerResolver.getInstance().getContainer();
   216             container = ContainerResolver.getInstance().getContainer();
   201 
   217 
   202         if(serviceName==null)
   218         if(serviceName==null)
   225         if (isStandard && implType.getAnnotation(WebServiceProvider.class)==null) {
   241         if (isStandard && implType.getAnnotation(WebServiceProvider.class)==null) {
   226             portTypeName = RuntimeModeler.getPortTypeName(implType, metadataReader);
   242             portTypeName = RuntimeModeler.getPortTypeName(implType, metadataReader);
   227         }
   243         }
   228 
   244 
   229         // Categorises the documents as WSDL, Schema etc
   245         // Categorises the documents as WSDL, Schema etc
   230         List<SDDocumentImpl> docList = categoriseMetadata(md, serviceName, portTypeName);
   246         Collection<SDDocumentImpl> docList = categoriseMetadata(md.iterator(), serviceName, portTypeName);
   231         // Finds the primary WSDL and makes sure that metadata doesn't have
   247         // Finds the primary WSDL and makes sure that metadata doesn't have
   232         // two concrete or abstract WSDLs
   248         // two concrete or abstract WSDLs
   233         SDDocumentImpl primaryDoc = primaryWsdl != null ? SDDocumentImpl.create(primaryWsdl,serviceName,portTypeName) : findPrimary(docList);
   249         SDDocumentImpl primaryDoc = primaryWsdl != null ? SDDocumentImpl.create(primaryWsdl,serviceName,portTypeName) : findPrimary(docList);
   234 
   250 
   235         EndpointAwareTube terminal;
   251         EndpointAwareTube terminal;
   324      * This done traversing from primary WSDL and its imports until it builds a
   340      * This done traversing from primary WSDL and its imports until it builds a
   325      * complete set of documents(transitive closure) for the endpoint.
   341      * complete set of documents(transitive closure) for the endpoint.
   326      *
   342      *
   327      * @param primaryDoc primary WSDL doc
   343      * @param primaryDoc primary WSDL doc
   328      * @param docList complete metadata
   344      * @param docList complete metadata
   329      * @return new metadata that doesn't contain extraneous documnets.
   345      * @return new metadata that doesn't contain extraneous documents.
   330      */
   346      */
   331     private static List<SDDocumentImpl> findMetadataClosure(SDDocumentImpl primaryDoc, List<SDDocumentImpl> docList, EntityResolver resolver) {
   347     private static Collection<SDDocumentImpl> findMetadataClosure(
   332         // create a map for old metadata
   348             final SDDocumentImpl primaryDoc, final Collection<SDDocumentImpl> docList, final EntityResolver resolver) {
   333         Map<String, SDDocumentImpl> oldMap = new HashMap<String, SDDocumentImpl>();
   349         return new AbstractCollection<SDDocumentImpl>() {
   334         for(SDDocumentImpl doc : docList) {
   350             @Override
   335             oldMap.put(doc.getSystemId().toString(), doc);
   351             public Iterator<SDDocumentImpl> iterator() {
   336         }
   352                 // create a map for old metadata
   337         // create a map for new metadata
   353                 Map<String, SDDocumentImpl> oldMap = new HashMap<String, SDDocumentImpl>();
   338         Map<String, SDDocumentImpl> newMap = new HashMap<String, SDDocumentImpl>();
   354                 Iterator<SDDocumentImpl> oldDocs = docList.iterator();
   339         newMap.put(primaryDoc.getSystemId().toString(), primaryDoc);
   355 
   340 
   356                 // create a map for new metadata
   341         List<String> remaining = new ArrayList<String>();
   357                 Map<String, SDDocumentImpl> newMap = new HashMap<String, SDDocumentImpl>();
   342         remaining.addAll(primaryDoc.getImports());
   358                 newMap.put(primaryDoc.getSystemId().toString(), primaryDoc);
   343         while(!remaining.isEmpty()) {
   359 
   344             String url = remaining.remove(0);
   360                 List<String> remaining = new ArrayList<String>();
   345             SDDocumentImpl doc = oldMap.get(url);
   361                 remaining.addAll(primaryDoc.getImports());
   346             if (doc == null) {
   362                 while(!remaining.isEmpty()) {
   347                 // old metadata doesn't have this imported doc, may be external
   363                     String url = remaining.remove(0);
   348                 if (resolver != null) {
   364                     SDDocumentImpl doc = oldMap.get(url);
   349                         try {
   365                     if (doc == null) {
   350                                 InputSource source = resolver.resolveEntity(null, url);
   366                         while (oldDocs.hasNext()) {
   351                                 if (source != null) {
   367                             SDDocumentImpl old = oldDocs.next();
   352                                         MutableXMLStreamBuffer xsb = new MutableXMLStreamBuffer();
   368                             String id = old.getSystemId().toString();
   353                                         XMLStreamReader reader = XmlUtil.newXMLInputFactory(true).createXMLStreamReader(source.getByteStream());
   369                             oldMap.put(id, old);
   354                                         xsb.createFromXMLStreamReader(reader);
   370                             if (id.equals(url)) {
   355 
   371                                 doc = old;
   356                                         SDDocumentSource sdocSource = SDDocumentImpl.create(new URL(url), xsb);
   372                                 break;
   357                                         doc = SDDocumentImpl.create(sdocSource, null, null);
   373                             }
       
   374                         }
       
   375 
       
   376                         if (doc == null) {
       
   377                             // old metadata doesn't have this imported doc, may be external
       
   378                                 if (resolver != null) {
       
   379                                         try {
       
   380                                                 InputSource source = resolver.resolveEntity(null, url);
       
   381                                                 if (source != null) {
       
   382                                                         MutableXMLStreamBuffer xsb = new MutableXMLStreamBuffer();
       
   383                                                         XMLStreamReader reader = XmlUtil.newXMLInputFactory(true).createXMLStreamReader(source.getByteStream());
       
   384                                                         xsb.createFromXMLStreamReader(reader);
       
   385 
       
   386                                                         SDDocumentSource sdocSource = SDDocumentImpl.create(new URL(url), xsb);
       
   387                                                         doc = SDDocumentImpl.create(sdocSource, null, null);
       
   388                                                 }
       
   389                                         } catch (Exception ex) {
       
   390                                                 ex.printStackTrace();
       
   391                                         }
   358                                 }
   392                                 }
   359                         } catch (Exception ex) {
       
   360                                 ex.printStackTrace();
       
   361                         }
   393                         }
       
   394                     }
       
   395                     // Check if new metadata already contains this doc
       
   396                     if (doc != null && !newMap.containsKey(url)) {
       
   397                         newMap.put(url, doc);
       
   398                         remaining.addAll(doc.getImports());
       
   399                     }
   362                 }
   400                 }
   363             }
   401 
   364             // Check if new metadata already contains this doc
   402                 return newMap.values().iterator();
   365             if (doc != null && !newMap.containsKey(url)) {
   403             }
   366                 newMap.put(url, doc);
   404 
   367                 remaining.addAll(doc.getImports());
   405             @Override
   368             }
   406             public int size() {
   369         }
   407                 int size = 0;
   370         List<SDDocumentImpl> newMetadata = new ArrayList<SDDocumentImpl>();
   408                 Iterator<SDDocumentImpl> it = iterator();
   371         newMetadata.addAll(newMap.values());
   409                 while (it.hasNext()) {
   372         return newMetadata;
   410                     it.next();
       
   411                     size++;
       
   412                 }
       
   413                 return size;
       
   414             }
       
   415 
       
   416             @Override
       
   417             public void clear() {
       
   418                 throw new UnsupportedOperationException();
       
   419             }
       
   420 
       
   421             @Override
       
   422             public boolean isEmpty() {
       
   423                 return docList.isEmpty();
       
   424             }
       
   425         };
   373     }
   426     }
   374 
   427 
   375     private static <T> void processHandlerAnnotation(WSBinding binding, Class<T> implType, QName serviceName, QName portName) {
   428     private static <T> void processHandlerAnnotation(WSBinding binding, Class<T> implType, QName serviceName, QName portName) {
   376         HandlerAnnotationInfo chainInfo =
   429         HandlerAnnotationInfo chainInfo =
   377                 HandlerAnnotationProcessor.buildHandlerInfo(
   430                 HandlerAnnotationProcessor.buildHandlerInfo(
   597 
   650 
   598     /**
   651     /**
   599      * Generates the WSDL and XML Schema for the endpoint if necessary
   652      * Generates the WSDL and XML Schema for the endpoint if necessary
   600      * It generates WSDL only for SOAP1.1, and for XSOAP1.2 bindings
   653      * It generates WSDL only for SOAP1.1, and for XSOAP1.2 bindings
   601      */
   654      */
   602     private static SDDocumentImpl generateWSDL(WSBinding binding, AbstractSEIModelImpl seiModel, List<SDDocumentImpl> docs,
   655     private static SDDocumentImpl generateWSDL(WSBinding binding, AbstractSEIModelImpl seiModel, Collection<SDDocumentImpl> docs,
   603                                                Container container, Class implType) {
   656                                                Container container, Class implType) {
   604         BindingID bindingId = binding.getBindingId();
   657         BindingID bindingId = binding.getBindingId();
   605         if (!bindingId.canGenerateWSDL()) {
   658         if (!bindingId.canGenerateWSDL()) {
   606             throw new ServerRtException("can.not.generate.wsdl", bindingId);
   659             throw new ServerRtException("can.not.generate.wsdl", bindingId);
   607         }
   660         }
   632     }
   685     }
   633 
   686 
   634     /**
   687     /**
   635      * Builds {@link SDDocumentImpl} from {@link SDDocumentSource}.
   688      * Builds {@link SDDocumentImpl} from {@link SDDocumentSource}.
   636      */
   689      */
   637     private static List<SDDocumentImpl> categoriseMetadata(
   690     private static Collection<SDDocumentImpl> categoriseMetadata(
   638         List<SDDocumentSource> src, QName serviceName, QName portTypeName) {
   691         final Iterator<SDDocumentSource> src, final QName serviceName, final QName portTypeName) {
   639 
   692 
   640         List<SDDocumentImpl> r = new ArrayList<SDDocumentImpl>(src.size());
   693         return new AbstractCollection<SDDocumentImpl>() {
   641         for (SDDocumentSource doc : src) {
   694             private final Collection<SDDocumentImpl> theConverted = new ArrayList<SDDocumentImpl>();
   642             r.add(SDDocumentImpl.create(doc,serviceName,portTypeName));
   695 
   643         }
   696             @Override
   644         return r;
   697             public boolean add(SDDocumentImpl arg0) {
       
   698                 return theConverted.add(arg0);
       
   699             }
       
   700 
       
   701             @Override
       
   702             public Iterator<SDDocumentImpl> iterator() {
       
   703                 return new Iterator<SDDocumentImpl>() {
       
   704                     private Iterator<SDDocumentImpl> convIt = theConverted.iterator();
       
   705                     @Override
       
   706                     public boolean hasNext() {
       
   707                         if (convIt != null && convIt.hasNext())
       
   708                             return true;
       
   709                         return src.hasNext();
       
   710                     }
       
   711 
       
   712                     @Override
       
   713                     public SDDocumentImpl next() {
       
   714                         if (convIt != null && convIt.hasNext())
       
   715                             return convIt.next();
       
   716                         convIt = null;
       
   717                         if (!src.hasNext())
       
   718                             throw new NoSuchElementException();
       
   719                         SDDocumentImpl next = SDDocumentImpl.create(src.next(),serviceName,portTypeName);
       
   720                         theConverted.add(next);
       
   721                         return next;
       
   722                     }
       
   723 
       
   724                     @Override
       
   725                     public void remove() {
       
   726                         throw new UnsupportedOperationException();
       
   727                     }
       
   728                 };
       
   729             }
       
   730 
       
   731             @Override
       
   732             public int size() {
       
   733                 throw new UnsupportedOperationException();
       
   734             }
       
   735 
       
   736             @Override
       
   737             public boolean isEmpty() {
       
   738                 if (!theConverted.isEmpty())
       
   739                     return false;
       
   740                 return !src.hasNext();
       
   741             }
       
   742         };
   645     }
   743     }
   646 
   744 
   647     /**
   745     /**
   648      * Verifies whether the given primaryWsdl contains the given serviceName.
   746      * Verifies whether the given primaryWsdl contains the given serviceName.
   649      * If the WSDL doesn't have the service, it throws an WebServiceException.
   747      * If the WSDL doesn't have the service, it throws an WebServiceException.
   673      * it throws an exception.
   771      * it throws an exception.
   674      *
   772      *
   675      * @return primay wsdl document, null if is not there in the docList
   773      * @return primay wsdl document, null if is not there in the docList
   676      *
   774      *
   677      */
   775      */
   678     private static @Nullable SDDocumentImpl findPrimary(@NotNull List<SDDocumentImpl> docList) {
   776     private static @Nullable SDDocumentImpl findPrimary(@NotNull Collection<SDDocumentImpl> docList) {
   679         SDDocumentImpl primaryDoc = null;
   777         SDDocumentImpl primaryDoc = null;
   680         boolean foundConcrete = false;
   778         boolean foundConcrete = false;
   681         boolean foundAbstract = false;
   779         boolean foundAbstract = false;
   682         for(SDDocumentImpl doc : docList) {
   780         for(SDDocumentImpl doc : docList) {
   683             if (doc instanceof SDDocument.WSDL) {
   781             if (doc instanceof SDDocument.WSDL) {
   708      * @param serviceName service name in wsdl
   806      * @param serviceName service name in wsdl
   709      * @param portName port name in WSDL
   807      * @param portName port name in WSDL
   710      * @param container container in which this service is running
   808      * @param container container in which this service is running
   711      * @return non-null wsdl port object
   809      * @return non-null wsdl port object
   712      */
   810      */
   713     private static @NotNull WSDLPort getWSDLPort(SDDocumentSource primaryWsdl, List<? extends SDDocumentSource> metadata,
   811     private static @NotNull WSDLPort getWSDLPort(SDDocumentSource primaryWsdl, Collection<? extends SDDocumentSource> metadata,
   714                                                      @NotNull QName serviceName, @NotNull QName portName, Container container,
   812                                                      @NotNull QName serviceName, @NotNull QName portName, Container container,
   715                                                      EntityResolver resolver) {
   813                                                      EntityResolver resolver) {
   716         URL wsdlUrl = primaryWsdl.getSystemId();
   814         URL wsdlUrl = primaryWsdl.getSystemId();
   717         try {
   815         try {
   718             // TODO: delegate to another entity resolver
   816             // TODO: delegate to another entity resolver
   744 
   842 
   745     /**
   843     /**
   746      * {@link XMLEntityResolver} that can resolve to {@link SDDocumentSource}s.
   844      * {@link XMLEntityResolver} that can resolve to {@link SDDocumentSource}s.
   747      */
   845      */
   748     private static final class EntityResolverImpl implements XMLEntityResolver {
   846     private static final class EntityResolverImpl implements XMLEntityResolver {
   749         private Map<String,SDDocumentSource> metadata = new HashMap<String,SDDocumentSource>();
   847         private Iterator<? extends SDDocumentSource> origMetadata;
       
   848         private Map<String,SDDocumentSource> metadata = new ConcurrentHashMap<String,SDDocumentSource>();
   750         private EntityResolver resolver;
   849         private EntityResolver resolver;
   751 
   850 
   752         public EntityResolverImpl(List<? extends SDDocumentSource> metadata, EntityResolver resolver) {
   851         public EntityResolverImpl(Collection<? extends SDDocumentSource> metadata, EntityResolver resolver) {
   753             for (SDDocumentSource doc : metadata) {
   852             this.origMetadata = metadata.iterator();
   754                 this.metadata.put(doc.getSystemId().toExternalForm(),doc);
       
   755             }
       
   756             this.resolver = resolver;
   853             this.resolver = resolver;
   757         }
   854         }
   758 
   855 
   759         public Parser resolveEntity (String publicId, String systemId) throws IOException, XMLStreamException {
   856         public Parser resolveEntity (String publicId, String systemId) throws IOException, XMLStreamException {
   760             if (systemId != null) {
   857             if (systemId != null) {
   761                 SDDocumentSource doc = metadata.get(systemId);
   858                 SDDocumentSource doc = metadata.get(systemId);
   762                 if (doc != null)
   859                 if (doc != null)
   763                     return new Parser(doc);
   860                     return new Parser(doc);
       
   861                 synchronized(this) {
       
   862                     while(origMetadata.hasNext()) {
       
   863                         doc = origMetadata.next();
       
   864                         String extForm = doc.getSystemId().toExternalForm();
       
   865                         this.metadata.put(extForm,doc);
       
   866                         if (systemId.equals(extForm))
       
   867                             return new Parser(doc);
       
   868                     }
       
   869                 }
   764             }
   870             }
   765             if (resolver != null) {
   871             if (resolver != null) {
   766                 try {
   872                 try {
   767                     InputSource source = resolver.resolveEntity(publicId, systemId);
   873                     InputSource source = resolver.resolveEntity(publicId, systemId);
   768                     if (source != null) {
   874                     if (source != null) {
   778 
   884 
   779     }
   885     }
   780 
   886 
   781     private static final Logger logger = Logger.getLogger(
   887     private static final Logger logger = Logger.getLogger(
   782         com.sun.xml.internal.ws.util.Constants.LoggingDomain + ".server.endpoint");
   888         com.sun.xml.internal.ws.util.Constants.LoggingDomain + ".server.endpoint");
       
   889 
       
   890     private static class CollectionCollection<T> extends AbstractCollection<T> {
       
   891 
       
   892         private final Collection<Collection<? extends T>> cols = new ArrayList<Collection<? extends T>>();
       
   893 
       
   894         @Override
       
   895         public Iterator<T> iterator() {
       
   896             final Iterator<Collection<? extends T>> colIt = cols.iterator();
       
   897             return new Iterator<T>() {
       
   898                 private Iterator<? extends T> current = null;
       
   899 
       
   900                 @Override
       
   901                 public boolean hasNext() {
       
   902                     if (current == null || !current.hasNext()) {
       
   903                         do {
       
   904                             if (!colIt.hasNext())
       
   905                                 return false;
       
   906                             current = colIt.next().iterator();
       
   907                         } while (!current.hasNext());
       
   908                         return true;
       
   909                     }
       
   910                     return true;
       
   911                 }
       
   912 
       
   913                 @Override
       
   914                 public T next() {
       
   915                     if (!hasNext())
       
   916                         throw new NoSuchElementException();
       
   917                     return current.next();
       
   918                 }
       
   919 
       
   920                 @Override
       
   921                 public void remove() {
       
   922                     if (current == null)
       
   923                         throw new IllegalStateException();
       
   924                     current.remove();
       
   925                 }
       
   926             };
       
   927         }
       
   928 
       
   929         @Override
       
   930         public int size() {
       
   931             int size = 0;
       
   932             for (Collection<? extends T> c : cols)
       
   933                 size += c.size();
       
   934             return size;
       
   935         }
       
   936 
       
   937         @Override
       
   938         public boolean add(T arg0) {
       
   939             return cols.add(Collections.singleton(arg0));
       
   940         }
       
   941 
       
   942         @Override
       
   943         public boolean addAll(Collection<? extends T> arg0) {
       
   944             return cols.add(arg0);
       
   945         }
       
   946 
       
   947         @Override
       
   948         public void clear() {
       
   949             cols.clear();
       
   950         }
       
   951 
       
   952         @Override
       
   953         public boolean isEmpty() {
       
   954             return !iterator().hasNext();
       
   955         }
       
   956     }
   783 }
   957 }