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 * |
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( |
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. |
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 } |