001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.dbschema.nodes;
043:
044: import org.openide.actions.*;
045: import org.openide.nodes.*;
046:
047: import org.openide.util.HelpCtx;
048: import org.openide.util.NbBundle;
049: import org.openide.util.actions.SystemAction;
050:
051: import org.netbeans.modules.dbschema.*;
052:
053: /** The default implementation of the db nodes factory.
054: * Uses the standard node implementations in this package.
055: */
056: public class DefaultDBFactory implements DBElementNodeFactory,
057: IconStrings {
058: public static final String WAIT = "org/openide/src/resources/wait"; // NOI18N
059:
060: public static final String ERROR = "org/openide/src/resources/error"; // NOI18N
061:
062: /** Default instance of the factory with read-write properties. */
063: public static final DefaultDBFactory READ_WRITE = new DefaultDBFactory(
064: true);
065:
066: /** Default instance of the factory with read-only properties. */
067: public static final DefaultDBFactory READ_ONLY = new DefaultDBFactory(
068: false);
069:
070: /** Should be the element nodes read-only or writeable
071: * (properties, clipboard operations,...)
072: */
073: private boolean _writeable;
074:
075: /** Create a new factory.
076: * @param writeable <code>true</code> if the produced nodes
077: * should have writable properties
078: * @see DBElementNode#writeable
079: */
080: public DefaultDBFactory(boolean writeable) {
081: _writeable = writeable;
082: }
083:
084: /* Test whether this factory produces writeable nodes.
085: * @return <code>true</code> if so
086: */
087: public boolean isWriteable() {
088: return _writeable;
089: }
090:
091: /* Returns the node asociated with specified element.
092: * @return DBElementNode
093: */
094: public Node createSchemaNode(final SchemaElement element) {
095: return new SchemaElementNode(element,
096: createSchemaChildren(element), isWriteable());
097: }
098:
099: /** Create children for a schema node.
100: * Could be subclassed to customize, e.g., the ordering of children.
101: * The default implementation used {@link SchemaChildren}.
102: * @param element a schema element
103: * @return children for the schema element
104: */
105: protected Children createSchemaChildren(SchemaElement element) {
106: return createSchemaChildren(element,
107: (isWriteable() ? READ_WRITE : READ_ONLY));
108: }
109:
110: /** Create children for a schema node, with specified factory.
111: * The default implementation used {@link SchemaChildren}.
112: * @param element a schema element
113: * @param factory the factory which will be used to create children
114: * @return children for the schema element
115: */
116: final protected Children createSchemaChildren(
117: SchemaElement element, DBElementNodeFactory factory) {
118: SchemaChildren children = new SchemaChildren(factory, element);
119: boolean writeable = isWriteable();
120:
121: return children;
122: }
123:
124: /* Returns the node asociated with specified element.
125: * @return DBElementNode
126: */
127: public Node createColumnNode(final ColumnElement element) {
128: return new ColumnElementNode(element, isWriteable());
129: }
130:
131: /* Returns the node asociated with specified element.
132: * @return DBElementNode
133: */
134: public Node createColumnPairNode(final ColumnPairElement element) {
135: return new ColumnPairElementNode(element, isWriteable());
136: }
137:
138: /** Make a node representing an index.
139: * @param element the index
140: * @return an index node instance
141: */
142: public Node createIndexNode(final IndexElement element) {
143: return new IndexElementNode(element,
144: (TableChildren) createIndexChildren(element),
145: isWriteable());
146: }
147:
148: /** Create children for an index node.
149: * Could be subclassed to customize, e.g., the ordering of children.
150: * The default implementation used {@link IndexChildren}.
151: * @param element a index element
152: * @return children for the index element
153: */
154: protected Children createIndexChildren(IndexElement element) {
155: return createIndexChildren(element, (isWriteable() ? READ_WRITE
156: : READ_ONLY));
157: }
158:
159: /** Create children for a index node, with specified factory.
160: * The default implementation used {@link IndexChildren}.
161: * @param element a index element
162: * @param factory the factory which will be used to create children
163: * @return children for the index element
164: */
165: final protected Children createIndexChildren(IndexElement element,
166: DBElementNodeFactory factory) {
167: TableChildren children = new TableChildren(factory, element);
168: boolean writeable = isWriteable();
169:
170: return children;
171: }
172:
173: /** Make a node representing a foreign key.
174: * @param element the foreign key
175: * @return a foreign key node instance
176: */
177: public Node createForeignKeyNode(final ForeignKeyElement element) {
178: return new ForeignKeyElementNode(element,
179: (TableChildren) createForeignKeyChildren(element),
180: isWriteable());
181: }
182:
183: /** Create children for an index node.
184: * Could be subclassed to customize, e.g., the ordering of children.
185: * The default implementation used {@link IndexChildren}.
186: * @param element a index element
187: * @return children for the index element
188: */
189: protected Children createForeignKeyChildren(
190: ForeignKeyElement element) {
191: return createForeignKeyChildren(element,
192: (isWriteable() ? READ_WRITE : READ_ONLY));
193: }
194:
195: /** Create children for a index node, with specified factory.
196: * The default implementation used {@link IndexChildren}.
197: * @param element a index element
198: * @param factory the factory which will be used to create children
199: * @return children for the index element
200: */
201: final protected Children createForeignKeyChildren(
202: ForeignKeyElement element, DBElementNodeFactory factory) {
203: TableChildren children = new TableChildren(factory, element);
204: boolean writeable = isWriteable();
205:
206: return children;
207: }
208:
209: /* Returns the node asociated with specified element.
210: * @return DBElementNode
211: */
212: public Node createTableNode(TableElement element) {
213: return new TableElementNode(element,
214: createTableChildren(element), isWriteable());
215: }
216:
217: /** Create children for a table node.
218: * Could be subclassed to customize, e.g., the ordering of children.
219: * The default implementation used {@link TableChildren}.
220: * @param element a table element
221: * @return children for the table element
222: */
223: protected Children createTableChildren(TableElement element) {
224: return createTableChildren(element, (isWriteable() ? READ_WRITE
225: : READ_ONLY));
226: }
227:
228: /** Create children for a table node, with specified factory.
229: * The default implementation used {@link TableChildren}.
230: * @param element a table element
231: * @param factory the factory which will be used to create children
232: * @return children for the table element
233: */
234: final protected Children createTableChildren(TableElement element,
235: DBElementNodeFactory factory) {
236: TableChildren children = new TableChildren(factory, element);
237: TableElementFilter filter = new TableElementFilter();
238: boolean writeable = isWriteable();
239:
240: filter.setOrder(new int[] { TableElementFilter.TABLE,
241: TableElementFilter.VIEW });
242: children.setFilter(filter);
243: String db = element.getDeclaringSchema()
244: .getDatabaseProductName();
245: boolean viewSupport = false;
246: if (db != null) {
247: db = db.toLowerCase();
248: viewSupport = (db.indexOf("oracle") != -1 || db
249: .indexOf("microsoft sql server") != -1) ? true
250: : false;
251: }
252:
253: if (((TableElement) element).isTableOrView() || viewSupport)
254: // if (element.isTableOrView())
255: children.add(new Node[] {
256: new ElementCategoryNode(0, factory, element,
257: writeable),
258: new ElementCategoryNode(1, factory, element,
259: writeable),
260: new ElementCategoryNode(2, factory, element,
261: writeable), });
262: else
263: children.add(new Node[] { new ElementCategoryNode(0,
264: factory, element, writeable), });
265:
266: return children;
267: }
268:
269: /* Creates and returns the instance of the node
270: * representing the status 'WAIT' of the DataNode.
271: * It is used when it spent more time to create elements hierarchy.
272: * @return the wait node.
273: */
274: public Node createWaitNode() {
275: AbstractNode n = new AbstractNode(Children.LEAF);
276: n.setName(NbBundle.getMessage(DefaultDBFactory.class, "Wait"));
277: n.setIconBase(WAIT);
278: return n;
279: }
280:
281: /* Creates and returns the instance of the node
282: * representing the status 'ERROR' of the DataNode
283: * @return the error node.
284: */
285: public Node createErrorNode() {
286: AbstractNode n = new AbstractNode(Children.LEAF);
287: n.setName(NbBundle.getMessage(DefaultDBFactory.class, "Error")); // NO18N
288: n.setIconBase(ERROR);
289: return n;
290: }
291:
292: /** Array of the actions of the category nodes. */
293: private static final SystemAction[] CATEGORY_ACTIONS = new SystemAction[] { SystemAction
294: .get(ToolsAction.class), };
295:
296: /** The names of the category nodes */
297: static final String[] NAMES = new String[] {
298: NbBundle.getMessage(DefaultDBFactory.class, "Columns"), //NOI18N
299: NbBundle.getMessage(DefaultDBFactory.class, "Indexes"), //NOI18N
300: NbBundle.getMessage(DefaultDBFactory.class, "FKs"), //NOI18N
301: NbBundle.getMessage(DefaultDBFactory.class, "Tables") //NOI18N
302: };
303:
304: /** Filters under each category node */
305: static final int[][] FILTERS = new int[][] {
306: { TableElementFilter.COLUMN },
307: { TableElementFilter.INDEX }, { TableElementFilter.FK },
308: { SchemaElementFilter.TABLE }, };
309:
310: /** Array of the icons used for category nodes */
311: static final String[] CATEGORY_ICONS = new String[] {
312: COLUMNS_CATEGORY, INDEXES_CATEGORY, FKS_CATEGORY, TABLE };
313:
314: /**
315: * Category node - represents one section under table element node -
316: * columns, indexes, fks.
317: */
318: static class ElementCategoryNode extends AbstractNode {
319: /** The table element for this node */
320: DBElement element;
321:
322: /** The type of the category node - for new types. */
323: int newTypeIndex;
324:
325: /** Create new element category node for the specific category.
326: * @param index The index of type (0=columns, 1=indexes, 2=fks)
327: * @param factory The factory which is passed down to the table children
328: * object
329: * @param element the table element for which this node is created
330: */
331: ElementCategoryNode(int index, DBElementNodeFactory factory,
332: TableElement element, boolean writeable) {
333: this (index, new TableChildren(factory, element));
334: this .element = element;
335: newTypeIndex = writeable ? index : -1;
336: switch (index) {
337: case 0:
338: setName(NbBundle.getMessage(DefaultDBFactory.class,
339: "Columns"));
340: break; //NOI18N
341: case 1:
342: setName(NbBundle.getMessage(DefaultDBFactory.class,
343: "Indexes"));
344: break; //NOI18N
345: case 2:
346: setName(NbBundle.getMessage(DefaultDBFactory.class,
347: "FKs"));
348: break; //NOI18N
349: }
350: }
351:
352: ElementCategoryNode(int index, DBElementNodeFactory factory,
353: SchemaElement element, boolean writeable) {
354: this (index, new SchemaChildren(factory, element));
355: this .element = element;
356: newTypeIndex = writeable ? index : -1;
357: setName(NbBundle.getMessage(DefaultDBFactory.class,
358: "Tables")); //NOI18N
359: }
360:
361: /** Create new element node.
362: * @param index The index of type (0=columns, 1=indexes, 2=fks)
363: * @param children the table children of this node
364: */
365: private ElementCategoryNode(int index, TableChildren children) {
366: super (children);
367: setDisplayName(NAMES[index]);
368: systemActions = CATEGORY_ACTIONS;
369: TableElementFilter filter = new TableElementFilter();
370: filter.setOrder(FILTERS[index]);
371: children.setFilter(filter);
372: setIconBase(CATEGORY_ICONS[index]);
373: }
374:
375: private ElementCategoryNode(int index, SchemaChildren children) {
376: super (children);
377: setDisplayName(NAMES[index]);
378: systemActions = CATEGORY_ACTIONS;
379: setIconBase(CATEGORY_ICONS[index]);
380: }
381:
382: public HelpCtx getHelpCtx() {
383: return new HelpCtx("dbschema_ctxhelp_wizard"); //NOI18N
384: }
385: }
386: }
|