Package net.sourceforge.squirrel_sql.plugins.oracle.explainplan

Source Code of net.sourceforge.squirrel_sql.plugins.oracle.explainplan.ExplainPlanExecuter$ExplainPlanModel$ExplainRow

package net.sourceforge.squirrel_sql.plugins.oracle.explainplan;
/*
* Copyright (C) 2004 Jason Height
* jmheight@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 to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

import java.awt.BorderLayout;
import java.awt.Component;
import java.math.BigDecimal;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.JTree;
import javax.swing.table.TableColumnModel;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;

import net.sourceforge.squirrel_sql.client.session.ISQLEntryPanel;
import net.sourceforge.squirrel_sql.client.session.ISQLPanelAPI;
import net.sourceforge.squirrel_sql.client.session.ISession;
import net.sourceforge.squirrel_sql.client.session.event.ISQLResultExecuterTabListener;
import net.sourceforge.squirrel_sql.client.session.event.SQLResultExecuterTabEvent;
import net.sourceforge.squirrel_sql.client.session.mainpanel.IResultTab;
import net.sourceforge.squirrel_sql.client.session.mainpanel.ISQLResultExecuter;
import net.sourceforge.squirrel_sql.client.session.schemainfo.SchemaInfo;
import net.sourceforge.squirrel_sql.fw.id.IntegerIdentifierFactory;
import net.sourceforge.squirrel_sql.fw.sql.ISQLConnection;
import net.sourceforge.squirrel_sql.fw.sql.SQLUtilities;
import net.sourceforge.squirrel_sql.fw.util.StringManager;
import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory;
import net.sourceforge.squirrel_sql.fw.util.log.ILogger;
import net.sourceforge.squirrel_sql.fw.util.log.LoggerController;

import com.sun.treetable.AbstractTreeTableModel;
import com.sun.treetable.JTreeTable;
import com.sun.treetable.TreeTableModel;


/**
* This is the panel where Oracle Explain Plans are executed and results presented.
*
*/
public class ExplainPlanExecuter extends JPanel implements ISQLResultExecuter {

    private static final long serialVersionUID = 1L;

    private static final StringManager s_stringMgr =
    StringManagerFactory.getStringManager(ExplainPlanExecuter.class);


  /** Logger for this class. */
  private static final ILogger s_log = LoggerController.createLogger(
    ExplainPlanExecuter.class);

  transient private ISession _session;
  private boolean checkedPlanTable = false;
  /** Factory for generating unique IDs for the explain plan statement ids*/
  private IntegerIdentifierFactory _idFactory = new IntegerIdentifierFactory();

  private String _planTableName = "PLAN_TABLE";
 
  private static String USER_PLAN_TABLE_SQL =
      "SELECT 1 from USER_TABLES WHERE UPPER(TABLE_NAME) = UPPER(?)";

  private static String ALL_PLAN_TABLE_SQL =
      "SELECT OWNER, TABLE_NAME " +
      "from ALL_TABLES WHERE UPPER(TABLE_NAME) = UPPER(?)"
  /**
  * Ctor.
  *
  * @param  session   Current session.
  *
  * @throws  IllegalArgumentException
  *      Thrown if a <TT>null</TT> <TT>ISession</TT> passed.
  */
  public ExplainPlanExecuter(ISession session, ISQLPanelAPI sqlpanel) {
   super();
   setSession(session);
   createGUI();
   sqlpanel.addExecuterTabListener(new MySqlExecuterTabListener());
  }


  public String getTitle() {
    // i18n[oracle.explainPlan=Explain Plan]
   return s_stringMgr.getString("oracle.explainPlan");
  }

  public JComponent getComponent() {
   return this;
  }

  /**
  * Set the current session.
  *
  * @param  session   Current session.
  *
  * @throws  IllegalArgumentException
  *      Thrown if a <TT>null</TT> <TT>ISession</TT> passed.
  */
  public synchronized void setSession(ISession session) {
   if (session == null) {
    throw new IllegalArgumentException("Null ISession passed");
   }
   sessionClosing();
   _session = session;
  }

  /** Current session. */
  public ISession getSession() {
      return _session;
  }

  private void expandEntireTree(final JTree tree, final TreePath parentPath) {
   TreeNode parent = (TreeNode)parentPath.getLastPathComponent();
   int size = parent.getChildCount();
   for (int i=0;i<size;i++) {
    TreeNode child = parent.getChildAt(i);
    TreePath p = parentPath.pathByAddingChild(child);
    tree.expandPath(p);
    expandEntireTree(tree, p);
   }
  }

  protected JTreeTable createTreeTable(TreeTableModel model) {
   JTreeTable treeTable = new JTreeTable(model);
   treeTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
   TableColumnModel columnModel = treeTable.getColumnModel();
   //Operation column increased
   columnModel.getColumn(1).setPreferredWidth(300);
   //Options column increased
   columnModel.getColumn(2).setPreferredWidth(100);
   JTree treeTableTree = treeTable.getTree();
   treeTableTree.setCellRenderer(new PlanTreeCellRenderer());
   //Expand all of the rows in the tree if the root is non null.
   Object root = treeTableTree.getModel().getRoot();
   if (root != null) {
    TreePath p = new TreePath(root);
    expandEntireTree(treeTableTree, p);
   }
   return treeTable;
  }

  public void execute(ISQLEntryPanel sqlPanel) {
   String sqlToBeExecuted = sqlPanel.getSQLToBeExecuted();
   if (sqlToBeExecuted != null && (sqlToBeExecuted.trim().length() > 0)) {
         sqlToBeExecuted = sqlToBeExecuted.trim();
         if (sqlToBeExecuted.endsWith(";")) {
            sqlToBeExecuted =
                sqlToBeExecuted.substring(0, sqlToBeExecuted.length()-1);
            if (s_log.isDebugEnabled()) {
                s_log.debug("Executing SQL: "+sqlToBeExecuted);
            }
        }
        
    String statementId = "squirrel_exp_plan"+_idFactory.createIdentifier();
    PreparedStatement deletePlan = null;
    try {
      //Clear any previous plan
      deletePlan = getSession().getSQLConnection().prepareStatement(
        "delete from " + getPlanTableName() + " where statement_id = ?");
      deletePlan.setString(1, statementId);
      deletePlan.execute();
      deletePlan.close();

      String explainSql = "EXPLAIN PLAN SET STATEMENT_ID = '" + statementId +
        "' INTO " + getPlanTableName() + " FOR " + sqlToBeExecuted;
      Statement explainPlan = null;
      PreparedStatement returnPlan = null;
      try {
       explainPlan = getSession().getSQLConnection().createStatement();
       explainPlan.execute(explainSql);

       String extractPlanResults = "select " +
          "   id," +
          "   parent_id," +
          "   LEVEL," +
          "   STATEMENT_ID," +
          "   TIMESTAMP," +
          "   REMARKS," +
          "   OPERATION," +
          "   OPTIONS," +
          "   OBJECT_NODE," +
          "   OBJECT_OWNER," +
          "   OBJECT_NAME," +
          "   OBJECT_INSTANCE," +
          "   OBJECT_TYPE," +
          "   OPTIMIZER," +
          "   SEARCH_COLUMNS," +
          "   POSITION," +
          "   COST," +
          "   CARDINALITY," +
          "   BYTES," +
          "   OTHER_TAG," +
          "   PARTITION_START," +
          "   PARTITION_STOP," +
          "   PARTITION_ID," +
          "   OTHER," +
          "   DISTRIBUTION " +
          "from " + getPlanTableName() + " " +
          "connect by " +
          "prior id = parent_id and statement_id = ? " +
          "start with id = 0 and statement_id = ? " +
          "order by id";

       //SQLExecuterTask task = new SQLExecuterTask(_session, sql, new DefaultSQLExecuterHandler(_session));
       //jmh to run async_session.getApplication().getThreadPool().addTask(task);
       //jmhtask.run();
       //Set the ? to the statement identifier
       returnPlan = getSession().getSQLConnection().prepareStatement(
          extractPlanResults);
       returnPlan.setString(1, statementId);
       returnPlan.setString(2, statementId);
       if (returnPlan.execute()) {
        ResultSet rs = returnPlan.getResultSet();
        int previousLevel = 1;
        ExplainPlanModel.ExplainRow lastRow = null;
        ExplainPlanModel.ExplainRow root = new ExplainPlanModel.ExplainRow(null,
           -1, null, null, null, sqlToBeExecuted, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
        ExplainPlanModel model = new ExplainPlanModel(root);
        while (rs.next()) {
          BigDecimal id = rs.getBigDecimal(1);
          BigDecimal parent_id = rs.getBigDecimal(2);
          int level = rs.getBigDecimal(3).intValue();
          String stmntId = rs.getString(4);
          java.sql.Timestamp timeStamp = rs.getTimestamp(5);
          String remarks = rs.getString(6);
          String operation = rs.getString(7);
          String options = rs.getString(8);
          String object_node = rs.getString(9);
          String object_owner = rs.getString(10);
          String object_name = rs.getString(11);
          String object_instance = rs.getString(12);
          String object_type = rs.getString(13);
          String optimizer = rs.getString(14);
          BigDecimal searchColumns = rs.getBigDecimal(15);
          BigDecimal position = rs.getBigDecimal(16);
          BigDecimal cost = rs.getBigDecimal(17);
          BigDecimal cardinality = rs.getBigDecimal(18);
          BigDecimal bytes = rs.getBigDecimal(19);
          String other_tag = rs.getString(20);
          String distribution = rs.getString(21);

          ExplainPlanModel.ExplainRow parent = null;

          if (level == 1) {
           parent = (ExplainPlanModel.ExplainRow) model.getRoot();
          }
          else if (previousLevel == level) {
           parent = ((ExplainPlanModel.ExplainRow)lastRow.getParent().getParent()).findChild(parent_id.
              intValue());
          }
          else if (level > previousLevel) {
           parent = ((ExplainPlanModel.ExplainRow)lastRow.getParent()).findChild(parent_id.intValue());
          }
          else if (level < previousLevel) {
           parent = (ExplainPlanModel.ExplainRow)lastRow.getParent();
           for (int i=previousLevel-level;i>=0;i--) {
            parent = (ExplainPlanModel.ExplainRow)parent.getParent();
           }
           parent = parent.findChild(parent_id.intValue());
          }

          if (parent == null)
           throw new RuntimeException("parent is null. Coding error");

          ExplainPlanModel.ExplainRow row = new ExplainPlanModel.ExplainRow(
            parent,
            id.intValue(),
            stmntId,
            timeStamp,
            remarks,
            operation,
            options,
            object_node,
            object_owner,
            object_name,
            object_instance,
            object_type,
            optimizer,
            searchColumns,
            position,
            cost,
            cardinality,
            bytes,
            other_tag,
            distribution);
          parent.addChild(row);
          lastRow = row;
          previousLevel = level;
        }

        //Unfortunately we need to remove the exising tree table component and create a
        //new one due to limitations with replacing models in the existing
        //sun implementation. Why on earth they couldnt formalise the tree
        //table example on JFC (which we use) a bit more is anyones guess.
        this.removeAll();
        add(new javax.swing.JScrollPane(createTreeTable(model)), BorderLayout.CENTER);
       }

      }
      catch (SQLException ex) {
       getSession().showErrorMessage(ex);
             s_log.error(ex);
      }
      finally {
          SQLUtilities.closeStatement(explainPlan);
      }
    } catch (SQLException ex) {
        getSession().showErrorMessage(ex);
    } finally {
        SQLUtilities.closeStatement(deletePlan);
    }
   }
   else {
    _session.showErrorMessage(
      // i18n[oracle.noSql=No SQL selected for execution.]
      s_stringMgr.getString("oracle.noSql"));
   }
  }

  public String getPlanTableName() {
      return _planTableName;
  }

  /**
  * Sesssion is ending.
  * Remove all listeners that this component has setup. Close all
  * torn off result tab windows.
  */
  void sessionClosing() {
  }

  private void createGUI() {
   setLayout(new BorderLayout());
   add(new javax.swing.JScrollPane(createTreeTable( new ExplainPlanModel(null))), BorderLayout.CENTER);
  }

  /** Called when this executer is activated*/
  void createPlanTable() {
      if (!checkedPlanTable) {
          // only check once per session
          checkedPlanTable = true;
         
          if (!userPlanTableExists()) {
              boolean planTableAvailable = true;
             
              //if doesnt exist prompt to create it.
             
              //i18n[explainplanexecuter.createPlanTableMsg=The Oracle Plan
              //Table '{0}' doesnt exist in the current schema. Do you want to
              //create it?]
              String msg =
                  s_stringMgr.getString("explainplanexecuter.createPlanTableMsg",
                                        getPlanTableName());
             
              //i18n[explainplanexecuter.createPlanTableTitle=Create Plan Table]
              String title =
                  s_stringMgr.getString("explainplanexecuter.createPlanTableTitle");
             
              int result =
                  JOptionPane.showConfirmDialog(this,
                                                msg,
                                                title,
                                                JOptionPane.YES_NO_OPTION,
                                                JOptionPane.QUESTION_MESSAGE);
              if (result == JOptionPane.YES_OPTION) {
                  planTableAvailable = createLocalPlanTable();
              } else {
                  planTableAvailable = getAlternatePlanTable(getPlanTableName());
              }
              if (!planTableAvailable) {
                  // Tell the user that they won't be able to show the explain plan
                 
                  JFrame f = _session.getApplication().getMainFrame();                 
                  //i18n[explainplanexecuter.planTableUnavailable=Explain plans
                  //will be unavailable for this session]
                  msg =
                      s_stringMgr.getString(
                              "explainplanexecuter.planTableUnavailable");
                 
                  //i18n[explainplanexecuter.planTableUnavailableTitle=
                  //PLAN_TABLE not found]
                  title =
                      s_stringMgr.getString(
                              "explainplanexecuter.planTableUnavailableTitle");
                     
                  JOptionPane.showMessageDialog(f,
                                                msg,
                                                "title",
                                                JOptionPane.INFORMATION_MESSAGE);
                 
              }
          }
      }
  }

  private boolean createLocalPlanTable() {
      boolean result = true;
      String createPlanTableSQL =
          getCreatePlanTableSQL(getPlanTableName());
      Statement stmt = null;
      try {
          ISession session = getSession();
          ISQLConnection con = session.getSQLConnection();
          stmt = con.createStatement();
          stmt.execute(createPlanTableSQL);
          SchemaInfo schemaInfo = session.getSchemaInfo();
          schemaInfo.refershCacheForSimpleTableName("PLAN_TABLE");
      } catch (SQLException ex) {
          result = false;
          getSession().showErrorMessage(ex);
          s_log.error(ex);
      } finally {
          SQLUtilities.closeStatement(stmt);
      }     
      return result;
  }
 
  /**
   * Look for a PLAN_TABLE in another schema that we may be able to access
   * using the following SQL:
   *
   *  "SELECT OWNER, TABLE_NAME " +
      "from ALL_TABLES WHERE UPPER(TABLE_NAME) = UPPER(?)";
   *
   */
  private boolean getAlternatePlanTable(String planTableName) {
      PreparedStatement pstmt = null;
      ResultSet rs = null;
      ArrayList<String> planTableList = new ArrayList<String>();
      try {
          ISQLConnection con = _session.getSQLConnection();
          pstmt = con.prepareStatement(ALL_PLAN_TABLE_SQL);
          pstmt.setString(1, planTableName);
          rs = pstmt.executeQuery();
          while (rs.next()) {
              String owner = rs.getString(1);
              String tableName = rs.getString(2);
              StringBuffer tmp = new StringBuffer();
              tmp.append(owner);
              tmp.append(".");
              tmp.append(tableName);
              planTableList.add(tmp.toString());
          }
      } catch (SQLException e) {
          getSession().showErrorMessage(e);
          s_log.error(e);         
      } finally {
          SQLUtilities.closeResultSet(rs);
          SQLUtilities.closeStatement(pstmt);
      }
      if (planTableList.size() == 0) {
          s_log.info("No PLAN_TABLE table found in view ALL_TABLES");
          return false;
      }
      String[] planTables =
          planTableList.toArray(new String[planTableList.size()]);
     
      JFrame f = _session.getApplication().getMainFrame();
     
      //i18n[explainplanexecuter.choosePlanTableMsg=Choose a PLAN_TABLE to
      //store the result in]
      String message =
          s_stringMgr.getString("explainplanexecuter.choosePlanTableMsg");
     
      //i18n[explainplanexecuter.choosePlanTableTitle=Available PLAN_TABLEs]
      String chooserTitle =
          s_stringMgr.getString("explainplanexecuter.choosePlanTableMsg");
         
      
      String option =
          (String)JOptionPane.showInputDialog(f,
                                              message,
                                              chooserTitle,
                                              JOptionPane.INFORMATION_MESSAGE,
                                              null,
                                              planTables,
                                              planTables[0]);
      if (option != null) {
          _planTableName = option;
      } else {
          return false;
      }     
      return true;
  }
 
  /**
   * Determines if the user has a PLAN_TABLE in their schema using SQL:
   *
   * "SELECT 1 from USER_TABLES WHERE UPPER(TABLE_NAME) = UPPER(?)";
   *
   * @return true if PLAN_TABLE exists; false otherwise.
   */
  private boolean userPlanTableExists() {
      boolean result = false;
      PreparedStatement stmt = null;
      ResultSet rs = null;
      try {
          ISQLConnection con = getSession().getSQLConnection();
          stmt = con.prepareStatement(USER_PLAN_TABLE_SQL);
          stmt.setString(1, getPlanTableName());
          rs = stmt.executeQuery();
          if (rs.next()) {
              result = true;
          }
      } catch (SQLException e) {
          getSession().showErrorMessage(e);
          s_log.error(e);
      } finally {
          SQLUtilities.closeResultSet(rs);
          SQLUtilities.closeStatement(stmt);
      }
      return result;
  }
 
  private String getCreatePlanTableSQL(String tableName) {
      StringBuffer result = new StringBuffer("CREATE TABLE ");
      result.append(tableName);
      result.append(" (");
      result.append("STATEMENT_ID                    VARCHAR2(30),");
      result.append("TIMESTAMP                       DATE,");
      result.append("REMARKS                         VARCHAR2(80),");
      result.append("OPERATION                       VARCHAR2(30),");
      result.append("OPTIONS                         VARCHAR2(30),");
      result.append("OBJECT_NODE                     VARCHAR2(128),");
      result.append("OBJECT_OWNER                    VARCHAR2(30),");
      result.append("OBJECT_NAME                     VARCHAR2(30),");
      result.append("OBJECT_INSTANCE                 NUMBER(38),");
      result.append("OBJECT_TYPE                     VARCHAR2(30),");
      result.append("OPTIMIZER                       VARCHAR2(255),");
      result.append("SEARCH_COLUMNS                  NUMBER,");
      result.append("ID                              NUMBER(38),");
      result.append("PARENT_ID                       NUMBER(38),");
      result.append("POSITION                        NUMBER(38),");
      result.append("COST                            NUMBER(38),");
      result.append("CARDINALITY                     NUMBER(38),");
      result.append("BYTES                           NUMBER(38),");
      result.append("OTHER_TAG                       VARCHAR2(255),");
      result.append("PARTITION_START                 VARCHAR2(255),");
      result.append("PARTITION_STOP                  VARCHAR2(255),");
      result.append("PARTITION_ID                    NUMBER(38),");
      result.append("OTHER                           LONG,");
      result.append("DISTRIBUTION                    VARCHAR2(30)");
      result.append(")");
      return result.toString();
  }
 
  private class MySqlExecuterTabListener implements ISQLResultExecuterTabListener {
   public void executerTabAdded(SQLResultExecuterTabEvent evt) {}

   public void executerTabRemoved(SQLResultExecuterTabEvent evt) {}

   public void executerTabActivated(SQLResultExecuterTabEvent evt) {
    if (evt.getExecuter() == ExplainPlanExecuter.this) {
      createPlanTable();
    }
   }
  }

  public static class ExplainPlanModel extends AbstractTreeTableModel {
    // Names of the columns.
    private final String[]  cNames = {
                                        //i18n[explainplanexecuter.enumeration=#]
                                        s_stringMgr.getString("explainplanexecuter.enumeration"),
                                        //i18n[explainplanexecuter.operation=Operation]
                                        s_stringMgr.getString("explainplanexecuter.operation"),
                                        //i18n[explainplanexecuter.options=Options]
                                        s_stringMgr.getString("explainplanexecuter.options"),
                                        //i18n[explainplanexecuter.objectName=Object Name]
                                        s_stringMgr.getString("explainplanexecuter.objectName"),
                                        //i18n[explainplanexecuter.mode=Mode]
                                        s_stringMgr.getString("explainplanexecuter.mode"),
                                        //i18n[explainplanexecuter.cost=Cost]
                                        s_stringMgr.getString("explainplanexecuter.cost"),
                                        //i18n[explainplanexecuter.bytes=Bytes]
                                        s_stringMgr.getString("explainplanexecuter.bytes"),
                                        //i18n[explainplanexecuter.cardinality=Cardinality]
                                        s_stringMgr.getString("explainplanexecuter.cardinality"),
                            };

    // Types of the columns.
    private final Class<?>[]  cTypes = { TreeTableModel.class,
                             String.class,
                             String.class,
                             String.class,
                             String.class,
                             String.class,
                             String.class,
                             String.class
                            };
    @SuppressWarnings("unused")
    public static class ExplainRow implements TreeNode {
      private ExplainRow parent;
      private List<ExplainRow> children;
      private int id;
      private String idObj;
      private String stmntId;
      private java.sql.Timestamp timeStamp;
      private String remarks;
      private String operation;
      private String options;
      private String object_node;
      private String object_owner;
      private String object_name;
      private String object_instance;
      private String object_type;
      private String optimizer;
      private BigDecimal searchColumns;
      private BigDecimal position;
      private BigDecimal cost;
      private BigDecimal cardinality;
      private BigDecimal bytes;
      private String other_tag;
      private String distribution;

      public ExplainRow(ExplainRow parent,
                  int id,
                  String stmntId,
                  java.sql.Timestamp timeStamp,
                  String remarks,
                  String operation,
                  String options,
                  String object_node,
                  String object_owner,
                  String object_name,
                  String object_instance,
                  String object_type,
                  String optimizer,
                  BigDecimal searchColumns,
                  BigDecimal position,
                  BigDecimal cost,
                  BigDecimal cardinality,
                  BigDecimal bytes,
                  String other_tag,
                  String distribution) {
       this.parent = parent;
       this.id = id;
       if (id == -1)
        this.idObj = "";
       else this.idObj = Integer.toString(id);
       this.stmntId = stmntId;
       this.timeStamp = timeStamp;
       this.remarks = remarks;
       this.operation = operation;
       this.options = options;
       this.object_node = object_node;
       this.object_owner = object_owner;
       this.object_name = object_name;
       this.object_instance = object_instance;
       this.object_type = object_type;
       this.optimizer = optimizer;
       this.searchColumns = searchColumns;
       this.position = position;
       this.cost = cost;
       this.cardinality = cardinality;
       this.bytes = bytes;
       this.other_tag = other_tag;
       this.distribution = distribution;
      }

      public int getID() {
       return id;
      }

      //TreeNode Interface
      public TreeNode getParent() {
       return parent;
      }

      public Enumeration<ExplainRow> children() {
       if (children == null) {
        children = new ArrayList<ExplainRow>();
             }
       return Collections.enumeration(children);
      }

      public boolean getAllowsChildren() {
       return true;
      }

      public int getIndex(TreeNode node) {
       if (children == null)
        return -1;
       return children.indexOf(node);
      }

      public void addChild(ExplainRow row) {
       if (children == null) {
        children = new ArrayList<ExplainRow>();
             }
       children.add(row);
      }

      public boolean isLeaf() {
       return  ((children == null)||(children.size() == 0));
      }

      public Object getValueAt(int column) {
       switch (column) {
        case 0: return this.idObj;
        case 1: return this.operation;
        case 2: return this.options;
        case 3: return this.object_name;
        case 4: return this.optimizer;
        case 5: return this.cost;
        case 6: return this.bytes;
        case 7: return this.cardinality;
        default: return null;
       }
      }

      public int getChildCount() {
       return (children==null) ? 0 : children.size();
      }

      public TreeNode getChildAt(int child) {
       return children.get(child);
      }

      public ExplainRow findChild(int id) {
       for (int i=getChildCount()-1;i>=0;i--) {
        ExplainRow child = (ExplainRow)getChildAt(i);
        if (child.getID() == id) {
          return child;
        }
       }
       return null;
      }

      public String toString() {
       return idObj;
      }
    }

    public ExplainPlanModel(ExplainRow root) {
      super(root);
    }

    //
    // The TreeModel interface
    //

    /**
     * Returns the number of children of <code>node</code>.
     */
    public int getChildCount(Object node) {
      ExplainRow er = (ExplainRow)node;
      return er.getChildCount();
    }

    /**
     * Returns the child of <code>node</code> at index <code>i</code>.
     */
    public Object getChild(Object node, int i) {
      ExplainRow er = (ExplainRow)node;
      return er.getChildAt(i);
    }

    /**
     * Returns true if the passed in object represents a leaf, false
     * otherwise.
     */
    public boolean isLeaf(Object node) {
       return ((ExplainRow)node).isLeaf();
    }

    //
    //  The TreeTableNode interface.
    //

    /**
     * Returns the number of columns.
     */
    public int getColumnCount() {
       return cNames.length;
    }

    /**
     * Returns the name for a particular column.
     */
    public String getColumnName(int column) {
       return cNames[column];
    }

    /**
     * Returns the class for the particular column.
     */
    public Class<?> getColumnClass(int column) {
       return cTypes[column];
    }

    /**
     * Returns the value of the particular column.
     */
    public Object getValueAt(Object node, int column) {
       ExplainRow     fn = (ExplainRow)node;
       return fn.getValueAt(column);
    }
  }

  private class PlanTreeCellRenderer extends DefaultTreeCellRenderer {

      private static final long serialVersionUID = 6829431667964347305L;

      public Component getTreeCellRendererComponent(JTree tree,
                                                    Object value,
                                                    boolean selected,
                                                    boolean expanded,
                                                    boolean leaf,
                                                    int row,
                                                    boolean hasFocus)
      {
          super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
          this.setIcon(null);
          return this;
      }

  }


  public static void main(String[] args) {
   javax.swing.JFrame frame = new javax.swing.JFrame("Tree Table test");
   ExplainPlanModel.ExplainRow root = new ExplainPlanModel.ExplainRow(null, -1, "root", null, null, "JMH Root", null, null, null, null, null, null, null, null, null, null, null, null, null, null);
   ExplainPlanModel.ExplainRow child = new ExplainPlanModel.ExplainRow(root, 0, "child", null, null, "Child 0", null, null, null, null, null, null, null, null, null, null, null, null, null, null);
   ExplainPlanModel.ExplainRow child2 = new ExplainPlanModel.ExplainRow(root, 1, "child 2", null, null, "Child 1", null, null, null, null, null, null, null, null, null, null, null, null, null, null);
   ExplainPlanModel.ExplainRow child3 = new ExplainPlanModel.ExplainRow(child2, 2, "child 3", null, null, "Child 2", null, null, null, null, null, null, null, null, null, null, null, null, null, null);
   ExplainPlanModel.ExplainRow child4 = new ExplainPlanModel.ExplainRow(child3, 4, "child 4", null, null, "Child 4", null, null, null, null, null, null, null, null, null, null, null, null, null, null);
   ExplainPlanModel.ExplainRow child5 = new ExplainPlanModel.ExplainRow(child2, 5, "child 5", null, null, "Child 5", null, null, null, null, null, null, null, null, null, null, null, null, null, null);

   root.addChild(child);
   root.addChild(child2);
   child2.addChild(child3);
   child2.addChild(child5);
   child3.addChild(child4);
   TreeTableModel model = new ExplainPlanModel(root);
   JTreeTable treeTable = new JTreeTable(model);
   int rowCount = treeTable.getTree().getRowCount();
   for (int i=0;i<rowCount;i++) {
    treeTable.getTree().expandRow(i);
   }
   frame.getContentPane().add(new javax.swing.JScrollPane(treeTable));
   frame.setSize(640, 480);
   frame.setDefaultCloseOperation(javax.swing.JFrame.DISPOSE_ON_CLOSE);
   frame.setVisible(true);

  }

  /**
   * @see net.sourceforge.squirrel_sql.client.session.mainpanel.ISQLResultExecuter#getSelectedResultTab()
   */
  public IResultTab getSelectedResultTab() {
      throw new UnsupportedOperationException("ExplainPlanExecuter has no ResultTabs");
  }


 

}
TOP

Related Classes of net.sourceforge.squirrel_sql.plugins.oracle.explainplan.ExplainPlanExecuter$ExplainPlanModel$ExplainRow

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.