KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > core > databinding > beans > BeansObservables


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 164268, 171616
11  * Brad Reynolds - bug 147515
12  *******************************************************************************/

13 package org.eclipse.core.databinding.beans;
14
15 import java.beans.BeanInfo JavaDoc;
16 import java.beans.IntrospectionException JavaDoc;
17 import java.beans.Introspector JavaDoc;
18 import java.beans.PropertyDescriptor JavaDoc;
19
20 import org.eclipse.core.databinding.BindingException;
21 import org.eclipse.core.databinding.observable.IObservable;
22 import org.eclipse.core.databinding.observable.Realm;
23 import org.eclipse.core.databinding.observable.list.IObservableList;
24 import org.eclipse.core.databinding.observable.map.IObservableMap;
25 import org.eclipse.core.databinding.observable.masterdetail.IObservableFactory;
26 import org.eclipse.core.databinding.observable.masterdetail.MasterDetailObservables;
27 import org.eclipse.core.databinding.observable.set.IObservableSet;
28 import org.eclipse.core.databinding.observable.value.IObservableValue;
29 import org.eclipse.core.internal.databinding.internal.beans.BeanObservableListDecorator;
30 import org.eclipse.core.internal.databinding.internal.beans.BeanObservableSetDecorator;
31 import org.eclipse.core.internal.databinding.internal.beans.BeanObservableValueDecorator;
32 import org.eclipse.core.internal.databinding.internal.beans.JavaBeanObservableList;
33 import org.eclipse.core.internal.databinding.internal.beans.JavaBeanObservableMap;
34 import org.eclipse.core.internal.databinding.internal.beans.JavaBeanObservableSet;
35 import org.eclipse.core.internal.databinding.internal.beans.JavaBeanObservableValue;
36
37 /**
38  * A factory for creating observable objects of Java objects that conform to the
39  * <a HREF="http://java.sun.com/products/javabeans/docs/spec.html">JavaBean
40  * specification</a> for bound properties.
41  *
42  * @since 1.1
43  *
44  */

45 final public class BeansObservables {
46
47     /**
48      *
49      */

50     public static final boolean DEBUG = true;
51
52     /**
53      * Returns an observable value in the default realm tracking the current
54      * value of the named property of the given bean.
55      *
56      * @param bean
57      * the object
58      * @param propertyName
59      * the name of the property
60      * @return an observable value tracking the current value of the named
61      * property of the given bean
62      */

63     public static IObservableValue observeValue(Object JavaDoc bean, String JavaDoc propertyName) {
64         return observeValue(Realm.getDefault(), bean, propertyName);
65     }
66
67     /**
68      * Returns an observable value in the given realm tracking the current value
69      * of the named property of the given bean.
70      *
71      * @param realm
72      * the realm
73      * @param bean
74      * the object
75      * @param propertyName
76      * the name of the property
77      * @return an observable value tracking the current value of the named
78      * property of the given bean
79      */

80     public static IObservableValue observeValue(Realm realm, Object JavaDoc bean,
81             String JavaDoc propertyName) {
82         PropertyDescriptor JavaDoc descriptor = getPropertyDescriptor(bean.getClass(),
83                 propertyName);
84         return new JavaBeanObservableValue(realm, bean, descriptor, null);
85     }
86
87     /**
88      * Returns an observable map in the default realm tracking the current
89      * values of the named property for the beans in the given set.
90      *
91      * @param domain
92      * the set of bean objects
93      * @param beanClass
94      * the common base type of bean objects that may be in the set
95      * @param propertyName
96      * the name of the property
97      * @return an observable map tracking the current values of the named
98      * property for the beans in the given domain set
99      */

100     public static IObservableMap observeMap(IObservableSet domain,
101             Class JavaDoc beanClass, String JavaDoc propertyName) {
102         PropertyDescriptor JavaDoc descriptor = getPropertyDescriptor(beanClass,
103                 propertyName);
104         return new JavaBeanObservableMap(domain, descriptor);
105     }
106
107     private static PropertyDescriptor JavaDoc getPropertyDescriptor(Class JavaDoc beanClass,
108             String JavaDoc propertyName) {
109         BeanInfo JavaDoc beanInfo;
110         try {
111             beanInfo = Introspector.getBeanInfo(beanClass);
112         } catch (IntrospectionException JavaDoc e) {
113             // cannot introspect, give up
114
return null;
115         }
116         PropertyDescriptor JavaDoc[] propertyDescriptors = beanInfo
117                 .getPropertyDescriptors();
118         for (int i = 0; i < propertyDescriptors.length; i++) {
119             PropertyDescriptor JavaDoc descriptor = propertyDescriptors[i];
120             if (descriptor.getName().equals(propertyName)) {
121                 return descriptor;
122             }
123         }
124         throw new BindingException(
125                 "Could not find property with name " + propertyName + " in class " + beanClass); //$NON-NLS-1$ //$NON-NLS-2$
126
}
127
128     /**
129      * Returns an array of observable maps in the default realm tracking the
130      * current values of the named propertys for the beans in the given set.
131      *
132      * @param domain
133      * the set of objects
134      * @param beanClass
135      * the common base type of objects that may be in the set
136      * @param propertyNames
137      * the array of property names
138      * @return an array of observable maps tracking the current values of the
139      * named propertys for the beans in the given domain set
140      */

141     public static IObservableMap[] observeMaps(IObservableSet domain,
142             Class JavaDoc beanClass, String JavaDoc[] propertyNames) {
143         IObservableMap[] result = new IObservableMap[propertyNames.length];
144         for (int i = 0; i < propertyNames.length; i++) {
145             result[i] = observeMap(domain, beanClass, propertyNames[i]);
146         }
147         return result;
148     }
149
150     /**
151      * Returns an observable list in the given realm tracking the
152      * collection-typed named property of the given bean object. The returned
153      * list is mutable.
154      *
155      * @param realm
156      * the realm
157      * @param bean
158      * the object
159      * @param propertyName
160      * the name of the collection-typed property
161      * @return an observable list tracking the collection-typed named property
162      * of the given bean object
163      * @see #observeList(Realm, Object, String, Class)
164      */

165     public static IObservableList observeList(Realm realm, Object JavaDoc bean,
166             String JavaDoc propertyName) {
167         return observeList(realm, bean, propertyName, null);
168     }
169
170     /**
171      * Returns an observable list in the given realm tracking the
172      * collection-typed named property of the given bean object. The returned
173      * list is mutable. When an item is added or removed the setter is invoked
174      * for the list on the parent bean to provide notification to other
175      * listeners via <code>PropertyChangeEvents</code>. This is done to
176      * provide the same behavior as is expected from arrays as specified in the
177      * bean spec in section 7.2.
178      *
179      * @param realm
180      * the realm
181      * @param bean
182      * the bean object
183      * @param propertyName
184      * the name of the property
185      * @param elementType
186      * type of the elements in the list. If <code>null</code> and
187      * the property is an array the type will be inferred. If
188      * <code>null</code> and the property type cannot be inferred
189      * element type will be <code>null</code>.
190      * @return an observable list tracking the collection-typed named property
191      * of the given bean object
192      */

193     public static IObservableList observeList(Realm realm, Object JavaDoc bean,
194             String JavaDoc propertyName, Class JavaDoc elementType) {
195         PropertyDescriptor JavaDoc propertyDescriptor = getPropertyDescriptor(bean
196                 .getClass(), propertyName);
197         elementType = getCollectionElementType(elementType, propertyDescriptor);
198
199         return new JavaBeanObservableList(realm, bean, propertyDescriptor,
200                 elementType);
201     }
202
203     /**
204      * Returns an observable set in the given realm tracking the
205      * collection-typed named property of the given bean object
206      *
207      * @param realm
208      * the realm
209      * @param bean
210      * the bean object
211      * @param propertyName
212      * the name of the property
213      * @return an observable set tracking the collection-typed named property of
214      * the given bean object
215      */

216     public static IObservableSet observeSet(Realm realm, Object JavaDoc bean,
217             String JavaDoc propertyName) {
218         return observeSet(realm, bean, propertyName, null);
219     }
220
221     /**
222      * Returns a factory for creating obervable values tracking the given
223      * property of a particular bean object
224      *
225      * @param realm
226      * the realm to use
227      * @param propertyName
228      * the name of the property
229      * @return an observable value factory
230      */

231     public static IObservableFactory valueFactory(final Realm realm,
232             final String JavaDoc propertyName) {
233         return new IObservableFactory() {
234             public IObservable createObservable(Object JavaDoc target) {
235                 return observeValue(realm, target, propertyName);
236             }
237         };
238     }
239
240     /**
241      * Returns a factory for creating obervable lists tracking the given
242      * property of a particular bean object
243      *
244      * @param realm
245      * the realm to use
246      * @param propertyName
247      * the name of the property
248      * @param elementType
249      * @return an observable list factory
250      */

251     public static IObservableFactory listFactory(final Realm realm,
252             final String JavaDoc propertyName, final Class JavaDoc elementType) {
253         return new IObservableFactory() {
254             public IObservable createObservable(Object JavaDoc target) {
255                 return observeList(realm, target, propertyName, elementType);
256             }
257         };
258     }
259
260     /**
261      * Returns a factory for creating obervable sets tracking the given property
262      * of a particular bean object
263      *
264      * @param realm
265      * the realm to use
266      * @param propertyName
267      * the name of the property
268      * @return an observable set factory
269      */

270     public static IObservableFactory setFactory(final Realm realm,
271             final String JavaDoc propertyName) {
272         return new IObservableFactory() {
273             public IObservable createObservable(Object JavaDoc target) {
274                 return observeSet(realm, target, propertyName);
275             }
276         };
277     }
278
279     /**
280      * Helper method for
281      * <code>MasterDetailObservables.detailValue(master, valueFactory(realm,
282      propertyName), propertyType)</code>
283      *
284      * @param realm
285      * @param master
286      * @param propertyName
287      * @param propertyType
288      * can be <code>null</code>
289      * @return an observable value that tracks the current value of the named
290      * property for the current value of the master observable value
291      *
292      * @see MasterDetailObservables
293      */

294     public static IObservableValue observeDetailValue(Realm realm,
295             IObservableValue master, String JavaDoc propertyName, Class JavaDoc propertyType) {
296
297         IObservableValue value = MasterDetailObservables.detailValue(master,
298                 valueFactory(realm, propertyName), propertyType);
299         BeanObservableValueDecorator decorator = new BeanObservableValueDecorator(
300                 value, master, getValueTypePropertyDescriptor(master,
301                         propertyName));
302
303         return decorator;
304     }
305
306     /**
307      * Helper method for
308      * <code>MasterDetailObservables.detailList(master, listFactory(realm,
309      propertyName, propertyType), propertyType)</code>
310      *
311      * @param realm
312      * @param master
313      * @param propertyName
314      * @param propertyType
315      * can be <code>null</code>
316      * @return an observable list that tracks the named property for the current
317      * value of the master observable value
318      *
319      * @see MasterDetailObservables
320      */

321     public static IObservableList observeDetailList(Realm realm,
322             IObservableValue master, String JavaDoc propertyName, Class JavaDoc propertyType) {
323         IObservableList observableList = MasterDetailObservables.detailList(
324                 master, listFactory(realm, propertyName, propertyType),
325                 propertyType);
326         BeanObservableListDecorator decorator = new BeanObservableListDecorator(
327                 observableList, master, getValueTypePropertyDescriptor(master,
328                         propertyName));
329
330         return decorator;
331     }
332
333     /**
334      * Helper method for
335      * <code>MasterDetailObservables.detailSet(master, setFactory(realm,
336      propertyName), propertyType)</code>
337      *
338      * @param realm
339      * @param master
340      * @param propertyName
341      * @param propertyType
342      * can be <code>null</code>
343      * @return an observable set that tracks the named property for the current
344      * value of the master observable value
345      *
346      * @see MasterDetailObservables
347      */

348     public static IObservableSet observeDetailSet(Realm realm,
349             IObservableValue master, String JavaDoc propertyName, Class JavaDoc propertyType) {
350
351         IObservableSet observableSet = MasterDetailObservables.detailSet(
352                 master, setFactory(realm, propertyName, propertyType),
353                 propertyType);
354         BeanObservableSetDecorator decorator = new BeanObservableSetDecorator(
355                 observableSet, master, getValueTypePropertyDescriptor(master,
356                         propertyName));
357
358         return decorator;
359     }
360
361     /**
362      * @param realm
363      * @param bean
364      * @param propertyName
365      * @param elementType
366      * can be <code>null</code>
367      * @return an observable set that tracks the current value of the named
368      * property for given bean object
369      */

370     public static IObservableSet observeSet(Realm realm, Object JavaDoc bean,
371             String JavaDoc propertyName, Class JavaDoc elementType) {
372         PropertyDescriptor JavaDoc propertyDescriptor = getPropertyDescriptor(bean
373                 .getClass(), propertyName);
374         elementType = getCollectionElementType(elementType, propertyDescriptor);
375
376         return new JavaBeanObservableSet(realm, bean, propertyDescriptor,
377                 elementType);
378     }
379
380     /**
381      * @param realm
382      * @param propertyName
383      * @param elementType
384      * can be <code>null</code>
385      * @return an observable set factory for creating observable sets
386      */

387     public static IObservableFactory setFactory(final Realm realm,
388             final String JavaDoc propertyName, final Class JavaDoc elementType) {
389         return new IObservableFactory() {
390             public IObservable createObservable(Object JavaDoc target) {
391                 return observeSet(realm, target, propertyName, elementType);
392             }
393         };
394     }
395
396     /**
397      * @param elementType
398      * can be <code>null</code>
399      * @param propertyDescriptor
400      * @return type of the items in a collection/array property
401      */

402     private static Class JavaDoc getCollectionElementType(Class JavaDoc elementType,
403             PropertyDescriptor JavaDoc propertyDescriptor) {
404         if (elementType == null) {
405             Class JavaDoc propertyType = propertyDescriptor.getPropertyType();
406             elementType = propertyType.isArray() ? propertyType
407                     .getComponentType() : Object JavaDoc.class;
408         }
409
410         return elementType;
411     }
412
413     /**
414      * @param observable
415      * @param propertyName
416      * @return property descriptor or <code>null</code>
417      */

418     private static PropertyDescriptor JavaDoc getValueTypePropertyDescriptor(
419             IObservableValue observable, String JavaDoc propertyName) {
420         return (observable.getValueType() != null) ? getPropertyDescriptor(
421                 (Class JavaDoc) observable.getValueType(), propertyName) : null;
422     }
423 }
424
Popular Tags