Coverage Report - org.kuali.student.common.util.ExceptionMappingAdvice
 
Classes in this File Line Coverage Branch Coverage Complexity
ExceptionMappingAdvice
0%
0/35
0%
0/6
2.143
 
 1  
 /**
 2  
  * Copyright 2010 The Kuali Foundation Licensed under the
 3  
  * Educational Community License, Version 2.0 (the "License"); you may
 4  
  * not use this file except in compliance with the License. You may
 5  
  * obtain a copy of the License at
 6  
  *
 7  
  * http://www.osedu.org/licenses/ECL-2.0
 8  
  *
 9  
  * Unless required by applicable law or agreed to in writing,
 10  
  * software distributed under the License is distributed on an "AS IS"
 11  
  * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 12  
  * or implied. See the License for the specific language governing
 13  
  * permissions and limitations under the License.
 14  
  */
 15  
 
 16  
 package org.kuali.student.common.util;
 17  
 
 18  
 import java.io.PrintWriter;
 19  
 import java.io.StringWriter;
 20  
 import java.lang.reflect.Constructor;
 21  
 import java.util.Map;
 22  
 
 23  
 import org.apache.log4j.Logger;
 24  
 import org.springframework.aop.ThrowsAdvice;
 25  
 import org.springframework.core.Ordered;
 26  
 
 27  
 /**
 28  
  * @author Daniel Epstein
 29  
  *         <p>
 30  
  *         Use this Advice to map one exception to another for use when other
 31  
  *         advice eats your runtime exceptions outside of your code. This happens in
 32  
  *         Transactions when commit is not called until outside of your DAO
 33  
  *         layer.
 34  
  *         </p>
 35  
  * 
 36  
  * <p>
 37  
  * Set the property "exceptionMapping" as a map that maps an exception class to
 38  
  * your own exception class
 39  
  * </p>
 40  
  * 
 41  
  * <p>
 42  
  * Remember that aspect order is important and that this bean will always be
 43  
  * order "500"
 44  
  * </p>
 45  
  * 
 46  
  * Example:
 47  
  * 
 48  
  * <pre>
 49  
  * &lt;tx:annotation-driven transaction-manager=&quot;JtaTxManager&quot; order=&quot;1000&quot;/&gt;
 50  
  * lt;bean id=&quot;mapExceptionAdvisor&quot;
 51  
  * class=&quot;org.myfoo.ExceptionMappingAdvice&quot;&gt;
 52  
  * &lt;property name=&quot;exceptionMapping&quot;&gt;
 53  
  *         &lt;map&gt;
 54  
  *                 &lt;entry key=&quot;javax.persistence.EntityExistsException&quot;
 55  
  *                         value=&quot;org.myfoo.exceptions.AlreadyExistsException&quot; /&gt;
 56  
  *         &lt;/map&gt;
 57  
  * &lt;/property&gt;
 58  
  * lt;/bean&gt;
 59  
  * lt;aop:config&gt;
 60  
  * &lt;aop:aspect id=&quot;dataAccessToBusinessException&quot;
 61  
  *         ref=&quot;mapExceptionAdvisor&quot;&gt;
 62  
  *         &lt;aop:after-throwing
 63  
  *                 pointcut=&quot;execution(* org.myfoo.service.*.*(..))&quot;
 64  
  *                 method=&quot;afterThrowing&quot; throwing=&quot;ex&quot; /&gt;
 65  
  * &lt;/aop:aspect&gt;
 66  
  * lt;/aop:config&gt;
 67  
  * </pre>
 68  
  */
 69  0
 public class ExceptionMappingAdvice implements ThrowsAdvice, Ordered {
 70  0
         private int order = 500;
 71  
         private static final long serialVersionUID = 1L;
 72  
         private Map<Class<? extends Exception>, Class<? extends Exception>> exceptionMapping;
 73  
         private Class<? extends Exception> defaultException;
 74  0
         final Logger logger = Logger.getLogger(ExceptionMappingAdvice.class);
 75  
 
 76  
         /**
 77  
          * This method will use the real exception thrown and look up the exception
 78  
          * that should be thrown
 79  
          * 
 80  
          * @param ex
 81  
          * @throws Exception
 82  
          */
 83  
         public void afterThrowing(Exception ex) throws Exception {
 84  0
                 Class<? extends Exception> mappedExceptionClass = exceptionMapping
 85  
                                 .get(ex.getClass());
 86  
 
 87  0
                 if (mappedExceptionClass != null) {
 88  0
                 logger.debug("Mapping exception "+ex.getClass()+" to "+mappedExceptionClass);
 89  0
                 Constructor<? extends Exception> c = mappedExceptionClass
 90  
                                         .getConstructor(String.class);
 91  0
                         Exception mappedException = c.newInstance(ex.getMessage());
 92  0
                         throw mappedException;
 93  
                 }
 94  
                 
 95  
                 //Throw a default exception if this is a runtime exception
 96  0
                 if(ex instanceof RuntimeException){
 97  0
                         logger.trace("No mapping available, throwing default exception "+defaultException);
 98  0
                         if (defaultException != null) {
 99  
                                 //Log the error
 100  0
                                 StringWriter traceWriter = new StringWriter();
 101  0
                                 PrintWriter printWriter = new PrintWriter(traceWriter, false);
 102  0
                                 logger.error(printWriter, ex);
 103  0
                                 printWriter.close();
 104  0
                                 String faultMessage = traceWriter.getBuffer().toString();
 105  0
                                 logger.error(faultMessage);
 106  
                                 //Throw the default exception
 107  
                                 try{
 108  0
                                         Constructor<? extends Exception> c = defaultException
 109  
                                                         .getConstructor(String.class, Throwable.class);
 110  0
                                         throw c.newInstance(ex.getMessage(), ex);
 111  0
                                 }catch(NoSuchMethodException e){
 112  0
                                         Constructor<? extends Exception> c = defaultException
 113  
                                                         .getConstructor(String.class);
 114  0
                                         throw c.newInstance(ex.getMessage());
 115  
                                 }
 116  
                         }
 117  
                         //Check if no default was defined
 118  0
                         logger.debug("No mapping or default exception available. Exception "+ex.getClass());
 119  0
                         throw new RuntimeException("Could Not Map Exception: " + ex.toString());
 120  
                 }
 121  0
         }
 122  
 
 123  
         @Override
 124  
         public int getOrder() {
 125  0
                 return order;
 126  
         }
 127  
 
 128  
         /**
 129  
          * @param order
 130  
          *            the order to set
 131  
          */
 132  
         public void setOrder(int order) {
 133  0
                 this.order = order;
 134  0
         }
 135  
 
 136  
         /**
 137  
          * @return the exceptionMapping
 138  
          */
 139  
         public Map<Class<? extends Exception>, Class<? extends Exception>> getExceptionMapping() {
 140  0
                 return exceptionMapping;
 141  
         }
 142  
 
 143  
         /**
 144  
          * @param exceptionMapping
 145  
          *            the exceptionMapping to set
 146  
          */
 147  
         public void setExceptionMapping(
 148  
                         Map<Class<? extends Exception>, Class<? extends Exception>> exceptionMapping) {
 149  0
                 this.exceptionMapping = exceptionMapping;
 150  0
         }
 151  
 
 152  
         /**
 153  
          * @return the defaultException
 154  
          */
 155  
         public Class<? extends Exception> getDefaultException() {
 156  0
                 return defaultException;
 157  
         }
 158  
 
 159  
         /**
 160  
          * @param defaultException
 161  
          *            the defaultException to set
 162  
          */
 163  
         public void setDefaultException(Class<? extends Exception> defaultException) {
 164  0
                 this.defaultException = defaultException;
 165  0
         }
 166  
 
 167  
 }