metasim 01/01/08 11:43:33
Modified: src/antidote/org/apache/tools/ant/gui/core AppContext.java
ProjectManager.java
Added: src/antidote/org/apache/tools/ant/gui/core
SelectionManager.java
Log:
Added *internal* support multiple projects, and generalized the selection
state mechanism.
Revision Changes Path
1.4 +37 -77
jakarta-ant/src/antidote/org/apache/tools/ant/gui/core/AppContext.java
Index: AppContext.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/src/antidote/org/apache/tools/ant/gui/core/AppContext.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- AppContext.java 2001/01/04 21:11:13 1.3
+++ AppContext.java 2001/01/08 19:43:30 1.4
@@ -54,6 +54,8 @@
package org.apache.tools.ant.gui.core;
import org.apache.tools.ant.BuildListener;
import org.apache.tools.ant.gui.event.*;
+import org.apache.tools.ant.gui.acs.ACSProjectElement;
+import org.apache.tools.ant.gui.acs.ACSTargetElement;
import java.awt.Frame;
import java.util.*;
@@ -61,7 +63,7 @@
* A container for the state information for the application. Provides
* a centeralized place to gain access to resources and data.
*
- * @version $Revision: 1.3 $
+ * @version $Revision: 1.4 $
* @author Simeon Fitch
*/
public class AppContext {
@@ -71,29 +73,49 @@
private ResourceManager _resources = new ResourceManager();
/** The project manager. */
private ProjectManager _projectManager = new ProjectManager();
+ /** Thing that keeps track of the current selection state. */
+ private SelectionManager _selectionManager = new SelectionManager();
+
/** Application actions. */
private ActionManager _actions =
new ActionManager(_eventBus, new ResourceManager(
"org.apache.tools.ant.gui.resources.action"));
- /** 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. */
private Frame _parentFrame = null;
- /** The current data model. */
- private ProjectProxy _project = null;
+ /**
+ * Constructor of apps that don't have a graphical
+ * component (e.g. web based).
+ *
+ */
+ public AppContext() {
+ this(null);
+ }
+ /**
+ * Standard constructor.
+ *
+ * @param parent Parent frame. XXX may go away.
+ */
public AppContext(Frame parent) {
_parentFrame = parent;
- // Add the build listener for dispatching BuildEvent
- // objects to the EventBus.
BuildEventForwarder handler = new BuildEventForwarder(this);
- addBuildListener(handler);
+ _projectManager.addBuildListener(handler);
+ _eventBus.addMember(EventBus.MONITORING, _selectionManager);
}
/**
+ * Get the parent frame. XXX may change...
+ *
+ * @return Parent frame.
+ */
+ public Frame getParentFrame() {
+ return _parentFrame;
+ }
+
+ /**
* Get the localized resources.
*
* @return Resources.
@@ -120,15 +142,6 @@
return _eventBus;
}
- /**
- * Get the parent frame. XXX may change...
- *
- * @return Parent frame.
- */
- public Frame getParentFrame() {
- return _parentFrame;
- }
-
/**
* Get the project manager.
*
@@ -138,68 +151,15 @@
return _projectManager;
}
- /**
- * Get the current project.
- *
- * @return Current project. NUll if no active project.
- */
- public ProjectProxy getProject() {
- 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);
- }
-
- /**
- * Determine if the given BuildListener is registered.
- *
- * @param l Listener to test for.
- * @return True if listener has been added, false if unknown.
- */
- public boolean isRegisteredBuildListener(BuildListener l) {
- return _buildListeners.contains(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;
+ /**
+ * Get the selection manager.
+ *
+ * @return Selection manager.
+ */
+ public SelectionManager getSelectionManager() {
+ return _selectionManager;
}
- /**
- * Set the current project.
- *
- * @param project Next project to operate on. May be null for the
"close"
- * action.
-
- */
- public void setProject(ProjectProxy project) {
- if(_project == null || !_project.equals(project)) {
- _project = project;
- getEventBus().postEvent(new NewProjectEvent(this));
- }
- }
}
1.2 +234 -3
jakarta-ant/src/antidote/org/apache/tools/ant/gui/core/ProjectManager.java
Index: ProjectManager.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/src/antidote/org/apache/tools/ant/gui/core/ProjectManager.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ProjectManager.java 2001/01/04 21:10:36 1.1
+++ ProjectManager.java 2001/01/08 19:43:31 1.2
@@ -53,22 +53,35 @@
*/
package org.apache.tools.ant.gui.core;
+import org.apache.tools.ant.BuildListener;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectHelper;
+import org.apache.tools.ant.BuildEvent;
import org.apache.tools.ant.gui.acs.*;
-import java.io.IOException;
+import org.apache.tools.ant.gui.event.BuildEventType;
+import java.io.*;
import java.net.URL;
+import java.net.URLConnection;
import java.util.*;
/**
* This class is responsible for managing the currently open projects,
* and the loading of new projects.
*
- * @version $Revision: 1.1 $
+ * XXX need to add property change listeners support.
+ *
+ * @version $Revision: 1.2 $
* @author Simeon Fitch
*/
public class ProjectManager {
/** Set of open projects. */
private List _projects = new ArrayList(1);
+ /** List of build listeners to register when build starts. */
+ private List _buildListeners = new LinkedList();
+ /** The current thread executing a build. */
+ private Thread _buildThread = null;
public ProjectManager() {
}
@@ -110,18 +123,44 @@
// xxx Fix me.
throw new IOException("xxx need a file name xxx");
}
+
+ Writer out = null;
+ try {
+ URLConnection connection = location.openConnection();
+ connection.setDoInput(false);
+ connection.setDoOutput(true);
+ out = new OutputStreamWriter(connection.getOutputStream());
+ project.write(out);
+ project.setLocation(location);
+ }
+ finally {
+ try { out.close(); } catch(Exception ex) {}
+ }
+ }
+
+ /**
+ * Open the project persisted at the given location
+ *
+ * @param location Location of project file.
+ * @return Successfully loaded project.
+ * @throws IOException thrown if there is a problem opening the project.
+ */
+ public ACSProjectElement open(File location) throws IOException {
+ return open(new URL("file", null, location.getPath()));
}
/**
* Open the project persisted at the given location
*
- * @param location Location to save to.
+ * @param location Location of project file.
* @return Successfully loaded project.
* @throws IOException thrown if there is a problem opening the project.
*/
public ACSProjectElement open(URL location) throws IOException {
ACSProjectElement retval = null;
retval = ACSFactory.getInstance().load(location);
+ retval.setLocation(location);
+ _projects.add(retval);
return retval;
}
@@ -133,5 +172,197 @@
public ACSProjectElement createNew() {
ACSProjectElement retval = null;
return retval;
+ }
+
+ /**
+ * Remove the given project from the set of active projects.
+ *
+ * @param project Project to close.
+ */
+ public void close(ACSProjectElement project) {
+ _projects.remove(project);
+ }
+
+ /**
+ * Build the project with the given target (or the default target
+ * if none is selected. Build occurs on a separate thread, so method
+ * returns immediately.
+ *
+ * @param project Project to build.
+ * @param targets Targets to build in project.
+ */
+ public void build(ACSProjectElement project, ACSTargetElement[] targets)
+ throws BuildException {
+ _buildThread = new Thread(new BuildRunner(project, targets));
+ _buildThread.start();
+ }
+
+ /**
+ * Add a build listener.
+ *
+ * @param l Listener to add.
+ */
+ public void addBuildListener(BuildListener l) {
+ synchronized(_buildListeners) {
+ _buildListeners.add(l);
+ }
+ }
+
+ /**
+ * Remove a build listener.
+ *
+ * @param l Listener to remove.
+ */
+ public void removeBuildListener(BuildListener l) {
+ synchronized(_buildListeners) {
+ _buildListeners.remove(l);
+ }
+ }
+
+ /**
+ * Determine if the given BuildListener is registered.
+ *
+ * @param l Listener to test for.
+ * @return True if listener has been added, false if unknown.
+ */
+ public boolean isRegisteredBuildListener(BuildListener l) {
+ synchronized(_buildListeners) {
+ return _buildListeners.contains(l);
+ }
+ }
+
+ /**
+ * Get the set of current build listeners.
+ *
+ * @return Set of current build listeners.
+ */
+ public BuildListener[] getBuildListeners() {
+ synchronized(_buildListeners) {
+ BuildListener[] retval = new
BuildListener[_buildListeners.size()];
+ _buildListeners.toArray(retval);
+ return retval;
+ }
+ }
+
+ /** Class for executing the build in a separate thread. */
+ private class BuildRunner implements Runnable {
+ /** The project to execute build on. */
+ private ACSProjectElement _project = null;
+ /** Targets to build. */
+ private ACSTargetElement[] _targets = null;
+ /** The Ant core representation of a project. */
+ private Project _antProject = null;
+
+ /**
+ * Standard ctor.
+ *
+ * @param project Project to execute build on.
+ * @param targets Targets to build.
+ */
+ public BuildRunner(ACSProjectElement project,
+ ACSTargetElement[] targets) throws BuildException
{
+ _project = project;
+ _targets = targets;
+
+ URL location = _project.getLocation();
+ if(location == null) {
+ // XXX this needs to be changed so that if the project is
+ // not saved, or the persistence mechanism is remote
+ // then a temporary version is saved first.
+ throw new BuildException("Project must be saved first");
+ }
+
+ // XXX hopefully we will eventually be able to save
+ // project files to any type of URL. Right now the Ant core
+ // only supports Files.
+ if(!location.getProtocol().equals("file")) {
+ throw new IllegalArgumentException(
+ "The Ant core only supports building from locally " +
+ "stored build files.");
+ }
+
+ File f = new File(location.getFile());
+
+ _antProject = new Project();
+ _antProject.init();
+ // XXX there is a bunch of stuff in the class
+ // org.apache.tools.ant.Main that needs 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. JAVA_HOME may have to be set,
+ // as well as checking the .ant.properties
+ _antProject.setUserProperty(
+ "ant.file" , f.getAbsolutePath());
+ ProjectHelper.configureProject(_antProject, f);
+ }
+
+ /**
+ * Convenience method for causeing the project to fire a build event.
+ * Implemented because the corresponding method in the Project class
+ * is not publically accessible.
+ *
+ * @param event Event to fire.
+ */
+ private void fireBuildEvent(BuildEvent event, BuildEventType type) {
+ Enumeration enum = _antProject.getBuildListeners().elements();
+ while(enum.hasMoreElements()) {
+ BuildListener l = (BuildListener) enum.nextElement();
+ type.fireEvent(event, l);
+ }
+ }
+
+ /**
+ * Run the build.
+ *
+ */
+ public void run() {
+ synchronized(_antProject) {
+ // Add the build listeners
+ BuildListener[] listeners = getBuildListeners();
+ for(int i = 0; i < listeners.length; i++) {
+ _antProject.addBuildListener(listeners[i]);
+ }
+
+ try {
+
+ fireBuildEvent(new BuildEvent(
+ _antProject), BuildEventType.BUILD_STARTED);
+
+
+ Vector targetNames = new Vector();
+ if(_targets == null || _targets.length == 0) {
+ targetNames.add(_antProject.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.
+ _antProject.executeTargets(targetNames);
+ }
+ catch(BuildException ex) {
+ BuildEvent errorEvent = new BuildEvent(_antProject);
+ errorEvent.setException(ex);
+ errorEvent.setMessage(ex.getMessage(), Project.MSG_ERR);
+ fireBuildEvent(errorEvent,
BuildEventType.MESSAGE_LOGGED);
+ }
+ finally {
+ fireBuildEvent(new BuildEvent(
+ _antProject), BuildEventType.BUILD_FINISHED);
+
+ // Remove the build listeners.
+ for(int i = 0; i < listeners.length; i++) {
+ _antProject.removeBuildListener(listeners[i]);
+ }
+ }
+ }
+ }
}
}
1.1
jakarta-ant/src/antidote/org/apache/tools/ant/gui/core/SelectionManager.java
Index: SelectionManager.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001 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", "Ant", 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 [EMAIL PROTECTED]
*
* 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.core;
import org.apache.tools.ant.gui.event.*;
import org.apache.tools.ant.gui.command.*;
import org.apache.tools.ant.gui.acs.*;
import java.util.EventObject;
import java.awt.event.ActionEvent;
import javax.swing.*;
/**
* State management class for keeping track of what build file elements are
* currently selected. It monitors the EventBus for selection events and
* Records the current state. It should be registered with the EventBus
* at the MONITORING level.
*
* @version $Revision: 1.1 $
* @author Simeon Fitch
*/
public class SelectionManager implements BusMember {
/** The filter for getting the correct events.*/
private final Filter _filter = new Filter();
/** The currently selected project. */
private ACSProjectElement _project = null;
/** The current set of selected targets. */
private ACSTargetElement[] _targets = null;
/** The current set of selected elements. */
private ACSElement[] _elements = null;
public SelectionManager() {
}
/**
* 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;
}
/**
* Get the currently selected project.
*
* @return Current project.
*/
public ACSProjectElement getSelectedProject() {
return _project;
}
/**
* Get the selected elements that are targets.
*
*/
public ACSTargetElement[] getSelectedTargets() {
return _targets;
}
/**
* Get the selected elements.
*
*/
public ACSElement[] getSelectedElements() {
return _elements;
}
/**
* Called when an event is to be posed to the member.
*
* @param event Event to post.
* @return true if event should be propogated, false if
* it should be cancelled.
*/
public boolean eventPosted(EventObject event) {
_elements = ((ElementSelectionEvent)event).getSelectedElements();
if(event instanceof TargetSelectionEvent) {
_targets = ((TargetSelectionEvent)event).getSelectedTargets();
}
else if(event instanceof ProjectSelectedEvent) {
_project = ((ProjectSelectedEvent)event).getSelectedProject();
}
return true;
}
/** Filter for ElementSelectionEvent objects. */
private static class Filter implements BusFilter {
public boolean accept(EventObject event) {
return event instanceof ElementSelectionEvent;
}
}
}