📄 elparserhelper.java
字号:
/* * Copyright 2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.apache.myfaces.el;import java.io.StringReader;import java.util.List;import javax.faces.application.Application;import javax.faces.component.UIComponent;import javax.faces.context.FacesContext;import javax.faces.el.EvaluationException;import javax.faces.el.ReferenceSyntaxException;import javax.servlet.jsp.el.ELException;import javax.servlet.jsp.el.FunctionMapper;import javax.servlet.jsp.el.VariableResolver;import org.apache.myfaces.util.StringUtils;import org.apache.commons.el.ArraySuffix;import org.apache.commons.el.BinaryOperatorExpression;import org.apache.commons.el.Coercions;import org.apache.commons.el.ComplexValue;import org.apache.commons.el.ConditionalExpression;import org.apache.commons.el.Expression;import org.apache.commons.el.ExpressionString;import org.apache.commons.el.FunctionInvocation;import org.apache.commons.el.Literal;import org.apache.commons.el.Logger;import org.apache.commons.el.NamedValue;import org.apache.commons.el.PropertySuffix;import org.apache.commons.el.UnaryOperatorExpression;import org.apache.commons.el.ValueSuffix;import org.apache.commons.el.parser.ELParser;import org.apache.commons.el.parser.ParseException;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;/** * Utility class to implement support functionality to "morph" JSP EL into JSF * EL * * @author Anton Koinov (latest modification by $Author: svieujot $) * @version $Revision: 1.7 $ $Date: 2005/04/11 17:39:36 $ * * $Log: ELParserHelper.java,v $ * Revision 1.7 2005/04/11 17:39:36 svieujot * ELParserHelper : Fix a String IndexOutOfBoundsException & several bugs in toJspELExpression. * Add a JUnit Test. * * Revision 1.6 2004/10/13 11:51:00 matze * renamed packages to org.apache * * Revision 1.5 2004/09/28 19:11:50 dave0000 * uppercase static final prop * remove redundant code * * Revision 1.4 2004/07/01 22:05:11 mwessendorf * ASF switch * * Revision 1.3 2004/05/10 05:30:13 dave0000 * Fix issue with setting Managed Bean to a wrong scope * * Revision 1.2 2004/04/08 23:22:18 dave0000 * remove assert statements * */public class ELParserHelper{ static final Log log = LogFactory.getLog(ELParserHelper.class); public static final Logger LOGGER = new Logger(System.out); private ELParserHelper() { // util class, do not instantiate } /** * Gets the parsed form of the given expression string. Returns either an * Expression or ExpressionString. */ public static Object parseExpression(String expressionString) { expressionString = toJspElExpression(expressionString); ELParser parser = new ELParser(new StringReader(expressionString)); try { Object expression = parser.ExpressionString(); if (!(expression instanceof Expression) && !(expression instanceof ExpressionString)) { throw new ReferenceSyntaxException("Invalid expression: '" + expressionString + "'. Parsed Expression of unexpected type " + expression.getClass().getName()); } replaceSuffixes(expression); return expression; } catch (ParseException e) { String msg = "Invalid expression: '" + expressionString + "'"; log.debug(msg, e); throw new ReferenceSyntaxException(msg, e); } } /** * Convert ValueBinding syntax #{ } to JSP EL syntax ${ } * * @param expressionString <code>ValueBinding</code> reference expression * * @return JSP EL compatible expression */ static String toJspElExpression(String expressionString) { StringBuffer sb = new StringBuffer(expressionString.length()); int remainsPos = 0; for (int posOpenBrace = expressionString.indexOf('{'); posOpenBrace >= 0; posOpenBrace = expressionString.indexOf('{', remainsPos)) { if (posOpenBrace > 0) { if( posOpenBrace-1 > remainsPos ) sb.append(expressionString.substring(remainsPos, posOpenBrace - 1)); if (expressionString.charAt(posOpenBrace - 1) == '$') { sb.append("${'${'}"); remainsPos = posOpenBrace+1; continue; } else if (expressionString.charAt(posOpenBrace - 1) == '#') {// // TODO: should use \\ as escape for \ always, not just when before #{// // allow use of '\' as escape symbol for #{ (for compatibility with Sun's extended implementation)// if (isEscaped(expressionString, posOpenBrace - 1)) // {// escapes: {// for (int i = sb.length() - 1; i >= 0; i--)// {// if (sb.charAt(i) != '\\')// {// sb.setLength(// sb.length() - (sb.length() - i) / 2);// break escapes;// }// }// sb.setLength(sb.length() / 2);// }// sb.append("#{");// }// else// { sb.append("${"); int posCloseBrace = indexOfMatchingClosingBrace(expressionString, posOpenBrace); sb.append(expressionString.substring(posOpenBrace + 1, posCloseBrace + 1)); remainsPos = posCloseBrace + 1; continue;// } }else{ if( posOpenBrace > remainsPos ) sb.append( expressionString.charAt(posOpenBrace - 1) ); } } // Standalone brace sb.append('{'); remainsPos = posOpenBrace + 1; } sb.append(expressionString.substring(remainsPos)); // Create a new String to shrink mem size since we are caching return new String(sb.toString()); } private static int findQuote(String expressionString, int start) { int indexofSingleQuote = expressionString.indexOf('\'', start); int indexofDoubleQuote = expressionString.indexOf('"', start); return StringUtils.minIndex(indexofSingleQuote, indexofDoubleQuote); } /** * Return the index of the matching closing brace, skipping over quoted text * * @param expressionString string to search * @param indexofOpeningBrace the location of opening brace to match * * @return the index of the matching closing brace * * @throws ReferenceSyntaxException if matching brace cannot be found */ private static int indexOfMatchingClosingBrace(String expressionString, int indexofOpeningBrace) { int len = expressionString.length(); int i = indexofOpeningBrace + 1; // Loop through quoted strings for (;;) { if (i >= len) { throw new ReferenceSyntaxException( "Missing closing brace. Expression: '" + expressionString + "'"); } int indexofClosingBrace = expressionString.indexOf('}', i); i = StringUtils.minIndex(indexofClosingBrace, findQuote( expressionString, i)); if (i < 0) { // No delimiter found throw new ReferenceSyntaxException( "Missing closing brace. Expression: '" + expressionString + "'"); } // 1. If quoted literal, find closing quote if (i != indexofClosingBrace) { i = indexOfMatchingClosingQuote(expressionString, i) + 1; if (i == 0) { // Note: if no match, i==0 because -1 + 1 = 0 throw new ReferenceSyntaxException( "Missing closing quote. Expression: '" + expressionString + "'"); } } else { // Closing brace return i; } } } /** * Returns the index of the matching closing quote, skipping over escaped * quotes * * @param expressionString string to scan * @param indexOfOpeningQuote start from this position in the string * @return -1 if no match, the index of closing quote otherwise */ private static int indexOfMatchingClosingQuote(String expressionString, int indexOfOpeningQuote) { char quote = expressionString.charAt(indexOfOpeningQuote); for (int i = expressionString.indexOf(quote, indexOfOpeningQuote + 1); i >= 0; i = expressionString.indexOf(quote, i + 1)) { if (!isEscaped(expressionString, i)) { return i; } } // No matching quote found return -1; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -