1 21 22 package org.apache.derby.iapi.services.context; 23 24 import org.apache.derby.iapi.services.sanity.SanityManager; 25 import org.apache.derby.iapi.services.stream.HeaderPrintWriter; 26 27 import org.apache.derby.iapi.error.PassThroughException; 28 29 import org.apache.derby.iapi.error.StandardException; 30 import org.apache.derby.iapi.services.monitor.Monitor; 31 32 import org.apache.derby.iapi.reference.Property; 33 import org.apache.derby.iapi.services.property.PropertyUtil; 34 35 import org.apache.derby.iapi.error.ExceptionSeverity; 36 import org.apache.derby.iapi.services.i18n.LocaleFinder; 37 38 import java.util.HashMap ; 39 import java.util.ArrayList ; 40 import java.util.List ; 41 import java.util.Collections ; 42 import java.util.Locale ; 43 44 58 59 public class ContextManager 60 { 61 67 private static final class CtxStack { 68 private ArrayList stack_ = new ArrayList (); 69 70 private Context top_ = null; 75 76 void push(Context context) { 77 stack_.add(context); 78 top_ = context; 79 } 80 void pop() { 81 stack_.remove(stack_.size()-1); 82 top_ = stack_.isEmpty() ? 83 null : (Context) stack_.get(stack_.size()-1); 84 } 85 void remove(Context context) { 86 if (context == top_) { 87 pop(); 88 return; 89 } 90 stack_.remove(stack_.lastIndexOf(context)); 91 } 92 Context top() { 93 return top_; 94 } 95 boolean isEmpty() { return stack_.isEmpty(); } 96 List getUnmodifiableList() { 97 return Collections.unmodifiableList(stack_); 98 } 99 } 100 101 104 106 111 private final HashMap ctxTable = new HashMap (); 112 113 116 private final ArrayList holder = new ArrayList (); 117 118 124 public void pushContext(Context newContext) 125 { 126 checkInterrupt(); 127 final String contextId = newContext.getIdName(); 128 CtxStack idStack = (CtxStack) ctxTable.get(contextId); 129 130 if (idStack == null) { 132 idStack = new CtxStack(); 133 ctxTable.put(contextId, idStack); 134 } 135 136 idStack.push(newContext); 138 139 holder.add(newContext); 141 } 142 143 149 public Context getContext(String contextId) { 150 checkInterrupt(); 151 152 final CtxStack idStack = (CtxStack) ctxTable.get(contextId); 153 if (SanityManager.DEBUG) 154 SanityManager.ASSERT( idStack == null || 155 idStack.isEmpty() || 156 idStack.top().getIdName() == contextId); 157 return (idStack==null?null:idStack.top()); 158 } 159 160 164 public void popContext() 165 { 166 checkInterrupt(); 167 if (holder.isEmpty()) { 169 return; 170 } 171 172 Context theContext = (Context) holder.remove(holder.size()-1); 174 175 final String contextId = theContext.getIdName(); 177 final CtxStack idStack = (CtxStack) ctxTable.get(contextId); 178 179 if (SanityManager.DEBUG) { 180 SanityManager.ASSERT( idStack != null && 181 (! idStack.isEmpty()) && 182 idStack.top().getIdName() == contextId); 183 } 184 idStack.pop(); 185 } 186 187 192 void popContext(Context theContext) 193 { 194 checkInterrupt(); 195 if (SanityManager.DEBUG) 196 SanityManager.ASSERT(!holder.isEmpty()); 197 198 holder.remove(holder.lastIndexOf(theContext)); 200 201 final String contextId = theContext.getIdName(); 202 final CtxStack idStack = (CtxStack) ctxTable.get(contextId); 203 204 idStack.remove(theContext); 206 } 207 208 211 final boolean isEmpty() 212 { 213 return holder.isEmpty(); 214 } 215 216 228 public final List getContextStack(String contextId) { 229 final CtxStack cs = (CtxStack) ctxTable.get(contextId); 230 return (cs==null?Collections.EMPTY_LIST:cs.getUnmodifiableList()); 231 } 232 233 234 237 public boolean cleanupOnError(Throwable error) 238 { 239 if (shutdown) 240 return true; 241 242 if (errorStringBuilder == null) 243 errorStringBuilder = new ErrorStringBuilder(errorStream.getHeader()); 244 245 ThreadDeath seenThreadDeath = null; 246 if (error instanceof ThreadDeath ) 247 seenThreadDeath = (ThreadDeath ) error; 248 249 if (error instanceof PassThroughException) 250 error = ((PassThroughException) error).getException(); 251 252 boolean reportError = reportError(error); 253 254 if (reportError) 255 { 256 ContextImpl lcc = null; 257 StringBuffer sb = null; 258 if (! shutdown) 259 { 260 lcc = (ContextImpl) getContext(org.apache.derby.iapi.reference.ContextId.LANG_CONNECTION); 262 if (lcc != null) { 263 sb = lcc.appendErrorInfo(); 264 } 265 } 266 267 String cleanup = "Cleanup action starting"; 268 269 if (sb != null) { 270 sb.append(cleanup); 271 cleanup = sb.toString(); 272 } 273 274 errorStringBuilder.appendln(cleanup); 275 276 if (!shutdown) { 278 ContextImpl sc = (ContextImpl) getContext(org.apache.derby.iapi.reference.ContextId.LANG_STATEMENT); 279 if (sc != null) 281 { 282 sb = sc.appendErrorInfo(); 283 if (sb != null) 284 errorStringBuilder.appendln(sb.toString()); 285 } 286 } 287 } 288 289 295 296 297 forever: for (;;) { 298 299 int errorSeverity = error instanceof StandardException ? 300 ((StandardException) error).getSeverity() : 301 ExceptionSeverity.NO_APPLICABLE_SEVERITY; 302 if (reportError) { 303 errorStringBuilder.stackTrace(error); 304 flushErrorString(); 305 } 306 307 308 boolean lastHandler = false; 309 310 311 316 cleanup: for (int index = holder.size() - 1; index >= 0; index--) { 317 318 try { 319 if (lastHandler) 320 { 321 break; 322 } 323 324 Context ctx = ((Context) holder.get(index)); 325 lastHandler = ctx.isLastHandler(errorSeverity); 326 327 ctx.cleanupOnError(error); 328 } 329 catch (StandardException se) { 330 331 if (error instanceof StandardException) { 332 333 if (se.getSeverity() > ((StandardException) error).getSeverity()) { 334 error = se; 337 reportError = reportError(se); 338 if (reportError) { 339 errorStream.println("New exception raised during cleanup " + error.getMessage()); 340 errorStream.flush(); 341 } 342 continue forever; 343 } 344 } 345 346 if (reportError(se)) { 347 errorStringBuilder.appendln("Less severe exception raised during cleanup (ignored) " + se.getMessage()); 348 errorStringBuilder.stackTrace(se); 349 flushErrorString(); 350 } 351 352 355 continue cleanup; 356 } 357 catch (Throwable t) { 358 reportError = reportError(t); 359 360 361 if (error instanceof StandardException) { 362 368 error = t; 369 if (reportError) { 370 errorStream.println("New exception raised during cleanup " + error.getMessage()); 371 errorStream.flush(); 372 } 373 continue forever; 374 } 375 376 377 if (reportError) { 378 errorStringBuilder.appendln("Equally severe exception raised during cleanup (ignored) " + t.getMessage()); 379 errorStringBuilder.stackTrace(t); 380 flushErrorString(); 381 } 382 383 if (t instanceof ThreadDeath ) { 384 if (seenThreadDeath != null) 385 throw seenThreadDeath; 386 387 seenThreadDeath = (ThreadDeath ) t; 388 } 389 390 394 continue cleanup; 395 } 396 } 397 398 if (reportError) { 399 errorStream.println("Cleanup action completed"); 400 errorStream.flush(); 401 } 402 403 if (seenThreadDeath != null) 404 throw seenThreadDeath; 405 406 return false; 407 } 408 409 } 410 411 412 synchronized boolean setInterrupted(Context c) { 413 414 boolean interruptMe = (c == null) || holder.contains(c); 415 416 if (interruptMe) { 417 this.shutdown = true; 418 } 419 return interruptMe; 420 } 421 422 428 private void checkInterrupt() { 429 if (shutdown) { 430 throw new ShutdownException(); 432 } 433 } 434 435 438 public void setLocaleFinder(LocaleFinder finder) { 439 this.finder = finder; 440 } 441 442 private Locale messageLocale; 443 444 public void setMessageLocale(String localeID) throws StandardException { 445 this.messageLocale = Monitor.getLocaleFromString(localeID); 446 } 447 448 public Locale getMessageLocale() 449 { 450 if (messageLocale != null) 451 return messageLocale; 452 else if (finder != null) { 453 try { 454 return finder.getCurrentLocale(); 455 } catch (StandardException se) { 456 457 } 458 } 459 return Locale.getDefault(); 460 } 461 462 466 private void flushErrorString() 467 { 468 errorStream.print(errorStringBuilder.get().toString()); 469 errorStream.flush(); 470 errorStringBuilder.reset(); 471 } 472 473 476 477 private boolean reportError(Throwable t) { 478 479 if (t instanceof StandardException) { 480 481 StandardException se = (StandardException) t; 482 483 switch (se.report()) { 484 case StandardException.REPORT_DEFAULT: 485 int level = se.getSeverity(); 486 return (level >= logSeverityLevel) || 487 (level == ExceptionSeverity.NO_APPLICABLE_SEVERITY); 488 489 case StandardException.REPORT_NEVER: 490 return false; 491 492 case StandardException.REPORT_ALWAYS: 493 default: 494 return true; 495 } 496 } 497 498 return !(t instanceof ShutdownException); 499 500 } 501 502 508 ContextManager(ContextService csf, HeaderPrintWriter stream) 509 { 510 errorStream = stream; 511 owningCsf = csf; 512 513 logSeverityLevel = PropertyUtil.getSystemInt(Property.LOG_SEVERITY_LEVEL, 514 SanityManager.DEBUG ? 0 : ExceptionSeverity.SESSION_SEVERITY); 515 } 516 517 final ContextService owningCsf; 518 519 private int logSeverityLevel; 520 521 private HeaderPrintWriter errorStream; 522 private ErrorStringBuilder errorStringBuilder; 523 524 private boolean shutdown; 525 private LocaleFinder finder; 526 527 546 Thread activeThread; 547 548 558 int activeCount; 559 } 560 | Popular Tags |