KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jface > internal > databinding > provisional > beans > BeanObservableFactory


1 /*******************************************************************************
2  * Copyright (c) 2005, 2006 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  *******************************************************************************/

11 package org.eclipse.jface.internal.databinding.provisional.beans;
12
13 import java.beans.BeanInfo JavaDoc;
14 import java.beans.IntrospectionException JavaDoc;
15 import java.beans.Introspector JavaDoc;
16 import java.beans.PropertyDescriptor JavaDoc;
17 import java.util.Collection JavaDoc;
18
19 import org.eclipse.jface.internal.databinding.internal.beans.JavaBeanObservableList;
20 import org.eclipse.jface.internal.databinding.internal.beans.JavaBeanObservableMultiMapping;
21 import org.eclipse.jface.internal.databinding.internal.beans.JavaBeanObservableValue;
22 import org.eclipse.jface.internal.databinding.provisional.BindingException;
23 import org.eclipse.jface.internal.databinding.provisional.DataBindingContext;
24 import org.eclipse.jface.internal.databinding.provisional.description.Property;
25 import org.eclipse.jface.internal.databinding.provisional.description.TableModelDescription;
26 import org.eclipse.jface.internal.databinding.provisional.factories.IObservableFactory;
27 import org.eclipse.jface.internal.databinding.provisional.observable.IObservable;
28 import org.eclipse.jface.internal.databinding.provisional.observable.list.IObservableList;
29
30 /**
31  * A factory for creating observable objects for properties of plain Java
32  * objects with JavaBeans-style notification.
33  *
34  * This factory supports the following description objects:
35  * <ul>
36  * <li>org.eclipse.jface.databinding.PropertyDescription:
37  * <ul>
38  * <li>Returns an observable value representing the specified value property of
39  * the given object, if {@link Property#isCollectionProperty()} returns false</li>
40  * <li>Returns an observable collection representing the specified collection
41  * property of the given object, if {@link Property#isCollectionProperty()}
42  * returns false</li>
43  * </ul>
44  * </li>
45  * </ul>
46  *
47  * @since 1.0
48  *
49  */

50 final public class BeanObservableFactory implements IObservableFactory {
51
52     private final DataBindingContext dataBindingContext;
53
54     private final Class JavaDoc[] includedTypes;
55
56     private final Class JavaDoc[] excludedTypes;
57
58     /**
59      * @param dataBindingContext
60      * @param includedTypes
61      * a list of supertypes to include, or null for including all
62      * types
63      * @param excludedTypes
64      * a list of supertypes to exclude, or null for not excluding any
65      * types
66      */

67     public BeanObservableFactory(DataBindingContext dataBindingContext,
68             Class JavaDoc[] includedTypes, Class JavaDoc[] excludedTypes) {
69         this.dataBindingContext = dataBindingContext;
70         this.includedTypes = includedTypes;
71         this.excludedTypes = excludedTypes;
72     }
73
74     public IObservable createObservable(Object JavaDoc description) {
75         if (description instanceof Property) {
76             Property property = (Property) description;
77             if (property.getObject() != null) {
78                 Object JavaDoc object = property.getObject();
79                 Class JavaDoc objectClass = object.getClass();
80                 if (includedTypes != null) {
81                     boolean included = false;
82                     for (int i = 0; i < includedTypes.length; i++) {
83                         if (includedTypes[i].isAssignableFrom(objectClass)) {
84                             included = true;
85                             break;
86                         }
87                     }
88                     if (!included) {
89                         // object's class is not a subtype of any type on the
90
// inclusion list
91
return null;
92                     }
93                 }
94                 if (excludedTypes != null) {
95                     for (int i = 0; i < excludedTypes.length; i++) {
96                         if (excludedTypes[i].isAssignableFrom(objectClass)) {
97                             // object's class is a subtype of one of the
98
// exclusions
99
return null;
100                         }
101                     }
102                 }
103                 BeanInfo JavaDoc beanInfo;
104                 try {
105                     beanInfo = Introspector.getBeanInfo(objectClass);
106                 } catch (IntrospectionException JavaDoc e) {
107                     // cannot introspect, give up
108
return null;
109                 }
110                 PropertyDescriptor JavaDoc[] propertyDescriptors = beanInfo
111                         .getPropertyDescriptors();
112                 for (int i = 0; i < propertyDescriptors.length; i++) {
113                     PropertyDescriptor JavaDoc descriptor = propertyDescriptors[i];
114                     if (descriptor.getName().equals(property.getPropertyID())) {
115                         if (descriptor.getPropertyType().isArray()
116                                 || Collection JavaDoc.class.isAssignableFrom(descriptor
117                                         .getPropertyType())) {
118                             // If we are a collection them the type must be
119
// explicitly specified in order to be edited.
120
// There is no way to derive it by name matching
121
// (because of different ways of plurals being made,
122
// e.g. getFlies() and addFly(Fly aFly) or
123
// getHooves() and addHoof(Hoof aHoof)
124
Class JavaDoc elementType = descriptor.getPropertyType()
125                                     .isArray() ? descriptor.getPropertyType()
126                                     .getComponentType() : property
127                                     .getPropertyType();
128                             if (elementType == null) {
129                                 // If we don't know the element type, use the
130
// polymorphic converter
131
// This should usually get us object to string,
132
// but won't get us string
133
// back to the object. At least this handles the
134
// read-only case for
135
// tables and handles Combos and Lists.
136
elementType = Object JavaDoc.class;
137                             }
138                             return new JavaBeanObservableList(object,
139                                     descriptor, elementType);
140                         }
141                         return new JavaBeanObservableValue(object, descriptor);
142                     }
143                 }
144             }
145             // else if (description instanceof ITree)
146
// return new JavaBeanObservableTree((ITree) description);
147
// else if (description instanceof TreeModelDescription) {
148
// Object root = ((TreeModelDescription) description).getRoot();
149
// if (root == null || !(root instanceof IObservable)
150
// && !(root instanceof Property)) // TODO workaround until the
151
// // context's factory is
152
// // driven first
153
// return new JavaBeanObservableTree(new JavaBeanTree(
154
// (TreeModelDescription) description));
155
} else if (description instanceof TableModelDescription) {
156             TableModelDescription tableModelDescription = (TableModelDescription) description;
157             IObservable collectionObservable = tableModelDescription.getObservableList();
158             if (collectionObservable == null) {
159                 collectionObservable = dataBindingContext
160                     .createObservable(tableModelDescription
161                             .getCollectionProperty());
162             }
163             if (collectionObservable == null) {
164                 return null;
165             }
166             IObservableList readableList;
167             if (collectionObservable instanceof IObservableList) {
168                 readableList = (IObservableList) collectionObservable;
169             } else {
170                 throw new BindingException(
171                         "collection inside a TableModelDescription needs to be IObservableList"); //$NON-NLS-1$
172
}
173             Object JavaDoc[] columnIDs = tableModelDescription.getColumnIDs();
174             PropertyDescriptor JavaDoc[] propertyDescriptors = new PropertyDescriptor JavaDoc[columnIDs.length];
175             Class JavaDoc elementType = (Class JavaDoc) readableList.getElementType();
176             for (int i = 0; i < columnIDs.length; i++) {
177                 propertyDescriptors[i] = getPropertyDescriptor(elementType,
178                         (String JavaDoc) columnIDs[i]);
179             }
180             return new JavaBeanObservableMultiMapping(readableList,
181                     propertyDescriptors);
182         }
183         return null;
184     }
185
186     private PropertyDescriptor JavaDoc getPropertyDescriptor(Class JavaDoc elementType,
187             String JavaDoc propertyName) {
188         BeanInfo JavaDoc beanInfo;
189         try {
190             beanInfo = Introspector.getBeanInfo(elementType);
191         } catch (IntrospectionException JavaDoc ex) {
192             throw new BindingException("Cannot introspect " + elementType, ex); //$NON-NLS-1$
193
}
194         PropertyDescriptor JavaDoc[] propertyDescriptors = beanInfo
195                 .getPropertyDescriptors();
196         for (int i = 0; i < propertyDescriptors.length; i++) {
197             if (propertyDescriptors[i].getName().equals(propertyName)) {
198                 return propertyDescriptors[i];
199             }
200         }
201         return null;
202     }
203 }
204
Popular Tags