refactor: simplify collection.toArray()
[egit/eclipse.git] / org.eclipse.egit.core / src / org / eclipse / egit / core / op / AssumeUnchangedOperation.java
blob8bc6e90cff10f22f84fef25e84f8956716086b7b
1 /*******************************************************************************
2 * Copyright (C) 2007, Robin Rosenberg <robin.rosenberg@dewire.com>
3 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
4 * Copyright (C) 2008, Google Inc.
5 * Copyright (C) 2010, Matthias Sohn <matthias.sohn@sap.com>
7 * All rights reserved. This program and the accompanying materials
8 * are made available under the terms of the Eclipse Public License 2.0
9 * which accompanies this distribution, and is available at
10 * https://www.eclipse.org/legal/epl-2.0/
12 * SPDX-License-Identifier: EPL-2.0
13 *******************************************************************************/
14 package org.eclipse.egit.core.op;
16 import java.io.IOException;
17 import java.util.Collection;
18 import java.util.Collections;
19 import java.util.IdentityHashMap;
20 import java.util.Map;
22 import org.eclipse.core.resources.IProject;
23 import org.eclipse.core.resources.IResource;
24 import org.eclipse.core.runtime.CoreException;
25 import org.eclipse.core.runtime.IPath;
26 import org.eclipse.core.runtime.IProgressMonitor;
27 import org.eclipse.core.runtime.Path;
28 import org.eclipse.core.runtime.SubMonitor;
29 import org.eclipse.core.runtime.jobs.ISchedulingRule;
30 import org.eclipse.egit.core.Activator;
31 import org.eclipse.egit.core.internal.CoreText;
32 import org.eclipse.egit.core.internal.job.RuleUtil;
33 import org.eclipse.egit.core.project.GitProjectData;
34 import org.eclipse.egit.core.project.RepositoryMapping;
35 import org.eclipse.jgit.dircache.DirCache;
36 import org.eclipse.jgit.dircache.DirCacheEntry;
37 import org.eclipse.jgit.lib.Repository;
38 import org.eclipse.osgi.util.NLS;
40 /**
41 * Tell JGit to ignore changes in selected files
43 public class AssumeUnchangedOperation implements IEGitOperation {
44 private final Collection<? extends IResource> rsrcList;
45 private final Collection<IPath> locations;
47 private Repository db;
49 private final IdentityHashMap<Repository, DirCache> caches;
51 private final boolean assumeUnchanged;
53 /**
54 * Create a new operation to ignore changes in tracked files
56 * @param rsrcs
57 * collection of {@link IResource}s which should be ignored when
58 * looking for changes or committing.
59 * @param assumeUnchanged
60 * {@code true} to set the assume-valid flag in the git index
61 * entry, {@code false} to unset the assume-valid flag in the git
62 * index entry
64 public AssumeUnchangedOperation(
65 final Collection<? extends IResource> rsrcs, boolean assumeUnchanged) {
66 rsrcList = rsrcs;
67 locations = Collections.emptyList();
68 caches = new IdentityHashMap<>();
69 this.assumeUnchanged = assumeUnchanged;
72 /**
73 * Create a new operation to ignore changes in tracked files
75 * @param repository
76 * a Git repository
77 * @param locations
78 * collection of {@link IPath}s which should be ignored when
79 * looking for changes or committing.
80 * @param assumeUnchanged
81 * {@code true} to set the assume-valid flag in the git index
82 * entry, {@code false} to unset the assume-valid flag in the git
83 * index entry
85 public AssumeUnchangedOperation(final Repository repository,
86 final Collection<IPath> locations,
87 boolean assumeUnchanged) {
88 this.db = repository;
89 this.locations = locations;
90 this.rsrcList = Collections.emptyList();
91 caches = new IdentityHashMap<>();
92 this.assumeUnchanged = assumeUnchanged;
95 @Override
96 public void execute(IProgressMonitor monitor) throws CoreException {
97 SubMonitor progress = SubMonitor.convert(monitor, (rsrcList.size() + locations.size()) * 2);
98 progress.setTaskName(CoreText.AssumeUnchangedOperation_adding);
100 caches.clear();
102 try {
103 for (IResource resource : rsrcList) {
104 assumeValid(resource);
105 progress.worked(1);
107 for (IPath location : locations) {
108 assumeValid(location);
109 progress.worked(1);
112 progress.setWorkRemaining(caches.size());
113 for (Map.Entry<Repository, DirCache> e : caches.entrySet()) {
114 final Repository db = e.getKey();
115 final DirCache editor = e.getValue();
116 progress.setTaskName(NLS.bind(
117 CoreText.AssumeUnchangedOperation_writingIndex, db
118 .getDirectory()));
119 editor.write();
120 editor.commit();
121 progress.worked(1);
123 } catch (RuntimeException e) {
124 throw new CoreException(Activator.error(CoreText.UntrackOperation_failed, e));
125 } catch (IOException e) {
126 throw new CoreException(Activator.error(CoreText.UntrackOperation_failed, e));
127 } finally {
128 for (DirCache cache : caches.values()) {
129 cache.unlock();
131 caches.clear();
135 @Override
136 public ISchedulingRule getSchedulingRule() {
137 return RuleUtil.getRuleForRepositories(rsrcList.toArray(new IResource[0]));
140 private void assumeValid(final IResource resource) throws CoreException {
141 final IProject proj = resource.getProject();
142 if (proj == null) {
143 return;
145 final GitProjectData pd = GitProjectData.get(proj);
146 if (pd == null) {
147 return;
149 final RepositoryMapping rm = pd.getRepositoryMapping(resource);
150 if (rm == null) {
151 return;
153 this.db = rm.getRepository();
154 assumeValid(resource.getLocation());
157 private void assumeValid(final IPath location) throws CoreException {
158 DirCache cache = caches.get(db);
159 if (cache == null) {
160 try {
161 cache = db.lockDirCache();
162 } catch (IOException err) {
163 throw new CoreException(Activator.error(CoreText.UntrackOperation_failed, err));
165 caches.put(db, cache);
168 IPath dbDir = new Path(db.getWorkTree().getAbsolutePath());
169 final String path = location.makeRelativeTo(dbDir).toString();
170 if (location.toFile().isDirectory()) {
171 for (DirCacheEntry ent : cache.getEntriesWithin(path)) {
172 ent.setAssumeValid(assumeUnchanged);
174 } else {
175 DirCacheEntry ent = cache.getEntry(path);
176 if (ent != null) {
177 ent.setAssumeValid(assumeUnchanged);