Browse Source

Added option to turn on notification of emacs on a build error so that emacs

goes to the file and location of the error. Also added the ability to provide a
build file to load at startup from the command line.


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@268195 13f79535-47bb-0310-9956-ffa450edef68
master
metasim 24 years ago
parent
commit
71cd7defed
13 changed files with 404 additions and 37 deletions
  1. +22
    -0
      src/antidote/ChangeLog
  2. +3
    -0
      src/antidote/TODO
  3. +3
    -4
      src/antidote/build.xml
  4. +16
    -3
      src/antidote/org/apache/tools/ant/gui/ActionManager.java
  5. +18
    -0
      src/antidote/org/apache/tools/ant/gui/AntAction.java
  6. +1
    -1
      src/antidote/org/apache/tools/ant/gui/Antidote.java
  7. +38
    -1
      src/antidote/org/apache/tools/ant/gui/AppContext.java
  8. +8
    -1
      src/antidote/org/apache/tools/ant/gui/EventResponder.java
  9. +11
    -4
      src/antidote/org/apache/tools/ant/gui/Main.java
  10. +24
    -21
      src/antidote/org/apache/tools/ant/gui/ProjectProxy.java
  11. +106
    -0
      src/antidote/org/apache/tools/ant/gui/ide/EmacsNotifier.java
  12. +146
    -0
      src/antidote/org/apache/tools/ant/gui/ide/FileErrorNotifier.java
  13. +8
    -2
      src/antidote/org/apache/tools/ant/gui/resources/action.properties

+ 22
- 0
src/antidote/ChangeLog View File

@@ -1,3 +1,25 @@
2000-11-16 Simeon H.K. Fitch <simeon@fitch.net>

* org/apache/tools/ant/gui/AntAction.java: Added toggle property.

* org/apache/tools/ant/gui/ActionManager.java: Added ability to
handle toggle actions to menu bar (still need to add support to
tool bar).

* org/apache/tools/ant/gui/EventResponder.java: Added emacs
notifier command.

* org/apache/tools/ant/gui/ide/EmacsNotifier.java: Imported.

* org/apache/tools/ant/gui/ProjectProxy.java: Added code to add
listeners registered with the AppContext to the build.

* org/apache/tools/ant/gui/AppContext.java: Now allows registering
of build listeners to be added to project at build time.

* org/apache/tools/ant/gui/Main.java: Added loading of build file
provided on command line.

2000-11-14 Simeon H.K. Fitch <simeon@fitch.net>

* org/apache/tools/ant/gui/Antidote.java: Added top area widget,


+ 3
- 0
src/antidote/TODO View File

@@ -1,4 +1,7 @@
TODO List:
* Add support to ActionManager to handle toggle actions in tool bar. Also
need a better way of detecting the selected state of the action button.

* Need Ant API access to:
- Tasks within a Target
- The topo sorted task list to get flattened dependencies


+ 3
- 4
src/antidote/build.xml View File

@@ -31,9 +31,8 @@
<!-- =================================================================== -->
<!-- Set some the defaults the user can override in .ant.properties -->
<!-- =================================================================== -->
<property name="build.compiler" value="classic"/>
<property name="build.compiler" value="jikes"/>
<property name="build.compiler.emacs" value="on"/>
<property name="junit.fork" value="false" />

<!-- =================================================================== -->
<!-- Define a global set of patterns that can be referenced by -->
@@ -61,8 +60,8 @@
<javac srcdir="${src.dir}"
destdir="${build.classes}"
debug="on"
deprecation="off"
optimize="on" >
deprecation="on"
optimize="off" >
<classpath refid="classpath" />
</javac>


+ 16
- 3
src/antidote/org/apache/tools/ant/gui/ActionManager.java View File

@@ -164,9 +164,22 @@ public class ActionManager {
menu.getMenuComponentCount() > 0) {
menu.addSeparator();
}
JMenuItem item = menu.add(action);
item.setAccelerator(action.getAccelerator());
addNiceStuff(item, action);

if(!action.isToggle()) {
JMenuItem item = menu.add(action);
item.setAccelerator(action.getAccelerator());
addNiceStuff(item, action);
}
else {
JCheckBoxMenuItem b =
new JCheckBoxMenuItem(action.getName());
b.setActionCommand(action.getID());
b.addActionListener(action);
b.setAction(action);
addNiceStuff(b, action);
menu.add(b);
}

}
}



+ 18
- 0
src/antidote/org/apache/tools/ant/gui/AntAction.java View File

@@ -75,6 +75,7 @@ public class AntAction extends AbstractAction {
public static final String ENABLED = "enabled";
public static final String ENABLE_ON = "enableOn";
public static final String DISABLE_ON = "disableOn";
public static final String TOGGLE = "toggle";

/** Property resources. */
private ResourceBundle _resources = null;
@@ -89,6 +90,8 @@ public class AntAction extends AbstractAction {
/** Events that the action should cause transition to the
* enabled(false) state. */
private Class[] _disableOn = null;
/** Flag indicating toggle action. */
private boolean _toggle = false;


/**
@@ -118,6 +121,12 @@ public class AntAction extends AbstractAction {
putValue(ACCELERATOR, KeyStroke.getKeyStroke(accelerator));
}

// Check to see if action is a toggle action.
String toggle = getString(TOGGLE);
if(toggle != null) {
_toggle = Boolean.valueOf(toggle).booleanValue();
}

// Add an icon if any (which means it'll show up on the tool bar).
String iconName = getString("icon");
if(iconName != null) {
@@ -272,6 +281,15 @@ public class AntAction extends AbstractAction {
return _disableOn;
}

/**
* True if this is a toggle action, false otherwise.
*
* @return True if this is a toggle action, false otherwise.
*/
public boolean isToggle() {
return _toggle;
}

/**
* Pass the action on to the EventBus.
*


+ 1
- 1
src/antidote/org/apache/tools/ant/gui/Antidote.java View File

@@ -100,7 +100,7 @@ public class Antidote extends JPanel {

add(BorderLayout.NORTH, populateEditors("top"));

setPreferredSize(new Dimension(640, 480));
setPreferredSize(new Dimension(640, 600));
}




+ 38
- 1
src/antidote/org/apache/tools/ant/gui/AppContext.java View File

@@ -52,9 +52,10 @@
* <http://www.apache.org/>.
*/
package org.apache.tools.ant.gui;
import org.apache.tools.ant.BuildListener;
import org.apache.tools.ant.gui.event.*;
import java.awt.Frame;
import java.util.*;

/**
* A container for the state information for the application. Provides
@@ -70,6 +71,8 @@ public class AppContext {
private ResourceManager _resources = new ResourceManager();
/** Application actions. */
private ActionManager _actions = new ActionManager(_eventBus);
/** List of build listeners to register when build starts. */
private List _buildListeners = new LinkedList();

/** Parent frame used in various operations. XXX what do we do
* in the applet context. */
@@ -81,6 +84,10 @@ public class AppContext {

public AppContext(Frame parent) {
_parentFrame = parent;
// Add the build listener for dispatching BuildEvent
// objects to the EventBus.
BuildEventForwarder handler = new BuildEventForwarder(this);
addBuildListener(handler);
}

/**
@@ -128,6 +135,36 @@ public class AppContext {
return _project;
}


/**
* Add a build listener.
*
* @param l Listener to add.
*/
public void addBuildListener(BuildListener l) {
_buildListeners.add(l);
}

/**
* Remove a build listener.
*
* @param l Listener to remove.
*/
public void removeBuildListener(BuildListener l) {
_buildListeners.remove(l);
}

/**
* Get the set of current build listeners.
*
* @return Set of current build listeners.
*/
public BuildListener[] getBuildListeners() {
BuildListener[] retval = new BuildListener[_buildListeners.size()];
_buildListeners.toArray(retval);
return retval;
}

/**
* Set the current project.
*


+ 8
- 1
src/antidote/org/apache/tools/ant/gui/EventResponder.java View File

@@ -57,7 +57,7 @@ import org.apache.tools.ant.gui.event.*;
import org.apache.tools.ant.gui.command.*;
import java.util.EventObject;
import java.awt.event.ActionEvent;
import javax.swing.JFrame;
import javax.swing.*;

/**
* The purpose of this class is to watch for events that require some sort
@@ -134,6 +134,13 @@ class EventResponder {
else if(command.equals(ChangeLookAndFeelCmd.ACTION_NAME)) {
new ChangeLookAndFeelCmd(_context).execute();
}
else if(command.equals(ChangeLookAndFeelCmd.ACTION_NAME)) {
new ChangeLookAndFeelCmd(_context).execute();
}
else if(command.equals(EmacsNotifyCmd.ACTION_NAME)) {
AbstractButton source = (AbstractButton) event.getSource();
new EmacsNotifyCmd(_context, source.isSelected()).execute();
}
else {
// XXX log me.
System.err.println("Unhandled action: " + command);


+ 11
- 4
src/antidote/org/apache/tools/ant/gui/Main.java View File

@@ -52,9 +52,10 @@
* <http://www.apache.org/>.
*/
package org.apache.tools.ant.gui;
import org.apache.tools.ant.gui.util.WindowUtils;
import org.apache.tools.ant.gui.command.LoadFileCmd;
import javax.swing.*;
import java.awt.BorderLayout;
import java.io.File;

/**
* Launch point for the Antidote GUI. Configurs it as an application.
@@ -74,7 +75,9 @@ public class Main {
String vmVersion = System.getProperty("java.vm.vendor");
if(vmVersion.indexOf("Blackdown") > 0 &&
vmVersion.indexOf("RC") > 0) {
System.err.println("Warning: Antidote will not work with VM version Blackdown-1.3.0-RC1.");
System.err.println(
"Warning: Antidote will not work with VM version " +
"Blackdown-1.3.0-RC1.");
System.err.println("Your version: " + vmVersion);
}

@@ -101,9 +104,13 @@ public class Main {
f.pack();

f.setVisible(true);
// Hack around linux window placement annoyance.
WindowUtils.centerWindow(f);


// XXX this will change once full command line argument parsing
// is supported.
if(args.length > 0) {
new LoadFileCmd(context, new File(args[0])).execute();
}
}
catch(Exception ex) {
ex.printStackTrace();


+ 24
- 21
src/antidote/org/apache/tools/ant/gui/ProjectProxy.java View File

@@ -62,8 +62,7 @@ import javax.swing.text.Document;
import javax.swing.tree.TreeSelectionModel;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import java.util.Enumeration;
import java.util.Vector;
import java.util.*;

/**
* This class provides the gateway interface to the data model for
@@ -96,6 +95,7 @@ public class ProjectProxy {
_file = file;
_context = context;
loadProject();

}

/**
@@ -108,15 +108,6 @@ public class ProjectProxy {
_selections.addTreeSelectionListener(new SelectionForwarder());
}

/**
* Called to indicate that the project is no longer going to be used
* by the GUI, and that any cleanup should occur.
*
*/
//public void close() {
//
//}

/**
* Build the project with the current target (or the default target
* if none is selected. Build occurs on a separate thread, so method
@@ -128,12 +119,13 @@ public class ProjectProxy {
project.init();
// XXX there is a bunch of stuff in the class
// org.apache.tools.ant.Main that needs to be
// abstracted out so that it doesn't have to be
// refactored out so that it doesn't have to be
// replicated here.
// XXX need to provide a way to pass in externally
// defined properties. Perhaps define an external
// Antidote properties file.
// Antidote properties file. JAVA_HOME may have to be set,
// as well as checking the .ant.properties
project.setUserProperty("ant.file" , _file.getAbsolutePath());
ProjectHelper.configureProject(project, _file);

@@ -189,7 +181,14 @@ public class ProjectProxy {

/** Class for executing the build in a separate thread. */
private class BuildRunner implements Runnable {
/** The project to execute build on. */
private Project _project = null;

/**
* Standard ctor.
*
* @param project Project to execute build on.
*/
public BuildRunner(Project project) {
_project = project;
}
@@ -214,13 +213,14 @@ public class ProjectProxy {
*
*/
public void run() {
// Add the build listener for
// dispatching BuildEvent objects to the
// EventBus.
BuildEventForwarder handler =
new BuildEventForwarder(_context);
_project.addBuildListener(handler);
// Add the build listeners
BuildListener[] listeners = _context.getBuildListeners();
for(int i = 0; i < listeners.length; i++) {
_project.addBuildListener(listeners[i]);
}
try {

fireBuildEvent(new BuildEvent(
_project), BuildEventType.BUILD_STARTED);
@@ -250,8 +250,11 @@ public class ProjectProxy {
finally {
fireBuildEvent(new BuildEvent(
_project), BuildEventType.BUILD_FINISHED);
_project.removeBuildListener(handler);
_buildThread = null;

// Remove the build listeners.
for(int i = 0; i < listeners.length; i++) {
_project.removeBuildListener(listeners[i]);
}
}
}
}


+ 106
- 0
src/antidote/org/apache/tools/ant/gui/ide/EmacsNotifier.java View File

@@ -0,0 +1,106 @@
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999, 2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/

package org.apache.tools.ant.gui.ide;

import org.apache.tools.ant.taskdefs.ExecTask;
import org.apache.tools.ant.Project;
import java.util.StringTokenizer;
import java.io.File;

/**
* FileErrorNotifier specialization for sending file error
* messages to emacs via the emacsclient command. This
* command <i>must</i> be in the runtime path of the JVM for
* it to be found.
* <p> Install the notifier by running Ant as follows:<br>
* <code>
* &nbsp;&nbsp;ant -listener net.noemis.ant.EmacsNotifier
* </code>
*
* @version $Revision$
* @author <a href="mailto:simeon@fitch.net">Simeon H.K. Fitch</a> */
public class EmacsNotifier extends FileErrorNotifier {
/** Command to run to communicate with emacs. */
// XXX This should only be a default. A property should be checked
// for the actual version. Should Project.getProperty() or
// Project.getUserProperty() be used???
private static final String EMACS = "emacsclient";

/**
* Called when a message has been logged indicating that
* there is an error of some sort at the given file and
* line number. Sends a message bto emacs to make emacs
* visit the file and place the mark at the source of
* the error.
*
* @param file File containing the error.
* @param lineNum Line number of error.
*/
protected void fireFileErrorNotification(
Project project, File file, int lineNum) {
// Launch our command using the built in exec support.
ExecTask exec = (ExecTask) project.createTask("exec");
// Construct the command to communicate with emacs.
// Command has the form:
// emacsclient [-n] [--no-wait] [+LINENUMBER] FILENAME
exec.setExecutable(EMACS);
exec.createArg().setValue("-n");
exec.createArg().setValue("--no-wait");
exec.createArg().setValue("+" + lineNum);
exec.createArg().setValue(file.toString());
exec.setFailonerror(false);
exec.execute();
}
}

+ 146
- 0
src/antidote/org/apache/tools/ant/gui/ide/FileErrorNotifier.java View File

@@ -0,0 +1,146 @@
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999, 2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/

package org.apache.tools.ant.gui.ide;

import org.apache.tools.ant.BuildListener;
import org.apache.tools.ant.BuildEvent;
import org.apache.tools.ant.Project;
import java.util.StringTokenizer;
import java.io.File;

/**
* Abstract base class for BuildListener specializations interested
* in notification of build errors in source files.
*
* @version $Revision$
* @author <a href="mailto:simeon@fitch.net">Simeon H.K. Fitch</a>
*/
abstract class FileErrorNotifier implements BuildListener {
/** Command to run to communicate with emacs. */
private static final String EMACS = "emacsclient";

/**
* Fired whenever a message is logged. Parses error messages looking
* for a filename and line number specification, which when found
* is then sent to the method <code>fireFileErrorNotification()</code>
* source of the error. Only the first error is processed.
*
* @param event Incoming event that is filtered for error messages.
*/
public void messageLogged(BuildEvent event) {
if(event.getPriority() == Project.MSG_ERR ||
event.getPriority() == Project.MSG_WARN) {
StringTokenizer tok = new StringTokenizer(event.getMessage(), ":");
File file = null;
int line = -1;
if(tok.hasMoreTokens()) {
file = new File(tok.nextToken());
if(tok.hasMoreTokens()) {
try {
line = Integer.parseInt(tok.nextToken());
}
catch(NumberFormatException ex) {
// Allow execption to fall through as we test
// success by the value of 'line' below.
}
}
}

// Test for successful filename and line number detection.
if(file != null && line > 0 && file.exists()) {
// Since we only want to trigger on the first error,
// remove ourself from being notified of others.
// XXX are there any reasons this should occur after
// notification?
event.getProject().removeBuildListener(this);

// Send notification.
fireFileErrorNotification(event.getProject(), file, line);
}
}
}

/**
* Called when a message has been logged indicating that there
* is an error of some sort at the given file and line number.
*
* @param file File containing the error.
* @param lineNum Line number of error.
*/
protected abstract void fireFileErrorNotification(
Project project, File file, int lineNum);

// Event types that are ignored. Looks like we really need a
// BuildAdapter class...
/** Ignored */
public void buildStarted(BuildEvent event) {
}
/** Ignored */
public void buildFinished(BuildEvent event) {
}
/** Ignored */
public void targetStarted(BuildEvent event) {
}
/** Ignored */
public void targetFinished(BuildEvent event) {
}
/** Ignored */
public void taskStarted(BuildEvent event) {
}
/** Ignored */
public void taskFinished(BuildEvent event) {
}
}

+ 8
- 2
src/antidote/org/apache/tools/ant/gui/resources/action.properties View File

@@ -3,7 +3,8 @@ menus=File, Build, Options, Help

# Declare the list of known actions.
actions=\
open, save, close, exit, about, startBuild, stopBuild, changeLookAndFeel
open, save, close, exit, about, startBuild, stopBuild, \
notifyEmacs, changeLookAndFeel

# Configure the decalred actions.

@@ -73,5 +74,10 @@ changeLookAndFeel.name=Look and Feel...
changeLookAndFeel.shortDescription=Change the Look and Feel
changeLookAndFeel.parentMenuName=Options
changeLookAndFeel.enabled=true
changeLookAndFeel.separator=true


notifyEmacs.name=Notify Emacs
notifyEmacs.shortDescription=\
Send a notification event to Emacs on build errors.
notifyEmacs.parentMenuName=Options
notifyEmacs.toggle=true

Loading…
Cancel
Save