View Javadoc
1   package org.apache.commons.jcs.utils.props;
2   
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  
22  import org.apache.commons.jcs.access.exception.ConfigurationException;
23  
24  import java.util.Properties;
25  
26  /**
27   * Provides a mechanism to load properties into objects.
28   * <p>
29   * Functions that depend on properties should call ensureProperties() before it uses any properties.
30   */
31  public abstract class AbstractPropertyContainer
32  {
33      /** File, db, etc */
34      private static final PropertiesFactory DEFAULT_PROPERTIES_FACTORY = new PropertiesFactoryFileImpl();
35  
36      /**
37       * A property group is a subsection of properties. It's sent to the properties factory to
38       * specify which group of properties to pull back. This will probably mean different things to
39       * different property factories. For PropertiesFactoryFileImpl, the propertiesGroup maps to a
40       * filename.
41       */
42      private String propertiesGroup;
43  
44      /**
45       * The property heading is used to specify a starting point in the properties object. This is
46       * used so that settings can be relative to this propertiesHeading, as opposed to being
47       * statically coded. There's no enforcement of this, but users are encouraged to call
48       * getProperties().get( getPropertiesHeading() + ".foo" );
49       */
50      private String propertiesHeading;
51  
52      /** The factory to use. */
53      private PropertiesFactory propertiesFactory;
54  
55      /** The loaded properties. */
56      private Properties properties;
57  
58      /**
59       * Makes sure an AbstractPropertyClass has all the properties it needs.
60       * <p>
61       * Synchronized mutators so multiple threads cannot cause problems. We wouldn't want the
62       * properties heading to get changed as we were processing the properties.
63       * <p>
64       * @throws ConfigurationException on configuration failure
65       */
66      public synchronized void ensureProperties()
67          throws ConfigurationException
68      {
69          if ( getProperties() == null )
70          {
71              initializeProperties();
72          }
73      }
74  
75      /**
76       * Loads the properties and then calls handleProperties. Typically, you don't need to call this.
77       * This is primarily intended for reinitialization.
78       * <p>
79       * If the properties object is null, when you call ensureProperties initialize will be called.
80       * <p>
81       * @throws ConfigurationException on configuration failure
82       */
83      public synchronized void initializeProperties()
84          throws ConfigurationException
85      {
86          loadProperties();
87  
88          handleProperties();
89      }
90  
91      /**
92       * This loads the properties regardless of whether or not they have already been loaded.
93       * <p>
94       * @throws ConfigurationException on configuration failure
95       */
96      private void loadProperties()
97          throws ConfigurationException
98      {
99          if ( getPropertiesGroup() == null )
100         {
101             throw new ConfigurationException( "Properties group is null and it shouldn't be" );
102         }
103 
104         if ( getPropertiesHeading() == null )
105         {
106             throw new ConfigurationException( "Properties heading is null and it shouldn't be" );
107         }
108 
109         if ( getPropertiesFactory() == null )
110         {
111             setProperties( DEFAULT_PROPERTIES_FACTORY.getProperties( getPropertiesGroup() ) );
112         }
113         else
114         {
115             setProperties( getPropertiesFactory().getProperties( getPropertiesGroup() ) );
116         }
117     }
118 
119     /**
120      * Sets fields for properties, and verifies that all necessary properties are there.
121      * <p>
122      * @throws ConfigurationException on configuration failure
123      */
124     protected abstract void handleProperties()
125         throws ConfigurationException;
126 
127     /**
128      * @return Returns the properties.
129      */
130     public synchronized Properties getProperties()
131     {
132         return properties;
133     }
134 
135     /**
136      * @param properties The properties to set.
137      */
138     public synchronized void setProperties( Properties properties )
139     {
140         this.properties = properties;
141     }
142 
143     /**
144      * @return Returns the propertiesHeading.
145      */
146     public synchronized String getPropertiesHeading()
147     {
148         return propertiesHeading;
149     }
150 
151     /**
152      * @param propertiesHeading The propertiesHeading to set.
153      */
154     public synchronized void setPropertiesHeading( String propertiesHeading )
155     {
156         this.propertiesHeading = propertiesHeading;
157     }
158 
159     /**
160      * @return Returns the propertiesFactory.
161      */
162     public PropertiesFactory getPropertiesFactory()
163     {
164         return propertiesFactory;
165     }
166 
167     /**
168      * @param propertiesFactory The propertiesFactory to set.
169      */
170     public void setPropertiesFactory( PropertiesFactory propertiesFactory )
171     {
172         this.propertiesFactory = propertiesFactory;
173     }
174 
175     /**
176      * @return Returns the propertiesGroup.
177      */
178     public String getPropertiesGroup()
179     {
180         return propertiesGroup;
181     }
182 
183     /**
184      * @param propertiesGroup The propertiesGroup to set.
185      */
186     public void setPropertiesGroup( String propertiesGroup )
187     {
188         this.propertiesGroup = propertiesGroup;
189     }
190 }