/*
* (C) Copyright 2007 Nuxeo SAS (http://nuxeo.com/) and contributors.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser General Public License
* (LGPL) version 2.1 which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/lgpl.html
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* Contributors:
* Nuxeo - initial API and implementation
*
* $Id: ComponentTagUtils.java 28610 2008-01-09 17:13:52Z sfermigier $
*/
package org.nuxeo.ecm.platform.ui.web.util;
import javax.el.ELContext;
import javax.el.ExpressionFactory;
import javax.el.ValueExpression;
import javax.faces.application.Application;
import javax.faces.context.FacesContext;
import javax.faces.view.facelets.FaceletContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Component tag utils.
*
* @author <a href="mailto:at@nuxeo.com">Anahide Tchertchian</a>
*/
public final class ComponentTagUtils {
private static final Log log = LogFactory.getLog(ComponentTagUtils.class);
// Utility class.
private ComponentTagUtils() {
}
/**
* Returns true if the specified value contains a value expression, e.g the
* start and end of EL markers.
*
* @param value the value to evaluate, returns false if null
*/
public static boolean isValueReference(String value) {
if (value == null) {
return false;
}
return value.contains("#{") && value.indexOf("#{") < value.indexOf('}')
|| value.contains("${")
&& value.indexOf("${") < value.indexOf('}');
}
/**
* Returns true if the specified value is a value expression, e.g starting
* and ending with EL markers after being trimmed.
*
* @param value the value to evaluate, returns false if null
* @since 5.6
*/
public static boolean isStrictValueReference(String value) {
if (value == null) {
return false;
}
value = value.trim();
return (value.startsWith("#{")
&& value.indexOf("#{") < value.indexOf('}') && value.endsWith("}"))
|| (value.startsWith("${")
&& value.indexOf("${") < value.indexOf('}') && value.endsWith("}"));
}
/**
* Returns a value name for given strict value reference. If reference is
* #{foo} or ${foo}, will return "foo".
*
* @since 5.6
* @throws IllegalArgumentException if reference is null or
* {@link #isStrictValueReference(String)} returns false.
* @param valueReference
*/
public static String getBareValueName(String valueReference) {
if (!isStrictValueReference(valueReference)) {
throw new IllegalArgumentException(String.format(
"Invalid value reference '%s'", valueReference));
}
return valueReference.substring(2, valueReference.length() - 1);
}
/**
* Returns true if the specified value conforms to the syntax requirements
* of a method binding expression.
* <p>
* The method can have parameters and the expression must use parentheses
* even if no parameters are needed.
*
* @param value the value to evaluate (not null)
* @deprecated since 5.5: method and value references are now equivalent
* with jboss EL
*/
@Deprecated
public static boolean isMethodReference(String value) {
boolean isValue = isValueReference(value);
if (isValue) {
if (value.contains("(")
&& value.indexOf('(') < value.indexOf(')')
// make sure it's not a function
&& (!value.contains(":") || value.indexOf(':') > value.indexOf('('))) {
return true;
}
}
return false;
}
/**
* Resolves an expression from a given faces context.
* <p>
* Resolves the expression a second time when first resolution gives a
* String value using the EL Expression syntax.
* <p>
* Does not throw any error when resolution fails (only logs an error
* message).
*
* @see #resolveElExpression(FaceletContext, String)
*/
public static Object resolveElExpression(FacesContext context,
String elExpression) {
if (!isValueReference(elExpression)) {
// literal
return elExpression;
} else {
if (context == null) {
log.error(String.format(
"FacesContext is null => cannot resolve el expression '%s'",
elExpression));
return null;
}
// expression => evaluate
Application app = context.getApplication();
try {
return app.evaluateExpressionGet(context, elExpression,
Object.class);
} catch (Exception e) {
log.error(String.format(
"Faces context: Error processing expression '%s'",
elExpression), e);
return null;
}
}
}
/**
* Resolves given value expression as string and sets given value on it.
*
* @since 6.0
*/
public static void applyValueExpression(FacesContext context,
String elExpression, Object value) {
if (!isStrictValueReference(elExpression)) {
log.warn(String.format("Cannot set value '%s' for expression '%s'",
value, elExpression));
} else {
if (context == null) {
log.error(String.format(
"FacesContext is null => cannot resolve el expression '%s'",
elExpression));
return;
}
Application app = context.getApplication();
ExpressionFactory eFactory = app.getExpressionFactory();
ELContext elContext = context.getELContext();
try {
ValueExpression vExpression = eFactory.createValueExpression(
elContext, elExpression, Object.class);
vExpression.setValue(elContext, value);
} catch (Exception e) {
log.error(String.format(
"Error setting value '%s' for expression '%s'", value,
elExpression), e);
}
}
}
/**
* Resolves an expression from a given facelet context, using its
* {@link ExpressionFactory} that can hold a wider context than the faces
* context behind it.
* <p>
* Resolves the expression a second time when first resolution gives a
* String value using the EL Expression syntax.
* <p>
* Does not throw any error when resolution fails (only logs an error
* message).
*/
public static Object resolveElExpression(FaceletContext faceletContext,
String elExpression) {
if (!isValueReference(elExpression)) {
// literal
return elExpression;
} else {
if (faceletContext == null) {
log.error(String.format(
"FaceletContext is null => cannot resolve el expression '%s'",
elExpression));
return null;
}
// expression => evaluate
ExpressionFactory eFactory = faceletContext.getExpressionFactory();
ELContext elContext = faceletContext.getFacesContext().getELContext();
ValueExpression expr = eFactory.createValueExpression(
faceletContext, elExpression, Object.class);
try {
return expr.getValue(elContext);
} catch (Exception e) {
log.error(String.format(
"Facelet context: Error processing expression '%s'",
elExpression), e);
return null;
}
}
}
}