001/* 002 * (C) Copyright 2007 Nuxeo SA (http://nuxeo.com/) and others. 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 * Contributors: 017 * Nuxeo - initial API and implementation 018 * 019 * $Id: MetaValueExpression.java 28491 2008-01-04 19:04:30Z sfermigier $ 020 */ 021 022package org.nuxeo.ecm.platform.ui.web.binding; 023 024import java.io.IOException; 025import java.io.ObjectInput; 026import java.io.ObjectOutput; 027import java.io.Serializable; 028 029import javax.el.ELContext; 030import javax.el.ELException; 031import javax.el.ExpressionFactory; 032import javax.el.FunctionMapper; 033import javax.el.ValueExpression; 034import javax.el.VariableMapper; 035import javax.faces.application.Application; 036import javax.faces.context.FacesContext; 037 038import org.apache.commons.logging.Log; 039import org.apache.commons.logging.LogFactory; 040import org.nuxeo.ecm.platform.ui.web.util.ComponentTagUtils; 041 042/** 043 * Meta value expression used to invoke the EL expression that is already the result of a value expression. 044 * 045 * @author <a href="mailto:at@nuxeo.com">Anahide Tchertchian</a> 046 */ 047public class MetaValueExpression extends ValueExpression implements Serializable { 048 049 private static final long serialVersionUID = -2721042412903607760L; 050 051 private static final Log log = LogFactory.getLog(MetaValueExpression.class); 052 053 private ValueExpression originalValueExpression; 054 055 private FunctionMapper fnMapper; 056 057 private VariableMapper varMapper; 058 059 public MetaValueExpression(ValueExpression originalValueExpression) { 060 this(originalValueExpression, null, null); 061 } 062 063 public MetaValueExpression(ValueExpression originalValueExpression, FunctionMapper fnMapper, 064 VariableMapper varMapper) { 065 this.originalValueExpression = originalValueExpression; 066 this.fnMapper = fnMapper; 067 this.varMapper = varMapper; 068 } 069 070 // Expression interface 071 072 @Override 073 public boolean equals(Object obj) { 074 if (this == obj) { 075 return true; 076 } 077 if (!(obj instanceof MetaValueExpression)) { 078 return false; 079 } 080 MetaValueExpression other = (MetaValueExpression) obj; 081 return originalValueExpression.equals(other.originalValueExpression); 082 } 083 084 @Override 085 public int hashCode() { 086 return originalValueExpression.hashCode(); 087 } 088 089 @Override 090 public String getExpressionString() { 091 return originalValueExpression.getExpressionString(); 092 } 093 094 @Override 095 public boolean isLiteralText() { 096 // XXX should invoke first 097 return originalValueExpression.isLiteralText(); 098 } 099 100 // ValueExpression interface 101 102 @Override 103 public Class<?> getExpectedType() { 104 // XXX should invoke first 105 return originalValueExpression.getExpectedType(); 106 } 107 108 private ELContext getLocalContext(ELContext context) { 109 if (fnMapper == null && varMapper == null) { 110 return context; 111 } 112 return new org.nuxeo.ecm.platform.ui.web.binding.EvaluationContext(context, fnMapper, varMapper); 113 } 114 115 @Override 116 public Class<?> getType(ELContext context) { 117 ELContext nxcontext = getLocalContext(context); 118 // XXX should invoke first... 119 return originalValueExpression.getType(nxcontext); 120 } 121 122 @Override 123 public Object getValue(ELContext context) { 124 ELContext nxcontext = getLocalContext(context); 125 Object res = null; 126 if (originalValueExpression != null) { 127 res = originalValueExpression.getValue(nxcontext); 128 if (res instanceof String) { 129 String expression = (String) res; 130 if (ComponentTagUtils.isValueReference(expression)) { 131 FacesContext faces = FacesContext.getCurrentInstance(); 132 Application app = faces.getApplication(); 133 ExpressionFactory factory = app.getExpressionFactory(); 134 ValueExpression newExpr = factory.createValueExpression(nxcontext, expression, Object.class); 135 try { 136 res = newExpr.getValue(nxcontext); 137 } catch (ELException err) { 138 log.error("Error processing expression " + expression + ": " + err); 139 res = null; 140 } 141 } else { 142 res = expression; 143 } 144 } 145 } 146 return res; 147 } 148 149 @Override 150 public boolean isReadOnly(ELContext context) { 151 return true; 152 } 153 154 @Override 155 public void setValue(ELContext context, Object value) { 156 // do nothing 157 } 158 159 // Externalizable interface 160 161 public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { 162 originalValueExpression = (ValueExpression) in.readObject(); 163 } 164 165 public void writeExternal(ObjectOutput out) throws IOException { 166 out.writeObject(originalValueExpression); 167 } 168 169}