/*
* Copyright (c) 2013-2017 Cinchapi Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.cinchapi.concourse.util;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Map;
import com.google.common.base.Throwables;
import com.google.common.collect.Maps;
/**
* Utilities to handle getting resources in a standard and portable way.
*
* @author Jeff Nelson
*/
public class Resources {
/**
* Collection which maps a resource name with its URL.
*/
private static Map<String, URL> map = Maps.newHashMap();
/**
* Finds a resource with a given name. The rules for searching resources
* associated with a given class are implemented by the defining
* {@linkplain ClassLoader class loader} of the class. This method
* delegates to this object's class loader. If this object was loaded by
* the bootstrap class loader, the method delegates to
* {@link ClassLoader#getSystemResourceAsStream}.
*
* <p>
* Before delegation, an absolute resource name is constructed from the
* given resource name using this algorithm:
*
* <ul>
*
* <li>If the {@code name} begins with a {@code '/'} (<tt>'\u002f'</tt>
* ), then the absolute name of the resource is the portion of the
* {@code name} following the {@code '/'}.
*
* <li>Otherwise, the absolute name is of the following form:
*
* <blockquote> {@code modified_package_name/name} </blockquote>
*
* <p>
* Where the {@code modified_package_name} is the package name of this
* object with {@code '/'} substituted for {@code '.'} (
* <tt>'\u002e'</tt>).
*
* </ul>
*
* @param name name of the desired resource
* @return A {@link java.io.InputStream} object or {@code null} if
* no resource with this name is found
* @throws NullPointerException If {@code name} is {@code null}
* @since JDK1.1
*/
public static URL get(final String name) {
File temp;
try {
URL url = map.get(name);
if(url == null) {
temp = File.createTempFile("java-resource", ".tmp");
Path path = Paths.get(temp.getAbsolutePath());
Files.copy(Resources.class.getResourceAsStream(name), path,
StandardCopyOption.REPLACE_EXISTING);
url = temp.toURI().toURL();
map.put(name, url);
return url;
}
else {
return url;
}
}
catch (IOException e) {
throw Throwables.propagate(e);
}
}
/**
* Find a resource with a given {@code name} and return an absolute file
* path to access that resource using File path based APIs.
*
* @param name
* @return the file path
*/
public static String getAbsolutePath(final String name) {
try {
return new File(Resources.get(name).toURI()).getAbsolutePath();
}
catch (URISyntaxException e) {
throw Throwables.propagate(e);
}
}
}