001: /**********************************************************************************
002: * $URL: https://source.sakaiproject.org/svn/component/tags/sakai_2-4-1/component-api/component/src/java/org/sakaiproject/util/PropertyOverrideConfigurer.java $
003: * $Id: PropertyOverrideConfigurer.java 6821 2006-03-21 18:34:36Z ggolden@umich.edu $
004: ***********************************************************************************
005: *
006: * Copyright (c) 2003, 2004, 2005, 2006 The Sakai Foundation.
007: *
008: * Licensed under the Educational Community License, Version 1.0 (the "License");
009: * you may not use this file except in compliance with the License.
010: * You may obtain a copy of the License at
011: *
012: * http://www.opensource.org/licenses/ecl1.php
013: *
014: * Unless required by applicable law or agreed to in writing, software
015: * distributed under the License is distributed on an "AS IS" BASIS,
016: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: * See the License for the specific language governing permissions and
018: * limitations under the License.
019: *
020: **********************************************************************************/
021:
022: /**********************************************************************************
023: * code modified from: org.springframework.beans.factory.config.PropertyOverrideConfigurer from Spring 1.1.5
024: *
025: * Copyright 2002-2004 the original author or authors.
026: *
027: * Licensed under the Apache License, Version 2.0 (the "License");
028: * you may not use this file except in compliance with the License.
029: * You may obtain a copy of the License at
030: *
031: * http://www.apache.org/licenses/LICENSE-2.0
032: *
033: * Unless required by applicable law or agreed to in writing, software
034: * distributed under the License is distributed on an "AS IS" BASIS,
035: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
036: * See the License for the specific language governing permissions and
037: * limitations under the License.
038: *
039: **********************************************************************************/package org.sakaiproject.util;
040:
041: import java.util.Collections;
042: import java.util.Enumeration;
043: import java.util.HashMap;
044: import java.util.HashSet;
045: import java.util.Map;
046: import java.util.Properties;
047: import java.util.Set;
048:
049: import org.apache.commons.logging.Log;
050: import org.apache.commons.logging.LogFactory;
051: import org.springframework.beans.BeansException;
052: import org.springframework.beans.factory.BeanInitializationException;
053: import org.springframework.beans.factory.config.BeanDefinition;
054: import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
055: import org.springframework.beans.factory.config.PropertyResourceConfigurer;
056:
057: /**
058: * <p>
059: * Sakai's extension to the Spring PropertyOverrideConfigurer - allow our dotted bean ids, use @ as a separator between the bean id and the property name.
060: * </p>
061: * <p>
062: * This could be an extension, just defining a new processKey(), but for the *private* members that the extension does not have access to...
063: * </p>
064: */
065: public class PropertyOverrideConfigurer extends
066: PropertyResourceConfigurer {
067: /** Our logger. */
068: private static Log M_log = LogFactory
069: .getLog(PropertyOverrideConfigurer.class);
070:
071: protected boolean ignoreInvalidKeys = false;
072:
073: /** Contains names of beans that have overrides */
074: protected Set beanNames = Collections
075: .synchronizedSet(new HashSet());
076:
077: /** Here are all the name=value entries we read in. */
078: protected Map m_entries = new HashMap();
079:
080: /**
081: * Access the value of the entry with this name key
082: *
083: * @param name
084: * The key to search for.
085: * @return The value for this key, or null if not defined.
086: */
087: public String getValue(String name) {
088: return (String) m_entries.get(name);
089: }
090:
091: /**
092: * Set whether to ignore invalid keys. Default is false.
093: * <p>
094: * If you ignore invalid keys, keys that do not follow the 'beanName.property' format will just be logged as warning. This allows to have arbitrary other keys in a properties file.
095: */
096: public void setIgnoreInvalidKeys(boolean ignoreInvalidKeys) {
097: this .ignoreInvalidKeys = ignoreInvalidKeys;
098: }
099:
100: protected void processProperties(
101: ConfigurableListableBeanFactory beanFactory,
102: Properties props) throws BeansException {
103: for (Enumeration en = props.propertyNames(); en
104: .hasMoreElements();) {
105: String key = (String) en.nextElement();
106:
107: String value = props.getProperty(key);
108: m_entries.put(key, value);
109:
110: try {
111: processKey(beanFactory, key, value);
112: } catch (BeansException ex) {
113: // String msg = "Could not process key [" + key + "] in PropertyOverrideConfigurer";
114: // if (this.ignoreInvalidKeys)
115: // {
116: // if (M_log.isDebugEnabled())
117: // {
118: // M_log.debug(msg + ": " + ex.getMessage());
119: // }
120: // else if (M_log.isWarnEnabled())
121: // {
122: // M_log.warn(msg + ": " + ex.getMessage());
123: // }
124: // }
125: // else
126: // {
127: // throw new BeanInitializationException(msg, ex);
128: // }
129: }
130: }
131: }
132:
133: /**
134: * Process the given key as 'beanName@property' entry.
135: */
136: protected void processKey(ConfigurableListableBeanFactory factory,
137: String key, String value) throws BeansException {
138: int atIndex = key.indexOf('@');
139: if (atIndex == -1) {
140: throw new BeanInitializationException("Invalid key [" + key
141: + "]: expected 'property@beanName'");
142: }
143: String beanProperty = key.substring(0, atIndex);
144: String beanName = key.substring(atIndex + 1);
145: this .beanNames.add(beanName);
146: applyPropertyValue(factory, beanName, beanProperty, value);
147: if (M_log.isDebugEnabled()) {
148: // if there's a password in the key, let's not display the value
149: if (key.indexOf("password") != -1) {
150: M_log.debug("Property '" + key + "' set to [***]");
151: } else {
152: M_log.debug("Property '" + key + "' set to [" + value
153: + "]");
154: }
155: }
156: }
157:
158: /**
159: * Apply the given property value to the corresponding bean.
160: */
161: protected void applyPropertyValue(
162: ConfigurableListableBeanFactory factory, String beanName,
163: String property, String value) {
164: BeanDefinition bd = factory.getBeanDefinition(beanName);
165: bd.getPropertyValues().addPropertyValue(property, value);
166: }
167:
168: /**
169: * Were there overrides for this bean? Only valid after processing has occurred at least once.
170: *
171: * @param beanName
172: * name of the bean to query status for
173: * @return whether there were property overrides for the named bean
174: */
175: public boolean hasPropertyOverridesFor(String beanName) {
176: return this.beanNames.contains(beanName);
177: }
178: }
|