/* * The Kuali Financial System, a comprehensive financial management system for higher education. * * Copyright 2005-2014 The Kuali Foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * 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 org.kuali.kfs.sys.context; import org.apache.commons.lang.StringUtils; import org.kuali.kfs.sys.KFSConstants; import org.kuali.rice.core.api.util.ClassLoaderUtils; import org.kuali.rice.core.impl.config.property.JAXBConfigImpl; import org.springframework.beans.factory.FactoryBean; import org.springframework.core.io.DefaultResourceLoader; import java.io.IOException; import java.io.InputStream; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.Set; import java.util.List; import java.util.Properties; public class PropertyLoadingFactoryBean implements FactoryBean<Properties> { private static final String PROPERTY_FILE_NAMES_KEY = "property.files"; private static final String PROPERTY_TEST_FILE_NAMES_KEY = "property.test.files"; private static final String SECURITY_PROPERTY_FILE_NAME_KEY = "security.property.file"; private static final String KFS_DEFAULT_CONFIGURATION_FILE_NAME = "kfs-default-config"; private static final String KFS_RICE_DEFAULT_CONFIGURATION_FILE_NAME = "kfs-rice-default-config"; private static final String KFS_SECURITY_DEFAULT_CONFIGURATION_FILE_NAME = "kfs-security-default-config"; private static final Properties BASE_PROPERTIES = new Properties(); private static final String HTTP_URL_PROPERTY_NAME = "http.url"; private static final String KSB_REMOTING_URL_PROPERTY_NAME = "ksb.remoting.url"; private static final String REMOTING_URL_SUFFIX = "/remoting"; private static final String ADDITIONAL_KFS_CONFIG_LOCATIONS_PARAM = "additional.kfs.config.locations"; private static final String ADDITIONAL_KFS_TEST_CONFIG_LOCATIONS_PARAM = "additional.kfs.test.config.locations"; private Properties props = new Properties(); private boolean testMode; private boolean secureMode; private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PropertyLoadingFactoryBean.class); public Properties getObject() { loadBaseProperties(); props.putAll(BASE_PROPERTIES); if (secureMode) { loadPropertyList(props, SECURITY_PROPERTY_FILE_NAME_KEY); } else { loadPropertyList(props,PROPERTY_FILE_NAMES_KEY); } if (testMode) { loadPropertyList(props,PROPERTY_TEST_FILE_NAMES_KEY); } if (StringUtils.isBlank(System.getProperty(HTTP_URL_PROPERTY_NAME))) { props.put(KSB_REMOTING_URL_PROPERTY_NAME, props.getProperty(KFSConstants.APPLICATION_URL_KEY) + REMOTING_URL_SUFFIX); } else { props.put(KSB_REMOTING_URL_PROPERTY_NAME, new StringBuilder("http://").append(System.getProperty(HTTP_URL_PROPERTY_NAME)).append("/kfs-").append(props.getProperty(KFSConstants.ENVIRONMENT_KEY)).append(REMOTING_URL_SUFFIX).toString()); } if (LOG.isDebugEnabled()) { for (Object key: props.keySet()) { String value = (String) props.get(key); System.out.println(key + ": " + value); LOG.debug(key + ": " + value); } } return props; } public Class<Properties> getObjectType() { return Properties.class; } public boolean isSingleton() { return true; } private static void loadPropertyList(Properties props, String listPropertyName) { for (String propertyFileName : getBaseListProperty(listPropertyName)) { loadProperties(props,propertyFileName); } } private static void loadProperties( Properties props, String propertyFileName) { InputStream propertyFileInputStream = null; try { try { propertyFileInputStream = new DefaultResourceLoader(ClassLoaderUtils.getDefaultClassLoader()).getResource(propertyFileName).getInputStream(); props.load(propertyFileInputStream); } finally { if (propertyFileInputStream != null) { propertyFileInputStream.close(); } } } catch (IOException e) { LOG.error(e); // throw new RuntimeException("PropertyLoadingFactoryBean unable to load property file: " + propertyFileName); } } public static String getBaseProperty(String propertyName) { loadBaseProperties(); return BASE_PROPERTIES.getProperty(propertyName); } protected static List<String> getBaseListProperty(String propertyName) { loadBaseProperties(); return Arrays.asList(BASE_PROPERTIES.getProperty(propertyName).split(",")); } protected static void loadBaseProperties() { if (BASE_PROPERTIES.isEmpty()) { List<String> riceXmlConfigurations = new ArrayList<String>(); riceXmlConfigurations.add("classpath:META-INF/common-config-defaults.xml"); JAXBConfigImpl riceXmlConfigurer = new JAXBConfigImpl(riceXmlConfigurations); try { riceXmlConfigurer.parseConfig(); } catch (IOException ex) { ex.printStackTrace(); } BASE_PROPERTIES.putAll(riceXmlConfigurer.getProperties()); loadProperties(BASE_PROPERTIES, new StringBuilder("classpath:").append(KFS_DEFAULT_CONFIGURATION_FILE_NAME).append(".properties").toString()); loadProperties(BASE_PROPERTIES, new StringBuilder("classpath:").append(KFS_RICE_DEFAULT_CONFIGURATION_FILE_NAME).append(".properties").toString()); loadProperties(BASE_PROPERTIES, new StringBuilder("classpath:").append(KFS_SECURITY_DEFAULT_CONFIGURATION_FILE_NAME).append(".properties").toString()); loadExternalProperties(BASE_PROPERTIES, ADDITIONAL_KFS_CONFIG_LOCATIONS_PARAM); loadExternalProperties(BASE_PROPERTIES, ADDITIONAL_KFS_TEST_CONFIG_LOCATIONS_PARAM); } } /** * Loads properties from an external file. Also merges in all System properties * @param props the properties object */ private static void loadExternalProperties(Properties props, String location) { String externalConfigLocationPaths = System.getProperty(location); if (StringUtils.isNotEmpty(externalConfigLocationPaths)) { String[] files = externalConfigLocationPaths.split(","); for (String f: files) { if (StringUtils.isNotEmpty(f)) { System.err.println("Loading properties from " + f); loadProperties(props, new StringBuffer("file:").append(f).toString()); } } } props.putAll(System.getProperties()); } public void setTestMode(boolean testMode) { this.testMode = testMode; } public void setSecureMode(boolean secureMode) { this.secureMode = secureMode; } public static void clear() { BASE_PROPERTIES.clear(); } }