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 if (context == null) { 172 throw new NullPointerException(); 173 } 174 Object result = null; 175 if (!tranzient) { 176 if (valueExpression instanceof StateHolder) { 177 Object [] stateStruct = new Object[2]; 178 179 // save the actual state of our wrapped valueExpression 180 stateStruct[0] = ((StateHolder)valueExpression).saveState(context); 181 // save the class name of the valueExpression impl 182 stateStruct[1] = valueExpression.getClass().getName(); 183 184 result = stateStruct; 185 } 186 else { 187 result = valueExpression; 188 } 189 } 190 191 return result; 192 193 } 194 195 public void restoreState(FacesContext context, Object state) { 196 if (context == null) { 197 throw new NullPointerException(); 198 } 199 // if we have state 200 if (null == state) { 201 return; 202 } 203 204 if (!(state instanceof ValueExpression)) { 205 Object [] stateStruct = (Object []) state; 206 Object savedState = stateStruct[0]; 207 String className = stateStruct[1].toString(); 208 ValueExpression result = null; 209 210 Class toRestoreClass = null; 211 if (null != className) { 212 try { 213 toRestoreClass = loadClass(className, this); 214 } 215 catch (ClassNotFoundException e) { 216 throw new IllegalStateException(e.getMessage()); 217 } 218 219 if (null != toRestoreClass) { 220 try { 221 result = 222 (ValueExpression) toRestoreClass.newInstance(); 223 } 224 catch (InstantiationException e) { 225 throw new IllegalStateException(e.getMessage()); 226 } 227 catch (IllegalAccessException a) { 228 throw new IllegalStateException(a.getMessage()); 229 } 230 } 231 232 if (null != result && null != savedState) { 233 // don't need to check transient, since that was 234 // done on the saving side. 235 ((StateHolder)result).restoreState(context, savedState); 236 } 237 valueExpression = result; 238 } 239 } 240 else { 241 valueExpression = (ValueExpression) state; 242 } 243 } 244 245 public boolean equals(Object other) { 246 247 if (other == this) { 248 return true; 249 } 250 251 if (other instanceof ValueBindingValueExpressionAdapter) { 252 ValueExpression expr = 253 ((ValueBindingValueExpressionAdapter) other).getWrapped(); 254 return (valueExpression.equals(expr)); 255 } else if (other instanceof ValueBinding) { 256 FacesContext context = FacesContext.getCurrentInstance(); 257 ValueBinding otherVB = (ValueBinding) other; 258 Class type = otherVB.getType(context); 259 if (type != null) { 260 return type.equals(valueExpression.getType(context.getELContext())); 261 } 262 } 263 return false; 264 265 } 266 267 public int hashCode() { 268 assert(null != valueExpression); 269 return valueExpression.hashCode(); 270 } 271 272 public ValueExpression getWrapped() { 273 return valueExpression; 274 } 275 276 // 277 // Helper methods for StateHolder 278 // 279 280 private static Class loadClass(String name, 281 Object fallbackClass) throws ClassNotFoundException { 282 ClassLoader loader = 283 Thread.currentThread().getContextClassLoader(); 284 if (loader == null) { 285 loader = fallbackClass.getClass().getClassLoader(); 286 } 287 return Class.forName(name, true, loader); 288 } 289 290 291 292 }