ratpack.util.internal.TypeCoercingProperties.java Source code

Java tutorial

Introduction

Here is the source code for ratpack.util.internal.TypeCoercingProperties.java

Source

/*
 * Copyright 2013 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 ratpack.util.internal;

import com.google.common.collect.ImmutableList;
import com.google.common.io.ByteSource;
import com.google.common.io.Files;
import com.google.common.io.Resources;

import java.io.*;
import java.net.*;
import java.util.List;
import java.util.Properties;

import static java.lang.String.format;

/**
 * A delegate for {@link java.util.Properties} that can coerce values to various types.
 */
public class TypeCoercingProperties {

    private final Properties delegate;
    private final ClassLoader classLoader;

    public TypeCoercingProperties(Properties delegate) {
        this(delegate, TypeCoercingProperties.class.getClassLoader());
    }

    public TypeCoercingProperties(Properties delegate, ClassLoader classLoader) {
        this.delegate = delegate;
        this.classLoader = classLoader;
    }

    /**
     * Gets a property value as a String, substituting a default if the property does not exist.
     *
     * @param key the property key.
     * @param defaultValue the value to use if the property does not exist.
     * @return the property value as a String or <code>defaultValue</code> if it does not exist.
     * @see Properties#getProperty(String, String)
     */
    public String asString(String key, String defaultValue) {
        return delegate.getProperty(key, defaultValue);
    }

    /**
     * Gets a property value as a boolean, substituting a default if the property does not exist.
     *
     * @param key the property key.
     * @param defaultValue the value to use if the property does not exist.
     * @return the property value coerced to a boolean as specified by {@link Boolean#parseBoolean(String)} or <code>defaultValue</code> if it does not exist.
     */
    public boolean asBoolean(String key, boolean defaultValue) {
        return Boolean.parseBoolean(delegate.getProperty(key, Boolean.toString(defaultValue)));
    }

    /**
     * Gets a property value as an int, substituting a default if the property does not exist.
     *
     * @param key the property key.
     * @param defaultValue the value to use if the property does not exist.
     * @return the property value coerced to an int as specified by {@link Integer#parseInt(String)} or <code>defaultValue</code> if it does not exist.
     */
    public int asInt(String key, int defaultValue) {
        return Integer.parseInt(delegate.getProperty(key, Integer.toString(defaultValue)));
    }

    /**
     * Gets a property value as an long, substituting a default if the property does not exist.
     *
     * @param key the property key.
     * @param defaultValue the value to use if the property does not exist.
     * @return the property value coerced to an long as specified by {@link Long#parseLong(String)} or <code>defaultValue</code> if it does not exist.
     */
    public long asLong(String key, long defaultValue) {
        return Long.parseLong(delegate.getProperty(key, Long.toString(defaultValue)));
    }

    /**
     * Gets a property value as a URI.
     *
     * @param key the property key.
     * @return the URI represented by the property value or <code>null</code> if the property does not exist.
     * @throws URISyntaxException if the property value is not a valid URI.
     */
    public URI asURI(String key) throws URISyntaxException {
        URI uri = null;
        String uriString = delegate.getProperty(key);

        if (uriString != null) {
            uri = new URI(uriString);
        }
        return uri;
    }

    /**
     * Gets a property value as an InetAddress.
     *
     * @param key the property key.
     * @return the InetAddress represented by the property value or <code>null</code> if the property does not exist.
     * @throws UnknownHostException if the property value is not a valid address.
     */
    public InetAddress asInetAddress(String key) throws UnknownHostException {
        String addressString = delegate.getProperty(key);
        if (addressString == null) {
            return null;
        } else {
            return InetAddress.getByName(addressString);
        }
    }

    /**
     * Gets a property value as a List of Strings. Each element of the returned List is trimmed of leading and trailing whitespace. Empty elements are omitted from the List.
     *
     * @param key the property key.
     * @return a List of Strings created by treating the property value as a comma-separated list or an empty List if the property does not exist.
     */
    public List<String> asList(String key) {
        String delimitedValues = delegate.getProperty(key, "");
        ImmutableList.Builder<String> trimmed = ImmutableList.builder();
        for (String value : delimitedValues.split(",")) {
            value = value.trim();
            if (!value.isEmpty()) {
                trimmed.add(value);
            }
        }
        return trimmed.build();
    }

    /**
     * Gets a property value as a ByteSource. The property value can be any of:
     * <ul>
     *   <li>An absolute file path to a file that exists.</li>
     *   <li>A valid URI.</li>
     *   <li>A classpath resource path loaded via the ClassLoader passed to the constructor.</li>
     * </ul>
     *
     * @param  key the property key.
     * @return a ByteSource or {@code null} if the property does not exist.
     * @throws java.lang.IllegalArgumentException if the property value cannot be resolved to a byte source.
     */
    public ByteSource asByteSource(String key) {
        ByteSource byteSource = null;
        String path = delegate.getProperty(key);
        if (path != null) {
            // try to treat it as a File path
            File file = new File(path);
            if (file.isFile()) {
                byteSource = Files.asByteSource(file);
            } else {
                // try to treat it as a URL
                try {
                    URL url = new URL(path);
                    byteSource = Resources.asByteSource(url);
                } catch (MalformedURLException e) {
                    // try to treat it as a resource path
                    byteSource = Resources.asByteSource(Resources.getResource(path));
                }
            }
        }
        return byteSource;
    }

    /**
     * Gets a property value as an InputStream. The property value can be any of:
     * <ul>
     *   <li>An absolute file path to a file that exists.</li>
     *   <li>A valid URI.</li>
     *   <li>A classpath resource path loaded via the ClassLoader passed to the constructor.</li>
     * </ul>
     *
     * @param key the property key.
     * @return an InputStream or <code>null</code> if the property does not exist.
     * @throws FileNotFoundException if the property value cannot be resolved to a stream source.
     */
    public InputStream asStream(String key) throws IOException {
        InputStream stream = null;
        String path = delegate.getProperty(key);
        if (path != null) {
            // try to treat it as a File path
            File file = new File(path);
            if (file.isFile()) {
                stream = new FileInputStream(file);
            } else {
                // try to treat it as a URL
                try {
                    URL url = new URL(path);
                    stream = url.openStream();
                } catch (MalformedURLException e) {
                    // try to treat it as a resource path
                    stream = classLoader.getResourceAsStream(path);
                    if (stream == null) {
                        throw new FileNotFoundException(path);
                    }
                }
            }
        }
        return stream;
    }

    /**
     * Gets a property value as a Class. The property value should be a fully-qualified class name that can be loaded via the ClassLoader passed to the constructor. The class should be an instance of the <code>type</code> parameter typically an interface.
     *
     * @param key the property key.
     * @param type the expected type of the Class, typically the interface it should implement.
     * @return a Class or <code>null</code> if the property does not exist.
     * @throws ClassNotFoundException if no Class is found matching the name from the property value.
     * @throws ClassCastException if a Class is loaded but it does not implement the <code>type</code> interface.
     */
    @SuppressWarnings("unchecked")
    public <T> Class<T> asClass(String key, Class<T> type) throws ClassNotFoundException {
        String className = delegate.getProperty(key);
        if (className == null) {
            return null;
        }

        Class<?> untypedClass = classLoader.loadClass(className);
        if (!type.isAssignableFrom(untypedClass)) {
            throw new ClassCastException(format("Class '%s' does not implement '%s", className, type.getName()));
        }

        return (Class<T>) classLoader.loadClass(className);
    }

}