KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > core > execution > ExecutionEngine


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.core.execution;
21
22 import java.io.File JavaDoc;
23 import java.io.IOException JavaDoc;
24 import java.io.OutputStream JavaDoc;
25 import java.io.PrintStream JavaDoc;
26 import java.util.*;
27 import java.security.CodeSource JavaDoc;
28 import java.security.PermissionCollection JavaDoc;
29 import java.security.Policy JavaDoc;
30 import java.util.logging.Level JavaDoc;
31 import java.util.logging.Logger JavaDoc;
32
33 import org.openide.execution.NbClassPath;
34 import org.openide.execution.ExecutorTask;
35 import org.openide.util.Lookup;
36 import org.openide.windows.InputOutput;
37
38 import org.netbeans.core.NbTopManager;
39
40 /** Execution that provides support for starting a class with main
41 *
42 * @author Ales Novak
43 *
44 * The class handles redirecting of out/in/err for all tasks in the system.
45 * First instance of TaskIO is created for Corona. So call System.out.println()
46 * from Corona is redirected to a window.
47 * Situation for executed task is following it uses System.out/err/in - because
48 * the task is in some threadgroup it will be recognized and new panel in window
49 * for that task will be created. Further System.out.println() means that
50 * (in System.out is our class now - SysOut) calling thread is found and its threadgroup
51 * is examined - SysOut propagates call to taskIOs in ExecutionEngine. IOTable
52 * look for mapping the threadgroup to TaskIO class (it may create that). TaskIO
53 * is created uninitialized. So if only out is used, err/in are never initialized.
54 * Initializing is lazy - for request. TaskIO.out is an instance of SysPrintStream,
55 * that is redirected to OutputWriter that is redirected to a window.
56 */

57 public final class
58     ExecutionEngine extends org.openide.execution.ExecutionEngine {
59
60     /** base group for all running tasks */
61     public static final ThreadGroup JavaDoc base = new ThreadGroup JavaDoc("base"); // NOI18N
62

63     /** used for naming groups */
64     private int number = 1;
65
66     /** IO class for corona */
67     public static final TaskIO systemIO = new TaskIO();
68
69     /** maps ThreadGroups to TaskIO */
70     private static IOTable taskIOs;
71
72     /* table of window:threadgrp */
73     static private WindowTable wtable = new WindowTable();
74
75     /** list of ExecutionListeners */
76     private HashSet<ExecutionListener> executionListeners = new HashSet<ExecutionListener>();
77
78     /** List of running executions */
79     private List<ExecutorTask> runningTasks = Collections.synchronizedList(new ArrayList<ExecutorTask>( 5 ));
80
81     static {
82         systemIO.out = new OutputStreamWriter(System.out);
83         systemIO.err = new OutputStreamWriter(System.err);
84         systemIO.in = new java.io.InputStreamReader JavaDoc(System.in);
85     }
86
87     static final long serialVersionUID =9072488605180080803L;
88
89     public ExecutionEngine () {
90         /* SysIn is a class that redirects System.in of some running task to
91            a window (probably OutWindow).
92            SysOut/Err are classes that redirect out/err to the window
93         */

94         System.setIn(new SysIn());
95         System.setOut(createPrintStream(true));
96         System.setErr(createPrintStream(false));
97     }
98
99     /** Get the default ExecutionEngine instance.
100      * @return the instance, or null if none could be found
101      */

102     public static ExecutionEngine getExecutionEngine() {
103         ExecutionEngine ee = (ExecutionEngine)Lookup.getDefault().lookup(ExecutionEngine.class);
104         if (ee != null) return ee;
105         org.openide.execution.ExecutionEngine ee2 = (org.openide.execution.ExecutionEngine)Lookup.getDefault().lookup(org.openide.execution.ExecutionEngine.class);
106         if (ee2 instanceof ExecutionEngine) return (ExecutionEngine)ee2;
107         return null;
108     }
109     
110     /** Returns a snapshot of a collection of tasks which did not ended yet */
111     public Collection JavaDoc<ExecutorTask> getRunningTasks() {
112         // toArray is atomic on synchronized list, contrary to just passing
113
// the list to a Collection constructor.
114
return Arrays.asList(runningTasks.toArray(new ExecutorTask[0]));
115     }
116     
117     /** Returns name of running task */
118     public String JavaDoc getRunningTaskName( ExecutorTask task ) {
119         if ( !runningTasks.contains( task ) ||
120              !(task instanceof DefaultSysProcess) ) {
121             return null;
122         }
123         else {
124             return ((DefaultSysProcess)task).getName();
125         }
126     }
127
128     /** Should prepare environment for Executor and start it. Is called from
129     * Executor.execute method.
130     *
131     * @param executor to start
132     * @param info about class to start
133     */

134     public ExecutorTask execute(String JavaDoc name, Runnable JavaDoc run, InputOutput inout) {
135         TaskThreadGroup g = new TaskThreadGroup(base, "exec_" + name + "_" + number); // NOI18N
136
g.setDaemon(true);
137         ExecutorTaskImpl task = new ExecutorTaskImpl();
138         synchronized (task.lock) {
139             try {
140                 new RunClassThread(g, name, number++, inout, this, task, run);
141                 task.lock.wait();
142             } catch (InterruptedException JavaDoc e) {
143                 throw new IllegalStateException JavaDoc(e.getMessage());
144             }
145         }
146         return task;
147     }
148
149     /** Method that allows implementor of the execution engine to provide
150     * class path to all libraries that one could find useful for development
151     * in the system.
152     *
153     * @return class path to libraries
154     */

155     protected NbClassPath createLibraryPath() {
156         @SuppressWarnings JavaDoc("unchecked") List<File JavaDoc> l = NbTopManager.getUninitialized().getModuleJars();
157         return new NbClassPath (l.toArray (new File JavaDoc[l.size ()]));
158     }
159
160     /** adds a listener */
161     public final void addExecutionListener (ExecutionListener l) {
162         synchronized (executionListeners) {
163             executionListeners.add(l);
164         }
165     }
166
167     /** removes a listener */
168     public final void removeExecutionListener (ExecutionListener l) {
169         synchronized (executionListeners) {
170             executionListeners.remove(l);
171         }
172     }
173
174     /** Creates new PermissionCollection for given CodeSource and given PermissionCollection.
175      * @param cs a CodeSource
176      * @param io an InputOutput
177      * @return PermissionCollection for given CodeSource and InputOutput
178      */

179     protected final PermissionCollection JavaDoc createPermissions(CodeSource JavaDoc cs, InputOutput io) {
180         PermissionCollection JavaDoc pc = Policy.getPolicy().getPermissions(cs);
181         ThreadGroup JavaDoc grp = Thread.currentThread().getThreadGroup();
182         return new IOPermissionCollection(io, pc, (grp instanceof TaskThreadGroup ? (TaskThreadGroup) grp: null));
183     }
184
185     /** fires event that notifies about new process */
186     protected final void fireExecutionStarted (ExecutionEvent ev) {
187         runningTasks.add( ev.getProcess() );
188     @SuppressWarnings JavaDoc("unchecked")
189         Iterator<ExecutionListener> iter = ((HashSet<ExecutionListener>) executionListeners.clone()).iterator();
190         while (iter.hasNext()) {
191             ExecutionListener l = iter.next();
192             l.startedExecution(ev);
193         }
194     }
195
196     /** fires event that notifies about the end of a process */
197     protected final void fireExecutionFinished (ExecutionEvent ev) {
198         runningTasks.remove( ev.getProcess() );
199     @SuppressWarnings JavaDoc("unchecked")
200         Iterator<ExecutionListener> iter = ((HashSet<ExecutionListener>) executionListeners.clone()).iterator();
201         while (iter.hasNext()) {
202             ExecutionListener l = iter.next();
203             l.finishedExecution(ev);
204         }
205         ev.getProcess().destroyThreadGroup(base);
206     }
207
208     static void putWindow(java.awt.Window JavaDoc w, TaskThreadGroup tg) {
209         wtable.putTaskWindow(w, tg);
210     }
211     static void closeGroup(ThreadGroup JavaDoc tg) {
212         wtable.closeGroup(tg);
213     }
214     static boolean hasWindows(ThreadGroup JavaDoc tg) {
215         return wtable.hasWindows(tg);
216     }
217
218     /**
219     * @return IOTable with couples ThreadGroup:TaskIO
220     */

221     static IOTable getTaskIOs() {
222         if (taskIOs == null) {
223             taskIOs = new IOTable(base, systemIO);
224         }
225         return taskIOs;
226     }
227
228     /** finds top thread group of the calling thread
229     * @return null iff the calling thread is not in any exec group
230     * or exec group of calling thread
231     */

232     public static ThreadGroup JavaDoc findGroup () {
233         ThreadGroup JavaDoc g = Thread.currentThread().getThreadGroup ();
234         ThreadGroup JavaDoc old = null;
235         while (g != null && g != base) {
236             old = g;
237             g = g.getParent ();
238         }
239         return (g == null) ? null : old;
240     }
241
242     /** The OutputStream redirects output on behalf of task */
243     static class SysOut extends OutputStream JavaDoc {
244
245         /** Is it err or std out? */
246         boolean std;
247
248         /** Creates new Stream */
249         SysOut(boolean std) {
250             this.std = std;
251         }
252
253         public void write(int b) throws IOException JavaDoc {
254             if (std) {
255                 getTaskIOs().getOut().write(b);
256             } else {
257                 getTaskIOs().getErr().write (b);
258             }
259         }
260
261         public void write(byte[] buff, int off, int len) throws IOException JavaDoc {
262             String JavaDoc s = new String JavaDoc (buff, off, len);
263             if (std) {
264                 getTaskIOs().getOut().write(s.toCharArray(), 0, s.length());
265             } else {
266                 getTaskIOs().getErr().write(s.toCharArray(), 0, s.length());
267             }
268         }
269
270         public void flush() throws IOException JavaDoc {
271             if (std) {
272                 getTaskIOs().getOut().flush();
273             } else {
274                 getTaskIOs().getErr().flush();
275             }
276         }
277
278         public void close() throws IOException JavaDoc {
279             if (std) {
280                 getTaskIOs().getOut().close();
281             } else {
282                 getTaskIOs().getErr().close();
283             }
284         }
285     }
286
287     static PrintStream JavaDoc createPrintStream(boolean stdOut) {
288         return new WriterPrintStream(new SysOut(stdOut), stdOut);
289     }
290    
291 }
292
Popular Tags