001 package org.apache.myfaces.tobago.compat; 002 003 /* 004 * Licensed to the Apache Software Foundation (ASF) under one or more 005 * contributor license agreements. See the NOTICE file distributed with 006 * this work for additional information regarding copyright ownership. 007 * The ASF licenses this file to You under the Apache License, Version 2.0 008 * (the "License"); you may not use this file except in compliance with 009 * the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 */ 019 020 import org.apache.myfaces.tobago.event.TabChangeSource; 021 import org.apache.myfaces.tobago.event.ValueExpressionPopupActionListener; 022 import org.apache.myfaces.tobago.event.ValueExpressionTabChangeListener; 023 import org.apache.myfaces.tobago.util.ValueExpressionComparator; 024 import org.slf4j.Logger; 025 import org.slf4j.LoggerFactory; 026 027 import javax.el.ExpressionFactory; 028 import javax.el.MethodExpression; 029 import javax.el.ValueExpression; 030 import javax.faces.component.ActionSource; 031 import javax.faces.component.ContextCallback; 032 import javax.faces.component.EditableValueHolder; 033 import javax.faces.component.NamingContainer; 034 import javax.faces.component.UIComponent; 035 import javax.faces.component.ValueHolder; 036 import javax.faces.context.FacesContext; 037 import javax.faces.el.EvaluationException; 038 import javax.faces.el.MethodBinding; 039 import javax.faces.event.AbortProcessingException; 040 import javax.faces.event.FacesEvent; 041 import javax.faces.validator.MethodExpressionValidator; 042 import java.util.Comparator; 043 044 public class FacesUtilsEL { 045 046 private static final Logger LOG = LoggerFactory.getLogger(FacesUtilsEL.class); 047 048 public static boolean invokeOnComponent( 049 FacesContext context, UIComponent component, String clientId, ContextCallback callback) { 050 String thisClientId = component.getClientId(context); 051 052 if (clientId.equals(thisClientId)) { 053 callback.invokeContextCallback(context, component); 054 return true; 055 } else if (component instanceof NamingContainer) { 056 // This component is a naming container. If the client id shows it's inside this naming container, 057 // then process further. 058 // Otherwise we know the client id we're looking for is not in this naming container, 059 // so for improved performance short circuit and return false. 060 if (clientId.startsWith(thisClientId) 061 && (clientId.charAt(thisClientId.length()) == NamingContainer.SEPARATOR_CHAR)) { 062 if (invokeOnComponentFacetsAndChildren(context, component, clientId, callback)) { 063 return true; 064 } 065 } 066 } else { 067 if (invokeOnComponentFacetsAndChildren(context, component, clientId, callback)) { 068 return true; 069 } 070 } 071 072 return false; 073 } 074 075 private static boolean invokeOnComponentFacetsAndChildren( 076 FacesContext context, UIComponent component, String clientId, ContextCallback callback) { 077 for (java.util.Iterator<UIComponent> it = component.getFacetsAndChildren(); it.hasNext();) { 078 UIComponent child = it.next(); 079 080 if (child.invokeOnComponent(context, clientId, callback)) { 081 return true; 082 } 083 } 084 return false; 085 } 086 087 public static void invokeMethodBinding(FacesContext facesContext, MethodBinding methodBinding, FacesEvent event) { 088 if (methodBinding != null && event != null) { 089 try { 090 methodBinding.invoke(facesContext, new Object[]{event}); 091 } catch (EvaluationException e) { 092 Throwable cause = e.getCause(); 093 if (cause instanceof AbortProcessingException) { 094 throw (AbortProcessingException) cause; 095 } else { 096 throw e; 097 } 098 } 099 } 100 } 101 102 public static void invokeMethodExpression( 103 FacesContext facesContext, MethodExpression methodExpression, FacesEvent event) { 104 105 if (methodExpression != null && event != null) { 106 try { 107 methodExpression.invoke(facesContext.getELContext(), new Object[]{event}); 108 } catch (Exception e) { 109 throw new AbortProcessingException(e); 110 } 111 } 112 } 113 114 public static Object getValueFromValueBindingOrValueExpression( 115 FacesContext context, UIComponent component, String name) { 116 return component.getValueExpression(name).getValue(context.getELContext()); 117 } 118 119 120 public static boolean hasValueBindingOrValueExpression(UIComponent component, String name) { 121 return component.getValueExpression(name) != null; 122 } 123 124 public static boolean isReadonlyValueBindingOrValueExpression( 125 FacesContext context, UIComponent component, String name) { 126 return component.getValueExpression(name).isReadOnly(context.getELContext()); 127 } 128 129 130 public static String getExpressionString(UIComponent component, String name) { 131 return component.getValueExpression(name).getExpressionString(); 132 } 133 134 public static void setValueOfBindingOrExpression( 135 FacesContext context, Object value, UIComponent component, String bindingName) { 136 ValueExpression ve = component.getValueExpression(bindingName); 137 if (ve != null) { 138 ve.setValue(context.getELContext(), value); 139 } 140 } 141 142 public static void setValueOfBindingOrExpression( 143 FacesContext context, Object value, Object bindingOrExpression) { 144 if (bindingOrExpression instanceof ValueExpression) { 145 ValueExpression ve = (ValueExpression) bindingOrExpression; 146 ve.setValue(context.getELContext(), value); 147 } 148 } 149 150 public static void copyValueBindingOrValueExpression( 151 UIComponent fromComponent, String fromName, UIComponent toComponent, String toName) { 152 ValueExpression ve = fromComponent.getValueExpression(fromName); 153 if (ve != null) { 154 toComponent.setValueExpression(toName, ve); 155 } 156 } 157 158 public static Object getValueFromBindingOrExpression(Object obj) { 159 if (obj instanceof ValueExpression) { 160 ValueExpression expression = (ValueExpression) obj; 161 return expression.getValue(FacesContext.getCurrentInstance().getELContext()); 162 } 163 return null; 164 } 165 166 public static Object createExpressionOrBinding(String string) { 167 FacesContext facesContext = FacesContext.getCurrentInstance(); 168 ExpressionFactory expressionFactory = facesContext.getApplication().getExpressionFactory(); 169 ValueExpression valueExpression = 170 expressionFactory.createValueExpression(facesContext.getELContext(), string, Object.class); 171 return valueExpression; 172 } 173 174 public static void setValidator(EditableValueHolder editableValueHolder, Object validator) { 175 if (validator instanceof MethodExpression) { 176 editableValueHolder.addValidator(new MethodExpressionValidator((MethodExpression) validator)); 177 } else { 178 LOG.error("Unknow instance for validator: " + (validator != null ? validator.getClass().getName() : validator)); 179 } 180 } 181 182 public static void setConverter(ValueHolder valueHolder, Object converterExpression) { 183 if (converterExpression instanceof ValueExpression) { 184 ValueExpression expression = (ValueExpression) converterExpression; 185 if (!expression.isLiteralText()) { 186 ((UIComponent) valueHolder).setValueExpression("converter", expression); 187 } else { 188 valueHolder.setConverter(FacesContext.getCurrentInstance() 189 .getApplication().createConverter(expression.getExpressionString())); 190 } 191 } 192 } 193 194 public static void setBindingOrExpression(UIComponent component, String name, Object valueBindingOrExpression) { 195 component.setValueExpression(name, (ValueExpression) valueBindingOrExpression); 196 } 197 198 public static void addBindingOrExpressionTabChangeListener( 199 TabChangeSource source, String type, Object bindingOrExpression) { 200 if (bindingOrExpression instanceof ValueExpression) { 201 source.addTabChangeListener(new ValueExpressionTabChangeListener(type, (ValueExpression) bindingOrExpression)); 202 } 203 } 204 205 public static Comparator getBindingOrExpressionComparator( 206 FacesContext facesContext, UIComponent child, String var, boolean descending, Comparator comparator) { 207 ValueExpression valueBinding = child.getValueExpression("value"); 208 return new ValueExpressionComparator(facesContext, var, valueBinding, descending, comparator); 209 } 210 211 public static void addBindingOrExpressionPopupActionListener(ActionSource actionSource, Object bindingOrExpression) { 212 actionSource.addActionListener(new ValueExpressionPopupActionListener((ValueExpression) bindingOrExpression)); 213 } 214 }