Java tutorial
/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 1997-2009 Sun Microsystems, Inc. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common * Development and Distribution License("CDDL") (collectively, the * "License"). You may not use this file except in compliance with the * License. You can obtain a copy of the License at * http://www.netbeans.org/cddl-gplv2.html * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the * specific language governing permissions and limitations under the * License. When distributing the software, include this License Header * Notice in each file and include the License file at * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this * particular file as subject to the "Classpath" exception as provided * by Sun in the GPL Version 2 section of the License file that * accompanied this code. If applicable, add the following below the * License Header, with the fields enclosed by brackets [] replaced by * your own identifying information: * "Portions Copyrighted [year] [name of copyright owner]" * * Contributor(s): * * The Original Software is NetBeans. The Initial Developer of the Original * Software is Sun Microsystems, Inc. Portions Copyright 1997-2009 Sun * Microsystems, Inc. All Rights Reserved. * Portions Copyright 2009 Alexander Coles (Ikonoklastik Productions). * * If you wish your version of this file to be governed by only the CDDL * or only the GPL Version 2, indicate your decision by adding * "[Contributor] elects to include this software in this distribution * under the [CDDL or GPL Version 2] license." If you do not indicate a * single choice of license, a recipient has the option to distribute * your version of this file under either the CDDL, the GPL Version 2 or * to extend the choice of license to its licensees as provided above. * However, if you add GPL Version 2 code and therefore, elected the GPL * Version 2 license, then the option applies only if the new code is * made subject to such option by the copyright holder. */ package org.nbgit.ui.clone; import java.awt.event.ActionEvent; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.net.URISyntaxException; import javax.swing.SwingUtilities; import org.nbgit.Git; import org.nbgit.GitProgressMonitor; import org.nbgit.GitProgressSupport; import org.nbgit.OutputLogger; import org.nbgit.ui.ContextAction; import org.nbgit.util.GitProjectUtils; import org.nbgit.util.GitUtils; import org.netbeans.api.project.Project; import org.netbeans.api.project.ProjectManager; import org.netbeans.modules.versioning.spi.VCSContext; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.openide.util.RequestProcessor; import org.eclipse.jgit.errors.NotSupportedException; import org.eclipse.jgit.errors.TransportException; import org.eclipse.jgit.lib.Commit; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.GitIndex; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.RefUpdate; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.Tree; import org.eclipse.jgit.lib.WorkDirCheckout; import org.eclipse.jgit.transport.FetchResult; import org.eclipse.jgit.transport.RefSpec; import org.eclipse.jgit.transport.RemoteConfig; import org.eclipse.jgit.transport.Transport; import org.eclipse.jgit.transport.URIish; public class CloneAction extends ContextAction { public CloneAction(String name, VCSContext context) { super(name, context); } @Override protected void performAction(ActionEvent event) { final File root = GitUtils.getRootFile(context); if (root == null) return; // Get unused Clone Folder name File tmp = root.getParentFile(); File projFile = GitUtils.getProjectFile(context); String folderName = root.getName(); Boolean projIsRepos = true; if (!root.equals(projFile)) { // Git Repository is not the same as project root projIsRepos = false; } for (int i = 0; i < 10000; i++) { if (!new File(tmp, folderName + "_clone" + i).exists()) { // NOI18N tmp = new File(tmp, folderName + "_clone" + i); // NOI18N break; } } Clone clone = new Clone(root, tmp); if (!clone.showDialog()) { return; } URIish source = null; try { source = new URIish(root.toURL()); } catch (MalformedURLException ex) { Exceptions.printStackTrace(ex); } performClone(source, clone.getTargetDir(), projIsRepos, projFile, true, true); } public static RequestProcessor.Task performClone(final URIish source, final File target, boolean projIsRepos, File projFile, boolean scanForProjects) { return performClone(source, target, projIsRepos, projFile, false, scanForProjects); } private static RequestProcessor.Task performClone(final URIish source, final File target, final Boolean projIsRepos, final File projFile, final boolean isLocalClone, final boolean scanForProjects) { RequestProcessor rp = Git.getInstance().getRequestProcessor(source.toString()); final GitProgressSupport support = new GitProgressSupport() { Repository repo = Git.getInstance().getRepository(target); @Override protected void perform() { String projName = (projFile != null) ? GitProjectUtils.getProjectName(projFile) : null; OutputLogger logger = getLogger(); try { if (projName != null) { logger.outputInRed( NbBundle.getMessage(CloneAction.class, "MSG_CLONE_FROM", projName, source)); // NOI18N logger.outputInRed( NbBundle.getMessage(CloneAction.class, "MSG_CLONE_TO", projName, target)); // NOI18N } else { logger.outputInRed( NbBundle.getMessage(CloneAction.class, "MSG_EXTERNAL_CLONE_FROM", source)); // NOI18N logger.outputInRed(NbBundle.getMessage(CloneAction.class, "MSG_EXTERNAL_CLONE_TO", target)); // NOI18N } logger.output(""); // NOI18N doInit(repo, source, logger); FetchResult r = doFetch(repo, logger); Ref branch = r.getAdvertisedRef(Constants.HEAD); if (branch == null) { this.cancel(); } doCheckout(repo, branch, logger); if (isLocalClone) { Git git = Git.getInstance(); ProjectManager projectManager = ProjectManager.getDefault(); File normalizedCloneFolder = FileUtil.normalizeFile(target); File cloneProjFile; if (!projIsRepos) { String name = (projFile != null) ? projFile.getAbsolutePath().substring(source.getPath().length() + 1) : target.getAbsolutePath(); cloneProjFile = new File(normalizedCloneFolder, name); } else { cloneProjFile = normalizedCloneFolder; } openProject(cloneProjFile, projectManager, git); } else if (scanForProjects) { CloneCompleted cc = new CloneCompleted(target); if (isCanceled()) { return; } cc.scanForProjects(this); } } catch (URISyntaxException usex) { notifyLater(usex); } catch (IOException ex) { notifyLater(ex); } finally { if (!isLocalClone) { logger.outputInRed(NbBundle.getMessage(CloneAction.class, "MSG_CLONE_DONE")); // NOI18N logger.output(""); // NOI18N } } } private void openProject(final File cloneProjFile, final ProjectManager projectManager, final Git git) { SwingUtilities.invokeLater(new Runnable() { public void run() { // Open and set focus on the cloned project if possible OutputLogger logger = getLogger(); try { FileObject cloneProj = FileUtil.toFileObject(cloneProjFile); Project proj = null; if (cloneProjFile != null && cloneProj != null) { proj = projectManager.findProject(cloneProj); } if (proj != null) { GitProjectUtils.openProject(proj, this, false); // TODO: GitModuleConfig.getDefault().getSetMainProject() git.versionedFilesChanged(); git.refreshAllAnnotations(); } else { logger.outputInRed(NbBundle.getMessage(CloneAction.class, "MSG_EXTERNAL_CLONE_PRJ_NOT_FOUND_CANT_SETASMAIN")); // NOI18N } } catch (IOException ioe) { notifyLater(ioe); } finally { logger.outputInRed(NbBundle.getMessage(CloneAction.class, "MSG_CLONE_DONE")); // NOI18N logger.output(""); // NOI18N } } }); } }; //support.setRepositoryRoot(source); return support.start(rp, source.toString(), org.openide.util.NbBundle.getMessage(CloneAction.class, "LBL_Clone_Progress", source)); // NO } public static void doInit(Repository repo, URIish uri, OutputLogger logger) throws IOException, URISyntaxException { repo.create(); repo.getConfig().setBoolean("core", null, "bare", false); repo.getConfig().save(); logger.output("Initialized empty Git repository in " + repo.getWorkDir().getAbsolutePath()); logger.flushLog(); // save remote final RemoteConfig rc = new RemoteConfig(repo.getConfig(), "origin"); rc.addURI(uri); rc.addFetchRefSpec(new RefSpec().setForceUpdate(true).setSourceDestination(Constants.R_HEADS + "*", Constants.R_REMOTES + "origin" + "/*")); rc.update(repo.getConfig()); repo.getConfig().save(); } public static FetchResult doFetch(Repository repo, OutputLogger logger) throws NotSupportedException, TransportException, URISyntaxException { final FetchResult r; final Transport tn = Transport.open(repo, "origin"); try { r = tn.fetch(new GitProgressMonitor(), null); } finally { tn.close(); } logger.output("--- Fetch Completed ---"); return r; } public static void doCheckout(Repository repo, Ref branch, OutputLogger logger) throws IOException { final GitIndex index = new GitIndex(repo); final Commit mapCommit = repo.mapCommit(branch.getObjectId()); final Tree tree = mapCommit.getTree(); final RefUpdate u; final WorkDirCheckout co; u = repo.updateRef(Constants.HEAD); u.setNewObjectId(mapCommit.getCommitId()); u.forceUpdate(); // checking out files co = new WorkDirCheckout(repo, repo.getWorkDir(), index, tree); co.checkout(); // writing index index.write(); } }