KickJava   Java API By Example, From Geeks To Geeks.

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


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 com.starbase.starteam.File;
40 import com.starbase.starteam.Folder;
41 import com.starbase.starteam.Item;
42 import com.starbase.starteam.TypeNotFoundException;
43 import com.starbase.starteam.PropertyNames;
44 import com.starbase.starteam.Server;
45 import com.starbase.starteam.ServerException;
46 import com.starbase.starteam.StarTeamFinder;
47 import com.starbase.starteam.TypeNames;
48 import com.starbase.starteam.User;
49 import com.starbase.starteam.UserAccount;
50 import com.starbase.starteam.View;
51 import com.starbase.starteam.ViewConfiguration;
52 import com.starbase.util.OLEDate;
53 import net.sourceforge.cruisecontrol.CruiseControlException;
54 import net.sourceforge.cruisecontrol.Modification;
55 import net.sourceforge.cruisecontrol.SourceControl;
56 import net.sourceforge.cruisecontrol.util.ValidationHelper;
57 import org.apache.log4j.Logger;
58
59 import java.util.ArrayList JavaDoc;
60 import java.util.Date JavaDoc;
61 import java.util.HashMap JavaDoc;
62 import java.util.Hashtable JavaDoc;
63 import java.util.Iterator JavaDoc;
64 import java.util.List JavaDoc;
65 import java.util.Map JavaDoc;
66
67 /**
68  * This class logs into StarTeam and collects information on any modifications
69  * made since the last successful build.
70  *
71  * @author Christopher Charlier -- ThoughtWorks Inc. 2001
72  * @author <a HREF="mailto:jcyip@thoughtworks.com">Jason Yip</a>
73  * @author Neill
74  * @author Ben Burgess
75  */

76 public class StarTeam implements SourceControl {
77
78     private static final Logger LOG = Logger.getLogger(StarTeam.class);
79
80     private String JavaDoc userName;
81     private String JavaDoc password;
82     private String JavaDoc folder;
83     private String JavaDoc url;
84     private List JavaDoc modifications = new ArrayList JavaDoc();
85     private OLEDate nowDate;
86     private Folder lastBuildRoot;
87     private PropertyNames stPropertyNames;
88     private Server server;
89     private TypeNames stTypeNames;
90
91     private Hashtable JavaDoc properties = new Hashtable JavaDoc();
92     private String JavaDoc property;
93     private String JavaDoc propertyOnDelete;
94
95     private boolean preloadFileInformation = true;
96     private boolean canLookupEmails = true;
97     private boolean canLookupDeletions = true;
98
99     /**
100      * Set StarTeam user name
101      */

102     public void setUsername(String JavaDoc userName) {
103         this.userName = userName;
104     }
105
106     /**
107      * Set password for StarTeam user
108      */

109     public void setPassword(String JavaDoc password) {
110         this.password = password;
111     }
112
113     /**
114      * Set repository folder
115      */

116     public void setFolder(String JavaDoc folder) {
117         this.folder = folder;
118     }
119
120     public void setPreloadFileInformation(boolean preloadFileInformation) {
121         this.preloadFileInformation = preloadFileInformation;
122     }
123
124     public void setStarteamurl(String JavaDoc url) {
125         this.url = url;
126     }
127
128     public void setProperty(String JavaDoc property) {
129         this.property = property;
130     }
131
132     public void setPropertyOnDelete(String JavaDoc propertyOnDelete) {
133         this.propertyOnDelete = propertyOnDelete;
134     }
135
136     public Map JavaDoc getProperties() {
137         return properties;
138     }
139
140     public void validate() throws CruiseControlException {
141         ValidationHelper.assertIsSet(folder, "folder", this.getClass());
142         ValidationHelper.assertIsSet(url, "url", this.getClass());
143         ValidationHelper.assertIsSet(userName, "username", this.getClass());
144         ValidationHelper.assertIsSet(password, "password", this.getClass());
145
146         // uncomment below for debugging which properties to populateNow
147
//com.starbase.starteam.vts.comm.NetMonitor.onConsole();
148
}
149
150     /**
151      * Populates the modification set with all appropriate information based on
152      * the changes since the last successful build.
153      */

154     public List JavaDoc getModifications(Date lastBuild, Date now) {
155         // Clean out the modifications list. Otherwise we get duplicate entries
156
// when this function is called more than once in a quiet period breach
157
// We normally would need to clean out the email list as well, except we
158
// know that all entries in current list will still be required
159
modifications.clear();
160
161         // Store OLEDate equivalents of now and lastbuild for performance
162
nowDate = new OLEDate(now.getTime());
163         OLEDate lastBuildDate = new OLEDate(lastBuild.getTime());
164
165         server = null;
166         try {
167             // Set up two view snapshots, one at lastbuild time, one now
168
View view = StarTeamFinder.openView(userName + ":" + password + "@" + url);
169             server = view.getServer();
170
171             View snapshotAtNow = new View(view, ViewConfiguration.createFromTime(nowDate));
172             View snapshotAtLastBuild =
173                 new View(view, ViewConfiguration.createFromTime(lastBuildDate));
174
175             Map JavaDoc nowFiles = new HashMap JavaDoc();
176             Map JavaDoc lastBuildFiles = new HashMap JavaDoc();
177
178             Folder nowRoot = StarTeamFinder.findFolder(snapshotAtNow.getRootFolder(), folder);
179
180             stPropertyNames = server.getPropertyNames();
181             stTypeNames = server.getTypeNames();
182             // properties to fetch immediately and cache
183
final String JavaDoc[] propertiesToCache =
184                 new String JavaDoc[] {
185                     stPropertyNames.FILE_CONTENT_REVISION,
186                     stPropertyNames.MODIFIED_TIME,
187                     stPropertyNames.FILE_FILE_TIME_AT_CHECKIN,
188                     stPropertyNames.COMMENT,
189                     stPropertyNames.MODIFIED_USER_ID,
190                     stPropertyNames.FILE_NAME };
191
192             if (preloadFileInformation) {
193                 // cache information for now
194
nowRoot.populateNow(stTypeNames.FILE, propertiesToCache, -1);
195             }
196
197             // Visit all files in the snapshots and add to Maps
198
addFolderModsToList(nowFiles, nowRoot);
199
200             try {
201                 lastBuildRoot =
202                     StarTeamFinder.findFolder(snapshotAtLastBuild.getRootFolder(), folder);
203
204                 if (preloadFileInformation) {
205                     // cache information for last build
206
lastBuildRoot.populateNow(stTypeNames.FILE, propertiesToCache, -1);
207                 }
208
209                 addFolderModsToList(lastBuildFiles, lastBuildRoot);
210             } catch (ServerException se) {
211                 LOG.error(url + ": Server Exception occurred visiting last build view: ", se);
212             }
213
214             compareFileLists(nowFiles, lastBuildFiles);
215
216             // Discard cached items so memory is not eaten up
217
snapshotAtNow.getRootFolder().discardItems(stTypeNames.FILE, -1);
218
219             try {
220                 snapshotAtLastBuild.getRootFolder().discardItems(stTypeNames.FILE, -1);
221             } catch (ServerException se) {
222                 LOG.error(url + ": Server Exception occurred discarding last build file cache: ", se);
223             }
224
225             LOG.info(url + ": " + modifications.size() + " modifications in " + nowRoot.getFolderHierarchy());
226             return modifications;
227         } catch (Exception JavaDoc e) {
228             LOG.error(url + ": Problem looking up modifications in StarTeam.", e);
229             modifications.clear();
230             return modifications;
231         } finally {
232             if (server != null) {
233                 server.disconnect();
234             }
235         }
236     }
237
238     /**
239      * Compare old and new file lists to determine what happened
240      */

241     private void compareFileLists(Map JavaDoc nowFiles, Map JavaDoc lastBuildFiles) {
242         for (Iterator JavaDoc iter = nowFiles.keySet().iterator(); iter.hasNext();) {
243             Integer JavaDoc currentItemID = (Integer JavaDoc) iter.next();
244             File currentFile = (File) nowFiles.get(currentItemID);
245
246             if (lastBuildFiles.containsKey(currentItemID)) {
247                 File lastBuildFile = (File) lastBuildFiles.get(currentItemID);
248
249                 if (fileHasBeenModified(currentFile, lastBuildFile)) {
250                     addRevision(currentFile, "modified");
251                 } else if (fileHasBeenMoved(currentFile, lastBuildFile)) {
252                     addRevision(currentFile, "moved");
253                 }
254                 // Remove the identified last build file from the list of
255
// last build files. It will make processing the delete
256
// check on the last builds quicker
257
lastBuildFiles.remove(currentItemID);
258             } else {
259                 // File is new
260
addRevision(currentFile, "new");
261             }
262         }
263         examineOldFiles(lastBuildFiles);
264     }
265
266     /**
267      * Now examine old files. They have to have been deleted as we know they
268      * are not in the new list from the processing above.
269      */

270     private void examineOldFiles(Map JavaDoc lastBuildFiles) {
271
272         // START - 1st Comment out if StarTeam 4.2 SP2 or older
273
if (canLookupDeletions && preloadFileInformation && !lastBuildFiles.isEmpty()) {
274             try {
275                 // properties to fetch immediately and cache
276
final String JavaDoc[] propertiesToCacheForDeletes =
277                     new String JavaDoc[] {
278                         stPropertyNames.AUDIT_CLASS_ID,
279                         stPropertyNames.AUDIT_OBJECT_ID,
280                         stPropertyNames.AUDIT_EVENT_ID,
281                         stPropertyNames.MODIFIED_TIME,
282                         stPropertyNames.AUDIT_USER_ID };
283
284                 lastBuildRoot.populateNow(stTypeNames.AUDIT, propertiesToCacheForDeletes, -1);
285             } catch (TypeNotFoundException tnfx) {
286                 LOG.debug(url + ": Error caching Audit information (StarTeam 4.2 SP2 SDK or older in use)."
287                         + " Deletions will be reported as by Unknown.", tnfx);
288                 canLookupDeletions = false;
289             }
290         }
291         // END - 1st Comment out if StarTeam 4.2 SP2 or older
292

293         for (Iterator JavaDoc iter = lastBuildFiles.values().iterator(); iter.hasNext();) {
294             File currentLastBuildFile = (File) iter.next();
295             addRevision((File) currentLastBuildFile.getFromHistoryByDate(nowDate), "deleted");
296         }
297     }
298
299     private boolean fileHasBeenModified(File currentFile, File lastBuildFile) {
300         return currentFile.getContentVersion() != lastBuildFile.getContentVersion();
301     }
302
303     private boolean fileHasBeenMoved(File currentFile, File lastBuildFile) {
304         return !currentFile.getParentFolder().getFolderHierarchy().equals(
305             lastBuildFile.getParentFolder().getFolderHierarchy());
306     }
307
308     private void addFolderModsToList(Map JavaDoc fileList, Folder folder) {
309         //try {
310
// Thread.sleep(100);
311
//} catch (InterruptedException ignoredInterruptedException) {}
312

313         Item[] files = folder.getItems(stTypeNames.FILE);
314         for (int i = 0; i < files.length; i++) {
315             File file = (File) files[i];
316             fileList.put(new Integer JavaDoc(file.getItemID()), file);
317         }
318
319         Folder[] folders = folder.getSubFolders();
320         for (int i = 0; i < folders.length; i++) {
321             addFolderModsToList(fileList, folders[i]);
322         }
323     }
324
325     /**
326      * Adds the revision to the modification set.
327      *
328      * @param revision
329      */

330     private void addRevision(File revision, String JavaDoc status) {
331
332         Modification mod = new Modification();
333         mod.type = "StarTeam";
334         String JavaDoc fileName = revision.getName();
335         Folder parentFolder = revision.getParentFolder();
336         String JavaDoc folderName = parentFolder.getFolderHierarchy();
337         if (folderName.length() > 0 && (folderName.endsWith("\\") || folderName.endsWith("/"))) {
338             folderName = folderName.substring(0, folderName.length() - 1);
339         }
340         Modification.ModifiedFile modFile = mod.createModifiedFile(fileName, folderName);
341         modFile.action = status;
342
343         User user = null;
344         if (property != null) {
345             properties.put(property, "true");
346         }
347         if (status.equals("deleted")) {
348             if (propertyOnDelete != null) {
349                 properties.put(propertyOnDelete, "true");
350             }
351
352             boolean foundAudit = false;
353
354             // START - 2nd Comment out if StarTeam 4.2 SP2 or older
355
if (canLookupDeletions) {
356                 try {
357                     Item[] audits = parentFolder.getItems(stTypeNames.AUDIT);
358                     for (int i = 0; i < audits.length && !foundAudit; i++) {
359                         com.starbase.starteam.Audit audit = (com.starbase.starteam.Audit) (audits[i]);
360                         if (audit.getItemDescriptor().equals(fileName) && (audit.getEnumDisplayName(
361                                 stPropertyNames.AUDIT_EVENT_ID, audit.getInt(stPropertyNames.AUDIT_EVENT_ID)).equals(
362                                 "Deleted"))) {
363                             foundAudit = true;
364                             mod.modifiedTime = audit.getModifiedTime().createDate();
365                             user = server.getUser(audit.getInt(stPropertyNames.AUDIT_USER_ID));
366                             mod.userName = user.getName();
367                         }
368                     }
369                 } catch (TypeNotFoundException tnfx) {
370                     LOG.debug(url + ": Error looking up Audit information (StarTeam 4.2 SP2 SDK or older in use)."
371                             + " Deletions will be reported as by Unknown.", tnfx);
372                     canLookupDeletions = false;
373                 }
374             }
375             // END - 2nd Comment out if StarTeam 4.2 SP2 or older
376

377             if (!foundAudit) {
378                 mod.modifiedTime = revision.getModifiedTime().createDate();
379                 mod.userName = "Unknown";
380             }
381         } else {
382             mod.modifiedTime = revision.getModifiedTime().createDate();
383             user = server.getUser(revision.getModifiedBy());
384             mod.userName = user.getName();
385             mod.comment = revision.getComment();
386             mod.revision = "" + revision.getContentVersion();
387         }
388
389         // Only get emails for users still on the system
390
if (user != null && canLookupEmails) {
391
392             // Try to obtain email to add. This is only allowed if logged on
393
// user is SERVER ADMINISTRATOR
394
try {
395                 // check if user account exists
396
UserAccount useracct =
397                         server.getAdministration().findUserAccount(user.getID());
398                 if (useracct == null) {
399                     LOG.warn(url + ": User account for " + user.getName() + " with ID " + user.getID() + " not found.");
400                 } else {
401                     mod.emailAddress = useracct.getEmailAddress();
402                 }
403             } catch (ServerException sx) {
404                 // Logged on user does not have permission to get user's email.
405
// Return the modifying user's name instead. Then use the
406
// email.properties file to map the name to an email address
407
// outside of StarTeam
408
LOG.debug(url + ": Error looking up user email address.", sx);
409                 canLookupEmails = false;
410             }
411         }
412
413         modifications.add(mod);
414     }
415
416 }
417
Popular Tags