001: /*
002: * Copyright 2006 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:
017: package org.apache.myfaces.el.unified.resolver;
018:
019: import java.beans.FeatureDescriptor;
020: import java.util.ArrayList;
021: import java.util.Iterator;
022: import java.util.Map;
023: import java.util.ResourceBundle;
024: import javax.el.ELContext;
025: import javax.el.ELException;
026: import javax.el.ELResolver;
027: import javax.el.PropertyNotFoundException;
028: import javax.el.PropertyNotWritableException;
029: import javax.faces.application.Application;
030: import javax.faces.context.FacesContext;
031:
032: import org.apache.myfaces.config.RuntimeConfig;
033:
034: /**
035: * See JSF 1.2 spec section 5.6.1.4
036: *
037: * @author Stan Silvert
038: */
039: public class ResourceBundleResolver extends ELResolver {
040:
041: /**
042: * RuntimeConfig is instantiated once per servlet and never changes--we can
043: * safely cache it
044: */
045: private RuntimeConfig runtimeConfig;
046:
047: /** Creates a new instance of ResourceBundleResolver */
048: public ResourceBundleResolver() {
049: }
050:
051: public void setValue(ELContext context, Object base,
052: Object property, Object value) throws NullPointerException,
053: PropertyNotFoundException, PropertyNotWritableException,
054: ELException {
055:
056: if ((base == null) && (property == null))
057: throw new PropertyNotFoundException();
058:
059: if (!(property instanceof String))
060: return;
061:
062: ResourceBundle bundle = getResourceBundle(context,
063: (String) property);
064:
065: if (bundle != null) {
066: throw new PropertyNotWritableException(
067: "ResourceBundles are read-only");
068: }
069: }
070:
071: public boolean isReadOnly(ELContext context, Object base,
072: Object property) throws NullPointerException,
073: PropertyNotFoundException, ELException {
074:
075: if (base != null)
076: return false;
077: if (property == null)
078: throw new PropertyNotFoundException();
079: if (!(property instanceof String))
080: return false;
081:
082: ResourceBundle bundle = getResourceBundle(context,
083: (String) property);
084:
085: if (bundle != null) {
086: context.setPropertyResolved(true);
087: return true;
088: }
089:
090: return false;
091: }
092:
093: public Object getValue(ELContext context, Object base,
094: Object property) throws NullPointerException,
095: PropertyNotFoundException, ELException {
096:
097: if (base != null)
098: return null;
099: if (property == null)
100: throw new PropertyNotFoundException();
101: if (!(property instanceof String))
102: return null;
103:
104: ResourceBundle bundle = getResourceBundle(context,
105: (String) property);
106:
107: if (bundle != null) {
108: context.setPropertyResolved(true);
109: return bundle;
110: }
111:
112: return null;
113: }
114:
115: public Class<?> getType(ELContext context, Object base,
116: Object property) throws NullPointerException,
117: PropertyNotFoundException, ELException {
118:
119: if (base != null)
120: return null;
121: if (property == null)
122: throw new PropertyNotFoundException();
123: if (!(property instanceof String))
124: return null;
125:
126: ResourceBundle bundle = getResourceBundle(context,
127: (String) property);
128:
129: if (bundle != null) {
130: context.setPropertyResolved(true);
131: return ResourceBundle.class;
132: }
133:
134: return null;
135: }
136:
137: public Iterator<FeatureDescriptor> getFeatureDescriptors(
138: ELContext context, Object base) {
139:
140: if (base != null)
141: return null;
142:
143: ArrayList<FeatureDescriptor> descriptors = new ArrayList<FeatureDescriptor>();
144:
145: Map<String, org.apache.myfaces.config.impl.digester.elements.ResourceBundle> resourceBundles = runtimeConfig(
146: context).getResourceBundles();
147:
148: for (org.apache.myfaces.config.impl.digester.elements.ResourceBundle resourceBundle : resourceBundles
149: .values()) {
150: descriptors.add(makeDescriptor(resourceBundle));
151: }
152:
153: return descriptors.iterator();
154: }
155:
156: public Class<?> getCommonPropertyType(ELContext context, Object base) {
157:
158: if (base != null)
159: return null;
160:
161: return String.class;
162: }
163:
164: // get the FacesContext from the ELContext
165: private FacesContext facesContext(ELContext context) {
166: return (FacesContext) context.getContext(FacesContext.class);
167: }
168:
169: private ResourceBundle getResourceBundle(ELContext context,
170: String property) {
171: FacesContext facesContext = facesContext(context);
172: if (facesContext != null) {
173: Application application = facesContext.getApplication();
174: return application
175: .getResourceBundle(facesContext, property);
176: }
177:
178: return null;
179: }
180:
181: protected RuntimeConfig runtimeConfig(ELContext context) {
182: FacesContext facesContext = facesContext(context);
183:
184: // application-level singleton - we can safely cache this
185: if (this .runtimeConfig == null) {
186: this .runtimeConfig = RuntimeConfig
187: .getCurrentInstance(facesContext
188: .getExternalContext());
189: }
190:
191: return runtimeConfig;
192: }
193:
194: private FeatureDescriptor makeDescriptor(
195: org.apache.myfaces.config.impl.digester.elements.ResourceBundle bundle) {
196: FeatureDescriptor fd = new FeatureDescriptor();
197: fd.setValue(ELResolver.RESOLVABLE_AT_DESIGN_TIME, Boolean.TRUE);
198: fd.setName(bundle.getVar());
199: fd.setDisplayName(bundle.getDisplayName());
200: fd.setValue(ELResolver.TYPE, ResourceBundle.class);
201: fd.setShortDescription("");
202: fd.setExpert(false);
203: fd.setHidden(false);
204: fd.setPreferred(true);
205: return fd;
206: }
207: }
|