001    /*
002     * Copyright (C) 2007 Google Inc.
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    
024    import java.io.IOException;
025    import java.io.InputStream;
026    import java.io.InputStreamReader;
027    import java.io.OutputStream;
028    import java.net.URL;
029    import java.nio.charset.Charset;
030    import java.util.List;
031    
032    /**
033     * Provides utility methods for working with resources in the classpath.
034     * Note that even though these methods use {@link URL} parameters, they
035     * are usually not appropriate for HTTP or other non-classpath resources.
036     *
037     * <p>All method parameters must be non-null unless documented otherwise.
038     *
039     * @author Chris Nokleberg
040     * @author Ben Yu
041     * @since 1
042     */
043    @Beta
044    public final class Resources {
045      private Resources() {}
046    
047      /**
048       * Returns a factory that will supply instances of {@link InputStream} that
049       * read from the given URL.
050       *
051       * @param url the URL to read from
052       * @return the factory
053       */
054      public static InputSupplier<InputStream> newInputStreamSupplier(
055          final URL url) {
056        checkNotNull(url);
057        return new InputSupplier<InputStream>() {
058          public InputStream getInput() throws IOException {
059            return url.openStream();
060          }
061        };
062      }
063    
064      /**
065       * Returns a factory that will supply instances of
066       * {@link InputStreamReader} that read a URL using the given character set.
067       *
068       * @param url the URL to read from
069       * @param charset the character set used when reading the URL contents
070       * @return the factory
071       */
072      public static InputSupplier<InputStreamReader> newReaderSupplier(
073          URL url, Charset charset) {
074        return CharStreams.newReaderSupplier(newInputStreamSupplier(url), charset);
075      }
076    
077      /**
078       * Reads all bytes from a URL into a byte array.
079       *
080       * @param url the URL to read from
081       * @return a byte array containing all the bytes from the URL
082       * @throws IOException if an I/O error occurs
083       */
084      public static byte[] toByteArray(URL url) throws IOException {
085        return ByteStreams.toByteArray(newInputStreamSupplier(url));
086      }
087    
088      /**
089       * Reads all characters from a URL into a {@link String}, using the given
090       * character set.
091       *
092       * @param url the URL to read from
093       * @param charset the character set used when reading the URL
094       * @return a string containing all the characters from the URL
095       * @throws IOException if an I/O error occurs.
096       */
097      public static String toString(URL url, Charset charset) throws IOException {
098        return CharStreams.toString(newReaderSupplier(url, charset));
099      }
100    
101      /**
102       * Streams lines from a URL, stopping when our callback returns false, or we
103       * have read all of the lines.
104       *
105       * @param url the URL to read from
106       * @param charset the character set used when reading the URL
107       * @param callback the LineProcessor to use to handle the lines
108       * @return the output of processing the lines
109       * @throws IOException if an I/O error occurs
110       */
111      public static <T> T readLines(URL url, Charset charset,
112          LineProcessor<T> callback) throws IOException {
113        return CharStreams.readLines(newReaderSupplier(url, charset), callback);
114      }
115    
116      /**
117       * Reads all of the lines from a URL. The lines do not include
118       * line-termination characters, but do include other leading and trailing
119       * whitespace.
120       *
121       * @param url the URL to read from
122       * @param charset the character set used when writing the file
123       * @return a mutable {@link List} containing all the lines
124       * @throws IOException if an I/O error occurs
125       */
126      public static List<String> readLines(URL url, Charset charset)
127          throws IOException {
128        return CharStreams.readLines(newReaderSupplier(url, charset));
129      }
130    
131      /**
132       * Copies all bytes from a URL to an output stream.
133       *
134       * @param from the URL to read from
135       * @param to the output stream
136       * @throws IOException if an I/O error occurs
137       */
138      public static void copy(URL from, OutputStream to) throws IOException {
139        ByteStreams.copy(newInputStreamSupplier(from), to);
140      }
141      
142      /**
143       * Returns a {@code URL} pointing to {@code resourceName} if the resource is
144       * found in the class path. {@code Resources.class.getClassLoader()} is used
145       * to locate the resource.
146       * 
147       * @throws IllegalArgumentException if resource is not found
148       */
149      public static URL getResource(String resourceName) {
150        URL url = Resources.class.getClassLoader().getResource(resourceName);
151        checkArgument(url != null, "resource %s not found.", resourceName);
152        return url;
153      }
154    
155      /**
156       * Returns a {@code URL} pointing to {@code resourceName} that is relative to
157       * {@code contextClass}, if the resource is found in the class path. 
158       * 
159       * @throws IllegalArgumentException if resource is not found
160       */
161      public static URL getResource(Class<?> contextClass, String resourceName) {
162        URL url = contextClass.getResource(resourceName);
163        checkArgument(url != null, "resource %s relative to %s not found.",
164            resourceName, contextClass.getName());
165        return url;
166      }
167    }