1 /*******************************************************************************
2 * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
3 * Copyright (C) 2007, Shawn O. Pearce <spearce@spearce.org>
5 * All rights reserved. This program and the accompanying materials
6 * are made available under the terms of the Eclipse Public License v1.0
7 * See LICENSE for the full license text, also available.
8 *******************************************************************************/
9 package org
.spearce
.egit
.core
;
11 import java
.io
.IOException
;
13 import org
.eclipse
.core
.resources
.IFile
;
14 import org
.eclipse
.core
.resources
.IFolder
;
15 import org
.eclipse
.core
.resources
.IProject
;
16 import org
.eclipse
.core
.resources
.IProjectDescription
;
17 import org
.eclipse
.core
.resources
.IResource
;
18 import org
.eclipse
.core
.resources
.team
.IMoveDeleteHook
;
19 import org
.eclipse
.core
.resources
.team
.IResourceTree
;
20 import org
.eclipse
.core
.runtime
.Assert
;
21 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
22 import org
.eclipse
.core
.runtime
.IStatus
;
23 import org
.eclipse
.core
.runtime
.Status
;
24 import org
.spearce
.egit
.core
.project
.GitProjectData
;
25 import org
.spearce
.egit
.core
.project
.RepositoryMapping
;
26 import org
.spearce
.jgit
.dircache
.DirCache
;
27 import org
.spearce
.jgit
.dircache
.DirCacheBuilder
;
28 import org
.spearce
.jgit
.dircache
.DirCacheEditor
;
29 import org
.spearce
.jgit
.dircache
.DirCacheEntry
;
31 class GitMoveDeleteHook
implements IMoveDeleteHook
{
32 private static final boolean I_AM_DONE
= true;
34 private static final boolean FINISH_FOR_ME
= false;
36 private final GitProjectData data
;
38 GitMoveDeleteHook(final GitProjectData d
) {
43 public boolean deleteFile(final IResourceTree tree
, final IFile file
,
44 final int updateFlags
, final IProgressMonitor monitor
) {
45 final boolean force
= (updateFlags
& IResource
.FORCE
) == IResource
.FORCE
;
46 if (!force
&& !tree
.isSynchronized(file
, IResource
.DEPTH_ZERO
))
49 final RepositoryMapping map
= RepositoryMapping
.getMapping(file
);
54 final DirCache dirc
= DirCache
.lock(map
.getRepository());
55 final int first
= dirc
.findEntry(map
.getRepoRelativePath(file
));
61 final DirCacheBuilder edit
= dirc
.builder();
64 final int next
= dirc
.nextEntry(first
);
65 if (next
< dirc
.getEntryCount())
66 edit
.keep(next
, dirc
.getEntryCount() - next
);
68 tree
.failed(new Status(IStatus
.ERROR
, Activator
.getPluginId(),
69 0, CoreText
.MoveDeleteHook_operationError
, null));
70 tree
.standardDeleteFile(file
, updateFlags
, monitor
);
71 } catch (IOException e
) {
72 tree
.failed(new Status(IStatus
.ERROR
, Activator
.getPluginId(), 0,
73 CoreText
.MoveDeleteHook_operationError
, e
));
78 public boolean deleteFolder(final IResourceTree tree
, final IFolder folder
,
79 final int updateFlags
, final IProgressMonitor monitor
) {
80 // Deleting a GIT repository which is in use is a pretty bad idea. To
81 // delete disconnect the team provider first.
83 if (data
.isProtected(folder
)) {
84 return cannotModifyRepository(tree
);
90 public boolean deleteProject(final IResourceTree tree
,
91 final IProject project
, final int updateFlags
,
92 final IProgressMonitor monitor
) {
93 // TODO: Note that eclipse thinks folders are real, while
98 public boolean moveFile(final IResourceTree tree
, final IFile srcf
,
99 final IFile dstf
, final int updateFlags
,
100 final IProgressMonitor monitor
) {
101 final boolean force
= (updateFlags
& IResource
.FORCE
) == IResource
.FORCE
;
102 if (!force
&& !tree
.isSynchronized(srcf
, IResource
.DEPTH_ZERO
))
105 final RepositoryMapping srcm
= RepositoryMapping
.getMapping(srcf
);
108 final RepositoryMapping dstm
= RepositoryMapping
.getMapping(dstf
);
111 final DirCache sCache
= DirCache
.lock(srcm
.getRepository());
112 final String sPath
= srcm
.getRepoRelativePath(srcf
);
113 final DirCacheEntry sEnt
= sCache
.getEntry(sPath
);
119 final DirCacheEditor sEdit
= sCache
.editor();
120 sEdit
.add(new DirCacheEditor
.DeletePath(sEnt
));
121 if (dstm
!= null && dstm
.getRepository() == srcm
.getRepository()) {
122 final String dPath
= srcm
.getRepoRelativePath(dstf
);
123 sEdit
.add(new DirCacheEditor
.PathEdit(dPath
) {
125 public void apply(final DirCacheEntry dEnt
) {
126 dEnt
.copyMetaData(sEnt
);
131 tree
.failed(new Status(IStatus
.ERROR
, Activator
.getPluginId(),
132 0, CoreText
.MoveDeleteHook_operationError
, null));
134 tree
.standardMoveFile(srcf
, dstf
, updateFlags
, monitor
);
135 } catch (IOException e
) {
136 tree
.failed(new Status(IStatus
.ERROR
, Activator
.getPluginId(), 0,
137 CoreText
.MoveDeleteHook_operationError
, e
));
142 public boolean moveFolder(final IResourceTree tree
, final IFolder source
,
143 final IFolder destination
, final int updateFlags
,
144 final IProgressMonitor monitor
) {
145 // TODO: Implement this. Should be relatively easy, but consider that
146 // Eclipse thinks folders are real thinsgs, while Git does not care.
147 return FINISH_FOR_ME
;
150 public boolean moveProject(final IResourceTree tree
, final IProject source
,
151 final IProjectDescription description
, final int updateFlags
,
152 final IProgressMonitor monitor
) {
153 // TODO: We should be able to do this without too much effort when the
154 // projects belong to the same Git repository.
155 return FINISH_FOR_ME
;
158 private boolean cannotModifyRepository(final IResourceTree tree
) {
159 tree
.failed(new Status(IStatus
.ERROR
, Activator
.getPluginId(), 0,
160 CoreText
.MoveDeleteHook_cannotModifyFolder
, null));