2009/05/20 - Apache Shale has been retired.

For more information, please explore the Attic.

View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to you under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.shale.validator.util;
19  
20  import java.text.MessageFormat;
21  import java.util.Locale;
22  import java.util.MissingResourceException;
23  import java.util.ResourceBundle;
24  import javax.faces.component.StateHolder;
25  import javax.faces.context.FacesContext;
26  
27  /***
28   * <p>Abstract base class for converters and validators that use Apache Commons
29   * Validator as their foundation.  This class provides common utility methods
30   * for concrete converter and validator implementations.</p>
31   */
32  public abstract class AbstractUtilities implements StateHolder {
33  
34  
35      // ------------------------------------------------------------ Constructors
36  
37  
38      // ------------------------------------------------------ Manifest Constants
39  
40  
41      /***
42       * <p>Name of the resource bundle containing default message strings.</p>
43       */
44      public static final String DEFAULT_RESOURCE_BUNDLE =
45              "org.apache.shale.validator.resources.Bundle";
46  
47  
48      // -------------------------------------------------------------- Properties
49  
50  
51      /***
52       * <p>Custom error message template, if any.</p>
53       */
54      private String message = null;
55  
56  
57      /***
58       * <p>Return the custom error message template for this converter or
59       * validator, if any.  If not defined, a standard error message template
60       * will be used instead.</p>
61       */
62      public String getMessage() {
63          return this.message;
64      }
65  
66  
67      /***
68       * <p>Set the custom error message template for this validator.</p>
69       *
70       * @param message The new custom error message template, or <code>null</code>
71       *  to select the standard template
72       */
73      public void setMessage(String message) {
74          this.message = message;
75      }
76  
77  
78      // ----------------------------------------------------- StateHolder Methods
79  
80  
81      /*** {@inheritDoc} */
82      public void restoreState(FacesContext context, Object state) {
83          Object[] values = (Object[]) state;
84          this.message = (String) values[0];
85      }
86  
87  
88      /*** {@inheritDoc} */
89      public Object saveState(FacesContext context) {
90          Object[] values = new Object[1];
91          values[1] = this.message;
92          return values;
93      }
94  
95  
96      private boolean transientValue = false;
97  
98  
99      /*** {@inheritDoc} */
100     public boolean isTransient() {
101         return this.transientValue;
102     }
103 
104 
105     /*** {@inheritDoc} */
106     public void setTransient(boolean transientValue) {
107         this.transientValue = transientValue;
108     }
109 
110 
111     // ---------------------------------------------------------- Object Methods
112 
113 
114     // ------------------------------------------------------- Protected Methods
115 
116 
117     /***
118      * <p>Return a locale-sensitive message for this converter or
119      * validator.  The following algorithm is applied to select the
120      * appropriate message:</p>
121      * <ul>
122      * <li>If the <code>message</code> property has been set, use
123      *     that value explicitly</li>
124      * <li>If the application specifies a message resource bundle,
125      *     and this resource bundle includes a value for the specified
126      *     key, use that value</li>
127      * <li>If the default message resource bundle for this module
128      *     includes a value for the specified key, use that value</li>
129      * <li>Create and return a dummy value</li>
130      * </ul>
131      *
132      * @param context <code>FaceContext</code> for the current request
133      * @param key Message key for the requested message
134      */
135     protected String message(FacesContext context, String key) {
136 
137         // Return any explicitly specified message
138         String message = getMessage();
139         if (message != null) {
140             return message;
141         }
142 
143         // Set up variables we will need
144         ResourceBundle bundle = null;
145         Locale locale = context.getViewRoot().getLocale();
146         ClassLoader loader = Thread.currentThread().getContextClassLoader();
147 
148         // Search for a match in the application resource bundle (if any)
149         String name = context.getApplication().getMessageBundle();
150         if (name != null) {
151             bundle = ResourceBundle.getBundle(name, locale, loader);
152             if (bundle != null) {
153                 try {
154                     message = bundle.getString(key);
155                 } catch (MissingResourceException e) {
156                     message = null;
157                 }
158                 if (message != null) {
159                     return message;
160                 }
161             }
162         }
163 
164         // Otherwise, search the default resource bundle
165         bundle = ResourceBundle.getBundle(DEFAULT_RESOURCE_BUNDLE, locale, loader);
166         try {
167             return bundle.getString(key);
168         } catch (MissingResourceException e) {
169             return "???" + key + "???";
170         }
171 
172     }
173 
174 
175     /***
176      * <p>Retrieve a locale-specific message for the specified key, then
177      * treat it as a message format pattern, and substitute in the specified
178      * parameter values and return the resulting string.</p>
179      *
180      * @param context <code>FaceContext</code> for the current request
181      * @param key Message key for the requested message
182      * @param parameters Replacement parameters to substitute in to
183      *  the retrieved message
184      */
185     protected String message(FacesContext context, String key,
186                              Object[] parameters) {
187 
188         String message = message(context, key);
189         if ((parameters == null) || (parameters.length < 1)) {
190             return message;
191         }
192         return message(context.getViewRoot().getLocale(), message, parameters);
193 
194     }
195 
196 
197     /***
198      * <p>Use the specified message as a message format pattern, substitute
199      * in the specified parameter values, and return the resulting string.</p>
200      *
201      * @param locale Locale for performing parameter replacement
202      * @param message Message format pattern string
203      * @param parameters Replacement parameters to substitute in to
204      *  the message format pattern
205      */
206     protected String message(Locale locale, String message, Object[] parameters) {
207 
208         MessageFormat format =
209           new MessageFormat(message, locale);
210         return format.format(parameters);
211 
212     }
213 
214 
215 }