Java tutorial
// ~~~~~~~~~~~~~~~~~~~~~~~~~~ // //// /// /// /// ////// //// // //// //// /// //// //// // //// //// /// //// ///// // /// /// //// ///// // //// ////// // /// ///// // //// //// // //// ///// // //// //// ///////////// //// //// //////////// /// /// ///// ///// //// //// ///// ///// //// ///// // //// //// /// ///// // ///// ///// //////////// //// //// //// //// // The Web framework with class. // ~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2013 Adam R. Nelson // // 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.sector91.wit.resources; import java.io.IOException; import java.io.InputStream; import java.util.Objects; import java.util.concurrent.ExecutionException; import com.esotericsoftware.minlog.Log; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import com.google.common.util.concurrent.UncheckedExecutionException; public abstract class ResourceLoader<T> { static final String TAG = ResourceLoader.class.getSimpleName(); final ClassLoader context; final String rootPath; private final LoadingCache<String, T> cache; public ResourceLoader(Class<?> context) { this(context, ""); } public ResourceLoader(Class<?> context, String rootPath) { this(context.getClassLoader(), rootPath); } public ResourceLoader(Class<?> context, String rootPath, CacheBuilder<? super String, ? super T> cacheBuilder) { this(context.getClassLoader(), rootPath, cacheBuilder); } public ResourceLoader(ClassLoader context) { this(context, ""); } public ResourceLoader(ClassLoader context, String rootPath) { this(context, rootPath, CacheBuilder.newBuilder()); } public ResourceLoader(ClassLoader context, String rootPath, CacheBuilder<? super String, ? super T> cacheBuilder) { Objects.requireNonNull(context, "A ResourceLoader's ClassLoader cannot be null."); Objects.requireNonNull(rootPath, "A ResourceLoader's root path cannot be null."); this.context = context; while (rootPath.endsWith("/")) rootPath = rootPath.substring(0, rootPath.length() - 1); while (rootPath.startsWith("/")) rootPath = rootPath.substring(1); this.rootPath = rootPath; this.cache = cacheBuilder.build(new ResourceCacheLoader()); Log.trace(TAG, "Created ResourceLoader for path '" + rootPath + "'."); } public final T load(String path) throws ResourceNotFoundException { if (!path.startsWith("/")) path = "/" + path; try { Log.trace(TAG, "Loading resource '" + path + "', under root path '" + rootPath + "'."); return cache.get(path); } catch (ExecutionException ex) { throw (ResourceNotFoundException) ex.getCause(); } catch (UncheckedExecutionException ex) { throw (RuntimeException) ex.getCause(); } } protected abstract T convert(String path, InputStream in) throws IOException; class ResourceCacheLoader extends CacheLoader<String, T> { @Override public T load(String path) throws ResourceNotFoundException { final InputStream in = context.getResourceAsStream(rootPath + path); if (in == null) { final String msg = "Could not find resource '" + rootPath + path + "'."; Log.debug(TAG, msg); throw new ResourceNotFoundException(msg); } try { Log.trace(TAG, "Successfully loaded resource '" + rootPath + path + "'."); return convert(path, in); } catch (IOException ex) { throw new ResourceNotFoundException("Could not read resource '" + rootPath + path + "'.", ex); } } } }