stable elements for any type

This commit is contained in:
Gregory Shrago
2009-11-25 20:43:36 +03:00
parent ec239fd607
commit 044c141a60
3 changed files with 21 additions and 10 deletions
@@ -12,6 +12,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Factory;
import com.intellij.openapi.util.Key;
@@ -320,7 +321,7 @@ public final class DomManagerImpl extends DomManager {
}
final InvocationHandler handler = AdvancedProxy.getInvocationHandler(proxy);
if (handler instanceof StableInvocationHandler) {
final DomElement element = ((StableInvocationHandler)handler).getWrappedElement();
final DomElement element = ((StableInvocationHandler<DomElement>)handler).getWrappedElement();
return element == null ? null : getDomInvocationHandler(element);
}
if (handler instanceof DomInvocationHandler) {
@@ -493,9 +494,17 @@ public final class DomManagerImpl extends DomManager {
}
public final <T extends DomElement> T createStableValue(final Factory<T> provider) {
return createStableValue(provider, new Condition<T>() {
public boolean value(T t) {
return t.isValid();
}
});
}
public final <T> T createStableValue(final Factory<T> provider, final Condition<T> validator) {
final T initial = provider.create();
assert initial != null;
final StableInvocationHandler handler = new StableInvocationHandler<T>(initial, provider);
final StableInvocationHandler handler = new StableInvocationHandler<T>(initial, provider, validator);
final Set<Class> intf = new HashSet<Class>();
intf.addAll(Arrays.asList(initial.getClass().getInterfaces()));
@@ -16,6 +16,7 @@
package com.intellij.util.xml.impl;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Factory;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.xml.DomElement;
@@ -33,16 +34,18 @@ import java.util.Set;
/**
* @author peter
*/
class StableInvocationHandler<T extends DomElement> implements InvocationHandler, StableElement {
class StableInvocationHandler<T> implements InvocationHandler, StableElement {
private T myOldValue;
private T myCachedValue;
private final Set<Class> myClasses;
private final Factory<T> myProvider;
private final Condition<T> myValidator;
public StableInvocationHandler(final T initial, final Factory<T> provider) {
public StableInvocationHandler(final T initial, final Factory<T> provider, Condition<T> validator) {
myProvider = provider;
myCachedValue = initial;
myOldValue = initial;
myValidator = validator;
final Class superClass = initial.getClass().getSuperclass();
final Set<Class> classes = new HashSet<Class>();
classes.addAll(Arrays.asList(initial.getClass().getInterfaces()));
@@ -125,7 +128,7 @@ class StableInvocationHandler<T extends DomElement> implements InvocationHandler
}
}
public final DomElement getWrappedElement() {
public final T getWrappedElement() {
if (isNotValid(myCachedValue)) {
myCachedValue = myProvider.create();
}
@@ -137,7 +140,7 @@ class StableInvocationHandler<T extends DomElement> implements InvocationHandler
}
private boolean isNotValid(final T t) {
if (t == null || !t.isValid()) return true;
if (t == null || !myValidator.value(t)) return true;
for (final Class aClass : myClasses) {
if (!aClass.isInstance(t)) return true;
}
@@ -19,10 +19,7 @@ import com.intellij.openapi.Disposable;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Factory;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.ModificationTracker;
import com.intellij.openapi.util.NotNullLazyKey;
import com.intellij.openapi.util.*;
import com.intellij.psi.PsiReferenceFactory;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlFile;
@@ -121,6 +118,8 @@ public abstract class DomManager implements ModificationTracker {
*/
public abstract <T extends DomElement> T createStableValue(Factory<T> provider);
public abstract <T> T createStableValue(final Factory<T> provider, final Condition<T> validator);
/**
* Registers a new {@link com.intellij.util.xml.DomFileDescription} within the manager. The description parameter describes some DOM
* parameters and restrictions to the particular XML files, that need DOM support. Should be called on