📄 jsputil.java
字号:
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.jasper.compiler;
import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.Vector;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
import javax.el.FunctionMapper;
import javax.servlet.jsp.el.ExpressionEvaluator;
import org.apache.el.ExpressionFactoryImpl;
import org.apache.jasper.Constants;
import org.apache.jasper.JasperException;
import org.apache.jasper.JspCompilationContext;
import org.apache.jasper.el.ExpressionEvaluatorImpl;
import org.xml.sax.Attributes;
/**
* This class has all the utility method(s).
* Ideally should move all the bean containers here.
*
* @author Mandar Raje.
* @author Rajiv Mordani.
* @author Danno Ferrin
* @author Pierre Delisle
* @author Shawn Bayern
* @author Mark Roth
*/
public class JspUtil {
private static final String WEB_INF_TAGS = "/WEB-INF/tags/";
private static final String META_INF_TAGS = "/META-INF/tags/";
// Delimiters for request-time expressions (JSP and XML syntax)
private static final String OPEN_EXPR = "<%=";
private static final String CLOSE_EXPR = "%>";
private static final String OPEN_EXPR_XML = "%=";
private static final String CLOSE_EXPR_XML = "%";
private static int tempSequenceNumber = 0;
//private static ExpressionEvaluatorImpl expressionEvaluator
//= new ExpressionEvaluatorImpl();
//tc6
private final static ExpressionEvaluator expressionEvaluator =
new ExpressionEvaluatorImpl(new ExpressionFactoryImpl());
private static final String javaKeywords[] = {
"abstract", "assert", "boolean", "break", "byte", "case",
"catch", "char", "class", "const", "continue",
"default", "do", "double", "else", "enum", "extends",
"final", "finally", "float", "for", "goto",
"if", "implements", "import", "instanceof", "int",
"interface", "long", "native", "new", "package",
"private", "protected", "public", "return", "short",
"static", "strictfp", "super", "switch", "synchronized",
"this", "throws", "transient", "try", "void",
"volatile", "while" };
public static final int CHUNKSIZE = 1024;
public static char[] removeQuotes(char []chars) {
CharArrayWriter caw = new CharArrayWriter();
for (int i = 0; i < chars.length; i++) {
if (chars[i] == '%' && chars[i+1] == '\\' &&
chars[i+2] == '>') {
caw.write('%');
caw.write('>');
i = i + 2;
} else {
caw.write(chars[i]);
}
}
return caw.toCharArray();
}
public static char[] escapeQuotes (char []chars) {
// Prescan to convert %\> to %>
String s = new String(chars);
while (true) {
int n = s.indexOf("%\\>");
if (n < 0)
break;
StringBuffer sb = new StringBuffer(s.substring(0, n));
sb.append("%>");
sb.append(s.substring(n + 3));
s = sb.toString();
}
chars = s.toCharArray();
return (chars);
// Escape all backslashes not inside a Java string literal
/*
CharArrayWriter caw = new CharArrayWriter();
boolean inJavaString = false;
for (int i = 0; i < chars.length; i++) {
if (chars[i] == '"') inJavaString = !inJavaString;
// escape out the escape character
if (!inJavaString && (chars[i] == '\\')) caw.write('\\');
caw.write(chars[i]);
}
return caw.toCharArray();
*/
}
/**
* Checks if the token is a runtime expression.
* In standard JSP syntax, a runtime expression starts with '<%' and
* ends with '%>'. When the JSP document is in XML syntax, a runtime
* expression starts with '%=' and ends with '%'.
*
* @param token The token to be checked
* return whether the token is a runtime expression or not.
*/
public static boolean isExpression(String token, boolean isXml) {
String openExpr;
String closeExpr;
if (isXml) {
openExpr = OPEN_EXPR_XML;
closeExpr = CLOSE_EXPR_XML;
} else {
openExpr = OPEN_EXPR;
closeExpr = CLOSE_EXPR;
}
if (token.startsWith(openExpr) && token.endsWith(closeExpr)) {
return true;
} else {
return false;
}
}
/**
* @return the "expression" part of a runtime expression,
* taking the delimiters out.
*/
public static String getExpr (String expression, boolean isXml) {
String returnString;
String openExpr;
String closeExpr;
if (isXml) {
openExpr = OPEN_EXPR_XML;
closeExpr = CLOSE_EXPR_XML;
} else {
openExpr = OPEN_EXPR;
closeExpr = CLOSE_EXPR;
}
int length = expression.length();
if (expression.startsWith(openExpr) &&
expression.endsWith(closeExpr)) {
returnString = expression.substring(
openExpr.length(), length - closeExpr.length());
} else {
returnString = "";
}
return returnString;
}
/**
* Takes a potential expression and converts it into XML form
*/
public static String getExprInXml(String expression) {
String returnString;
int length = expression.length();
if (expression.startsWith(OPEN_EXPR)
&& expression.endsWith(CLOSE_EXPR)) {
returnString = expression.substring (1, length - 1);
} else {
returnString = expression;
}
return escapeXml(returnString.replace(Constants.ESC, '$'));
}
/**
* Checks to see if the given scope is valid.
*
* @param scope The scope to be checked
* @param n The Node containing the 'scope' attribute whose value is to be
* checked
* @param err error dispatcher
*
* @throws JasperException if scope is not null and different from
* "page", "request", "session", and
* "application"
*/
public static void checkScope(String scope, Node n, ErrorDispatcher err)
throws JasperException {
if (scope != null && !scope.equals("page") && !scope.equals("request")
&& !scope.equals("session") && !scope.equals("application")) {
err.jspError(n, "jsp.error.invalid.scope", scope);
}
}
/**
* Checks if all mandatory attributes are present and if all attributes
* present have valid names. Checks attributes specified as XML-style
* attributes as well as attributes specified using the jsp:attribute
* standard action.
*/
public static void checkAttributes(String typeOfTag,
Node n,
ValidAttribute[] validAttributes,
ErrorDispatcher err)
throws JasperException {
Attributes attrs = n.getAttributes();
Mark start = n.getStart();
boolean valid = true;
// AttributesImpl.removeAttribute is broken, so we do this...
int tempLength = (attrs == null) ? 0 : attrs.getLength();
Vector temp = new Vector(tempLength, 1);
for (int i = 0; i < tempLength; i++) {
String qName = attrs.getQName(i);
if ((!qName.equals("xmlns")) && (!qName.startsWith("xmlns:")))
temp.addElement(qName);
}
// Add names of attributes specified using jsp:attribute
Node.Nodes tagBody = n.getBody();
if( tagBody != null ) {
int numSubElements = tagBody.size();
for( int i = 0; i < numSubElements; i++ ) {
Node node = tagBody.getNode( i );
if( node instanceof Node.NamedAttribute ) {
String attrName = node.getAttributeValue( "name" );
temp.addElement( attrName );
// Check if this value appear in the attribute of the node
if (n.getAttributeValue(attrName) != null) {
err.jspError(n, "jsp.error.duplicate.name.jspattribute",
attrName);
}
}
else {
// Nothing can come before jsp:attribute, and only
// jsp:body can come after it.
break;
}
}
}
/*
* First check to see if all the mandatory attributes are present.
* If so only then proceed to see if the other attributes are valid
* for the particular tag.
*/
String missingAttribute = null;
for (int i = 0; i < validAttributes.length; i++) {
int attrPos;
if (validAttributes[i].mandatory) {
attrPos = temp.indexOf(validAttributes[i].name);
if (attrPos != -1) {
temp.remove(attrPos);
valid = true;
} else {
valid = false;
missingAttribute = validAttributes[i].name;
break;
}
}
}
// If mandatory attribute is missing then the exception is thrown
if (!valid)
err.jspError(start, "jsp.error.mandatory.attribute", typeOfTag,
missingAttribute);
// Check to see if there are any more attributes for the specified tag.
int attrLeftLength = temp.size();
if (attrLeftLength == 0)
return;
// Now check to see if the rest of the attributes are valid too.
String attribute = null;
for (int j = 0; j < attrLeftLength; j++) {
valid = false;
attribute = (String) temp.elementAt(j);
for (int i = 0; i < validAttributes.length; i++) {
if (attribute.equals(validAttributes[i].name)) {
valid = true;
break;
}
}
if (!valid)
err.jspError(start, "jsp.error.invalid.attribute", typeOfTag,
attribute);
}
// XXX *could* move EL-syntax validation here... (sb)
}
public static String escapeQueryString(String unescString) {
if ( unescString == null )
return null;
String escString = "";
String shellSpChars = "\\\"";
for(int index=0; index<unescString.length(); index++) {
char nextChar = unescString.charAt(index);
if( shellSpChars.indexOf(nextChar) != -1 )
escString += "\\";
escString += nextChar;
}
return escString;
}
/**
* Escape the 5 entities defined by XML.
*/
public static String escapeXml(String s) {
if (s == null) return null;
StringBuffer sb = new StringBuffer();
for(int i=0; i<s.length(); i++) {
char c = s.charAt(i);
if (c == '<') {
sb.append("<");
} else if (c == '>') {
sb.append(">");
} else if (c == '\'') {
sb.append("'");
} else if (c == '&') {
sb.append("&");
} else if (c == '"') {
sb.append(""");
} else {
sb.append(c);
}
}
return sb.toString();
}
/**
* Replaces any occurrences of the character <tt>replace</tt> with the
* string <tt>with</tt>.
*/
public static String replace(String name, char replace, String with) {
StringBuffer buf = new StringBuffer();
int begin = 0;
int end;
int last = name.length();
while (true) {
end = name.indexOf(replace, begin);
if (end < 0) {
end = last;
}
buf.append(name.substring(begin, end));
if (end == last) {
break;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -