Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
PropertiesFilterFactoryBean |
|
| 2.6666666666666665;2.667 |
1 | /** | |
2 | * Copyright 2010 The Kuali Foundation Licensed under the | |
3 | * Educational Community License, Version 2.0 (the "License"); you may | |
4 | * not use this file except in compliance with the License. You may | |
5 | * obtain a copy of the License at | |
6 | * | |
7 | * http://www.osedu.org/licenses/ECL-2.0 | |
8 | * | |
9 | * Unless required by applicable law or agreed to in writing, | |
10 | * software distributed under the License is distributed on an "AS IS" | |
11 | * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | |
12 | * or implied. See the License for the specific language governing | |
13 | * permissions and limitations under the License. | |
14 | */ | |
15 | ||
16 | package org.kuali.student.common.util; | |
17 | ||
18 | import java.io.FileInputStream; | |
19 | import java.io.IOException; | |
20 | import java.io.InputStream; | |
21 | import java.net.URL; | |
22 | import java.util.HashSet; | |
23 | import java.util.Properties; | |
24 | import java.util.Set; | |
25 | ||
26 | import org.springframework.beans.factory.FactoryBean; | |
27 | import org.springframework.core.io.ClassPathResource; | |
28 | ||
29 | /** | |
30 | * A really simple properties filter that returns a properties object for a | |
31 | * subset of a properties file. Give this method the file name of the properties | |
32 | * file, and then give it the prefix to filter on. The prefix gets a "." | |
33 | * appended to it on filtering. | |
34 | * <p> | |
35 | * For example, if the properties are: | |
36 | * <ul> | |
37 | * <li>prop1.test1=value1</li> | |
38 | * <li>prop1.test2=value2</li> | |
39 | * <li>prop2.test1=value1</li> | |
40 | * <li>prop1butnottherealprop1.test3=value3</li> | |
41 | * </ul> | |
42 | * Then filtering on "prop1" returns a Properties object with values: | |
43 | * <ul> | |
44 | * <li>test1=value1</li> | |
45 | * <li>test2=value2</li> | |
46 | * </ul> | |
47 | * </p> | |
48 | * | |
49 | * @author Kuali Student Team (ks.team2@kuali.org) | |
50 | */ | |
51 | 0 | public class PropertiesFilterFactoryBean implements FactoryBean { |
52 | ||
53 | private static final String CLASSPATH_PREFIX = "classpath:"; | |
54 | ||
55 | private static final String FILEURL_PREFIX = "file:"; | |
56 | ||
57 | private String propertyFile; | |
58 | private String prefix; | |
59 | ||
60 | @Override | |
61 | public Object getObject() throws Exception { | |
62 | ||
63 | InputStream stream; | |
64 | ||
65 | 0 | if (propertyFile.startsWith(CLASSPATH_PREFIX)) { |
66 | 0 | ClassPathResource resource = new ClassPathResource(propertyFile |
67 | .substring(CLASSPATH_PREFIX.length())); | |
68 | 0 | stream = resource.getInputStream(); |
69 | 0 | } else if(propertyFile.toLowerCase().startsWith(FILEURL_PREFIX)){ |
70 | 0 | URL url = new URL(propertyFile); |
71 | 0 | stream = url.openConnection().getInputStream(); |
72 | 0 | } else { |
73 | 0 | stream = new FileInputStream(propertyFile); |
74 | } | |
75 | ||
76 | 0 | Properties inProperties = new Properties(); |
77 | try { | |
78 | 0 | inProperties.load(stream); |
79 | } finally { | |
80 | 0 | if (stream != null) { |
81 | try { | |
82 | 0 | stream.close(); |
83 | 0 | } catch (IOException e) { |
84 | 0 | } |
85 | } | |
86 | } | |
87 | ||
88 | 0 | Properties outProperties = new Properties(); |
89 | 0 | int prefixLength = prefix.length(); |
90 | 0 | for (String key : inProperties.stringPropertyNames()) { |
91 | 0 | if (key.startsWith(prefix)) { |
92 | 0 | String stringValue = resolvePlaceholder(key, inProperties); |
93 | 0 | String resolvedProperty = this.parseStringValue(stringValue, inProperties, new HashSet<String>()); |
94 | 0 | outProperties.setProperty(key.substring(prefixLength), |
95 | resolvedProperty); | |
96 | 0 | } |
97 | } | |
98 | ||
99 | 0 | return outProperties; |
100 | } | |
101 | ||
102 | @Override | |
103 | public Class<?> getObjectType() { | |
104 | 0 | return Properties.class; |
105 | } | |
106 | ||
107 | @Override | |
108 | public boolean isSingleton() { | |
109 | 0 | return false; |
110 | } | |
111 | ||
112 | public String getPropertyFile() { | |
113 | 0 | return propertyFile; |
114 | } | |
115 | ||
116 | /** | |
117 | * @param propertyFile | |
118 | * the filename of the properties file, either a file system path | |
119 | * or classpath:path | |
120 | */ | |
121 | public void setPropertyFile(String propertyFile) { | |
122 | 0 | this.propertyFile = propertyFile; |
123 | 0 | } |
124 | ||
125 | public String getPrefix() { | |
126 | 0 | return prefix; |
127 | } | |
128 | ||
129 | /** | |
130 | * @param prefix | |
131 | * The prefix to filter on, a '.' will be appended. | |
132 | */ | |
133 | public void setPrefix(String prefix) { | |
134 | 0 | this.prefix = prefix + "."; |
135 | 0 | } |
136 | ||
137 | /** | |
138 | * Parse the given String value recursively, to be able to resolve nested | |
139 | * placeholders (when resolved property values in turn contain placeholders | |
140 | * again). | |
141 | * @param strVal | |
142 | * @param props | |
143 | * @param visitedPlaceholders | |
144 | * @return the resolved String | |
145 | */ | |
146 | protected String parseStringValue(String strVal, Properties props, | |
147 | Set<String> visitedPlaceholders) { | |
148 | ||
149 | 0 | if(strVal!=null&&strVal.indexOf("${")>-1){ |
150 | ||
151 | 0 | String begin = strVal.substring(0, strVal.indexOf("${")); |
152 | 0 | String resolveString = strVal.substring(strVal.indexOf("${")+2,strVal.indexOf("}")); |
153 | 0 | String end = strVal.substring(strVal.indexOf("}")+1); |
154 | 0 | if(!visitedPlaceholders.add(resolveString)){ |
155 | 0 | return ""; |
156 | } | |
157 | 0 | String propVal = resolvePlaceholder(resolveString, props); |
158 | 0 | String parsedString = parseStringValue(begin+propVal+end, props, |
159 | visitedPlaceholders); | |
160 | 0 | visitedPlaceholders.add(resolveString); |
161 | 0 | return parsedString; |
162 | } | |
163 | 0 | return strVal; |
164 | } | |
165 | ||
166 | /** | |
167 | * Resolve the given key as a Property, JVM system property, and optionally also as | |
168 | * system environment variable if no matching system property has been | |
169 | * found. | |
170 | * | |
171 | * @param key | |
172 | * the placeholder to resolve as system property key | |
173 | * @return the system property value, or <code>null</code> if not found | |
174 | * @see #setSearchSystemEnvironment | |
175 | * @see java.lang.System#getProperty(String) | |
176 | * @see java.lang.System#getenv(String) | |
177 | */ | |
178 | protected String resolvePlaceholder(String key, Properties props) { | |
179 | try { | |
180 | 0 | String value = props.getProperty(key); |
181 | 0 | if (value == null) { |
182 | 0 | value = System.getProperty(key); |
183 | } | |
184 | 0 | if (value == null) { |
185 | 0 | value = System.getenv(key); |
186 | } | |
187 | 0 | return value; |
188 | 0 | } catch (Throwable ex) { |
189 | 0 | return null; |
190 | } | |
191 | } | |
192 | ||
193 | } |