001: /*
002: * Copyright 2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.apache.myfaces.taglib.core;
017:
018: import java.util.ArrayList;
019: import java.util.Collection;
020: import java.util.Enumeration;
021: import java.util.HashSet;
022: import java.util.List;
023: import java.util.Locale;
024: import java.util.Map;
025: import java.util.MissingResourceException;
026: import java.util.ResourceBundle;
027: import java.util.Set;
028:
029: import javax.faces.component.UIViewRoot;
030: import javax.faces.context.FacesContext;
031: import javax.servlet.jsp.JspException;
032: import javax.servlet.jsp.tagext.Tag;
033: import javax.servlet.jsp.tagext.TagSupport;
034: import javax.el.ValueExpression;
035:
036: /**
037: * TODO:
038: * We should find a way to save loaded bundles in the state, because otherwise
039: * on the next request the bundle map will not be present before the render phase
040: * and value bindings that reference to the bundle will always log annoying
041: * "Variable 'xxx' could not be resolved" error messages.
042: *
043: * @author Manfred Geiler (latest modification by $Author: baranda $)
044: * @version $Revision: 466386 $ $Date: 2006-10-21 14:05:14 +0200 (Sa, 21 Okt 2006) $
045: */
046: public class LoadBundleTag extends TagSupport {
047: private static final long serialVersionUID = -8892145684062838928L;
048:
049: private ValueExpression _basename;
050: private String _var;
051:
052: public void setBasename(ValueExpression basename) {
053: _basename = basename;
054: }
055:
056: public void setVar(String var) {
057: _var = var;
058: }
059:
060: public int doStartTag() throws JspException {
061: if (null == _var) {
062: throw new NullPointerException(
063: "LoadBundle: 'var' must not be null");
064: }
065:
066: FacesContext facesContext = FacesContext.getCurrentInstance();
067: if (facesContext == null) {
068: throw new JspException("No faces context?!");
069: }
070:
071: UIViewRoot viewRoot = facesContext.getViewRoot();
072: if (viewRoot == null) {
073: throw new JspException(
074: "No view root! LoadBundle must be nested inside <f:view> action.");
075: }
076:
077: Locale locale = viewRoot.getLocale();
078: if (locale == null) {
079: locale = facesContext.getApplication().getDefaultLocale();
080: }
081:
082: String basename = null;
083: if (_basename != null) {
084: if (_basename.isLiteralText()) {
085: basename = _basename.getExpressionString();
086: } else {
087: basename = (String) _basename.getValue(facesContext
088: .getELContext());
089: }
090: }
091:
092: if (null == basename) {
093: throw new NullPointerException(
094: "LoadBundle: 'basename' must not be null");
095: }
096:
097: final ResourceBundle bundle;
098: try {
099: bundle = ResourceBundle.getBundle(basename, locale, Thread
100: .currentThread().getContextClassLoader());
101: } catch (MissingResourceException e) {
102: throw new JspException("Resource bundle '" + basename
103: + "' could not be found.", e);
104: }
105:
106: facesContext.getExternalContext().getRequestMap().put(_var,
107: new BundleMap(bundle));
108: return Tag.SKIP_BODY;
109: }
110:
111: private static class BundleMap implements Map {
112: private ResourceBundle _bundle;
113: private List<String> _values;
114:
115: public BundleMap(ResourceBundle bundle) {
116: _bundle = bundle;
117: }
118:
119: //Optimized methods
120:
121: public Object get(Object key) {
122: try {
123: return _bundle.getObject(key.toString());
124: } catch (Exception e) {
125: return "???" + key + "???";
126: }
127: }
128:
129: public boolean isEmpty() {
130: return !_bundle.getKeys().hasMoreElements();
131: }
132:
133: public boolean containsKey(Object key) {
134: try {
135: return _bundle.getObject(key.toString()) != null;
136: } catch (MissingResourceException e) {
137: return false;
138: }
139: }
140:
141: //Unoptimized methods
142:
143: public Collection values() {
144: if (_values == null) {
145: _values = new ArrayList<String>();
146: for (Enumeration<String> enumer = _bundle.getKeys(); enumer
147: .hasMoreElements();) {
148: String v = _bundle.getString(enumer.nextElement());
149: _values.add(v);
150: }
151: }
152: return _values;
153: }
154:
155: public int size() {
156: return values().size();
157: }
158:
159: public boolean containsValue(Object value) {
160: return values().contains(value);
161: }
162:
163: public Set entrySet() {
164: Set<Entry> set = new HashSet<Entry>();
165: for (Enumeration<String> enumer = _bundle.getKeys(); enumer
166: .hasMoreElements();) {
167: final String k = enumer.nextElement();
168: set.add(new Map.Entry() {
169: public Object getKey() {
170: return k;
171: }
172:
173: public Object getValue() {
174: return _bundle.getObject(k);
175: }
176:
177: public Object setValue(Object value) {
178: throw new UnsupportedOperationException(this
179: .getClass().getName()
180: + " UnsupportedOperationException");
181: }
182: });
183: }
184: return set;
185: }
186:
187: public Set keySet() {
188: Set<String> set = new HashSet<String>();
189: for (Enumeration<String> enumer = _bundle.getKeys(); enumer
190: .hasMoreElements();) {
191: set.add(enumer.nextElement());
192: }
193: return set;
194: }
195:
196: //Unsupported methods
197:
198: public Object remove(Object key) {
199: throw new UnsupportedOperationException(this .getClass()
200: .getName()
201: + " UnsupportedOperationException");
202: }
203:
204: public void putAll(Map t) {
205: throw new UnsupportedOperationException(this .getClass()
206: .getName()
207: + " UnsupportedOperationException");
208: }
209:
210: public Object put(Object key, Object value) {
211: throw new UnsupportedOperationException(this .getClass()
212: .getName()
213: + " UnsupportedOperationException");
214: }
215:
216: public void clear() {
217: throw new UnsupportedOperationException(this .getClass()
218: .getName()
219: + " UnsupportedOperationException");
220: }
221:
222: }
223:
224: }
|