View Javadoc

1   /*
2    * $Id: Settings.java 652734 2008-05-02 02:29:02Z mrdon $
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  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         // Locale processing has been moved to the LegacyPropertiesConfigurationProvider
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         // this is dumb.. maybe it should just throw an unsupported op like the rest of the *Impl
194         // methods in this class.
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             // Create bootstrap implementation
271             defaultImpl = new DefaultSettings();
272 
273             // Create default implementation
274             try {
275                 String className = get(StrutsConstants.STRUTS_CONFIGURATION);
276 
277                 if (!className.equals(defaultImpl.getClass().getName())) {
278                     try {
279                         // singleton instances shouldn't be built accessing request or session-specific context data
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                 // ignore
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 }