KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > cruisecontrol > sourcecontrols > BuildStatus


1 /********************************************************************************
2  * CruiseControl, a Continuous Integration Toolkit
3  * Copyright (c) 2001, ThoughtWorks, Inc.
4  * 651 W Washington Ave. Suite 600
5  * Chicago, IL 60661 USA
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * + Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * + Redistributions in binary form must reproduce the above
16  * copyright notice, this list of conditions and the following
17  * disclaimer in the documentation and/or other materials provided
18  * with the distribution.
19  *
20  * + Neither the name of ThoughtWorks, Inc., CruiseControl, nor the
21  * names of its contributors may be used to endorse or promote
22  * products derived from this software without specific prior
23  * written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
29  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  ********************************************************************************/

37
38 package net.sourceforge.cruisecontrol.sourcecontrols;
39
40 import java.io.File JavaDoc;
41 import java.io.FilenameFilter JavaDoc;
42 import java.util.ArrayList JavaDoc;
43 import java.util.Date JavaDoc;
44 import java.util.Hashtable JavaDoc;
45 import java.util.List JavaDoc;
46 import java.util.Map JavaDoc;
47
48 import org.apache.log4j.Logger;
49 import net.sourceforge.cruisecontrol.CruiseControlException;
50 import net.sourceforge.cruisecontrol.Modification;
51 import net.sourceforge.cruisecontrol.SourceControl;
52 import net.sourceforge.cruisecontrol.Log;
53 import net.sourceforge.cruisecontrol.util.ValidationHelper;
54
55 import net.sourceforge.cruisecontrol.util.DateUtil;
56 import net.sourceforge.cruisecontrol.util.XMLLogHelper;
57 import org.jdom.input.SAXBuilder;
58 import org.jdom.Document;
59 import org.jdom.Element;
60 import org.jdom.JDOMException;
61 import java.io.IOException JavaDoc;
62
63 /**
64  * This class allows for starting builds based on the results of another
65  * build. It does this by examining the build's log files. Only
66  * successful builds count as modifications.
67  *
68  * @author Garrick Olson
69  */

70 public class BuildStatus implements SourceControl {
71
72     private static final Logger LOG = Logger.getLogger(BuildStatus.class);
73
74     /** The location being checked for new log files. */
75     public static final String JavaDoc MOST_RECENT_LOGDIR_KEY = "most.recent.logdir";
76
77     /** The name of the newest logfile included in the modification set
78      * (e.g. "log20040120120000L0.1.xml"). */

79     public static final String JavaDoc MOST_RECENT_LOGFILE_KEY = "most.recent.logfile";
80
81     /** The timestamp of the newest build included in the modification set
82      * (e.g. "20040120120000"). */

83     public static final String JavaDoc MOST_RECENT_LOGTIME_KEY = "most.recent.logtime";
84
85     /**
86      * The label of the newest build included in the modification set
87      * (e.g. "0.1").
88      */

89     public static final String JavaDoc MOST_RECENT_LOGLABEL_KEY = "most.recent.loglabel";
90
91     private Hashtable JavaDoc properties = new Hashtable JavaDoc();
92     private String JavaDoc logDir;
93
94     /**
95      * This method is used to make certain attributes of the most
96      * recent modification available to Ant tasks.
97      * @return A Hashtable object containing either no properties (if there
98      * were no modifications) or four properties (keys are
99      * provided as constants on this class). Never returns null.
100      */

101     public Map JavaDoc getProperties() {
102         return properties;
103     }
104
105     /**
106      * Indicate where the build to be monitored places its output (log files).
107      *
108      * @param logDir Absolute path to the log directory.
109      */

110     public void setLogDir(String JavaDoc logDir) {
111         this.logDir = logDir;
112         properties.put(MOST_RECENT_LOGDIR_KEY, logDir);
113     }
114
115     /**
116      * Make sure any attributes provided by the user are correctly specified.
117      */

118     public void validate() throws CruiseControlException {
119         ValidationHelper.assertIsSet(logDir, "logdir", this.getClass());
120
121         File JavaDoc logDirectory = new File JavaDoc(logDir);
122         ValidationHelper.assertTrue(logDirectory.exists(),
123             "Log directory does not exist: " + logDirectory.getAbsolutePath());
124         ValidationHelper.assertTrue(logDirectory.isDirectory(),
125             "Log directory is not a directory: " + logDirectory.getAbsolutePath());
126     }
127
128     /**
129      * The modifications reported by this method will be the list of new
130      * log files created as the result of successful builds (the log files
131      * will include the build label).
132      *
133      * @param lastBuild Look for successful builds newer than this date
134      * (may not be null).
135      * @param unused The timestamp of the current build is passed here
136      * (as per SourceControl interface) but we don't use it.
137      */

138     public List JavaDoc getModifications(Date JavaDoc lastBuild, Date JavaDoc unused) {
139         List JavaDoc modifications = new ArrayList JavaDoc();
140         File JavaDoc logDirectory = new File JavaDoc(logDir);
141         final String JavaDoc filename = Log.formatLogFileName(lastBuild);
142
143         try {
144             File JavaDoc[] newLogs = logDirectory.listFiles(new FilenameFilter JavaDoc() {
145                 public boolean accept(File JavaDoc dir, String JavaDoc name) {
146                     return name.compareTo(filename) > 0 && Log.wasSuccessfulBuild(name);
147                 }
148             });
149
150             Modification mostRecent = null;
151
152             for (int i = 0; i < newLogs.length; i++) {
153                 Modification modification = new Modification("buildstatus");
154                 String JavaDoc name = newLogs[i].getName();
155
156                 modification.modifiedTime = Log.parseDateFromLogFileName(name);
157                 modification.userName = "cc-" + getProjectFromLog(newLogs[i]);
158                 modification.comment = logDir.substring(logDir.lastIndexOf('/') + 1);
159                 modification.revision = Log.parseLabelFromLogFileName(name);
160
161                 Modification.ModifiedFile modfile = modification.createModifiedFile(name, null);
162                 modfile.revision = modification.revision;
163                 modfile.action = "add";
164
165                 if (mostRecent == null || modification.modifiedTime.after(mostRecent.modifiedTime)) {
166                     mostRecent = modification;
167                 }
168
169                 modifications.add(modification);
170             }
171
172             // This makes information about the most recent modification
173
// available to Ant tasks
174
if (mostRecent != null) {
175                 properties.put(MOST_RECENT_LOGFILE_KEY, ((Modification.ModifiedFile) mostRecent.files.get(0)).fileName);
176                 properties.put(MOST_RECENT_LOGTIME_KEY, DateUtil.getFormattedTime(mostRecent.modifiedTime));
177                 properties.put(MOST_RECENT_LOGLABEL_KEY, mostRecent.revision);
178             }
179
180         } catch (Exception JavaDoc e) {
181             LOG.error("Error checking for modifications", e);
182         }
183         return modifications;
184     }
185
186     private String JavaDoc getProjectFromLog(File JavaDoc f) {
187         LOG.info("Getting project from file: " + f.getName());
188         try {
189             Document doc = readDocFromFile(f);
190             LOG.info("Loaded xml document for BuildStatus");
191             Element root = doc.getRootElement();
192             XMLLogHelper log = new XMLLogHelper(root);
193         return log.getProjectName();
194         } catch (JDOMException ex) {
195             LOG.info("Failed to load BuildStatus xml document" + ex);
196         } catch (IOException JavaDoc ex) {
197             LOG.info("Failed to load BuildStatus xml document" + ex);
198         } catch (CruiseControlException ex) {
199             LOG.info("Could load BuildStatus xml log document, but generated exception anyway" + ex);
200         }
201         return "Unknown";
202     }
203
204     private Document readDocFromFile(File JavaDoc f) throws JDOMException, IOException JavaDoc {
205         SAXBuilder sxb = new SAXBuilder();
206         return sxb.build(f);
207     }
208 }
209
210
Popular Tags