| /* |
| * 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; |
| } |
| }; |
| } |
| } |