KickJava   Java API By Example, From Geeks To Geeks.

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


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.awt.datatransfer.Transferable JavaDoc;
23 import java.awt.datatransfer.DataFlavor JavaDoc;
24 import java.beans.*;
25 import java.io.IOException JavaDoc;
26 import java.lang.reflect.InvocationTargetException JavaDoc;
27
28 import org.openide.nodes.*;
29 import org.openide.util.HelpCtx;
30 import org.openide.util.NbBundle;
31 import org.openide.util.WeakListeners;
32 import org.openide.util.actions.SystemAction;
33 import org.openide.util.datatransfer.ExTransferable;
34
35 import org.netbeans.modules.dbschema.*;
36
37 /** Superclass of nodes representing elements in the database metadata
38  * hierarchy.
39  * <p>Element nodes generally:
40  * <ul>
41  * <li>Have an associated icon, according to {@link #resolveIconBase}.
42  * <li>Have a display name based on the element's properties.
43  * <li>Have some node properties (displayable on the property sheet), according
44  * to the element's properties, and with suitable editors.
45  * <li>Permit renames and deletes, if a member element and writeable.
46  * <li>As permitted by the element, and a writable flag in the node,
47  * permit cut/copy/paste operations, as well as creation of new members.
48  * </ul>
49  */

50 public abstract class DBElementNode extends AbstractNode implements IconStrings, DBElementProperties, Node.Cookie {
51
52     /** Default return value of getIconAffectingProperties method. */
53     private static final String JavaDoc[] ICON_AFFECTING_PROPERTIES = new String JavaDoc[]{};
54
55     /** Associated element. */
56     protected DBElement element;
57
58     /** Is this node read-only or are modifications permitted? */
59     protected boolean writeable;
60
61     /** Listener to forbid its garbage collection */
62     private transient PropertyChangeListener listener;
63
64     /** Create a new element node.
65      *
66      * @param element element to represent
67      * @param children child nodes
68      * @param writeable <code>true</code> if this node should allow
69      * modifications. These include writable properties, clipboard operations,
70      * deletions, etc.
71      */

72     public DBElementNode(DBElement element, Children children, boolean writeable) {
73         super(children);
74         this.element = element;
75         this.writeable = writeable;
76         setIconBase(resolveIconBase());
77         setName(element.getName().getName());
78         setDisplayName(element.getName().getName());
79         listener = new ElementListener();
80         element.addPropertyChangeListener(WeakListeners.propertyChange(listener, element));
81     }
82
83     /** Get the currently appropriate icon base.
84      * Subclasses should make this sensitive to the state of the element--for
85      * example, a pk column may have a different icon than a regular one.
86      * The icon will be automatically changed whenever a {@link
87      * #getIconAffectingProperties relevant} change is made to the element.
88      * @return icon base
89      * @see AbstractNode#setIconBase
90      */

91     abstract protected String JavaDoc resolveIconBase();
92
93     /** Get the names of all element properties which might affect the choice of
94      * icon. The default implementation returns an empty array.
95      * @return the property names, from {@link DBElementProperties}
96      */

97     protected String JavaDoc[] getIconAffectingProperties() {
98         return ICON_AFFECTING_PROPERTIES;
99     }
100   
101     public HelpCtx getHelpCtx () {
102         return new HelpCtx("dbschema_ctxhelp_wizard"); //NOI18N
103
}
104
105     /** Test whether this node can be renamed.
106      * The default implementation assumes it can if this node is {@link
107      * #writeable}.
108      * @return <code>true</code> if this node can be renamed
109      */

110     public boolean canRename () {
111         return writeable;
112     }
113
114     /** Test whether this node can be deleted.
115      * The default implementation assumes it can if this node is {@link
116      * #writeable}.
117      * @return <code>true</code> if this node can be renamed
118      */

119     public boolean canDestroy () {
120         return writeable;
121     }
122
123     /* Copy this node to the clipboard.
124      *
125      * @return {@link ExTransferable.Single} with one flavor, {@link
126      * NodeTransfer#nodeCopyFlavor}
127      * @throws IOException if it could not copy
128      */

129     public Transferable JavaDoc clipboardCopy () throws IOException JavaDoc {
130         ExTransferable ex = ExTransferable.create(super.clipboardCopy());
131
132         ex.put(new ElementStringTransferable());
133
134         return ex;
135     }
136
137     /* Cut this node to the clipboard.
138      *
139      * @return {@link ExTransferable.Single} with one flavor, {@link
140      * NodeTransfer#nodeCopyFlavor}
141      * @throws IOException if it could not cut
142      */

143     public Transferable JavaDoc clipboardCut () throws IOException JavaDoc {
144         if (!writeable)
145             throw new IOException JavaDoc();
146
147         ExTransferable ex = ExTransferable.create(super.clipboardCut());
148         ex.put(new ElementStringTransferable());
149         
150         return ex;
151     }
152
153     /** Transferable for elements as String. */
154     class ElementStringTransferable extends ExTransferable.Single {
155         /** Construct new Transferable for this node. */
156         ElementStringTransferable() { super(DataFlavor.stringFlavor); }
157
158         /** @return the data as String */
159         protected Object JavaDoc getData() { return element.toString(); }
160     }
161   
162     /** Test whether this node can be copied.
163      * The default implementation returns <code>true</code>.
164      * @return <code>true</code> if it can
165      */

166     public boolean canCopy() {
167         return true;
168     }
169
170     /** Test whether this node can be cut.
171      * The default implementation assumes it can if this node is {@link
172      * #writeable}.
173      * @return <code>true</code> if it can
174      */

175     public boolean canCut() {
176         return writeable;
177     }
178
179     /** Calls super.fireCookieChange. The reason why is redefined
180      * is only to allow the access from this package.
181      */

182     void superFireCookieChange() {
183         fireCookieChange();
184     }
185
186     /** Get a cookie from this node.
187      * First tries the node itself, then {@link DBElement#getCookie}.
188      * Since {@link DBElement} implements <code>Node.Cookie</code>, it is
189      * possible to find the element from a node using code such as:
190      * <p><code><pre>
191      * Node someNode = ...;
192      * ColumnElement element =
193      * (ColumnElement)someNode.getCookie(ColumnElement.class);
194      * if (element != null) { ... }
195      * </pre></code>
196      * @param type the cookie class
197      * @return the cookie or <code>null</code>
198      */

199     public Node.Cookie getCookie (Class JavaDoc type) {
200         Node.Cookie c = super.getCookie(type);
201
202         if (c == null && (type.isAssignableFrom(DBElementProvider.class) ||
203             type.isAssignableFrom(DBElement.class)))
204         {
205             c = new DBElementProvider(element);
206         }
207
208         return c;
209     }
210       
211     /** Test for equality.
212      * @return <code>true</code> if the represented {@link DBElement}s are equal
213      */

214     public boolean equals (Object JavaDoc o) {
215         return ((o instanceof DBElementNode) && (element.equals(((DBElementNode)o).element)));
216     }
217
218     /** Get a hash code.
219      * @return the hash code from the represented {@link DBElement}
220      */

221     public int hashCode() {
222         return element.hashCode();
223     }
224
225     /** Create a node property representing the element's name.
226      * @param canW if <code>false</code>, property will be read-only
227      * @return the property.
228      */

229     protected Node.Property createNameProperty (boolean canW) {
230         return new ElementProp(Node.PROP_NAME, String JavaDoc.class,canW) {
231             /** Gets the value */
232             public Object JavaDoc getValue () {
233                 return ((DBElement) element).getName().getFullName();
234             }
235         };
236     }
237
238     void superSetName(String JavaDoc name) {
239         super.setName(name);
240     }
241   
242     // ================== Element listener =================================
243

244     /** Listener for changes of the element's property changes.
245      * It listens and changes updates the iconBase and displayName
246      * if the changed property could affect them.
247      */

248     private class ElementListener implements PropertyChangeListener {
249             public ElementListener () {}
250             
251         /** Called when any element's property changed.
252         */

253         public void propertyChange (PropertyChangeEvent evt) {
254             String JavaDoc propName = evt.getPropertyName();
255
256             if (propName == null) {
257                 setIconBase(resolveIconBase());
258             } else {
259                 // icon
260
String JavaDoc[] iconProps = getIconAffectingProperties();
261                 for (int i = 0; i < iconProps.length; i++)
262                     if (iconProps[i].equals(propName)) {
263                         setIconBase(resolveIconBase());
264                         break;
265                     }
266
267                 if (propName.equals(Node.PROP_NAME)) {
268                     // set inherited name - this code should rather in
269
// DBMemberElementNode,
270
// but we safe one instance of listener for each node
271
// if it will be here. [Petr]
272
try {
273                         superSetName(((DBMemberElement)DBElementNode.this.element).getName().toString());
274                     } catch (ClassCastException JavaDoc e) {
275                         // it is strange - PROP_NAME has only member element.
276
}
277                 } else {
278                     if (propName.equals(Node.PROP_COOKIE)) {
279                         // Fires the changes of the cookies of the element.
280
superFireCookieChange();
281                         return;
282                     }
283                 }
284             }
285             DBElementNode.this.firePropertyChange(evt.getPropertyName(), evt.getOldValue(), evt.getNewValue());
286         }
287     }
288
289     // ================== Property support for element nodes =================
290

291     /** Property support for element nodes properties.
292      */

293     static abstract class ElementProp extends PropertySupport {
294         /** Constructs a new ElementProp - support for properties of
295          * element hierarchy nodes.
296          *
297          * @param name The name of the property
298          * @param type The class type of the property
299          * @param canW The canWrite flag of the property
300          */

301         public ElementProp (String JavaDoc name, Class JavaDoc type, boolean canW) {
302             super(name, type, NbBundle.getMessage(DBElementNode.class, "PROP_" + name), NbBundle.getMessage(DBElementNode.class, "HINT_" + name), true, canW); //NOI18N
303
}
304
305         /** Setter for the value. This implementation only tests
306          * if the setting is possible.
307          *
308          * @param val the value of the property
309          * @exception IllegalAccessException when this ElementProp was
310          * constructed like read-only.
311          */

312         public void setValue (Object JavaDoc val) throws IllegalArgumentException JavaDoc, IllegalAccessException JavaDoc, InvocationTargetException JavaDoc {
313             if (!canWrite())
314                 throw new IllegalAccessException JavaDoc(NbBundle.getMessage(DBElementNode.class, "MSG_Cannot_Write")); //NOI18N
315
}
316
317     }
318 }
319
Popular Tags