001/* 002 * (C) Copyright 2007 Nuxeo SAS (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * Nuxeo - initial API and implementation 016 * 017 * $Id: MetaValueExpression.java 28491 2008-01-04 19:04:30Z sfermigier $ 018 */ 019 020package org.nuxeo.ecm.platform.ui.web.binding; 021 022import java.io.IOException; 023import java.io.ObjectInput; 024import java.io.ObjectOutput; 025import java.io.Serializable; 026 027import javax.el.ELContext; 028import javax.el.ELException; 029import javax.el.ExpressionFactory; 030import javax.el.FunctionMapper; 031import javax.el.ValueExpression; 032import javax.el.VariableMapper; 033import javax.faces.application.Application; 034import javax.faces.context.FacesContext; 035 036import org.apache.commons.logging.Log; 037import org.apache.commons.logging.LogFactory; 038import org.nuxeo.ecm.platform.ui.web.util.ComponentTagUtils; 039 040/** 041 * Meta value expression used to invoke the EL expression that is already the result of a value expression. 042 * 043 * @author <a href="mailto:at@nuxeo.com">Anahide Tchertchian</a> 044 */ 045public class MetaValueExpression extends ValueExpression implements Serializable { 046 047 private static final long serialVersionUID = -2721042412903607760L; 048 049 private static final Log log = LogFactory.getLog(MetaValueExpression.class); 050 051 private ValueExpression originalValueExpression; 052 053 private FunctionMapper fnMapper; 054 055 private VariableMapper varMapper; 056 057 public MetaValueExpression(ValueExpression originalValueExpression) { 058 this(originalValueExpression, null, null); 059 } 060 061 public MetaValueExpression(ValueExpression originalValueExpression, FunctionMapper fnMapper, 062 VariableMapper varMapper) { 063 this.originalValueExpression = originalValueExpression; 064 this.fnMapper = fnMapper; 065 this.varMapper = varMapper; 066 } 067 068 // Expression interface 069 070 @Override 071 public boolean equals(Object obj) { 072 if (this == obj) { 073 return true; 074 } 075 if (!(obj instanceof MetaValueExpression)) { 076 return false; 077 } 078 MetaValueExpression other = (MetaValueExpression) obj; 079 return originalValueExpression.equals(other.originalValueExpression); 080 } 081 082 @Override 083 public int hashCode() { 084 return originalValueExpression.hashCode(); 085 } 086 087 @Override 088 public String getExpressionString() { 089 return originalValueExpression.getExpressionString(); 090 } 091 092 @Override 093 public boolean isLiteralText() { 094 // XXX should invoke first 095 return originalValueExpression.isLiteralText(); 096 } 097 098 // ValueExpression interface 099 100 @Override 101 public Class<?> getExpectedType() { 102 // XXX should invoke first 103 return originalValueExpression.getExpectedType(); 104 } 105 106 private ELContext getLocalContext(ELContext context) { 107 if (fnMapper == null && varMapper == null) { 108 return context; 109 } 110 return new org.nuxeo.ecm.platform.ui.web.binding.EvaluationContext(context, fnMapper, varMapper); 111 } 112 113 @Override 114 public Class<?> getType(ELContext context) { 115 ELContext nxcontext = getLocalContext(context); 116 // XXX should invoke first... 117 return originalValueExpression.getType(nxcontext); 118 } 119 120 @Override 121 public Object getValue(ELContext context) { 122 ELContext nxcontext = getLocalContext(context); 123 Object res = null; 124 if (originalValueExpression != null) { 125 res = originalValueExpression.getValue(nxcontext); 126 if (res instanceof String) { 127 String expression = (String) res; 128 if (ComponentTagUtils.isValueReference(expression)) { 129 FacesContext faces = FacesContext.getCurrentInstance(); 130 Application app = faces.getApplication(); 131 ExpressionFactory factory = app.getExpressionFactory(); 132 ValueExpression newExpr = factory.createValueExpression(nxcontext, expression, Object.class); 133 try { 134 res = newExpr.getValue(nxcontext); 135 } catch (ELException err) { 136 log.error(String.format("Error processing expression %s: %s", expression, err)); 137 res = null; 138 } 139 } else { 140 res = expression; 141 } 142 } 143 } 144 return res; 145 } 146 147 @Override 148 public boolean isReadOnly(ELContext context) { 149 return true; 150 } 151 152 @Override 153 public void setValue(ELContext context, Object value) { 154 // do nothing 155 } 156 157 // Externalizable interface 158 159 public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { 160 originalValueExpression = (ValueExpression) in.readObject(); 161 } 162 163 public void writeExternal(ObjectOutput out) throws IOException { 164 out.writeObject(originalValueExpression); 165 } 166 167}