Source Code Cross Referenced for ContextManager.java in  » Database-DBMS » db-derby-10.2 » org » apache » derby » iapi » services » context » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database DBMS » db derby 10.2 » org.apache.derby.iapi.services.context 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:
003:           Derby - Class org.apache.derby.iapi.services.context.ContextManager
004:
005:           Licensed to the Apache Software Foundation (ASF) under one or more
006:           contributor license agreements.  See the NOTICE file distributed with
007:           this work for additional information regarding copyright ownership.
008:           The ASF licenses this file to you under the Apache License, Version 2.0
009:           (the "License"); you may not use this file except in compliance with
010:           the License.  You may obtain a copy of the License at
011:
012:              http://www.apache.org/licenses/LICENSE-2.0
013:
014:           Unless required by applicable law or agreed to in writing, software
015:           distributed under the License is distributed on an "AS IS" BASIS,
016:           WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017:           See the License for the specific language governing permissions and
018:           limitations under the License.
019:
020:         */
021:
022:        package org.apache.derby.iapi.services.context;
023:
024:        import org.apache.derby.iapi.services.sanity.SanityManager;
025:        import org.apache.derby.iapi.services.stream.HeaderPrintWriter;
026:
027:        import org.apache.derby.iapi.error.PassThroughException;
028:
029:        import org.apache.derby.iapi.error.StandardException;
030:        import org.apache.derby.iapi.services.monitor.Monitor;
031:
032:        import org.apache.derby.iapi.reference.Property;
033:        import org.apache.derby.iapi.services.property.PropertyUtil;
034:
035:        import org.apache.derby.iapi.error.ExceptionSeverity;
036:        import org.apache.derby.iapi.services.i18n.LocaleFinder;
037:
038:        import java.util.HashMap;
039:        import java.util.ArrayList;
040:        import java.util.List;
041:        import java.util.Collections;
042:        import java.util.Locale;
043:
044:        /**
045:         *
046:         * The ContextManager collects contexts as they are
047:         * created. It maintains stacks of contexts by
048:         * named ids, so that the top context of a given
049:         * type can be returned. It also maintains a global
050:         * stack so that contexts can be traversed in the
051:         * order they were created.
052:         * <p>
053:         * The first implementation of the context manager
054:         * assumes there is only one thread to worry about
055:         * and that the user(s) of the class only create one
056:         * instance of ContextManager.
057:         */
058:
059:        public class ContextManager {
060:            /**
061:             * The CtxStack implement a stack on top of an ArrayList (to avoid
062:             * the inherent overhead associated with java.util.Stack which is
063:             * built on top of java.util.Vector, which is fully
064:             * synchronized).
065:             */
066:            private static final class CtxStack {
067:                private ArrayList stack_ = new ArrayList();
068:
069:                // Keeping a reference to the top element on the stack
070:                // optimizes the frequent accesses to this element. The
071:                // tradeoff is that pushing and popping becomes more
072:                // expensive, but those operations are infrequent.
073:                private Context top_ = null;
074:
075:                void push(Context context) {
076:                    stack_.add(context);
077:                    top_ = context;
078:                }
079:
080:                void pop() {
081:                    stack_.remove(stack_.size() - 1);
082:                    top_ = stack_.isEmpty() ? null : (Context) stack_
083:                            .get(stack_.size() - 1);
084:                }
085:
086:                void remove(Context context) {
087:                    if (context == top_) {
088:                        pop();
089:                        return;
090:                    }
091:                    stack_.remove(stack_.lastIndexOf(context));
092:                }
093:
094:                Context top() {
095:                    return top_;
096:                }
097:
098:                boolean isEmpty() {
099:                    return stack_.isEmpty();
100:                }
101:
102:                List getUnmodifiableList() {
103:                    return Collections.unmodifiableList(stack_);
104:                }
105:            }
106:
107:            /**
108:             * Empty ArrayList to use as void value
109:             */
110:            //private final ArrayList voidArrayList_ = new ArrayList(0);
111:            /**
112:             * HashMap that holds the Context objects. The Contexts are stored
113:             * with a String key.
114:             * @see ContextManager#pushContext(Context)
115:             */
116:            private final HashMap ctxTable = new HashMap();
117:
118:            /**
119:             * List of all Contexts
120:             */
121:            private final ArrayList holder = new ArrayList();
122:
123:            /**
124:             * Add a Context object to the ContextManager. The object is added
125:             * both to the holder list and to a stack for the specific type of
126:             * Context.
127:             * @param newContext the new Context object
128:             */
129:            public void pushContext(Context newContext) {
130:                checkInterrupt();
131:                final String contextId = newContext.getIdName();
132:                CtxStack idStack = (CtxStack) ctxTable.get(contextId);
133:
134:                // if the stack is null, create a new one.
135:                if (idStack == null) {
136:                    idStack = new CtxStack();
137:                    ctxTable.put(contextId, idStack);
138:                }
139:
140:                // add to top of id's stack
141:                idStack.push(newContext);
142:
143:                // add to top of global stack too
144:                holder.add(newContext);
145:            }
146:
147:            /**
148:             * Obtain the last pushed Context object of the type indicated by
149:             * the contextId argument.
150:             * @param contextId a String identifying the type of Context
151:             * @return The Context object with the corresponding contextId, or null if not found
152:             */
153:            public Context getContext(String contextId) {
154:                checkInterrupt();
155:
156:                final CtxStack idStack = (CtxStack) ctxTable.get(contextId);
157:                if (SanityManager.DEBUG)
158:                    SanityManager.ASSERT(idStack == null || idStack.isEmpty()
159:                            || idStack.top().getIdName() == contextId);
160:                return (idStack == null ? null : idStack.top());
161:            }
162:
163:            /**
164:             * Remove the last pushed Context object, regardless of type. If
165:             * there are no Context objects, no action is taken.
166:             */
167:            public void popContext() {
168:                checkInterrupt();
169:                // no contexts to remove, so we're done.
170:                if (holder.isEmpty()) {
171:                    return;
172:                }
173:
174:                // remove the top context from the global stack
175:                Context theContext = (Context) holder.remove(holder.size() - 1);
176:
177:                // now find its id and remove it from there, too
178:                final String contextId = theContext.getIdName();
179:                final CtxStack idStack = (CtxStack) ctxTable.get(contextId);
180:
181:                if (SanityManager.DEBUG) {
182:                    SanityManager.ASSERT(idStack != null
183:                            && (!idStack.isEmpty())
184:                            && idStack.top().getIdName() == contextId);
185:                }
186:                idStack.pop();
187:            }
188:
189:            /**
190:             * Removes the specified Context object. If
191:             * the specified Context object does not exist, the call will fail.
192:             * @param theContext the Context object to remove.
193:             */
194:            void popContext(Context theContext) {
195:                checkInterrupt();
196:                if (SanityManager.DEBUG)
197:                    SanityManager.ASSERT(!holder.isEmpty());
198:
199:                // first, remove it from the global stack.
200:                holder.remove(holder.lastIndexOf(theContext));
201:
202:                final String contextId = theContext.getIdName();
203:                final CtxStack idStack = (CtxStack) ctxTable.get(contextId);
204:
205:                // now remove it from its id's stack.
206:                idStack.remove(theContext);
207:            }
208:
209:            /**
210:             * Is the ContextManager empty containing no Contexts.
211:             */
212:            final boolean isEmpty() {
213:                return holder.isEmpty();
214:            }
215:
216:            /**
217:             * Return an unmodifiable list reference to the ArrayList backing
218:             * CtxStack object for this type of Contexts. This method allows
219:             * fast traversal of all Contexts on that stack. The first element
220:             * in the List corresponds to the bottom of the stack. The
221:             * assumption is that the Stack will not be modified while it is
222:             * being traversed.
223:             * @param contextId the type of Context stack to return.
224:             * @return an unmodifiable "view" of the ArrayList backing the stack
225:             * @see org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext#resetSavepoints()
226:             * @see org.apache.derby.iapi.sql.conn.StatementContext#resetSavePoint()
227:             */
228:            public final List getContextStack(String contextId) {
229:                final CtxStack cs = (CtxStack) ctxTable.get(contextId);
230:                return (cs == null ? Collections.EMPTY_LIST : cs
231:                        .getUnmodifiableList());
232:            }
233:
234:            /**
235:            	@return true if the context manager is shutdown, false otherwise.
236:             */
237:            public boolean cleanupOnError(Throwable error) {
238:                if (shutdown)
239:                    return true;
240:
241:                if (errorStringBuilder == null)
242:                    errorStringBuilder = new ErrorStringBuilder(errorStream
243:                            .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:                    ContextImpl lcc = null;
256:                    StringBuffer sb = null;
257:                    if (!shutdown) {
258:                        // report an id for the message if possible
259:                        lcc = (ContextImpl) getContext(org.apache.derby.iapi.reference.ContextId.LANG_CONNECTION);
260:                        if (lcc != null) {
261:                            sb = lcc.appendErrorInfo();
262:                        }
263:                    }
264:
265:                    String cleanup = "Cleanup action starting";
266:
267:                    if (sb != null) {
268:                        sb.append(cleanup);
269:                        cleanup = sb.toString();
270:                    }
271:
272:                    errorStringBuilder.appendln(cleanup);
273:
274:                    if (!shutdown) // Do this only during normal processing.
275:                    {
276:                        ContextImpl sc = (ContextImpl) getContext(org.apache.derby.iapi.reference.ContextId.LANG_STATEMENT);
277:                        // Output the SQL statement that failed in the log file.
278:                        if (sc != null) {
279:                            sb = sc.appendErrorInfo();
280:                            if (sb != null)
281:                                errorStringBuilder.appendln(sb.toString());
282:                        }
283:                    }
284:                }
285:
286:                /*
287:                  REVISIT RESOLVE
288:                  Ensure that the traversal of the stack works in all 
289:                  cases where contexts can  pop themselves *and* 
290:                  contexts can pop other contexts off the stack.
291:                 */
292:
293:                forever: for (;;) {
294:
295:                    int errorSeverity = error instanceof  StandardException ? ((StandardException) error)
296:                            .getSeverity()
297:                            : ExceptionSeverity.NO_APPLICABLE_SEVERITY;
298:                    if (reportError) {
299:                        errorStringBuilder.stackTrace(error);
300:                        flushErrorString();
301:                    }
302:
303:                    boolean lastHandler = false;
304:
305:                    /*
306:                    	Walk down the stack, calling
307:                    	cleanup on each context. We use
308:                    	the vector interface to do this.
309:                     */
310:                    cleanup: for (int index = holder.size() - 1; index >= 0; index--) {
311:
312:                        try {
313:                            if (lastHandler) {
314:                                break;
315:                            }
316:
317:                            Context ctx = ((Context) holder.get(index));
318:                            lastHandler = ctx.isLastHandler(errorSeverity);
319:
320:                            ctx.cleanupOnError(error);
321:                        } catch (StandardException se) {
322:
323:                            if (error instanceof  StandardException) {
324:
325:                                if (se.getSeverity() > ((StandardException) error)
326:                                        .getSeverity()) {
327:                                    // Ok, error handling raised a more severe error,
328:                                    // restart with the more severe error
329:                                    error = se;
330:                                    reportError = reportError(se);
331:                                    if (reportError) {
332:                                        errorStream
333:                                                .println("New exception raised during cleanup "
334:                                                        + error.getMessage());
335:                                        errorStream.flush();
336:                                    }
337:                                    continue forever;
338:                                }
339:                            }
340:
341:                            if (reportError(se)) {
342:                                errorStringBuilder
343:                                        .appendln("Less severe exception raised during cleanup (ignored) "
344:                                                + se.getMessage());
345:                                errorStringBuilder.stackTrace(se);
346:                                flushErrorString();
347:                            }
348:
349:                            /*
350:                            	For a less severe error, keep with the last error
351:                             */
352:                            continue cleanup;
353:                        } catch (Throwable t) {
354:                            reportError = reportError(t);
355:
356:                            if (error instanceof  StandardException) {
357:                                /*
358:                                	Ok, error handling raised a more severe error,
359:                                	restart with the more severe error
360:                                	A Throwable after a StandardException is always 
361:                                	more severe.
362:                                 */
363:                                error = t;
364:                                if (reportError) {
365:                                    errorStream
366:                                            .println("New exception raised during cleanup "
367:                                                    + error.getMessage());
368:                                    errorStream.flush();
369:                                }
370:                                continue forever;
371:                            }
372:
373:                            if (reportError) {
374:                                errorStringBuilder
375:                                        .appendln("Equally severe exception raised during cleanup (ignored) "
376:                                                + t.getMessage());
377:                                errorStringBuilder.stackTrace(t);
378:                                flushErrorString();
379:                            }
380:
381:                            if (t instanceof  ThreadDeath) {
382:                                if (seenThreadDeath != null)
383:                                    throw seenThreadDeath;
384:
385:                                seenThreadDeath = (ThreadDeath) t;
386:                            }
387:
388:                            /*
389:                            	For a less severe error, just continue with the last
390:                            	error
391:                             */
392:                            continue cleanup;
393:                        }
394:                    }
395:
396:                    if (reportError) {
397:                        errorStream.println("Cleanup action completed");
398:                        errorStream.flush();
399:                    }
400:
401:                    if (seenThreadDeath != null)
402:                        throw seenThreadDeath;
403:
404:                    return false;
405:                }
406:
407:            }
408:
409:            synchronized boolean setInterrupted(Context c) {
410:
411:                boolean interruptMe = (c == null) || holder.contains(c);
412:
413:                if (interruptMe) {
414:                    this .shutdown = true;
415:                }
416:                return interruptMe;
417:            }
418:
419:            /**
420:            	Check to see if we have been interrupted. If we have then
421:            	a ShutdownException will be thrown. This will be either the
422:            	one passed to interrupt or a generic one if some outside
423:            	source interrupted the thread.
424:             */
425:            private void checkInterrupt() {
426:                if (shutdown) {
427:                    // system must have changed underneath us
428:                    throw new ShutdownException();
429:                }
430:            }
431:
432:            /**
433:            	Set the locale for this context.
434:             */
435:            public void setLocaleFinder(LocaleFinder finder) {
436:                this .finder = finder;
437:            }
438:
439:            private Locale messageLocale;
440:
441:            public void setMessageLocale(String localeID)
442:                    throws StandardException {
443:                this .messageLocale = Monitor.getLocaleFromString(localeID);
444:            }
445:
446:            public Locale getMessageLocale() {
447:                if (messageLocale != null)
448:                    return messageLocale;
449:                else if (finder != null) {
450:                    try {
451:                        return finder.getCurrentLocale();
452:                    } catch (StandardException se) {
453:
454:                    }
455:                }
456:                return Locale.getDefault();
457:            }
458:
459:            /**
460:             * Flush the built up error string to whereever
461:             * it is supposed to go, and reset the error string
462:             */
463:            private void flushErrorString() {
464:                errorStream.print(errorStringBuilder.get().toString());
465:                errorStream.flush();
466:                errorStringBuilder.reset();
467:            }
468:
469:            /*
470:             ** Class methods
471:             */
472:
473:            private boolean reportError(Throwable t) {
474:
475:                if (t instanceof  StandardException) {
476:
477:                    StandardException se = (StandardException) t;
478:
479:                    switch (se.report()) {
480:                    case StandardException.REPORT_DEFAULT:
481:                        int level = se.getSeverity();
482:                        return (level >= logSeverityLevel)
483:                                || (level == ExceptionSeverity.NO_APPLICABLE_SEVERITY);
484:
485:                    case StandardException.REPORT_NEVER:
486:                        return false;
487:
488:                    case StandardException.REPORT_ALWAYS:
489:                    default:
490:                        return true;
491:                    }
492:                }
493:
494:                return !(t instanceof  ShutdownException);
495:
496:            }
497:
498:            /**
499:             * Constructs a new instance. No CtxStacks are inserted into the
500:             * hashMap as they will be allocated on demand.
501:             * @param csf the ContextService owning this ContextManager
502:             * @param stream error stream for reporting errors
503:             */
504:            ContextManager(ContextService csf, HeaderPrintWriter stream) {
505:                errorStream = stream;
506:                owningCsf = csf;
507:
508:                logSeverityLevel = PropertyUtil.getSystemInt(
509:                        Property.LOG_SEVERITY_LEVEL, SanityManager.DEBUG ? 0
510:                                : ExceptionSeverity.SESSION_SEVERITY);
511:            }
512:
513:            final ContextService owningCsf;
514:
515:            private int logSeverityLevel;
516:
517:            private HeaderPrintWriter errorStream;
518:            private ErrorStringBuilder errorStringBuilder;
519:
520:            private boolean shutdown;
521:            private LocaleFinder finder;
522:
523:            /**
524:             * The thread that owns this ContextManager, set by
525:             * ContextService.setCurrentContextManager and reset
526:             * by resetCurrentContextManager. Only a single
527:             * thread can be active in a ContextManager at any time,
528:             * and the thread only "owns" the ContextManager while
529:             * it is executing code within Derby. In the JDBC case
530:             * setCurrentContextManager is called at the start of
531:             * a JBDC method and resetCurrentContextManager on completion.
532:             * Nesting within the same thread is supported, such as server-side
533:             * JDBC calls in a Java routine or procedure. In that case
534:             * the activeCount will represent the level of nesting, in
535:             * some situations.
536:             * <BR>
537:
538:             * @see ContextService#setCurrentContextManager(ContextManager)
539:             * @see ContextService#resetCurrentContextManager(ContextManager)
540:             * @see #activeCount
541:             */
542:            Thread activeThread;
543:
544:            /**
545:             * Count of the number of setCurrentContextManager calls
546:             * by a single thread, for nesting situations with a single
547:             * active Contextmanager. If nesting is occuring with multiple
548:             * different ContextManagers then this value is set to -1
549:             * and nesting is represented by entries in a stack in the
550:             * ThreadLocal variable, threadContextList.
551:             * 
552:             * @see ContextService#threadContextList
553:             */
554:            int activeCount;
555:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.