001: /*
002: * $Id: BaseConfig.java 471754 2006-11-06 14:55:09Z husted $
003: *
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021: package org.apache.struts.config;
022:
023: import java.io.Serializable;
024:
025: import java.util.Enumeration;
026: import java.util.Properties;
027:
028: /**
029: * <p> A abstract base class for all config classes. Provide basic support
030: * for arbitrary properties </p>
031: *
032: * @since Struts 1.3
033: */
034: public abstract class BaseConfig implements Serializable {
035: /**
036: * Indicates if configuration of this component been completed. TODO
037: * change protected to private and use methods provided by extenders?
038: */
039: protected boolean configured = false;
040:
041: /**
042: * A map of arbitrary properties configured for this component.
043: *
044: * @since Struts 1.3
045: */
046: private Properties properties = new Properties();
047:
048: /**
049: * Freeze the configuration of this action.
050: */
051: public void freeze() {
052: configured = true;
053: }
054:
055: /**
056: * Throw <code>IllegalStateException</code> if configuration is frozen.
057: *
058: * @throws IllegalStateException if configuration is frozen
059: */
060: public void throwIfConfigured() {
061: if (configured) {
062: throw new IllegalStateException("Configuration is frozen");
063: }
064: }
065:
066: /**
067: * <p> Set an arbitary key/value pair which can be retrieved by this
068: * config class. This facility should eliminate many use cases for
069: * subclassing <code>*Config</code> classes by providing a mechanism to
070: * pass any amount of arbitrary configuration information into an config
071: * class. <p /> This method must not be called after configuration is
072: * complete, or an <code>IllegalStateException</code> will be thrown.</p>
073: *
074: * <p><b>Example</b>
075: * <code><pre>
076: * <action path="/example" type="com.example.MyAction">
077: * <set-property key="foo" property="bar" />
078: * </action>
079: * </pre></code>
080: * </p>
081: *
082: * @param key the key by which this value will be retrieved
083: * @param value the value to store with the supplied key
084: * @throws IllegalStateException if this module configuration has been
085: * frozen
086: * @since Struts 1.3
087: */
088: public void setProperty(String key, String value) {
089: throwIfConfigured();
090: properties.setProperty(key, value);
091: }
092:
093: /**
094: * Return the property-value for the specified key, if any; otherwise
095: * return <code>null</code>.
096: *
097: * @param key a key specified in the <code>struts-config</code> file
098: * @return the value stored with the supplied key
099: * @since Struts 1.3
100: */
101: public String getProperty(String key) {
102: return properties.getProperty(key);
103: }
104:
105: /**
106: * <p> Return the entire set of properties configured for this object. At
107: * this time, this only needs to be exposed to support inheritance, so
108: * choosing a conservative access modifier ("protected"). </p>
109: *
110: * @return set of properties configured for this object
111: */
112: protected Properties getProperties() {
113: return this .properties;
114: }
115:
116: /**
117: * Set the entire set of properties configured for this object. At this
118: * time, this only needs to be exposed to support inheritance, so choosing
119: * a conservative access modifier ("protected").
120: */
121: protected void setProperties(Properties properties) {
122: this .properties = properties;
123: }
124:
125: /**
126: * <p>Compare the properties of this config with that of the given and
127: * copy those that are not present. This method is used by subclasses
128: * that support configuration inheritance.</p>
129: *
130: * @param baseConfig The config object to copy properties from.
131: */
132: protected void inheritProperties(BaseConfig baseConfig) {
133: throwIfConfigured();
134:
135: // Inherit forward properties
136: Properties baseProperties = baseConfig.getProperties();
137: Enumeration keys = baseProperties.propertyNames();
138:
139: while (keys.hasMoreElements()) {
140: String key = (String) keys.nextElement();
141:
142: // Check if we have this property before copying it
143: String value = this .getProperty(key);
144:
145: if (value == null) {
146: value = baseProperties.getProperty(key);
147: setProperty(key, value);
148: }
149: }
150: }
151:
152: /**
153: * <p>Return a copy of the properties held by this object.</p>
154: */
155: protected Properties copyProperties() {
156: Properties copy = new Properties();
157:
158: Enumeration keys = properties.propertyNames();
159:
160: while (keys.hasMoreElements()) {
161: String key = (String) keys.nextElement();
162:
163: copy.setProperty(key, properties.getProperty(key));
164: }
165:
166: return copy;
167: }
168: }
|