Package net.datacrow.console.components.panels.tree

Source Code of net.datacrow.console.components.panels.tree.FieldTreePanel

/******************************************************************************
*                                     __                                     *
*                              <-----/@@\----->                              *
*                             <-< <  \\//  > >->                             *
*                               <-<-\ __ /->->                               *
*                               Data /  \ Crow                               *
*                                   ^    ^                                   *
*                              info@datacrow.net                             *
*                                                                            *
*                       This file is part of Data Crow.                      *
*       Data Crow is free software; you can redistribute it and/or           *
*        modify it under the terms of the GNU General Public                 *
*       License as published by the Free Software Foundation; either         *
*              version 3 of the License, or any later version.               *
*                                                                            *
*        Data Crow 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 General Public License for more details.             *
*                                                                            *
*        You should have received a copy of the GNU General Public           *
*  License along with this program. If not, see http://www.gnu.org/licenses  *
*                                                                            *
******************************************************************************/

package net.datacrow.console.components.panels.tree;

import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import javax.swing.JMenuBar;
import javax.swing.SwingUtilities;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;

import net.datacrow.console.ComponentFactory;
import net.datacrow.console.menu.FieldTreePanelMenuBar;
import net.datacrow.core.DcRepository;
import net.datacrow.core.data.DataFilters;
import net.datacrow.core.data.DataManager;
import net.datacrow.core.db.DatabaseManager;
import net.datacrow.core.modules.DcModule;
import net.datacrow.core.modules.DcModules;
import net.datacrow.core.objects.DcField;
import net.datacrow.core.objects.DcMapping;
import net.datacrow.core.objects.DcObject;
import net.datacrow.core.objects.DcProperty;
import net.datacrow.core.resources.DcResources;
import net.datacrow.util.DcImageIcon;
import net.datacrow.util.PollerTask;
import net.datacrow.util.Utilities;

import org.apache.log4j.Logger;

public class FieldTreePanel extends TreePanel {

  private static Logger logger = Logger.getLogger(FieldTreePanel.class.getName());
    private int[] fields;
    private String empty = DcResources.getText("lblEmpty");
   
    private TreeHugger treeHugger;
   
    public FieldTreePanel(GroupingPane gp) {
        super(gp);
    }
   
    public int[] getGroupBy() {
        return fields;
    }
   
    @Override
    public String getName() {
        return DcResources.getText("lblDefault");
    }
   
    public void groupBy(int[] fields) {
        this.fields = fields;
        DcModules.get(getModule()).setSetting(DcRepository.ModuleSettings.stGroupedBy, fields);
        createTree();
    }
   
    @Override
    public void groupBy() {
        fields = (int[]) DcModules.get(getModule()).getSetting(DcRepository.ModuleSettings.stGroupedBy);
        groupBy(fields);
    }

    @Override
    protected JMenuBar getMenu() {
        return new FieldTreePanelMenuBar(getModule(), this);
    }
   
    @Override
    public void reset() {
        DcModules.get(getModule()).setSetting(DcRepository.ModuleSettings.stGroupedBy, null);
        fields = null;
        super.reset();
    }
   
    @Override
    public DcDefaultMutableTreeNode getFullPath(DcObject dco) {
        DcDefaultMutableTreeNode node = new DcDefaultMutableTreeNode("top");
        add(dco, 0, node);
        return node;
    }
   
    @Override
  public boolean isChanged(DcObject dco) {
      boolean changed = false;
      if (fields != null) {
        for (int field : fields)
          changed |= dco.isChanged(field);
      }
      return changed;
  }

  /************************************************************************
     * Initialization
     ************************************************************************/
   
    @Override
    protected void createTree() {
        if (treeHugger != null) {
            treeHugger.cancel();
        }
       
        activated = true;
        treeHugger = new TreeHugger();
        treeHugger.start();
    }
   
    private class TreeHugger extends Thread {
       
      private PollerTask poller;
     
        private boolean stop = false;
       
        @Override
        public void run() {
            if (poller != null) poller.finished(true);
           
            poller = new PollerTask(this, DcResources.getText("lblGroupingItems"));
            poller.start();

          createTree();
         
            poller.finished(true);
            poller = null;
        }
       
        public void cancel() {
            stop = true;
        }
       
        protected void createTree() {

          fields = (int[]) DcModules.get(getModule()).getSetting(DcRepository.ModuleSettings.stGroupedBy);
           
            build();
           
            if (fields != null)
                createTree(fields);
           
            SwingUtilities.invokeLater(
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            expandAll();
                            setDefaultSelection();
                        }
                    }));
        }
       
        /**
         * Creates a flat structure of the tree to be build.
         * The tree is created based on the result one SQL statement.
         * @param fields
         */
        private void createTree(int[] fields) {
            DcModule m = DcModules.get(getModule());

            StringBuffer sql = new StringBuffer("");
           
            List<String> joinOn = new ArrayList<String>();
           
            DcField field;
            DcModule reference;
            DcModule main;
           
            Collection<DcModule> modules = new ArrayList<DcModule>();
           
            if (m.isAbstract()) {
              modules = DcModules.getPersistentModules(m);
            } else {
              modules.add(m);
            }
           
            int moduleCounter = 0;
            int fieldCounter = 0;
           
            StringBuffer columns;
            StringBuffer joins;
           
            for (DcModule module : modules) {
             
              fieldCounter = 0;

              columns = new StringBuffer("select ");
                joins = new StringBuffer("from ");
                joins.append(module.getTableName());
               
              if (moduleCounter > 0)
                sql.append(" UNION ");
             
                columns.append(module.getTableName());
                columns.append(".ID, ");
                columns.append(module.getIndex());
                columns.append(" AS MODULEIDX");     
             
              for (int idx : fields) {
                  field = module.getField(idx);
                  if (field.isUiOnly() &&
                      field.getValueType() != DcRepository.ValueTypes._DCOBJECTCOLLECTION &&
                      field.getValueType() != DcRepository.ValueTypes._DCOBJECTREFERENCE) continue;
                 
                    columns.append(",");
                 
                  joinOn.add(module.getTableName() + fieldCounter + ".ID");
                 
                  if (field.getValueType() == DcRepository.ValueTypes._DCOBJECTCOLLECTION ||
                      field.getValueType() == DcRepository.ValueTypes._DCOBJECTREFERENCE) {
 
                      reference = DcModules.get(field.getReferenceIdx());
                      main = field.getValueType() == DcRepository.ValueTypes._DCOBJECTREFERENCE ? module :
                             DcModules.get(DcModules.getMappingModIdx(module.getIndex(), reference.getIndex(), field.getIndex()));
 
                      if (    field.getValueType() == DcRepository.ValueTypes._DCOBJECTCOLLECTION ||
                              field.getFieldType() == ComponentFactory._REFERENCEFIELD) {
                         
                          columns.append("subselect");
                          columns.append(fieldCounter);
                          columns.append(".ID AS ");
                          columns.append("ID");
                          columns.append(fieldCounter);
                          columns.append(", ");
                         
                          columns.append("subselect");
                          columns.append(fieldCounter);
                          columns.append(".name AS ");
                          columns.append("NAME");
                          columns.append(fieldCounter);
                          columns.append(", ");
                         
                          columns.append("subselect");
                          columns.append(fieldCounter);                           
                          columns.append(".icon AS ");
                          columns.append("ICON");
                          columns.append(fieldCounter);
                             
                          if (field.getValueType() == DcRepository.ValueTypes._DCOBJECTCOLLECTION) {
                              joins.append(" left outer join ");
                              joins.append("(select ");
                              joins.append(reference.getTableName());
                              joins.append(".ID as ID,");
                              joins.append(main.getTableName());
                              joins.append(".");
                              joins.append(main.getField(DcMapping._A_PARENT_ID).getDatabaseFieldName());
                              joins.append(" as parentID, ");
                              joins.append(reference.getTableName());
                              joins.append(".");
                              joins.append(reference.getField(reference.getSystemDisplayFieldIdx()).getDatabaseFieldName());
                              joins.append(" as name,");
                             
                              if (reference.getType() == DcModule._TYPE_PROPERTY_MODULE) {
                                  joins.append(reference.getTableName());
                                  joins.append(".");
                                  joins.append(reference.getField(DcProperty._B_ICON).getDatabaseFieldName());
                              } else {
                                  joins.append("NULL");
                              }
                             
                              joins.append(" as icon");
                              joins.append(" from ");
                              joins.append(reference.getTableName());
                              joins.append(" inner join ");
                              joins.append(main.getTableName());
                              joins.append(" on ");
                              joins.append(reference.getTableName());
                              joins.append(".ID = ");
                              joins.append(main.getTableName());
                              joins.append(".");
                              joins.append(main.getField(DcMapping._B_REFERENCED_ID).getDatabaseFieldName());
                              joins.append(") subselect");
                              joins.append(fieldCounter);
                              joins.append(" on ");
                              joins.append(" subselect");
                              joins.append(fieldCounter);
                              joins.append(".parentID = ");
                              joins.append(module.getTableName());
                              joins.append(".ID ");
 
                          } else {
                              joins.append(" left outer join ");
                              joins.append(reference.getTableName());
                              joins.append(" ");
                              joins.append(" subselect");
                              joins.append(fieldCounter);
                              joins.append(" on ");
                              joins.append(module.getTableName());
                              joins.append(".");
                              joins.append(field.getDatabaseFieldName());
                              joins.append("=");
                              joins.append(" subselect");
                              joins.append(fieldCounter);
                              joins.append(".ID");
                          }
                      }
                  } else {
                      columns.append(module.getTableName());
                      columns.append(".");
                      columns.append(field.getDatabaseFieldName());
                      columns.append(",");
                      columns.append(module.getTableName());
                      columns.append(".");
                      columns.append(field.getDatabaseFieldName() + " as df");
                      columns.append(fieldCounter);
                      columns.append(",NULL");
                     
                      joinOn.add(module.getTableName() + ".ID");
                  }
                  fieldCounter++;
              }
             
              sql.append(columns.toString() + " " + joins.toString());
              sql.append(" ");
              moduleCounter++;
            }

            if (m.isAbstract()) {
              sql.insert(0, "select * from (");
              sql.append(") ");
          }

            // index based order by
            int level = 0;
            boolean ordered = false;
            for (int idx : fields) {
              field = DcModules.get(getModule()).getField(idx);
                if (field.isUiOnly() &&
                    field.getIndex() != DcObject._SYS_MODULE &&
                    field.getValueType() != DcRepository.ValueTypes._DCOBJECTCOLLECTION &&
                    field.getValueType() != DcRepository.ValueTypes._DCOBJECTREFERENCE) continue;

                if (!ordered) {
                   sql.append(" order by ");
                   ordered = true;
                } else {
                sql.append(",");
                }
               
              if (field.getIndex() == DcObject._SYS_MODULE) {
                  sql.append("2");
              } else {
                  sql.append(String.valueOf((level * 3) + 4));
                  level++;
              }
            }
            createTree(sql.toString());
        }
       
        /**
         * Creates a tree from the result of an SQL statement.
         * The SQL statement should query the values in a flat hierarchy for each level of the tree:
         * key1-value-icon
         * key1-value-icon / key1-value-icon
         * key1-value-icon / key2-value-icon
         * key1-value-icon / key1-value-icon / key1-value-icon
         * key1-value-icon / key2-value-icon / key2-value-icon
         * @param sql
         */
        private void createTree(String sql) {
            try {
                logger.debug(sql);
               
                ResultSet rs = DatabaseManager.executeSQL(sql);
               
                NodeElement existingNe;
                NodeElement ne;
                String id = null;
                String value = null;
                Object key = null;
                DcImageIcon icon = null;
                String iconBase64 = null;
                DcField field = null;
                int module;

                DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
               
                DefaultMutableTreeNode current;
                DefaultMutableTreeNode parent;
                DefaultMutableTreeNode previous;
                boolean exists = false;
               
                Map<String, Integer> items = DataManager.getKeys(DataFilters.getCurrent(getModule()));
               
                Collection<String> keys = null;
                if (DataFilters.isFilterActive(getModule())) {
                    keys = new ArrayList<String>(items.keySet());
                }
               
                while (rs.next() && !stop) {
                    int level = 0;
                    parent = top;
                   
                    for (int idx = 0; idx < fields.length; idx++) {
                     
                      field = DcModules.get(getModule()).getField(fields[idx]);
                      if (field.isUiOnly() &&
                          field.getIndex() != DcObject._SYS_MODULE &&
                          field.getValueType() != DcRepository.ValueTypes._DCOBJECTCOLLECTION &&
                          field.getFieldType() != ComponentFactory._REFERENCEFIELD)
                        continue;
                     
                       
                        if (stop) break;
                       
                        // for each level the field index is shifted to the end.
                        id = rs.getString(1);
                        module = rs.getInt(2);
                        key = field.getIndex() == DcObject._SYS_MODULE ? DcModules.get(module).getLabel() : rs.getObject((level * 3) + 3);
                        value =  field.getIndex() == DcObject._SYS_MODULE ? DcModules.get(module).getLabel() : rs.getString((level * 3) + 4);
                        iconBase64 = field.getIndex() != DcObject._SYS_MODULE ? rs.getString((level * 3) + 5) : null;
                       
                        icon = field.getIndex() == DcObject._SYS_MODULE ?
                                new DcImageIcon(DcModules.get(module).getIcon16().getImage()) :
                                iconBase64 != null ? DataManager.addIcon(String.valueOf(key), iconBase64) : null;
                       
                        if (keys != null && !keys.contains(id)) continue;
                       
                        previous = parent.getChildCount() == 0 ? null : ((DefaultMutableTreeNode) parent.getChildAt(parent.getChildCount() - 1));
                        exists = previous == null || (((NodeElementprevious.getUserObject()).getKey() == null && key != null) ? false :
                                ((NodeElementprevious.getUserObject()).getKey() == key || // empty key
                                ((NodeElementprevious.getUserObject()).getKey().equals(key);
                       
                        if (!exists) {
                            if (key == null) {
                                ne = new NodeElement(null, empty, null);
                            } else {
                                ne = new NodeElement(key, value, icon);
                            }
                           
                            ne.addItem(id, module);
                            current = new DcDefaultMutableTreeNode(ne);
                            parent.add(current);
                            parent = current;
                          
                        } else { // exists
                            existingNe =(NodeElement) previous.getUserObject();
                            existingNe.addItem(id, module);
                            model.nodeChanged(previous);
                            parent = previous;   
                        }
                       
                        if (field.getIndex() != DcObject._SYS_MODULE)
                            level++;
                    }
                }
               
                rs.close();
               
                NodeElement topElem = (NodeElement) top.getUserObject();
                topElem.setItems(items);
                model.nodeChanged(top);
               
            } catch (Exception e) {
                logger.error(e, e);
            }
        }
    }
   
    @Override
    protected void createTopNode() {
        DcModule mod = DcModules.get(getModule());
        String label = mod.getObjectNamePlural();
       
        if (isEnabled() && fields != null && fields.length > 0) {
            label += " by ";
            for (int i = 0; i < fields.length; i++)
                label += (i > 0 ? " & " : "") + mod.getField(fields[i]).getLabel();
        }
       
        top = new DcDefaultMutableTreeNode(label);
        top.setUserObject(new NodeElement(null, label, null));
    }

    private void add(DcObject dco, int level, DcDefaultMutableTreeNode node) {
       
        int index = level;
       
        if (fields == null || index >= fields.length) return;
       
        DcDefaultMutableTreeNode child;
        DcField field = dco.getField(fields[index]);
        Object value = dco.getValue(fields[index]);
        index++;
        if (Utilities.isEmpty(value)) {
            child = new DcDefaultMutableTreeNode(new NodeElement(empty, empty, null));
            node.add(child);
            add(dco, index, child);
        } else {
            if (field.getValueType() == DcRepository.ValueTypes._DCOBJECTCOLLECTION) {
                @SuppressWarnings("unchecked")
        Collection<DcObject> references = (Collection<DcObject>) dco.getValue(field.getIndex());
                if (references != null && references.size() > 0) {
                    for (DcObject reference : references) {
                        child = new DcDefaultMutableTreeNode(new NodeElement(reference.toString(), reference.toString(), reference.getIcon()));
                        node.insert(child, 0);
                        add(dco, index, child);
                    }
                }
            } else {
                String key = dco.getDisplayString(field.getIndex());
                child = new DcDefaultMutableTreeNode(new NodeElement(key, key, null));
                node.add(child);
                add(dco, index, child);
            }
        }
    }
}
TOP

Related Classes of net.datacrow.console.components.panels.tree.FieldTreePanel

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.