fixed some bugs
[fedora-idea.git] / dom / impl / src / com / intellij / util / xml / impl / StableInvocationHandler.java
blobe62420e304b8958429545fd0d936c4eb05ee6161
1 /*
2 * Copyright (c) 2000-2006 JetBrains s.r.o. All Rights Reserved.
3 */
4 package com.intellij.util.xml.impl;
6 import com.intellij.openapi.util.Factory;
7 import com.intellij.util.xml.DomElement;
8 import com.intellij.util.xml.StableElement;
9 import net.sf.cglib.proxy.InvocationHandler;
11 import java.lang.reflect.InvocationTargetException;
12 import java.lang.reflect.Method;
13 import java.util.Set;
15 /**
16 * @author peter
18 class StableInvocationHandler<T extends DomElement> implements InvocationHandler, StableElement {
19 private T myOldValue;
20 private T myCachedValue;
21 private Set<Class> myClasses;
22 private final Factory<T> myProvider;
24 public StableInvocationHandler(final T initial, final Factory<T> provider) {
25 myProvider = provider;
26 myCachedValue = initial;
27 myOldValue = initial;
30 public void setClasses(final Set<Class> classes) {
31 myClasses = classes;
34 public final Object invoke(Object proxy, final Method method, final Object[] args) throws Throwable {
35 if (StableElement.class.equals(method.getDeclaringClass())) {
36 try {
37 return method.invoke(this, args);
39 catch (InvocationTargetException e) {
40 throw e.getCause();
44 if (AdvancedProxy.FINALIZE_METHOD.equals(method)) {
45 return null;
48 if (isNotValid(myCachedValue)) {
49 if (myCachedValue != null) {
50 myOldValue = myCachedValue;
52 myCachedValue = myProvider.create();
53 if (isNotValid(myCachedValue)) {
54 if (myOldValue != null && Object.class.equals(method.getDeclaringClass())) {
55 return method.invoke(myOldValue, args);
58 if ("isValid".equals(method.getName())) {
59 return Boolean.FALSE;
61 throw new AssertionError("Calling methods on invalid value");
65 try {
66 return method.invoke(myCachedValue, args);
68 catch (InvocationTargetException e) {
69 throw e.getCause();
73 public final void revalidate() {
74 final T t = myProvider.create();
75 if (!isNotValid(t) && !t.equals(myCachedValue)) {
76 doInvalidate();
77 myCachedValue = t;
81 private void doInvalidate() {
82 final DomInvocationHandler handler = DomManagerImpl.getDomInvocationHandler(myCachedValue);
83 if (handler != null) {
84 handler.detach(true);
88 public final void invalidate() {
89 if (!isNotValid(myCachedValue)) {
90 doInvalidate();
94 public final DomElement getWrappedElement() {
95 if (isNotValid(myCachedValue)) {
96 myCachedValue = myProvider.create();
98 return myCachedValue;
101 public T getOldValue() {
102 return myOldValue;
105 private boolean isNotValid(final T t) {
106 if (t == null || !t.isValid()) return true;
107 for (final Class aClass : myClasses) {
108 if (!aClass.isInstance(t)) return true;
110 return false;