You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
307 lines
15 KiB
307 lines
15 KiB
package de.superx.rest; |
|
|
|
import java.io.IOException; |
|
import java.sql.SQLException; |
|
import java.text.ParseException; |
|
|
|
import javax.xml.parsers.ParserConfigurationException; |
|
import javax.xml.transform.TransformerException; |
|
|
|
import org.apache.log4j.Logger; |
|
import org.springframework.dao.DataIntegrityViolationException; |
|
import org.springframework.dao.DuplicateKeyException; |
|
import org.springframework.data.relational.core.conversion.DbActionExecutionException; |
|
import org.springframework.http.HttpStatus; |
|
import org.springframework.http.ResponseEntity; |
|
import org.springframework.web.bind.annotation.ExceptionHandler; |
|
import org.springframework.web.context.request.RequestAttributes; |
|
import org.springframework.web.context.request.RequestContextHolder; |
|
import org.springframework.web.context.request.ServletRequestAttributes; |
|
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; |
|
|
|
import de.memtext.tree.KeyParentEqualException; |
|
import de.memtext.tree.NoMainEntryException; |
|
import de.superx.bianalysis.FaultyMetadataException; |
|
import de.superx.bianalysis.service.IllegalMetaDataOperation; |
|
import de.superx.common.AccessDeniedException; |
|
import de.superx.common.ConfigurationException; |
|
import de.superx.common.DBServletException; |
|
import de.superx.common.InvalidDataTypeException; |
|
import de.superx.common.InvalidEntityException; |
|
import de.superx.common.InvalidKeyException; |
|
import de.superx.common.EtlConfigurationException; |
|
import de.superx.common.NotYetImplementedException; |
|
import de.superx.common.ObligatoryFieldEmptyException; |
|
import de.superx.common.SichtException; |
|
import de.superx.common.UngueltigeEingabeException; |
|
import de.superx.dbt.UnsupportedPythonVersionException; |
|
import de.superx.rest.model.ExceptionResponse; |
|
import de.superx.rest.model.RestMessageWrapperException; |
|
import freemarker.template.TemplateException; |
|
import net.sf.jasperreports.engine.JRException; |
|
|
|
/*** |
|
* Rip-Off of HISinOne's 'RestControllerBase' class. |
|
* Contains common functionality of REST controllers. |
|
* @author witt |
|
* |
|
*/ |
|
abstract public class RestControllerBase { |
|
|
|
protected static ResponseEntity<ExceptionResponse> handleServerError(String message) { |
|
ExceptionResponse er = new ExceptionResponse(null, message, null); |
|
ResponseEntity<ExceptionResponse> re = new ResponseEntity<ExceptionResponse>(er, HttpStatus.INTERNAL_SERVER_ERROR); |
|
return re; |
|
} |
|
|
|
protected static ResponseEntity<ExceptionResponse> handleUserInputError(String message) { |
|
ExceptionResponse er = new ExceptionResponse(null, message, null); |
|
ResponseEntity<ExceptionResponse> re = new ResponseEntity<ExceptionResponse>(er, HttpStatus.UNPROCESSABLE_ENTITY); |
|
return re; |
|
} |
|
|
|
protected static ResponseEntity<ExceptionResponse> handleUserInputError(ExceptionResponse er, HttpStatus status) { |
|
ResponseEntity<ExceptionResponse> re = new ResponseEntity<ExceptionResponse>(er, status); |
|
return re; |
|
} |
|
|
|
abstract protected Logger getLogger(); |
|
|
|
/*** |
|
* changed dispatching of exception to handlers to explicit/central point, so we do not miss unexpected exceptions |
|
* @param ex - the exception to be dispatched to a specific handler |
|
* @return the response object for the web service call |
|
*/ |
|
@ExceptionHandler(Exception.class) |
|
public ResponseEntity<ExceptionResponse> dispatchExceptionHandler(Exception ex) { |
|
if (ex instanceof MethodArgumentTypeMismatchException) { |
|
return handleMethodArgumentTypeMismatchException((MethodArgumentTypeMismatchException)ex); |
|
} else if (ex instanceof DBServletException) { |
|
return handleDBServletException((DBServletException)ex); |
|
} else if (ex instanceof IOException) { |
|
return handleIOException((IOException)ex); |
|
} else if (ex instanceof CloneNotSupportedException) { |
|
return handleCloneNotSupportedException((CloneNotSupportedException)ex); |
|
} else if (ex instanceof TemplateException) { |
|
return handleTemplateException((TemplateException)ex); |
|
} else if (ex instanceof SQLException) { |
|
return handleSQLException((SQLException)ex); |
|
} else if (ex instanceof ParserConfigurationException) { |
|
return handleParserConfigurationException((ParserConfigurationException)ex); |
|
} else if (ex instanceof ParseException) { |
|
return handleParseException((ParseException)ex); |
|
} else if (ex instanceof JRException) { |
|
return handleJRException((JRException)ex); |
|
} else if (ex instanceof KeyParentEqualException) { |
|
return handleKeyParentEqualException((KeyParentEqualException)ex); |
|
} else if (ex instanceof NoMainEntryException) { |
|
return handleNoMainEntryException((NoMainEntryException)ex); |
|
} else if (ex instanceof InvalidDataTypeException) { |
|
return handleInvalidDataTypeException((InvalidDataTypeException)ex); |
|
} else if (ex instanceof SichtException) { |
|
return handleSichtException((SichtException)ex); |
|
} else if (ex instanceof UngueltigeEingabeException) { |
|
return handleUngueltigeEingabeException((UngueltigeEingabeException)ex); |
|
} else if (ex instanceof ObligatoryFieldEmptyException) { |
|
return handleObligatoryFieldEmptyException((ObligatoryFieldEmptyException)ex); |
|
} else if (ex instanceof InvalidKeyException) { |
|
return handleInvalidKeyException((InvalidKeyException)ex); |
|
} else if (ex instanceof TransformerException) { |
|
return handleTransformerException((TransformerException)ex); |
|
} else if (ex instanceof NotYetImplementedException) { |
|
return handleNotYetImplementedException((NotYetImplementedException)ex); |
|
} else if (ex instanceof UnsupportedPythonVersionException) { |
|
return handleUnsupportedPythonVersionException((UnsupportedPythonVersionException)ex); |
|
} else if (ex instanceof InvalidEntityException) { |
|
return handleInvalidEntityException((InvalidEntityException)ex); |
|
} else if (ex instanceof DbActionExecutionException) { |
|
return handleDbActionExecutionException((DbActionExecutionException)ex); |
|
} else if (ex instanceof EtlConfigurationException) { |
|
return handleEtlConfigurationException((EtlConfigurationException)ex); |
|
} else if (ex instanceof ConfigurationException) { |
|
return handleConfigurationException((ConfigurationException)ex); |
|
} else if (ex instanceof AccessDeniedException) { |
|
return handleAccessDeniedException((AccessDeniedException)ex); |
|
} else if (ex instanceof InputValidationError) { |
|
return handleUserInputError(ex.getMessage()); |
|
} else if (ex instanceof FaultyMetadataException) { |
|
return handleFaultyMetadataException((FaultyMetadataException)ex); |
|
} else if (ex instanceof RestMessageWrapperException) { |
|
return handleRestMessageWrapperException((RestMessageWrapperException)ex); |
|
} else if (ex instanceof IllegalMetaDataOperation) { |
|
return handleIllegalMetaDataOperation((IllegalMetaDataOperation)ex); |
|
} |
|
else if (ex instanceof RuntimeException) { |
|
// Log stacktraces of runtime exceptions, otherwise the information is lost! |
|
getLogger().error("RuntimeException:", ex); |
|
} |
|
getLogger().error("an unexpected exception occured; exception type: ", ex); |
|
return handleServerError("an exception occured: " + ex.getCause()); |
|
} |
|
|
|
/*** |
|
* This exception occurs for example under the following circumstance: |
|
* Say we have a method annotated with "@RequestMapping". |
|
* This method has a parameter "int bla" that is annotated with "@RequestParam". |
|
* If someone calls this method (via web service), but the mapped parameter cannot |
|
* be transformed to an "int", this handler is entered. |
|
* @param ex |
|
* @return |
|
*/ |
|
public ResponseEntity<ExceptionResponse> handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException ex) { |
|
getLogger().error("MethodArgumentTypeMismatchException occured", ex); |
|
return handleUserInputError(ex.getMessage()); |
|
} |
|
|
|
public ResponseEntity<ExceptionResponse> handleDBServletException(DBServletException ex) { |
|
getLogger().error("DBServletException occured", ex); |
|
return handleServerError("Interner Serverfehler"); |
|
} |
|
|
|
public ResponseEntity<ExceptionResponse> handleIOException(IOException ex) { |
|
getLogger().error("IOException occured", ex); |
|
return handleServerError("Interner Serverfehler"); |
|
} |
|
|
|
public ResponseEntity<ExceptionResponse> handleCloneNotSupportedException(CloneNotSupportedException ex) { |
|
getLogger().error("CloneNotSupportedException occured", ex); |
|
return handleServerError("Interner Serverfehler"); |
|
} |
|
|
|
public ResponseEntity<ExceptionResponse> handleTemplateException(TemplateException ex) { |
|
getLogger().error("TemplateException occured", ex); |
|
return handleServerError("Interner Serverfehler"); |
|
} |
|
|
|
public ResponseEntity<ExceptionResponse> handleAccessDeniedException(AccessDeniedException ex) { |
|
getLogger().error("AccessDeniedException occured", ex); |
|
ExceptionResponse exceptionResponse = new ExceptionResponse("", "Kein Zugriff", null); |
|
// the original consideration was the following: |
|
// only return '404 - nor found' for security reasons: |
|
// caller must not even know, whether a resource exists or not |
|
// but: |
|
// HISinOne-Web Services send status 401 in case of missing permissions, |
|
// so we should do it as well... |
|
ResponseEntity<ExceptionResponse> responseEntity = |
|
new ResponseEntity<ExceptionResponse>(exceptionResponse, HttpStatus.UNAUTHORIZED); |
|
return responseEntity; |
|
} |
|
|
|
public ResponseEntity<ExceptionResponse> handleSQLException(SQLException ex) { |
|
getLogger().error("SQLException occured", ex); |
|
return handleServerError("Interner Serverfehler"); |
|
} |
|
|
|
public ResponseEntity<ExceptionResponse> handleParserConfigurationException(ParserConfigurationException ex) { |
|
getLogger().error("ParserConfigurationException occured", ex); |
|
return handleServerError("Interner Serverfehler"); |
|
} |
|
|
|
public ResponseEntity<ExceptionResponse> handleParseException(ParseException ex) { |
|
getLogger().error("ParseException occured", ex); |
|
return handleServerError("Interner Serverfehler"); |
|
} |
|
|
|
public ResponseEntity<ExceptionResponse> handleJRException(JRException ex) { |
|
getLogger().error("ParserConfigurationException occured", ex); |
|
return handleServerError("Interner Serverfehler"); |
|
} |
|
|
|
public ResponseEntity<ExceptionResponse> handleKeyParentEqualException(KeyParentEqualException ex) { |
|
getLogger().error("KeyParentEqualException occured", ex); |
|
return handleServerError("Interner Serverfehler"); |
|
} |
|
|
|
public ResponseEntity<ExceptionResponse> handleNoMainEntryException(NoMainEntryException ex) { |
|
getLogger().error("NoMainEntryException occured", ex); |
|
return handleServerError("Interner Serverfehler"); |
|
} |
|
|
|
public ResponseEntity<ExceptionResponse> handleInvalidDataTypeException(InvalidDataTypeException ex) { |
|
getLogger().error("InvalidDataTypeException occured", ex); |
|
return handleUserInputError(ex.getMessage()); |
|
} |
|
|
|
public ResponseEntity<ExceptionResponse> handleSichtException(SichtException ex) { |
|
getLogger().error("SichtException occured", ex); |
|
return handleServerError(ex.getMessage()); |
|
} |
|
|
|
public ResponseEntity<ExceptionResponse> handleUngueltigeEingabeException(UngueltigeEingabeException ex) { |
|
getLogger().error("UngueltigeEingabeException occured", ex); |
|
return handleUserInputError(ex.getMessage()); |
|
} |
|
|
|
public ResponseEntity<ExceptionResponse> handleObligatoryFieldEmptyException(ObligatoryFieldEmptyException ex) { |
|
getLogger().error("ObligatoryFieldEmptyException occured", ex); |
|
return handleUserInputError(ex.getMessage()); |
|
} |
|
|
|
public ResponseEntity<ExceptionResponse> handleInvalidKeyException(InvalidKeyException ex) { |
|
getLogger().error("InvalidKeyException occured", ex); |
|
return handleUserInputError(ex.getMessage()); |
|
} |
|
|
|
public ResponseEntity<ExceptionResponse> handleTransformerException(TransformerException ex) { |
|
getLogger().error("TransformerException occured", ex); |
|
return handleServerError(ex.getMessage()); |
|
} |
|
|
|
public ResponseEntity<ExceptionResponse> handleNotYetImplementedException(NotYetImplementedException ex) { |
|
getLogger().error("NotYetImplementedException occured", ex); |
|
return handleServerError(ex.getMessage()); |
|
} |
|
|
|
public ResponseEntity<ExceptionResponse> handleIllegalMetaDataOperation(IllegalMetaDataOperation ex) { |
|
getLogger().error("IllegalMetaDataOperation occured", ex); |
|
return handleServerError(ex.getMessage()); |
|
} |
|
|
|
public ResponseEntity<ExceptionResponse> handleFaultyMetadataException(FaultyMetadataException ex) { |
|
getLogger().error("FaultyMetadataException occured", ex); |
|
return handleServerError(ex.getMessage()); |
|
} |
|
|
|
public ResponseEntity<ExceptionResponse> handleInvalidEntityException(InvalidEntityException ex) { |
|
getLogger().error("InvalidEntityException occured", ex); |
|
return handleUserInputError(ex.getMessage()); |
|
} |
|
|
|
public ResponseEntity<ExceptionResponse> handleDbActionExecutionException(DbActionExecutionException ex) { |
|
getLogger().error("DbActionExecutionException occured", ex); |
|
String nestedExceptionMessage = ex.getCause().getCause().getMessage(); |
|
if (ex.getCause().getClass().equals(DuplicateKeyException.class)) { |
|
return handleUserInputError(nestedExceptionMessage); |
|
} |
|
if (ex.getCause().getClass().equals(DataIntegrityViolationException.class)) { |
|
return handleUserInputError(nestedExceptionMessage); |
|
} |
|
return handleServerError("Interner Serverfehler"); |
|
} |
|
|
|
public ResponseEntity<ExceptionResponse> handleEtlConfigurationException(EtlConfigurationException ex) { |
|
getLogger().error("EtlConfigurationException occured", ex); |
|
return handleServerError("Invalid etl configuration: " + ex.getMessage()); |
|
} |
|
|
|
public ResponseEntity<ExceptionResponse> handleConfigurationException(ConfigurationException ex) { |
|
getLogger().error("ConfigurationException occured", ex); |
|
return handleUserInputError(ex.getMessage()); |
|
} |
|
|
|
public ResponseEntity<ExceptionResponse> handleRestMessageWrapperException(RestMessageWrapperException ex) { |
|
getLogger().error("RestMessageWrapperException occured", ex); |
|
return handleUserInputError(ex.exceptionResponse, ex.httpStatus); |
|
} |
|
|
|
public ResponseEntity<ExceptionResponse> handleUnsupportedPythonVersionException(UnsupportedPythonVersionException ex) { |
|
getLogger().error("UnsupportedPythonVersionException occured", ex); |
|
return handleServerError(ex.getMessage()); |
|
} |
|
|
|
protected static boolean isHttpRequestPresent() { |
|
RequestAttributes attrs = RequestContextHolder.getRequestAttributes(); |
|
return (attrs instanceof ServletRequestAttributes); |
|
} |
|
|
|
}
|
|
|