Package net.sourceforge.cruisecontrol.sourcecontrols

Source Code of net.sourceforge.cruisecontrol.sourcecontrols.StarTeam

/********************************************************************************
* CruiseControl, a Continuous Integration Toolkit
* Copyright (c) 2001, ThoughtWorks, Inc.
* 651 W Washington Ave. Suite 600
* Chicago, IL 60661 USA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
*     + Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*
*     + Redistributions in binary form must reproduce the above
*       copyright notice, this list of conditions and the following
*       disclaimer in the documentation and/or other materials provided
*       with the distribution.
*
*     + Neither the name of ThoughtWorks, Inc., CruiseControl, nor the
*       names of its contributors may be used to endorse or promote
*       products derived from this software without specific prior
*       written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
********************************************************************************/
package net.sourceforge.cruisecontrol.sourcecontrols;

import com.starbase.starteam.File;
import com.starbase.starteam.Folder;
import com.starbase.starteam.Item;
import com.starbase.starteam.PropertyNames;
import com.starbase.starteam.Server;
import com.starbase.starteam.ServerException;
import com.starbase.starteam.StarTeamFinder;
import com.starbase.starteam.User;
import com.starbase.starteam.UserAccount;
import com.starbase.starteam.View;
import com.starbase.starteam.ViewConfiguration;
import com.starbase.util.OLEDate;
import net.sourceforge.cruisecontrol.CruiseControlException;
import net.sourceforge.cruisecontrol.Modification;
import net.sourceforge.cruisecontrol.SourceControl;
import net.sourceforge.cruisecontrol.util.ValidationHelper;
import org.apache.log4j.Logger;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
* This class logs into StarTeam and collects information on any modifications
* made since the last successful build.
*
* @author Christopher Charlier -- ThoughtWorks Inc. 2001
* @author <a href="mailto:jcyip@thoughtworks.com">Jason Yip</a>
* @author Neill
*/
public class StarTeam implements SourceControl {

    private static final Logger LOG = Logger.getLogger(StarTeam.class);

    private String userName;
    private String password;
    private String folder;
    private String url;
    private List modifications = new ArrayList();
    private OLEDate nowDate;

    private Hashtable properties = new Hashtable();
    private String property;
    private String propertyOnDelete;

    private boolean preloadFileInformation = true;
    private boolean canLookupEmails = true;

    /**
     * Set StarTeam user name
     */
    public void setUsername(String userName) {
        this.userName = userName;
    }

    /**
     * Set password for StarTeam user
     */
    public void setPassword(String password) {
        this.password = password;
    }

    /**
     * Set repository folder
     */
    public void setFolder(String folder) {
        this.folder = folder;
    }

    public void setPreloadFileInformation(boolean preloadFileInformation) {
        this.preloadFileInformation = preloadFileInformation;
    }

    public void setStarteamurl(String url) {
        this.url = url;
    }

    public void setProperty(String property) {
        this.property = property;
    }

    public void setPropertyOnDelete(String propertyOnDelete) {
        this.propertyOnDelete = propertyOnDelete;
    }

    public Hashtable getProperties() {
        return properties;
    }

    public void validate() throws CruiseControlException {
        ValidationHelper.assertIsSet(folder, "folder", this.getClass());
        ValidationHelper.assertIsSet(url, "url", this.getClass());
        ValidationHelper.assertIsSet(userName, "username", this.getClass());
        ValidationHelper.assertIsSet(password, "password", this.getClass());
    }

    /**
     * Populates the modification set with all appropriate information based on
     * the changes since the last successful build.
     */
    public List getModifications(Date lastBuild, Date now) {
        // Clean out the modifications list.  Otherwise we get duplicate entries
        // when this function is called more than once in a quiet period breach
        // We normally would need to clean out the email list as well, except we
        // know that all entries in current list will still be required
        modifications.clear();

        // Store OLEDate equivalents of now and lastbuild for performance
        nowDate = new OLEDate(now.getTime());
        OLEDate lastBuildDate = new OLEDate(lastBuild.getTime());

        Server server = null;
        try {
            // Set up two view snapshots, one at lastbuild time, one now
            View view = StarTeamFinder.openView(userName + ":" + password + "@" + url);
            server = view.getServer();

            View snapshotAtNow = new View(view, ViewConfiguration.createFromTime(nowDate));
            View snapshotAtLastBuild =
                new View(view, ViewConfiguration.createFromTime(lastBuildDate));

            Map nowFiles = new HashMap();
            Map lastBuildFiles = new HashMap();

            Folder nowRoot = StarTeamFinder.findFolder(snapshotAtNow.getRootFolder(), folder);

            PropertyNames stPropertyNames = server.getPropertyNames();
            // properties to fetch immediately and cache
            final String[] propertiesToCache =
                new String[] {
                    stPropertyNames.FILE_CONTENT_REVISION,
                    stPropertyNames.MODIFIED_TIME,
                    stPropertyNames.FILE_FILE_TIME_AT_CHECKIN,
                    stPropertyNames.COMMENT,
                    stPropertyNames.MODIFIED_USER_ID,
                    stPropertyNames.FILE_NAME };

            if (preloadFileInformation) {
                // cache information for now
                nowRoot.populateNow(server.getTypeNames().FILE, propertiesToCache, -1);
            }

            // Visit all files in the snapshots and add to Maps
            addFolderModsToList(nowFiles, nowRoot);

            try {
                Folder lastBuildRoot =
                    StarTeamFinder.findFolder(snapshotAtLastBuild.getRootFolder(), folder);

                if (preloadFileInformation) {
                    // cache information for last build
                    lastBuildRoot.populateNow(server.getTypeNames().FILE, propertiesToCache, -1);
                }

                addFolderModsToList(lastBuildFiles, lastBuildRoot);
            } catch (ServerException se) {
                LOG.error("Server Exception occurred visiting last build view: ", se);
            }

            compareFileLists(nowFiles, lastBuildFiles);

            // Discard cached items so memory is not eaten up
            snapshotAtNow.getRootFolder().discardItems(server.getTypeNames().FILE, -1);

            try {
                snapshotAtLastBuild.getRootFolder().discardItems(server.getTypeNames().FILE, -1);
            } catch (ServerException se) {
                LOG.error("Server Exception occurred discarding last build file cache: ", se);
            }

            LOG.info(modifications.size() + " modifications in " + folder);
            return modifications;
        } catch (Exception e) {
            LOG.error("Problem looking up modifications in StarTeam.", e);
            modifications.clear();
            return modifications;
        } finally {
            if (server != null) {
                server.disconnect();
            }
        }
    }

    /**
     * Compare old and new file lists to determine what happened
     */
    private void compareFileLists(Map nowFiles, Map lastBuildFiles) {
        for (Iterator iter = nowFiles.keySet().iterator(); iter.hasNext();) {
            Integer currentItemID = (Integer) iter.next();
            File currentFile = (File) nowFiles.get(currentItemID);

            if (lastBuildFiles.containsKey(currentItemID)) {
                File lastBuildFile = (File) lastBuildFiles.get(currentItemID);

                if (fileHasBeenModified(currentFile, lastBuildFile)) {
                    addRevision(currentFile, "modified");
                } else if (fileHasBeenMoved(currentFile, lastBuildFile)) {
                    addRevision(currentFile, "moved");
                }
                // Remove the identified last build file from the list of
                // last build files.  It will make processing the delete
                // check on the last builds quicker
                lastBuildFiles.remove(currentItemID);
            } else {
                // File is new
                addRevision(currentFile, "new");
            }
        }
        examineOldFiles(lastBuildFiles);
    }

    /**
     * Now examine old files.  They have to have been deleted as we know they
     * are not in the new list from the processing above.
     */
    private void examineOldFiles(Map lastBuildFiles) {
        for (Iterator iter = lastBuildFiles.values().iterator(); iter.hasNext();) {
            File currentLastBuildFile = (File) iter.next();
            addRevision((File) currentLastBuildFile.getFromHistoryByDate(nowDate), "deleted");
        }
    }

    private boolean fileHasBeenModified(File currentFile, File lastBuildFile) {
        return currentFile.getContentVersion() != lastBuildFile.getContentVersion();
    }

    private boolean fileHasBeenMoved(File currentFile, File lastBuildFile) {
        return !currentFile.getParentFolder().getFolderHierarchy().equals(
            lastBuildFile.getParentFolder().getFolderHierarchy());
    }

    private void addFolderModsToList(Map fileList, Folder folder) {
        //try {
        //    Thread.sleep(100);
        //} catch (InterruptedException ignoredInterruptedException) {}

        Item[] files = folder.getItems("File");
        for (int i = 0; i < files.length; i++) {
            File file = (File) files[i];
            fileList.put(new Integer(file.getItemID()), file);
        }

        Folder[] folders = folder.getSubFolders();
        for (int i = 0; i < folders.length; i++) {
            addFolderModsToList(fileList, folders[i]);
        }
    }

    /**
     * Adds the revision to the modification set.
     *
     * @param revision
     */
    private void addRevision(File revision, String status) {
        User user = revision.getServer().getUser(revision.getModifiedBy());

        if ((user != null) && (user.getName().equals("BuildMaster"))) {
            return;
        }

        Modification mod = new Modification();
        mod.type = "StarTeam";
        String fileName = revision.getName();
        String folderName = revision.getParentFolder().getFolderHierarchy();
        Modification.ModifiedFile modFile = mod.createModifiedFile(fileName, folderName);
        modFile.action = status;
        mod.modifiedTime = revision.getModifiedTime().createDate();
        mod.userName = user.getName();
        mod.comment = revision.getComment();

        //  Only get emails for users still on the system
        if (user != null && canLookupEmails) {

            // Try to obtain email to add.  This is only allowed if logged on
            // user is SERVER ADMINISTRATOR
            try {
                // check if user account exists
                UserAccount useracct =
                    user.getServer().getAdministration().findUserAccount(user.getID());
                if (useracct == null) {
                    LOG.warn("User account " + user.getID() + " not found for email address.");
                } else {
                    mod.emailAddress = useracct.getEmailAddress();
                }
            } catch (ServerException sx) {
                // Logged on user does not have permission to get user's email.
                // Return the modifying user's name instead. Then use the
                // email.properties file to map the name to an email address
                // outside of StarTeam
                LOG.debug("Error looking up user email address.", sx);
                canLookupEmails = false;
            }
        }

        modifications.add(mod);
        if (status.equals("deleted")) {
            if (propertyOnDelete != null) {
                properties.put(propertyOnDelete, "true");
            }
        }
        if (property != null) {
            properties.put(property, "true");
        }
    }

}
TOP

Related Classes of net.sourceforge.cruisecontrol.sourcecontrols.StarTeam

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.