/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.riotfamily.common.beans.config;
import java.util.Enumeration;
import java.util.Properties;
import org.springframework.beans.propertyeditors.PropertiesEditor;
import org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer;
/**
* PropertyPlaceholderConfigurer that accepts wildcards to populate properties
* that expect a java.util.Properties value.
* <p>
* Example:
* <pre>
* <bean class="org.riotfamily.common.hibernate.RiotSessionFactoryBean">
* <property name="hibernateProperties" value="${riot.(hibernate.*)}" />
* </bean>
* </pre>
*
* The configurer will look for all properties start start with
* '<code>riot.hibernate.</code>'. So having a properties file like this ...
*
* <pre>
* riot.hibernate.cache.use_query_cache = true
* riot.hibernate.show_sql = false
* </pre>
*
* ... would be equivalent to writing:
* <pre>
* <bean class="org.riotfamily.common.hibernate.RiotSessionFactoryBean">
* <property name="hibernateProperties">
* <value>
* hibernate.cache.use_query_cache = true
* hibernate.show_sql = false
* </value>
* </property>
* </bean>
* </pre>
*
* Spring's {@link PropertiesEditor} will then take care of converting the
* String value into a <code>java.util.Properties</code> object.
*
* <p>
* Since Riot 9.0, the placeholder may contain parenthesis to indicate that
* a part of the placeholder should be included in the resulting keys.
* For example the placeholder <code>${riot.(hibernate.*)}</code> will result
* in keys that all start with <code>"hibernate."</code>. If the parenthesis
* were omitted, only the part matched by the asterisk would be used as key.
*
* @author Felix Gnass [fgnass at neteye dot de]
* @since 6.4
*/
public class PropertiesPlaceholderConfigurer extends
ServletContextPropertyPlaceholderConfigurer {
protected String resolvePlaceholder(String placeholder, Properties props) {
int i = placeholder.indexOf('*');
if (i != -1) {
return resolveAll(props, placeholder.substring(0, i));
}
return super.resolvePlaceholder(placeholder, props);
}
protected String resolveAll(Properties props, String match) {
String prefix = match;
int i = match.indexOf('(');
if (i != -1) {
if (i > match.length()-1) {
prefix = match.substring(i + 1);
}
else {
prefix = "";
}
match = match.substring(0, i) + prefix;
}
StringBuffer sb = new StringBuffer();
Enumeration<?> names = props.propertyNames();
while (names.hasMoreElements()) {
String name = (String) names.nextElement();
if (name.startsWith(match) && name.length() > match.length()) {
sb.append(prefix);
sb.append(name.substring(match.length()));
sb.append('=');
sb.append(props.getProperty(name));
sb.append('\n');
}
}
return sb.toString();
}
}