Quelle ErrorDispatcher.java
Sprache: 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.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import org.apache.jasper.JasperException;
import org.apache.jasper.JspCompilationContext;
import org.xml.sax.SAXException;
/**
* Class responsible for dispatching JSP parse and javac compilation errors
* to the configured error handler .
*
* This class is also responsible for localizing any error codes before they
* are passed on to the configured error handler .
*
* In the case of a Java compilation error , the compiler error message is
* parsed into an array of JavacErrorDetail instances , which is passed on to
* the configured error handler .
*
* @ author Jan Luehe
* @ author Kin - man Chung
*/
public class ErrorDispatcher {
/**
* Custom error handler
*/
private final ErrorHandler errHandler;
/**
* Indicates whether the compilation was initiated by JspServlet or JspC
*/
private final boolean jspcMode;
/**
* Constructor .
*
* @ param jspcMode true if compilation has been initiated by JspC , false
* otherwise
*/
public ErrorDispatcher(boolean jspcMode) {
// XXX check web.xml for custom error handler
errHandler = new DefaultErrorHandler();
this .jspcMode = jspcMode;
}
/**
* Dispatches the given JSP parse error to the configured error handler .
*
* The given error code is localized . If it is not found in the
* resource bundle for localized error messages , it is used as the error
* message .
*
* @ param errCode Error code
* @ param args Arguments for parametric replacement
* @ throws JasperException An error occurred
*/
public void jspError(String errCode, String... args) throws JasperException {
dispatch(null , errCode, args, null );
}
/**
* Dispatches the given JSP parse error to the configured error handler .
*
* The given error code is localized . If it is not found in the
* resource bundle for localized error messages , it is used as the error
* message .
*
* @ param where Error location
* @ param errCode Error code
* @ param args Arguments for parametric replacement
* @ throws JasperException An error occurred
*/
public void jspError(Mark where, String errCode, String... args)
throws JasperException {
dispatch(where, errCode, args, null );
}
/**
* Dispatches the given JSP parse error to the configured error handler .
*
* The given error code is localized . If it is not found in the
* resource bundle for localized error messages , it is used as the error
* message .
*
* @ param n Node that caused the error
* @ param errCode Error code
* @ param args Arguments for parametric replacement
* @ throws JasperException An error occurred
*/
public void jspError(Node n, String errCode, String... args)
throws JasperException {
dispatch(n.getStart(), errCode, args, null );
}
/**
* Dispatches the given parsing exception to the configured error handler .
*
* @ param e Parsing exception
* @ throws JasperException An error occurred
*/
public void jspError(Exception e) throws JasperException {
dispatch(null , null , null , e);
}
/**
* Dispatches the given JSP parse error to the configured error handler .
*
* The given error code is localized . If it is not found in the
* resource bundle for localized error messages , it is used as the error
* message .
*
* @ param errCode Error code
* @ param args Arguments for parametric replacement
* @ param e Parsing exception
* @ throws JasperException An error occurred
*/
public void jspError(Exception e, String errCode, String... args)
throws JasperException {
dispatch(null , errCode, args, e);
}
/**
* Dispatches the given JSP parse error to the configured error handler .
*
* The given error code is localized . If it is not found in the
* resource bundle for localized error messages , it is used as the error
* message .
*
* @ param where Error location
* @ param e Parsing exception
* @ param errCode Error code
* @ param args Arguments for parametric replacement
* @ throws JasperException An error occurred
*/
public void jspError(Mark where, Exception e, String errCode, String... args)
throws JasperException {
dispatch(where, errCode, args, e);
}
/**
* Dispatches the given JSP parse error to the configured error handler .
*
* The given error code is localized . If it is not found in the
* resource bundle for localized error messages , it is used as the error
* message .
*
* @ param n Node that caused the error
* @ param e Parsing exception
* @ param errCode Error code
* @ param args Arguments for parametric replacement
* @ throws JasperException An error occurred
*/
public void jspError(Node n, Exception e, String errCode, String... args)
throws JasperException {
dispatch(n.getStart(), errCode, args, e);
}
/**
* Parses the given error message into an array of javac compilation error
* messages ( one per javac compilation error line number ) .
*
* @ param errMsg Error message
* @ param fname Name of Java source file whose compilation failed
* @ param page Node representation of JSP page from which the Java source
* file was generated
*
* @ return Array of javac compilation errors , or null if the given error
* message does not contain any compilation error line numbers
* @ throws JasperException An error occurred
* @ throws IOException IO error which usually should not occur
*/
public static JavacErrorDetail[] parseJavacErrors(String errMsg,
String fname,
Node.Nodes page)
throws JasperException, IOException {
return parseJavacMessage(errMsg, fname, page);
}
/**
* Dispatches the given javac compilation errors to the configured error
* handler .
*
* @ param javacErrors Array of javac compilation errors
* @ throws JasperException An error occurred
*/
public void javacError(JavacErrorDetail[] javacErrors)
throws JasperException {
errHandler.javacError(javacErrors);
}
/**
* Dispatches the given compilation error report and exception to the
* configured error handler .
*
* @ param errorReport Compilation error report
* @ param e Compilation exception
* @ throws JasperException An error occurred
*/
public void javacError(String errorReport, Exception e)
throws JasperException {
errHandler.javacError(errorReport, e);
}
//*********************************************************************
// Private utility methods
/**
* Dispatches the given JSP parse error to the configured error handler .
*
* The given error code is localized . If it is not found in the
* resource bundle for localized error messages , it is used as the error
* message .
*
* @ param where Error location
* @ param errCode Error code
* @ param args Arguments for parametric replacement
* @ param e Parsing exception
* @ throws JasperException An error occurred
*/
private void dispatch(Mark where, String errCode, Object[] args,
Exception e) throws JasperException {
String file = null ;
String errMsg = null ;
int line = -1 ;
int column = -1 ;
boolean hasLocation = false ;
// Localize
if (errCode != null ) {
errMsg = Localizer.getMessage(errCode, args);
} else if (e != null ) {
// give a hint about what's wrong
errMsg = e.getMessage();
}
// Get error location
if (where != null ) {
if (jspcMode) {
// Get the full URL of the resource that caused the error
try {
URL url = where.getURL();
if (url != null ) {
file = url.toString();
} else {
// Fallback to using context-relative path
file = where.getFile();
}
} catch (MalformedURLException me) {
// Fallback to using context-relative path
file = where.getFile();
}
} else {
// Get the context-relative resource path, so as to not
// disclose any local filesystem details
file = where.getFile();
}
line = where.getLineNumber();
column = where.getColumnNumber();
hasLocation = true ;
}
// Get nested exception
Exception nestedEx = e;
if ((e instanceof SAXException)
&& (((SAXException) e).getException() != null )) {
nestedEx = ((SAXException) e).getException();
}
if (hasLocation) {
errHandler.jspError(file, line, column, errMsg, nestedEx);
} else {
errHandler.jspError(errMsg, nestedEx);
}
}
/**
* Parses the given Java compilation error message , which may contain one
* or more compilation errors , into an array of JavacErrorDetail instances .
*
* Each JavacErrorDetail instance contains the information about a single
* compilation error .
*
* @ param errMsg Compilation error message that was generated by the
* javac compiler
* @ param fname Name of Java source file whose compilation failed
* @ param page Node representation of JSP page from which the Java source
* file was generated
*
* @ return Array of JavacErrorDetail instances corresponding to the
* compilation errors
* @ throws JasperException An error occurred
* @ throws IOException IO error which usually should not occur
*/
private static JavacErrorDetail[] parseJavacMessage(
String errMsg, String fname, Node.Nodes page)
throws IOException, JasperException {
List<JavacErrorDetail> errors = new ArrayList<>();
StringBuilder errMsgBuf = null ;
int lineNum = -1 ;
JavacErrorDetail javacError = null ;
BufferedReader reader = new BufferedReader(new StringReader(errMsg));
/*
* Parse compilation errors . Each compilation error consists of a file
* path and error line number , followed by a number of lines describing
* the error .
*/
String line = null ;
while ((line = reader.readLine()) != null ) {
/*
* Error line number is delimited by set of colons .
* Ignore colon following drive letter on Windows ( fromIndex = 2 ) .
* XXX Handle deprecation warnings that don ' t have line info
*/
int beginColon = line.indexOf(':' , 2 );
int endColon = line.indexOf(':' , beginColon + 1 );
if ((beginColon >= 0 ) && (endColon >= 0 )) {
if (javacError != null ) {
// add previous error to error vector
errors.add(javacError);
}
String lineNumStr = line.substring(beginColon + 1 , endColon);
try {
lineNum = Integer.parseInt(lineNumStr);
} catch (NumberFormatException e) {
lineNum = -1 ;
}
errMsgBuf = new StringBuilder();
javacError = createJavacError(fname, page, errMsgBuf, lineNum);
}
// Ignore messages preceding first error
if (errMsgBuf != null ) {
errMsgBuf.append(line);
errMsgBuf.append(System.lineSeparator());
}
}
// Add last error to error vector
if (javacError != null ) {
errors.add(javacError);
}
reader.close();
JavacErrorDetail[] errDetails = null ;
if (errors.size() > 0 ) {
errDetails = errors.toArray(new JavacErrorDetail[0 ]);
}
return errDetails;
}
/**
* Create a compilation error .
* @ param fname The file name
* @ param page The page nodes
* @ param errMsgBuf The error message
* @ param lineNum The source line number of the error
* @ return JavacErrorDetail The error details
* @ throws JasperException An error occurred
*/
public static JavacErrorDetail createJavacError(String fname,
Node.Nodes page, StringBuilder errMsgBuf, int lineNum)
throws JasperException {
return createJavacError(fname, page, errMsgBuf, lineNum, null );
}
/**
* Create a compilation error .
* @ param fname The file name
* @ param page The page nodes
* @ param errMsgBuf The error message
* @ param lineNum The source line number of the error
* @ param ctxt The compilation context
* @ return JavacErrorDetail The error details
* @ throws JasperException An error occurred
*/
public static JavacErrorDetail createJavacError(String fname,
Node.Nodes page, StringBuilder errMsgBuf, int lineNum,
JspCompilationContext ctxt) throws JasperException {
JavacErrorDetail javacError;
// Attempt to map javac error line number to line in JSP page
ErrorVisitor errVisitor = new ErrorVisitor(lineNum);
page.visit(errVisitor);
Node errNode = errVisitor.getJspSourceNode();
if ((errNode != null ) && (errNode.getStart() != null )) {
// If this is a scriplet node then there is a one to one mapping
// between JSP lines and Java lines
if (errVisitor.getJspSourceNode() instanceof Node.Scriptlet ||
errVisitor.getJspSourceNode() instanceof Node.Declaration) {
javacError = new JavacErrorDetail(
fname,
lineNum,
errNode.getStart().getFile(),
errNode.getStart().getLineNumber() + lineNum -
errVisitor.getJspSourceNode().getBeginJavaLine(),
errMsgBuf,
ctxt);
} else {
javacError = new JavacErrorDetail(
fname,
lineNum,
errNode.getStart().getFile(),
errNode.getStart().getLineNumber(),
errMsgBuf,
ctxt);
}
} else {
/*
* javac error line number cannot be mapped to JSP page
* line number . For example , this is the case if a
* scriptlet is missing a closing brace , which causes
* havoc with the try - catch - finally block that the code
* generator places around all generated code : As a result
* of this , the javac error line numbers will be outside
* the range of begin and end java line numbers that were
* generated for the scriptlet , and therefore cannot be
* mapped to the start line number of the scriptlet in the
* JSP page .
* Include just the javac error info in the error detail .
*/
javacError = new JavacErrorDetail(
fname,
lineNum,
errMsgBuf);
}
return javacError;
}
/**
* Visitor responsible for mapping a line number in the generated servlet
* source code to the corresponding JSP node .
*/
private static class ErrorVisitor extends Node.Visitor {
/**
* Java source line number to be mapped
*/
private final int lineNum;
/**
* JSP node whose Java source code range in the generated servlet
* contains the Java source line number to be mapped
*/
private Node found;
/**
* Constructor .
*
* @ param lineNum Source line number in the generated servlet code
*/
ErrorVisitor(int lineNum) {
this .lineNum = lineNum;
}
@Override
public void doVisit(Node n) throws JasperException {
if ((lineNum >= n.getBeginJavaLine())
&& (lineNum < n.getEndJavaLine())) {
found = n;
}
}
/**
* Gets the JSP node to which the source line number in the generated
* servlet code was mapped .
*
* @ return JSP node to which the source line number in the generated
* servlet code was mapped
*/
public Node getJspSourceNode() {
return found;
}
}
}
Messung V0.5 in Prozent C=92 H=80 G=86
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-09-27)
¤
*© Formatika GbR, Deutschland
2026-10-11
Neuigkeiten
Aktuelles
Motto des Tages
Open Source Software
Jenseits des Üblichen ....
Besucherstatistik
Statistik
#Sources=1126864
#Domains=2039723