|
What this is
Other links
The source code/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2002 Sun * Microsystems, Inc. All Rights Reserved. */ package org.netbeans.core.compiler; import java.util.LinkedList; import java.util.List; import java.util.Collection; import java.util.Iterator; import java.util.ListIterator; import java.util.Hashtable; import java.util.Enumeration; import org.openide.ErrorManager; import org.openide.compiler.DependencyException; import org.openide.compiler.CompilationEngine; import org.openide.compiler.CompilerTask; import org.openide.compiler.CompilerGroup; import org.openide.compiler.CompilerJob; import org.openide.compiler.CompilerGroupException; import org.openide.compiler.CompilerListener; /** A class that makes compiling. * * @author Ales Novak */ public class CompilationEngineImpl extends CompilationEngine { /** a queue */ private LinkedList queue; /** a thread */ private CompilerThread t; /** an event listener */ CompilerDisplayer displayer; /** new CompilationEngineImpl */ public CompilationEngineImpl() { queue = new LinkedList(); displayer = new CompilerDisplayer(); t = new CompilerThread(queue, displayer); t.start(); } /** Starts asynchronous compilation of a compiler job. * It supports nested jobs, if they are invoked from within a * CompilerGroup. * * @param job the job to compile * @return the task object, one can wait for it to finish * and obtain its results */ protected CompilerTask start(CompilerJob job) { CompilerTaskImpl task = null; synchronized (queue) { Object[] twins = new Object[2]; twins[0] = job; task = new CompilerTaskImpl(job, this, twins); twins[1] = task; if (!t.isAlive()) { (t = new CompilerThread(queue, displayer)).start(); } Thread current = Thread.currentThread(); if (current.getClass() == CompilerThread.GroupCompiler.class) { // contact the compiler thread t.runNested(twins); } else { queue.addLast(twins); queue.notify(); } } /* To implement synch compilation (would be useful for scripting etc.): task.waitFinished(); */ return task; } // not API inherited methods - user must cast to this Class /** Restarts compiler thread. */ public void stop() { synchronized (queue) { t.stopIt(); CompilerThread.GroupCompiler.interruptAll(); Iterator it = queue.iterator(); while (it.hasNext()) { ((CompilerTaskImpl) ((Object[]) it.next())[1]).done(); } queue.clear(); queue.notify(); t = new CompilerThread(queue, displayer); t.start(); } } /** @return true if compiling is executed */ public boolean isCompiling() { return CompilerThread.GroupCompiler.all.size() > 0; } /** stops specified job */ void stopTask(CompilerTaskImpl job) { synchronized (queue) { if (queue.remove(job.ref)) { return; } else { stop(); } } } /** makes it public */ static List createLevels(CompilerJob job) throws DependencyException { return createComputationLevels(job); } static Collection createGroups(Collection c) throws CompilerGroupException { return createCompilerGroups(c); } /** A thread of control that compiles. */ protected static class CompilerThread extends Thread { /** a queue */ public LinkedList queue; /** an EventListener */ public CompilerDisplayer displayer; /** stop flag */ private boolean stop; /** current job */ public CompilerJob currentJob; /** current task */ public CompilerTaskImpl currentTask; /** new thread */ public CompilerThread(LinkedList queue, CompilerDisplayer displayer) { setName("Compilation"); // NOI18N setPriority(2); setDaemon(true); this.queue = queue; this.displayer = displayer; } /** stops the thread */ public void stopIt() { stop = true; } /** @return next CompilerJob from the queue */ private void nextJobAndTask() throws InterruptedException { synchronized (queue) { currentJob = null; while (queue.size() == 0) { queue.wait(); } Object[] twins = (Object[]) queue.removeFirst(); currentJob = (CompilerJob) twins[0]; currentTask = (CompilerTaskImpl) twins[1]; } } /** a run method */ public void run() { for (;!stop;) { boolean uptodate = true; try { nextJobAndTask(); // set currentTask and currentJob displayer.compilationStarted(currentTask); uptodate = processJob(); } catch (Exception e) { ErrorManager.getDefault().notify(ErrorManager.EXCEPTION, e); currentTask.success = false; } catch (ThreadDeath td) { stop = true; } finally { displayer.compilationFinished(currentTask, uptodate & currentTask.success); currentJob = null; currentTask = null; } } } void runNested(Object[] twins) { CompilerJob saveJob = currentJob; CompilerTaskImpl saveTask = currentTask; try { // set the current job/task manually instead of calling // nextJobAndTask. currentJob = (CompilerJob)twins[0]; currentTask = (CompilerTaskImpl)twins[1]; processJob(); } finally { currentJob = saveJob; currentTask = saveTask; } } /** * @return true, if some CompilerGroup was created/run */ boolean processJob() { CompilerGroup[] groups; GroupCompiler compiler; boolean success; boolean uptodate = true; ListIterator iterator; try { iterator = createLevels(currentJob).listIterator(); groups = new CompilerGroup[0]; success = true; while (iterator.hasNext() && success) { // through levels // if one level fails - stop it groups = (CompilerGroup[]) createGroups((Collection) iterator.next()).toArray(groups); // an array of groups - do parallel compilation compiler = null; uptodate &= (groups.length == 0); for (int i = 0; i < groups.length; i++) { if (groups[i] == null) break; groups[i].addCompilerListener(displayer); compiler = new GroupCompiler(groups[i], compiler); } if (compiler != null) { // is not upToDate success &= compiler.stay(displayer); // wait for one level } } currentTask.success = success; } catch (Exception e) { ErrorManager.getDefault().notify(ErrorManager.EXCEPTION, e); currentTask.success = false; } finally { if (currentTask != null) { currentTask.done(); //displayer.compilationFinished(currentTask, uptodate & currentTask.success); } } return uptodate; } /** Compiles CompilerGroup */ protected static class GroupCompiler extends Thread { static Hashtable all = new Hashtable(11); public CompilerGroup grp; public GroupCompiler parent; public boolean status; public GroupCompiler(CompilerGroup grp, GroupCompiler parent) { this.grp = grp; this.parent = parent; status = true; // OK this.start(); } /* called by compilation thread */ public boolean stay(CompilerListener listener) throws InterruptedException { try { all.put(this, this); join(); grp.removeCompilerListener(listener); if (parent != null) { return parent.stay(listener) && status; } else { return status; } } finally { all.remove(this); } } public void run() { try { status = grp.start(); } catch (ThreadDeath t) { ErrorManager.getDefault().notify(ErrorManager.EXCEPTION, t); status = false; } catch (RuntimeException re) { ErrorManager.getDefault().notify(ErrorManager.EXCEPTION, re); status = false; } } /** interrupts all groups threads */ static void interruptAll() { Enumeration e = all.keys(); while (e.hasMoreElements()) { Thread tt = (Thread) e.nextElement(); tt.interrupt(); } } } } } |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.