Submitted by: Simeon Fitch <metasim@yahoo.com> git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@268157 13f79535-47bb-0310-9956-ffa450edef68master
@@ -0,0 +1,36 @@ | |||
TODO List: | |||
* Need Ant API access to: | |||
- Tasks within a Target | |||
- The topo sorted task list to get flattened dependencies | |||
- The build setup code to recduce code replication. | |||
- Normalize the Ant data model to represent a more consistent | |||
tree structure, and more bean-like API. | |||
* Cause console to clear when a project is closed. | |||
* Better define the data model architecture, and how it interfaces | |||
with the Ant data model. | |||
* Define a list of proposed changes for the Ant datamodel, | |||
specifically the Project class and the ability to stop running builds, | |||
and reduction of code duplication in launching builds. | |||
* Project navigator (currently stubbed out in the ProjectNavigator class). | |||
* Implement a ListSelectionModel that is backed by a set of selected | |||
targets. | |||
* Project properties viewer, including the ability to view | |||
dependencies (local and cascading). | |||
* Acquire or implement a logging facility. | |||
* Build launching capability. | |||
* Build monitoring console. | |||
* Get some icons! | |||
* Create a listener for the ActionManager that knows how to change | |||
the enanbled state of the various actions based on the | |||
application state. |
@@ -5,7 +5,7 @@ | |||
</HEAD> | |||
<BODY> | |||
<H1>Ant GUI Feature List</H1> | |||
<P>Version 0.3 (2000/10/31)</P> | |||
<P>Version 0.4 (2000/11/06)</P> | |||
<P>Authors: | |||
<A HREF="mailto:simeon@fitch.net">Simeon H.K. Fitch</A>, | |||
<A HREF="mailto:chris@christophertodd.com">Chris Todd</A>, | |||
@@ -31,7 +31,6 @@ | |||
<P>The features are in a loose order of expressed interested by | |||
contributors.</P> | |||
<!-- Section List --> | |||
<OL TYPE="A"> | |||
@@ -68,7 +67,6 @@ | |||
</OL> | |||
<BR> | |||
<LI><H2>Build Wizard (auto-configure)</H2></LI> | |||
<P>To make starting a new project with Ant as easy as possible, the a | |||
wizard type of UI can be used where the user provides some basic | |||
@@ -155,7 +153,9 @@ | |||
introspection to discover attribute set, then reference some other | |||
mechanism for attributes that are manifested as properties.</I> | |||
</LI> | |||
<LI>Report errors in the XML source.</LI> | |||
<LI>Report errors in the XML source.</LI> | |||
<LI>Provide a list of recently opened documents for | |||
quick reloading.</LI> | |||
</OL> | |||
<LI>View project contents.</LI> | |||
<OL TYPE="a"> | |||
@@ -54,6 +54,7 @@ | |||
package org.apache.tools.ant.gui; | |||
import org.apache.tools.ant.gui.event.*; | |||
import javax.swing.*; | |||
import javax.swing.plaf.ComponentUI; | |||
import javax.swing.text.Document; | |||
import java.awt.BorderLayout; | |||
import java.awt.FlowLayout; | |||
@@ -82,7 +83,7 @@ public class Console extends AntEditor { | |||
context.getEventBus().addMember(EventBus.MONITORING, new Handler()); | |||
setLayout(new BorderLayout()); | |||
_text = new JTextPane(); | |||
_text = new NoWrapTextPane(); | |||
_text.setEditable(false); | |||
JScrollPane scroller = new JScrollPane(_text); | |||
scroller.setVerticalScrollBarPolicy( | |||
@@ -162,7 +163,6 @@ public class Console extends AntEditor { | |||
} | |||
} | |||
} | |||
/** Class providing filtering for project events. */ | |||
private static class Filter implements BusFilter { | |||
/** | |||
@@ -176,4 +176,20 @@ public class Console extends AntEditor { | |||
} | |||
} | |||
/** Specialization of JTextPane to provide proper wrapping behavior. */ | |||
private static class NoWrapTextPane extends JTextPane { | |||
/** | |||
* Overridden to ensure that the JTextPane is only | |||
* forced to match the viewport if it is smaller than | |||
* the viewport. | |||
* | |||
* @return True if smaller than viewport, false otherwise. | |||
*/ | |||
public boolean getScrollableTracksViewportWidth() { | |||
ComponentUI ui = getUI(); | |||
return getParent() != null ? ui.getPreferredSize(this).width <= | |||
getParent().getSize().width : true; | |||
} | |||
} | |||
} |
@@ -116,9 +116,11 @@ class ProjectNavigator extends AntEditor { | |||
// XXX this needs to be tested against | |||
// different version of Swing... | |||
_tree.setModel(null); | |||
_tree.setSelectionModel(null); | |||
} | |||
else { | |||
_tree.setModel(project.getTreeModel()); | |||
_tree.setSelectionModel(project.getTreeSelectionModel()); | |||
} | |||
} | |||
} | |||
@@ -52,17 +52,17 @@ | |||
* <http://www.apache.org/>. | |||
*/ | |||
package org.apache.tools.ant.gui; | |||
import org.apache.tools.ant.Project; | |||
import org.apache.tools.ant.ProjectHelper; | |||
import org.apache.tools.ant.BuildEvent; | |||
import org.apache.tools.ant.BuildException; | |||
import org.apache.tools.ant.BuildListener; | |||
import org.apache.tools.ant.*; | |||
import org.apache.tools.ant.gui.event.*; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import javax.swing.tree.TreeModel; | |||
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; | |||
/** | |||
* This class provides the gateway interface to the data model for | |||
@@ -81,8 +81,10 @@ public class ProjectProxy { | |||
private File _file = null; | |||
/** The real Ant Project instance. */ | |||
private Project _project = null; | |||
/** Private the current thread executing a build. */ | |||
/** The current thread executing a build. */ | |||
private Thread _buildThread = null; | |||
/** The selection model for selected targets. */ | |||
private TargetSelectionModel _selections = null; | |||
/** | |||
* File loading ctor. | |||
@@ -101,6 +103,8 @@ public class ProjectProxy { | |||
*/ | |||
private void loadProject() throws IOException { | |||
_project = new Project(); | |||
_selections = new TargetSelectionModel(); | |||
_selections.addTreeSelectionListener(new SelectionForwarder()); | |||
synchronized(_project) { | |||
_project.init(); | |||
@@ -117,6 +121,15 @@ public class ProjectProxy { | |||
} | |||
} | |||
/** | |||
* 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 | |||
@@ -152,6 +165,15 @@ public class ProjectProxy { | |||
return null; | |||
} | |||
/** | |||
* Get the tree selection model for selected targets. | |||
* | |||
* @return Selection model. | |||
*/ | |||
public TreeSelectionModel getTreeSelectionModel() { | |||
return _selections; | |||
} | |||
/** | |||
* Get the Document perspective on the data. | |||
* | |||
@@ -197,10 +219,23 @@ public class ProjectProxy { | |||
try { | |||
fireBuildEvent(new BuildEvent( | |||
_project), BuildEventType.BUILD_STARTED); | |||
// XXX add code to indicate target execution | |||
// on the targets that are selected. | |||
_project.executeTarget( | |||
_project.getDefaultTarget()); | |||
// Generate list of targets to execute. | |||
Target[] targets = _selections.getSelectedTargets(); | |||
Vector targetNames = new Vector(); | |||
if(targets.length == 0) { | |||
targetNames.add(_project.getDefaultTarget()); | |||
} | |||
else { | |||
for(int i = 0; i < targets.length; i++) { | |||
targetNames.add(targets[i].getName()); | |||
} | |||
} | |||
// Execute build on selected targets. XXX It would be | |||
// nice if the Project API supported passing in target | |||
// objects rather than String names. | |||
_project.executeTargets(targetNames); | |||
} | |||
catch(BuildException ex) { | |||
BuildEvent errorEvent = new BuildEvent(_project); | |||
@@ -218,4 +253,12 @@ public class ProjectProxy { | |||
} | |||
} | |||
/** Forwards selection events to the event bus. */ | |||
private class SelectionForwarder implements TreeSelectionListener { | |||
public void valueChanged(TreeSelectionEvent e) { | |||
_context.getEventBus().postEvent(new TargetSelectionEvent( | |||
_context, _selections.getSelectedTargets())); | |||
} | |||
} | |||
} |
@@ -52,7 +52,13 @@ | |||
* <http://www.apache.org/>. | |||
*/ | |||
package org.apache.tools.ant.gui; | |||
import org.apache.tools.ant.Target; | |||
import org.apache.tools.ant.gui.event.*; | |||
import javax.swing.*; | |||
import java.util.*; | |||
import java.io.StringReader; | |||
import java.io.IOException; | |||
import java.awt.BorderLayout; | |||
/** | |||
* Stub for a property editor. | |||
@@ -62,8 +68,162 @@ import javax.swing.*; | |||
*/ | |||
class PropertyEditor extends AntEditor { | |||
/** Text pane. */ | |||
private JEditorPane _text = null; | |||
/** | |||
* Standard ctor. | |||
* | |||
* @param context Application context. | |||
*/ | |||
public PropertyEditor(AppContext context) { | |||
super(context); | |||
add(new JLabel(getName())); | |||
context.getEventBus().addMember(EventBus.MONITORING, new Handler()); | |||
setLayout(new BorderLayout()); | |||
_text = new JEditorPane("text/html", getAppContext().getResources(). | |||
getString(getClass(), "noTargets")); | |||
_text.setEditable(false); | |||
_text.setOpaque(false); | |||
add(BorderLayout.CENTER, _text); | |||
} | |||
/** | |||
* Populate the display with the given target info. | |||
* | |||
* @param targets Targets to display info for. | |||
*/ | |||
private void displayTargetInfo(Target[] targets) { | |||
// The text to display. | |||
String text = null; | |||
int num = targets == null ? 0 : targets.length; | |||
Object[] args = null; | |||
switch(num) { | |||
case 0: | |||
text = getAppContext().getResources(). | |||
getString(getClass(), "noTargets"); | |||
break; | |||
case 1: | |||
args = getTargetParams(targets[0]); | |||
text = getAppContext().getResources(). | |||
getMessage(getClass(), "oneTarget", args); | |||
break; | |||
default: | |||
args = getTargetParams(targets); | |||
text = getAppContext().getResources(). | |||
getMessage(getClass(), "manyTargets", args); | |||
break; | |||
} | |||
if(text != null) { | |||
_text.setText(text); | |||
} | |||
} | |||
/** | |||
* Get the parameters for the formatted message presented for a single | |||
* target. | |||
* | |||
* @param target Target to generate params for. | |||
* @return Argument list for the formatted message. | |||
*/ | |||
private Object[] getTargetParams(Target target) { | |||
List args = new LinkedList(); | |||
args.add(target.getName()); | |||
args.add(target.getDescription() == null ? | |||
"" : target.getDescription()); | |||
StringBuffer buf = new StringBuffer(); | |||
Enumeration enum = target.getDependencies(); | |||
while(enum.hasMoreElements()) { | |||
buf.append(enum.nextElement()); | |||
if(enum.hasMoreElements()) { | |||
buf.append(", "); | |||
} | |||
} | |||
args.add(buf.toString()); | |||
return args.toArray(); | |||
} | |||
/** | |||
* Get the parameters for the formatted message presented for multiple | |||
* targets. | |||
* | |||
* @param target Targets to generate params for. | |||
* @return Argument list for the formatted message. | |||
*/ | |||
private Object[] getTargetParams(Target[] targets) { | |||
List args = new LinkedList(); | |||
StringBuffer buf = new StringBuffer(); | |||
Set depends = new HashSet(); | |||
for(int i = 0; i < targets.length; i++) { | |||
buf.append(targets[i].getName()); | |||
if(i < targets.length - 1) { | |||
buf.append(", "); | |||
} | |||
Enumeration enum = targets[i].getDependencies(); | |||
while(enum.hasMoreElements()) { | |||
depends.add(enum.nextElement()); | |||
} | |||
} | |||
args.add(buf.toString()); | |||
Iterator it = depends.iterator(); | |||
buf = new StringBuffer(); | |||
while(it.hasNext()) { | |||
buf.append(it.next()); | |||
if(it.hasNext()) { | |||
buf.append(", "); | |||
} | |||
} | |||
args.add(buf.toString()); | |||
return args.toArray(); | |||
} | |||
/** Class for handling project events. */ | |||
private class Handler implements BusMember { | |||
private final Filter _filter = new Filter(); | |||
/** | |||
* Get the filter to that is used to determine if an event should | |||
* to to the member. | |||
* | |||
* @return Filter to use. | |||
*/ | |||
public BusFilter getBusFilter() { | |||
return _filter; | |||
} | |||
/** | |||
* Called when an event is to be posted to the member. | |||
* | |||
* @param event Event to post. | |||
*/ | |||
public void eventPosted(EventObject event) { | |||
TargetSelectionEvent e = (TargetSelectionEvent) event; | |||
Target[] targets = e.getSelectedTargets(); | |||
displayTargetInfo(targets); | |||
} | |||
} | |||
/** Class providing filtering for project events. */ | |||
private static class Filter implements BusFilter { | |||
/** | |||
* Determines if the given event should be accepted. | |||
* | |||
* @param event Event to test. | |||
* @return True if event should be given to BusMember, false otherwise. | |||
*/ | |||
public boolean accept(EventObject event) { | |||
return event instanceof TargetSelectionEvent; | |||
} | |||
} | |||
} |
@@ -0,0 +1,96 @@ | |||
/* | |||
* 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; | |||
import org.apache.tools.ant.Target; | |||
import javax.swing.tree.DefaultTreeSelectionModel; | |||
import javax.swing.tree.TreePath; | |||
import java.util.*; | |||
/** | |||
* Selection model for the currently selected targets. | |||
* | |||
* @version $Revision$ | |||
* @author Simeon Fitch | |||
*/ | |||
class TargetSelectionModel extends DefaultTreeSelectionModel { | |||
/** | |||
* Default ctor. | |||
* | |||
*/ | |||
public TargetSelectionModel() { | |||
setSelectionMode(DISCONTIGUOUS_TREE_SELECTION); | |||
} | |||
/** | |||
* Convenience method for providing the set of currently selected | |||
* targets. | |||
* | |||
* @return the currently selected targets. | |||
*/ | |||
public Target[] getSelectedTargets() { | |||
TreePath[] path = getSelectionPaths(); | |||
List values = new LinkedList(); | |||
for(int i = 0; path != null && i < path.length; i++) { | |||
Object val = path[i].getLastPathComponent(); | |||
if(val instanceof Target) { | |||
values.add(val); | |||
} | |||
} | |||
Target[] retval = new Target[values.size()]; | |||
values.toArray(retval); | |||
return retval; | |||
} | |||
} |
@@ -0,0 +1,98 @@ | |||
/* | |||
* 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.event; | |||
import org.apache.tools.ant.Target; | |||
import org.apache.tools.ant.gui.command.Command; | |||
import org.apache.tools.ant.gui.command.NoOpCmd; | |||
import org.apache.tools.ant.gui.AppContext; | |||
/** | |||
* Event indicating that the current set of selected targets has changed. | |||
* | |||
* @version $Revision$ | |||
* @author Simeon Fitch | |||
*/ | |||
public class TargetSelectionEvent extends AntEvent { | |||
/** New set of selected targets. */ | |||
private Target[] _selectedTargets = null; | |||
/** | |||
* Standard ctor. | |||
* | |||
* @param context application context. | |||
*/ | |||
public TargetSelectionEvent(AppContext context, Target[] selectedTargets) { | |||
super(context); | |||
_selectedTargets = selectedTargets; | |||
} | |||
/** | |||
* Current set of selected targets. | |||
* | |||
* @return selected target set. | |||
*/ | |||
public Target[] getSelectedTargets() { | |||
return _selectedTargets; | |||
} | |||
/** | |||
* Create the appropriate default response command to this event. | |||
* | |||
* @return Command representing an appropriate response to this event. | |||
*/ | |||
public Command createDefaultCmd() { | |||
return new NoOpCmd(); | |||
} | |||
} |
@@ -1,6 +1,6 @@ | |||
menus=File, Build, Help | |||
actions=open, close, exit, about, startBuild, stopBuild | |||
actions=open, close, exit, about, startBuild | |||
new.name=New | |||
new.shortDescription=Create a new project | |||
@@ -15,7 +15,22 @@ org.apache.tools.ant.gui.Antidote.bottom.editors=\ | |||
# Set specific class properties. | |||
org.apache.tools.ant.gui.SourceEditor.name=Source | |||
org.apache.tools.ant.gui.PropertyEditor.name=Properties | |||
org.apache.tools.ant.gui.PropertyEditor.name=Target Info | |||
org.apache.tools.ant.gui.PropertyEditor.noTargets=No targets selected. | |||
org.apache.tools.ant.gui.PropertyEditor.oneTarget=\ | |||
<html><table>\ | |||
<tr><td align="right"><b>Name</b>:</td><td>{0}</td></tr>\ | |||
<tr><td align="right"><b>Description</b>:</td><td>{1}</td></tr>\ | |||
<tr><td align="right"><b>Depends</b>:</td><td>{2}</td></tr>\ | |||
</table></html> | |||
org.apache.tools.ant.gui.PropertyEditor.manyTargets=\ | |||
<html><table>\ | |||
<tr><td align="right"><b>Names</b>:</td><td>{0}</td></tr>\ | |||
<tr><td align="right"><b>Depends</b>:</td><td>{1}</td></tr>\ | |||
</table></html> | |||
org.apache.tools.ant.gui.ProjectNavigator.name=Project | |||
org.apache.tools.ant.gui.Console.name=Console | |||
org.apache.tools.ant.gui.Console.logLevel=Log message level: | |||