/* * Copyright (C) 2006 Davy Vanherbergen * dvanherbergen@users.sourceforge.net * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sourceforge.sqlexplorer.dbstructure.nodes; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import net.sourceforge.sqlexplorer.dbproduct.MetaDataSession; import net.sourceforge.sqlexplorer.plugin.SQLExplorerPlugin; import net.sourceforge.sqlexplorer.util.ImageUtil; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Composite; /** * Abstract implementation of INode. Extend this class to create your own node * types. * * @author Davy Vanherbergen */ public abstract class AbstractNode implements INode { private static final Log _logger = LogFactory.getLog(AbstractNode.class); protected ArrayList<INode> _children = new ArrayList<INode>(); protected boolean _childrenLoaded = false; protected Image _image; protected String _imageKey = "Images.DefaultNodeImage"; protected String _expandedImageKey = null; protected boolean _isExpanded = false; protected String _name; protected INode _parent; protected MetaDataSession _session; protected String _type; // Added 20130409 TDQ-7101 yyin protected String _schemaName = null; public AbstractNode(String name) { this._name = name; } public AbstractNode(String name, MetaDataSession session) { this._name = name; this._session = session; } public AbstractNode(INode parent, String name, MetaDataSession session, String type) { this._parent = parent; this._name = name; this._session = session; this._type = type; } /** * Adds a new child node to this node * * @param child node */ public final void addChildNode(INode childNode) { _children.add(childNode); } /* * (non-Javadoc) * * @see net.sourceforge.sqlexplorer.dbstructure.nodes.INode#fillDetailComposite(org.eclipse.swt.widgets.Composite) */ public void fillDetailComposite(Composite composite) { // noop } /** * Get an iterator to all child nodes. If child nodes haven't been loaded * yet, loading is triggered. * * @return Iterator of child elements */ public final Iterator getChildIterator() { if (!_childrenLoaded) { load(); } return _children.iterator(); } /** * Get all the children of this node. If child nodes haven't been loaded * yet, loading is triggered. * * @return All child nodes of this node. * @see net.sourceforge.sqlexplorer.db.INode#getChildren() */ public final INode[] getChildNodes() { if (!_childrenLoaded) { load(); Comparator comp = getComparator(); if (comp != null) { Collections.sort(_children, getComparator()); } } return (INode[]) _children.toArray(new INode[] {}); } /** * Override this method to implement custom sorting of child nodes. */ public Comparator getComparator() { return new Comparator() { public int compare(Object arg0, Object arg1) { if (arg0 == null || arg1 == null) { return 0; } String name0 = ((INode) arg0).getName(); String name1 = ((INode) arg1).getName(); if (name0 == null || name1 == null) { return 0; } return name0.compareTo(name1); } }; } /** * Override this method to change the image that is displayed for this node * in the database structure outline. */ public final Image getExpandedImage() { if (_expandedImageKey == null) { return null; } return ImageUtil.getImage(_expandedImageKey); } /** * Override this method to change the image that is displayed for this node * in the database structure outline. */ public Image getImage() { if (_image != null) { return _image; } if (_imageKey == null) { return _image; } return ImageUtil.getImage(_imageKey); } public String getLabelDecoration() { return null; } /** * Override this method to change the text that is displayed in the database * structure outline for this node. */ public String getLabelText() { return getName(); } /** * @return simple name for this node. */ public String getName() { if (_name == null) { return "<null>"; } return _name; } /** * Get the parent of this node. * * @return Parent node of this node. * @see net.sourceforge.sqlexplorer.db.INode#getParent() */ public final INode getParent() { return _parent; } /* * (non-Javadoc) * * @see net.sourceforge.sqlexplorer.dbstructure.nodes.INode#getUniqueIdentifier() */ public String getQualifiedName() { return getName(); } public String getSchemaOrCatalogName() { INode node = this; while (!(node.getType().equalsIgnoreCase("schema") || node.getType().equalsIgnoreCase("catalog"))) { node = node.getParent(); if (node == null) { return null; } } return node.getName(); } /** * @return SessionTreeNode for this node. */ public final MetaDataSession getSession() { return _session; } public String getType() { return _type; } /** * Implement this method to return a unique identifier for this node. It is * used to identify the node in the detail cache. * * @see net.sourceforge.sqlexplorer.dbstructure.nodes.INode#getUniqueIdentifier() */ public String getUniqueIdentifier() { return getParent().getQualifiedName() + "." + getQualifiedName(); } /** * Checks if this node has children. If child nodes haven't been loaded yet, * this method always returns true. This defers the loading of metadata used * in the database structure outline until it is actually required. * * @return true if this node has children. */ public final boolean hasChildNodes() { if (!_childrenLoaded && !isEndNode()) { return true; } if (_children == null || _children.size() == 0) { return false; } return true; } /** * Returns true. Override this method to return false if your node cannot * have any children. This will avoid the twistie being displayed in the * database structure outline for nodes that cannot have children. * * @see net.sourceforge.sqlexplorer.dbstructure.nodes.INode#isEndNode() */ public boolean isEndNode() { return false; } public boolean isExpanded() { return _isExpanded; } /** * Loads all the children for this node if they haven't been loaded yet. */ public final void load() { if (!_childrenLoaded) { try { if (_logger.isDebugEnabled()) { _logger.debug("Loading child nodes for " + _name); } loadChildren(); _childrenLoaded = true; } catch (AbstractMethodError e) { SQLExplorerPlugin.error("Could not load child nodes for " + _name, e); } catch (Throwable e) { SQLExplorerPlugin.error("Could not load child nodes for " + _name, e); } } } /** * Load all the children of this node here. Do not call this method, but use * load() instead. */ public abstract void loadChildren(); /** * Refresh. This will clear the nodes' children and reload them. It will * also update the dictionary for this node & descendants */ public final void refresh() { _children.clear(); _childrenLoaded = false; load(); } public final void setExpanded(boolean expanded) { _isExpanded = expanded; } public void setImage(Image image) { this._image = image; } protected void setImageKey(String imageKey) { this._imageKey = imageKey; } public String getExpandedImageKey() { return _expandedImageKey; } public String get_imageKey() { return _imageKey; } protected void setExpandedImageKey(String expandedImageKey) { this._expandedImageKey = expandedImageKey; } /** * Set parent node for this node. * * @param parent */ public final void setParent(INode parent) { this._parent = parent; } /** * Set sessiontreenode for this node * * @param session */ public final void setSession(MetaDataSession session) { this._session = session; } public void setType(String type) { this._type = type; } /* * (non-Javadoc) * * @see java.lang.Object#toString() */ public String toString() { return getName(); } /* * (non-Javadoc) * * @see net.sourceforge.sqlexplorer.dbstructure.nodes.INode#setSchemaName(java.lang.String) */ public void setSchemaName(String schemaName) { // mainly used for catalog + schema _schemaName = schemaName; } public String getSchemaName() { return this._schemaName; } public boolean isChildrenLoaded() { return _childrenLoaded; } }