| /* |
| * 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.history.integration.revertion; |
| |
| import com.intellij.history.core.Content; |
| import com.intellij.history.core.LocalHistoryFacade; |
| import com.intellij.history.core.Paths; |
| import com.intellij.history.core.revisions.Difference; |
| import com.intellij.history.core.revisions.Revision; |
| import com.intellij.history.core.tree.Entry; |
| import com.intellij.history.integration.IdeaGateway; |
| import com.intellij.openapi.project.Project; |
| import com.intellij.openapi.vfs.VirtualFile; |
| import com.intellij.util.containers.ContainerUtil; |
| import gnu.trove.THashSet; |
| |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.LinkedHashSet; |
| import java.util.List; |
| import java.util.Set; |
| |
| public class DifferenceReverter extends Reverter { |
| private final IdeaGateway myGateway; |
| private final List<Difference> myDiffs; |
| private final Revision myLeftRevision; |
| |
| public DifferenceReverter(Project p, LocalHistoryFacade vcs, IdeaGateway gw, List<Difference> diffs, Revision leftRevision) { |
| super(p, vcs, gw); |
| myGateway = gw; |
| myDiffs = diffs; |
| myLeftRevision = leftRevision; |
| } |
| |
| @Override |
| protected Revision getTargetRevision() { |
| return myLeftRevision; |
| } |
| |
| @Override |
| protected List<VirtualFile> getFilesToClearROStatus() throws IOException { |
| LinkedHashSet<VirtualFile> files = new LinkedHashSet<VirtualFile>(); |
| for (Difference each : myDiffs) { |
| Entry l = each.getLeft(); |
| Entry r = each.getRight(); |
| VirtualFile f = l == null ? null : myGateway.findVirtualFile(l.getPath()); |
| if (f != null) files.add(f); |
| |
| f = r == null ? null : myGateway.findVirtualFile(r.getPath()); |
| if (f != null) files.add(f); |
| } |
| return new ArrayList<VirtualFile>(files); |
| } |
| |
| @Override |
| protected void doRevert() throws IOException { |
| doRevert(true); |
| } |
| |
| public void doRevert(boolean revertContentChanges) throws IOException { |
| Set<String> vetoedFiles = new THashSet<String>(); |
| |
| for (Difference each : ContainerUtil.iterateBackward(myDiffs)) { |
| Entry l = each.getLeft(); |
| Entry r = each.getRight(); |
| |
| if (l == null) { |
| revertCreation(r, vetoedFiles); |
| continue; |
| } |
| |
| vetoedFiles.add(l.getPath()); |
| if (r == null) { |
| revertDeletion(l); |
| continue; |
| } |
| |
| VirtualFile file = myGateway.findOrCreateFileSafely(r.getPath(), r.isDirectory()); |
| revertRename(l, file); |
| if (revertContentChanges) revertContentChange(l, file); |
| } |
| } |
| |
| private void revertCreation(Entry r, Set<String> vetoedFiles) throws IOException { |
| String path = r.getPath(); |
| for (String each : vetoedFiles) { |
| if (Paths.isParent(path, each)) return; |
| } |
| |
| VirtualFile f = myGateway.findVirtualFile(path); |
| if (f != null) f.delete(this); |
| } |
| |
| private void revertDeletion(Entry l) throws IOException { |
| VirtualFile f = myGateway.findOrCreateFileSafely(l.getPath(), l.isDirectory()); |
| if (l.isDirectory()) return; |
| setContent(l, f); |
| } |
| |
| private void revertRename(Entry l, VirtualFile file) throws IOException { |
| String oldName = l.getName(); |
| if (!oldName.equals(file.getName())) { |
| VirtualFile existing = file.getParent().findChild(oldName); |
| if (existing != null) { |
| existing.delete(this); |
| } |
| file.rename(this, oldName); |
| } |
| } |
| |
| private void revertContentChange(Entry l, VirtualFile file) throws IOException { |
| if (l.isDirectory()) return; |
| if (file.getTimeStamp() != l.getTimestamp()) { |
| setContent(l, file); |
| } |
| } |
| |
| private void setContent(Entry l, VirtualFile file) throws IOException { |
| Content c = l.getContent(); |
| if (!c.isAvailable()) return; |
| file.setBinaryContent(c.getBytes(), -1, l.getTimestamp()); |
| } |
| } |