001    /*
002     * Copyright (C) 2007 The Guava Authors
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    package com.google.common.io;
018    
019    import static com.google.common.base.Preconditions.checkArgument;
020    import static com.google.common.base.Preconditions.checkNotNull;
021    
022    import com.google.common.annotations.Beta;
023    import com.google.common.base.Charsets;
024    
025    import java.io.IOException;
026    import java.io.InputStream;
027    import java.io.InputStreamReader;
028    import java.io.OutputStream;
029    import java.net.URL;
030    import java.nio.charset.Charset;
031    import java.util.List;
032    
033    /**
034     * Provides utility methods for working with resources in the classpath.
035     * Note that even though these methods use {@link URL} parameters, they
036     * are usually not appropriate for HTTP or other non-classpath resources.
037     *
038     * <p>All method parameters must be non-null unless documented otherwise.
039     *
040     * @author Chris Nokleberg
041     * @author Ben Yu
042     * @since 1.0
043     */
044    @Beta
045    public final class Resources {
046      private Resources() {}
047    
048      /**
049       * Returns a factory that will supply instances of {@link InputStream} that
050       * read from the given URL.
051       *
052       * @param url the URL to read from
053       * @return the factory
054       */
055      public static InputSupplier<InputStream> newInputStreamSupplier(
056          final URL url) {
057        checkNotNull(url);
058        return new InputSupplier<InputStream>() {
059          @Override
060          public InputStream getInput() throws IOException {
061            return url.openStream();
062          }
063        };
064      }
065    
066      /**
067       * Returns a factory that will supply instances of
068       * {@link InputStreamReader} that read a URL using the given character set.
069       *
070       * @param url the URL to read from
071       * @param charset the charset used to decode the input stream; see {@link
072       *     Charsets} for helpful predefined constants
073       * @return the factory
074       */
075      public static InputSupplier<InputStreamReader> newReaderSupplier(
076          URL url, Charset charset) {
077        return CharStreams.newReaderSupplier(newInputStreamSupplier(url), charset);
078      }
079    
080      /**
081       * Reads all bytes from a URL into a byte array.
082       *
083       * @param url the URL to read from
084       * @return a byte array containing all the bytes from the URL
085       * @throws IOException if an I/O error occurs
086       */
087      public static byte[] toByteArray(URL url) throws IOException {
088        return ByteStreams.toByteArray(newInputStreamSupplier(url));
089      }
090    
091      /**
092       * Reads all characters from a URL into a {@link String}, using the given
093       * character set.
094       *
095       * @param url the URL to read from
096       * @param charset the charset used to decode the input stream; see {@link
097       *     Charsets} for helpful predefined constants
098       * @return a string containing all the characters from the URL
099       * @throws IOException if an I/O error occurs.
100       */
101      public static String toString(URL url, Charset charset) throws IOException {
102        return CharStreams.toString(newReaderSupplier(url, charset));
103      }
104    
105      /**
106       * Streams lines from a URL, stopping when our callback returns false, or we
107       * have read all of the lines.
108       *
109       * @param url the URL to read from
110       * @param charset the charset used to decode the input stream; see {@link
111       *     Charsets} for helpful predefined constants
112       * @param callback the LineProcessor to use to handle the lines
113       * @return the output of processing the lines
114       * @throws IOException if an I/O error occurs
115       */
116      public static <T> T readLines(URL url, Charset charset,
117          LineProcessor<T> callback) throws IOException {
118        return CharStreams.readLines(newReaderSupplier(url, charset), callback);
119      }
120    
121      /**
122       * Reads all of the lines from a URL. The lines do not include
123       * line-termination characters, but do include other leading and trailing
124       * whitespace.
125       *
126       * @param url the URL to read from
127       * @param charset the charset used to decode the input stream; see {@link
128       *     Charsets} for helpful predefined constants
129       * @return a mutable {@link List} containing all the lines
130       * @throws IOException if an I/O error occurs
131       */
132      public static List<String> readLines(URL url, Charset charset)
133          throws IOException {
134        return CharStreams.readLines(newReaderSupplier(url, charset));
135      }
136    
137      /**
138       * Copies all bytes from a URL to an output stream.
139       *
140       * @param from the URL to read from
141       * @param to the output stream
142       * @throws IOException if an I/O error occurs
143       */
144      public static void copy(URL from, OutputStream to) throws IOException {
145        ByteStreams.copy(newInputStreamSupplier(from), to);
146      }
147      
148      /**
149       * Returns a {@code URL} pointing to {@code resourceName} if the resource is
150       * found in the class path. {@code Resources.class.getClassLoader()} is used
151       * to locate the resource.
152       * 
153       * @throws IllegalArgumentException if resource is not found
154       */
155      public static URL getResource(String resourceName) {
156        URL url = Resources.class.getClassLoader().getResource(resourceName);
157        checkArgument(url != null, "resource %s not found.", resourceName);
158        return url;
159      }
160    
161      /**
162       * Returns a {@code URL} pointing to {@code resourceName} that is relative to
163       * {@code contextClass}, if the resource is found in the class path. 
164       * 
165       * @throws IllegalArgumentException if resource is not found
166       */
167      public static URL getResource(Class<?> contextClass, String resourceName) {
168        URL url = contextClass.getResource(resourceName);
169        checkArgument(url != null, "resource %s relative to %s not found.",
170            resourceName, contextClass.getName());
171        return url;
172      }
173    }