KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > core > internal > databinding > internal > beans > JavaBeanObservableValue


1 /*******************************************************************************
2  * Copyright (c) 2005, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  * Brad Reynolds - bug 164653
11  * Brad Reynolds - bug 164134, 171616
12  *******************************************************************************/

13 package org.eclipse.core.internal.databinding.internal.beans;
14
15 import java.beans.PropertyChangeListener JavaDoc;
16 import java.beans.PropertyDescriptor JavaDoc;
17 import java.lang.reflect.InvocationTargetException JavaDoc;
18 import java.lang.reflect.Method JavaDoc;
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 /**
32  * @since 1.0
33  *
34  */

35 public class JavaBeanObservableValue extends AbstractObservableValue implements IBeanObservable {
36     private final Object JavaDoc object;
37     private boolean updating = false;
38
39     private final PropertyDescriptor JavaDoc propertyDescriptor;
40     private final Class JavaDoc overrideType;
41     private ListenerSupport listenerSupport;
42
43     /**
44      * @param realm
45      * @param object
46      * @param descriptor
47      * @param overrideType
48      */

49     public JavaBeanObservableValue(Realm realm, Object JavaDoc object,
50             PropertyDescriptor JavaDoc descriptor, Class JavaDoc overrideType) {
51         super(realm);
52         this.object = object;
53         this.propertyDescriptor = descriptor;
54         this.overrideType = overrideType;
55     }
56
57     protected void firstListenerAdded() {
58         PropertyChangeListener JavaDoc listener = new PropertyChangeListener JavaDoc() {
59             public void propertyChange(java.beans.PropertyChangeEvent JavaDoc event) {
60                 if (!updating) {
61                     final ValueDiff diff = Diffs.createValueDiff(event.getOldValue(),
62                                             event.getNewValue());
63                     getRealm().exec(new Runnable JavaDoc(){
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 JavaDoc value) {
79         updating = true;
80         try {
81             Object JavaDoc oldValue = doGetValue();
82             Method JavaDoc writeMethod = propertyDescriptor.getWriteMethod();
83             if (!writeMethod.isAccessible()) {
84                 writeMethod.setAccessible(true);
85             }
86             writeMethod.invoke(object, new Object JavaDoc[] { value });
87             fireValueChange(Diffs.createValueDiff(oldValue, doGetValue()));
88         } catch (InvocationTargetException JavaDoc e) {
89             /*
90              * InvocationTargetException wraps any exception thrown by the
91              * invoked method.
92              */

93             throw new RuntimeException JavaDoc(e.getCause());
94         } catch (Exception JavaDoc 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)); //$NON-NLS-1$ //$NON-NLS-2$
104
}
105         } finally {
106             updating = false;
107         }
108     }
109
110     public Object JavaDoc doGetValue() {
111         try {
112             Method JavaDoc readMethod = propertyDescriptor.getReadMethod();
113             if (readMethod == null) {
114                 throw new BindingException(propertyDescriptor.getName()
115                         + " property does not have a read method."); //$NON-NLS-1$
116
}
117             if (!readMethod.isAccessible()) {
118                 readMethod.setAccessible(true);
119             }
120             return readMethod.invoke(object, null);
121         } catch (InvocationTargetException JavaDoc e) {
122             /*
123              * InvocationTargetException wraps any exception thrown by the
124              * invoked method.
125              */

126             throw new RuntimeException JavaDoc(e.getCause());
127         } catch (Exception JavaDoc 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)); //$NON-NLS-1$ //$NON-NLS-2$
137
}
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 JavaDoc getValueType() {
154         Class JavaDoc type = propertyDescriptor.getPropertyType();
155         if (type == Object JavaDoc.class && overrideType != null)
156             type = overrideType;
157         return type;
158     }
159
160     public Object JavaDoc getObserved() {
161         return object;
162     }
163
164     public PropertyDescriptor JavaDoc getPropertyDescriptor() {
165         return propertyDescriptor;
166     }
167
168     public synchronized void dispose() {
169         unhookListener();
170         super.dispose();
171     }
172 }
173
Popular Tags