KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > uitags > tagutil > TaglibProperties


1 /**
2  * Nov 12, 2004
3  *
4  * Copyright 2004 uitags
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18 package net.sf.uitags.tagutil;
19
20 import java.io.IOException JavaDoc;
21 import java.util.Enumeration JavaDoc;
22 import java.util.MissingResourceException JavaDoc;
23 import java.util.Properties JavaDoc;
24 import java.util.ResourceBundle JavaDoc;
25
26
27 import net.sf.uitags.util.ArrayUtils;
28 import net.sf.uitags.util.PropertiesLoadingException;
29 import net.sf.uitags.util.StringUtils;
30
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogFactory;
33
34 /**
35  * Configuration properties for the taglib. There are 3 types of properties,
36  * listed here in order of loading sequence (last one loaded wins):
37  * <ol>
38  * <li>The <i>factory-default</i> properties are part of the taglib.
39  * These configuration entries are <i>overridden</i> if they are
40  * also defined in the property file described below.</li>
41  * <li>The <i>site-wide properties</i> file (uitags.properties)
42  * contains site-wide configuration, overriding the factory-default
43  * properties. Configuration entries in this file affect all tags which
44  * do not define their own run-time properties. This file is optional.
45  * </li>
46  * <li>The <i>run-time properties</i> are not set in any file. A run-time
47  * property is specified in the JSP as a tag attribute. The
48  * executing tag handler <i>has</i> to pass run-time properties'
49  * values to
50  * {@link TaglibProperties#setRuntimeProperty(String, String)}.
51  * This allows handlers which subsequently retrieve properties
52  * from the <code>TaglibProperties</code> instance see the
53  * overriding values.</li>
54  * </ol>
55  *
56  * @author jonni
57  * @version $Id: TaglibProperties.java,v 1.6 2006/07/28 11:41:20 jonni Exp $
58  */

59 public class TaglibProperties {
60   ///////////////////////////////
61
////////// Constants //////////
62
///////////////////////////////
63

64   /**
65    * Name of the factory-default properties file
66    */

67   private static final String JavaDoc FACTORY_DEFAULT = "factory-default.properties";
68   /**
69    * Path to the site-wide properties file
70    */

71   private static final String JavaDoc SITE_WIDE = "uitags";
72
73
74
75   ////////////////////////////
76
////////// Fields //////////
77
////////////////////////////
78

79   /**
80    * Logger
81    */

82   private static Log log = LogFactory.getLog(TaglibProperties.class);
83
84   /**
85    * Contains entries from the factory-default properties, overriden by the
86    * ones from the site-wide properties.
87    */

88   private static Properties JavaDoc mergedProps = new Properties JavaDoc();
89
90   /**
91    * An immutable version of the merged properties. The purpose of this variable
92    * is to allow utility classes access properties whose value always remain
93    * constant (never changes due to overriding).
94    */

95   public static final TaglibProperties MERGED;
96
97   /**
98    * The runtime properties, those that are defined in JSP. Entries in this
99    * object shadow those that are in "mergedProps".
100    */

101   private Properties JavaDoc runtimeProps;
102
103
104
105   /////////////////////////////////////////////////////
106
////////// Construction and initialization //////////
107
/////////////////////////////////////////////////////
108

109   /**
110    * Loads the factory-default and site-wide properties.
111    *
112    * @throws PropertiesLoadingException if failed to load the
113    * factory-default properties
114    */

115   static {
116     // Load the factory-default properties
117
try {
118       mergedProps.load(
119           TaglibProperties.class.getResourceAsStream(FACTORY_DEFAULT));
120     }
121     catch (IOException JavaDoc e) {
122       throw new PropertiesLoadingException(e, FACTORY_DEFAULT);
123     }
124
125     // Load the site-wide properties. It's OK if it's not provided.
126
ResourceBundle JavaDoc rb = null;
127     try {
128       rb = ResourceBundle.getBundle(SITE_WIDE);
129       // Exception would have been thrown here if not found
130
Enumeration JavaDoc keys = rb.getKeys();
131       while (keys.hasMoreElements()) {
132         String JavaDoc key = (String JavaDoc) keys.nextElement();
133         mergedProps.setProperty(key, rb.getString(key));
134       }
135     }
136     catch (MissingResourceException JavaDoc e) {
137       if (log.isDebugEnabled()) {
138         log.debug("Properties file '" + SITE_WIDE + "' not found.");
139       }
140     }
141
142     if (log.isDebugEnabled()) {
143       log.debug("Taglib properties loaded: " + mergedProps);
144     }
145
146     // An immutable version of the merged properties
147
MERGED = new TaglibProperties() {
148       public void setRuntimeProperty(String JavaDoc key, String JavaDoc value) {
149         throw new IllegalStateException JavaDoc("Object is immutable.");
150       }
151     };
152   }
153
154   /**
155    * Made private to allow for limited subclassing.
156    */

157   private TaglibProperties() {
158     this.runtimeProps = new Properties JavaDoc();
159   }
160
161   /**
162    * Creates an instance whose entries can be safely overriden without
163    * affecting other instances.
164    *
165    * @return an new instance
166    */

167   public static TaglibProperties getInstance() {
168     return new TaglibProperties();
169   }
170
171
172
173   /////////////////////////////////////////////////
174
////////// Used by this class' clients //////////
175
/////////////////////////////////////////////////
176

177   /**
178    * Sets a runtime property, overriding the corresponding property
179    * configured in the factory-default and site-wide properties files.
180    * If the supplied <code>value</code> is <code>null</code> nothing is
181    * done.
182    *
183    * @param key the key of the property to set
184    * @param value the value of the property to set
185    */

186   public void setRuntimeProperty(String JavaDoc key, String JavaDoc value) {
187     if (value == null) {
188       return;
189     }
190     this.runtimeProps.setProperty(key, value);
191   }
192
193   /**
194    * Returns the value of the property whose key is supplied.
195    *
196    * @param key the key of the property to return
197    * @return the property as <code>String</code>. If value is
198    * <code>null</code>, an empty string is returned instead.
199    */

200   public String JavaDoc get(String JavaDoc key) {
201     // A runtime property is given higher priority.
202
String JavaDoc ret = this.runtimeProps.getProperty(key);
203
204     // If it's not a runtime property, try loading it from the factory-default
205
// or site-wide configuration.
206
if (ret == null) {
207       ret = mergedProps.getProperty(key);
208     }
209
210     if (ret == null) {
211       throw new IllegalStateException JavaDoc(
212           "Property with key '" + key + "' is not set");
213     }
214     return ret;
215   }
216
217   public void setRuntimeProperty(String JavaDoc key, String JavaDoc[] values) {
218     if (values == null) {
219       return;
220     }
221     this.runtimeProps.setProperty(key, StringUtils.join(values));
222   }
223
224   public String JavaDoc[] getAsArray(String JavaDoc key) {
225     String JavaDoc stringValue = get(key);
226     return ArrayUtils.toArray(stringValue);
227   }
228 }
229
Popular Tags