001/**
002 * Copyright 2010-2016 Boxfuse GmbH
003 * <p/>
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 * <p/>
008 * http://www.apache.org/licenses/LICENSE-2.0
009 * <p/>
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 */
016package org.avaje.classpath.scanner.internal.scanner.classpath;
017
018import org.avaje.classpath.scanner.internal.FileCopyUtils;
019import org.avaje.classpath.scanner.Resource;
020import org.avaje.classpath.scanner.core.ClassPathScanException;
021
022import java.io.File;
023import java.io.IOException;
024import java.io.InputStream;
025import java.io.InputStreamReader;
026import java.io.Reader;
027import java.io.UnsupportedEncodingException;
028import java.net.URL;
029import java.net.URLDecoder;
030import java.nio.charset.Charset;
031
032/**
033 * A resource on the classpath.
034 */
035public class ClassPathResource implements Comparable<ClassPathResource>, Resource {
036  /**
037   * The location of the resource on the classpath.
038   */
039  private String location;
040
041  /**
042   * The ClassLoader to use.
043   */
044  private ClassLoader classLoader;
045
046  /**
047   * Creates a new ClassPathResource.
048   *
049   * @param location    The location of the resource on the classpath.
050   * @param classLoader The ClassLoader to use.
051   */
052  public ClassPathResource(String location, ClassLoader classLoader) {
053    this.location = location;
054    this.classLoader = classLoader;
055  }
056
057  public String toString() {
058    return location;
059  }
060
061  public String getLocation() {
062    return location;
063  }
064
065  public String getLocationOnDisk() {
066    URL url = getUrl();
067    if (url == null) {
068      throw new ClassPathScanException("Unable to location resource on disk: " + location);
069    }
070    try {
071      return new File(URLDecoder.decode(url.getPath(), "UTF-8")).getAbsolutePath();
072    } catch (UnsupportedEncodingException e) {
073      throw new ClassPathScanException("Unknown encoding: UTF-8", e);
074    }
075  }
076
077  /**
078   * @return The url of this resource.
079   */
080  private URL getUrl() {
081    return classLoader.getResource(location);
082  }
083
084  public String loadAsString(String encoding) {
085    try {
086      InputStream inputStream = classLoader.getResourceAsStream(location);
087      if (inputStream == null) {
088        throw new ClassPathScanException("Unable to obtain inputstream for resource: " + location);
089      }
090      Reader reader = new InputStreamReader(inputStream, Charset.forName(encoding));
091
092      return FileCopyUtils.copyToString(reader);
093    } catch (IOException e) {
094      throw new ClassPathScanException("Unable to load resource: " + location + " (encoding: " + encoding + ")", e);
095    }
096  }
097
098  public byte[] loadAsBytes() {
099    try {
100      InputStream inputStream = classLoader.getResourceAsStream(location);
101      if (inputStream == null) {
102        throw new ClassPathScanException("Unable to obtain inputstream for resource: " + location);
103      }
104      return FileCopyUtils.copyToByteArray(inputStream);
105    } catch (IOException e) {
106      throw new ClassPathScanException("Unable to load resource: " + location, e);
107    }
108  }
109
110  public String getFilename() {
111    return location.substring(location.lastIndexOf("/") + 1);
112  }
113
114  public boolean exists() {
115    return getUrl() != null;
116  }
117
118  @SuppressWarnings({"RedundantIfStatement"})
119  @Override
120  public boolean equals(Object o) {
121    if (this == o) return true;
122    if (o == null || getClass() != o.getClass()) return false;
123
124    ClassPathResource that = (ClassPathResource) o;
125
126    if (!location.equals(that.location)) return false;
127
128    return true;
129  }
130
131  @Override
132  public int hashCode() {
133    return location.hashCode();
134  }
135
136  @SuppressWarnings("NullableProblems")
137  public int compareTo(ClassPathResource o) {
138    return location.compareTo(o.location);
139  }
140}