KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > oddjob > ant > AntJob


1 package org.oddjob.ant;
2
3 import java.io.BufferedReader JavaDoc;
4 import java.io.IOException JavaDoc;
5 import java.io.ObjectInputStream JavaDoc;
6 import java.io.ObjectOutputStream JavaDoc;
7 import java.io.OutputStream JavaDoc;
8 import java.io.PrintStream JavaDoc;
9 import java.io.StringReader JavaDoc;
10 import java.util.ArrayList JavaDoc;
11 import java.util.HashMap JavaDoc;
12 import java.util.Iterator JavaDoc;
13 import java.util.List JavaDoc;
14 import java.util.Map JavaDoc;
15
16 import org.apache.tools.ant.BuildEvent;
17 import org.apache.tools.ant.BuildException;
18 import org.apache.tools.ant.BuildListener;
19 import org.apache.tools.ant.BuildLogger;
20 import org.apache.tools.ant.DefaultLogger;
21 import org.apache.tools.ant.Project;
22 import org.apache.tools.ant.ProjectComponent;
23 import org.apache.tools.ant.Task;
24 import org.apache.tools.ant.util.StringUtils;
25 import org.oddjob.OddjobException;
26 import org.oddjob.arooa.ArooaContext;
27 import org.oddjob.arooa.ArooaHandler;
28 import org.oddjob.framework.SimpleJob;
29 import org.oddjob.util.OddjobConfigException;
30
31 /**
32  * @oddjob.description Run a series of <a HREF="http://ant.apache.org">Ant</a>
33  * tasks. This job doesn't run
34  * Ant, instead it uses the ant tasks directly. Oddjob creates
35  * and configures the tasks and this has some side affects:
36  * <ul>
37  * <li>The properties of an Ant task aren't constant. Oddjob variables
38  * can change unlike Ant properties.</li>
39  * <li>The Ant property tag has no affect. It's Oddjob that is
40  * setting the properties of the task, not Ant.</li>
41  * <li>Unlike Ant, the tasks are created at file parse time,
42  * not on execution. The Ant taskdef declaration doesn't work and
43  * some other related features.</li>
44  * <li>Types are allowed (such as pathelement) but the id
45  * must be const. This is because the reference is set
46  * at parse time.</li>
47  * </ul>
48  * Not all tasks will work and not all have been tested.
49  *
50  * @oddjob.example
51  *
52  * Please see the ant example in the provided examples.
53  */

54
55 public class AntJob extends SimpleJob {
56     static final long serialVersionUID = 20050202;
57
58     private static Map JavaDoc messageLevels = new HashMap JavaDoc();
59     
60     static {
61         messageLevels.put("DEBUG", new Integer JavaDoc(Project.MSG_DEBUG));
62         messageLevels.put("ERR", new Integer JavaDoc(Project.MSG_ERR));
63         messageLevels.put("INFO", new Integer JavaDoc(Project.MSG_INFO));
64         messageLevels.put("VERBOSE", new Integer JavaDoc(Project.MSG_VERBOSE));
65         messageLevels.put("WARN", new Integer JavaDoc(Project.MSG_WARN));
66     }
67     
68     /**
69      * @oddjob.property
70      * @oddjob.description A reference to project in another ant job.
71      * This allows reference ids to be shared.
72      *
73      * @oddjob.required No.
74      */

75     private transient Project project;
76     
77     private transient List JavaDoc tasks = new ArrayList JavaDoc();
78
79     /**
80      * @oddjob.property
81      * @oddjob.description The message level for output. one of
82      * DEBUG, ERROR, INFO, VERBOSE, WARN.
83      * @oddjob.required No.
84      */

85     private transient String JavaDoc messageLevel;
86     
87     /** Ouput from the Ant tasks. */
88     private transient OutputStream JavaDoc output;
89     
90     /**
91      * Provide a handler to parse children.
92      */

93     public ArooaHandler handlerFor(ArooaContext context) {
94         return new AntJobComponentHandler(getProject());
95     }
96     
97     /**
98      * Add an Ant ProjectComponent to this job.
99      *
100      * @param component The project component.
101      */

102     public void addComponent(ProjectComponent component) {
103         tasks.add(component);
104     }
105     
106     public void setOutput(OutputStream JavaDoc out) {
107         this.output = out;
108     }
109     /**
110      * Return the ant tasks output.
111      *
112      * @return The output as a string.
113      */

114     public OutputStream JavaDoc getOutput() {
115         return output;
116     }
117     
118     /**
119      * Get the project used for the tasks.
120      *
121      * @return The project.
122      */

123     public Project getProject() {
124         if (project == null) {
125             arooaRuntime().configure();
126         }
127         if (project == null) {
128             project = new Project();
129             ClassLoader JavaDoc cl = Thread.currentThread().getContextClassLoader();
130             if (cl != null) {
131                 logger().debug("Setting classloader to: " + cl);
132                 project.setCoreLoader(cl);
133             }
134             project.init();
135         }
136         return project;
137     }
138     
139     /**
140      * Set the project to use for the tasks. Can only be set once.
141      * It is assumed the project is already initialised.
142      *
143      * @param project The project.
144      * @throws OddjobException if the project is already set.
145      */

146     public void setProject(Project project) throws OddjobException {
147         if (this.project != null) {
148             return;
149         }
150         this.project = project;
151     }
152
153     public void setMessageLevel(String JavaDoc messageLevel) {
154         messageLevel = messageLevel.toUpperCase();
155         if (messageLevels.get(messageLevel) == null) {
156             throw new OddjobConfigException("Message level of [" + messageLevel + "] not known.");
157         }
158         this.messageLevel = messageLevel;
159     }
160     
161     public String JavaDoc getMessageLevel() {
162         return messageLevel;
163     }
164     
165     int messageLevel() {
166         if (messageLevel == null) {
167             return Project.MSG_INFO;
168         }
169         return ((Integer JavaDoc)messageLevels.get(messageLevel)).intValue();
170     }
171     
172     /**
173      * Execute the tasks.
174      */

175     protected int execute() throws Exception JavaDoc {
176
177         BuildLogger logger = new DefaultLogger();
178         if (output != null) {
179             logger.setOutputPrintStream(new PrintStream JavaDoc(output));
180             logger.setErrorPrintStream(new PrintStream JavaDoc(output));
181             logger.setMessageOutputLevel(messageLevel());
182             project.addBuildListener(logger);
183         }
184         DebugBuildListener debug = new DebugBuildListener();
185         debug.setMessageOutputLevel(messageLevel());
186         project.addBuildListener(debug);
187         try {
188             for (Iterator JavaDoc it = tasks.iterator(); it.hasNext();) {
189                 ProjectComponent pc = (ProjectComponent)it.next();
190                 if (pc instanceof Task) {
191                     Task task = (Task)pc;
192                     logger().debug("Starting task [" + task.getTaskName() + "]");
193                     task.execute();
194                 }
195             }
196             return 0;
197         }
198         catch (BuildException e) {
199             logger().debug("Build excpetion.", e);
200             return 1;
201         }
202         finally {
203             if (output != null) {
204                 project.removeBuildListener(logger);
205             }
206             project.removeBuildListener(debug);
207         }
208     }
209
210     /**
211      * Destroy.
212      */

213     public void onDestroy() {
214         tasks.clear();
215     }
216     
217     private void writeObject(ObjectOutputStream JavaDoc s)
218     throws IOException JavaDoc {
219         s.defaultWriteObject();
220     }
221     
222     private void readObject(ObjectInputStream JavaDoc s)
223     throws IOException JavaDoc, ClassNotFoundException JavaDoc {
224         s.defaultReadObject();
225         tasks = new ArrayList JavaDoc();
226     }
227     
228     class DebugBuildListener implements BuildListener {
229         /**
230          * Size of left-hand column for right-justified task name.
231          * @see #messageLogged(BuildEvent)
232          */

233         public static final int LEFT_COLUMN_SIZE = 12;
234
235         /** Lowest level of message to write out */
236         protected int msgOutputLevel = Project.MSG_ERR;
237
238         /** Line separator */
239         protected final String JavaDoc lSep = StringUtils.LINE_SEP;
240
241         /**
242          * Sets the highest level of message this logger should respond to.
243          *
244          * Only messages with a message level lower than or equal to the
245          * given level should be written to the log.
246          * <P>
247          * Constants for the message levels are in the
248          * {@link Project Project} class. The order of the levels, from least
249          * to most verbose, is <code>MSG_ERR</code>, <code>MSG_WARN</code>,
250          * <code>MSG_INFO</code>, <code>MSG_VERBOSE</code>,
251          * <code>MSG_DEBUG</code>.
252          * <P>
253          * The default message level for DefaultLogger is Project.MSG_ERR.
254          *
255          * @param level the logging level for the logger.
256          */

257         public void setMessageOutputLevel(int level) {
258             this.msgOutputLevel = level;
259         }
260
261         /**
262          * Ignore - Ant job doesn't start a build.
263          *
264          * @param event Ignored.
265          */

266         public void buildStarted(BuildEvent event) {
267         }
268
269         /**
270          * Ignore = Ant job doesn't finish a build.
271          *
272          * @param event Ignored
273          */

274         public void buildFinished(BuildEvent event) {
275         }
276
277         /**
278          * Ignore - Ant Job doesn't start targets.
279          *
280          * @param event Ignored
281           */

282         public void targetStarted(BuildEvent event) {
283         }
284
285         /**
286          * No-op implementation.
287          *
288          * @param event Ignored.
289          */

290         public void targetFinished(BuildEvent event) {
291         }
292
293         /**
294          * No-op implementation.
295          *
296          * @param event Ignored.
297          */

298         public void taskStarted(BuildEvent event) {
299         }
300
301         /**
302          * No-op implementation.
303          *
304          * @param event Ignored.
305          */

306         public void taskFinished(BuildEvent event) {
307         }
308
309         /**
310          * Logs a message, if the priority is suitable.
311          * In non-emacs mode, task level messages are prefixed by the
312          * task name which is right-justified.
313          *
314          * @param event A BuildEvent containing message information.
315          * Must not be <code>null</code>.
316          */

317         public void messageLogged(BuildEvent event) {
318             int priority = event.getPriority();
319             // Filter out messages based on priority
320
if (priority <= msgOutputLevel) {
321
322                 StringBuffer JavaDoc message = new StringBuffer JavaDoc();
323                 if (event.getTask() != null) {
324                     // Print out the name of the task if we're in one
325
String JavaDoc name = event.getTask().getTaskName();
326                     String JavaDoc label = "[" + name + "] ";
327                     int size = LEFT_COLUMN_SIZE - label.length();
328                     StringBuffer JavaDoc tmp = new StringBuffer JavaDoc();
329                     for (int i = 0; i < size; i++) {
330                         tmp.append(" ");
331                     }
332                     tmp.append(label);
333                     label = tmp.toString();
334
335                     try {
336                         BufferedReader JavaDoc r =
337                             new BufferedReader JavaDoc(
338                                 new StringReader JavaDoc(event.getMessage()));
339                         String JavaDoc line = r.readLine();
340                         boolean first = true;
341                         while (line != null) {
342                             if (!first) {
343                                 message.append(StringUtils.LINE_SEP);
344                             }
345                             first = false;
346                             message.append(label).append(line);
347                             line = r.readLine();
348                         }
349                     } catch (IOException JavaDoc e) {
350                         // shouldn't be possible
351
message.append(label).append(event.getMessage());
352                     }
353                 } else {
354                     message.append(event.getMessage());
355                 }
356
357                 String JavaDoc msg = message.toString();
358                 logger().debug("(Message) " + msg);
359             }
360         }
361
362     }
363 }
364
Popular Tags