/*
* Copyright (C) 2002-2004 Colin Bell
* colbell@users.sourceforge.net
*
* This library 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 toS the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.List;
import javax.swing.tree.TreePath;
import net.sourceforge.squirrel_sql.client.session.ISession;
import net.sourceforge.squirrel_sql.fw.gui.GUIUtils;
import net.sourceforge.squirrel_sql.fw.sql.DatabaseObjectInfo;
import net.sourceforge.squirrel_sql.fw.sql.DatabaseObjectType;
import net.sourceforge.squirrel_sql.fw.sql.IDatabaseObjectInfo;
import net.sourceforge.squirrel_sql.fw.util.log.ILogger;
import net.sourceforge.squirrel_sql.fw.util.log.LoggerController;
/**
* This class actually loads the tree.
* Note: This class was extracted from {@link ObjectTree} to make it more testable.
*/
public class TreeLoader
{
/** Logger for this class. */
private static final ILogger s_log =
LoggerController.createLogger(TreeLoader.class);
private ObjectTree objectTree;
private ObjectTreeNode _parentNode;
private INodeExpander[] _expanders;
private boolean _selectParentNode;
private ObjectTreeModel model;
private ISession session;
TreeLoader(ISession session, ObjectTree objectTree, ObjectTreeModel model, ObjectTreeNode parentNode, INodeExpander[] expanders,
boolean selectParentNode)
{
super();
this.session = session;
this.objectTree = objectTree;
this.model = model;
_parentNode = parentNode;
_expanders = expanders;
_selectParentNode= selectParentNode;
}
void execute()
{
try
{
try
{
ObjectTreeNode loadingNode = showLoadingNode();
try
{
loadChildren();
}
finally
{
if (_parentNode.isNodeChild(loadingNode)){
_parentNode.remove(loadingNode);
}
}
}
finally
{
fireStructureChanged(_parentNode);
if (_selectParentNode)
{
this.objectTree.clearSelection();
this.objectTree.setSelectionPath(new TreePath(_parentNode.getPath()));
}
}
}
catch (Throwable ex)
{
final String msg = "Error: " + _parentNode.toString();
s_log.error(msg, ex);
this.session.showErrorMessage(msg + ": " + ex.toString());
}
}
/**
* This adds a node to the tree that says "Loading..." in order to give
* feedback to the user.
*/
private ObjectTreeNode showLoadingNode()
{
IDatabaseObjectInfo doi = new DatabaseObjectInfo(null, null,
"Loading...", DatabaseObjectType.OTHER,
this.session.getSQLConnection().getSQLMetaData());
ObjectTreeNode loadingNode = new ObjectTreeNode(this.session, doi);
_parentNode.add(loadingNode);
fireStructureChanged(_parentNode);
return loadingNode;
}
/**
* This expands the parent node and shows all its children.
*/
private void loadChildren() throws SQLException
{
boolean noChildrenFound = true;
for (int i = 0; i < _expanders.length; ++i)
{
boolean nodeTypeAllowsChildren = false;
DatabaseObjectType lastDboType = null;
List<ObjectTreeNode> list = _expanders[i].createChildren(this.session, _parentNode);
if(list.isEmpty() == false){
noChildrenFound = false;
}
Iterator<ObjectTreeNode> it = list.iterator();
while (it.hasNext())
{
Object nextObj = it.next();
if (nextObj instanceof ObjectTreeNode)
{
ObjectTreeNode childNode = (ObjectTreeNode)nextObj;
if (childNode.getExpanders().length >0)
{
childNode.setAllowsChildren(true);
}
else
{
DatabaseObjectType childNodeDboType = childNode.getDatabaseObjectType();
if (childNodeDboType != lastDboType)
{
this.objectTree.getTypedModel().addKnownDatabaseObjectType(childNodeDboType);
lastDboType = childNodeDboType;
if (this.model.getExpanders(childNodeDboType).length > 0)
{
nodeTypeAllowsChildren = true;
}
else
{
nodeTypeAllowsChildren = false;
}
}
childNode.setAllowsChildren(nodeTypeAllowsChildren);
}
_parentNode.add(childNode);
}
}
}
// We cann't use getChildCount, because the node has a temporary child called "Loading..."
_parentNode.setNoChildrenFoundWithExpander(noChildrenFound);
}
/**
* Let the object tree model know that its structure has changed.
*/
private void fireStructureChanged(final ObjectTreeNode node)
{
GUIUtils.processOnSwingEventThread(new Runnable()
{
public void run()
{
model.nodeStructureChanged(node);
}
});
}
}