source: other-projects/trunk/gs3-release-maker/apache-ant-1.6.5/src/main/org/apache/tools/ant/taskdefs/optional/ide/VAJBuildInfo.java@ 14627

Last change on this file since 14627 was 14627, checked in by oranfry, 17 years ago

initial import of the gs3-release-maker

File size: 14.7 KB
Line 
1/*
2 * Copyright 2001-2002,2004 The Apache Software Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18package org.apache.tools.ant.taskdefs.optional.ide;
19
20
21import java.beans.PropertyChangeListener;
22import java.beans.PropertyChangeSupport;
23import java.io.File;
24import java.util.Enumeration;
25import java.util.StringTokenizer;
26import java.util.Vector;
27import org.apache.tools.ant.BuildEvent;
28import org.apache.tools.ant.BuildException;
29import org.apache.tools.ant.BuildListener;
30import org.apache.tools.ant.Project;
31import org.apache.tools.ant.ProjectHelper;
32import org.apache.tools.ant.Target;
33
34/**
35 * This class wraps the Ant project information needed to
36 * start Ant from Visual Age.
37 * It serves the following purposes:
38 * - acts as model for AntMakeFrame
39 * - converts itself to/from String (to store the information
40 * as ToolData in the VA repository)
41 * - wraps Project functions for the GUI (get target list,
42 * execute target)
43 * - manages a seperate thread for Ant project execution
44 * this allows interrupting a running build from a GUI
45 *
46 */
47
48class VAJBuildInfo implements Runnable {
49 /**
50 * This exception is thrown when a build is interrupted
51 */
52 public static class BuildInterruptedException extends BuildException {
53 public String toString() {
54 return "BUILD INTERRUPTED";
55 }
56 }
57
58 /**
59 * BuildListener which checks for interruption and throws Exception
60 * if build process is interrupted. This class is a wrapper around
61 * a 'real' listener.
62 */
63 private class InterruptedChecker implements BuildListener {
64 // the real listener
65 BuildListener wrappedListener;
66
67 /**
68 * Can only be constructed as wrapper around a real listener
69 * @param listener the real listener
70 */
71 public InterruptedChecker(BuildListener listener) {
72 super();
73 wrappedListener = listener;
74 }
75
76 /**
77 * checks if the thread was interrupted. When an
78 * interrupt occurred, throw an Exception to stop
79 * the execution.
80 */
81 protected void checkInterrupted() {
82 if (buildThread.isInterrupted()) {
83 throw new BuildInterruptedException();
84 }
85 }
86
87 /**
88 * Fired after the last target has finished. This event
89 * will still be thrown if an error occurred during the build.
90 */
91 public void buildFinished(BuildEvent event) {
92 wrappedListener.buildFinished(event);
93 checkInterrupted();
94 }
95
96 /**
97 * Fired before any targets are started.
98 */
99 public void buildStarted(BuildEvent event) {
100 wrappedListener.buildStarted(event);
101 checkInterrupted();
102 }
103
104 /**
105 * Fired whenever a message is logged.
106 */
107 public void messageLogged(BuildEvent event) {
108 wrappedListener.messageLogged(event);
109 checkInterrupted();
110 }
111
112 /**
113 * Fired when a target has finished. This event will
114 * still be thrown if an error occurred during the build.
115 */
116 public void targetFinished(BuildEvent event) {
117 wrappedListener.targetFinished(event);
118 checkInterrupted();
119 }
120
121 /**
122 * Fired when a target is started.
123 */
124 public void targetStarted(BuildEvent event) {
125 wrappedListener.targetStarted(event);
126 checkInterrupted();
127 }
128
129 /**
130 * Fired when a task has finished. This event will still
131 * be throw if an error occurred during the build.
132 */
133 public void taskFinished(BuildEvent event) {
134 wrappedListener.taskFinished(event);
135 checkInterrupted();
136 }
137
138 /**
139 * Fired when a task is started.
140 */
141 public void taskStarted(BuildEvent event) {
142 wrappedListener.taskStarted(event);
143 checkInterrupted();
144 }
145 }
146
147 // name of the VA project this BuildInfo belongs to
148 private String vajProjectName = "";
149
150 // name of the Ant build file
151 private String buildFileName = "";
152
153 // main targets found in the build file
154 private Vector projectTargets = new Vector();
155
156 // target selected for execution
157 private String target = "";
158
159 // log level
160 private int outputMessageLevel = Project.MSG_INFO;
161
162 // Ant Project created from build file
163 private transient Project project;
164
165 // is true if Project initialization was successful
166 private transient boolean projectInitialized = false;
167
168 // Support for bound properties
169 protected transient PropertyChangeSupport propertyChange;
170
171 // thread for Ant build execution
172 private Thread buildThread;
173
174 // the listener used to log output.
175 private BuildListener projectLogger;
176
177
178 /**
179 * The addPropertyChangeListener method was generated to support the
180 * propertyChange field.
181 */
182 public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
183 getPropertyChange().addPropertyChangeListener(listener);
184 }
185
186 /**
187 * Returns the BuildInfo information as String. The BuildInfo can
188 * be rebuilt from that String by calling parse().
189 * @return String
190 */
191 public String asDataString() {
192 String result = getOutputMessageLevel() + "|" + getBuildFileName()
193 + "|" + getTarget();
194 for (Enumeration e = getProjectTargets().elements();
195 e.hasMoreElements();) {
196 result = result + "|" + e.nextElement();
197 }
198
199 return result;
200 }
201
202 /**
203 * Search for the insert position to keep names a sorted list of Strings
204 * This method has been copied from org.apache.tools.ant.Main
205 */
206 private static int findTargetPosition(Vector names, String name) {
207 int res = names.size();
208 for (int i = 0; i < names.size() && res == names.size(); i++) {
209 if (name.compareTo((String) names.elementAt(i)) < 0) {
210 res = i;
211 }
212 }
213 return res;
214 }
215
216 /**
217 * The firePropertyChange method was generated to support the propertyChange field.
218 */
219 public void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
220 getPropertyChange().firePropertyChange(propertyName, oldValue, newValue);
221 }
222
223 /**
224 * Returns the build file name.
225 * @return build file name.
226 */
227 public String getBuildFileName() {
228 return buildFileName;
229 }
230
231 /**
232 * Returns the log level
233 * @return log level.
234 */
235 public int getOutputMessageLevel() {
236 return outputMessageLevel;
237 }
238
239 /**
240 * Returns the Ant project
241 * @return org.apache.tools.ant.Project
242 */
243 private Project getProject() {
244 if (project == null) {
245 project = new Project();
246 }
247 return project;
248 }
249
250 /**
251 * return a list of all targets in the current buildfile
252 */
253 public Vector getProjectTargets() {
254 return projectTargets;
255 }
256
257 /**
258 * Accessor for the propertyChange field.
259 */
260 protected PropertyChangeSupport getPropertyChange() {
261 if (propertyChange == null) {
262 propertyChange = new PropertyChangeSupport(this);
263 }
264 return propertyChange;
265 }
266
267 /**
268 * returns the selected target.
269 */
270 public String getTarget() {
271 return target;
272 }
273
274 /**
275 * returns the VA project name
276 */
277 public String getVAJProjectName() {
278 return vajProjectName;
279 }
280
281 /**
282 * Initializes the Ant project. Assumes that the
283 * project attribute is already set.
284 */
285 private void initProject() {
286 try {
287 project.init();
288 File buildFile = new File(getBuildFileName());
289 project.setUserProperty("ant.file", buildFile.getAbsolutePath());
290 ProjectHelper.configureProject(project, buildFile);
291 setProjectInitialized(true);
292 } catch (RuntimeException exc) {
293 setProjectInitialized(false);
294 throw exc;
295 } catch (Error err) {
296 setProjectInitialized(false);
297 throw err;
298 }
299 }
300
301 /**
302 * Returns true, if the Ant project is initialized.
303 * (i.e., if the buildfile loaded).
304 */
305 public boolean isProjectInitialized() {
306 return projectInitialized;
307 }
308
309 /**
310 * Creates a BuildInfo object from a String
311 * The String must be in the format
312 * outputMessageLevel'|'buildFileName'|'defaultTarget'|'(project target'|')*
313 *
314 * @return org.apache.tools.ant.taskdefs.optional.vaj.BuildInfo
315 * @param data String
316 */
317 public static VAJBuildInfo parse(String data) {
318 VAJBuildInfo result = new VAJBuildInfo();
319
320 try {
321 StringTokenizer tok = new StringTokenizer(data, "|");
322 result.setOutputMessageLevel(tok.nextToken());
323 result.setBuildFileName(tok.nextToken());
324 result.setTarget(tok.nextToken());
325 while (tok.hasMoreTokens()) {
326 result.projectTargets.addElement(tok.nextToken());
327 }
328 } catch (Throwable t) {
329 // if parsing the info fails, just return
330 // an empty VAJBuildInfo
331 }
332 return result;
333 }
334
335 /**
336 * The removePropertyChangeListener method was generated
337 * to support the propertyChange field.
338 */
339 public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
340 getPropertyChange().removePropertyChangeListener(listener);
341 }
342
343 /**
344 * Sets the build file name
345 * @param buildFileName build file name
346 */
347 public void setBuildFileName(String newBuildFileName) {
348 String oldValue = buildFileName;
349 buildFileName = newBuildFileName;
350 setProjectInitialized(false);
351 firePropertyChange("buildFileName", oldValue, buildFileName);
352 }
353
354 /**
355 * Sets the log level (value must be one of the constants in Project)
356 * @param outputMessageLevel log level.
357 */
358 public void setOutputMessageLevel(int newOutputMessageLevel) {
359 int oldValue = outputMessageLevel;
360 outputMessageLevel = newOutputMessageLevel;
361 firePropertyChange("outputMessageLevel",
362 new Integer(oldValue), new Integer(outputMessageLevel));
363 }
364
365 /**
366 * Sets the log level (value must be one of the constants in Project)
367 * @param outputMessageLevel log level as String.
368 */
369 private void setOutputMessageLevel(String outputMessageLevel) {
370 int level = Integer.parseInt(outputMessageLevel);
371 setOutputMessageLevel(level);
372 }
373
374 /**
375 * sets the initialized flag
376 */
377 private void setProjectInitialized(boolean initialized) {
378 Boolean oldValue = new Boolean(projectInitialized);
379 projectInitialized = initialized;
380 firePropertyChange("projectInitialized", oldValue, new Boolean(projectInitialized));
381 }
382
383 /**
384 * Sets the target to execute when executeBuild is called
385 * @param newTarget build target
386 */
387 public void setTarget(String newTarget) {
388 String oldValue = target;
389 target = newTarget;
390 firePropertyChange("target", oldValue, target);
391 }
392
393 /**
394 * Sets the name of the Visual Age for Java project where
395 * this BuildInfo belongs to
396 * @param newProjectName VAJ project
397 */
398 public void setVAJProjectName(String newVAJProjectName) {
399 String oldValue = vajProjectName;
400 vajProjectName = newVAJProjectName;
401 firePropertyChange("VAJProjectName", oldValue, vajProjectName);
402 }
403
404 /**
405 * reloads the build file and updates the target list
406 */
407 public void updateTargetList() {
408 project = new Project();
409 initProject();
410 projectTargets.removeAllElements();
411 Enumeration ptargets = project.getTargets().elements();
412 while (ptargets.hasMoreElements()) {
413 Target currentTarget = (Target) ptargets.nextElement();
414 if (currentTarget.getDescription() != null) {
415 String targetName = currentTarget.getName();
416 int pos = findTargetPosition(projectTargets, targetName);
417 projectTargets.insertElementAt(targetName, pos);
418 }
419 }
420 }
421
422
423 /**
424 * cancels a build.
425 */
426 public void cancelBuild() {
427 buildThread.interrupt();
428 }
429
430 /**
431 * Executes the target set by setTarget().
432 * @param listener BuildListener for the output of the build
433 */
434 public void executeProject(BuildListener logger) {
435 Throwable error;
436 projectLogger = logger;
437 try {
438 buildThread = new Thread(this);
439 buildThread.setPriority(Thread.MIN_PRIORITY);
440 buildThread.start();
441 } catch (RuntimeException exc) {
442 error = exc;
443 throw exc;
444 } catch (Error err) {
445 error = err;
446 throw err;
447 }
448 }
449
450 /**
451 * Executes a build. This method is executed by
452 * the Ant execution thread
453 */
454 public void run() {
455 try {
456 InterruptedChecker ic = new InterruptedChecker(projectLogger);
457 BuildEvent e = new BuildEvent(getProject());
458 try {
459 ic.buildStarted(e);
460
461 if (!isProjectInitialized()) {
462 initProject();
463 }
464
465 project.addBuildListener(ic);
466 project.executeTarget(target);
467
468 ic.buildFinished(e);
469 } catch (Throwable t) {
470 e.setException(t);
471 ic.buildFinished(e);
472 } finally {
473 project.removeBuildListener(ic);
474 }
475 } catch (Throwable t2) {
476 System.out.println("unexpected exception!");
477 t2.printStackTrace();
478 }
479 }
480}
Note: See TracBrowser for help on using the repository browser.