PatternMatchingExceptionHandler.java
// license-header java merge-point
// Generated by andromda-jsf cartridge (exception\PatternMatchingExceptionHandler.java.vsl) DO NOT EDIT!
//
package org.andromda.presentation.jsf;
import java.io.Serializable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
/**
* <p>
* A configurable pattern matching error handler retrieves exception mapping
* keys from an exception, and re-throws the exception if a pattern can not be
* retrieved. This is used to retrieve keys from the back-end exceptions
* which can be mapped to exception messages keyed in an application resource
* file.
* </p>
*/
public class PatternMatchingExceptionHandler
implements Serializable
{
private static final long serialVersionUID = 1L;
private static final PatternMatchingExceptionHandler instance = new PatternMatchingExceptionHandler();
private static final Pattern compiledPattern = Pattern.compile("(.*)(\\{\\s*([\\w|\\.+]*)\\s*\\})(.*)");
/**
* Gets the shared PatternMatchingExceptionHandler instance.
*
* @return the shared instance
*/
public static PatternMatchingExceptionHandler instance()
{
return instance;
}
/**
* Handles Exceptions by retrieving the message and attempting to extract
* the specified pattern defined within this class. If a string can not be
* found matching the pattern, the exception is re-thrown
*
* @param throwable the Exception containing the message to retrieve
* @return the retrieved string matching the pattern.
* @throws Throwable
*/
public String handleException(final Throwable throwable) throws Throwable
{
final Throwable cause = this.findRootCause(throwable);
String matched = null;
if (cause != null && cause.getMessage() != null)
{
final Matcher matcher = compiledPattern.matcher(cause.getMessage().replaceAll("[\\s]+", " "));
try
{
if (matcher.matches())
{
matched = matcher.group(3);
}
}
catch (IllegalStateException ex)
{
// no match was found ignore
}
if (matched != null)
{
return matched;
}
}
throw throwable;
}
/**
* The property on the exception which could possibly contain any arguments on the matched exception.
*/
private static final String MESSAGE_ARGUMENTS = "messageArguments";
/**
* Attempts to retrieve any arguments from the exception from a property named "messageArguments"
* on the exception.
*
* @param throwable the Exception containing the message to retrieve
* @return the retrieved message arguments (if any) from the exception.
* @throws Throwable
*/
public Object[] getMessageArguments(final Throwable throwable) throws Throwable
{
Object[] arguments = null;
final Throwable cause = this.findRootCause(throwable);
if (cause != null && cause.getMessage() != null)
{
if (PropertyUtils.isReadable(cause, MESSAGE_ARGUMENTS))
{
arguments = (Object[])PropertyUtils.getProperty(cause, MESSAGE_ARGUMENTS);
}
}
return arguments;
}
/**
* Finds the root cause of the parent exception
* by traveling up the exception hierarchy.
* @param throwable the Exception containing the message to retrieve
* @throws Throwable
*/
private Throwable findRootCause(Throwable throwable)
{
final Throwable rootCause = ExceptionUtils.getRootCause(throwable);
if (rootCause != null)
{
throwable = rootCause;
}
return throwable;
}
}