Java tutorial
/** * License Agreement. * * Rich Faces - Natural Ajax for Java Server Faces (JSF) * * Copyright (C) 2007 Exadel, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1 as published by the Free Software Foundation. * * 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. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package org.richfaces.el; import javax.el.ELContext; import javax.el.ExpressionFactory; import javax.el.ValueExpression; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Class provides EL parsing for filter and sort attributes of columns component. * @author Andrey Markavtsov * */ public class ELBuilder { /** Log */ Log log = LogFactory.getLog(ELBuilder.class); /** Original value expression string */ String[] orig; /** Result buffer */ StringBuffer res = new StringBuffer(); int l; /** Columns var string */ String var; /** Columns index string */ String index; /** Replacement to change var string */ String varReplacement; /** Replacement to change index string */ String indexReplacement; int varL; int indexL; boolean isLiteral; String postFix; /** * Constructor * @param orig - original value expression string * @param var - columns var string * @param index - columns index string * @param varR - replacement for var * @param indexR - replacement for index */ public ELBuilder(String orig, String var, String index, String varR, String indexR) { this.orig = orig.split("#"); this.var = var; this.index = index; this.varReplacement = varR; this.indexReplacement = indexR; varL = var.length(); indexL = index.length(); } /** * Parsing method * @return String parsing result */ public String parse() { try { for (String s : orig) { if (s != null && s.trim().length() > 0) { String trim = trimEL(s); if (!isLiteral) { l = trim.length(); res.append("#{"); internalParse(trim); res.append("}"); res.append(postFix); } else { res.append(s); } } } } catch (Exception e) { log.error("Error occured during ValueExpression parsing. Keep old expression. " + e); res.append(orig); } return res.toString(); } /** * Creates new expression using replacements provided * @param expr - original expression * @param expectedType - expected type * @param factory - expression factory * @param elContext - El context * @param var - var string * @param index - index string * @param varR - replacement for var * @param indexR - replacement for index * @return */ public static ValueExpression createValueExpression(String expr, Class<?> expectedType, ExpressionFactory factory, ELContext elContext, String var, String index, String varR, String indexR) { ELBuilder builder = new ELBuilder(expr, var, index, varR, indexR); String newExpr = builder.parse(); return factory.createValueExpression(elContext, newExpr, expectedType); } /** * Evaluates expression body * @param orig - original expression * @return */ private String trimEL(String orig) { int end = orig.lastIndexOf("}"); if (orig.startsWith("{") && end != -1) { isLiteral = false; postFix = (end + 1 < orig.length()) ? orig.substring(end + 1) : ""; return orig.substring(1, end); } isLiteral = true; return orig; } /** * Returns var replacement * @param expr * @return */ public static String getVarReplacement(String expr) { int start = 0; int end = 0; int l = expr.length(); boolean f = false; boolean f2 = true; for (int i = 0; i < l; i++) { char c = expr.charAt(i); if (c == '#') { f = true; } else if (c == '}') { end = i; } else if (c == '{' && f && f2) { start = (i + 1 < l) ? i + 1 : i; f2 = false; } } return (end > start) ? expr.substring(start, end) : null; } private int internalParse(String s) { final char firstVar = var.charAt(0); final char firstIndex = index.charAt(0); for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); if (c == firstIndex) { i = parseIndex(s, i, c); } else if (c == firstVar) { i = parseVar(s, i, c); } else if (isQuote(c)) { i = parseString(s, i, c); } else { res.append(c); } } return 0; } private int parseIndex(String s, int i, char c) { if (s.indexOf(index, i) == i) { Character before = (i != 0) ? s.charAt(i - 1) : null; Character after = (i + indexL < l) ? s.charAt(i + indexL) : null; if (isIndex(c, before, after)) { res.append(indexReplacement); return i + indexL - 1; } else { res.append(c); return i++; } } res.append(c); return i; } private int parseVar(String s, int i, char c) { if (s.indexOf(var, i) == i) { Character before = (i != 0) ? s.charAt(i - 1) : null; Character after = (i + varL < l) ? s.charAt(i + varL) : null; if (isVar(c, before, after)) { res.append(varReplacement); return i + varL - 1; } else { res.append(c); return i++; } } res.append(c); return i; } private int parseString(String s, int i, char c) { res.append(s.charAt(i)); int j = i++; while (j < l) { if (isQuote(s.charAt(j))) { break; } else { res.append(s.charAt(j)); } j++; } return j; } private boolean isIndex(Character c, Character before, Character after) { boolean ret = before == null || (Character.isWhitespace(before) || isMath(before) || before == '[' || before == '(' || before == '{'); if (ret) { ret = after == null || (Character.isWhitespace(after) || isMath(after) || after == ']' || before == ')' || before == '}'); } return ret; } private boolean isVar(Character c, Character before, Character after) { boolean ret = before == null || (Character.isWhitespace(before) || before == '(' || before == '{'); if (ret) { ret = after == null || (Character.isWhitespace(after) || after == ')' || after == '(' || after == ']' || after == '[' || after == '.'); } return ret; } private boolean isMath(Character c) { return c == '+' || c == '*' || c == '-' || c == '/' || c == '%' || c == '(' || c == ')'; } private boolean isQuote(Character c) { return c == '\'' || c == '\"'; } }