0.102
diff --git a/ant/org.eclipse.ant.ui/.classpath b/ant/org.eclipse.ant.ui/.classpath
new file mode 100644
index 0000000..7416417
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/.classpath
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+    <classpathentry kind="src" path="\org.eclipse.ant.core"/>
+    <classpathentry kind="lib" path="C:\eclipse\jre\lib\rt.jar"/>
+    <classpathentry kind="src" path="\org.eclipse.core.resources"/>
+    <classpathentry kind="src" path="\org.eclipse.core.runtime"/>
+    <classpathentry kind="src" path="Eclipse Ant UI"/>
+    <classpathentry kind="lib" path="C:\eclipse\plugins\org.eclipse.ui\workbench.jar"/>
+    <classpathentry kind="lib" path="\org.eclipse.ant.core\ant.jar"/>
+    <classpathentry kind="src" path="\org.eclipse.core.boot"/>
+    <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/ant/org.eclipse.ant.ui/.cvsignore b/ant/org.eclipse.ant.ui/.cvsignore
new file mode 100644
index 0000000..c5e82d7
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/.cvsignore
@@ -0,0 +1 @@
+bin
\ No newline at end of file
diff --git a/ant/org.eclipse.ant.ui/.vcm_meta b/ant/org.eclipse.ant.ui/.vcm_meta
new file mode 100644
index 0000000..aa7cca7
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/.vcm_meta
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<project-description>

+	<comment></comment>

+	<nature id="org.eclipse.jdt.core.javanature"/>

+	<reference project-name="org.eclipse.ant.core"/>

+	<reference project-name="org.eclipse.core.boot"/>

+	<reference project-name="org.eclipse.core.resources"/>

+	<reference project-name="org.eclipse.core.runtime"/>

+	<builder name="org.eclipse.jdt.core.javabuilder">

+	</builder>

+</project-description>

diff --git a/ant/org.eclipse.ant.ui/icons/antbuild.gif b/ant/org.eclipse.ant.ui/icons/antbuild.gif
new file mode 100644
index 0000000..6572423
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/icons/antbuild.gif
Binary files differ
diff --git a/ant/org.eclipse.ant.ui/plugin.jars b/ant/org.eclipse.ant.ui/plugin.jars
new file mode 100644
index 0000000..2fd734a
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/plugin.jars
@@ -0,0 +1 @@
+antui.jar=Eclipse Ant UI

diff --git a/ant/org.eclipse.ant.ui/plugin.xml b/ant/org.eclipse.ant.ui/plugin.xml
new file mode 100644
index 0000000..25c52ff
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/plugin.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>

+

+<plugin

+  name = "AntUI"

+  id="org.eclipse.ant.internal.ui"

+  version = "0.0"

+  vendor-name = "IBM"

+  class="org.eclipse.ant.internal.ui.AntUIPlugin">

+

+  <requires>

+    <import plugin="org.eclipse.ui"/>

+    <import plugin="org.eclipse.core.resources"/>

+    <import plugin="org.eclipse.ant.core"/>

+  </requires>

+

+  <runtime>

+    <library name="antui.jar">  

+      <export name = "*"/>

+    </library> 

+  </runtime>

+

+  <extension point="org.eclipse.ui.popupMenus">

+	<objectContribution

+		id="org.eclipse.ant.internal.ui.RunAnt"

+		objectClass="org.eclipse.core.resources.IResource"

+		nameFilter="*.xml">

+		<action

+			id="RunAnt"

+			label="Run Ant"

+			tooltip="Run Ant with the selected build file"

+			menubarPath="additions"

+			enablesFor="1"

+			class="org.eclipse.ant.internal.ui.RunAntActionDelegate">

+		</action>

+	</objectContribution>			

+  </extension>

+

+</plugin>

diff --git a/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/AntUIPlugin.java b/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/AntUIPlugin.java
new file mode 100644
index 0000000..9d59421
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/AntUIPlugin.java
@@ -0,0 +1,28 @@
+package org.eclipse.ant.internal.ui;

+

+import org.eclipse.core.runtime.IPluginDescriptor;

+import org.eclipse.ui.plugin.AbstractUIPlugin;

+

+/**

+ * The plug-in runtime class for the AntUI plug-in.

+ */

+public final class AntUIPlugin extends AbstractUIPlugin {

+

+	/**

+	 * Unique identifier constant (value <code>"org.eclipse.ant.ui"</code>)

+	 * for the Ant UI plug-in.

+	 */

+	public static final String PI_ANTUI= "org.eclipse.ant.ui";

+	/**

+	 * The single instance of this plug-in runtime class.

+	 */

+	private static AntUIPlugin plugin;

+

+	public AntUIPlugin(IPluginDescriptor desc) {

+		super(desc);

+		plugin= this;

+	}

+	public static AntUIPlugin getPlugin() {

+		return plugin;

+	}

+}

diff --git a/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/BuildCanceledException.java b/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/BuildCanceledException.java
new file mode 100644
index 0000000..3c8ab68
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/BuildCanceledException.java
@@ -0,0 +1,10 @@
+package org.eclipse.ant.internal.ui;

+

+import org.apache.tools.ant.BuildException;

+

+public class BuildCanceledException extends BuildException {

+

+	public BuildCanceledException() {

+		super("Canceled");

+	}

+}

diff --git a/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/RunAntActionDelegate.java b/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/RunAntActionDelegate.java
new file mode 100644
index 0000000..6790c41
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/RunAntActionDelegate.java
@@ -0,0 +1,96 @@
+package org.eclipse.ant.internal.ui;

+

+import java.lang.reflect.InvocationTargetException;

+import org.apache.tools.ant.BuildException;

+import org.eclipse.swt.widgets.Shell;

+import org.eclipse.ant.core.AntRunner;

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.core.runtime.Status;

+import org.eclipse.ui.IWorkbenchWindow;

+import org.eclipse.ui.IWorkbenchWindowActionDelegate;

+import org.eclipse.jface.action.IAction;

+import org.eclipse.jface.dialogs.ErrorDialog;

+import org.eclipse.jface.dialogs.ProgressMonitorDialog;

+import org.eclipse.jface.operation.IRunnableWithProgress;

+import org.eclipse.jface.viewers.ISelection;

+import org.eclipse.jface.viewers.IStructuredSelection;

+

+

+public class RunAntActionDelegate implements IWorkbenchWindowActionDelegate, IRunnableWithProgress {

+

+	private ISelection selection;

+

+	/*

+	 * @see IWorkbenchWindowActionDelegate

+	 */

+	public void dispose() {

+	}

+	/**

+	  * Returns the active shell.

+	  */

+	protected Shell getShell() {

+		return AntUIPlugin.getPlugin().getWorkbench().getActiveWorkbenchWindow().getShell();

+	}

+	/*

+	 * @see IWorkbenchWindowActionDelegate

+	 */

+	public void init(IWorkbenchWindow window) {

+	}

+	/*

+	 * @see IRunnableWithProgress

+	 */

+	public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {

+		String buildFileName= null;

+		IFile buildFile= null;

+		if (selection instanceof IStructuredSelection) {

+			Object first= ((IStructuredSelection) selection).getFirstElement();

+			if (first instanceof IFile) {

+				buildFile= (IFile) first;

+				buildFileName= buildFile.getLocation().toOSString();

+			}

+		}

+

+		String[] args= {"-buildfile", buildFileName};

+		monitor.beginTask("Running Ant", IProgressMonitor.UNKNOWN);

+

+		try {

+			//TBD: should remove the build listener somehow

+			new AntRunner().run(args, new UIBuildListener(monitor, buildFile));

+		} 

+		catch (BuildCanceledException e) {

+			// build was canceled don't propagate exception

+			return;

+		}

+		catch (Exception e) {

+			throw new InvocationTargetException(e);

+		}

+		finally {

+			monitor.done();

+		}

+	}

+	/*

+	 * @see IActionDelegate

+	 */

+	public void run(IAction action) {

+		Shell shell= getShell();

+		try {

+			ProgressMonitorDialog dialog= new ProgressMonitorDialog(shell);

+			dialog.run(true, true, this);

+		} catch (InvocationTargetException e) {

+			Throwable target= e.getTargetException();

+			IStatus s= new Status(IStatus.ERROR, AntUIPlugin.PI_ANTUI, IStatus.ERROR, target.getMessage(), null);

+			ErrorDialog.openError(getShell(), "Ant", "Exception while running Ant", s);

+		} catch (InterruptedException e) {

+			// do nothing on cancel

+			return;

+		}

+	}

+	/*

+	 * @see IWorkbenchActionDelegate

+	 */

+	public void selectionChanged(IAction action, ISelection selection) {

+		this.selection= selection;

+	}

+}

diff --git a/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/UIBuildListener.java b/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/UIBuildListener.java
new file mode 100644
index 0000000..73b4309
--- /dev/null
+++ b/ant/org.eclipse.ant.ui/src/org/eclipse/ant/internal/ui/UIBuildListener.java
@@ -0,0 +1,114 @@
+package org.eclipse.ant.internal.ui;

+

+import java.util.HashMap;

+import java.util.Map;

+import org.apache.tools.ant.BuildEvent;

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.BuildListener;

+import org.apache.tools.ant.Location;

+import org.apache.tools.ant.Target;

+import org.apache.tools.ant.Task;

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.resources.IMarker;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.core.runtime.IProgressMonitor;

+

+// TBD

+// * Marker mechanism doesn't work for Locations other than

+//   the original build file. This could pose problems for

+//   ant tasks.

+// * incremental task shows minimal feedback

+

+public class UIBuildListener implements BuildListener {

+	IProgressMonitor fMonitor;

+	Target fTarget;

+	Task fTask;

+	IFile fBuildFile;

+	

+	public UIBuildListener(IProgressMonitor monitor, IFile file) {

+		fMonitor= monitor;

+		fBuildFile= file;

+	}

+	public void buildFinished(BuildEvent be){

+		fMonitor.done();

+		if (be.getException() != null) {

+			handleBuildException(be.getException());

+		}

+	}

+	public void buildStarted(BuildEvent be) {

+		fMonitor.subTask("Build started...");

+		removeMarkers();

+	}

+	private void checkCanceled() {

+		if (fMonitor.isCanceled())

+			throw new BuildCanceledException();

+	}

+	private void createMarker(IFile file, BuildException be) {

+		try {

+			int lineNumber= getLineFromLocation(be.getLocation());

+			IMarker marker= file.createMarker(IMarker.PROBLEM);

+			Map map= new HashMap();

+			map.put(IMarker.LINE_NUMBER, new Integer(lineNumber));

+			map.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR));

+			map.put(IMarker.MESSAGE, be.getMessage());

+			map.put(IMarker.LOCATION, Integer.toString(lineNumber));

+			marker.setAttributes(map);

+		} catch (CoreException e) {

+			e.printStackTrace();

+		}

+	}

+	private int getLineFromLocation(Location l) {

+		String locstr= l.toString();

+		int end= locstr.lastIndexOf(':');

+		int start= locstr.lastIndexOf(':', end-1);

+		String lstr= locstr.substring(start+1, end);

+		try {

+			return Integer.parseInt(lstr);

+		} catch (NumberFormatException e) {

+			return -1;

+		}

+	}

+	private void handleBuildException(Throwable t) {

+		System.out.println("BuildException: "+t);

+		if (t instanceof BuildException) {

+			BuildException bex= (BuildException)t;

+			// the build exception has a location that

+			// refers to a build file

+			if (bex.getLocation() != Location.UNKNOWN_LOCATION) {

+				createMarker(fBuildFile, bex);					System.out.println(bex.getLocation());

+			}

+		}

+	}

+	public void messageLogged(BuildEvent be) {

+		checkCanceled();

+		System.out.println("Message"+be.getMessage());

+	}

+	private void removeMarkers() {

+		try {

+			fBuildFile.deleteMarkers(IMarker.PROBLEM, true, IResource.DEPTH_ZERO);

+		} catch (CoreException e) {

+			e.printStackTrace();

+		}

+	}

+	public void targetFinished(BuildEvent be) {

+		checkCanceled();

+		if (be.getException() != null)

+			handleBuildException(be.getException());

+	}

+	public void targetStarted(BuildEvent be) {

+		checkCanceled();

+		fTarget= be.getTarget();

+		fMonitor.subTask("Target: \""+fTarget.getName()+"\" starting...");

+	}

+	public void taskFinished(BuildEvent be) {

+		checkCanceled();

+	}

+	public void taskStarted(BuildEvent be) {

+		checkCanceled();

+		fTask= be.getTask();

+		fMonitor.subTask("Target: \""+fTarget.getName()+"\" - "+fTask.getTaskName());

+		if (be.getException() != null)

+			handleBuildException(be.getException());

+	}

+}