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