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.MethodExpression; 028 import javax.el.ValueExpression; 029 import javax.faces.component.ActionSource; 030 import javax.faces.component.ContextCallback; 031 import javax.faces.component.EditableValueHolder; 032 import javax.faces.component.NamingContainer; 033 import javax.faces.component.UIComponent; 034 import javax.faces.component.ValueHolder; 035 import javax.faces.context.FacesContext; 036 import javax.faces.el.EvaluationException; 037 import javax.faces.el.MethodBinding; 038 import javax.faces.event.AbortProcessingException; 039 import javax.faces.event.FacesEvent; 040 import javax.faces.validator.MethodExpressionValidator; 041 import java.util.Comparator; 042 043 public class FacesUtilsEL { 044 045 private static final Logger LOG = LoggerFactory.getLogger(FacesUtilsEL.class); 046 047 public static boolean invokeOnComponent( 048 FacesContext context, UIComponent component, String clientId, ContextCallback callback) { 049 String thisClientId = component.getClientId(context); 050 051 if (clientId.equals(thisClientId)) { 052 callback.invokeContextCallback(context, component); 053 return true; 054 } else if (component instanceof NamingContainer) { 055 // This component is a naming container. If the client id shows it's inside this naming container, 056 // then process further. 057 // Otherwise we know the client id we're looking for is not in this naming container, 058 // so for improved performance short circuit and return false. 059 if (clientId.startsWith(thisClientId) 060 && (clientId.charAt(thisClientId.length()) == NamingContainer.SEPARATOR_CHAR)) { 061 if (invokeOnComponentFacetsAndChildren(context, component, clientId, callback)) { 062 return true; 063 } 064 } 065 } else { 066 if (invokeOnComponentFacetsAndChildren(context, component, clientId, callback)) { 067 return true; 068 } 069 } 070 071 return false; 072 } 073 074 private static boolean invokeOnComponentFacetsAndChildren( 075 FacesContext context, UIComponent component, String clientId, ContextCallback callback) { 076 for (java.util.Iterator<UIComponent> it = component.getFacetsAndChildren(); it.hasNext();) { 077 UIComponent child = it.next(); 078 079 if (child.invokeOnComponent(context, clientId, callback)) { 080 return true; 081 } 082 } 083 return false; 084 } 085 086 public static void invokeMethodBinding(FacesContext facesContext, MethodBinding methodBinding, FacesEvent event) { 087 if (methodBinding != null && event != null) { 088 try { 089 methodBinding.invoke(facesContext, new Object[]{event}); 090 } catch (EvaluationException e) { 091 Throwable cause = e.getCause(); 092 if (cause instanceof AbortProcessingException) { 093 throw (AbortProcessingException) cause; 094 } else { 095 throw e; 096 } 097 } 098 } 099 } 100 101 public static void invokeMethodExpression( 102 FacesContext facesContext, MethodExpression methodExpression, FacesEvent event) { 103 104 if (methodExpression != null && event != null) { 105 try { 106 methodExpression.invoke(facesContext.getELContext(), new Object[]{event}); 107 } catch (Exception e) { 108 throw new AbortProcessingException(e); 109 } 110 } 111 } 112 113 public static Object getValueFromValueBindingOrValueExpression( 114 FacesContext context, UIComponent component, String name) { 115 return component.getValueExpression(name).getValue(context.getELContext()); 116 } 117 118 119 public static boolean hasValueBindingOrValueExpression(UIComponent component, String name) { 120 return component.getValueExpression(name) != null; 121 } 122 123 public static boolean isReadonlyValueBindingOrValueExpression( 124 FacesContext context, UIComponent component, String name) { 125 return component.getValueExpression(name).isReadOnly(context.getELContext()); 126 } 127 128 129 public static String getExpressionString(UIComponent component, String name) { 130 return component.getValueExpression(name).getExpressionString(); 131 } 132 133 public static void setValueOfBindingOrExpression( 134 FacesContext context, Object value, UIComponent component, String bindingName) { 135 ValueExpression ve = component.getValueExpression(bindingName); 136 if (ve != null) { 137 ve.setValue(context.getELContext(), value); 138 } 139 } 140 141 public static void setValueOfBindingOrExpression( 142 FacesContext context, Object value, Object bindingOrExpression) { 143 if (bindingOrExpression instanceof ValueExpression) { 144 ValueExpression ve = (ValueExpression) bindingOrExpression; 145 ve.setValue(context.getELContext(), value); 146 } 147 } 148 149 public static void copyValueBindingOrValueExpression( 150 UIComponent fromComponent, String fromName, UIComponent toComponent, String toName) { 151 ValueExpression ve = fromComponent.getValueExpression(fromName); 152 if (ve != null) { 153 toComponent.setValueExpression(toName, ve); 154 } 155 } 156 157 public static Object getValueFromBindingOrExpression(Object obj) { 158 if (obj instanceof ValueExpression) { 159 ValueExpression expression = (ValueExpression) obj; 160 return expression.getValue(FacesContext.getCurrentInstance().getELContext()); 161 } 162 return null; 163 } 164 165 public static void setValidator(EditableValueHolder editableValueHolder, Object validator) { 166 if (validator instanceof MethodExpression) { 167 editableValueHolder.addValidator(new MethodExpressionValidator((MethodExpression) validator)); 168 } else { 169 LOG.error("Unknow instance for validator: " + (validator != null ? validator.getClass().getName() : validator)); 170 } 171 } 172 173 public static void setConverter(ValueHolder valueHolder, Object converterExpression) { 174 if (converterExpression instanceof ValueExpression) { 175 ValueExpression expression = (ValueExpression) converterExpression; 176 if (!expression.isLiteralText()) { 177 ((UIComponent) valueHolder).setValueExpression("converter", expression); 178 } else { 179 valueHolder.setConverter(FacesContext.getCurrentInstance() 180 .getApplication().createConverter(expression.getExpressionString())); 181 } 182 } 183 } 184 185 public static void setBindingOrExpression(UIComponent component, String name, Object valueBindingOrExpression) { 186 component.setValueExpression(name, (ValueExpression) valueBindingOrExpression); 187 } 188 189 public static void addBindingOrExpressionTabChangeListener( 190 TabChangeSource source, String type, Object bindingOrExpression) { 191 if (bindingOrExpression instanceof ValueExpression) { 192 source.addTabChangeListener(new ValueExpressionTabChangeListener(type, (ValueExpression) bindingOrExpression)); 193 } 194 } 195 196 public static Comparator getBindingOrExpressionComparator( 197 FacesContext facesContext, UIComponent child, String var, boolean descending, Comparator comparator) { 198 ValueExpression valueBinding = child.getValueExpression("value"); 199 return new ValueExpressionComparator(facesContext, var, valueBinding, descending, comparator); 200 } 201 202 public static void addBindingOrExpressionPopupActionListener(ActionSource actionSource, Object bindingOrExpression) { 203 actionSource.addActionListener(new ValueExpressionPopupActionListener((ValueExpression) bindingOrExpression)); 204 } 205 }