001    /*******************************************************************************
002     * Portions created by Sebastian Thomschke are copyright (c) 2005-2011 Sebastian
003     * Thomschke.
004     * 
005     * All Rights Reserved. This program and the accompanying materials
006     * are made available under the terms of the Eclipse Public License v1.0
007     * which accompanies this distribution, and is available at
008     * http://www.eclipse.org/legal/epl-v10.html
009     * 
010     * Contributors:
011     *     Sebastian Thomschke - initial implementation.
012     *******************************************************************************/
013    package net.sf.oval.exception;
014    
015    import net.sf.oval.ConstraintViolation;
016    import net.sf.oval.context.ConstructorParameterContext;
017    import net.sf.oval.context.FieldContext;
018    import net.sf.oval.context.MethodEntryContext;
019    import net.sf.oval.context.MethodParameterContext;
020    import net.sf.oval.context.MethodReturnValueContext;
021    import net.sf.oval.context.OValContext;
022    import net.sf.oval.internal.Log;
023    
024    /**
025     * Translates OVal specific exceptions to standard exceptions part of the JRE:
026     * <ul>
027     * <li><code>ConstraintsViolatedException</code> for constructor/method parameter translated to <code>IllegalArgumentException</code>
028     * <li><code>ConstraintsViolatedException</code> for class field translated to <code>IllegalStateException</code>
029     * <li><code>ConstraintsViolatedException</code> for method return values translated to <code>IllegalStateException</code>
030     * <li>Other exceptions based on <code>OValException</code> translated to <code>RuntimeException</code>
031     * </ul>
032     * @author Sebastian Thomschke
033     */
034    public class ExceptionTranslatorJDKExceptionsImpl implements ExceptionTranslator
035    {
036            private static final Log LOG = Log.getLog(ExceptionTranslatorJDKExceptionsImpl.class);
037    
038            /**
039             * {@inheritDoc}
040             */
041            public RuntimeException translateException(final OValException ex)
042            {
043                    // translate ConstraintsViolatedException based on the validation context
044                    if (ex instanceof ConstraintsViolatedException)
045                    {
046                            final ConstraintsViolatedException cex = (ConstraintsViolatedException) ex;
047                            final ConstraintViolation cv = cex.getConstraintViolations()[0];
048                            final OValContext ctx = cv.getContext();
049    
050                            // translate exceptions for preconditions to IllegalArgumentExceptions
051                            if (ctx instanceof MethodParameterContext || ctx instanceof ConstructorParameterContext
052                                            || ctx instanceof MethodEntryContext)
053                            {
054                                    final IllegalArgumentException iaex = new IllegalArgumentException(cv.getMessage(), ex.getCause());
055                                    iaex.setStackTrace(ex.getStackTrace());
056                                    LOG.debug("Translated Exception {1} to {2}", ex, iaex);
057                                    return iaex;
058                            }
059    
060                            // translate invariant exceptions to IllegalStateExceptions
061                            if (ctx instanceof FieldContext || ctx instanceof MethodReturnValueContext)
062                            {
063                                    final IllegalStateException ise = new IllegalStateException(cv.getMessage(), ex.getCause());
064                                    ise.setStackTrace(ex.getStackTrace());
065                                    LOG.debug("Translated Exception {1} to {2}", ex, ise);
066                                    return ise;
067                            }
068                    }
069    
070                    // translate all other messages to runtime exceptions
071                    {
072                            final RuntimeException rex = new RuntimeException(ex.getMessage(), ex.getCause());
073                            rex.setStackTrace(ex.getStackTrace());
074                            LOG.debug("Translated Exception {1} to {2}", ex, rex);
075                            return rex;
076                    }
077            }
078    }