1 /*
2 * $Id: BaseConfig.java 471754 2006-11-06 14:55:09Z husted $
3 *
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
19 * under the License.
20 */
21 package org.apache.struts.config;
22
23 import java.io.Serializable;
24
25 import java.util.Enumeration;
26 import java.util.Properties;
27
28 /**
29 * <p> A abstract base class for all config classes. Provide basic support
30 * for arbitrary properties </p>
31 *
32 * @since Struts 1.3
33 */
34 public abstract class BaseConfig implements Serializable {
35 /**
36 * Indicates if configuration of this component been completed. TODO
37 * change protected to private and use methods provided by extenders?
38 */
39 protected boolean configured = false;
40
41 /**
42 * A map of arbitrary properties configured for this component.
43 *
44 * @since Struts 1.3
45 */
46 private Properties properties = new Properties();
47
48 /**
49 * Freeze the configuration of this action.
50 */
51 public void freeze() {
52 configured = true;
53 }
54
55 /**
56 * Throw <code>IllegalStateException</code> if configuration is frozen.
57 *
58 * @throws IllegalStateException if configuration is frozen
59 */
60 public void throwIfConfigured() {
61 if (configured) {
62 throw new IllegalStateException("Configuration is frozen");
63 }
64 }
65
66 /**
67 * <p> Set an arbitary key/value pair which can be retrieved by this
68 * config class. This facility should eliminate many use cases for
69 * subclassing <code>*Config</code> classes by providing a mechanism to
70 * pass any amount of arbitrary configuration information into an config
71 * class. <p /> This method must not be called after configuration is
72 * complete, or an <code>IllegalStateException</code> will be thrown.</p>
73 *
74 * <p><b>Example</b>
75 * <code><pre>
76 * <action path="/example" type="com.example.MyAction">
77 * <set-property key="foo" property="bar" />
78 * </action>
79 * </pre></code>
80 * </p>
81 *
82 * @param key the key by which this value will be retrieved
83 * @param value the value to store with the supplied key
84 * @throws IllegalStateException if this module configuration has been
85 * frozen
86 * @since Struts 1.3
87 */
88 public void setProperty(String key, String value) {
89 throwIfConfigured();
90 properties.setProperty(key, value);
91 }
92
93 /**
94 * Return the property-value for the specified key, if any; otherwise
95 * return <code>null</code>.
96 *
97 * @param key a key specified in the <code>struts-config</code> file
98 * @return the value stored with the supplied key
99 * @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 }