Java tutorial
/*********************************************************************************************** * Copyright (c) Microsoft Corporation All rights reserved. * * MIT License: * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. ***********************************************************************************************/ package com.microsoft.gittf.core.tasks; import java.net.URI; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.eclipse.jgit.dircache.DirCache; import org.eclipse.jgit.dircache.DirCacheCheckout; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.RefUpdate; import org.eclipse.jgit.lib.Repository; import com.microsoft.gittf.core.Messages; import com.microsoft.gittf.core.config.ChangesetCommitMap; import com.microsoft.gittf.core.interfaces.VersionControlService; import com.microsoft.gittf.core.tasks.framework.NullTaskProgressMonitor; import com.microsoft.gittf.core.tasks.framework.Task; import com.microsoft.gittf.core.tasks.framework.TaskExecutor; import com.microsoft.gittf.core.tasks.framework.TaskProgressDisplay; import com.microsoft.gittf.core.tasks.framework.TaskProgressMonitor; import com.microsoft.gittf.core.tasks.framework.TaskStatus; import com.microsoft.gittf.core.util.Check; import com.microsoft.gittf.core.util.ObjectIdUtil; import com.microsoft.gittf.core.util.RepositoryUtil; import com.microsoft.gittf.core.util.TfsBranchUtil; import com.microsoft.tfs.core.clients.versioncontrol.GetItemsOptions; import com.microsoft.tfs.core.clients.versioncontrol.soapextensions.Changeset; import com.microsoft.tfs.core.clients.versioncontrol.soapextensions.DeletedState; import com.microsoft.tfs.core.clients.versioncontrol.soapextensions.Item; import com.microsoft.tfs.core.clients.versioncontrol.soapextensions.ItemType; import com.microsoft.tfs.core.clients.versioncontrol.soapextensions.RecursionType; import com.microsoft.tfs.core.clients.versioncontrol.specs.version.ChangesetVersionSpec; import com.microsoft.tfs.core.clients.versioncontrol.specs.version.LatestVersionSpec; import com.microsoft.tfs.core.clients.versioncontrol.specs.version.VersionSpec; import com.microsoft.tfs.core.clients.workitem.WorkItemClient; public class CloneTask extends Task { private final URI serverURI; private final VersionControlService vcClient; private final String tfsPath; private final Repository repository; private final WorkItemClient witClient; private boolean bare; private VersionSpec versionSpec = LatestVersionSpec.INSTANCE; private int depth = 1; private boolean tag = true; private static final Log log = LogFactory.getLog(CloneTask.class); public CloneTask(final URI serverURI, final VersionControlService vcClient, final String tfsPath, final Repository repository) { this(serverURI, vcClient, tfsPath, repository, null); } public CloneTask(final URI serverURI, final VersionControlService vcClient, final String tfsPath, final Repository repository, final WorkItemClient witClient) { Check.notNull(serverURI, "serverURI"); //$NON-NLS-1$ Check.notNull(vcClient, "vcClient"); //$NON-NLS-1$ Check.notNullOrEmpty(tfsPath, "tfsPath"); //$NON-NLS-1$ Check.notNull(repository, "repository"); //$NON-NLS-1$ this.serverURI = serverURI; this.vcClient = vcClient; this.tfsPath = tfsPath; this.repository = repository; this.witClient = witClient; } public void setBare(final boolean bare) { this.bare = bare; } public boolean isBare() { return bare; } public void setVersionSpec(final VersionSpec versionSpec) { Check.notNull(versionSpec, "versionSpec"); //$NON-NLS-1$ this.versionSpec = versionSpec; } public VersionSpec getVersionSpec() { return versionSpec; } public void setDepth(final int depth) { Check.isTrue(depth >= 1, "depth >= 1"); //$NON-NLS-1$ this.depth = depth; } public int getDepth() { return depth; } public boolean getTag() { return tag; } public void setTag(final boolean tag) { this.tag = tag; } @Override public TaskStatus run(final TaskProgressMonitor progressMonitor) throws Exception { final String taskName = Messages.formatString("CloneTask.CloningFormat", //$NON-NLS-1$ tfsPath, bare ? repository.getDirectory().getAbsolutePath() : repository.getWorkTree().getAbsolutePath()); progressMonitor.beginTask(taskName, 1, TaskProgressDisplay.DISPLAY_PROGRESS.combine(TaskProgressDisplay.DISPLAY_SUBTASK_DETAIL)); /* * Query the changesets. */ /* See if this is an actual server path. */ final Item item = vcClient.getItem(tfsPath, versionSpec, DeletedState.NON_DELETED, GetItemsOptions.NONE); Check.notNull(item, "item"); //$NON-NLS-1$ if (item.getItemType() != ItemType.FOLDER) { return new TaskStatus(TaskStatus.ERROR, Messages.formatString("CloneTask.CannotCloneFileFormat", tfsPath)); //$NON-NLS-1$ } /* Determine the latest changeset on the server. */ final Changeset[] changesets = vcClient.queryHistory(tfsPath, versionSpec, 0, RecursionType.FULL, null, new ChangesetVersionSpec(0), versionSpec, depth, false, false, false, false); /* * Create and configure the repository. */ repository.create(bare); final ConfigureRepositoryTask configureTask = new ConfigureRepositoryTask(repository, serverURI, tfsPath); configureTask.setTag(tag); final TaskStatus configureStatus = new TaskExecutor(new NullTaskProgressMonitor()).execute(configureTask); if (!configureStatus.isOK()) { return configureStatus; } if (changesets.length > 0) { ObjectId lastCommitID = null; ObjectId lastTreeID = null; Item[] previousChangesetItems = null; /* * Download changesets. */ final int numberOfChangesetToDownload = changesets.length; progressMonitor.setWork(numberOfChangesetToDownload); for (int i = numberOfChangesetToDownload; i > 0; i--) { CreateCommitForChangesetVersionSpecTask commitTask = new CreateCommitForChangesetVersionSpecTask( repository, vcClient, changesets[i - 1], previousChangesetItems, lastCommitID, witClient); TaskStatus commitStatus = new TaskExecutor(progressMonitor.newSubTask(1)).execute(commitTask); if (!commitStatus.isOK()) { return commitStatus; } lastCommitID = commitTask.getCommitID(); lastTreeID = commitTask.getCommitTreeID(); previousChangesetItems = commitTask.getCommittedItems(); Check.notNull(lastCommitID, "lastCommitID"); //$NON-NLS-1$ Check.notNull(lastTreeID, "lastTreeID"); //$NON-NLS-1$ new ChangesetCommitMap(repository).setChangesetCommit(changesets[i - 1].getChangesetID(), commitTask.getCommitID()); progressMonitor.displayVerbose(Messages.formatString("CloneTask.ClonedFormat", //$NON-NLS-1$ Integer.toString(changesets[i - 1].getChangesetID()), ObjectIdUtil.abbreviate(repository, lastCommitID))); } progressMonitor.setDetail(Messages.getString("CloneTask.Finalizing")); //$NON-NLS-1$ /* Update master head reference */ RefUpdate ref = repository.updateRef(Constants.R_HEADS + Constants.MASTER); ref.setNewObjectId(lastCommitID); ref.update(); /* Create tfs branch */ TfsBranchUtil.create(repository, Constants.R_HEADS + Constants.MASTER); /* * Check out the cloned commit. */ if (!bare) { DirCache dirCache = repository.lockDirCache(); DirCacheCheckout checkout = new DirCacheCheckout(repository, dirCache, lastTreeID); checkout.checkout(); dirCache.unlock(); RepositoryUtil.fixFileAttributes(repository); } progressMonitor.endTask(); final int finalChangesetID = changesets[0].getChangesetID(); if (numberOfChangesetToDownload == 1) { progressMonitor.displayMessage(Messages.formatString("CloneTask.ClonedFormat", //$NON-NLS-1$ Integer.toString(finalChangesetID), ObjectIdUtil.abbreviate(repository, lastCommitID))); } else { progressMonitor.displayMessage(Messages.formatString("CloneTask.ClonedMultipleFormat", //$NON-NLS-1$ changesets.length, Integer.toString(finalChangesetID), ObjectIdUtil.abbreviate(repository, lastCommitID))); } } else { // the folder exists on the server but is empty progressMonitor.displayMessage(Messages.getString("CloneTask.NothingToDownload")); //$NON-NLS-1$ progressMonitor.displayMessage(Messages.formatString("CloneTask.ClonedFolderEmptyFormat", //$NON-NLS-1$ tfsPath)); } log.info("Clone task completed."); //$NON-NLS-1$ return TaskStatus.OK_STATUS; } }