KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > dbschema > nodes > SchemaRootChildren


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.dbschema.nodes;
21
22 import java.beans.PropertyChangeListener JavaDoc;
23 import java.beans.PropertyChangeEvent JavaDoc;
24 import java.util.Collection JavaDoc;
25 import java.util.Collections JavaDoc;
26 import java.util.LinkedList JavaDoc;
27 import org.openide.ErrorManager;
28
29 import org.openide.nodes.Children;
30 import org.openide.nodes.Node;
31 import org.openide.util.RequestProcessor;
32 import org.openide.util.WeakListeners;
33
34 import org.netbeans.modules.dbschema.*;
35 import org.netbeans.modules.dbschema.jdbcimpl.*;
36
37 /** Normal implementation of children for source element nodes.
38 * <P>
39 * Ordering and filtering of the children can be customized
40 * using {@link SourceElementFilter}.
41 * {@link FilterCookie} is implemented to provide a means
42 * for user customization of the filter.
43 * <p>The child list listens to changes in the source element, as well as the filter, and
44 * automatically updates itself as appropriate.
45 * <p>A child factory can be used to cause the children list to create
46 * non-{@link DefaultFactory default} child nodes, if desired, both at the time of the creation
47 * of the children list, and when new children are added.
48 * <p>The children list may be unattached to any source element temporarily,
49 * in which case it will have no children (except possibly an error indicator).
50 *
51 * @author Dafe Simonek, Jan Jancura
52 */

53 public class SchemaRootChildren extends Children.Keys {
54
55   /** The key describing state of source element */
56   static final Object JavaDoc NOT_KEY = new Object JavaDoc();
57   /** The key describing state of source element */
58   static final Object JavaDoc ERROR_KEY = new Object JavaDoc();
59   
60   /** The element whose subelements are represented. */
61   protected SchemaElement element;
62   /** Factory for obtaining class nodes. */
63   protected DBElementNodeFactory factory;
64   /** Weak listener to the element and filter changes */
65   private PropertyChangeListener JavaDoc wPropL;
66   /** Listener to the element and filter changes. This reference must
67   * be kept to prevent the listener from finalizing when we are alive */

68   private DBElementListener propL;
69   /** Flag saying whether we have our nodes initialized */
70   private boolean nodesInited = false;
71
72
73   private boolean parseStatus = false;
74   private Object JavaDoc parseLock = new Object JavaDoc();
75   
76   private org.netbeans.modules.dbschema.jdbcimpl.DBschemaDataObject obj;
77   
78   /** Create a children list.
79   * @param factory a factory for creating children
80   * @param obj database schema data object
81   */

82   public SchemaRootChildren(final DBElementNodeFactory factory, org.netbeans.modules.dbschema.jdbcimpl.DBschemaDataObject obj) {
83     super();
84     this.factory = factory;
85     this.obj = obj;
86   }
87   
88     // Children implementation ..............................................................
89

90     /* Overrides initNodes to run the preparation task of the
91     * source element, call refreshKeys and start to
92     * listen to the changes in the element too. */

93     protected void addNotify () {
94         SchemaElement el = getElement();
95
96         if (el != null) {
97             // listen to the source element property changes
98
if (wPropL == null) {
99                 propL = new DBElementListener();
100                 wPropL = WeakListeners.propertyChange(propL, el);
101             }
102             el.addPropertyChangeListener (wPropL);
103         }
104         
105         refreshKeys ();
106     }
107
108     protected void removeNotify () {
109         setKeys (java.util.Collections.EMPTY_SET);
110         nodesInited = false;
111     }
112
113     /* Create nodes for given key.
114     * The node is created using node factory.
115     */

116     protected Node[] createNodes (final Object JavaDoc key) {
117     if (key instanceof SchemaElement)
118         return new Node[] { factory.createSchemaNode((SchemaElement) key) };
119     if (NOT_KEY.equals(key))
120         return new Node[] { factory.createWaitNode() };
121         
122     // never should get here
123
ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL,
124             new Exception JavaDoc ("DbSchema: Error node created for object " + key +
125                 " (class " + ((key == null) ? "null" : key.getClass().getName()) + ")"));
126     return new Node[] { factory.createErrorNode() };
127     }
128
129
130     // main public methods ..................................................................
131

132     /** Get the currently attached source element.
133      * @return the element, or <code>null</code> if unattached
134      */

135     public SchemaElement getElement () {
136         if (element == null && !parseStatus) {
137             refreshKeys2();
138           
139             RequestProcessor.getDefault().post(new Runnable JavaDoc() {
140                 public void run () {
141                     synchronized (parseLock) {
142                         if (!parseStatus) {
143                             nodesInited = true;
144                             setElement(obj.getSchema());
145                             parseStatus = true;
146                         }
147                     }
148                 }
149             }, 0);
150         }
151
152         return element;
153     }
154
155     /** Set a new source element to get information about children from.
156     * @param element the new element, or <code>null</code> to detach
157     */

158     public void setElement (final SchemaElement element) {
159         if (this.element != null)
160             this.element.removePropertyChangeListener(wPropL);
161
162         this.element = element;
163         if (this.element != null) {
164             if (wPropL == null) {
165                 propL = new DBElementListener();
166                 wPropL = WeakListeners.propertyChange(propL, this.element);
167             }
168             else {
169                 // #55249 - need to recreate the listener with the right element
170
wPropL = WeakListeners.propertyChange(propL, this.element);
171             }
172             
173             this.element.addPropertyChangeListener(wPropL);
174         }
175         
176         // change element nodes according to the new element
177
if (nodesInited)
178             refreshKeys ();
179     }
180
181     // other methods ..........................................................................
182

183     /** Refreshes the keys according to the current state of the element and
184     * filter etc.
185     * (This method is also called when the change of properties occurs either
186     * in the filter or in the element)
187     * PENDING - (for Hanz - should be implemented better, change only the
188     * keys which belong to the changed property).
189     * @param evt the event describing changed property (or null to signalize
190     * that all keys should be refreshed)
191     */

192     public void refreshKeys () {
193         int status;
194
195         SchemaElement el = getElement();
196
197         if (parseStatus)
198             status = (el == null) ? SchemaElement.STATUS_ERROR : el.getStatus();
199         else
200             status = (el == null) ? SchemaElement.STATUS_NOT : el.getStatus();
201             
202         switch (status) {
203             case SchemaElement.STATUS_NOT:
204                 setKeys(new Object JavaDoc[] { NOT_KEY });
205                 break;
206             case SchemaElement.STATUS_ERROR:
207                 setKeys(new Object JavaDoc[] { ERROR_KEY });
208                 break;
209             case SchemaElement.STATUS_PARTIAL:
210             case SchemaElement.STATUS_OK:
211                 refreshAllKeys();
212                 break;
213         }
214     }
215   
216     private void refreshKeys2() {
217         setKeys(new Object JavaDoc[] {NOT_KEY});
218     }
219   
220     /** Updates all the keys (elements) according to the current
221     * filter and ordering */

222     private void refreshAllKeys () {
223         int[] order = SchemaElementFilter.DEFAULT_ORDER;
224
225         final LinkedList JavaDoc keys = new LinkedList JavaDoc();
226         // build ordered and filtered keys for the subelements
227
for (int i = 0; i < order.length; i++)
228             addKeysOfType(keys, order[i]);
229
230         // set new keys
231
javax.swing.SwingUtilities.invokeLater(new Runnable JavaDoc() {
232             public void run() {
233                 // #55249 - first reset to empty set, so the old keys are eliminated.
234
// Due to the way equals() is implemented on schema elements, this needs
235
// to be done: two elements are considered equal if their names are equal,
236
// even if the sets of subelements are not equal
237
setKeys2(Collections.EMPTY_SET);
238                 setKeys2(keys);
239             }
240         });
241     }
242
243     /** Filters and adds the keys of specified type to the given
244     * key collection.
245     */

246     private void addKeysOfType (Collection JavaDoc keys, final int elementType) {
247         SchemaElement schemaElement = (SchemaElement) getElement();
248         if (elementType != 0)
249             keys.add (schemaElement);
250     }
251
252     private void setKeys2(Collection JavaDoc c) {
253       setKeys(c);
254     }
255
256     // innerclasses ...........................................................................
257

258     /** The listener for listening to the property changes in the filter.
259     */

260     private final class DBElementListener implements PropertyChangeListener JavaDoc {
261         public DBElementListener () {}
262         
263         public void propertyChange (PropertyChangeEvent JavaDoc evt) {
264             boolean refresh = DBElementProperties.PROP_SCHEMA.equals(evt.getPropertyName());
265             if (!refresh && DBElementProperties.PROP_STATUS.equals(evt.getPropertyName())) {
266                 Integer JavaDoc val = (Integer JavaDoc) evt.getNewValue();
267                 refresh = ((val == null) || (val.intValue() != SchemaElement.STATUS_NOT));
268             }
269             
270             if (refresh)
271                 javax.swing.SwingUtilities.invokeLater(new Runnable JavaDoc() {
272                     public void run() {
273                         refreshKeys();
274                     }
275                 });
276         }
277     } // end of ElementListener inner class
278
}
279
Popular Tags