package jetbrains.mps.vcs.changesmanager.tree;
/*Generated by MPS */
import org.apache.log4j.Logger;
import org.apache.log4j.LogManager;
import org.jetbrains.mps.openapi.module.SRepository;
import java.util.Map;
import jetbrains.mps.vcs.changesmanager.tree.features.Feature;
import jetbrains.mps.internal.collections.runtime.MapSequence;
import java.util.HashMap;
import jetbrains.mps.util.CounterMap;
import java.util.List;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import java.util.ArrayList;
import org.jetbrains.annotations.NotNull;
import jetbrains.mps.internal.collections.runtime.Sequence;
import jetbrains.mps.internal.collections.runtime.IWhereFilter;
import jetbrains.mps.internal.collections.runtime.IVisitor;
import org.jetbrains.annotations.Nullable;
import org.apache.log4j.Level;
/**
* This is a map from 'Feature' to arbitrary value. Also it stores which features are ancestors of
* features which are added in this map.
*
* @param <V> map value
*/
public class FeatureForestMap<V> {
private static final Logger LOG = LogManager.getLogger(FeatureForestMap.class);
private static boolean ourLoggingEnabled = "true".equals(System.getProperty("changesmanager.debug"));
private final SRepository myRepo;
private final Map<Feature, V> myFeatureToValue = MapSequence.fromMap(new HashMap<Feature, V>());
private final Map<Feature, Feature[]> myFeatureToAncestors = MapSequence.fromMap(new HashMap<Feature, Feature[]>());
private final CounterMap<Feature> myFeaturesIsAncestorCounterMap = new CounterMap<Feature>(new FeatureForestMap.MyCounterMapHandler());
private final List<FeatureForestMapListener> myListeners = ListSequence.fromList(new ArrayList<FeatureForestMapListener>());
public FeatureForestMap(SRepository repository) {
myRepo = repository;
}
public void put(@NotNull Feature feature, @NotNull V value) {
if (MapSequence.fromMap(myFeatureToValue).containsKey(feature)) {
log("Trying to put already present feature " + feature);
}
Feature[] ancestors = feature.getAncestors(myRepo);
Feature ancestor = Sequence.fromIterable(Sequence.fromArray(ancestors)).findFirst(new IWhereFilter<Feature>() {
public boolean accept(Feature a) {
return MapSequence.fromMap(myFeatureToValue).containsKey(a);
}
});
if (ancestor != null) {
log(String.format("Trying to put feature (%s) which is ancestor of already added (%s)", feature, ancestor));
}
MapSequence.fromMap(myFeatureToValue).put(feature, value);
MapSequence.fromMap(myFeatureToAncestors).put(feature, ancestors);
Sequence.fromIterable(Sequence.fromArray(ancestors)).visitAll(new IVisitor<Feature>() {
public void visit(Feature a) {
myFeaturesIsAncestorCounterMap.increment(a);
}
});
fireFeatureStateChanged(feature);
}
public void removeKey(@NotNull Feature feature) {
if (!(MapSequence.fromMap(myFeatureToValue).containsKey(feature))) {
log("Trying to remove feature which is not added: " + feature);
}
Feature[] ancestors = MapSequence.fromMap(myFeatureToAncestors).get(feature);
MapSequence.fromMap(myFeatureToValue).removeKey(feature);
MapSequence.fromMap(myFeatureToAncestors).removeKey(feature);
Sequence.fromIterable(Sequence.fromArray(ancestors)).visitAll(new IVisitor<Feature>() {
public void visit(Feature a) {
myFeaturesIsAncestorCounterMap.decrement(a);
}
});
fireFeatureStateChanged(feature);
}
@Nullable
public V get(@NotNull Feature feature) {
return MapSequence.fromMap(myFeatureToValue).get(feature);
}
public boolean isAncestorOfAddedFeature(@NotNull Feature feature) {
return !(myFeaturesIsAncestorCounterMap.isZero(feature));
}
@Nullable
public Feature getAddedAncestor(@NotNull Feature feature) {
return Sequence.fromIterable(Sequence.fromArray(feature.getAncestors(myRepo))).findFirst(new IWhereFilter<Feature>() {
public boolean accept(Feature a) {
return MapSequence.fromMap(myFeatureToValue).containsKey(a);
}
});
}
@Nullable
public V getAddedAncestorValue(@NotNull Feature feature) {
return MapSequence.fromMap(myFeatureToValue).get(getAddedAncestor(feature));
}
public void addListener(@NotNull FeatureForestMapListener listener) {
synchronized (myListeners) {
ListSequence.fromList(myListeners).addElement(listener);
}
}
public void removeListener(@NotNull FeatureForestMapListener listener) {
synchronized (myListeners) {
ListSequence.fromList(myListeners).removeElement(listener);
}
}
@NotNull
private List<FeatureForestMapListener> copyListeners() {
synchronized (myListeners) {
return ListSequence.fromListWithValues(new ArrayList<FeatureForestMapListener>(), myListeners);
}
}
private void fireFeatureStateChanged(@NotNull Feature feature) {
for (FeatureForestMapListener listener : ListSequence.fromList(copyListeners())) {
try {
listener.featureStateChanged(feature);
} catch (Throwable t) {
if (t instanceof InterruptedException || check_tcy57o_a0a0a0a0a0ab(t) instanceof InterruptedException) {
// ignore
} else {
if (LOG.isEnabledFor(Level.ERROR)) {
LOG.error("Exception on firing featureStateChanged event", t);
}
}
}
}
}
public static void setLoggingEnabled(boolean loggingEnabled) {
ourLoggingEnabled = loggingEnabled;
}
private static void log(String msg) {
if (ourLoggingEnabled) {
if (LOG.isEnabledFor(Level.ERROR)) {
LOG.error(msg);
}
}
}
private class MyCounterMapHandler implements CounterMap.CounterMapHandler<Feature> {
public MyCounterMapHandler() {
}
@Override
public void counterZero(@NotNull Feature feature) {
fireFeatureStateChanged(feature);
}
@Override
public void counterNonZero(@NotNull Feature feature) {
fireFeatureStateChanged(feature);
}
}
private static Throwable check_tcy57o_a0a0a0a0a0ab(Throwable checkedDotOperand) {
if (null != checkedDotOperand) {
return checkedDotOperand.getCause();
}
return null;
}
}