KickJava   Java API By Example, From Geeks To Geeks.

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


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 package net.sourceforge.cruisecontrol.sourcecontrols;
38
39 import net.sourceforge.cruisecontrol.SourceControl;
40 import net.sourceforge.cruisecontrol.CruiseControlException;
41 import net.sourceforge.cruisecontrol.Modification;
42 import net.sourceforge.cruisecontrol.util.ValidationHelper;
43 import net.sourceforge.cruisecontrol.util.ManagedCommandline;
44
45 import org.apache.log4j.Logger;
46
47 import java.util.Hashtable JavaDoc;
48 import java.util.Date JavaDoc;
49 import java.util.List JavaDoc;
50 import java.util.ArrayList JavaDoc;
51 import java.util.Map JavaDoc;
52 import java.util.StringTokenizer JavaDoc;
53 import java.util.Iterator JavaDoc;
54 import java.io.IOException JavaDoc;
55
56 /**
57  * This class implements the SourceControl methods for an AlienBrain
58  * repository. It does this by taking advantage of the AlienBrain command-
59  * line utility. Obviously, the command line utility must be installed
60  * and working in order for this class to work.
61  *
62  * This class is based very heavily on P4.java.
63  *
64  * @author <a HREF="mailto:scottj+cc@escherichia.net">Scott Jacobs</a>
65  */

66 public class AlienBrain extends AlienBrainCore implements SourceControl {
67     
68     private static final Logger LOG = Logger.getLogger(AlienBrain.class);
69     /*
70      * The difference between January 1, 1601 0:00:00 UTC and January 1,
71      * 1970 0:00:00 UTC in milliseconds.
72      * ((369 years * 365 days) + 89 leap days) * 24h * 60m * 60s * 1000ms
73      */

74     private static final long FILETIME_EPOCH_DIFF = 11644473600000L;
75     /* 100-ns intervals per ms */
76     private static final long HUNDRED_NANO_PER_MILLI_RATIO = 10000L;
77     private static final String JavaDoc AB_NO_MODIFICATIONS = "No files or folders found!";
78     private static final String JavaDoc AB_MODIFICATION_SUMMARY_PREFIX = "Total of ";
79     
80     private Hashtable JavaDoc properties = new Hashtable JavaDoc();
81
82     /**
83      * Any properties that have been set in this sourcecontrol.
84      * Currently, this would be none.
85      */

86     public Map JavaDoc getProperties() {
87         return properties;
88     }
89    
90     public void validate() throws CruiseControlException {
91         ValidationHelper.assertIsSet(getPath(), "path", this.getClass());
92     }
93
94     /**
95      * Get a List of Modifications detailing all the changes between now and
96      * the last build
97      *
98      *@param lastBuild
99      *@param now
100      *@return List of Modification objects
101      */

102     public List JavaDoc getModifications(Date JavaDoc lastBuild, Date JavaDoc now) {
103         List JavaDoc mods = new ArrayList JavaDoc();
104         try {
105             validate();
106             mods = getModificationsFromAlienBrain(lastBuild, now);
107         } catch (Exception JavaDoc e) {
108             LOG.error("Log command failed to execute succesfully", e);
109         }
110         
111         return mods;
112     }
113     
114     /**
115      * Convert a Java Date into an AlienBrain SCIT timestamp.
116      * AlienBrain provides a 64-bit modification timestamp that is in windows
117      * FILETIME format, which is a 65-bit value representing the number of
118      * 100-nanosecond intervals since January 1, 1601 (UTC).
119      */

120     public static long dateToFiletime(Date JavaDoc date) {
121         long milliSecsSinceUnixEpoch = date.getTime();
122         long milliSecsSinceFiletimeEpoch = milliSecsSinceUnixEpoch + FILETIME_EPOCH_DIFF;
123         return milliSecsSinceFiletimeEpoch * HUNDRED_NANO_PER_MILLI_RATIO;
124     }
125     
126     /**
127      * Convert an AlienBrain SCIT timestamp into a Java Date.
128      * AlienBrain provides a 64-bit modification timestamp that is in windows
129      * FILETIME format, which is a 64-bit value representing the number of
130      * 100-nanosecond intervals since January 1, 1601 (UTC).
131      */

132     public static Date JavaDoc filetimeToDate(long filetime) {
133         long milliSecsSinceFiletimeEpoch = filetime / HUNDRED_NANO_PER_MILLI_RATIO;
134         long milliSecsSinceUnixEpoch = milliSecsSinceFiletimeEpoch - FILETIME_EPOCH_DIFF;
135         return new Date JavaDoc(milliSecsSinceUnixEpoch);
136     }
137
138     /**
139      * Construct a ManagedCommandline which will run the AlienBrain command-line
140      * client in such a way that it will return a list of modifications.
141      *
142      *@param lastBuild
143      *@param now
144      */

145     protected ManagedCommandline buildGetModificationsCommand(Date JavaDoc lastBuild, Date JavaDoc now) {
146         ManagedCommandline cmdLine = buildCommonCommand();
147         cmdLine.createArgument().setValue("find");
148         cmdLine.createArgument().setValue(getPath());
149         cmdLine.createArgument().setValue("-regex");
150         cmdLine.createArgument().setValue("SCIT > " + dateToFiletime(lastBuild));
151         cmdLine.createArgument().setValue("-format");
152         cmdLine.createArgument().setValue("#SCIT#|#DbPath#|#Changed By#|#CheckInComment#");
153         
154         return cmdLine;
155     }
156    
157     /**
158      * Run the AlienBrain command-line client and return a list of
159      * Modifications since lastBuild, if any.
160      *@param lastBuild
161      *@param now
162      */

163     protected List JavaDoc getModificationsFromAlienBrain(Date JavaDoc lastBuild, Date JavaDoc now)
164         throws IOException JavaDoc, CruiseControlException {
165  
166         if (getBranch() != null) {
167             setActiveBranch(getBranch());
168         }
169             
170         ManagedCommandline cmdLine = buildGetModificationsCommand(lastBuild, now);
171         LOG.debug("Executing: " + cmdLine.toString());
172         cmdLine.execute();
173
174         return parseModifications(cmdLine.getStdoutAsList());
175     }
176    
177     /**
178      * Turn a stream containing the results of running the AlienBrain
179      * command-line client into a list of Modifications.
180      */

181     protected List JavaDoc parseModifications(List JavaDoc modifications) throws IOException JavaDoc {
182         List JavaDoc mods = new ArrayList JavaDoc();
183         
184         for (Iterator JavaDoc it = modifications.iterator(); it.hasNext(); ) {
185             String JavaDoc line = (String JavaDoc) it.next();
186             line = line.trim();
187             if (line.equals(AB_NO_SESSION)) {
188                 LOG.error(AB_NO_SESSION);
189                 continue;
190             } else if (line.equals(AB_NO_MODIFICATIONS)) {
191                 continue;
192             } else if (line.startsWith(AB_MODIFICATION_SUMMARY_PREFIX)) {
193                 continue;
194             } else if (line.startsWith("|")) {
195                 //Folders don't seem to always have a checked-in time, so
196
//fake one.
197
line = "0" + line;
198             }
199             
200             Modification m = parseModificationDescription(line);
201             mods.add(m);
202         }
203         return mods;
204     }
205     
206     /**
207      * Turns a string, most likely provided from the AlienBrain command-line
208      * client, into a Modification.
209      */

210     protected static Modification parseModificationDescription(String JavaDoc description) {
211         Modification m = new Modification("AlienBrain");
212         
213         StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(description, "|");
214         
215         m.modifiedTime = AlienBrain.filetimeToDate(Long.parseLong(st.nextToken()));
216         m.createModifiedFile(st.nextToken(), null);
217         m.userName = st.nextToken();
218         while (st.hasMoreTokens()) {
219             m.comment += st.nextToken();
220         }
221                 
222         return m;
223     }
224 }
225
Popular Tags