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 * See LICENSE for the full license text, also available.
9 *******************************************************************************/
10 package org
.spearce
.egit
.core
;
12 import java
.io
.IOException
;
14 import org
.eclipse
.core
.resources
.IFile
;
15 import org
.eclipse
.core
.resources
.IFolder
;
16 import org
.eclipse
.core
.resources
.IProject
;
17 import org
.eclipse
.core
.resources
.IProjectDescription
;
18 import org
.eclipse
.core
.resources
.IResource
;
19 import org
.eclipse
.core
.resources
.team
.IMoveDeleteHook
;
20 import org
.eclipse
.core
.resources
.team
.IResourceTree
;
21 import org
.eclipse
.core
.runtime
.Assert
;
22 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
23 import org
.eclipse
.core
.runtime
.IStatus
;
24 import org
.eclipse
.core
.runtime
.Status
;
25 import org
.spearce
.egit
.core
.project
.GitProjectData
;
26 import org
.spearce
.egit
.core
.project
.RepositoryMapping
;
27 import org
.spearce
.jgit
.dircache
.DirCache
;
28 import org
.spearce
.jgit
.dircache
.DirCacheBuilder
;
29 import org
.spearce
.jgit
.dircache
.DirCacheEditor
;
30 import org
.spearce
.jgit
.dircache
.DirCacheEntry
;
32 class GitMoveDeleteHook
implements IMoveDeleteHook
{
33 private static final boolean I_AM_DONE
= true;
35 private static final boolean FINISH_FOR_ME
= false;
37 private final GitProjectData data
;
39 GitMoveDeleteHook(final GitProjectData d
) {
44 public boolean deleteFile(final IResourceTree tree
, final IFile file
,
45 final int updateFlags
, final IProgressMonitor monitor
) {
46 final boolean force
= (updateFlags
& IResource
.FORCE
) == IResource
.FORCE
;
47 if (!force
&& !tree
.isSynchronized(file
, IResource
.DEPTH_ZERO
))
50 final RepositoryMapping map
= RepositoryMapping
.getMapping(file
);
55 final DirCache dirc
= DirCache
.lock(map
.getRepository());
56 final int first
= dirc
.findEntry(map
.getRepoRelativePath(file
));
62 final DirCacheBuilder edit
= dirc
.builder();
65 final int next
= dirc
.nextEntry(first
);
66 if (next
< dirc
.getEntryCount())
67 edit
.keep(next
, dirc
.getEntryCount() - next
);
69 tree
.failed(new Status(IStatus
.ERROR
, Activator
.getPluginId(),
70 0, CoreText
.MoveDeleteHook_operationError
, null));
71 tree
.standardDeleteFile(file
, updateFlags
, monitor
);
72 } catch (IOException e
) {
73 tree
.failed(new Status(IStatus
.ERROR
, Activator
.getPluginId(), 0,
74 CoreText
.MoveDeleteHook_operationError
, e
));
79 public boolean deleteFolder(final IResourceTree tree
, final IFolder folder
,
80 final int updateFlags
, final IProgressMonitor monitor
) {
81 // Deleting a GIT repository which is in use is a pretty bad idea. To
82 // delete disconnect the team provider first.
84 if (data
.isProtected(folder
)) {
85 return cannotModifyRepository(tree
);
91 public boolean deleteProject(final IResourceTree tree
,
92 final IProject project
, final int updateFlags
,
93 final IProgressMonitor monitor
) {
94 // TODO: Note that eclipse thinks folders are real, while
99 public boolean moveFile(final IResourceTree tree
, final IFile srcf
,
100 final IFile dstf
, final int updateFlags
,
101 final IProgressMonitor monitor
) {
102 final boolean force
= (updateFlags
& IResource
.FORCE
) == IResource
.FORCE
;
103 if (!force
&& !tree
.isSynchronized(srcf
, IResource
.DEPTH_ZERO
))
106 final RepositoryMapping srcm
= RepositoryMapping
.getMapping(srcf
);
109 final RepositoryMapping dstm
= RepositoryMapping
.getMapping(dstf
);
112 final DirCache sCache
= DirCache
.lock(srcm
.getRepository());
113 final String sPath
= srcm
.getRepoRelativePath(srcf
);
114 final DirCacheEntry sEnt
= sCache
.getEntry(sPath
);
120 final DirCacheEditor sEdit
= sCache
.editor();
121 sEdit
.add(new DirCacheEditor
.DeletePath(sEnt
));
122 if (dstm
!= null && dstm
.getRepository() == srcm
.getRepository()) {
123 final String dPath
= srcm
.getRepoRelativePath(dstf
);
124 sEdit
.add(new DirCacheEditor
.PathEdit(dPath
) {
126 public void apply(final DirCacheEntry dEnt
) {
127 dEnt
.copyMetaData(sEnt
);
132 tree
.failed(new Status(IStatus
.ERROR
, Activator
.getPluginId(),
133 0, CoreText
.MoveDeleteHook_operationError
, null));
135 tree
.standardMoveFile(srcf
, dstf
, updateFlags
, monitor
);
136 } catch (IOException e
) {
137 tree
.failed(new Status(IStatus
.ERROR
, Activator
.getPluginId(), 0,
138 CoreText
.MoveDeleteHook_operationError
, e
));
143 public boolean moveFolder(final IResourceTree tree
, final IFolder srcf
,
144 final IFolder dstf
, final int updateFlags
,
145 final IProgressMonitor monitor
) {
146 final boolean force
= (updateFlags
& IResource
.FORCE
) == IResource
.FORCE
;
147 if (!force
&& !tree
.isSynchronized(srcf
, IResource
.DEPTH_ZERO
))
150 final RepositoryMapping srcm
= RepositoryMapping
.getMapping(srcf
);
153 final RepositoryMapping dstm
= RepositoryMapping
.getMapping(dstf
);
156 final DirCache sCache
= DirCache
.lock(srcm
.getRepository());
157 final String sPath
= srcm
.getRepoRelativePath(srcf
);
158 final DirCacheEntry
[] sEnt
= sCache
.getEntriesWithin(sPath
);
159 if (sEnt
.length
== 0) {
164 final DirCacheEditor sEdit
= sCache
.editor();
165 sEdit
.add(new DirCacheEditor
.DeleteTree(sPath
));
166 if (dstm
!= null && dstm
.getRepository() == srcm
.getRepository()) {
167 final String dPath
= srcm
.getRepoRelativePath(dstf
) + "/";
168 final int sPathLen
= sPath
.length() + 1;
169 for (final DirCacheEntry se
: sEnt
) {
170 final String p
= se
.getPathString().substring(sPathLen
);
171 sEdit
.add(new DirCacheEditor
.PathEdit(dPath
+ p
) {
173 public void apply(final DirCacheEntry dEnt
) {
174 dEnt
.copyMetaData(se
);
180 tree
.failed(new Status(IStatus
.ERROR
, Activator
.getPluginId(),
181 0, CoreText
.MoveDeleteHook_operationError
, null));
183 tree
.standardMoveFolder(srcf
, dstf
, updateFlags
, monitor
);
184 } catch (IOException e
) {
185 tree
.failed(new Status(IStatus
.ERROR
, Activator
.getPluginId(), 0,
186 CoreText
.MoveDeleteHook_operationError
, e
));
191 public boolean moveProject(final IResourceTree tree
, final IProject source
,
192 final IProjectDescription description
, final int updateFlags
,
193 final IProgressMonitor monitor
) {
194 // TODO: We should be able to do this without too much effort when the
195 // projects belong to the same Git repository.
196 return FINISH_FOR_ME
;
199 private boolean cannotModifyRepository(final IResourceTree tree
) {
200 tree
.failed(new Status(IStatus
.ERROR
, Activator
.getPluginId(), 0,
201 CoreText
.MoveDeleteHook_cannotModifyFolder
, null));