/* * Copyright 2000-2011 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.intellij.openapi.vcs.changes; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.AbstractVcs; import com.intellij.openapi.vcs.ProjectLevelVcsManager; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.ObjectUtils; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; public class IgnoredFilesCompositeHolder implements IgnoredFilesHolder { private final Map<AbstractVcs, IgnoredFilesHolder> myVcsIgnoredHolderMap; private IgnoredFilesHolder myIdeIgnoredFilesHolder; private final Project myProject; private AbstractVcs myCurrentVcs; private final ProjectLevelVcsManager myVcsManager; public IgnoredFilesCompositeHolder(final Project project) { super(); myProject = project; myVcsIgnoredHolderMap = new HashMap<>(); myIdeIgnoredFilesHolder = new RecursiveFileHolder<>(myProject, HolderType.IGNORED); myVcsManager = ProjectLevelVcsManager.getInstance(myProject); } @Override public void cleanAll() { myVcsIgnoredHolderMap.values().forEach(IgnoredFilesHolder::cleanAll); myVcsIgnoredHolderMap.clear(); myIdeIgnoredFilesHolder.cleanAll(); } @Override public void cleanAndAdjustScope(VcsModifiableDirtyScope scope) { final AbstractVcs vcs = scope.getVcs(); if (myVcsIgnoredHolderMap.containsKey(vcs)) { myVcsIgnoredHolderMap.get(vcs).cleanAndAdjustScope(scope); } myIdeIgnoredFilesHolder.cleanAndAdjustScope(scope); } @Override public FileHolder copy() { final IgnoredFilesCompositeHolder result = new IgnoredFilesCompositeHolder(myProject); for (Map.Entry<AbstractVcs, IgnoredFilesHolder> entry : myVcsIgnoredHolderMap.entrySet()) { result.myVcsIgnoredHolderMap.put(entry.getKey(), (IgnoredFilesHolder)entry.getValue().copy()); } result.myIdeIgnoredFilesHolder = (IgnoredFilesHolder)myIdeIgnoredFilesHolder.copy(); return result; } @Override public HolderType getType() { return HolderType.IGNORED; } @Override public void addFile(VirtualFile file) { myIdeIgnoredFilesHolder.addFile(file); } public boolean isInUpdatingMode() { return myVcsIgnoredHolderMap.values().stream() .anyMatch((holder) -> (holder instanceof VcsIgnoredFilesHolder) && ((VcsIgnoredFilesHolder)holder).isInUpdatingMode()); } @Override public boolean containsFile(VirtualFile file) { if (myIdeIgnoredFilesHolder.containsFile(file)) return true; final AbstractVcs vcs = myVcsManager.getVcsFor(file); if (vcs == null) return false; final IgnoredFilesHolder ignoredFilesHolder = myVcsIgnoredHolderMap.get(vcs); return ignoredFilesHolder != null && ignoredFilesHolder.containsFile(file); } @Override public Collection<VirtualFile> values() { final HashSet<VirtualFile> result = ContainerUtil.newHashSet(); result.addAll(myIdeIgnoredFilesHolder.values()); result.addAll( myVcsIgnoredHolderMap.values().stream().map(IgnoredFilesHolder::values).flatMap(set -> set.stream()).collect(Collectors.toSet())); return result; } @Override public void notifyVcsStarted(AbstractVcs vcs) { myCurrentVcs = vcs; if (myVcsIgnoredHolderMap.containsKey(vcs)) return; IgnoredFilesHolder ignoredFilesHolder = ObjectUtils.chooseNotNull(getHolderFromEP(vcs, myProject), new RecursiveFileHolder<>(myProject, HolderType.IGNORED)); ignoredFilesHolder.notifyVcsStarted(vcs); myVcsIgnoredHolderMap.put(vcs, ignoredFilesHolder); } @Nullable public IgnoredFilesHolder getActiveVcsHolder() { return getIgnoredHolderByVcs(myCurrentVcs); } @Nullable private IgnoredFilesHolder getIgnoredHolderByVcs(AbstractVcs vcs) { if (!myVcsIgnoredHolderMap.containsKey(vcs)) return null; return myVcsIgnoredHolderMap.get(vcs); } @Nullable private static VcsIgnoredFilesHolder getHolderFromEP(AbstractVcs vcs, @NotNull Project project) { Optional<VcsIgnoredFilesHolder> ignoredFilesHolder = Stream.of(Extensions.getExtensions(VcsIgnoredFilesHolder.VCS_IGNORED_FILES_HOLDER_EP, project)) .filter(holder -> holder.getVcs().equals(vcs)) .findFirst(); return ignoredFilesHolder.isPresent() ? ignoredFilesHolder.get() : null; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!(obj instanceof IgnoredFilesCompositeHolder)) { return false; } IgnoredFilesCompositeHolder other = (IgnoredFilesCompositeHolder)obj; return myVcsIgnoredHolderMap.equals(other.myVcsIgnoredHolderMap) && myIdeIgnoredFilesHolder.equals(other.myIdeIgnoredFilesHolder); } @Override public int hashCode() { return Objects.hash(myVcsIgnoredHolderMap, myIdeIgnoredFilesHolder); } }