Source Code Cross Referenced for ContextService.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.ContextService
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.monitor.Monitor;
025:        import org.apache.derby.iapi.services.sanity.SanityManager;
026:        import org.apache.derby.iapi.services.stream.HeaderPrintWriter;
027:
028:        import java.util.Hashtable;
029:        import java.util.Enumeration;
030:
031:        import java.util.HashSet;
032:        import java.util.Iterator;
033:
034:        /**
035:         A set of static methods to supply easier access to contexts.
036:         */
037:        public final class ContextService //OLD extends Hashtable
038:        {
039:
040:            private static ContextService factory;
041:            private HeaderPrintWriter errorStream;
042:
043:            /**
044:            	Maintains a list of all the contexts that this thread has created
045:            	and/or used. The object stored in the thread local varys according
046:            	how this thread has been used and will be one of:
047:
048:            	<UL>
049:            	<LI> null - the thread no affiliation with a context manager.
050:
051:            	<LI> ContextManager - the current thread has used or is using
052:                    this context manager. If ContextManager.activeThread equals
053:                    the current thread then the thread is currently active with
054:                    the ContextManager. In this case ContextManager.activeCount
055:                    will be greater than zero and represent the level of nested
056:                    setCurrentContextmanager calls.
057:                    If ContextManager.activeThread is null then no other thread
058:                    is using the Contextmanager, if ContextManager.activeThread
059:                    is not-null and not equal to the current thread then some
060:                    other thread is using the context. It is assumed that
061:                    only a single thread can be using a ContextManager at any time
062:                    and this is enforced by synchronization outside the ContextManager.
063:                    E.g for JDBC connections, synchronization at the JDBC level.
064:
065:            	<LI> java.util.Stack containing ContextManagers - the current
066:                thread is actively using multiple different ContextManagers,
067:                with nesting. All ContextManagers in the stack will have
068:                activeThread set to the current thread, and their activeCount
069:                set to -1. This is beacause nesting is soley represented by
070:                the stack, with the current context manager on top of the stack.
071:                This supports multiple levels of nesting across two stacks, e.g.
072:                C1->C2->C2->C1->C2.
073:            	</UL>
074:
075:            	This thread local is used to find the current context manager. Basically it provides
076:            	fast access to a list of candidate contexts. If one of the contexts has its activeThread
077:            	equal to the current thread then it is the current context manager.
078:
079:            	If the thread has pushed multiple contexts (e.g. open a new non-nested Cloudscape connection
080:            	from a server side method) then threadContextList will contain a Stack. The value for each cm
081:            	will be a push order, with higher numbers being more recently pushed.
082:
083:            	To support the case where a single context manager is pushed twice (nested connection),
084:            	the context manager keeps track of the number of times it has been pushed (set). Note that
085:            	our synchronization requires that a single context can only be accessed by a single thread at a time.
086:            	In the JDBC layer this is enforced by the synchronization on the connection object.
087:
088:            	<P>
089:            	There are two cases we are trying to optimise.
090:            	<UL>
091:            	<LI> Typical JDBC client program where there a Connection is always executed using a single thread.
092:            		In this case this variable will contain the Connection's context manager 
093:            	<LI> Typical application server pooled connection where a single thread may use a connection from a pool
094:            	for the lifetime of the request. In this case this variable will contain a  WeakReference.
095:            	</UL>
096:                <BR>
097:                Single thread for Connection exection.
098:                <pre>
099:                threadContextList.get() == cm
100:                // while in JDBC engine code
101:                cm.activeThread == Thread.currentThread();
102:                cm.activeCount = 1;
103:                </pre>
104:                
105:                <BR>
106:                J2EE single thread for lifetime of execution.
107:                <pre>
108:                // thread executing request
109:                 threadContextList.get() == cm
110:                // while in JDBC engine code
111:                cm.activeThread == Thread.currentThread();
112:                cm.activeCount = 1;
113:                
114:                // other threads that have recently executed
115:                // the same connection can have
116:                threadContextList.get() == cm
117:                cm.activeThread != Thread.currentThread();
118:               </pre>
119:                
120:                <BR>
121:                Nested routine calls within single connection
122:                <pre>
123:                threadContextList.get() == cm
124:                // Within server-side JDBC code in a
125:                // function called from another function/procedure
126:                // called from an applications's statement
127:                // (three levels of nesting)
128:                cm.activeThread == Thread.currentThread();
129:                cm.activeCount = 3;         
130:                </pre>
131:                
132:                <BR>
133:                Nested routine calls with the inner routine
134:                using a different connection to access a Derby database.
135:                Note nesting of orignal Contextmanager cm is changed
136:                from an activeCount of 2 to nesting within the stack
137:                once multiple ContextManagers are involved.
138:                <pre>
139:                threadContextList.get() == stack {cm2,cm,cm}
140:                cm.activeThread == Thread.currentThread();
141:                cm.activeCount = -1; // nesting in stack
142:                cm2.activeThread == Thread.currentThread();
143:                cm2.activeCount = -1; // nesting in stack
144:                </pre> 
145:                
146:                <BR>
147:                Nested multiple ContextManagers, the code supports
148:                this, though it may not be possible currently
149:                to have a stack like this from SQL/JDBC.
150:                <pre>
151:                threadContextList.get() == stack {cm3,cm2,cm,cm2,cm,cm}
152:                cm.activeThread == Thread.currentThread();
153:                cm.activeCount = -1; // nesting in stack
154:                cm2.activeThread == Thread.currentThread();
155:                cm2.activeCount = -1; // nesting in stack
156:                cm3.activeThread == Thread.currentThread();
157:                cm3.activeCount = -1; // nesting in stack
158:                </pre>   
159:             */
160:            private ThreadLocal threadContextList = new ThreadLocal();
161:
162:            /**
163:             * Collection of all ContextManagers that are open
164:             * in the complete Derby system. A ContextManager is
165:             * added when it is created with newContextManager and
166:             * removed when the session is closed.
167:             * 
168:             * @see #newContextManager()
169:             * @see SystemContext#cleanupOnError(Throwable)
170:             */
171:            private HashSet allContexts;
172:
173:            /**
174:             * Create a new ContextService for a Derby system.
175:             * Only a single system is active at any time.
176:             *
177:             */
178:            public ContextService() {
179:
180:                // find the error stream
181:                errorStream = Monitor.getStream();
182:
183:                ContextService.factory = this ;
184:
185:                allContexts = new HashSet();
186:
187:            }
188:
189:            /**
190:            	So it can be given to us and taken away...
191:             */
192:            public static void stop() {
193:                // For some unknown reason, the ContextManager and
194:                // ContextService objects will not be garbage collected
195:                // without the next two lines.
196:                ContextService fact = ContextService.factory;
197:                if (fact != null) {
198:                    synchronized (fact) {
199:                        fact.allContexts = null;
200:                        fact.threadContextList = null;
201:                        ContextService.factory = null;
202:                    }
203:                }
204:            }
205:
206:            public static ContextService getFactory() {
207:                ContextService csf = factory;
208:
209:                if (csf == null)
210:                    throw new ShutdownException();
211:                return csf;
212:            }
213:
214:            /**
215:            	Find the context with the given name in the context service factory
216:            	loaded for the system.
217:
218:            	@return The requested context, null if it doesn't exist.
219:             */
220:            public static Context getContext(String contextId) {
221:
222:                ContextManager cm = getFactory().getCurrentContextManager();
223:
224:                if (cm == null)
225:                    return null;
226:
227:                return cm.getContext(contextId);
228:            }
229:
230:            /**
231:            	Find the context with the given name in the context service factory
232:            	loaded for the system.
233:
234:            	This version will not do any debug checking, but return null
235:            	quietly if it runs into any problems.
236:
237:            	@return The requested context, null if it doesn't exist.
238:             */
239:            public static Context getContextOrNull(String contextId) {
240:                ContextService csf = factory;
241:
242:                if (csf == null)
243:                    return null;
244:
245:                ContextManager cm = csf.getCurrentContextManager();
246:
247:                if (cm == null)
248:                    return null;
249:
250:                return cm.getContext(contextId);
251:            }
252:
253:            /**
254:             * Get current Context Manager linked to the current Thread.
255:             * See setCurrentContextManager for details.
256:             * Note that this call can be expensive and is only
257:             * intended to be used in "stateless" situations.
258:             * Ideally code has a reference to the correct
259:             * ContextManager from another Object, such as a pushed Context.
260:             * 
261:             * @return ContextManager current Context Manager
262:             */
263:            public ContextManager getCurrentContextManager() {
264:
265:                ThreadLocal tcl = threadContextList;
266:                if (tcl == null) {
267:                    // The context service is already stopped.
268:                    return null;
269:                }
270:
271:                Object list = tcl.get();
272:
273:                if (list instanceof  ContextManager) {
274:
275:                    Thread me = Thread.currentThread();
276:
277:                    ContextManager cm = (ContextManager) list;
278:                    if (cm.activeThread == me)
279:                        return cm;
280:                    return null;
281:                }
282:
283:                if (list == null)
284:                    return null;
285:
286:                java.util.Stack stack = (java.util.Stack) list;
287:                return (ContextManager) (stack.peek());
288:
289:            }
290:
291:            /**
292:             * Break the link between the current Thread and the passed
293:             * in ContextManager. Called in a pair with setCurrentContextManager,
294:             * see that method for details.
295:             */
296:            public void resetCurrentContextManager(ContextManager cm) {
297:                ThreadLocal tcl = threadContextList;
298:
299:                if (tcl == null) {
300:                    // The context service is already stopped.
301:                    return;
302:                }
303:
304:                if (SanityManager.DEBUG) {
305:
306:                    if (Thread.currentThread() != cm.activeThread) {
307:                        SanityManager
308:                                .THROWASSERT("resetCurrentContextManager - mismatch threads - current"
309:                                        + Thread.currentThread()
310:                                        + " - cm's "
311:                                        + cm.activeThread);
312:                    }
313:
314:                    if (getCurrentContextManager() != cm) {
315:                        SanityManager
316:                                .THROWASSERT("resetCurrentContextManager - mismatch contexts - "
317:                                        + Thread.currentThread());
318:                    }
319:
320:                    if (cm.activeCount < -1) {
321:                        SanityManager
322:                                .THROWASSERT("resetCurrentContextManager - invalid count - current"
323:                                        + Thread.currentThread()
324:                                        + " - count "
325:                                        + cm.activeCount);
326:                    }
327:
328:                    if (cm.activeCount == 0) {
329:                        SanityManager
330:                                .THROWASSERT("resetCurrentContextManager - invalid count - current"
331:                                        + Thread.currentThread()
332:                                        + " - count "
333:                                        + cm.activeCount);
334:                    }
335:
336:                    if (cm.activeCount > 0) {
337:                        if (tcl.get() != cm)
338:                            SanityManager
339:                                    .THROWASSERT("resetCurrentContextManager - invalid thread local "
340:                                            + Thread.currentThread()
341:                                            + " - object " + tcl.get());
342:
343:                    }
344:                }
345:
346:                if (cm.activeCount != -1) {
347:                    if (--cm.activeCount == 0) {
348:                        cm.activeThread = null;
349:
350:                        // If the ContextManager is empty
351:                        // then don't keep a reference to it
352:                        // when it is not in use. The ContextManager
353:                        // has been closed (most likely) and this
354:                        // is now unwanted. Keeping the reference
355:                        // would hold onto memory and increase the
356:                        // chance of holding onto a another reference
357:                        // will could cause issues for future operations.
358:                        if (cm.isEmpty())
359:                            tcl.set(null);
360:
361:                    }
362:                    return;
363:                }
364:
365:                java.util.Stack stack = (java.util.Stack) tcl.get();
366:
367:                Object oldCM = stack.pop();
368:
369:                ContextManager nextCM = (ContextManager) stack.peek();
370:
371:                boolean seenMultipleCM = false;
372:                boolean seenCM = false;
373:                for (int i = 0; i < stack.size(); i++) {
374:
375:                    Object stackCM = stack.elementAt(i);
376:                    if (stackCM != nextCM)
377:                        seenMultipleCM = true;
378:
379:                    if (stackCM == cm)
380:                        seenCM = true;
381:                }
382:
383:                if (!seenCM) {
384:                    cm.activeThread = null;
385:                    cm.activeCount = 0;
386:                }
387:
388:                if (!seenMultipleCM) {
389:                    // all the context managers on the stack
390:                    // are the same so reduce to a simple count.
391:                    nextCM.activeCount = stack.size();
392:                    tcl.set(nextCM);
393:                }
394:            }
395:
396:            /**
397:             * The current thread (passed in a me) is setting associateCM
398:             * to be its current context manager. Sets the thread local
399:             * variable threadContextList to reflect associateCM being
400:             * the current ContextManager.
401:             * 
402:             * @return True if the nesting level is to be represented in
403:             * the ContextManager.activeCount field. False if not.
404:             * 
405:             * @see ContextManager#activeCount
406:             * @see ContextManager#activeThread
407:             */
408:            private boolean addToThreadList(Thread me,
409:                    ContextManager associateCM) {
410:
411:                ThreadLocal tcl = threadContextList;
412:
413:                if (tcl == null) {
414:                    // The context service is already stopped.
415:                    return false;
416:                }
417:
418:                Object list = tcl.get();
419:
420:                // Already set up to reflect associateCM ContextManager
421:                if (associateCM == list)
422:                    return true;
423:
424:                // Not currently using any ContextManager
425:                if (list == null) {
426:                    tcl.set(associateCM);
427:                    return true;
428:                }
429:
430:                java.util.Stack stack;
431:                if (list instanceof  ContextManager) {
432:
433:                    // Could be two situations:
434:                    // 1. Single ContextManager not in use by this thread
435:                    // 2. Single ContextManager in use by this thread (nested call)
436:
437:                    ContextManager threadsCM = (ContextManager) list;
438:                    if (me == null)
439:                        me = Thread.currentThread();
440:
441:                    if (threadsCM.activeThread != me) {
442:                        // Not nested, just a CM left over
443:                        // from a previous execution.
444:                        tcl.set(associateCM);
445:                        return true;
446:                    }
447:
448:                    // Nested, need to create a Stack of ContextManagers,
449:                    // the top of the stack will be the active one.
450:                    stack = new java.util.Stack();
451:                    tcl.set(stack);
452:
453:                    // The stack represents the true nesting
454:                    // of ContextManagers, splitting out nesting
455:                    // of a single ContextManager into multiple
456:                    // entries in the stack.
457:                    for (int i = 0; i < threadsCM.activeCount; i++) {
458:                        stack.push(threadsCM);
459:                    }
460:                    threadsCM.activeCount = -1;
461:                } else {
462:                    // existing stack, nesting represented
463:                    // by stack entries, not activeCount.
464:                    stack = (java.util.Stack) list;
465:                }
466:
467:                stack.push(associateCM);
468:                associateCM.activeCount = -1;
469:
470:                if (SanityManager.DEBUG) {
471:
472:                    if (SanityManager.DEBUG_ON("memoryLeakTrace")) {
473:
474:                        if (stack.size() > 10)
475:                            System.out
476:                                    .println("memoryLeakTrace:ContextService:threadLocal "
477:                                            + stack.size());
478:                    }
479:                }
480:
481:                return false;
482:            }
483:
484:            /**
485:             * Link the current thread to the passed in Contextmanager
486:             * so that a subsequent call to getCurrentContextManager by
487:             * the current Thread will return cm.
488:             * ContextManagers are tied to a Thread while the thread
489:             * is executing Derby code. For example on most JDBC method
490:             * calls the ContextManager backing the Connection object
491:             * is tied to the current Thread at the start of the method
492:             * and reset at the end of the method. Once the Thread
493:             * has completed its Derby work the method resetCurrentContextManager
494:             * must be called with the same ContextManager to break the link.
495:             * Note that a subsquent use of the ContextManager may be on
496:             * a separate Thread, the Thread is only linked to the ContextManager
497:             * between the setCurrentContextManager and resetCurrentContextManager calls.
498:             * <BR>
499:             * ContextService supports nesting of calls by a single Thread, either
500:             * with the same ContextManager or a different ContextManager.
501:             * <UL>
502:             * <LI>The same ContextManager would be pushed during a nested JDBC call in
503:             * a procedure or function.
504:             * <LI>A different ContextManager would be pushed during a call on
505:             * a different embedded JDBC Connection in a procedure or function.
506:             * </UL>
507:             */
508:            public void setCurrentContextManager(ContextManager cm) {
509:
510:                if (SanityManager.DEBUG) {
511:                    Thread me = Thread.currentThread();
512:
513:                    if (cm.activeThread != null && me != cm.activeThread) {
514:                        SanityManager
515:                                .THROWASSERT("setCurrentContextManager - mismatch threads - current "
516:                                        + me + " - cm's " + cm.activeThread);
517:                    }
518:
519:                }
520:
521:                Thread me = null;
522:
523:                if (cm.activeThread == null) {
524:                    cm.activeThread = (me = Thread.currentThread());
525:                }
526:                if (addToThreadList(me, cm))
527:                    cm.activeCount++;
528:            }
529:
530:            /**
531:             * It's up to the caller to track this context manager and set it
532:             * in the context manager list using setCurrentContextManager.
533:             * We don't keep track of it due to this call being made.
534:             */
535:            public ContextManager newContextManager() {
536:                ContextManager cm = new ContextManager(this , errorStream);
537:
538:                // push a context that will shut down the system on
539:                // a severe error.
540:                new SystemContext(cm);
541:
542:                synchronized (this ) {
543:                    allContexts.add(cm);
544:
545:                    if (SanityManager.DEBUG) {
546:
547:                        if (SanityManager.DEBUG_ON("memoryLeakTrace")) {
548:
549:                            if (allContexts.size() > 50)
550:                                System.out
551:                                        .println("memoryLeakTrace:ContextService:allContexts "
552:                                                + allContexts.size());
553:                        }
554:                    }
555:                }
556:
557:                return cm;
558:            }
559:
560:            public void notifyAllActiveThreads(Context c) {
561:                Thread me = Thread.currentThread();
562:
563:                synchronized (this ) {
564:                    for (Iterator i = allContexts.iterator(); i.hasNext();) {
565:
566:                        ContextManager cm = (ContextManager) i.next();
567:
568:                        Thread active = cm.activeThread;
569:
570:                        if (active == me)
571:                            continue;
572:
573:                        if (active == null)
574:                            continue;
575:
576:                        if (cm.setInterrupted(c))
577:                            active.interrupt();
578:                    }
579:                }
580:            }
581:
582:            /**
583:             * Remove a ContextManager from the list of all active
584:             * contexts managers.
585:             */
586:            synchronized void removeContext(ContextManager cm) {
587:                if (allContexts != null)
588:                    allContexts.remove(cm);
589:            }
590:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.