1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.reactive.configuration;
18
19 import org.springframework.core.io.Resource;
20 import org.springframework.core.io.ClassPathResource;
21 import org.springframework.core.io.FileSystemResource;
22 import org.springframework.beans.factory.InitializingBean;
23 import org.springframework.beans.factory.BeanInitializationException;
24 import org.springframework.util.PropertiesPersister;
25 import org.springframework.util.DefaultPropertiesPersister;
26 import org.igfay.jfig.*;
27 import org.reactive.beans.factory.config.PlaceholderEvaluator;
28 import org.reactive.beans.factory.config.Placeholder;
29 import org.reactive.beans.factory.config.InvalidPlaceholderException;
30 import org.reactive.beans.factory.config.DefaultPlaceholder;
31 import org.reactive.beans.factory.config.properties.PropertiesPlaceholderEvaluator;
32 import org.apache.commons.logging.Log;
33 import org.apache.commons.logging.LogFactory;
34
35 import java.io.InputStream;
36 import java.io.IOException;
37 import java.io.InputStreamReader;
38 import java.util.Properties;
39 import java.util.Enumeration;
40
41 /***
42 * This class merges properties from several sources into one Properties object.
43 *
44 * <p>An example of the bean factory configuration required for Commons Configuration</p>
45 * <pre>
46 * TODO: Add example XML
47 * </pre>
48 *
49 * <p>
50 * Note: This class is basically Spring's org.springframework.beans.factory.config.PropertyResourceConfigurer
51 * by Juergen Hoeller with a few things moved to other classes.
52 * </p>
53 *
54 * @author Dan Washusen
55 * @version $Id: PropertiesConfigurationFactory.java,v 1.1 2004/12/30 23:28:28 dan_washusen Exp $
56 * @since 31.12.2004
57 */
58 public class PropertiesConfigurationFactory
59 implements InitializingBean {
60 protected final Log logger = LogFactory.getLog(PropertiesConfigurationFactory.class);
61
62 private Properties properties;
63
64 private Resource[] locations;
65
66 private String fileEncoding;
67
68 private PropertiesPersister propertiesPersister = new DefaultPropertiesPersister();
69
70 private boolean ignoreResourceNotFound = false;
71
72 private Properties mergedProperties;
73
74 /***
75 * Set local properties, e.g. via the "props" tag in XML bean definitions.
76 * These can be considered defaults, to be overridden by properties
77 * loaded from files.
78 * @see #setLocation
79 * @see #setLocations
80 */
81 public void setProperties(Properties properties) {
82 this.properties = properties;
83 }
84
85 /***
86 * Set a location of a properties file to be loaded.
87 * @see #setLocations
88 */
89 public void setLocation(Resource location) {
90 this.locations = new Resource[] {location};
91 }
92
93 /***
94 * Set locations of properties files to be loaded.
95 * @see #setLocation
96 */
97 public void setLocations(Resource[] locations) {
98 this.locations = locations;
99 }
100
101 /***
102 * Set the encoding to use for parsing properties files.
103 * Default is none, using java.util.Properties' default encoding.
104 * @see org.springframework.util.PropertiesPersister#load
105 */
106 public void setFileEncoding(String encoding) {
107 this.fileEncoding = encoding;
108 }
109
110 /***
111 * Set the PropertiesPersister to use for parsing properties files.
112 * The default is DefaultPropertiesPersister.
113 * @see org.springframework.util.DefaultPropertiesPersister
114 */
115 public void setPropertiesPersister(PropertiesPersister propertiesPersister) {
116 this.propertiesPersister = propertiesPersister;
117 }
118
119 /***
120 * Set if failure to find the property resource should be ignored.
121 * True is appropriate if the properties file is completely optional.
122 * Default is false.
123 */
124 public void setIgnoreResourceNotFound(boolean ignoreResourceNotFound) {
125 this.ignoreResourceNotFound = ignoreResourceNotFound;
126 }
127
128 /***
129 * Merges the properties provided by {@link #setLocations(org.springframework.core.io.Resource[])} and
130 * {@link #setProperties(java.util.Properties)} after all properties have been set by the bean factory.
131 * @throws Exception If an IO error occurs while attempting to read a properties file from disk
132 */
133 public void afterPropertiesSet()
134 throws Exception {
135 this.mergedProperties = new Properties();
136
137 if (this.properties != null) {
138
139 for (Enumeration en = this.properties.propertyNames(); en.hasMoreElements();) {
140 String key = (String) en.nextElement();
141 mergedProperties.setProperty(key, this.properties.getProperty(key));
142 }
143 }
144
145 if (this.locations != null) {
146 for (int i = 0; i < this.locations.length; i++) {
147 Resource location = this.locations[i];
148 if (logger.isInfoEnabled()) {
149 logger.info("Loading properties from " + location + "");
150 }
151 try {
152 InputStream is = location.getInputStream();
153 try {
154 if (this.fileEncoding != null) {
155 this.propertiesPersister.load(mergedProperties, new InputStreamReader(is, this.fileEncoding));
156 }
157 else {
158 this.propertiesPersister.load(mergedProperties, is);
159 }
160 }
161 finally {
162 is.close();
163 }
164 }
165 catch (IOException ex) {
166 String msg = "Could not load properties from " + location;
167 if (this.ignoreResourceNotFound) {
168 if (logger.isWarnEnabled()) {
169 logger.warn(msg + ": " + ex.getMessage());
170 }
171 }
172 else {
173 throw new BeanInitializationException(msg, ex);
174 }
175 }
176 }
177 }
178 }
179
180 /***
181 * Returns the merge properties, the result of merging the properties specified by {@link #setLocation(org.springframework.core.io.Resource)},
182 * {@link #setLocations(org.springframework.core.io.Resource[])} and {@link #setProperties(java.util.Properties)}.
183 * @return The merged properties
184 */
185 public Properties getMergedProperties() {
186 return mergedProperties;
187 }
188
189 /***
190 * A convenience method that returns the merged properties.
191 * @return The merged properties
192 */
193 public Properties getConfiguration() {
194 return getMergedProperties();
195 }
196 }