001    package org.apache.torque.util;
002    
003    import java.io.File;
004    import java.io.FileInputStream;
005    import java.io.InputStreamReader;
006    import java.io.Reader;
007    import java.util.Map;
008    import java.util.Properties;
009    import java.util.Set;
010    
011    import org.apache.commons.beanutils.BeanUtils;
012    import org.apache.commons.lang.StringUtils;
013    import org.apache.commons.logging.Log;
014    import org.apache.commons.logging.LogFactory;
015    import org.kuali.core.db.torque.PropertyHandlingException;
016    import org.kuali.core.db.torque.Utils;
017    import org.springframework.core.io.DefaultResourceLoader;
018    import org.springframework.core.io.Resource;
019    import org.springframework.core.io.ResourceLoader;
020    
021    public class BeanPropertiesLoader {
022            private static final Log log = LogFactory.getLog(BeanPropertiesLoader.class);
023    
024            Utils utils = new Utils();
025            String location;
026            String encoding;
027            Object bean;
028            boolean overrideExistingPropertyValues = true;
029            boolean overrideSystemProperties = false;
030            String description;
031    
032            public BeanPropertiesLoader() {
033                    this(null, null, null, null);
034            }
035    
036            public BeanPropertiesLoader(Object bean, String location, String encoding, String description) {
037                    super();
038                    this.bean = bean;
039                    this.location = location;
040                    this.encoding = encoding;
041                    this.description = description;
042            }
043    
044            public boolean isPropertiesExist() {
045                    return utils.isFileOrResource(location);
046            }
047    
048            protected boolean isSkip(Map<String, Object> description, String key) {
049                    Object value = description.get(key);
050                    if (value != null && !isOverrideExistingPropertyValues()) {
051                            // The property is already set, don't override it unless they have asked us to
052                            log.debug("Skipping property " + key + " it is already set to " + value);
053                            return true;
054                    }
055                    Set<String> beanProperties = description.keySet();
056                    if (!beanProperties.contains(key)) {
057                            // This is not a property of the bean
058                            log.debug("Skipping property " + key + " as it is not a property of this bean");
059                            return true;
060                    }
061                    return false;
062            }
063    
064            @SuppressWarnings("unchecked")
065            public void loadToBean() throws PropertyHandlingException {
066                    if (!utils.isFileOrResource(location)) {
067                            log.info("------------------------------------------------------------------------");
068                            log.warn("No properties file located at " + location);
069                            log.info("------------------------------------------------------------------------");
070                            return;
071                    } else {
072                            log.info("------------------------------------------------------------------------");
073                            log.info("Loading " + getDescription() + " properties from " + location);
074                            log.info("------------------------------------------------------------------------");
075                    }
076                    try {
077                            Properties properties = getProperties();
078                            if (!overrideSystemProperties) {
079                                    properties.putAll(System.getProperties());
080                            }
081                            Set<String> keys = properties.stringPropertyNames();
082                            Map<String, Object> description = BeanUtils.describe(bean);
083                            for (String key : keys) {
084                                    if (isSkip(description, key)) {
085                                            continue;
086                                    }
087                                    // Extract the value and set it on the bean
088                                    String newValue = properties.getProperty(key);
089                                    log.info("Setting " + key + "=" + getLogValue(key, newValue));
090                                    BeanUtils.copyProperty(bean, key, newValue);
091                            }
092                    } catch (Exception e) {
093                            throw new PropertyHandlingException(e);
094                    }
095            }
096    
097            /**
098             * Don't display password'ish type properties
099             */
100            protected String getLogValue(String key, String value) {
101                    int pos = key.toLowerCase().indexOf("password");
102                    if (pos == -1) {
103                            return value;
104                    } else {
105                            return StringUtils.repeat("*", value.length());
106                    }
107            }
108    
109            /**
110             * Load the properties file into a Properties object
111             */
112            public Properties getProperties() throws PropertyHandlingException {
113                    try {
114                            Reader reader = getReader();
115                            Properties properties = new Properties();
116                            properties.load(reader);
117                            return properties;
118                    } catch (Exception e) {
119                            throw new PropertyHandlingException(e);
120                    }
121            }
122    
123            /**
124             * Return a Reader for reading in the properties file. First check the file system to see if the file exists. If
125             * not, return a Reader using Spring Resource loading
126             */
127            protected Reader getReader() throws PropertyHandlingException {
128                    try {
129                            File file = new File(location);
130                            if (file.exists()) {
131                                    return new InputStreamReader(new FileInputStream(file), getEncoding());
132                            }
133                            ResourceLoader loader = new DefaultResourceLoader();
134                            Resource resource = loader.getResource(location);
135                            return new InputStreamReader(resource.getInputStream(), getEncoding());
136                    } catch (Exception e) {
137                            throw new PropertyHandlingException(e);
138                    }
139            }
140    
141            public String getLocation() {
142                    return location;
143            }
144    
145            public void setLocation(String location) {
146                    this.location = location;
147            }
148    
149            public String getEncoding() {
150                    return encoding;
151            }
152    
153            public void setEncoding(String encoding) {
154                    this.encoding = encoding;
155            }
156    
157            public Object getBean() {
158                    return bean;
159            }
160    
161            public void setBean(Object bean) {
162                    this.bean = bean;
163            }
164    
165            public boolean isOverrideExistingPropertyValues() {
166                    return overrideExistingPropertyValues;
167            }
168    
169            public void setOverrideExistingPropertyValues(boolean override) {
170                    this.overrideExistingPropertyValues = override;
171            }
172    
173            public String getDescription() {
174                    return description;
175            }
176    
177            public void setDescription(String description) {
178                    this.description = description;
179            }
180    
181            public boolean isOverrideSystemProperties() {
182                    return overrideSystemProperties;
183            }
184    
185            public void setOverrideSystemProperties(boolean overrideSystemProperties) {
186                    this.overrideSystemProperties = overrideSystemProperties;
187            }
188    
189    }