001    /*
002     * Copyright 2007 The Kuali Foundation
003     * 
004     * Licensed under the Educational Community 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     * 
008     * http://www.opensource.org/licenses/ecl2.php
009     * 
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     */
016    package org.kuali.kfs.sys.context;
017    
018    import java.lang.System;
019    
020    import java.io.IOException;
021    import java.io.InputStream;
022    import java.util.ArrayList;
023    import java.util.Arrays;
024    import java.util.List;
025    import java.util.Properties;
026    
027    import org.apache.commons.lang.StringUtils;
028    import org.kuali.kfs.sys.KFSConstants;
029    import org.kuali.rice.core.config.JAXBConfigImpl;
030    import org.kuali.rice.core.util.ClassLoaderUtils;
031    import org.springframework.beans.factory.FactoryBean;
032    import org.springframework.core.io.DefaultResourceLoader;
033    
034    public class PropertyLoadingFactoryBean implements FactoryBean {
035        private static final String PROPERTY_FILE_NAMES_KEY = "property.files";
036        private static final String PROPERTY_TEST_FILE_NAMES_KEY = "property.test.files";
037        private static final String SECURITY_PROPERTY_FILE_NAME_KEY = "security.property.file";
038        private static final String CONFIGURATION_FILE_NAME = "configuration";
039        private static final Properties BASE_PROPERTIES = new Properties();
040        private static final String HTTP_URL_PROPERTY_NAME = "http.url";
041        private static final String KSB_REMOTING_URL_PROPERTY_NAME = "ksb.remoting.url";
042        private static final String REMOTING_URL_SUFFIX = "/remoting";
043        private Properties props = new Properties();
044        private boolean testMode;
045        private boolean secureMode;
046    
047        public Object getObject() throws Exception {
048            loadBaseProperties();
049            props.putAll(BASE_PROPERTIES);
050            if (secureMode) {
051                loadPropertyList(props,SECURITY_PROPERTY_FILE_NAME_KEY);
052            } else {
053                loadPropertyList(props,PROPERTY_FILE_NAMES_KEY);
054                if (testMode) {
055                    loadPropertyList(props,PROPERTY_TEST_FILE_NAMES_KEY);
056                }            
057            }
058            if (StringUtils.isBlank(System.getProperty(HTTP_URL_PROPERTY_NAME))) {
059                props.put(KSB_REMOTING_URL_PROPERTY_NAME, props.getProperty(KFSConstants.APPLICATION_URL_KEY) + REMOTING_URL_SUFFIX);
060            }
061            else {
062                props.put(KSB_REMOTING_URL_PROPERTY_NAME, new StringBuffer("http://").append(System.getProperty(HTTP_URL_PROPERTY_NAME)).append("/kfs-").append(props.getProperty(KFSConstants.ENVIRONMENT_KEY)).append(REMOTING_URL_SUFFIX).toString());
063            }
064            System.out.println(KSB_REMOTING_URL_PROPERTY_NAME + " set to " + props.getProperty(KSB_REMOTING_URL_PROPERTY_NAME));
065            return props;
066        }
067    
068        public Class getObjectType() {
069            return Properties.class;
070        }
071    
072        public boolean isSingleton() {
073            return true;
074        }
075    
076        private static void loadPropertyList(Properties props, String listPropertyName) {
077            for (String propertyFileName : getBaseListProperty(listPropertyName)) {
078                loadProperties(props,propertyFileName);
079            }
080        }
081    
082        private static void loadProperties( Properties props, String propertyFileName) {
083            InputStream propertyFileInputStream = null;
084            try {
085                try {
086                    propertyFileInputStream = new DefaultResourceLoader(ClassLoaderUtils.getDefaultClassLoader()).getResource(propertyFileName).getInputStream();
087                    props.load(propertyFileInputStream);
088                }
089                finally {
090                    if (propertyFileInputStream != null) {
091                        propertyFileInputStream.close();
092                    }
093                }
094            }
095            catch (IOException e) {
096                throw new RuntimeException("PropertyLoadingFactoryBean unable to load property file: " + propertyFileName);
097            }
098        }
099    
100        public static String getBaseProperty(String propertyName) {
101            loadBaseProperties();
102            return BASE_PROPERTIES.getProperty(propertyName);
103        }
104    
105        protected static List<String> getBaseListProperty(String propertyName) {
106            loadBaseProperties();
107            return Arrays.asList(BASE_PROPERTIES.getProperty(propertyName).split(","));
108        }
109    
110        protected static void loadBaseProperties() {
111            if (BASE_PROPERTIES.isEmpty()) {
112                List<String> riceXmlConfigurations = new ArrayList<String>();
113                riceXmlConfigurations.add("classpath:META-INF/common-config-defaults.xml");
114                JAXBConfigImpl riceXmlConfigurer = new JAXBConfigImpl(riceXmlConfigurations);
115                try {
116                    riceXmlConfigurer.parseConfig();
117                    BASE_PROPERTIES.putAll(riceXmlConfigurer.getProperties());
118                }
119                catch (Exception e) {
120                    // Couldn't load the rice configs
121                }
122    
123                loadProperties(BASE_PROPERTIES, new StringBuffer("classpath:").append(CONFIGURATION_FILE_NAME).append(".properties").toString());
124            }
125    
126            final String additionalProps = BASE_PROPERTIES.getProperty("additional.config.locations");
127            final JAXBConfigImpl additionalConfigurer = new JAXBConfigImpl(java.util.Arrays.asList(additionalProps));
128            try {
129                additionalConfigurer.parseConfig();
130                System.out.println("Adding props from " + additionalProps);
131                BASE_PROPERTIES.putAll(additionalConfigurer.getProperties());                    
132            }
133            catch (Exception e) {
134                // Unable to load additional configs
135                e.printStackTrace();
136            }
137        }
138    
139        public void setTestMode(boolean testMode) {
140            this.testMode = testMode;
141        }
142    
143        public void setSecureMode(boolean secureMode) {
144            this.secureMode = secureMode;
145        }
146        
147        public static void clear() {
148            BASE_PROPERTIES.clear();
149        }
150    }