1 /*
2 * $Id: ValueBindingValueExpressionAdapter.java,v 1.6 2007/04/27 22:00:12 ofung Exp $
3 */
4
5 /*
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
7 *
8 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
9 *
10 * The contents of this file are subject to the terms of either the GNU
11 * General Public License Version 2 only ("GPL") or the Common Development
12 * and Distribution License("CDDL") (collectively, the "License"). You
13 * may not use this file except in compliance with the License. You can obtain
14 * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
15 * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
16 * language governing permissions and limitations under the License.
17 *
18 * When distributing the software, include this License Header Notice in each
19 * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
20 * Sun designates this particular file as subject to the "Classpath" exception
21 * as provided by Sun in the GPL Version 2 section of the License file that
22 * accompanied this code. If applicable, add the following below the License
23 * Header, with the fields enclosed by brackets [] replaced by your own
24 * identifying information: "Portions Copyrighted [year]
25 * [name of copyright owner]"
26 *
27 * Contributor(s):
28 *
29 * If you wish your version of this file to be governed by only the CDDL or
30 * only the GPL Version 2, indicate your decision by adding "[Contributor]
31 * elects to include this software in this distribution under the [CDDL or GPL
32 * Version 2] license." If you don't indicate a single choice of license, a
33 * recipient has the option to distribute your version of this file under
34 * either the CDDL, the GPL Version 2 or to extend the choice of license to
35 * its licensees as provided above. However, if you add GPL Version 2 code
36 * and therefore, elected the GPL Version 2 license, then the option applies
37 * only if the new code is made subject to such option by the copyright
38 * holder.
39 */
40
41 package javax.faces.component;
42
43 import java.io.Serializable;
44
45 import javax.faces.component.StateHolder;
46 import javax.faces.context.FacesContext;
47 import javax.faces.el.EvaluationException;
48 import javax.faces.el.PropertyNotFoundException;
49 import javax.faces.el.ReferenceSyntaxException;
50 import javax.faces.el.ValueBinding;
51
52 import javax.el.ValueExpression;
53 import javax.el.ELException;
54
55 /**
56 * <p>Wrap a ValueExpression instance and expose it as a ValueBinding</p>
57 *
58 * @author Jacob Hookom
59 */
60 class ValueBindingValueExpressionAdapter extends ValueBinding implements StateHolder,
61 Serializable {
62
63 private static final long serialVersionUID = -8015491904782686906L;
64
65 private ValueExpression valueExpression= null;
66 private boolean tranzient;
67
68 public ValueBindingValueExpressionAdapter() {} // for StateHolder
69
70 ValueBindingValueExpressionAdapter(ValueExpression valueExpression) {
71 this.valueExpression = valueExpression;
72 }
73
74
75 /* (non-Javadoc)
76 * @see javax.faces.el.ValueBinding#getExpressionString()
77 */
78 public String getExpressionString() {
79 assert(null != valueExpression);
80 return valueExpression.getExpressionString();
81 }
82
83 /* (non-Javadoc)
84 * @see javax.faces.el.ValueBinding#getType(javax.faces.context.FacesContext)
85 */
86 public Class getType(FacesContext context) throws EvaluationException,
87 PropertyNotFoundException {
88
89 if (context == null) {
90 throw new NullPointerException("FacesContext -> null");
91 }
92 Class result = null;
93 try {
94 result = valueExpression.getType(context.getELContext());
95 } catch (javax.el.PropertyNotFoundException pnfe) {
96 throw new PropertyNotFoundException(pnfe);
97 } catch (ELException elex) {
98 throw new EvaluationException(elex);
99 }
100 return result;
101 }
102
103 /* (non-Javadoc)
104 * @see javax.faces.el.ValueBinding#getValue(javax.faces.context.FacesContext)
105 */
106 public Object getValue(FacesContext context) throws EvaluationException,
107 PropertyNotFoundException {
108 if (context == null) {
109 throw new NullPointerException("FacesContext -> null");
110 }
111 Object result = null;
112 try {
113 result = valueExpression.getValue(context.getELContext());
114 } catch (javax.el.PropertyNotFoundException pnfe) {
115 throw new PropertyNotFoundException(pnfe);
116 } catch (ELException elex) {
117 throw new EvaluationException(elex);
118 }
119 return result;
120 }
121
122 /* (non-Javadoc)
123 * @see javax.faces.el.ValueBinding#isReadOnly(javax.faces.context.FacesContext)
124 */
125 public boolean isReadOnly(FacesContext context) throws EvaluationException,
126 PropertyNotFoundException {
127
128 if (context == null) {
129 throw new NullPointerException("FacesContext -> null");
130 }
131 boolean result = false;
132 try {
133 result = valueExpression.isReadOnly(context.getELContext());
134 } catch (ELException elex) {
135 throw new EvaluationException(elex);
136 }
137 return result;
138 }
139
140
141
142 /* (non-Javadoc)
143 * @see javax.faces.el.ValueBinding#setValue(javax.faces.context.FacesContext, java.lang.Object)
144 */
145 public void setValue(FacesContext context, Object value)
146 throws EvaluationException, PropertyNotFoundException {
147
148 if (context == null) {
149 throw new NullPointerException("FacesContext -> null");
150 }
151 try {
152 valueExpression.setValue(context.getELContext(), value);
153 } catch (javax.el.PropertyNotFoundException pnfe) {
154 throw new PropertyNotFoundException(pnfe);
155 } catch (javax.el.PropertyNotWritableException pnwe) {
156 throw new PropertyNotFoundException(pnwe);
157 } catch (ELException elex) {
158 throw new EvaluationException(elex);
159 }
160 }
161
162 public boolean isTransient() {
163 return this.tranzient;
164 }
165
166 public void setTransient(boolean tranzient) {
167 this.tranzient = tranzient;
168 }
169
170 public Object saveState(FacesContext context){
171 Object result = null;
172 if (!tranzient) {
173 if (valueExpression instanceof StateHolder) {
174 Object [] stateStruct = new Object[2];
175
176 // save the actual state of our wrapped valueExpression
177 stateStruct[0] = ((StateHolder)valueExpression).saveState(context);
178 // save the class name of the valueExpression impl
179 stateStruct[1] = valueExpression.getClass().getName();
180
181 result = stateStruct;
182 }
183 else {
184 result = valueExpression;
185 }
186 }
187
188 return result;
189
190 }
191
192 public void restoreState(FacesContext context, Object state) {
193 // if we have state
194 if (null == state) {
195 return;
196 }
197
198 if (!(state instanceof ValueExpression)) {
199 Object [] stateStruct = (Object []) state;
200 Object savedState = stateStruct[0];
201 String className = stateStruct[1].toString();
202 ValueExpression result = null;
203
204 Class toRestoreClass = null;
205 if (null != className) {
206 try {
207 toRestoreClass = loadClass(className, this);
208 }
209 catch (ClassNotFoundException e) {
210 throw new IllegalStateException(e.getMessage());
211 }
212
213 if (null != toRestoreClass) {
214 try {
215 result =
216 (ValueExpression) toRestoreClass.newInstance();
217 }
218 catch (InstantiationException e) {
219 throw new IllegalStateException(e.getMessage());
220 }
221 catch (IllegalAccessException a) {
222 throw new IllegalStateException(a.getMessage());
223 }
224 }
225
226 if (null != result && null != savedState) {
227 // don't need to check transient, since that was
228 // done on the saving side.
229 ((StateHolder)result).restoreState(context, savedState);
230 }
231 valueExpression = result;
232 }
233 }
234 else {
235 valueExpression = (ValueExpression) state;
236 }
237 }
238
239 public boolean equals(Object other) {
240
241 if (other == this) {
242 return true;
243 }
244
245 if (other instanceof ValueBindingValueExpressionAdapter) {
246 ValueExpression expr =
247 ((ValueBindingValueExpressionAdapter) other).getWrapped();
248 return (valueExpression.equals(expr));
249 } else if (other instanceof ValueBinding) {
250 FacesContext context = FacesContext.getCurrentInstance();
251 ValueBinding otherVB = (ValueBinding) other;
252 Class type = otherVB.getType(context);
253 if (type != null) {
254 return type.equals(valueExpression.getType(context.getELContext()));
255 }
256 }
257 return false;
258
259 }
260
261 public int hashCode() {
262 assert(null != valueExpression);
263 return valueExpression.hashCode();
264 }
265
266 public ValueExpression getWrapped() {
267 return valueExpression;
268 }
269
270 //
271 // Helper methods for StateHolder
272 //
273
274 private static Class loadClass(String name,
275 Object fallbackClass) throws ClassNotFoundException {
276 ClassLoader loader =
277 Thread.currentThread().getContextClassLoader();
278 if (loader == null) {
279 loader = fallbackClass.getClass().getClassLoader();
280 }
281 return Class.forName(name, true, loader);
282 }
283
284
285
286 }