1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.apache.struts2.config;
23
24 import java.util.Iterator;
25 import java.util.Locale;
26 import java.util.StringTokenizer;
27
28 import org.apache.struts2.StrutsConstants;
29
30 import com.opensymphony.xwork2.ObjectFactory;
31 import com.opensymphony.xwork2.util.location.Location;
32 import com.opensymphony.xwork2.util.logging.Logger;
33 import com.opensymphony.xwork2.util.logging.LoggerFactory;
34
35
36 /***
37 * Settings retrieves and exposes default values used by the framework.
38 * An application can override a factory default and provide its own value for a setting.
39 * <p>
40 * Implementation of the class is pluggable (the default implementation is {@link DefaultSettings}).
41 * Pluggability gives applications to ability to customize how settings are retrieved.
42 * As an example, an application may wish to check some custom property store
43 * before delegating to the usual configuration and property files.
44 * <p>
45 * Key methods:
46 * <ul>
47 * <li>{@link #getLocale()}</li>
48 * <li>{@link #get(String)}</li>
49 * <li>{@link #set(String, String)}</li>
50 * <li>{@link #list()}</li>
51 * </ul>
52 * <p>
53 * Key methods for subclasses (plugins):
54 * <ul>
55 * <li>{@link #getImpl(String)}</li>
56 * <li>{@link #setImpl(String, String)}</li>
57 * <li>{@link #listImpl()}</li>
58 * <li>{@link #isSetImpl(String)}</li>
59 * </ul>
60 * @deprecated Since Struts 2.1.2
61 */
62 class Settings {
63
64
65 /***
66 * A pluggable implementation of Settings,
67 * provided through the {@link #setInstance} method.
68 */
69 static Settings settingsImpl;
70
71 /***
72 * An instance of {@link DefaultSettings}
73 * to use when another implementation is not provided (plugged in).
74 */
75 static Settings defaultImpl;
76
77 /***
78 * An instance of the default locale as specified by the <code>struts.locale</code> setting.
79 *
80 * @see #getLocale
81 */
82 static Locale locale;
83
84 /***
85 * The Logging instance for this class.
86 */
87 private static final Logger LOG = LoggerFactory.getLogger(Settings.class);
88
89 /***
90 * Registers a custom Settings implementation (plugin),
91 * and resets the cached locale.
92 * <p>
93 * This method can only be called once.
94 *
95 * @param config a Settings implementation
96 * @throws IllegalStateException if an error occurs when setting the settings implementation.
97 */
98 public static void setInstance(Settings config) throws IllegalStateException {
99 settingsImpl = config;
100 locale = null;
101 }
102
103 /***
104 * Provides the Settings object.
105 * <p>
106 * This method will substitute the default instance if another instance is not registered.
107 *
108 * @return the Settings object.
109 */
110 public static Settings getInstance() {
111 return (settingsImpl == null) ? getDefaultInstance() : settingsImpl;
112 }
113
114 /***
115 * Provides the Struts default locale.
116 * <p>
117 * This method utilizes the <code>struts.locale</code> setting, which should be given
118 * as the Java {@link java.util.Locale#toString() toString()} representation of a Locale object
119 * ("en", "de_DE", "_GB", "en_US_WIN", "de__POSIX", "fr_MAC", and so forth).
120 * <p>
121 * If a <code>struts.locale</code> setting is not registered,
122 * then the default virtual machine locale is substituted and cached.
123 *
124 * @return the Struts default locale if specified or the VM default locale.
125 * @see java.util.Locale#getDefault()
126 */
127 public static Locale getLocale() {
128
129
130 return locale;
131 }
132
133 /***
134 * Determines whether or not a setting has a registered value.
135 * <p>
136 * This method is useful for testing for the existance of setting without
137 * throwing an IllegalArgumentException.
138 *
139 * @param name the name of a setting to test.
140 * @return <code>true</code> if the setting exists and has a value, <code>false</code> otherwise.
141 */
142 public static boolean isSet(String name) {
143 return getInstance().isSetImpl(name);
144 }
145
146 /***
147 * Provides a setting value as a String.
148 * <p>
149 * The method will throw an <code>IllegalArgumentException</code> if an error occurs
150 * while retrieveing the property or if the property doesn't exist.
151 *
152 * @param name the name of the setting to retrieve.
153 * @return the setting value as a String.
154 * @throws IllegalArgumentException if an error occurs retrieving the property or the property does not exist.
155 */
156 public static String get(String name) throws IllegalArgumentException {
157 return getInstance().getImpl(name);
158 }
159
160 /***
161 * Provides the Location of a setting.
162 * <p>
163 * The Location is utilized as part of precise error reporting.
164 * <p>
165 * This method will throw an <code>IllegalArgumentException</code> if an error occurs
166 * while retrieving the value or if the setting doesn't exist.
167 *
168 * @param name the name of the property to get.
169 * @return the Location of a property.
170 * @throws IllegalArgumentException if an error occurs retrieving the property or the property does not exist.
171 */
172 public static Location getLocation(String name) throws IllegalArgumentException {
173 return getInstance().getLocationImpl(name);
174 }
175
176 /***
177 * Provides an Iterator of all properties names.
178 *
179 * @return an Iterator of all properties names.
180 */
181 public static Iterator list() {
182 return getInstance().listImpl();
183 }
184
185 /***
186 * Implements the {@link #isSet(String)} method.
187 *
188 * @param name Identifier for the setting value to change
189 * @return True if the setting exists and has a value, false otherwise.
190 * @see #isSet(String)
191 */
192 public boolean isSetImpl(String name) {
193
194
195 return false;
196 }
197
198 /***
199 * Registers a value for a setting.
200 * <p>
201 * This method raises an exception if an error occurs when setting the value or if the
202 * settings implementation does not support setting values.
203 *
204 * @param name the name of the setting.
205 * @param value the value to register for the setting.
206 * @throws IllegalArgumentException if an error occurs when setting the value.
207 * @throws UnsupportedOperationException if the config implementation does not support setting values.
208 */
209 public static void set(String name, String value) throws IllegalArgumentException, UnsupportedOperationException {
210 getInstance().setImpl(name, value);
211 }
212
213 /***
214 * Implements the {@link #set(String, String)} method.
215 *
216 * @param name Identifer for the setting to change.
217 * @param value The new value for the setting.
218 * @throws IllegalArgumentException if an error occurs when setting the value.
219 * @throws UnsupportedOperationException if the config implementation does not support setting values.
220 * @see #set(String, String)
221 */
222 public void setImpl(String name, String value) throws IllegalArgumentException, UnsupportedOperationException {
223 throw new UnsupportedOperationException("Settings: This implementation does not support setting a value.");
224 }
225
226 /***
227 * Implements the {@link #get(String)} method.
228 *
229 * @param name The name of the setting value to retreive
230 * @return The setting value as a String
231 * @throws IllegalArgumentException if an error occurs when retrieving the value
232 * @see #get(String)
233 */
234 public String getImpl(String name) throws IllegalArgumentException {
235 return null;
236 }
237
238 /***
239 * Implements the {@link #getLocation(String)} method.
240 *
241 * @param name Name of the setting to locate
242 * @return The location of the setting
243 * @throws IllegalArgumentException if an error occurs when retrieving the value
244 * @see #getLocation(String)
245 */
246 public Location getLocationImpl(String name) throws IllegalArgumentException {
247 return null;
248 }
249
250 /***
251 * Implements the {@link #list()} method.
252 *
253 * @see #list()
254 * @return A list of the settings as an iterator
255 */
256 public Iterator listImpl() {
257 throw new UnsupportedOperationException("Settings: This implementation does not support listing the registered settings");
258 }
259
260 /***
261 * Creates a default Settings object.
262 * <p>
263 * A default implementation may be specified by the <code>struts.configuration</code> setting;
264 * otherwise, this method instantiates {@link DefaultSettings} as the default implementation.
265 *
266 * @return A default Settings object.
267 */
268 private static Settings getDefaultInstance() {
269 if (defaultImpl == null) {
270
271 defaultImpl = new DefaultSettings();
272
273
274 try {
275 String className = get(StrutsConstants.STRUTS_CONFIGURATION);
276
277 if (!className.equals(defaultImpl.getClass().getName())) {
278 try {
279
280 defaultImpl = (Settings) ObjectFactory.getObjectFactory().buildBean(Thread.currentThread().getContextClassLoader().loadClass(className), null);
281 } catch (Exception e) {
282 LOG.error("Settings: Could not instantiate the struts.configuration object, substituting the default implementation.", e);
283 }
284 }
285 } catch (IllegalArgumentException ex) {
286
287 }
288 }
289
290 return defaultImpl;
291 }
292
293 /***
294 * Resets the default and any plugin Setting instance to null.
295 */
296 public static void reset() {
297 defaultImpl = null;
298 settingsImpl = null;
299 }
300 }