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