blob: 931f1031009bc6023da3c14885acddbd421a1b59 [file] [log] [blame]
/*
* Copyright 2000-2009 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.update;
import com.intellij.openapi.vfs.VirtualFile;
import java.util.*;
public class UpdatedFilesReverseSide {
// just list of same groups = another presentation/container of same
private final UpdatedFiles myFiles;
// children are also here
private final Map<String, FileGroup> myGroupHolder;
// file path, group
private final Map<String, FileGroup> myFileIdx;
private final static List<String> ourStoppingGroups = Arrays.asList(
FileGroup.MERGED_WITH_CONFLICT_ID, FileGroup.UNKNOWN_ID, FileGroup.SKIPPED_ID);
public UpdatedFilesReverseSide(final UpdatedFiles files) {
myFiles = files;
myGroupHolder = new HashMap<String, FileGroup>();
myFileIdx = new HashMap<String, FileGroup>();
}
public boolean isEmpty() {
return myFileIdx.isEmpty();
}
public FileGroup getGroup(final String id) {
return myGroupHolder.get(id);
}
public void addFileToGroup(final String groupId, final String file, final DuplicateLevel duplicateLevel, final String vcsName) {
final FileGroup newGroup = myGroupHolder.get(groupId);
addFileToGroup(newGroup, file, duplicateLevel, vcsName);
}
public void addFileToGroup(final FileGroup group, final String file, final DuplicateLevel duplicateLevel, final String vcsName) {
if (duplicateLevel.searchPreviousContainment(group.getId())) {
final FileGroup oldGroup = myFileIdx.get(file);
if (oldGroup != null) {
if (duplicateLevel.doesExistingWin(group.getId(), oldGroup.getId())) {
return;
}
oldGroup.remove(file);
}
}
group.add(file, vcsName, null);
myFileIdx.put(file, group);
}
public UpdatedFiles getUpdatedFiles() {
return myFiles;
}
public void rebuildFromUpdatedFiles() {
myFileIdx.clear();
myGroupHolder.clear();
for (FileGroup group : myFiles.getTopLevelGroups()) {
addGroupToIndexes(group);
}
}
private void addGroupToIndexes(final FileGroup fromGroup) {
myGroupHolder.put(fromGroup.getId(), fromGroup);
for (String file : fromGroup.getFiles()) {
myFileIdx.put(file, fromGroup);
}
for (FileGroup fromChild : fromGroup.getChildren()) {
addGroupToIndexes(fromChild);
}
}
private void copyGroup(final Parent parent, final FileGroup from, final DuplicateLevel duplicateLevel) {
final FileGroup to = createOrGet(parent, from);
for (FileGroup.UpdatedFile updatedFile : from.getUpdatedFiles()) {
addFileToGroup(to, updatedFile.getPath(), duplicateLevel, updatedFile.getVcsName());
}
for (FileGroup fromChild : from.getChildren()) {
copyGroup(new GroupParent(to), fromChild, duplicateLevel);
}
}
private interface Parent {
void accept(FileGroup group);
}
private class TopLevelParent implements Parent {
public void accept(final FileGroup group) {
myFiles.getTopLevelGroups().add(group);
}
}
private static class GroupParent implements Parent {
private final FileGroup myGroup;
private GroupParent(final FileGroup group) {
myGroup = group;
}
public void accept(final FileGroup group) {
myGroup.addChild(group);
}
}
private FileGroup createOrGet(final Parent possibleParent, final FileGroup fromGroup) {
FileGroup ownGroup = myGroupHolder.get(fromGroup.getId());
if (ownGroup == null) {
ownGroup = new FileGroup(fromGroup.getUpdateName(), fromGroup.getStatusName(), fromGroup.getSupportsDeletion(),
fromGroup.getId(), fromGroup.myCanBeAbsent);
possibleParent.accept(ownGroup);
myGroupHolder.put(fromGroup.getId(), ownGroup);
}
return ownGroup;
}
public static Set<String> getPathsFromUpdatedFiles(final UpdatedFiles from) {
UpdatedFilesReverseSide helper = new UpdatedFilesReverseSide(UpdatedFiles.create());
helper.accomulateFiles(from, DuplicateLevel.DUPLICATE_ERRORS);
return helper.myFileIdx.keySet();
}
public void accomulateFiles(final UpdatedFiles from, final DuplicateLevel duplicateLevel) {
final Parent topLevel = new TopLevelParent();
for (FileGroup fromGroup : from.getTopLevelGroups()) {
copyGroup(topLevel, fromGroup, duplicateLevel);
}
}
public boolean containErrors() {
return containErrors(myFiles);
}
public static boolean containErrors(final UpdatedFiles files) {
for (String groupId : ourStoppingGroups) {
final FileGroup group = files.getGroupById(groupId);
if ((group != null) && (! group.isEmpty())) {
return true;
}
}
return false;
}
public boolean containsFile(final VirtualFile file) {
return myFileIdx.containsKey(file.getPresentableUrl());
}
public abstract static class DuplicateLevel {
private final static List<String> ourErrorGroups = Arrays.asList(FileGroup.UNKNOWN_ID, FileGroup.SKIPPED_ID);
private final static List<String> ourLocals = Arrays.asList(FileGroup.LOCALLY_ADDED_ID, FileGroup.LOCALLY_REMOVED_ID);
abstract boolean searchPreviousContainment(final String groupId);
abstract boolean doesExistingWin(final String groupId, final String existingGroupId);
private DuplicateLevel() {
}
public static final DuplicateLevel NO_DUPLICATES = new DuplicateLevel() {
boolean searchPreviousContainment(final String groupId) {
return true;
}
boolean doesExistingWin(final String groupId, final String existingGroupId) {
return false;
}
};
public static final DuplicateLevel DUPLICATE_ERRORS_LOCALS = new DuplicateLevel() {
boolean searchPreviousContainment(final String groupId) {
return (! ourLocals.contains(groupId)) && (! ourErrorGroups.contains(groupId));
}
boolean doesExistingWin(final String groupId, final String existingGroupId) {
return ourLocals.contains(groupId);
}
};
public static final DuplicateLevel DUPLICATE_ERRORS = new DuplicateLevel() {
boolean searchPreviousContainment(final String groupId) {
return ! ourErrorGroups.contains(groupId);
}
boolean doesExistingWin(final String groupId, final String existingGroupId) {
return false;
}
};
public static final DuplicateLevel ALLOW_DUPLICATES = new DuplicateLevel() {
boolean searchPreviousContainment(final String groupId) {
return false;
}
boolean doesExistingWin(final String groupId, final String existingGroupId) {
return false;
}
};
}
}