org.solmix.runtime.cm.support.SpringConfigureUnitManager.java Source code

Java tutorial

Introduction

Here is the source code for org.solmix.runtime.cm.support.SpringConfigureUnitManager.java

Source

/*
 *  Copyright 2012 The Solmix Project
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.gnu.org/licenses/ 
 * or see the FSF site: http://www.fsf.org. 
 */

package org.solmix.runtime.cm.support;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.solmix.commons.util.DataUtils;
import org.solmix.runtime.cm.ConfigureUnit;
import org.solmix.runtime.cm.ConfigureUnitManager;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.util.DefaultPropertiesPersister;
import org.springframework.util.PropertiesPersister;

/**
 * 
 * @author solmix.f@gmail.com
 * @version $Id$ 2013-11-5
 */

public class SpringConfigureUnitManager implements ConfigureUnitManager {

    protected final Logger logger = LoggerFactory.getLogger(getClass());

    public static final String DEFAULT_CFG_FILES = "classpath*:META-INF/solmix/*.cfg";

    public static final String XML_FILE_EXTENSION = ".xml";

    private Map<String, ConfigureUnit> configCache;

    private final PropertiesPersister propertiesPersister = new DefaultPropertiesPersister();

    private String fileEncoding;

    @Override
    public ConfigureUnit createFactoryConfigureUnit(String factoryPid) throws IOException {
        throw new java.lang.RuntimeException("This method is not support by " + this.getClass().getName());

    }

    @Override
    public synchronized ConfigureUnit getConfigureUnit(String pid) throws IOException {

        if (configCache == null) {
            configCache = buildConfig();
        }
        return configCache.get(pid);
    }

    private Map<String, ConfigureUnit> buildConfig() throws IOException {
        Map<String, ConfigureUnit> configs = new java.util.concurrent.ConcurrentHashMap<String, ConfigureUnit>();
        List<Resource> defaultResources = getConfigureResource(DEFAULT_CFG_FILES);
        for (Resource re : defaultResources) {
            String pid = getPidByFileName(re.getFilename());
            configs.put(pid, new ConfigureUnitImpl(pid, loadProperties(re), this));
            logTraceMessage("Loaded default configuration properties  from file:", re);
        }
        String userParttern = System.getProperty(ConfigureUnit.USER_CONFIG_DIR_PROPERTY_NAME);
        if (userParttern == null)
            userParttern = ConfigureUnit.USER_CONFIG_DIR;
        List<Resource> userConfigs = getConfigureResource(userParttern);
        if (userConfigs != null && userConfigs.size() > 0) {
            for (Resource re : userConfigs) {
                String pid = getPidByFileName(re.getFilename());
                if (configs.containsKey(pid)) {
                    ConfigureUnit cu = configs.get(pid);
                    Properties p = loadProperties(re);
                    cu.update(toDictionary(p));
                    logTraceMessage("merge user configured properties to merge system default:", re);
                } else {
                    configs.put(pid, new ConfigureUnitImpl(pid, loadProperties(re), this));
                    logTraceMessage("Loaded user configuration properties  from file:", re);
                }
            }
        }

        return configs;
    }

    private void logTraceMessage(String msg, Resource location) {
        if (logger.isTraceEnabled()) {
            try {
                logger.trace(msg + location.getURL().getPath());
            } catch (IOException e) {
            }
        }
    }

    private Dictionary<String, ?> toDictionary(Properties properties) {
        Dictionary<String, Object> dic = new Hashtable<String, Object>();
        if (properties != null) {
            Enumeration<Object> en = properties.keys();
            while (en.hasMoreElements()) {
                Object key = en.nextElement();
                dic.put(key.toString(), properties.get(key));
            }
        }
        return dic;
    }

    protected String getPidByFileName(String fileName) {
        if (fileName.endsWith(".cfg")) {
            return fileName.substring(0, fileName.length() - 4);
        }
        return fileName;
    }

    @Override
    public ConfigureUnit[] listConfigureUnits(String filter) throws IOException {
        ConfigureUnit[] fiter = null;
        if (configCache == null) {
            configCache = buildConfig();
        }
        if (filter == null) {
            Collection<ConfigureUnit> conf = configCache.values();
            fiter = conf.toArray(new ConfigureUnit[] {});
        }
        return fiter;
    }

    public List<Resource> getConfigureResource(String dir) {
        List<Resource> resources = new ArrayList<Resource>();
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(
                Thread.currentThread().getContextClassLoader());
        try {
            Collections.addAll(resources, resolver.getResources(dir));

        } catch (IOException e) {
            logger.error("IOException", e);
        }
        return resources;
    }

    protected Properties loadProperties(Resource location) {
        Properties props = new Properties();
        InputStream is = null;
        try {
            is = location.getInputStream();
            String filename = location.getFilename();
            if (filename != null && filename.endsWith(XML_FILE_EXTENSION)) {
                this.propertiesPersister.loadFromXml(props, is);
            } else {
                if (this.fileEncoding != null) {
                    this.propertiesPersister.load(props, new InputStreamReader(is, this.fileEncoding));
                } else {
                    this.propertiesPersister.load(props, is);
                }
            }
        } catch (IOException ex) {
            if (logger.isWarnEnabled()) {
                logger.warn("Could not load properties from " + location + ": " + ex.getMessage());
            }
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                }
            }
        }
        checkSystemProperties(props);
        return props;
    }

    /**
     * @param props
     */
    private void checkSystemProperties(Properties properties) {
        if (properties != null) {
            Enumeration<Object> en = properties.keys();
            while (en.hasMoreElements()) {
                Object key = en.nextElement();
                Object value = properties.get(key);
                if (value != null) {
                    value = DataUtils.getTemplateValue(value.toString());
                }
                properties.put(key, value);
            }
        }

    }

}