001/**
002 * Copyright (c) 2015-2022, Michael Yang 杨福海 (fuhai999@gmail.com).
003 * <p>
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 * <p>
008 * http://www.apache.org/licenses/LICENSE-2.0
009 * <p>
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package io.jboot.app.config;
017
018import com.jfinal.kit.LogKit;
019
020import java.io.*;
021import java.net.URL;
022import java.util.Properties;
023
024
025class JbootProp {
026    protected Properties properties = null;
027    private static final String DEFAULT_ENCODING = "UTF-8";
028
029    public JbootProp(String fileName) {
030        this(fileName, DEFAULT_ENCODING);
031    }
032
033    public JbootProp(String fileName, String encoding) {
034        properties = new Properties();
035        InputStream inputStream = null;
036        try {
037            inputStream = getResourceAsStreamByCurrentThread(fileName);
038
039            if (inputStream == null) {
040                inputStream = getResourceAsStreamByClassloader(fileName);
041            }
042
043            // 当系统未编译的时候,开发环境下的 resources 目录下的 jboot.properties 文件不会自动被 copy 到 target/classes 目录下
044            // 此时,需要主动去探测 resources 目录的文件
045            if (inputStream == null) {
046                URL resourceURL = JbootProp.class.getResource("/");
047                if (resourceURL != null) {
048                    String classPath = resourceURL.toURI().getPath();
049
050                    if (removeSlashEnd(classPath).endsWith("classes")) {
051
052                        //from classes path
053                        File propFile = new File(classPath, fileName);
054                        if (propFile.exists() && propFile.isFile()) {
055                            inputStream = new FileInputStream(propFile);
056                        }
057
058                        //from resources path
059                        else {
060                            File resourcesDir = new File(classPath, "../../src/main/resources");
061                            propFile = new File(resourcesDir, fileName);
062                            if (propFile.exists() && propFile.isFile()) {
063                                inputStream = new FileInputStream(propFile);
064                            }
065                        }
066                    }
067                }
068            }
069
070            if (inputStream != null) {
071                properties.load(new InputStreamReader(inputStream, encoding));
072            } else if (!fileName.contains("-")) {
073                System.err.println("Warning: Can not load properties file in classpath, file name: " + fileName);
074            }
075        } catch (Exception e) {
076            System.err.println("Warning: Can not load properties file in classpath, file name: " + fileName);
077        } finally {
078            if (inputStream != null) {
079                try {
080                    inputStream.close();
081                } catch (IOException e) {
082                    LogKit.logNothing(e);
083                }
084            }
085        }
086    }
087
088    private InputStream getResourceAsStreamByCurrentThread(String fileName) {
089        ClassLoader ret = Thread.currentThread().getContextClassLoader();
090        return ret != null ? ret.getResourceAsStream(fileName) : null;
091    }
092
093
094    private InputStream getResourceAsStreamByClassloader(String fileName) {
095        ClassLoader ret = JbootProp.class.getClassLoader();
096        return ret != null ? ret.getResourceAsStream(fileName) : null;
097    }
098
099
100    private static String removeSlashEnd(String path) {
101        if (path != null && (path.endsWith("/") || path.endsWith("\\"))) {
102            return path.substring(0, path.length() - 1);
103        } else {
104            return path;
105        }
106    }
107
108
109    public JbootProp(File file) {
110        properties = new Properties();
111        try (InputStream inputStream = new FileInputStream(file)) {
112            properties.load(new InputStreamReader(inputStream, DEFAULT_ENCODING));
113        } catch (Exception e) {
114            System.err.println("Warning: Can not load properties file: " + file);
115        }
116    }
117
118
119    public Properties getProperties() {
120        return properties;
121    }
122}