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 }