com.opengamma.collect.io.ResourceLocator.java Source code

Java tutorial

Introduction

Here is the source code for com.opengamma.collect.io.ResourceLocator.java

Source

/**
 * Copyright (C) 2014 - present by OpenGamma Inc. and the OpenGamma group of companies
 * 
 * Please see distribution for license.
 */
package com.opengamma.collect.io;

import static com.google.common.base.MoreObjects.firstNonNull;

import java.io.File;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.stream.Stream;

import org.joda.convert.FromString;
import org.joda.convert.ToString;

import com.google.common.io.ByteSource;
import com.google.common.io.CharSource;
import com.google.common.io.Files;
import com.google.common.io.Resources;
import com.opengamma.collect.ArgChecker;

/**
 * A locator for a resource, specified as a file or classpath resource.
 * <p>
 * An instance of this class provides access to a resource, such as a configuration file.
 * The resource data is accessed using Guava {@link CharSource} or {@link ByteSource}.
 */
public final class ResourceLocator {

    /**
     * The prefix for classpath resource locators.
     */
    public static final String CLASSPATH_URL_PREFIX = "classpath:";
    /**
     * The prefix for file resource locators.
     */
    public static final String FILE_URL_PREFIX = "file:";

    /**
     * The resource locator.
     */
    private final String locator;
    /**
     * The source.
     */
    private final ByteSource source;

    //-------------------------------------------------------------------------
    /**
     * Creates a resource from a string locator.
     * <p>
     * This accepts locators starting with 'classpath:' or 'file:'.
     * It also accepts unprefixed locators, treated as 'file:'.
     * 
     * @param locator  the string form of the resource locator
     * @return the resource locator
     */
    @FromString
    public static ResourceLocator of(String locator) {
        ArgChecker.notNull(locator, "locator");
        try {
            if (locator.startsWith(CLASSPATH_URL_PREFIX)) {
                String urlStr = locator.substring(CLASSPATH_URL_PREFIX.length());
                return ofClasspathUrl(Resources.getResource(urlStr));

            } else if (locator.startsWith(FILE_URL_PREFIX)) {
                String fileStr = locator.substring(FILE_URL_PREFIX.length());
                return ofFile(new File(fileStr));

            } else {
                return ofFile(new File(locator));
            }
        } catch (RuntimeException ex) {
            throw new IllegalArgumentException("Invalid resource locator: " + locator, ex);
        }
    }

    /**
     * Creates a resource from a {@code File}.
     * 
     * @param file  the file to wrap
     * @return the resource
     */
    public static ResourceLocator ofFile(File file) {
        ArgChecker.notNull(file, "file");
        String filename = file.toString();
        // convert Windows separators to unix
        filename = (File.separatorChar == '\\' ? filename.replace('\\', '/') : filename);
        return new ResourceLocator(FILE_URL_PREFIX + filename, Files.asByteSource(file));
    }

    /**
     * Creates a resource from a {@code URL}.
     * 
     * @param url  the URL to wrap
     * @return the resource
     */
    public static ResourceLocator ofClasspathUrl(URL url) {
        ArgChecker.notNull(url, "url");
        String locator = CLASSPATH_URL_PREFIX + url.toString();
        return new ResourceLocator(locator, Resources.asByteSource(url));
    }

    /**
     * Creates a stream of resource locators.
     * <p>
     * This finds all occurrences of the resource name in the classpath and returns them.
     * 
     * @param classpathResourceName  the classpath resource name
     * @return the resource locators
     */
    @FromString
    public static Stream<ResourceLocator> streamOfClasspathResources(String classpathResourceName) {
        ArgChecker.notNull(classpathResourceName, "classpathResourceName");
        try {
            ClassLoader classLoader = firstNonNull(Thread.currentThread().getContextClassLoader(),
                    ResourceLocator.class.getClassLoader());
            return Collections.list(classLoader.getResources(classpathResourceName)).stream()
                    .map(url -> ResourceLocator.ofClasspathUrl(url));

        } catch (IOException ex) {
            throw new UncheckedIOException(ex);
        }
    }

    //-------------------------------------------------------------------------
    /**
     * Creates an instance of the locator.
     * 
     * @param locator  the locator
     * @param source  the byte source
     */
    private ResourceLocator(String locator, ByteSource source) {
        super();
        this.locator = locator;
        this.source = source;
    }

    //-------------------------------------------------------------------------
    /**
     * Gets the string form of the locator.
     * <p>
     * The string form of the locator describes the location of the resource.
     * 
     * @return the locator string
     */
    public String getLocator() {
        return locator;
    }

    /**
     * Gets the byte source to access the resource.
     * <p>
     * A byte source is a supplier of data.
     * The source itself is neither opened nor closed.
     * 
     * @return the byte source
     */
    public ByteSource getByteSource() {
        return source;
    }

    /**
     * Gets the char source to access the resource using UTF-8.
     * <p>
     * A char source is a supplier of data.
     * The source itself is neither opened nor closed.
     * 
     * @return the char source
     */
    public CharSource getCharSource() {
        return getCharSource(StandardCharsets.UTF_8);
    }

    /**
     * Gets the char source to access the resource specifying the character set.
     * <p>
     * A char source is a supplier of data.
     * The source itself is neither opened nor closed.
     * 
     * @param charset  the character set to use
     * @return the char source
     */
    public CharSource getCharSource(Charset charset) {
        return source.asCharSource(charset);
    }

    //-------------------------------------------------------------------------
    /**
     * Checks if this locator equals another locator.
     * <p>
     * The comparison checks the locator string.
     * 
     * @param obj  the other locator, null returns false
     * @return true if equal
     */
    @Override
    public boolean equals(Object obj) {
        if (obj == this) {
            return true;
        }
        if (obj instanceof ResourceLocator) {
            return locator.equals(((ResourceLocator) obj).locator);
        }
        return false;
    }

    /**
     * Returns a suitable hash code for the locator.
     * 
     * @return the hash code
     */
    @Override
    public int hashCode() {
        return locator.hashCode();
    }

    /**
     * Returns a string describing the locator.
     * <p>
     * This can be parsed using {@link #of(String)}.
     * 
     * @return the descriptive string
     */
    @ToString
    @Override
    public String toString() {
        return locator;
    }

}