iterator.util.Config.java Source code

Java tutorial

Introduction

Here is the source code for iterator.util.Config.java

Source

/*
 * Copyright 2012-2013 by Andrew Kennedy.
 *
 * 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 iterator.util;

import java.io.File;
import java.io.IOException;
import java.io.Reader;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.SortedMap;

import com.google.common.base.CaseFormat;
import com.google.common.base.Charsets;
import com.google.common.base.Joiner;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.base.Throwables;
import com.google.common.collect.ForwardingSortedMap;
import com.google.common.collect.ImmutableSortedMap;
import com.google.common.collect.Maps;
import com.google.common.io.Files;
import com.google.common.io.InputSupplier;
import com.google.common.io.Resources;

/**
 * Configuration {@link Map}.
 * <p>
 * Global cobfiguration values for use in preferences dialog.
 */
public class Config extends ForwardingSortedMap<String, String> {

    public static final String USER_HOME_PROPERTY = "user.home";

    public static final String PROPERTIES_FILE = "explorer.properties";

    public static final String EXPLORER_PROPERTY = "explorer";
    public static final String PALETTE_PROPERTY = EXPLORER_PROPERTY + ".palette";
    public static final String GRID_PROPERTY = EXPLORER_PROPERTY + ".grid";
    public static final String WINDOW_PROPERTY = EXPLORER_PROPERTY + ".window";
    public static final String DEBUG_PROPERTY = EXPLORER_PROPERTY + ".debug";
    public static final String MODE_PROPERTY = EXPLORER_PROPERTY + ".mode";
    public static final String THREADS_PROPERTY = EXPLORER_PROPERTY + ".threads";
    public static final String RENDER_PROPERTY = EXPLORER_PROPERTY + ".render";

    public static final String DEFAULT_PALETTE_FILE = "abstract";
    public static final Integer DEFAULT_PALETTE_SIZE = 64;
    public static final Long DEFAULT_PALETTE_SEED = 0L;
    public static final Integer DEFAULT_GRID_MIN = 10;
    public static final Integer DEFAULT_GRID_MAX = 50;
    public static final Integer DEFAULT_GRID_SNAP = 5;
    public static final Integer DEFAULT_WINDOW_SIZE = 600;
    public static final Integer MIN_WINDOW_SIZE = 400; // Details view requires 350px
    public static final Integer MIN_THREADS = 2;

    public static enum Mode {
        COLOUR, PALETTE, STEALING, IFS_COLOUR, GRAY;

        @Override
        public String toString() {
            return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, name()).toLowerCase(Locale.UK);
        }
    }

    public static final String MODE_COLOUR = Mode.COLOUR.toString();
    public static final String MODE_PALETTE = Mode.PALETTE.toString();
    public static final String MODE_STEALING = Mode.STEALING.toString();
    public static final String MODE_IFS_COLOUR = Mode.IFS_COLOUR.toString();
    public static final String MODE_GRAY = Mode.GRAY.toString();
    public static final String DEFAULT_MODE = MODE_GRAY;

    public static enum Render {
        STANDARD, TOP, MEASURE, IFS;

        @Override
        public String toString() {
            return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, name()).toLowerCase(Locale.UK);
        }
    }

    public static final String RENDER_STANDARD = Render.STANDARD.toString();
    public static final String RENDER_TOP = Render.TOP.toString();
    public static final String RENDER_MEASURE = Render.MEASURE.toString();
    public static final String RENDER_IFS = Render.IFS.toString();
    public static final String DEFAULT_RENDER = RENDER_STANDARD;

    public static final Predicate<CharSequence> EXPLORER_KEYS = Predicates
            .containsPattern("^" + EXPLORER_PROPERTY + ".");

    private final File override;
    private final SortedMap<String, String> config;

    private Config(File override) {
        this.override = override;
        this.config = Maps.newTreeMap();
    }

    public static Config loadProperties(File override) {
        Config instance = new Config(override);
        instance.load();
        return instance;
    }

    public SortedMap<String, String> copyOf() {
        return ImmutableSortedMap.copyOfSorted(this);
    }

    public void load() {
        clear();

        // Defaults from classpath
        load(Resources.newReaderSupplier(Resources.getResource(PROPERTIES_FILE), Charsets.UTF_8));

        // Configuration from home directory
        File home = new File(System.getProperty(USER_HOME_PROPERTY), "." + PROPERTIES_FILE);
        if (home.exists()) {
            load(Files.newReaderSupplier(home, Charsets.UTF_8));
        }

        // Configuration from current directory
        File current = new File(PROPERTIES_FILE);
        if (current.exists()) {
            load(Files.newReaderSupplier(current, Charsets.UTF_8));
        }

        // Override file from command line
        if (override != null) {
            load(Files.newReaderSupplier(override, Charsets.UTF_8));
        }

        // Finally load system properties (JAVA_OPTS)
        load(System.getProperties());
    }

    public void load(InputSupplier<? extends Reader> supplier) {
        try {
            Properties properties = new Properties();
            properties.load(supplier.getInput());
            load(properties);
        } catch (IOException ioe) {
            throw Throwables.propagate(ioe);
        }
    }

    public void load(Properties properties) {
        load(Maps.fromProperties(properties));
    }

    public void load(Map<String, String> data) {
        putAll(Maps.filterKeys(data, EXPLORER_KEYS));
    }

    @SuppressWarnings("unchecked")
    public <T> T get(String key, T defaultValue) {
        String value = get(key);
        if (value == null) {
            return defaultValue;
        } else {
            return (T) cast(value, defaultValue.getClass());
        }
    }

    @SuppressWarnings("unchecked")
    private <T> T cast(String value, Class<T> type) {
        if (Integer.class == type || Integer.TYPE == type) {
            return (T) Integer.valueOf(value);
        } else if (Long.class == type || Long.TYPE == type) {
            return (T) Long.valueOf(value);
        } else if (Float.class == type || Float.TYPE == type) {
            return (T) Float.valueOf(value);
        } else if (Double.class == type || Double.TYPE == type) {
            return (T) Double.valueOf(value);
        } else if (Short.class == type || Short.TYPE == type) {
            return (T) Short.valueOf(value);
        } else if (Byte.class == type || Byte.TYPE == type) {
            return (T) Byte.valueOf(value);
        } else if (Character.class == type || Character.TYPE == type) {
            if (value.length() != 1) {
                throw new IllegalArgumentException("Bad Character value: " + value);
            }
            return (T) Character.valueOf(value.charAt(0));
        } else if (Boolean.class == type || Boolean.TYPE == type) {
            return (T) Boolean.valueOf(value);
        } else if (String.class == type) {
            return (T) value;
        } else {
            throw new IllegalArgumentException(String.format("Cannot cast %s to %s", value, type.getName()));
        }
    }

    @Override
    protected SortedMap<String, String> delegate() {
        return config;
    }

    @Override
    public String toString() {
        return Joiner.on(",").useForNull("").withKeyValueSeparator("=").join(this);
    }
}