blob: f7ec23a5b3311fbab7297b88996384a5ff25e866 [file] [log] [blame]
/*
* Copyright 2000-2010 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.core;
import com.intellij.history.core.changes.*;
import com.intellij.psi.codeStyle.NameUtil;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.regex.Pattern;
public class ChangeCollectingVisitor extends ChangeVisitor {
private String myPath;
private final String myProjectId;
private final Pattern myPattern;
private ChangeSet myCurrentChangeSet;
private boolean myExists = true;
private boolean myDoNotAddAnythingElseFromCurrentChangeSet = false;
private final LinkedHashSet<ChangeSet> myResult = new LinkedHashSet<ChangeSet>();
public ChangeCollectingVisitor(String path, String projectId, @Nullable String pattern) {
myPath = path;
myProjectId = projectId;
myPattern = pattern == null ? null : Pattern.compile(NameUtil.buildRegexp(pattern, 0, true, true), Pattern.CASE_INSENSITIVE);
}
public List<ChangeSet> getChanges() {
return new ArrayList<ChangeSet>(myResult);
}
public String getPath() {
return myPath;
}
@Override
public void begin(ChangeSet c) throws StopVisitingException {
myCurrentChangeSet = c;
}
@Override
public void end(ChangeSet c) throws StopVisitingException {
myCurrentChangeSet = null;
myDoNotAddAnythingElseFromCurrentChangeSet = false;
}
@Override
public void visit(PutLabelChange c) throws StopVisitingException {
doVisit(c);
}
@Override
public void visit(StructuralChange c) throws StopVisitingException {
doVisit(c);
}
private void doVisit(Change c) {
if (skippedDueToNonexistence(c)) return;
addIfAffectsAndRevert(c);
}
@Override
public void visit(CreateEntryChange c) throws StopVisitingException {
if (skippedDueToNonexistence(c)) return;
addIfAffectsAndRevert(c);
if (c.isCreationalFor(myPath)) myExists = false;
}
@Override
public void visit(DeleteChange c) throws StopVisitingException {
if (skippedDueToNonexistence(c)) {
if (c.isDeletionOf(myPath)) {
addIfAffectsAndRevert(c);
myExists = true;
myDoNotAddAnythingElseFromCurrentChangeSet = true;
}
} else {
addIfAffectsAndRevert(c);
}
}
private void addIfAffectsAndRevert(Change c) {
if (!myDoNotAddAnythingElseFromCurrentChangeSet && (c.affectsPath(myPath) || c.affectsProject(myProjectId))) {
if (myPattern == null || c.affectsMatching(myPattern)) {
myResult.add(myCurrentChangeSet);
}
}
if (c instanceof StructuralChange) myPath = ((StructuralChange)c).revertPath(myPath);
}
private boolean skippedDueToNonexistence(Change c) {
if (myExists) return false;
if (c instanceof StructuralChange) myPath = ((StructuralChange)c).revertPath(myPath);
return true;
}
}