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

For more information, please explore the Attic.

Coverage Report - org.apache.shale.util.LoadBundle
 
Classes in this File Line Coverage Branch Coverage Complexity
LoadBundle
100%
25/25
N/A
2.65
LoadBundle$1
100%
3/3
N/A
2.65
 
 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.util;
 19  
 
 20  
 import java.beans.Beans;
 21  
 import java.util.ArrayList;
 22  
 import java.util.Collection;
 23  
 import java.util.Collections;
 24  
 import java.util.Enumeration;
 25  
 import java.util.HashMap;
 26  
 import java.util.HashSet;
 27  
 import java.util.List;
 28  
 import java.util.Locale;
 29  
 import java.util.Map;
 30  
 import java.util.MissingResourceException;
 31  
 import java.util.ResourceBundle;
 32  
 import java.util.Set;
 33  
 import javax.faces.component.UIViewRoot;
 34  
 
 35  
 import javax.faces.context.FacesContext;
 36  
 
 37  
 /**
 38  
  * <p>Utility class emulating the behavior of the standard JSF Core Library
 39  
  * tag <code>&lt;f:loadBundle&gt;</code>.  This class is designed to be used
 40  
  * as a managed bean, and exposes a <code>map</code> property containing the
 41  
  * messages in the resoruce bundle specified by the <code>basename</code>
 42  
  * property, localized for the <code>Locale</code> specified on the current
 43  
  * request.</p>
 44  
  *
 45  
  * <p>A typical use of this class would be to declare a managed bean like this:</p>
 46  
  * <pre>
 47  
  *    &lt;managed-bean&gt;
 48  
  *      &lt;managed-bean-name&gt;bundle&lt;/managed-bean-name&gt;
 49  
  *      &lt;managed-bean-class&gt;
 50  
  *        org.apache.shale.util.LoadBundle
 51  
  *      &lt;/managed-bean-class&gt;
 52  
  *      &lt;managed-bean-scope&gt;request&lt;/managed-bean-scope&gt;
 53  
  *      &lt;managed-property&gt;
 54  
  *        &lt;property-name&gt;basename&lt;/property-name&gt;
 55  
  *        &lt;value&gt;com.mycompany.mypackage.Bundle&lt;/value&gt;
 56  
  *      &lt;/managed-property&gt;
 57  
  *    &lt;/managed-bean&gt;
 58  
  * </pre>
 59  
  *
 60  
  * <p>This will result in creation of a request scope object whose <code>map</code>
 61  
  * property will return a <code>Map</code> representing the localized messages for
 62  
  * the <code>com.mycompany.mypackage.Bundle</code> resource bundle.  You can look
 63  
  * up localized messages in this <code>Map</code> by evaluating a value binding
 64  
  * expression like this:</p>
 65  
  * <blockquote>
 66  
  *   <code>#{messages.['message.key']}</code>
 67  
  * </blockquote>
 68  
  * <p>where <code>message.key</code> is the key for which to retrieve a
 69  
  * localized message.</p>
 70  
  *
 71  
  * <p>(Since 1.0.1) <strong>IMPLEMENTATION NOTE</strong> - For backwards
 72  
  * compatibility in applications that utilized the 1.0.0 version of this
 73  
  * class, the following sort of expression resolves to the same value:</p>
 74  
  * <blockquote>
 75  
  *   <code>#{messages.map['message.key']}</code>
 76  
  * </blockquote>
 77  
  */
 78  2
 public class LoadBundle {
 79  
 
 80  
    // ------------------------------------------------------------- Constructors
 81  
 
 82  
 
 83  
    /** Creates a new instance of LoadBundle. */
 84  
    public LoadBundle() {
 85  
         this(null);
 86  
    }
 87  
 
 88  
 
 89  
    /** <p>Creates a new instance of LoadBundle for the specified bundle.</p>
 90  
     *
 91  
     * @param basename Base resource bundle name for this <code>LoadBundle</code>
 92  
     */
 93  5
    public LoadBundle(String basename) {
 94  5
        this.basename = basename;
 95  5
    }
 96  
 
 97  
 
 98  
    // --------------------------------------------------------- Static Variables
 99  
 
 100  
 
 101  
    /**
 102  
     * <p>The default <code>Locale</code> for this application.</p>
 103  
     */
 104  1
    private static final Locale defaultLocale = Locale.getDefault();
 105  
 
 106  
 
 107  
    // --------------------------------------------------------------- Properties
 108  
 
 109  
 
 110  
    /**
 111  
     * <p>The base resource bundle name for this <code>LoadBundle</code> instance.</p>
 112  
     */
 113  5
    private String basename = null;
 114  
 
 115  
 
 116  
    /**
 117  
     * <p>Return the base resource bundle name for this <code>LoadBundle</code>
 118  
     * instance.</p>
 119  
     */
 120  
    public String getBasename() {
 121  1
        return this.basename;
 122  
    }
 123  
 
 124  
 
 125  
    /**
 126  
     * <p>Set the base resource bundle name for this <code>LoadBundle</code>
 127  
     * instance.</p>
 128  
     *
 129  
     * @param basename The new base resource bundle name
 130  
     */
 131  
    public void setBasename(String basename) {
 132  
        this.basename = basename;
 133  
    }
 134  
 
 135  
 
 136  
    // ----------------------------------------------------------- Public Methods
 137  
 
 138  
 
 139  
    /**
 140  
     * <p>Return a <code>Map</code> whose keys and values represent the content
 141  
     * of the application resource bundle specified by the <code>basename</code>
 142  
     * property, localized for the <code>Locale</code> stored in the
 143  
     * <code>UIViewRoot</code> for the current request.</p>
 144  
     *
 145  
     * @exception IllegalStateException if we are not inside a Faces request,
 146  
     *  or if there is not a current view root with a valid locale
 147  
     */
 148  
    public Map getMap() throws IllegalStateException {
 149  
 
 150  
        // Validate our current state
 151  4
        if (basename == null) {
 152  
            if (Beans.isDesignTime()) {
 153  
                return Collections.EMPTY_MAP;
 154  
            }
 155  
            throw new IllegalStateException("The 'basename' property cannot be null"); // FIXME - i18n
 156  
        }
 157  4
        FacesContext context = FacesContext.getCurrentInstance();
 158  4
        UIViewRoot root = null;
 159  4
        Locale locale = null;
 160  4
        if (context != null) {
 161  4
            root = context.getViewRoot();
 162  
        }
 163  4
        if (root != null) {
 164  4
            locale = root.getLocale();
 165  
        }
 166  4
        if (locale == null) {
 167  
            throw new IllegalStateException("Cannot retrieve locale-specific map if there " +
 168  
                    "is not a current Faces request, containing a valid view root, with" +
 169  
                    "a Locale instance inside.");
 170  
        }
 171  
 
 172  
        // Look up the requested resource bundle
 173  4
        final ResourceBundle bundle = getBundle(basename, locale);
 174  4
        if (bundle == null) {
 175  
            throw new IllegalArgumentException
 176  
              ("No resource bundle found for base name '" + basename + "' and locale '" + locale + "'"); // FIXME - i18n
 177  
        }
 178  
 
 179  
        // Construct and return an immutable Map representing these contents
 180  4
        Map map = new Map() {
 181  
 
 182  
            public void clear() {
 183  
                throw new UnsupportedOperationException();
 184  
            }
 185  
 
 186  
            public boolean containsKey(Object key) {
 187  
                boolean result = false;
 188  
                if (key != null) {
 189  
                    result = bundle.getObject(key.toString()) != null;
 190  
                }
 191  
                return result;
 192  
            }
 193  
 
 194  
            public boolean containsValue(Object value) {
 195  
                Enumeration keys = bundle.getKeys();
 196  
                while (keys.hasMoreElements()) {
 197  
                    Object val = bundle.getObject(keys.nextElement().toString());
 198  
                    if ((val != null) && val.equals(value)) {
 199  
                        return true;
 200  
                    }
 201  
                }
 202  
                return false;
 203  
            }
 204  
 
 205  
 
 206  
            public Set entrySet() {
 207  
                Map map = new HashMap();
 208  
                Enumeration keys = bundle.getKeys();
 209  
                while (keys.hasMoreElements()) {
 210  
                    String key = keys.nextElement().toString();
 211  
                    Object value = bundle.getObject(key);
 212  
                    map.put(key, value);
 213  
                }
 214  
                return map.entrySet();
 215  
            }
 216  
 
 217  
            public boolean equals(Object o) {
 218  
                if ((o == null) || !(o instanceof Map)) {
 219  
                    return false;
 220  
                }
 221  
                return entrySet().equals(((Map) o).entrySet());
 222  
            }
 223  
 
 224  
            public Object get(Object key) {
 225  6
                if (key == null) {
 226  
                    return null;
 227  
                }
 228  
                try {
 229  6
                    return bundle.getObject(key.toString());
 230  
                } catch (MissingResourceException e) {
 231  
                    return "???" + key.toString() + "???";
 232  
                }
 233  
            }
 234  
 
 235  
            public int hashCode() {
 236  
                return bundle.hashCode();
 237  
            }
 238  
 
 239  
            public boolean isEmpty() {
 240  
                Enumeration keys = bundle.getKeys();
 241  
                while (keys.hasMoreElements()) {
 242  
                    return false;
 243  
                }
 244  
                return true;
 245  
            }
 246  
 
 247  
            public Set keySet() {
 248  
                Set set = new HashSet();
 249  
                Enumeration keys = bundle.getKeys();
 250  
                while (keys.hasMoreElements()) {
 251  
                    set.add(keys.nextElement());
 252  
                }
 253  
                return set;
 254  
            }
 255  
 
 256  
            public Object put(Object key, Object value) {
 257  
                throw new UnsupportedOperationException();
 258  
            }
 259  
 
 260  
            public void putAll(Map map) {
 261  
                throw new UnsupportedOperationException();
 262  
            }
 263  
 
 264  
            public Object remove(Object key) {
 265  
                throw new UnsupportedOperationException();
 266  
            }
 267  
 
 268  
            public int size() {
 269  
                int size = 0;
 270  
                Enumeration keys = bundle.getKeys();
 271  
                while (keys.hasMoreElements()) {
 272  
                    keys.nextElement();
 273  
                    size++;
 274  
                }
 275  
                return size;
 276  
            }
 277  
 
 278  4
            public Collection values() {
 279  
                List list = new ArrayList();
 280  
                Enumeration keys = bundle.getKeys();
 281  
                while (keys.hasMoreElements()) {
 282  
                    String key = keys.nextElement().toString();
 283  
                    list.add(bundle.getObject(key));
 284  
                }
 285  
                return list;
 286  
            }
 287  
 
 288  
        };
 289  4
        return map;
 290  
 
 291  
    }
 292  
 
 293  
 
 294  
     // --------------------------------------------------------- Private Methods
 295  
 
 296  
 
 297  
     /**
 298  
      * <p>Return the localized <code>ResourceBundle</code> for the specified
 299  
      * <code>Locale</code>.</p>
 300  
      *
 301  
      * @param basename Base name of the resource bundle to return
 302  
      * @param locale Locale used to select the appropriate resource bundle
 303  
      */
 304  
     private ResourceBundle getBundle(String basename, Locale locale) {
 305  
 
 306  4
         assert basename != null;
 307  4
         assert locale != null;
 308  4
         ClassLoader rbcl = Thread.currentThread().getContextClassLoader();
 309  4
         if (rbcl == null) {
 310  
             rbcl = this.getClass().getClassLoader();
 311  
         }
 312  
         try {
 313  4
             return ResourceBundle.getBundle(basename, locale, rbcl);
 314  
         } catch (MissingResourceException e) {
 315  
             return ResourceBundle.getBundle(basename, defaultLocale, rbcl);
 316  
         }
 317  
 
 318  
     }
 319  
 
 320  
 
 321  
 }