       1 /*
       2  * Copyright (c) 2010, 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  */
      25
      26 package jdk.nashorn.api.scripting;
      27
      28 import java.io.CharArrayReader;
      29 import java.io.IOException;
      30 import java.io.Reader;
      31 import java.net.URL;
      32 import java.nio.charset.Charset;
      33 import java.util.Objects;
      34 import jdk.nashorn.internal.runtime.Source;
      35
      36 /**
      37  * A Reader that reads from a URL. Used to make sure that the reader
      38  * reads content from given URL and can be trusted to do so.
      39  *
      40  * @since 1.8u40
      41  */
      42 public final class URLReader extends Reader {
      43     // underlying URL
      44     private final URL url;
      45     // Charset used to convert
      46     private final Charset cs;
      47
      48     // lazily initialized underlying reader for URL
      49     private Reader reader;
      50
      51     /**
      52      * Constructor
      53      *
      54      * @param url URL for this URLReader
      55      * @throws NullPointerException if url is null
      56      */
      57     public URLReader(final URL url) {
      58         this(url, (Charset)null);
      59     }
      60
      61     /**
      62      * Constructor
      63      *
      64      * @param url URL for this URLReader
      65      * @param charsetName  Name of the Charset used to convert bytes to chars
      66      * @throws NullPointerException if url is null
      67      */
      68     public URLReader(final URL url, final String charsetName) {
      69         this(url, Charset.forName(charsetName));
      70     }
      71
      72     /**
      73      * Constructor
      74      *
      75      * @param url URL for this URLReader
      76      * @param cs  Charset used to convert bytes to chars
      77      * @throws NullPointerException if url is null
      78      */
      79     public URLReader(final URL url, final Charset cs) {
      80         this.url = Objects.requireNonNull(url);
      81         this.cs  = cs;
      82     }
      83
      84     @Override
      85     public int read(final char cbuf[], final int off, final int len) throws IOException {
      86         return getReader().read(cbuf, off, len);
      87     }
      88
      89     @Override
      90     public void close() throws IOException {
      91         getReader().close();
      92     }
      93
      94     /**
      95      * URL of this reader
      96      * @return the URL from which this reader reads.
      97      */
      98     public URL getURL() {
      99         return url;
     100     }
     101
     102     /**
     103      * Charset used by this reader
     104      *
     105      * @return the Charset used to convert bytes to chars
     106      */
     107     public Charset getCharset() {
     108         return cs;
     109     }
     110
     111     // lazily initialize char array reader using URL content
     112     private Reader getReader() throws IOException {
     113         synchronized (lock) {
     114             if (reader == null) {
     115                 reader = new CharArrayReader(Source.readFully(url, cs));
     116             }
     117         }
     118
     119         return reader;
     120     }
     121 }