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 }