org.vfny.geoserver.ServiceException Maven / Gradle / Ivy
/* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
* This code is licensed under the GPL 2.0 license, availible at the root
* application directory.
*/
package org.vfny.geoserver;
import org.vfny.geoserver.global.GeoServer;
import org.vfny.geoserver.util.Requests;
import org.vfny.geoserver.util.ResponseUtils;
import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;
import java.util.logging.Logger;
import javax.servlet.http.HttpServletRequest;
/**
* Represents a standard OGC service exception. Able to turn itself into the
* proper xml response.
*
*
* JG - here is my guess on what the parameters do:
*
*
* [?xml version="1.0" ?
* [ServiceExceptionReport
* version="1.2.0"
* xmlns="http://www.opengis.net/ogc"
* xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
* xsi:schemaLocation="http://www.opengis.net/ogc SchemaBaseUrl wfs/1.0.0/OGC-exception.xsd"]
* [ServiceException code="code"
* locator="locator"]
* preMessage:getMessage()
* stack trace
* [/ServiceException]
* [/ServiceExceptionReport]
*
*
*
* Where:
*
*
*
* -
* code: is a diagnostic code
*
* -
* locator: is the java class that caused the problem
*
* -
* preMessage: is your chance to place things in user terms
*
* -
* message: is the exception message
*
* -
* stack trace: is the exception strack trace
*
*
*
*
* Java Exception have recently developed the ability to contain other
* exceptions. By calling initCause on your ServiceConfig Exception you can
* get the real exception included in the stacktrace above.
*
*
* @author Gabriel Rold?n
* @author Chris Holmes
*
* @task REVISIT: Take a request in the constructor? This would make it so we
* do not have to rely on schemas.opengis.net being available, as it
* will just reference the geoserver instance that created it. But to
* do this we need the request, as that's how we figure out the baseUrl.
* Would probably not be that hard to get the request included, and
* would lead to better error reporting...
*/
public class ServiceException extends org.geoserver.platform.ServiceException {
/** Class logger */
private static Logger LOGGER = org.geotools.util.logging.Logging.getLogger("org.vfny.geoserver.responses");
/** message inserted by GeoServer as to what it thinks happened */
protected String preMessage = new String();
/** full classpath of originating GeoServer class */
protected String locator = new String();
/**
* Empty constructor.
*/
public ServiceException() {
super((String) null);
}
/**
* Empty constructor.
*
* @param message The message for the .
*/
public ServiceException(String message) {
super(message, (String) null);
}
/**
* This should be the most used entry point.
*
* @param message User message
* @param cause The origional exception that caused failure
*/
public ServiceException(String message, Throwable cause) {
super(message, cause, null);
}
/**
* Empty constructor.
*
* @param e The message for the .
*/
public ServiceException(Throwable e) {
super(e, null);
}
/**
* Empty constructor.
*
* @param message The message for the .
* @param locator The message for the .
*/
public ServiceException(String message, String locator) {
super(message);
this.locator = locator;
}
/**
* DOCUMENT ME!
*
* @param e The message for the .
* @param preMessage The message to tack on the front.
* @param locator The message for the .
*/
public ServiceException(Throwable e, String preMessage, String locator) {
this(e);
this.preMessage = preMessage;
this.locator = locator;
}
public ServiceException(ServiceException e) {
super(e.getMessage(), e.getCause(), e.getLocator());
this.preMessage = e.preMessage;
}
/**
* DOCUMENT ME!
*
* @param testString DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
protected boolean isEmpty(String testString) {
return (testString == null) || testString.equals("");
}
public String getLocator() {
return locator;
}
/**
* DOCUMENT ME!
*
* @param printStackTrace DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
//public String getXmlResponse() {
// return getXmlResponse(true);
//}
/**
* gets the message, encoding it with the proper escaped xml characters. If
* requested it prints the whole stack trace in the response.
*
* @param printStackTrace set to true if the full stack trace
* should be returned to client apps.
*
* @return The message of this error, with xml escapes.
*
* @task REVISIT: The stack trace printing is not that efficient, but it
* should be relatively small. Once we convert errors to print
* directly to the servlet output stream we can make it faster.
*/
public String getXmlMessage(boolean printStackTrace) {
String indent = " ";
StringBuffer mesg = new StringBuffer();
//this distinction no longer so much applies, as we don't always
//throw Service exceptions for all expected exceptions.
//if (!isEmpty(this.preMessage)) {
// mesg.append(this.preMessage + ": ");
//}
//mesg.append(ResponseUtils.encodeXML(this.getMessage()) + "\n");
// if (printStackTrace) {
if (printStackTrace) {
mesg.append(createStackTrace());
} else {
mesg.append(this.getMessage());
}
return ResponseUtils.encodeXML(mesg.toString());
}
private String createStackTrace() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintWriter writer = new PrintWriter(baos);
Throwable cause = getCause();
if (cause == null) {
this.printStackTrace(writer);
} else {
cause.printStackTrace(writer);
}
writer.flush();
return baos.toString();
}
/**
* Return request type.
*
* @param printStackTrace whether the stack trace should be included.
* @param request DOCUMENT ME!
*
* @return The ServiceExceptionReport of this error.
*
* @task REVISIT: Our error handling should actually have knowledge of the
* app configuration, so that we can set the ogc error report to
* validate right (reference our own schema), and to put the correct
* mime type here.
*/
public String getXmlResponse(boolean printStackTrace, HttpServletRequest request,
GeoServer geoserver) {
//Perhaps not the best place to do this, but it's by far the best place to ensure
//that all logged errors get recorded in the same way, as there all must return
//xml responses.
LOGGER.warning("encountered error: " + getMessage() + "\nStackTrace: " + createStackTrace());
String indent = " ";
StringBuffer returnXml = new StringBuffer("\n");
returnXml.append("\n");
//REVISIT: handle multiple service exceptions? must refactor class.
returnXml.append(indent + "\n" + indent + indent);
returnXml.append(getXmlMessage(printStackTrace));
returnXml.append(indent + " \n");
returnXml.append(" ");
LOGGER.fine("return wfs exception is " + returnXml);
return returnXml.toString();
}
/**
* Returns the mime type that should be exposed to the client
* when sending the exception message.
*
*
* Defaults to geoserver.getMimeType()
*
*
* @return
*/
public String getMimeType(GeoServer geoserver) {
return geoserver.getMimeType();
}
}