Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
RiceConfigPropertyPlaceholderConfigurer |
|
| 2.125;2.125 | ||||
RiceConfigPropertyPlaceholderConfigurer$PlaceholderResolvingStringValueResolver |
|
| 2.125;2.125 |
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.rice.student.core.config.spring; | |
17 | ||
18 | import java.io.IOException; | |
19 | import java.util.HashSet; | |
20 | import java.util.Properties; | |
21 | ||
22 | import org.apache.log4j.Logger; | |
23 | import org.kuali.rice.core.config.Config; | |
24 | import org.kuali.rice.core.config.ConfigContext; | |
25 | import org.kuali.rice.core.config.ConfigLogger; | |
26 | import org.springframework.beans.BeansException; | |
27 | import org.springframework.beans.factory.BeanDefinitionStoreException; | |
28 | import org.springframework.beans.factory.BeanFactory; | |
29 | import org.springframework.beans.factory.config.BeanDefinition; | |
30 | import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; | |
31 | import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer; | |
32 | import org.springframework.util.StringValueResolver; | |
33 | ||
34 | /** | |
35 | * This PropertyPlaceholderConfigurer impl will load properties from the current ConfigContext. | |
36 | * It also creates a BeanDefinitionVisitor that will allow for injection of Properties objects created | |
37 | * from properties of a like prefix identified by a value of $[my.prefix]. | |
38 | * | |
39 | * example: | |
40 | * foo.prop1=bar | |
41 | * foo.prop2=foo | |
42 | * fooPropertyObject=$[foo.] | |
43 | * | |
44 | * results in | |
45 | * fooPropertyObject={prop1=bar; prop2=foo} | |
46 | * | |
47 | * @author Kuali Rice Team (rice.collab@kuali.org) | |
48 | * | |
49 | */ | |
50 | 0 | public class RiceConfigPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer { |
51 | ||
52 | 0 | protected final org.apache.log4j.Logger log = Logger.getLogger(RiceConfigPropertyPlaceholderConfigurer.class); |
53 | ||
54 | // these have to be redeclared because they are private in the base with no getters | |
55 | private String beanName; | |
56 | private BeanFactory beanFactory; | |
57 | ||
58 | @Override | |
59 | protected void loadProperties(Properties props) throws IOException { | |
60 | // perform standard property resource file loading | |
61 | 0 | super.loadProperties(props); |
62 | // load the Rice properties | |
63 | 0 | Config config = ConfigContext.getCurrentContextConfig(); |
64 | 0 | if (config != null) { |
65 | 0 | log.debug("Replacing parameters in Spring using config:\r\n" + config); |
66 | 0 | ConfigLogger.logConfig(config); |
67 | 0 | props.putAll(config.getProperties()); |
68 | } | |
69 | 0 | } |
70 | ||
71 | @Override | |
72 | public void setBeanName(String beanName) { | |
73 | 0 | this.beanName = beanName; |
74 | 0 | super.setBeanName(beanName); |
75 | 0 | } |
76 | ||
77 | @Override | |
78 | public void setBeanFactory(BeanFactory beanFactory) { | |
79 | 0 | this.beanFactory = beanFactory; |
80 | 0 | super.setBeanFactory(beanFactory); |
81 | 0 | } |
82 | ||
83 | //------------------------------------------------------------------------------------ | |
84 | // begin spring 2.0 compatible impl | |
85 | //------------------------------------------------------------------------------------ | |
86 | // protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, Properties props) throws BeansException { | |
87 | // | |
88 | // BeanDefinitionVisitor visitor = new PlaceholderResolvingBeanDefinitionVisitor(props); | |
89 | // String[] beanNames = beanFactoryToProcess.getBeanDefinitionNames(); | |
90 | // for (int i = 0; i < beanNames.length; i++) { | |
91 | // // Check that we're not parsing our own bean definition, | |
92 | // // to avoid failing on unresolvable placeholders in properties file locations. | |
93 | // if (!(beanNames[i].equals(this.beanName) && beanFactoryToProcess.equals(this.beanFactory))) { | |
94 | // BeanDefinition bd = beanFactoryToProcess.getBeanDefinition(beanNames[i]); | |
95 | // try { | |
96 | // visitor.visitBeanDefinition(bd); | |
97 | // } catch (BeanDefinitionStoreException ex) { | |
98 | // throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanNames[i], ex.getMessage()); | |
99 | // } | |
100 | // } | |
101 | // } | |
102 | // } | |
103 | // | |
104 | // /** | |
105 | // * BeanDefinitionVisitor that resolves placeholders in String values, delegating to the <code>parseStringValue</code> | |
106 | // * method of the containing class. | |
107 | // */ | |
108 | // public class PlaceholderResolvingBeanDefinitionVisitor extends RiceConfigBeanDefinitionVisitor { | |
109 | // | |
110 | // private final Properties props; | |
111 | // | |
112 | // public PlaceholderResolvingBeanDefinitionVisitor(Properties props) { | |
113 | // this.props = props; | |
114 | // } | |
115 | // | |
116 | // protected String resolveStringValue(String strVal) throws BeansException { | |
117 | // return parseStringValue(strVal, this.props, new HashSet()); | |
118 | // } | |
119 | // | |
120 | // public Properties resolvePropertiesValue(String strVal) { | |
121 | // Properties prefixedProps = new Properties(); | |
122 | // | |
123 | // for (Object key : props.keySet()) { | |
124 | // String keyStr = (String) key; | |
125 | // if (keyStr.startsWith(strVal)) { | |
126 | // String newKeyStr = keyStr.substring(strVal.length()); | |
127 | // prefixedProps.put(newKeyStr, resolveStringValue((String) props.get(key))); | |
128 | // } | |
129 | // } | |
130 | // | |
131 | // return prefixedProps; | |
132 | // } | |
133 | // } | |
134 | //------------------------------------------------------------------------------------ | |
135 | // end spring 2.0 compatible impl | |
136 | //------------------------------------------------------------------------------------ | |
137 | ||
138 | ||
139 | //------------------------------------------------------------------------------------ | |
140 | // begin spring 2.5 compatible impl | |
141 | //------------------------------------------------------------------------------------ | |
142 | ||
143 | // this has to be redeclared because private in the base with no getter | |
144 | private String nullValue; | |
145 | ||
146 | protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, Properties props) throws BeansException { | |
147 | ||
148 | 0 | StringValueResolver valueResolver = new PlaceholderResolvingStringValueResolver(props); |
149 | 0 | RiceConfigBeanDefinitionVisitor visitor = new RiceConfigBeanDefinitionVisitor(valueResolver); |
150 | ||
151 | 0 | String[] beanNames = beanFactoryToProcess.getBeanDefinitionNames(); |
152 | 0 | for (int i = 0; i < beanNames.length; i++) { |
153 | // Check that we're not parsing our own bean definition, | |
154 | // to avoid failing on unresolvable placeholders in properties file locations. | |
155 | 0 | if (!(beanNames[i].equals(this.beanName) && beanFactoryToProcess.equals(this.beanFactory))) { |
156 | 0 | BeanDefinition bd = beanFactoryToProcess.getBeanDefinition(beanNames[i]); |
157 | try { | |
158 | 0 | visitor.visitBeanDefinition(bd); |
159 | 0 | } catch (BeanDefinitionStoreException ex) { |
160 | 0 | throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanNames[i], ex.getMessage()); |
161 | 0 | } |
162 | } | |
163 | } | |
164 | ||
165 | // New in Spring 2.5: resolve placeholders in alias target names and aliases as well. | |
166 | 0 | beanFactoryToProcess.resolveAliases(valueResolver); |
167 | 0 | } |
168 | ||
169 | /** | |
170 | * BeanDefinitionVisitor that resolves placeholders in String values, delegating to the <code>parseStringValue</code> | |
171 | * method of the containing class. | |
172 | */ | |
173 | 0 | public class PlaceholderResolvingStringValueResolver implements StringValueResolver { |
174 | ||
175 | private final Properties props; | |
176 | ||
177 | 0 | public PlaceholderResolvingStringValueResolver(Properties props) { |
178 | 0 | this.props = props; |
179 | 0 | } |
180 | ||
181 | public String resolveStringValue(String strVal) throws BeansException { | |
182 | 0 | String value = parseStringValue(strVal, this.props, new HashSet<String>()); |
183 | 0 | return (value.equals(nullValue) ? null : value); |
184 | } | |
185 | ||
186 | public Properties resolvePropertiesValue(String strVal) { | |
187 | 0 | Properties prefixedProps = new Properties(); |
188 | ||
189 | 0 | for (Object key : props.keySet()) { |
190 | 0 | String keyStr = (String) key; |
191 | 0 | if (keyStr.startsWith(strVal)) { |
192 | 0 | String newKeyStr = keyStr.substring(strVal.length()); |
193 | 0 | prefixedProps.put(newKeyStr, resolveStringValue((String) props.get(key))); |
194 | } | |
195 | 0 | } |
196 | ||
197 | 0 | return prefixedProps; |
198 | } | |
199 | ||
200 | } | |
201 | ||
202 | @Override | |
203 | public void setNullValue(String nullValue) { | |
204 | 0 | this.nullValue = nullValue; |
205 | 0 | super.setNullValue(nullValue); |
206 | 0 | } |
207 | //------------------------------------------------------------------------------------ | |
208 | // end spring 2.5 compatible impl | |
209 | //------------------------------------------------------------------------------------ | |
210 | ||
211 | } |