/**
 * Axelor Business Solutions
 *
 * Copyright (C) 2012-2014 Axelor (<http://axelor.com>).
 *
 * This program is free software: you can redistribute it and/or  modify
 * it under the terms of the GNU Affero General Public License, version 3,
 * as published by the Free Software Foundation.
 *
 * This program 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.axelor.app;

import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Properties;

import com.axelor.app.internal.AppFilter;
import com.axelor.common.ClassUtils;
import com.axelor.common.StringUtils;

public final class AppSettings {

	private static final String DEFAULT_CONFIG_LOCATION = "application.properties";
	private static final String CUSTOM_CONFIG_LOCATION = "axelor.config";

	private Properties properties;

	private static AppSettings instance;

	private AppSettings() {
		String config = System.getProperty(CUSTOM_CONFIG_LOCATION);
		InputStream stream = null;
		try {
			if (StringUtils.isBlank(config)) {
				stream = ClassUtils.getResourceStream(config = DEFAULT_CONFIG_LOCATION);
			} else {
				stream = new FileInputStream(config);
			}
			try {
				properties = new Properties();
				properties.load(stream);
			} finally {
				stream.close();
			}
		} catch (Exception e) {
			throw new RuntimeException("Unable to load application settings: " + config);
		}
	}

	public static AppSettings get() {
		if (instance == null) {
			instance = new AppSettings();
		}
		return instance;
	}

	public String get(String key) {
		return properties.getProperty(key);
	}

	public String get(String key, String defaultValue) {
		String value = properties.getProperty(key, defaultValue);
		if (value == null || "".equals(value.trim()))
			return defaultValue;
		return value;
	}

	public int getInt(String key, int defaultValue) {
		try {
			return Integer.parseInt(get(key).toString());
		} catch (Exception e){}
		return defaultValue;
	}

	public boolean getBoolean(String key, boolean defaultValue) {
		try {
			return Boolean.parseBoolean(get(key).toString());
		} catch (Exception e){}
		return defaultValue;
	}

	public String getPath(String key, String defaultValue) {
		String path = get(key, defaultValue);
		if (path == null) {
			return null;
		}
		return path.replace("{java.io.tmpdir}",
				System.getProperty("java.io.tmpdir")).replace("{user.home}",
				System.getProperty("user.home"));
	}

	/**
	 * Get the application base URL.
	 * <p>
	 * This method tries to calculate the base url from current http request. If
	 * the method is called outside of http request scope, it returns the value
	 * of <code>application.baseUrl</code> configuration setting.
	 * </p>
	 * 
	 * @return application base url
	 */
	public String getBaseURL() {
		String url = AppFilter.getBaseURL();
		if (url == null) {
			url = get("application.baseUrl");
		}
		return url;
	}

	public boolean isProduction() {
		return !"dev".equals(get("application.mode", "dev"));
	}

	/**
	 * For internal use only.
	 */
	public Properties getProperties() {
		return properties;
	}
}

@@ -775,32 +775,59 @@
 io.InputStream;%0A
+import java.util.Calendar;%0A
 import java.util
@@ -839,16 +839,16 @@
 erties;%0A
-
 %0Aimport 
@@ -1898,32 +1898,36 @@
 key) %7B%0A%09%09return 
+sub(
 properties.getPr
@@ -1937,16 +1937,17 @@
 rty(key)
+)
 ;%0A%09%7D%0A%0A%09p
@@ -2105,26 +2105,29 @@
 trim()))
+ %7B
 %0A%09%09%09
-return
+value =
  default
@@ -2133,16 +2133,20 @@
 tValue;%0A
+%09%09%7D%0A
 %09%09return
@@ -2146,21 +2146,26 @@
 %09return 
+sub(
 value
+)
 ;%0A%09%7D%0A%0A%09p
@@ -2649,20 +2649,339 @@
 %09return 
-path
+sub(path);%0A%09%7D%0A%0A%09private String sub(String value) %7B%0A%09%09if (value == null) %7B%0A%09%09%09return null;%0A%09%09%7D%0A%09%09final Calendar cal = Calendar.getInstance();%0A%09%09return value.replace(%22%7Byear%7D%22, %22%22 + cal.get(Calendar.YEAR))%0A%09%09%09%09%09.replace(%22%7Bmonth%7D%22, %22%22 + cal.get(Calendar.MONTH))%0A%09%09%09%09%09.replace(%22%7Bday%7D%22, %22%22 + cal.get(Calendar.DAY_OF_MONTH))%0A%09%09%09%09%09
 .replace
@@ -3000,21 +3000,17 @@
 mpdir%7D%22,
-%0A%09%09%09%09
+ 
 System.g
@@ -3038,16 +3038,22 @@
 mpdir%22))
+%0A%09%09%09%09%09
 .replace
@@ -3067,21 +3067,17 @@
 .home%7D%22,
-%0A%09%09%09%09
+ 
 System.g

Allow year/month/day placeholders in property values.