Source Code Cross Referenced for ModalContext.java in  » IDE-Eclipse » jface » org » eclipse » jface » operation » 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 » IDE Eclipse » jface » org.eclipse.jface.operation 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*******************************************************************************
002:         * Copyright (c) 2000, 2006 IBM Corporation and others.
003:         * All rights reserved. This program and the accompanying materials
004:         * are made available under the terms of the Eclipse Public License v1.0
005:         * which accompanies this distribution, and is available at
006:         * http://www.eclipse.org/legal/epl-v10.html
007:         *
008:         * Contributors:
009:         *     IBM Corporation - initial API and implementation
010:         *******************************************************************************/package org.eclipse.jface.operation;
011:
012:        import java.lang.reflect.InvocationTargetException;
013:
014:        import org.eclipse.core.runtime.IProgressMonitor;
015:        import org.eclipse.core.runtime.OperationCanceledException;
016:        import org.eclipse.core.runtime.ProgressMonitorWrapper;
017:        import org.eclipse.core.runtime.Assert;
018:        import org.eclipse.swt.widgets.Display;
019:
020:        /**
021:         * Utility class for supporting modal operations.
022:         * The runnable passed to the <code>run</code> method is executed in a
023:         * separate thread, depending on the value of the passed fork argument. 
024:         * If the runnable is executed in a separate thread then the current thread
025:         * either waits until the new thread ends or, if the current thread is the 
026:         * UI thread, it polls the SWT event queue and dispatches each event.
027:         * <p>
028:         * This class is not intended to be subclassed.
029:         * </p>
030:         */
031:        public class ModalContext {
032:
033:            /**
034:             * Indicated whether ModalContext is in debug mode;
035:             * <code>false</code> by default.
036:             */
037:            private static boolean debug = false;
038:
039:            /**
040:             * The number of nested modal runs, or 0 if not inside a modal run.
041:             * This is global state.
042:             */
043:            private static int modalLevel = 0;
044:
045:            /**
046:             * Indicates whether operations should be run in a separate thread.
047:             * Defaults to true.
048:             * For internal debugging use, set to false to run operations in the calling thread.
049:             */
050:            private static boolean runInSeparateThread = true;
051:
052:            /**
053:             * Thread which runs the modal context.
054:             */
055:            private static class ModalContextThread extends Thread {
056:                /**
057:                 * The operation to be run.
058:                 */
059:                private IRunnableWithProgress runnable;
060:
061:                /** 
062:                 * The exception thrown by the operation starter.
063:                 */
064:                private Throwable throwable;
065:
066:                /**
067:                 * The progress monitor used for progress and cancelation.
068:                 */
069:                private IProgressMonitor progressMonitor;
070:
071:                /**
072:                 * The display used for event dispatching.
073:                 */
074:                private Display display;
075:
076:                /**
077:                 * Indicates whether to continue event queue dispatching.
078:                 */
079:                private volatile boolean continueEventDispatching = true;
080:
081:                /**
082:                 * The thread that forked this modal context thread.
083:                 * 
084:                 * @since 3.1
085:                 */
086:                private Thread callingThread;
087:
088:                /**
089:                 * Creates a new modal context.
090:                 * 
091:                 * @param operation the runnable to run
092:                 * @param monitor the progress monitor to use to display progress and receive
093:                 *   requests for cancelation
094:                 * @param display the display to be used to read and dispatch events
095:                 */
096:                private ModalContextThread(IRunnableWithProgress operation,
097:                        IProgressMonitor monitor, Display display) {
098:                    super ("ModalContext"); //$NON-NLS-1$
099:                    Assert.isTrue(monitor != null && display != null);
100:                    runnable = operation;
101:                    progressMonitor = new AccumulatingProgressMonitor(monitor,
102:                            display);
103:                    this .display = display;
104:                    this .callingThread = Thread.currentThread();
105:                }
106:
107:                /* (non-Javadoc)
108:                 * Method declared on Thread.
109:                 */
110:                public void run() {
111:                    try {
112:                        if (runnable != null) {
113:                            runnable.run(progressMonitor);
114:                        }
115:                    } catch (InvocationTargetException e) {
116:                        throwable = e;
117:                    } catch (InterruptedException e) {
118:                        throwable = e;
119:                    } catch (RuntimeException e) {
120:                        throwable = e;
121:                    } catch (ThreadDeath e) {
122:                        // Make sure to propagate ThreadDeath, or threads will never fully terminate
123:                        throw e;
124:                    } catch (Error e) {
125:                        throwable = e;
126:                    } finally {
127:                        //notify the operation of change of thread of control
128:                        if (runnable instanceof  IThreadListener) {
129:                            ((IThreadListener) runnable)
130:                                    .threadChange(callingThread);
131:                        }
132:
133:                        // Make sure that all events in the asynchronous event queue
134:                        // are dispatched.
135:                        display.syncExec(new Runnable() {
136:                            public void run() {
137:                                // do nothing
138:                            }
139:                        });
140:
141:                        // Stop event dispatching
142:                        continueEventDispatching = false;
143:
144:                        // Force the event loop to return from sleep () so that
145:                        // it stops event dispatching.
146:                        display.asyncExec(null);
147:                    }
148:                }
149:
150:                /**
151:                 * Processes events or waits until this modal context thread terminates.
152:                 */
153:                public void block() {
154:                    if (display == Display.getCurrent()) {
155:                        while (continueEventDispatching) {
156:                            // Run the event loop.  Handle any uncaught exceptions caused
157:                            // by UI events.
158:                            try {
159:                                if (!display.readAndDispatch()) {
160:                                    display.sleep();
161:                                }
162:                            }
163:                            // ThreadDeath is a normal error when the thread is dying.  We must
164:                            // propagate it in order for it to properly terminate.
165:                            catch (ThreadDeath e) {
166:                                throw (e);
167:                            }
168:                            // For all other exceptions, log the problem.
169:                            catch (Throwable e) {
170:                                System.err
171:                                        .println("Unhandled event loop exception during blocked modal context."); //$NON-NLS-1$
172:                                e.printStackTrace();
173:                            }
174:                        }
175:                    } else {
176:                        try {
177:                            join();
178:                        } catch (InterruptedException e) {
179:                            throwable = e;
180:                        }
181:                    }
182:                }
183:            }
184:
185:            /**
186:             * Returns whether the first progress monitor is the same as, or
187:             * a wrapper around, the second progress monitor.
188:             *
189:             * @param monitor1 the first progress monitor
190:             * @param monitor2 the second progress monitor
191:             * @return <code>true</code> if the first is the same as, or
192:             *   a wrapper around, the second
193:             * @see ProgressMonitorWrapper
194:             */
195:            public static boolean canProgressMonitorBeUsed(
196:                    IProgressMonitor monitor1, IProgressMonitor monitor2) {
197:                if (monitor1 == monitor2) {
198:                    return true;
199:                }
200:
201:                while (monitor1 instanceof  ProgressMonitorWrapper) {
202:                    monitor1 = ((ProgressMonitorWrapper) monitor1)
203:                            .getWrappedProgressMonitor();
204:                    if (monitor1 == monitor2) {
205:                        return true;
206:                    }
207:                }
208:                return false;
209:            }
210:
211:            /**
212:             * Checks with the given progress monitor and throws 
213:             * <code>InterruptedException</code> if it has been canceled.
214:             * <p>
215:             * Code in a long-running operation should call this method
216:             * regularly so that a request to cancel will be honored.
217:             * </p>
218:             * <p>
219:             * Convenience for:
220:             * <pre>
221:             * if (monitor.isCanceled())
222:             *    throw new InterruptedException();
223:             * </pre>
224:             * </p>
225:             *
226:             * @param monitor the progress monitor
227:             * @exception InterruptedException if cancelling the operation has been requested
228:             * @see IProgressMonitor#isCanceled()
229:             */
230:            public static void checkCanceled(IProgressMonitor monitor)
231:                    throws InterruptedException {
232:                if (monitor.isCanceled()) {
233:                    throw new InterruptedException();
234:                }
235:            }
236:
237:            /**
238:             * Returns the currently active modal context thread, or null if no modal context is active.
239:             */
240:            private static ModalContextThread getCurrentModalContextThread() {
241:                Thread t = Thread.currentThread();
242:                if (t instanceof  ModalContextThread) {
243:                    return (ModalContextThread) t;
244:                }
245:                return null;
246:            }
247:
248:            /**
249:             * Returns the modal nesting level.
250:             * <p>
251:             * The modal nesting level increases by one each time the
252:             * <code>ModalContext.run</code> method is called within the
253:             * dynamic scope of another call to <code>ModalContext.run</code>.
254:             * </p>
255:             *
256:             * @return the modal nesting level, or <code>0</code> if 
257:             *  this method is called outside the dynamic scope of any
258:             *  invocation of <code>ModalContext.run</code>
259:             */
260:            public static int getModalLevel() {
261:                return modalLevel;
262:            }
263:
264:            /**
265:             * Returns whether the given thread is running a modal context.
266:             * 
267:             * @param thread The thread to be checked
268:             * @return <code>true</code> if the given thread is running a modal context, <code>false</code> if not
269:             */
270:            public static boolean isModalContextThread(Thread thread) {
271:                return thread instanceof  ModalContextThread;
272:            }
273:
274:            /**
275:             * Runs the given runnable in a modal context, passing it a progress monitor.
276:             * <p>
277:             * The modal nesting level is increased by one from the perspective
278:             * of the given runnable.
279:             * </p>
280:             *<p>
281:             * If the supplied operation implements <code>IThreadListener</code>, it
282:             * will be notified of any thread changes required to execute the operation.
283:             * Specifically, the operation will be notified of the thread that will call its 
284:             * <code>run</code> method before it is called, and will be notified of the
285:             * change of control back to the thread calling this method when the operation
286:             * completes.  These thread change notifications give the operation an 
287:             * opportunity to transfer any thread-local state to the execution thread before 
288:             * control is transferred to the new thread.
289:             *</p>
290:             * @param operation the runnable to run
291:             * @param fork <code>true</code> if the runnable should run in a separate thread,
292:             *   and <code>false</code> if in the same thread
293:             * @param monitor the progress monitor to use to display progress and receive
294:             *   requests for cancelation
295:             * @param display the display to be used to read and dispatch events
296:             * @exception InvocationTargetException if the run method must propagate a checked exception,
297:             * 	it should wrap it inside an <code>InvocationTargetException</code>; runtime exceptions and errors are automatically
298:             *  wrapped in an <code>InvocationTargetException</code> by this method
299:             * @exception InterruptedException if the operation detects a request to cancel, 
300:             *  using <code>IProgressMonitor.isCanceled()</code>, it should exit by throwing 
301:             *  <code>InterruptedException</code>; this method propagates the exception
302:             */
303:            public static void run(IRunnableWithProgress operation,
304:                    boolean fork, IProgressMonitor monitor, Display display)
305:                    throws InvocationTargetException, InterruptedException {
306:                Assert.isTrue(operation != null && monitor != null);
307:
308:                modalLevel++;
309:                try {
310:                    if (monitor != null) {
311:                        monitor.setCanceled(false);
312:                    }
313:                    // Is the runnable supposed to be execute in the same thread.
314:                    if (!fork || !runInSeparateThread) {
315:                        runInCurrentThread(operation, monitor);
316:                    } else {
317:                        ModalContextThread t = getCurrentModalContextThread();
318:                        if (t != null) {
319:                            Assert.isTrue(canProgressMonitorBeUsed(monitor,
320:                                    t.progressMonitor));
321:                            runInCurrentThread(operation, monitor);
322:                        } else {
323:                            t = new ModalContextThread(operation, monitor,
324:                                    display);
325:                            if (operation instanceof  IThreadListener) {
326:                                ((IThreadListener) operation).threadChange(t);
327:                            }
328:                            t.start();
329:                            t.block();
330:                            Throwable throwable = t.throwable;
331:                            if (throwable != null) {
332:                                if (debug
333:                                        && !(throwable instanceof  InterruptedException)
334:                                        && !(throwable instanceof  OperationCanceledException)) {
335:                                    System.err
336:                                            .println("Exception in modal context operation:"); //$NON-NLS-1$
337:                                    throwable.printStackTrace();
338:                                    System.err.println("Called from:"); //$NON-NLS-1$
339:                                    // Don't create the InvocationTargetException on the throwable,
340:                                    // otherwise it will print its stack trace (from the other thread).
341:                                    new InvocationTargetException(null)
342:                                            .printStackTrace();
343:                                }
344:                                if (throwable instanceof  InvocationTargetException) {
345:                                    throw (InvocationTargetException) throwable;
346:                                } else if (throwable instanceof  InterruptedException) {
347:                                    throw (InterruptedException) throwable;
348:                                } else if (throwable instanceof  OperationCanceledException) {
349:                                    // See 1GAN3L5: ITPUI:WIN2000 - ModalContext converts OperationCancelException into InvocationTargetException
350:                                    throw new InterruptedException(throwable
351:                                            .getMessage());
352:                                } else {
353:                                    throw new InvocationTargetException(
354:                                            throwable);
355:                                }
356:                            }
357:                        }
358:                    }
359:                } finally {
360:                    modalLevel--;
361:                }
362:            }
363:
364:            /**
365:             * Run a runnable.  Convert all thrown exceptions to 
366:             * either InterruptedException or InvocationTargetException
367:             */
368:            private static void runInCurrentThread(
369:                    IRunnableWithProgress runnable,
370:                    IProgressMonitor progressMonitor)
371:                    throws InterruptedException, InvocationTargetException {
372:                try {
373:                    if (runnable != null) {
374:                        runnable.run(progressMonitor);
375:                    }
376:                } catch (InvocationTargetException e) {
377:                    throw e;
378:                } catch (InterruptedException e) {
379:                    throw e;
380:                } catch (OperationCanceledException e) {
381:                    throw new InterruptedException();
382:                } catch (ThreadDeath e) {
383:                    // Make sure to propagate ThreadDeath, or threads will never fully terminate
384:                    throw e;
385:                } catch (RuntimeException e) {
386:                    throw new InvocationTargetException(e);
387:                } catch (Error e) {
388:                    throw new InvocationTargetException(e);
389:                }
390:            }
391:
392:            /**
393:             * Sets whether ModalContext is running in debug mode.
394:             *
395:             * @param debugMode <code>true</code> for debug mode, 
396:             *  and <code>false</code> for normal mode (the default)
397:             */
398:            public static void setDebugMode(boolean debugMode) {
399:                debug = debugMode;
400:            }
401:
402:            /**
403:             * Sets whether ModalContext may process events (by calling <code>Display.readAndDispatch()</code>)
404:             * while running operations. By default, ModalContext will process events while running operations.
405:             * Use this method to disallow event processing temporarily.
406:             * @param allowReadAndDispatch <code>true</code> (the default) if events may be processed while
407:             * running an operation, <code>false</code> if Display.readAndDispatch() should not be called
408:             * from ModalContext.
409:             * @since 3.2
410:             */
411:            public static void setAllowReadAndDispatch(
412:                    boolean allowReadAndDispatch) {
413:                // use a separate thread if and only if it is OK to spin the event loop
414:                runInSeparateThread = allowReadAndDispatch;
415:            }
416:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.