001    /**
002     * Copyright 2005-2013 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 edu.samplu.common;
017    
018    import java.io.IOException;
019    import java.io.InputStream;
020    import java.util.ArrayList;
021    import java.util.Enumeration;
022    import java.util.HashMap;
023    import java.util.Iterator;
024    import java.util.LinkedList;
025    import java.util.List;
026    import java.util.Map;
027    import java.util.Properties;
028    
029    /**
030     * @author Kuali Rice Team (rice.collab@kuali.org)
031     */
032    
033    public class PropertiesUtils {
034    
035    
036        public static Properties loadPropertiesWithSystemOverrides(InputStream inputStream) throws IOException {
037            Properties props = PropertiesUtils.loadProperties(inputStream);
038            PropertiesUtils.systemPropertiesOverride(props);
039            return props;
040        }
041    
042        public static Properties loadPropertiesWithSystemOverridesAndNumberedPropertiesToList(InputStream inputStream) throws IOException {
043            Properties props = PropertiesUtils.loadProperties(inputStream);
044            PropertiesUtils.systemPropertiesOverride(props);
045            PropertiesUtils.transformNumberedPropertiesToList(props);
046            return props;
047        }
048    
049        public static Properties loadProperties(InputStream inputStream) throws IOException {
050            Properties props = new Properties();
051    
052            if(inputStream != null) {
053                props.load(inputStream);
054            }
055    
056            return props;
057        }
058    
059        public static String removeNumber(final String numberedKey) {
060            String unnumberedKey = numberedKey;
061            int firstNumberIndex = unnumberedKey.length() - 1;
062            while (Character.isDigit(unnumberedKey.charAt(firstNumberIndex))) {
063                firstNumberIndex--;
064            }
065            unnumberedKey = unnumberedKey.substring(0, firstNumberIndex + 1);
066    
067            return unnumberedKey;
068        }
069    
070        public static void systemPropertiesOverride(Properties props) {
071            PropertiesUtils.systemPropertiesOverride(props, null);
072        }
073    
074        /**
075         * -Dkey.propertyname= to override the property value for propertyname.
076         * @param props properties to update with System.getProperty overrides.
077         * @param key optional value that the property names will be appended to.
078         */
079        public static void systemPropertiesOverride(Properties props, String key) {
080            Enumeration<?> names = props.propertyNames();
081            Object nameObject;
082            String name;
083            while (names.hasMoreElements()) {
084    
085                nameObject = names.nextElement();
086                if (nameObject instanceof String) {
087    
088                    name = (String)nameObject;
089                    if (key == null || key.isEmpty()) {
090                        props.setProperty(name, System.getProperty(name, props.getProperty(name)));
091                    } else {
092                        props.setProperty(name, System.getProperty(key + "." + name, props.getProperty(name)));
093                    }
094                }
095            }
096        }
097    
098        public static void transformNumberedPropertiesToList(Properties props) {
099            String key = null;
100            String unnumberedKey = null;
101            List<String> keyList = null;
102            List<String> removeKeys = new LinkedList<String>();
103    
104            // unnumber keys and place their values in a list
105            Iterator keys = props.keySet().iterator();
106            Map<String, List<String>> keysLists = new HashMap<String, List<String>>();
107            while (keys.hasNext()) {
108                key = (String)keys.next();
109                if (Character.isDigit(key.charAt(key.length()-1))) {
110                    unnumberedKey = removeNumber(key);
111                    if (keysLists.get(unnumberedKey) == null) {
112                        keyList = new ArrayList<String>();
113                        keyList.add(props.getProperty(key));
114                        keysLists.put(unnumberedKey, keyList);
115                        removeKeys.add(key);
116                    } else {
117                        keyList = keysLists.get(unnumberedKey);
118                        keyList.add(props.getProperty(key));
119                        keysLists.put(unnumberedKey, keyList);
120                        removeKeys.add(key);
121                    }
122                }
123            }
124    
125            // remove keys that where unnumbered
126            Iterator removeKey = removeKeys.iterator();
127            while (removeKey.hasNext()) {
128                key = (String)removeKey.next();
129                props.remove(key);
130            }
131    
132            // put new unnumbered key values mapped by unnumber key with an s appended to it.
133            Iterator newKeys = keysLists.keySet().iterator();
134            String newKey = null;
135            while (newKeys.hasNext()) {
136                newKey = (String)newKeys.next();
137                props.put(newKey + "s", keysLists.get(newKey));
138            }
139        }
140    }