00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030  
00031 package org.objectweb.proactive.core.exceptions.manager;
00032 
00033 import java.util.Collection;
00034 import java.util.Iterator;
00035 import java.util.LinkedList;
00036 import java.util.NoSuchElementException;
00037 
00038 
00039 public class ExceptionMaskStack {
00040 
00041     
00042     private LinkedList<ExceptionMaskLevel> stack;
00043 
00044     
00045     private ExceptionMaskLevel currentExceptionMask;
00046 
00047     private ExceptionMaskStack() {
00048         stack = new LinkedList<ExceptionMaskLevel>();
00049         currentExceptionMask = new ExceptionMaskLevel();
00050     }
00051 
00052     
00053 
00054 
00055 
00056 
00057     private static ThreadLocal threadLocalMask = new ThreadLocal() {
00058             protected synchronized Object initialValue() {
00059                 return new ExceptionMaskStack();
00060             }
00061         };
00062 
00063     
00064     static ExceptionMaskStack get() {
00065         return (ExceptionMaskStack) threadLocalMask.get();
00066     }
00067 
00068     void push(Class[] exceptions) {
00069         ExceptionMaskLevel level = new ExceptionMaskLevel(this, exceptions);
00070         stack.add(0, level);
00071         currentExceptionMask.addExceptionTypes(level);
00072     }
00073 
00074     void pop() {
00075         if (stack.isEmpty()) {
00076             throw new IllegalStateException("The stack has nothing to pop");
00077         }
00078 
00079         stack.removeFirst();
00080         updateExceptionMask();
00081     }
00082 
00083     
00084     private void updateExceptionMask() {
00085         currentExceptionMask = new ExceptionMaskLevel();
00086         Iterator<ExceptionMaskLevel> iter = stack.iterator();
00087         while (iter.hasNext()) {
00088             ExceptionMaskLevel level = iter.next();
00089             currentExceptionMask.addExceptionTypes(level);
00090         }
00091     }
00092 
00093     void throwArrivedException() {
00094         Collection caughtExceptions = getTopLevel().getCaughtExceptions();
00095         synchronized (caughtExceptions) {
00096             if (!caughtExceptions.isEmpty()) {
00097                 Throwable exc = (Throwable) caughtExceptions.iterator().next();
00098                 ExceptionThrower.throwException(exc);
00099             }
00100         }
00101     }
00102 
00103     private ExceptionMaskLevel getTopLevel() {
00104         try {
00105             return stack.getFirst();
00106         } catch (NoSuchElementException nsee) {
00107             throw new IllegalStateException("Exception stack is empty");
00108         }
00109     }
00110 
00111     void waitForPotentialException(boolean allLevels) {
00112         if (allLevels) {
00113             Iterator<ExceptionMaskLevel> iter = stack.iterator();
00114             while (iter.hasNext()) {
00115                 ExceptionMaskLevel level = iter.next();
00116                 level.waitForPotentialException();
00117             }
00118         } else {
00119             getTopLevel().waitForPotentialException();
00120         }
00121     }
00122 
00123     
00124     ExceptionMaskLevel findBestLevel(Class[] c) {
00125         Iterator<ExceptionMaskLevel> iter = stack.iterator();
00126         while (iter.hasNext()) {
00127             ExceptionMaskLevel level = iter.next();
00128             if (level.catchRuntimeException() ||
00129                     level.areExceptionTypesCaught(c)) {
00130                 return level;
00131             }
00132         }
00133 
00134         throw new IllegalStateException("No exception level found");
00135     }
00136 
00137     void waitForIntersection(Class[] exceptions) {
00138         if (currentExceptionMask.areExceptionTypesCaught(exceptions)) {
00139             Iterator<ExceptionMaskLevel> iter = stack.iterator();
00140             while (iter.hasNext()) {
00141                 ExceptionMaskLevel level = iter.next();
00142                 if (level.areExceptionTypesCaught(exceptions)) {
00143                     level.waitForPotentialException();
00144                 }
00145             }
00146         }
00147     }
00148 
00149     boolean areExceptionTypesCaught(Class[] c) {
00150         return currentExceptionMask.areExceptionTypesCaught(c);
00151     }
00152 
00153     boolean isExceptionTypeCaught(Class c) {
00154         return currentExceptionMask.isExceptionTypeCaught(c);
00155     }
00156 
00157     boolean isRuntimeExceptionHandled() {
00158         return currentExceptionMask.catchRuntimeException();
00159     }
00160 
00161     Collection getAllExceptions() {
00162         return getTopLevel().getAllExceptions();
00163     }
00164 }