1 /*
   2  * Copyright (c) 1997, 2017, 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  */
  25 
  26 package com.sun.xml.internal.ws.api.server;
  27 
  28 import com.sun.xml.internal.stream.buffer.XMLStreamBuffer;
  29 import com.sun.xml.internal.ws.api.streaming.XMLStreamReaderFactory;
  30 import com.sun.xml.internal.ws.server.ServerRtException;
  31 import com.sun.xml.internal.ws.streaming.TidyXMLStreamReader;
  32 
  33 import javax.xml.stream.XMLInputFactory;
  34 import javax.xml.stream.XMLStreamException;
  35 import javax.xml.stream.XMLStreamReader;
  36 import java.io.IOException;
  37 import java.io.InputStream;
  38 import java.lang.reflect.Method;
  39 import java.net.MalformedURLException;
  40 import java.net.URL;
  41 
  42 /**
  43  * SPI that provides the source of {@link SDDocument}.
  44  *
  45  * <p>
  46  * This abstract class could be implemented by applications, or one of the
  47  * {@link #create} methods can be used.
  48  *
  49  * @author Kohsuke Kawaguchi
  50  */
  51 public abstract class SDDocumentSource {
  52     /**
  53      * Returns the {@link XMLStreamReader} that reads the document.
  54      *
  55      * <p>
  56      * This method maybe invoked multiple times concurrently.
  57      *
  58      * @param xif
  59      *      The implementation may choose to use this object when it wants to
  60      *      create a new parser (or it can just ignore this parameter completely.)
  61      * @return
  62      *      The caller is responsible for closing the reader to avoid resource leak.
  63      *
  64      * @throws XMLStreamException
  65      *      if something goes wrong while creating a parser.
  66      * @throws IOException
  67      *      if something goes wrong trying to read the document.
  68      */
  69     public abstract XMLStreamReader read(XMLInputFactory xif) throws IOException, XMLStreamException;
  70 
  71     /**
  72      * Returns the {@link XMLStreamReader} that reads the document.
  73      *
  74      * <p>
  75      * This method maybe invoked multiple times concurrently.
  76      *
  77      * @return
  78      *      The caller is responsible for closing the reader to avoid resource leak.
  79      *
  80      * @throws XMLStreamException
  81      *      if something goes wrong while creating a parser.
  82      * @throws IOException
  83      *      if something goes wrong trying to read the document.
  84      */
  85     public abstract XMLStreamReader read() throws IOException, XMLStreamException;
  86 
  87     /**
  88      * System ID of this document.
  89      * @return
  90      */
  91     public abstract URL getSystemId();
  92 
  93     public static SDDocumentSource create(final Class<?> implClass, final String wsdlLocation) {
  94         ClassLoader cl = implClass.getClassLoader();
  95         URL url = cl.getResource(wsdlLocation);
  96         if (url != null) {
  97             return create(url);
  98         } else {
  99             return create(wsdlLocation, implClass);
 100         }
 101     }
 102 
 103     /**
 104      * Creates {@link SDDocumentSource} from an URL.
 105      * @param url
 106      * @return
 107      */
 108     public static SDDocumentSource create(final URL url) {
 109         return new SDDocumentSource() {
 110             private final URL systemId = url;
 111 
 112             @Override
 113             public XMLStreamReader read(XMLInputFactory xif) throws IOException, XMLStreamException {
 114                 InputStream is = url.openStream();
 115                 return new TidyXMLStreamReader(
 116                     xif.createXMLStreamReader(systemId.toExternalForm(),is), is);
 117             }
 118 
 119             @Override
 120             public XMLStreamReader read() throws IOException, XMLStreamException {
 121                 InputStream is = url.openStream();
 122                 return new TidyXMLStreamReader(
 123                    XMLStreamReaderFactory.create(systemId.toExternalForm(),is,false), is);
 124             }
 125 
 126             @Override
 127             public URL getSystemId() {
 128                 return systemId;
 129             }
 130         };
 131     }
 132 
 133     /**
 134      * Creates {@link SDDocumentSource} from resource path using resolvingClass to read the resource.
 135      * Required for Jigsaw runtime.
 136      *
 137      * @param resolvingClass class used to read resource
 138      * @param path resource path
 139      */
 140     private static SDDocumentSource create(final String path, final Class<?> resolvingClass) {
 141         return new SDDocumentSource() {
 142 
 143             @Override
 144             public XMLStreamReader read(XMLInputFactory xif) throws IOException, XMLStreamException {
 145                 InputStream is = inputStream();
 146                 return new TidyXMLStreamReader(xif.createXMLStreamReader(path,is), is);
 147             }
 148 
 149             @Override
 150             public XMLStreamReader read() throws IOException, XMLStreamException {
 151                 InputStream is = inputStream();
 152                 return new TidyXMLStreamReader(XMLStreamReaderFactory.create(path,is,false), is);
 153             }
 154 
 155             @Override
 156             public URL getSystemId() {
 157                 try {
 158                     return new URL("file://" + path);
 159                 } catch (MalformedURLException e) {
 160                     return null;
 161                 }
 162             }
 163 
 164             private InputStream inputStream() throws IOException {
 165                 java.lang.Module module = resolvingClass.getModule();
 166                 InputStream stream = module.getResourceAsStream(path);
 167                 if (stream != null) {
 168                     return stream;
 169                 }
 170                 throw new ServerRtException("cannot.load.wsdl", path);
 171             }
 172 
 173         };
 174     }
 175 
 176     /**
 177      * Creates a {@link SDDocumentSource} from {@link XMLStreamBuffer}.
 178      * @param systemId
 179      * @param xsb
 180      * @return
 181      */
 182     public static SDDocumentSource create(final URL systemId, final XMLStreamBuffer xsb) {
 183         return new SDDocumentSource() {
 184             @Override
 185             public XMLStreamReader read(XMLInputFactory xif) throws XMLStreamException {
 186                 return xsb.readAsXMLStreamReader();
 187             }
 188 
 189             @Override
 190             public XMLStreamReader read() throws XMLStreamException {
 191                 return xsb.readAsXMLStreamReader();
 192             }
 193 
 194             @Override
 195             public URL getSystemId() {
 196                 return systemId;
 197             }
 198         };
 199     }
 200 }