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: MetaMethodExpression.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.MethodExpression; 031import javax.el.MethodInfo; 032import javax.faces.application.Application; 033import javax.faces.context.FacesContext; 034 035import org.nuxeo.ecm.platform.ui.web.util.ComponentTagUtils; 036 037/** 038 * Meta method expression used to invoke the EL expression that is already the result of a method expression. 039 * <p> 040 * For instance it is useful to use this expression to provide action links defined in NXActions extensions with links 041 * like #{documentAction.createDocument('Domain')}. 042 * <p> 043 * There is no more than one level of abstraction: 044 * <ul> 045 * <li>the expression method value can be a standard method expression (with parameters or not); 046 * <li>the expression method value can result in another expression method value after being invoke, in which case it is 047 * reinvoked again using the same context; 048 * <li>no further method invoking will be performed. 049 * </ul> 050 * 051 * @author <a href="mailto:at@nuxeo.com">Anahide Tchertchian</a> 052 */ 053public class MetaMethodExpression extends MethodExpression implements Serializable { 054 055 private static final long serialVersionUID = -2721042412903607760L; 056 057 private MethodExpression originalMethodExpression; 058 059 public MetaMethodExpression(MethodExpression originalMethodExpression) { 060 this.originalMethodExpression = originalMethodExpression; 061 } 062 063 // Expression interface 064 065 @Override 066 public boolean equals(Object obj) { 067 if (this == obj) { 068 return true; 069 } 070 if (!(obj instanceof MetaMethodExpression)) { 071 return false; 072 } 073 MetaMethodExpression other = (MetaMethodExpression) obj; 074 return originalMethodExpression.equals(other.originalMethodExpression); 075 } 076 077 @Override 078 public int hashCode() { 079 return originalMethodExpression.hashCode(); 080 } 081 082 @Override 083 public String getExpressionString() { 084 return originalMethodExpression.getExpressionString(); 085 } 086 087 @Override 088 public boolean isLiteralText() { 089 return originalMethodExpression.isLiteralText(); 090 } 091 092 // MethodExpression interface 093 094 @Override 095 public MethodInfo getMethodInfo(ELContext context) { 096 // TODO Auto-generated method stub 097 return null; 098 } 099 100 @Override 101 public Object invoke(ELContext context, Object[] params) { 102 Object res = null; 103 if (originalMethodExpression != null) { 104 res = originalMethodExpression.invoke(context, params); 105 if (res instanceof String) { 106 String expression = (String) res; 107 if (ComponentTagUtils.isValueReference(expression)) { 108 FacesContext faces = FacesContext.getCurrentInstance(); 109 Application app = faces.getApplication(); 110 ExpressionFactory factory = app.getExpressionFactory(); 111 MethodExpression newMeth = factory.createMethodExpression(context, expression, Object.class, 112 new Class[0]); 113 try { 114 res = newMeth.invoke(context, null); 115 } catch (ELException e) { 116 throw e; 117 } catch (RuntimeException e) { 118 throw new ELException(e); 119 } 120 } else { 121 res = expression; 122 } 123 } 124 } 125 return res; 126 } 127 128 // Externalizable interface 129 130 public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { 131 originalMethodExpression = (MethodExpression) in.readObject(); 132 } 133 134 public void writeExternal(ObjectOutput out) throws IOException { 135 out.writeObject(originalMethodExpression); 136 } 137 138}