co.jirm.core.util.ResourceUtils.java Source code

Java tutorial

Introduction

Here is the source code for co.jirm.core.util.ResourceUtils.java

Source

/**
 * Copyright (C) 2012 the original author or authors.
 *
 * 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 co.jirm.core.util;

import java.io.IOException;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

import com.google.common.base.Charsets;
import com.google.common.base.Objects;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.base.Throwables;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.io.Resources;
import com.google.common.util.concurrent.UncheckedExecutionException;

public class ResourceUtils {

    public static long expire = 10;

    public static void setCacheExpire(long expire) {
        ResourceUtils.expire = expire;
    }

    private final static Supplier<Cache<ClasspathResourceKey, String>> cacheSupplier = Suppliers
            .memoize(new Supplier<Cache<ClasspathResourceKey, String>>() {
                @Override
                public Cache<ClasspathResourceKey, String> get() {
                    return CacheBuilder.newBuilder().maximumSize(100).expireAfterAccess(expire, TimeUnit.SECONDS)
                            .build();
                }
            });

    public static String getClasspathResourceAsString(final Class<?> klass, final String path, boolean cache)
            throws IOException {
        if (cache) {
            return getClasspathResourceAsString(klass, path);
        } else {
            return _getClasspathResourceAsString(klass, path);
        }
    }

    public static String getClasspathResourceAsString(final Class<?> klass, final String path) throws IOException {
        try {
            return cacheSupplier.get().get(new ClasspathResourceKey(path, klass), new Callable<String>() {
                @Override
                public String call() throws Exception {
                    return _getClasspathResourceAsString(klass, path);
                }

            });
        } catch (ExecutionException e) {
            throw new IOException(e);
        } catch (UncheckedExecutionException e) {
            throw Throwables.propagate(Objects.firstNonNull(e.getCause(), e));
        }
    }

    public static String getClasspathResourceAsString(final String path) throws IOException {
        try {
            return cacheSupplier.get().get(new ClasspathResourceKey(path), new Callable<String>() {
                @Override
                public String call() throws Exception {
                    return _getClasspathResourceAsString(path);
                }

            });
        } catch (ExecutionException e) {
            throw new IOException(e);
        } catch (UncheckedExecutionException e) {
            throw Throwables.propagate(Objects.firstNonNull(e.getCause(), e));
        }
    }

    private static String _getClasspathResourceAsString(Class<?> k, String path) throws IOException {
        return Resources.toString(Resources.getResource(k, path), Charsets.UTF_8);
    }

    public static String resolvePath(Class<?> c, String path) {
        return resolveName(c, path);
    }

    /*
     * Add a package name prefix if the name is not absolute Remove leading "/"
     * if name is absolute
     */
    private static String resolveName(Class<?> c, String name) {
        if (name == null) {
            return name;
        }
        if (!name.startsWith("/")) {
            while (c.isArray()) {
                c = c.getComponentType();
            }
            String baseName = c.getName();
            int index = baseName.lastIndexOf('.');
            if (index != -1) {
                name = baseName.substring(0, index).replace('.', '/') + "/" + name;
            }
        } else {
            name = name.substring(1);
        }
        return name;
    }

    private static String _getClasspathResourceAsString(String path) throws IOException {
        return Resources.toString(Resources.getResource(path), Charsets.UTF_8);
    }

    private static class ClasspathResourceKey {
        private final String path;
        private final String klassName;

        private ClasspathResourceKey(String path) {
            super();
            this.path = path;
            this.klassName = "";
        }

        private ClasspathResourceKey(String path, Class<?> klass) {
            super();
            this.path = path;
            /*
             * Lets avoid leaky permgen errors.
             */
            this.klassName = "CLASS:" + klass.getCanonicalName();
        }

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((klassName == null) ? 0 : klassName.hashCode());
            result = prime * result + ((path == null) ? 0 : path.hashCode());
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            ClasspathResourceKey other = (ClasspathResourceKey) obj;
            if (klassName == null) {
                if (other.klassName != null)
                    return false;
            } else if (!klassName.equals(other.klassName))
                return false;
            if (path == null) {
                if (other.path != null)
                    return false;
            } else if (!path.equals(other.path))
                return false;
            return true;
        }

    }

}