Correct reference to EPL in source headers
[egit/chris.git] / org.eclipse.egit.core / src / org / eclipse / egit / core / GitMoveDeleteHook.java
blob18842154930c09ac2b2e45733c617883aa6f2f25
1 /*******************************************************************************
2 * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
3 * Copyright (C) 2007, Shawn O. Pearce <spearce@spearce.org>
4 * Copyright (C) 2008, Google Inc.
6 * All rights reserved. This program and the accompanying materials
7 * are made available under the terms of the Eclipse Public License v1.0
8 * which accompanies this distribution, and is available at
9 * http://www.eclipse.org/legal/epl-v10.html
10 *******************************************************************************/
11 package org.eclipse.egit.core;
13 import java.io.IOException;
15 import org.eclipse.core.resources.IFile;
16 import org.eclipse.core.resources.IFolder;
17 import org.eclipse.core.resources.IProject;
18 import org.eclipse.core.resources.IProjectDescription;
19 import org.eclipse.core.resources.IResource;
20 import org.eclipse.core.resources.team.IMoveDeleteHook;
21 import org.eclipse.core.resources.team.IResourceTree;
22 import org.eclipse.core.runtime.Assert;
23 import org.eclipse.core.runtime.IProgressMonitor;
24 import org.eclipse.core.runtime.IStatus;
25 import org.eclipse.core.runtime.Status;
26 import org.eclipse.egit.core.project.GitProjectData;
27 import org.eclipse.egit.core.project.RepositoryMapping;
28 import org.spearce.jgit.dircache.DirCache;
29 import org.spearce.jgit.dircache.DirCacheBuilder;
30 import org.spearce.jgit.dircache.DirCacheEditor;
31 import org.spearce.jgit.dircache.DirCacheEntry;
33 class GitMoveDeleteHook implements IMoveDeleteHook {
34 private static final boolean I_AM_DONE = true;
36 private static final boolean FINISH_FOR_ME = false;
38 private final GitProjectData data;
40 GitMoveDeleteHook(final GitProjectData d) {
41 Assert.isNotNull(d);
42 data = d;
45 public boolean deleteFile(final IResourceTree tree, final IFile file,
46 final int updateFlags, final IProgressMonitor monitor) {
47 final boolean force = (updateFlags & IResource.FORCE) == IResource.FORCE;
48 if (!force && !tree.isSynchronized(file, IResource.DEPTH_ZERO))
49 return false;
51 final RepositoryMapping map = RepositoryMapping.getMapping(file);
52 if (map == null)
53 return false;
55 try {
56 final DirCache dirc = DirCache.lock(map.getRepository());
57 final int first = dirc.findEntry(map.getRepoRelativePath(file));
58 if (first < 0) {
59 dirc.unlock();
60 return false;
63 final DirCacheBuilder edit = dirc.builder();
64 if (first > 0)
65 edit.keep(0, first);
66 final int next = dirc.nextEntry(first);
67 if (next < dirc.getEntryCount())
68 edit.keep(next, dirc.getEntryCount() - next);
69 if (!edit.commit())
70 tree.failed(new Status(IStatus.ERROR, Activator.getPluginId(),
71 0, CoreText.MoveDeleteHook_operationError, null));
72 tree.standardDeleteFile(file, updateFlags, monitor);
73 } catch (IOException e) {
74 tree.failed(new Status(IStatus.ERROR, Activator.getPluginId(), 0,
75 CoreText.MoveDeleteHook_operationError, e));
77 return true;
80 public boolean deleteFolder(final IResourceTree tree, final IFolder folder,
81 final int updateFlags, final IProgressMonitor monitor) {
82 // Deleting a GIT repository which is in use is a pretty bad idea. To
83 // delete disconnect the team provider first.
85 if (data.isProtected(folder)) {
86 return cannotModifyRepository(tree);
87 } else {
88 return FINISH_FOR_ME;
92 public boolean deleteProject(final IResourceTree tree,
93 final IProject project, final int updateFlags,
94 final IProgressMonitor monitor) {
95 // TODO: Note that eclipse thinks folders are real, while
96 // Git does not care.
97 return FINISH_FOR_ME;
100 public boolean moveFile(final IResourceTree tree, final IFile srcf,
101 final IFile dstf, final int updateFlags,
102 final IProgressMonitor monitor) {
103 final boolean force = (updateFlags & IResource.FORCE) == IResource.FORCE;
104 if (!force && !tree.isSynchronized(srcf, IResource.DEPTH_ZERO))
105 return false;
107 final RepositoryMapping srcm = RepositoryMapping.getMapping(srcf);
108 if (srcm == null)
109 return false;
110 final RepositoryMapping dstm = RepositoryMapping.getMapping(dstf);
112 try {
113 final DirCache sCache = DirCache.lock(srcm.getRepository());
114 final String sPath = srcm.getRepoRelativePath(srcf);
115 final DirCacheEntry sEnt = sCache.getEntry(sPath);
116 if (sEnt == null) {
117 sCache.unlock();
118 return false;
121 final DirCacheEditor sEdit = sCache.editor();
122 sEdit.add(new DirCacheEditor.DeletePath(sEnt));
123 if (dstm != null && dstm.getRepository() == srcm.getRepository()) {
124 final String dPath = srcm.getRepoRelativePath(dstf);
125 sEdit.add(new DirCacheEditor.PathEdit(dPath) {
126 @Override
127 public void apply(final DirCacheEntry dEnt) {
128 dEnt.copyMetaData(sEnt);
132 if (!sEdit.commit())
133 tree.failed(new Status(IStatus.ERROR, Activator.getPluginId(),
134 0, CoreText.MoveDeleteHook_operationError, null));
136 tree.standardMoveFile(srcf, dstf, updateFlags, monitor);
137 } catch (IOException e) {
138 tree.failed(new Status(IStatus.ERROR, Activator.getPluginId(), 0,
139 CoreText.MoveDeleteHook_operationError, e));
141 return true;
144 public boolean moveFolder(final IResourceTree tree, final IFolder srcf,
145 final IFolder dstf, final int updateFlags,
146 final IProgressMonitor monitor) {
147 final boolean force = (updateFlags & IResource.FORCE) == IResource.FORCE;
148 if (!force && !tree.isSynchronized(srcf, IResource.DEPTH_ZERO))
149 return false;
151 final RepositoryMapping srcm = RepositoryMapping.getMapping(srcf);
152 if (srcm == null)
153 return false;
154 final RepositoryMapping dstm = RepositoryMapping.getMapping(dstf);
156 try {
157 final DirCache sCache = DirCache.lock(srcm.getRepository());
158 final String sPath = srcm.getRepoRelativePath(srcf);
159 final DirCacheEntry[] sEnt = sCache.getEntriesWithin(sPath);
160 if (sEnt.length == 0) {
161 sCache.unlock();
162 return false;
165 final DirCacheEditor sEdit = sCache.editor();
166 sEdit.add(new DirCacheEditor.DeleteTree(sPath));
167 if (dstm != null && dstm.getRepository() == srcm.getRepository()) {
168 final String dPath = srcm.getRepoRelativePath(dstf) + "/";
169 final int sPathLen = sPath.length() + 1;
170 for (final DirCacheEntry se : sEnt) {
171 final String p = se.getPathString().substring(sPathLen);
172 sEdit.add(new DirCacheEditor.PathEdit(dPath + p) {
173 @Override
174 public void apply(final DirCacheEntry dEnt) {
175 dEnt.copyMetaData(se);
180 if (!sEdit.commit())
181 tree.failed(new Status(IStatus.ERROR, Activator.getPluginId(),
182 0, CoreText.MoveDeleteHook_operationError, null));
184 tree.standardMoveFolder(srcf, dstf, updateFlags, monitor);
185 } catch (IOException e) {
186 tree.failed(new Status(IStatus.ERROR, Activator.getPluginId(), 0,
187 CoreText.MoveDeleteHook_operationError, e));
189 return true;
192 public boolean moveProject(final IResourceTree tree, final IProject source,
193 final IProjectDescription description, final int updateFlags,
194 final IProgressMonitor monitor) {
195 // TODO: We should be able to do this without too much effort when the
196 // projects belong to the same Git repository.
197 return FINISH_FOR_ME;
200 private boolean cannotModifyRepository(final IResourceTree tree) {
201 tree.failed(new Status(IStatus.ERROR, Activator.getPluginId(), 0,
202 CoreText.MoveDeleteHook_cannotModifyFolder, null));
203 return I_AM_DONE;