/*******************************************************************************
* Copyright (c) 2011 epyx SA.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* This program 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 Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
package ch.windmobile.server.resource;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ch.windmobile.server.datasourcemodel.DataSourceException;
import ch.windmobile.server.datasourcemodel.xml.Error;
public class ExceptionHandler {
protected static final Logger log = LoggerFactory.getLogger(ExceptionHandler.class);
private static String printStacktrace(Throwable e) {
if (e.getStackTrace() != null) {
Writer writer = new StringWriter();
PrintWriter printWriter = new PrintWriter(writer);
e.printStackTrace(printWriter);
return writer.toString();
}
return "";
}
public static String getFullURL(HttpServletRequest request) {
StringBuffer requestURL = request.getRequestURL();
String queryString = request.getQueryString();
if (queryString == null) {
return requestURL.toString();
} else {
return requestURL.append('?').append(queryString).toString();
}
}
private static void logException(WebApplicationException e, HttpServletRequest request) {
Object entity = e.getResponse().getEntity();
if (entity instanceof Error) {
Error error = (Error) entity;
log.error(getFullURL(request) + ": " + e.getResponse().getStatus() + " (" + error.getCode() + ", " + error.getMessage() + ")\n"
+ error.getStacktrace());
} else {
log.error(getFullURL(request) + ": " + e.getResponse().getStatus(), e);
}
}
public static WebApplicationException treatException(Throwable e, HttpServletRequest request) {
WebApplicationException exception;
if (e instanceof WebApplicationException) {
exception = (WebApplicationException) e;
} else if (e instanceof DataSourceException) {
DataSourceException dataSourceException = (DataSourceException) e;
Throwable cause = dataSourceException.getCause();
Error error = new Error();
error.setCode(dataSourceException.getError().getCode());
if (dataSourceException.getMessage() != null) {
error.setMessage(dataSourceException.getMessage());
} else if (cause != null) {
error.setMessage(cause.getMessage());
}
if (cause != null) {
error.setStacktrace(printStacktrace(cause));
} else {
error.setStacktrace(printStacktrace(dataSourceException));
}
Status httpStatus;
switch (dataSourceException.getError()) {
case CONNECTION_ERROR:
httpStatus = Status.SERVICE_UNAVAILABLE;
break;
case INVALID_DATA:
httpStatus = Status.BAD_REQUEST;
break;
case DATABASE_ERROR:
httpStatus = Status.INTERNAL_SERVER_ERROR;
break;
default:
httpStatus = Status.INTERNAL_SERVER_ERROR;
break;
}
exception = new WebApplicationException(Response.status(httpStatus).entity(error).build());
} else {
Error error = new Error();
error.setCode(DataSourceException.Error.SERVER_ERROR.getCode());
if (e.getMessage() != null) {
error.setMessage(e.getMessage());
} else if (e.getCause() != null) {
error.setMessage(e.getCause().getMessage());
}
error.setStacktrace(printStacktrace(e));
exception = new WebApplicationException(Response.status(Status.INTERNAL_SERVER_ERROR).entity(error).build());
}
logException(exception, request);
return exception;
}
}