Package net.hasor.core.environment

Source Code of net.hasor.core.environment.AbstractEnvironment$EnvVars

/*
* Copyright 2008-2009 the original 赵永春(zyc@hasor.net).
*
* 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 net.hasor.core.environment;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.hasor.core.Environment;
import net.hasor.core.EventContext;
import net.hasor.core.Hasor;
import net.hasor.core.Settings;
import net.hasor.core.SettingsListener;
import net.hasor.core.XmlNode;
import net.hasor.core.event.StandardEventManager;
import org.more.UnhandledException;
import org.more.util.ResourceWatch;
import org.more.util.StringUtils;
import org.more.util.map.DecSequenceMap;
/**
* {@link Environment}接口实现类,集成该类的子类需要调用{@link #initEnvironment()}方法以初始化。
* @version : 2013-4-9
* @author 赵永春 (zyc@hasor.net)
*/
public abstract class AbstractEnvironment implements Environment {
    private String[]     spanPackage  = null;
    private Settings     settings     = null;
    private Object       context      = null;
    private EventContext eventManager = null;
    //---------------------------------------------------------------------------------Basic Method
    @Override
    public Object getContext() {
        return this.context;
    }
    public void setContext(final Object context) {
        this.context = context;
    }
    @Override
    public boolean isDebug() {
        return this.settings.getBoolean("hasor.debug", false);
    }
    /**设置扫描路径*/
    public void setSpanPackage(final String[] spanPackage) {
        this.spanPackage = spanPackage;
    }
    @Override
    public String[] getSpanPackage() {
        return this.spanPackage;
    }
    @Override
    public Set<Class<?>> findClass(final Class<?> featureType) {
        return this.getSettings().findClass(featureType, this.spanPackage);
    }
    @Override
    public Settings getSettings() {
        return this.settings;
    }
    @Override
    public EventContext getEventContext() {
        if (this.eventManager == null) {
            this.eventManager = new StandardEventManager(this);
        }
        return this.eventManager;
    }
    //
    /*----------------------------------------------------------------------------------------Env*/
    /**初始化方法*/
    protected void initEnvironment() {
        Hasor.logInfo("initEnvironment.");
        //
        this.settingListenerList = new ArrayList<SettingsListener>();
        try {
            this.settings = this.createSettings();
            this.settings.refresh();
        } catch (Exception e) {
            if (e instanceof RuntimeException) {
                throw (RuntimeException) e;
            }
            throw new UnhandledException(e);
        }
        this.envVars = this.createEnvVars();
        //this.eventManager = this.createEventManager();
        //
        String[] spanPackages = this.getSettings().getStringArray("hasor.loadPackages", "net.hasor.core.*,net.hasor.plugins.*");
        Set<String> allPack = new HashSet<String>();
        for (String packs : spanPackages) {
            if (StringUtils.isBlank(packs) == true) {
                continue;
            }
            String[] packArray = packs.split(",");
            for (String pack : packArray) {
                if (StringUtils.isBlank(packs) == true) {
                    continue;
                }
                allPack.add(pack.trim());
            }
        }
        this.spanPackage = allPack.toArray(new String[allPack.size()]);
        Hasor.logInfo("loadPackages : " + Hasor.logString(this.spanPackage));
        //
        this.settingWatch = this.createSettingWatch();
        if (this.settingWatch != null) {
            this.settingWatch.setDaemon(true);
            this.settingWatch.start();
        }
    }
    /**创建{@link Settings}接口对象*/
    protected abstract Settings createSettings() throws IOException;
    /**在缓存目录内创建一个不重名的临时文件名。 */
    public synchronized File uniqueTempFile() throws IOException {
        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {}
        long markTime = System.currentTimeMillis();
        String atPath = this.genPath(markTime, 512);
        String fileName = atPath.substring(0, atPath.length() - 1) + "_" + String.valueOf(markTime) + ".tmp";
        File tmpFile = new File(this.evalEnvVar(Environment.TempPath), fileName);
        tmpFile.getParentFile().mkdirs();
        tmpFile.createNewFile();
        Hasor.logDebug("create Temp File at %s.", tmpFile);
        return tmpFile;
    }
    /**
    * 生成路径算法生成一个Path
    * @param number 参考数字
    * @param size 每个目录下可以拥有的子目录或文件数目。
    */
    public String genPath(long number, final int size) {
        StringBuffer buffer = new StringBuffer();
        long b = size;
        long c = number;
        do {
            long m = number % b;
            buffer.append(m + File.separator);
            c = number / b;
            number = c;
        } while (c > 0);
        return buffer.reverse().toString();
    }
    //
    /*-----------------------------------------------------------------------HasorSettingListener*/
    private SettingWatch           settingWatch        = null;
    private List<SettingsListener> settingListenerList = null;
    /**触发配置文件重载事件。*/
    protected void onSettingChangeEvent() {
        for (SettingsListener listener : this.settingListenerList) {
            listener.reload(this.getSettings());
        }
    }
    /**添加配置文件变更监听器。*/
    @Override
    public void addSettingsListener(final SettingsListener settingsListener) {
        if (this.settingListenerList.contains(settingsListener) == false) {
            this.settingListenerList.add(settingsListener);
        }
    }
    /**删除配置文件监听器。*/
    @Override
    public void removeSettingsListener(final SettingsListener settingsListener) {
        if (this.settingListenerList.contains(settingsListener) == true) {
            this.settingListenerList.remove(settingsListener);
        }
    }
    /**获得所有配置文件改变事件监听器。*/
    public SettingsListener[] getSettingListeners() {
        return this.settingListenerList.toArray(new SettingsListener[this.settingListenerList.size()]);
    }
    //
    /*------------------------------------------------------------------------------ResourceWatch*/
    /**创建{@link SettingWatch}对象,该方法可以返回null表示不需要监视器。*/
    protected SettingWatch createSettingWatch() {
        final SettingWatch settingWatch = new SettingWatch(this) {};
        /*设置监听器检测间隔*/
        long interval = this.getSettings().getLong("hasor.settingsMonitor.interval", 15000L);
        settingWatch.setCheckSeepTime(interval);
        /*注册一个配置文件监听器,当配置文件更新时通知监听器更新检测间隔*/
        this.addSettingsListener(new SettingsListener() {
            @Override
            public void reload(final Settings newConfig) {
                long interval = newConfig.getLong("hasor.settingsMonitor.interval", 15000L);
                if (interval != settingWatch.getCheckSeepTime()) {
                    Hasor.logInfo("SettingWatch to monitor configuration updates, set interval new Value is %s", interval);
                    settingWatch.setCheckSeepTime(interval);
                }
            }
        });
        return settingWatch;
    }
    /** 该类负责主配置文件的监听工作,以及引发配置文件重载事件。*/
    protected abstract static class SettingWatch extends ResourceWatch {
        private AbstractEnvironment env = null;
        //
        public SettingWatch(final AbstractEnvironment env) {
            this.env = env;
        }
        @Override
        public void firstStart(final URI resourceURI) throws IOException {}
        /**当配置文件被检测到有修改迹象时,调用刷新进行重载。*/
        @Override
        public final void onChange(final URI resourceURI) throws IOException {
            this.env.getSettings().refresh();
            this.env.onSettingChangeEvent();
        }
        /**检测主配置文件是否被修改*/
        @Override
        public long lastModify(final URI resourceURI) throws IOException {
            if ("file".equals(resourceURI.getScheme()) == true) {
                return new File(resourceURI).lastModified();
            }
            return 0;
        }
        @Override
        public synchronized void start() {
            this.setName("MasterConfiguration-Watch");
            Hasor.logInfo("settings Watch started thread name is %s.", this.getName());
            this.setDaemon(true);
            URI mainConfig = this.env.getSettingURI();
            //2.启动监听器
            try {
                if (mainConfig == null) {
                    Hasor.logWarn("ignore the master setting file, Watch Thread exit.");
                    return;
                }
                this.setResourceURI(this.env.getSettingURI());
            } catch (Exception e) {
                Hasor.logError("settings Watch start error, on : %s Settings file !%s", mainConfig, e);
            }
            //
            super.start();
        }
    }
    //
    /*-----------------------------------------------------------------------------------Env Vars*/
    private EnvVars envVars;
    @Override
    public String evalString(final String eval) {
        return this.envVars.evalString(eval);
    }
    @Override
    public String evalEnvVar(final String varName) {
        return this.envVars.evalEnvVar(varName);
    }
    @Override
    public String getEnvVar(final String varName) {
        return this.envVars.getEnvVar(varName);
    }
    @Override
    public void addEnvVar(final String varName, final String value) {
        this.envVars.addEnvVar(varName, value);
    }
    @Override
    public void remoteEnvVar(final String varName) {
        this.envVars.remoteEnvVar(varName);
    }
    @Override
    public void refreshVariables() {
        this.envVars.reload(this.getSettings());
    }
    public Map<String, String> getEnv() {
        return this.envVars.getEnv();
    }
    /**创建{@link EnvVars}接口对象*/
    protected EnvVars createEnvVars() {
        return new EnvVars(this);
    }
    /** 该类负责处理环境变量相关操作*/
    protected class EnvVars implements SettingsListener {
        /*所属的Environment*/
        private AbstractEnvironment env;
        /*最终使用的环境变量Map*/
        private Map<String, String> finalEnvMap;
        /*用户通过Api添加的环境变量Map*/
        private Map<String, String> userEnvMap;
        //
        public EnvVars(final AbstractEnvironment env) {
            this.env = Hasor.assertIsNotNull(env, "InitContext type parameter is empty!");
            this.userEnvMap = new HashMap<String, String>();
            this.env.addSettingsListener(this);
            this.reload(this.env.getSettings());
        }
        public void addEnvVar(final String envName, final String envValue) {
            if (StringUtils.isBlank(envName)) {
                Hasor.logWarn("%s env, name is empty.", envName);
                return;
            }
            //
            if (StringUtils.isBlank(envValue)) {
                Hasor.logWarn("%s env, value is empty.", envName);
            } else {
                Hasor.logInfo("%s = %s.", envName, envValue);
            }
            //
            this.userEnvMap.put(envName, StringUtils.isBlank(envValue) ? "" : envValue);
        }
        public void remoteEnvVar(final String varName) {
            if (StringUtils.isBlank(varName)) {
                Hasor.logWarn("%s env, name is empty.");
                return;
            }
            this.userEnvMap.remove(varName);
            Hasor.logInfo("%s env removed.", varName);
        }
        public String getEnvVar(final String envName) {
            return this.getEnv().get(envName);
        }
        public Map<String, String> getEnv() {
            if (this.finalEnvMap == null) {
                this.finalEnvMap = new HashMap<String, String>();
            }
            return Collections.unmodifiableMap(this.finalEnvMap);
        }
        //
        /**特殊配置的环境变量*/
        protected Map<String, String> configEnvironment() {
            Settings settings = this.env.getSettings();
            XmlNode[] xmlPropArray = settings.getXmlNodeArray("hasor.environmentVar");
            List<String> envNames = new ArrayList<String>();//用于收集环境变量名称
            for (XmlNode xmlProp : xmlPropArray) {
                for (XmlNode envItem : xmlProp.getChildren()) {
                    envNames.add(envItem.getName().toUpperCase());
                }
            }
            Map<String, String> hasorEnv = new HashMap<String, String>();
            for (String envItem : envNames) {
                hasorEnv.put(envItem, settings.getString("hasor.environmentVar." + envItem));
            }
            /*单独处理work_home*/
            String workDir = settings.getString("hasor.environmentVar.HASOR_WORK_HOME", "./");
            workDir = workDir.replace("/", File.separator);
            if (workDir.startsWith("." + File.separatorChar)) {
                hasorEnv.put("HASOR_WORK_HOME", new File(System.getProperty("user.dir"), workDir.substring(2)).getAbsolutePath());
            } else {
                hasorEnv.put("HASOR_WORK_HOME", workDir);
            }
            return hasorEnv;
        }
        /*
         * SettingListener 接口实现
         *   实现该接口的目的是,通过注册SettingListener动态更新环境变量相关信息。
         */
        @Override
        public void reload(final Settings newConfig) {
            //1.系统环境变量 & Java系统属性
            Map<String, String> systemEnv = new HashMap<String, String>();
            systemEnv.putAll(System.getenv());
            //2.Java属性
            Properties prop = System.getProperties();
            Map<String, String> javaProp = new HashMap<String, String>();
            for (Object propKey : prop.keySet()) {
                String k = propKey.toString();
                Object v = prop.get(propKey);
                if (v != null) {
                    javaProp.put(k, v.toString());
                }
            }
            //3.Hasor 特有变量
            Map<String, String> hasorEnv = this.configEnvironment();
            hasorEnv = hasorEnv == null ? new HashMap<String, String>() : hasorEnv;
            //4.设置生效
            DecSequenceMap<String, String> finalMap = new DecSequenceMap<String, String>();
            finalMap.addMap(this.userEnvMap);
            finalMap.addMap(hasorEnv);
            finalMap.addMap(javaProp);
            finalMap.addMap(systemEnv);
            //5.解析hasor 特有环境变量
            for (Entry<String, String> hasorEnt : hasorEnv.entrySet()) {
                String k = hasorEnt.getKey();
                String v = hasorEnt.getValue();
                finalMap.put(k, "");/*预输出,防止循环*/
                v = this.evalString(v, finalMap);
                finalMap.put(k, v);
                hasorEnt.setValue(v);
            }
            //
            this.finalEnvMap = finalMap;
            //
            /*日志输出*/
            if (Hasor.isInfoLogger()) {
                int keyMaxSize = 0;
                for (String key : finalMap.keySet()) {
                    keyMaxSize = key.length() >= keyMaxSize ? key.length() : keyMaxSize;
                }
                keyMaxSize = keyMaxSize + 2;
                StringBuffer sb = new StringBuffer();
                sb.append("EnvVars:");
                if (AbstractEnvironment.this.isDebug()) {
                    if (!systemEnv.isEmpty()) {
                        sb.append("\n" + this.formatMap4log(keyMaxSize, systemEnv));
                        sb.append("\n" + StringUtils.fixedString('-', 50));
                    }
                    if (!javaProp.isEmpty()) {
                        sb.append("\n" + this.formatMap4log(keyMaxSize, javaProp));
                        sb.append("\n" + StringUtils.fixedString('-', 50));
                    }
                }
                if (!hasorEnv.isEmpty()) {
                    sb.append("\n" + this.formatMap4log(keyMaxSize, hasorEnv));
                    sb.append("\n" + StringUtils.fixedString('-', 50));
                }
                if (!this.userEnvMap.isEmpty()) {
                    sb.append("\n" + this.formatMap4log(keyMaxSize, this.userEnvMap));
                    sb.append("\n" + StringUtils.fixedString('-', 50));
                }
                Hasor.logInfo(sb.toString());
            }
        }
        private String formatMap4log(final int colWidth, final Map<String, String> mapData) {
            /*输出系统环境变量日志*/
            StringBuffer outLog = new StringBuffer("");
            for (String key : mapData.keySet()) {
                String var = mapData.get(key);
                var = var != null ? var.replace("\r", "\\r").replace("\n", "\\n") : var;
                outLog.append(StringUtils.fixedString(' ', colWidth - key.length()));
                outLog.append(String.format(" %s : %s", key, var));
                outLog.append('\n');
            }
            if (outLog.length() > 1) {
                outLog.deleteCharAt(outLog.length() - 1);
            }
            return outLog.toString();
        }
        //
        public String evalEnvVar(final String varName) {
            return this.evalEnvVar(varName, new HashMap<String, String>());
        }
        public String evalString(final String evalString) {
            return this.evalString(evalString, new HashMap<String, String>());
        }
        private String evalEnvVar(final String varName, final Map<String, String> paramMap) {
            if (paramMap.containsKey(varName)) {
                return paramMap.get(varName);
            }
            paramMap.put(varName, "");/*预处理值*/
            //
            String varValue = this.getEnv().get(varName);
            if (StringUtils.isBlank(varValue)) {
                varValue = "";
            } else {
                varValue = this.evalString(varValue, paramMap);
            }
            paramMap.put(varName, varValue);/*覆盖预处理值*/
            return varValue;
        }
        private String evalString(final String evalString, final Map<String, String> paramMap) {
            if (StringUtils.isBlank(evalString)) {
                return "";
            }
            Pattern keyPattern = Pattern.compile("(?:%(\\w+)%){1,1}");//  (?:%(\w+)%)
            Matcher keyM = keyPattern.matcher(evalString);
            ArrayList<String> data = new ArrayList<String>();
            while (keyM.find()) {
                String varKey = keyM.group(1);
                String var = this.evalEnvVar(varKey, paramMap);
                var = StringUtils.isBlank(var) ? "%" + varKey + "%" : var;
                data.add(var);
            }
            String[] splitArr = keyPattern.split(evalString);
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < splitArr.length; i++) {
                sb.append(splitArr[i]);
                if (data.size() > i) {
                    sb.append(data.get(i));
                }
            }
            String returnData = sb.toString();
            Hasor.logDebug("evalString '%s' eval to '%s'.", evalString, returnData);
            return returnData;
        }
    }
}
TOP

Related Classes of net.hasor.core.environment.AbstractEnvironment$EnvVars

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.