Environment.java
- /*
- * Copyright 2010-2023 the original author or authors.
- *
- * 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
- *
- * https://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 org.apache.ibatis.migration;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.IOException;
- import java.nio.charset.Charset;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Collections;
- import java.util.List;
- import java.util.Locale;
- import java.util.Map;
- import java.util.Properties;
- public class Environment {
- public static final String CHANGELOG = "changelog";
- private enum SETTING_KEY {
- TIME_ZONE,
- DELIMITER,
- SCRIPT_CHAR_SET,
- FULL_LINE_DELIMITER,
- SEND_FULL_SCRIPT,
- AUTO_COMMIT,
- REMOVE_CRS,
- IGNORE_WARNINGS,
- DRIVER_PATH,
- DRIVER,
- URL,
- USERNAME,
- PASSWORD,
- HOOK_BEFORE_UP,
- HOOK_BEFORE_EACH_UP,
- HOOK_AFTER_EACH_UP,
- HOOK_AFTER_UP,
- HOOK_BEFORE_DOWN,
- HOOK_BEFORE_EACH_DOWN,
- HOOK_AFTER_EACH_DOWN,
- HOOK_AFTER_DOWN,
- HOOK_BEFORE_NEW,
- HOOK_AFTER_NEW,
- HOOK_BEFORE_SCRIPT,
- HOOK_BEFORE_EACH_SCRIPT,
- HOOK_AFTER_EACH_SCRIPT,
- HOOK_AFTER_SCRIPT;
- @Override
- public String toString() {
- return this.name().toLowerCase(Locale.ENGLISH);
- }
- }
- private static final List<String> SETTING_KEYS;
- static {
- ArrayList<String> list = new ArrayList<>();
- SETTING_KEY[] keys = SETTING_KEY.values();
- for (SETTING_KEY key : keys) {
- list.add(key.toString());
- }
- SETTING_KEYS = Collections.unmodifiableList(list);
- }
- private final String timeZone;
- private final String delimiter;
- private final String scriptCharset;
- private final boolean fullLineDelimiter;
- private final boolean sendFullScript;
- private final boolean autoCommit;
- private final boolean removeCrs;
- private final boolean ignoreWarnings;
- private final String driverPath;
- private final String driver;
- private final String url;
- private final String username;
- private final String password;
- private final String hookBeforeUp;
- private final String hookBeforeEachUp;
- private final String hookAfterEachUp;
- private final String hookAfterUp;
- private final String hookBeforeDown;
- private final String hookBeforeEachDown;
- private final String hookAfterEachDown;
- private final String hookAfterDown;
- private final String hookBeforeNew;
- private final String hookAfterNew;
- private final String hookBeforeScript;
- private final String hookBeforeEachScript;
- private final String hookAfterEachScript;
- private final String hookAfterScript;
- /**
- * Prefix used to lookup environment variable or system property.
- */
- private static final String PREFIX = "MIGRATIONS_";
- private final Map<String, String> envVars = System.getenv();
- private final Properties sysProps = System.getProperties();
- private final Properties variables = new Properties();
- private final VariableReplacer parser = new VariableReplacer(Arrays.asList(sysProps, envVars));
- public Environment(File file) {
- Properties prop = mergeProperties(file);
- this.timeZone = readProperty(prop, SETTING_KEY.TIME_ZONE.toString(), "GMT+0:00");
- this.delimiter = readProperty(prop, SETTING_KEY.DELIMITER.toString(), ";");
- this.scriptCharset = readProperty(prop, SETTING_KEY.SCRIPT_CHAR_SET.toString(),
- Charset.defaultCharset().toString());
- this.fullLineDelimiter = Boolean.parseBoolean(readProperty(prop, SETTING_KEY.FULL_LINE_DELIMITER.toString()));
- this.sendFullScript = Boolean.parseBoolean(readProperty(prop, SETTING_KEY.SEND_FULL_SCRIPT.toString()));
- this.autoCommit = Boolean.parseBoolean(readProperty(prop, SETTING_KEY.AUTO_COMMIT.toString()));
- this.removeCrs = Boolean.parseBoolean(readProperty(prop, SETTING_KEY.REMOVE_CRS.toString()));
- this.ignoreWarnings = Boolean.parseBoolean(readProperty(prop, SETTING_KEY.IGNORE_WARNINGS.toString(), "true"));
- this.driverPath = readProperty(prop, SETTING_KEY.DRIVER_PATH.toString());
- this.driver = readProperty(prop, SETTING_KEY.DRIVER.toString());
- this.url = readProperty(prop, SETTING_KEY.URL.toString());
- this.username = readProperty(prop, SETTING_KEY.USERNAME.toString());
- this.password = readProperty(prop, SETTING_KEY.PASSWORD.toString());
- this.hookBeforeUp = readProperty(prop, SETTING_KEY.HOOK_BEFORE_UP.toString());
- this.hookBeforeEachUp = readProperty(prop, SETTING_KEY.HOOK_BEFORE_EACH_UP.toString());
- this.hookAfterEachUp = readProperty(prop, SETTING_KEY.HOOK_AFTER_EACH_UP.toString());
- this.hookAfterUp = readProperty(prop, SETTING_KEY.HOOK_AFTER_UP.toString());
- this.hookBeforeDown = readProperty(prop, SETTING_KEY.HOOK_BEFORE_DOWN.toString());
- this.hookBeforeEachDown = readProperty(prop, SETTING_KEY.HOOK_BEFORE_EACH_DOWN.toString());
- this.hookAfterEachDown = readProperty(prop, SETTING_KEY.HOOK_AFTER_EACH_DOWN.toString());
- this.hookAfterDown = readProperty(prop, SETTING_KEY.HOOK_AFTER_DOWN.toString());
- this.hookBeforeNew = readProperty(prop, SETTING_KEY.HOOK_BEFORE_NEW.toString());
- this.hookAfterNew = readProperty(prop, SETTING_KEY.HOOK_AFTER_NEW.toString());
- this.hookBeforeScript = readProperty(prop, SETTING_KEY.HOOK_BEFORE_SCRIPT.toString());
- this.hookBeforeEachScript = readProperty(prop, SETTING_KEY.HOOK_BEFORE_EACH_SCRIPT.toString());
- this.hookAfterEachScript = readProperty(prop, SETTING_KEY.HOOK_AFTER_EACH_SCRIPT.toString());
- this.hookAfterScript = readProperty(prop, SETTING_KEY.HOOK_AFTER_SCRIPT.toString());
- // User defined variables.
- prop.entrySet().stream().filter(e -> !SETTING_KEYS.contains(e.getKey()))
- .forEach(e -> variables.put(e.getKey(), parser.replace((String) e.getValue())));
- }
- private Properties mergeProperties(File file) {
- // 1. Load from file.
- Properties prop = loadPropertiesFromFile(file);
- // 2. Read environment variables (existing entries are overwritten).
- envVars.entrySet().stream().filter(e -> isMigrationsKey(e.getKey()))
- .forEach(e -> prop.put(normalizeKey(e.getKey()), e.getValue()));
- // 3. Read system properties (existing entries are overwritten).
- sysProps.entrySet().stream().filter(e -> isMigrationsKey((String) e.getKey()))
- .forEach(e -> prop.put(normalizeKey((String) e.getKey()), e.getValue()));
- return prop;
- }
- private String normalizeKey(String key) {
- return key.substring(PREFIX.length()).toLowerCase(Locale.ENGLISH);
- }
- private boolean isMigrationsKey(String key) {
- return key.length() > PREFIX.length() && key.toUpperCase(Locale.ENGLISH).startsWith(PREFIX);
- }
- private Properties loadPropertiesFromFile(File file) {
- Properties properties = new Properties();
- try (FileInputStream inputStream = new FileInputStream(file)) {
- properties.load(inputStream);
- return properties;
- } catch (FileNotFoundException e) {
- throw new MigrationException("Environment file missing: " + file.getAbsolutePath());
- } catch (IOException e) {
- throw new MigrationException("Error loading environment properties. Cause: " + e, e);
- }
- }
- private String readProperty(Properties properties, String propertyKey) {
- return readProperty(properties, propertyKey, null);
- }
- private String readProperty(Properties properties, String propertyKey, String defaultValue) {
- String property = properties.getProperty(propertyKey, defaultValue);
- return property == null ? null : parser.replace(property);
- }
- public String getTimeZone() {
- return timeZone;
- }
- public String getDelimiter() {
- return delimiter;
- }
- public String getScriptCharset() {
- return scriptCharset;
- }
- public boolean isFullLineDelimiter() {
- return fullLineDelimiter;
- }
- public boolean isSendFullScript() {
- return sendFullScript;
- }
- public boolean isAutoCommit() {
- return autoCommit;
- }
- public boolean isRemoveCrs() {
- return removeCrs;
- }
- public boolean isIgnoreWarnings() {
- return ignoreWarnings;
- }
- public String getDriverPath() {
- return driverPath;
- }
- public String getDriver() {
- return driver;
- }
- public String getUrl() {
- return url;
- }
- public String getUsername() {
- return username;
- }
- public String getPassword() {
- return password;
- }
- public String getHookBeforeUp() {
- return hookBeforeUp;
- }
- public String getHookBeforeEachUp() {
- return hookBeforeEachUp;
- }
- public String getHookAfterEachUp() {
- return hookAfterEachUp;
- }
- public String getHookAfterUp() {
- return hookAfterUp;
- }
- public String getHookBeforeDown() {
- return hookBeforeDown;
- }
- public String getHookBeforeEachDown() {
- return hookBeforeEachDown;
- }
- public String getHookAfterEachDown() {
- return hookAfterEachDown;
- }
- public String getHookAfterDown() {
- return hookAfterDown;
- }
- public String getHookBeforeNew() {
- return hookBeforeNew;
- }
- public String getHookAfterNew() {
- return hookAfterNew;
- }
- public String getHookBeforeScript() {
- return hookBeforeScript;
- }
- public String getHookBeforeEachScript() {
- return hookBeforeEachScript;
- }
- public String getHookAfterEachScript() {
- return hookAfterEachScript;
- }
- public String getHookAfterScript() {
- return hookAfterScript;
- }
- public Properties getVariables() {
- return variables;
- }
- }