View Javadoc
1   /*
2    * $Id$
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      private static final long serialVersionUID = 7059240587081363820L;
36  
37      /**
38       * Indicates if configuration of this component been completed. TODO
39       * change protected to private and use methods provided by extenders?
40       */
41      protected boolean configured = false;
42  
43      /**
44       * A map of arbitrary properties configured for this component.
45       *
46       * @since Struts 1.3
47       */
48      private Properties properties = new Properties();
49  
50      /**
51       * Freeze the configuration of this action.
52       */
53      public void freeze() {
54          configured = true;
55      }
56  
57      /**
58       * Throw <code>IllegalStateException</code> if configuration is frozen.
59       *
60       * @throws IllegalStateException if configuration is frozen
61       */
62      public void throwIfConfigured() {
63          if (configured) {
64              throw new IllegalStateException("Configuration is frozen");
65          }
66      }
67  
68      /**
69       * <p> Set an arbitary key/value pair which can be retrieved by this
70       * config class. This facility should eliminate many use cases for
71       * subclassing <code>*Config</code> classes by providing a mechanism to
72       * pass any amount of arbitrary configuration information into an config
73       * class. <p /> This method must not be called after configuration is
74       * complete, or an <code>IllegalStateException</code> will be thrown.</p>
75       *
76       * <p><b>Example</b>
77       * <code><pre>
78       * &lt;action path="/example" type="com.example.MyAction"&gt;
79       *    &lt;set-property key="foo" property="bar" /&gt;
80       * &lt;/action&gt;
81       * </pre></code>
82       * </p>
83       *
84       * @param key   the key by which this value will be retrieved
85       * @param value the value to store with the supplied key
86       * @throws IllegalStateException if this module configuration has been
87       *                               frozen
88       * @since Struts 1.3
89       */
90      public void setProperty(String key, String value) {
91          throwIfConfigured();
92          properties.setProperty(key, value);
93      }
94  
95      /**
96       * Return the property-value for the specified key, if any; otherwise
97       * return <code>null</code>.
98       *
99       * @param key a key specified in the <code>struts-config</code> file
100      * @return the value stored with the supplied key
101      * @since Struts 1.3
102      */
103     public String getProperty(String key) {
104         return properties.getProperty(key);
105     }
106 
107     /**
108      * <p> Return the entire set of properties configured for this object. At
109      * this time, this only needs to be exposed to support inheritance, so
110      * choosing a conservative access modifier ("protected"). </p>
111      *
112      * @return set of properties configured for this object
113      */
114     protected Properties getProperties() {
115         return this.properties;
116     }
117 
118     /**
119      * Set the entire set of properties configured for this object. At this
120      * time, this only needs to be exposed to support inheritance, so choosing
121      * a conservative access modifier ("protected").
122      */
123     protected void setProperties(Properties properties) {
124         this.properties = properties;
125     }
126 
127     /**
128      * <p>Compare the properties of this config with that of the given and
129      * copy those that are not present.  This method is used by subclasses
130      * that support configuration inheritance.</p>
131      *
132      * @param baseConfig The config object to copy properties from.
133      */
134     protected void inheritProperties(BaseConfig baseConfig) {
135         throwIfConfigured();
136 
137         // Inherit forward properties
138         Properties baseProperties = baseConfig.getProperties();
139         Enumeration<?> keys = baseProperties.propertyNames();
140 
141         while (keys.hasMoreElements()) {
142             String key = (String) keys.nextElement();
143 
144             // Check if we have this property before copying it
145             String value = this.getProperty(key);
146 
147             if (value == null) {
148                 value = baseProperties.getProperty(key);
149                 setProperty(key, value);
150             }
151         }
152     }
153 
154     /**
155      * <p>Return a copy of the properties held by this object.</p>
156      */
157     protected Properties copyProperties() {
158         Properties copy = new Properties();
159 
160         Enumeration<?> keys = properties.propertyNames();
161 
162         while (keys.hasMoreElements()) {
163             String key = (String) keys.nextElement();
164 
165             copy.setProperty(key, properties.getProperty(key));
166         }
167 
168         return copy;
169     }
170 }