1 13 package org.eclipse.core.internal.databinding.internal.beans; 14 15 import java.beans.PropertyChangeListener ; 16 import java.beans.PropertyDescriptor ; 17 import java.lang.reflect.InvocationTargetException ; 18 import java.lang.reflect.Method ; 19 20 import org.eclipse.core.databinding.BindingException; 21 import org.eclipse.core.databinding.beans.BeansObservables; 22 import org.eclipse.core.databinding.beans.IBeanObservable; 23 import org.eclipse.core.databinding.observable.Diffs; 24 import org.eclipse.core.databinding.observable.Realm; 25 import org.eclipse.core.databinding.observable.value.AbstractObservableValue; 26 import org.eclipse.core.databinding.observable.value.ValueDiff; 27 import org.eclipse.core.databinding.util.Policy; 28 import org.eclipse.core.runtime.IStatus; 29 import org.eclipse.core.runtime.Status; 30 31 35 public class JavaBeanObservableValue extends AbstractObservableValue implements IBeanObservable { 36 private final Object object; 37 private boolean updating = false; 38 39 private final PropertyDescriptor propertyDescriptor; 40 private final Class overrideType; 41 private ListenerSupport listenerSupport; 42 43 49 public JavaBeanObservableValue(Realm realm, Object object, 50 PropertyDescriptor descriptor, Class overrideType) { 51 super(realm); 52 this.object = object; 53 this.propertyDescriptor = descriptor; 54 this.overrideType = overrideType; 55 } 56 57 protected void firstListenerAdded() { 58 PropertyChangeListener listener = new PropertyChangeListener () { 59 public void propertyChange(java.beans.PropertyChangeEvent event) { 60 if (!updating) { 61 final ValueDiff diff = Diffs.createValueDiff(event.getOldValue(), 62 event.getNewValue()); 63 getRealm().exec(new Runnable (){ 64 public void run() { 65 fireValueChange(diff); 66 }}); 67 } 68 } 69 }; 70 71 if (listenerSupport == null) { 72 listenerSupport = new ListenerSupport(listener, propertyDescriptor.getName()); 73 } 74 75 listenerSupport.hookListener(object); 76 } 77 78 public void doSetValue(Object value) { 79 updating = true; 80 try { 81 Object oldValue = doGetValue(); 82 Method writeMethod = propertyDescriptor.getWriteMethod(); 83 if (!writeMethod.isAccessible()) { 84 writeMethod.setAccessible(true); 85 } 86 writeMethod.invoke(object, new Object [] { value }); 87 fireValueChange(Diffs.createValueDiff(oldValue, doGetValue())); 88 } catch (InvocationTargetException e) { 89 93 throw new RuntimeException (e.getCause()); 94 } catch (Exception e) { 95 if (BeansObservables.DEBUG) { 96 Policy 97 .getLog() 98 .log( 99 new Status( 100 IStatus.WARNING, 101 Policy.JFACE_DATABINDING, 102 IStatus.OK, 103 "Could not change value of " + object + "." + propertyDescriptor.getName(), e)); } 105 } finally { 106 updating = false; 107 } 108 } 109 110 public Object doGetValue() { 111 try { 112 Method readMethod = propertyDescriptor.getReadMethod(); 113 if (readMethod == null) { 114 throw new BindingException(propertyDescriptor.getName() 115 + " property does not have a read method."); } 117 if (!readMethod.isAccessible()) { 118 readMethod.setAccessible(true); 119 } 120 return readMethod.invoke(object, null); 121 } catch (InvocationTargetException e) { 122 126 throw new RuntimeException (e.getCause()); 127 } catch (Exception e) { 128 if (BeansObservables.DEBUG) { 129 Policy 130 .getLog() 131 .log( 132 new Status( 133 IStatus.WARNING, 134 Policy.JFACE_DATABINDING, 135 IStatus.OK, 136 "Could not read value of " + object + "." + propertyDescriptor.getName(), e)); } 138 return null; 139 } 140 } 141 142 protected void lastListenerRemoved() { 143 unhookListener(); 144 } 145 146 private void unhookListener() { 147 if (listenerSupport != null) { 148 listenerSupport.dispose(); 149 listenerSupport = null; 150 } 151 } 152 153 public Object getValueType() { 154 Class type = propertyDescriptor.getPropertyType(); 155 if (type == Object .class && overrideType != null) 156 type = overrideType; 157 return type; 158 } 159 160 public Object getObserved() { 161 return object; 162 } 163 164 public PropertyDescriptor getPropertyDescriptor() { 165 return propertyDescriptor; 166 } 167 168 public synchronized void dispose() { 169 unhookListener(); 170 super.dispose(); 171 } 172 } 173 | Popular Tags |