All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ovea.tadjin.util.properties.PropertyPlaceholderResolver Maven / Gradle / Ivy

The newest version!
/**
 * Copyright (C) 2011 Ovea 
 *
 * 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.ovea.tadjin.util.properties;

import java.util.HashSet;
import java.util.Properties;
import java.util.Set;

public final class PropertyPlaceholderResolver {

    public static final String DEFAULT_PLACEHOLDER_PREFIX = "${";
    public static final String DEFAULT_PLACEHOLDER_SUFFIX = "}";

    private final String placeholderPrefix = DEFAULT_PLACEHOLDER_PREFIX;
    private final String placeholderSuffix = DEFAULT_PLACEHOLDER_SUFFIX;

    private boolean ignoreSystemEnvironment = false;
    private boolean ignoreUnresolvablePlaceholders = false;
    private SystemPropertiesMode systemPropertiesMode = SystemPropertiesMode.FALLBACK;

    public void setIgnoreSystemEnvironment(boolean ignoreSystemEnvironment) {
        this.ignoreSystemEnvironment = ignoreSystemEnvironment;
    }

    public void setIgnoreUnresolvablePlaceholders(boolean ignoreUnresolvablePlaceholders) {
        this.ignoreUnresolvablePlaceholders = ignoreUnresolvablePlaceholders;
    }

    public void setSystemPropertiesMode(SystemPropertiesMode systemPropertiesMode) {
        this.systemPropertiesMode = systemPropertiesMode;
    }

    public Properties resolveAll(Properties... properties) {
        Properties p = new Properties();
        Properties all = new Properties();
        for (Properties props : properties)
            all.putAll(props);
        for (String key : all.stringPropertyNames()) {
            String v = parseStringValue(all, all.getProperty(key), new HashSet());
            String k = parseStringValue(all, key, new HashSet());
            p.setProperty(k, v);
        }
        return p;
    }

    private String parseStringValue(Properties properties, String strVal, Set visitedPlaceholders) {
        StringBuilder buf = new StringBuilder(strVal);
        int startIndex = strVal.indexOf(this.placeholderPrefix);
        while (startIndex != -1) {
            int endIndex = findPlaceholderEndIndex(buf, startIndex);
            if (endIndex != -1) {
                String placeholder = buf.substring(startIndex + this.placeholderPrefix.length(), endIndex);
                if (!visitedPlaceholders.add(placeholder))
                    throw new IllegalStateException("Circular placeholder reference '" + placeholder + "' in property definitions");
                placeholder = parseStringValue(properties, placeholder, visitedPlaceholders);
                String propVal = resolvePlaceholder(properties, placeholder, this.systemPropertiesMode);
                if (propVal != null) {
                    propVal = parseStringValue(properties, propVal, visitedPlaceholders);
                    buf.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal);
                    startIndex = buf.indexOf(this.placeholderPrefix, startIndex + propVal.length());
                } else if (this.ignoreUnresolvablePlaceholders)
                    startIndex = buf.indexOf(this.placeholderPrefix, endIndex + this.placeholderSuffix.length());
                else
                    throw new IllegalStateException("Could not resolve placeholder '" + placeholder + "'");
                visitedPlaceholders.remove(placeholder);
            } else
                startIndex = -1;
        }
        return buf.toString();
    }

    private int findPlaceholderEndIndex(CharSequence buf, int startIndex) {
        int index = startIndex + this.placeholderPrefix.length();
        int withinNestedPlaceholder = 0;
        while (index < buf.length()) {
            if (substringMatch(buf, index, this.placeholderSuffix)) {
                if (withinNestedPlaceholder > 0) {
                    withinNestedPlaceholder--;
                    index = index + this.placeholderSuffix.length();
                } else
                    return index;
            } else if (substringMatch(buf, index, this.placeholderPrefix)) {
                withinNestedPlaceholder++;
                index = index + this.placeholderPrefix.length();
            } else
                index++;
        }
        return -1;
    }

    public String merge(String line, Properties properties) {
        return parseStringValue(properties, line, new HashSet());
    }

    public String resolve(String placeholder, Properties properties) {
        return resolvePlaceholder(properties, placeholder, systemPropertiesMode);
    }

    private String resolvePlaceholder(Properties properties, String placeholder, SystemPropertiesMode mode) {
        String propVal = null;
        if (mode == SystemPropertiesMode.OVERRIDE)
            propVal = resolveSystemProperty(placeholder);
        if (propVal == null)
            propVal = properties.getProperty(placeholder);
        if (propVal == null && mode == SystemPropertiesMode.FALLBACK)
            propVal = resolveSystemProperty(placeholder);
        return propVal;
    }

    private String resolveSystemProperty(String key) {
        try {
            String value = System.getProperty(key);
            if (value == null && !this.ignoreSystemEnvironment)
                value = System.getenv(key);
            return value;
        }
        catch (RuntimeException ex) {
            return null;
        }
    }

    private static boolean substringMatch(CharSequence str, int index, CharSequence substring) {
        for (int j = 0; j < substring.length(); j++) {
            int i = index + j;
            if (i >= str.length() || str.charAt(i) != substring.charAt(j))
                return false;
        }
        return true;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy