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