package net.codjo.dataprocess.gui.util.tableexplorer; import net.codjo.dataprocess.client.HandlerCommandSender; import net.codjo.dataprocess.common.DataProcessConstants; import net.codjo.dataprocess.gui.plugin.DataProcessGuiConfiguration; import net.codjo.dataprocess.gui.util.GuiUtils; import net.codjo.gui.toolkit.waiting.WaitingPanel; import net.codjo.mad.client.request.RequestException; import net.codjo.mad.client.request.Result; import net.codjo.mad.gui.framework.GuiContext; import net.codjo.mad.gui.framework.MutableGuiContext; import net.codjo.mad.gui.request.Preference; import net.codjo.mad.gui.request.PreferenceFactory; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.beans.PropertyVetoException; import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.StringTokenizer; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.InputMap; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JInternalFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.JTree; import javax.swing.KeyStroke; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.event.TreeModelListener; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeModel; import javax.swing.tree.TreePath; /** * */ public class TableExploratorGui { private JPanel mainPanel; private JTextField filterField; private JTree tableTree; private JButton quitButton; private JButton openButton; private JLabel statusLabel; private JTextArea whereTextArea; private JInternalFrame frame; private MutableGuiContext ctxt; private DataProcessGuiConfiguration dataProcessGuiConfig; private DatabaseTreeModel databaseTreeModel = new DatabaseTreeModel(); private Map<String, Action> windowActionMap = new HashMap<String, Action>(); private WaitingPanel waitingPanel = new WaitingPanel("R�cup�ration de la liste des tables ..."); TableExploratorGui(MutableGuiContext ctxt, JInternalFrame frame, DataProcessGuiConfiguration dataProcessGuiConfig) { this.frame = frame; this.ctxt = ctxt; this.dataProcessGuiConfig = dataProcessGuiConfig; frame.setGlassPane(waitingPanel); tableTree.setModel(new DefaultTreeModel(null)); tableTree.setToggleClickCount(0); statusLabel.setText(""); createListener(); ctxt.getDesktopPane().add(frame); frame.pack(); GuiUtils.setToLeftSide(frame); frame.setVisible(true); try { frame.setSelected(true); } catch (PropertyVetoException e) { ; } } private void createListener() { InputMap inputMap = frame.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); inputMap.put(KeyStroke.getKeyStroke("ESCAPE"), "cancel"); final JInternalFrame frame1 = frame; frame.getActionMap().put("cancel", new javax.swing.AbstractAction() { public void actionPerformed(ActionEvent evt) { frame1.dispose(); } }); frame.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("control F"), "focus_filterField"); frame.getActionMap().put("focus_filterField", new AbstractAction() { public void actionPerformed(ActionEvent e) { filterField.requestFocus(); filterField.selectAll(); } }); filterField.getDocument().addDocumentListener(new DocumentListener() { public void insertUpdate(DocumentEvent evt) { filterChanged(); } public void removeUpdate(DocumentEvent evt) { filterChanged(); } public void changedUpdate(DocumentEvent evt) { filterChanged(); } }); filterField.addKeyListener(new KeyAdapter() { @Override public void keyPressed(KeyEvent e) { if (KeyEvent.VK_DOWN == e.getKeyCode()) { tableTree.requestFocus(); tableTree.setSelectionPath(new TreePath("Tables")); } } }); openButton.addActionListener(new OpenTablesButtonListener()); tableTree.addMouseListener(new MyMouseAdapter()); tableTree.addKeyListener(new MyTreeKeyAdapter()); quitButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { frame.dispose(); } }); } private void filterChanged() { tableTree.setModel(new DefaultTreeModel(null)); databaseTreeModel.filter(filterField.getText()); tableTree.setModel(databaseTreeModel); updateStatus(true); } public void loadData(final boolean exclude) { waitingPanel.exec(new Runnable() { public void run() { try { loadMetaData(exclude); filterField.requestFocusInWindow(); } catch (RequestException ex) { GuiUtils.showErrorDialog(TableExploratorGui.this.frame, getClass(), "Erreur interne", ex); } } }); } public JPanel getMainPanel() { return mainPanel; } private void loadMetaData(boolean exclude) throws RequestException { HandlerCommandSender commandSender = new HandlerCommandSender(); Result result = commandSender.sendCommand(ctxt, "dbGetAllFieldNamesByTable", null); if (result.getRowCount() > 0) { String metaDataList = result.getRow(0).getFieldValue("result"); StringTokenizer tokenizer = new StringTokenizer(metaDataList, ","); while (tokenizer.hasMoreElements()) { String metaData = (String)tokenizer.nextElement(); String table = metaData.substring(0, metaData.indexOf('.')); if (!matchExclusionRules(table) || !exclude) { String column = metaData.substring(metaData.indexOf('.') + 1); if (!databaseTreeModel.getTableNamesList().contains(table)) { databaseTreeModel.getTableNamesList().add(table); databaseTreeModel.getTableNamesListRef().add(table); databaseTreeModel.getColumnListByTable().put(table, new ArrayList<String>()); databaseTreeModel.getColumnListByTableRef().put(table, new ArrayList<String>()); } List<String> columnList = databaseTreeModel.getColumnListByTable().get(table); List<String> columnListRef = databaseTreeModel.getColumnListByTableRef().get(table); if (!columnList.contains(column)) { columnList.add(column); } if (!columnListRef.contains(column)) { columnListRef.add(column); } } } } for (Entry<String, List<String>> entry : databaseTreeModel.getColumnListByTable().entrySet()) { List<String> list = entry.getValue(); Collections.sort(list); } for (Entry<String, List<String>> entry : databaseTreeModel.getColumnListByTableRef().entrySet()) { List<String> list = entry.getValue(); Collections.sort(list); } tableTree.setModel(databaseTreeModel); updateStatus(exclude); } private void updateStatus(boolean showTooltip) { Set<String> exclusionRuleSet = dataProcessGuiConfig.getTableExploratorConfig().getExclusionRuleSet(); statusLabel.setText(databaseTreeModel.getColumnListByTable().size() + " tables affich�es / " + databaseTreeModel.getColumnListByTableRef().size()); if (showTooltip) { statusLabel.setToolTipText(exclusionRuleSet.size() + " tables cach�es"); } else { statusLabel.setToolTipText(""); } } private boolean matchExclusionRules(String table) { Set<String> exclusionRuleSet = dataProcessGuiConfig.getTableExploratorConfig().getExclusionRuleSet(); for (String rule : exclusionRuleSet) { Pattern pattern = Pattern.compile(rule); Matcher matcher = pattern.matcher(table); if (matcher.find()) { return true; } } return false; } private String getClassNameListWindow(String tableName) { StringBuilder sb = new StringBuilder(); try { Preference preference = PreferenceFactory.getPreference(tableName); String detailWindowClassName = preference.getDetailWindowClass().getName(); sb.append(detailWindowClassName .substring(0, detailWindowClassName.length() - "DetailWindow".length())); sb.append("Action"); } catch (Exception ex) { String actionClassName = dataProcessGuiConfig.getTableExploratorConfig() .getTableAction(tableName); if (actionClassName != null) { sb.append(actionClassName); } } return sb.toString(); } private void openTable(String preference) { String actionClassName = null; try { actionClassName = getClassNameListWindow(preference); Action action; if (windowActionMap.get(actionClassName) == null) { Constructor constructor = Class.forName(actionClassName).getConstructor(GuiContext.class); action = (Action)constructor.newInstance(ctxt); windowActionMap.put(actionClassName, action); } else { action = windowActionMap.get(actionClassName); } ctxt.putProperty(DataProcessConstants.WHERE_CLAUSE_KEY, whereTextArea.getText()); action.actionPerformed(new ActionEvent(DataProcessConstants.TABLE_EXPLORATOR, 0, whereTextArea.getText())); } catch (Exception ex) { GuiUtils.showErrorDialog(frame, getClass(), String.format("Impossible d'ouvrir l'action '%s' de la table" + " avec la pr�f�rence '%s'", actionClassName, preference), ex); } } private static class DatabaseTreeModel implements TreeModel { private List<String> tableNamesListRef = new ArrayList<String>(); private List<String> tableNamesList = new ArrayList<String>(); private Map<String, List<String>> columnListByTableRef = new HashMap<String, List<String>>(); private Map<String, List<String>> columnListByTable = new HashMap<String, List<String>>(); private String root = "Tables"; DatabaseTreeModel() { } public void filter(String filter) { tableNamesList.clear(); columnListByTable.clear(); for (String tableName : tableNamesListRef) { if (filter.startsWith("*")) { if (tableName.toLowerCase().contains(filter.substring(1).toLowerCase())) { tableNamesList.add(tableName); columnListByTable.put(tableName, columnListByTableRef.get(tableName)); } } else { if (tableName.toLowerCase().startsWith(filter.toLowerCase())) { tableNamesList.add(tableName); columnListByTable.put(tableName, columnListByTableRef.get(tableName)); } } } } public Map<String, List<String>> getColumnListByTable() { return columnListByTable; } public Map<String, List<String>> getColumnListByTableRef() { return columnListByTableRef; } public List<String> getTableNamesList() { return tableNamesList; } public List<String> getTableNamesListRef() { return tableNamesListRef; } public void addTreeModelListener(TreeModelListener l1) { } public Object getChild(Object parent, int index) { if (parent == root) { return tableNamesList.get(index); } List<String> list = columnListByTable.get(parent.toString()); return list.get(index); } public int getChildCount(Object parent) { if (parent == root) { return tableNamesList.size(); } List<String> list = columnListByTable.get(parent.toString()); return list.size(); } public int getIndexOfChild(Object parent, Object child) { if (parent == root) { return tableNamesList.lastIndexOf(child.toString()); } List<String> list = columnListByTable.get(parent.toString()); return list.lastIndexOf(child.toString()); } public Object getRoot() { return root; } public boolean isLeaf(Object node) { return node != root && !tableNamesList.contains(node.toString()); } public void removeTreeModelListener(TreeModelListener l1) { } public void valueForPathChanged(TreePath path, Object newValue) { } } private class MyMouseAdapter extends MouseAdapter { @Override public void mousePressed(MouseEvent evt) { int selRow = tableTree.getRowForLocation(evt.getX(), evt.getY()); if (selRow != -1) { if (evt.getClickCount() == 2) { TreePath path = tableTree.getSelectionModel().getSelectionPath(); if (path != null && path.getPathCount() >= 2) { String tableName = (String)path.getPathComponent(1); openTable(tableName); } } } } } private class OpenTablesButtonListener implements ActionListener { public void actionPerformed(ActionEvent evt) { TreePath[] paths = tableTree.getSelectionModel().getSelectionPaths(); if (paths != null) { for (TreePath path : paths) { if (path.getPathCount() >= 2) { String tableName = (String)path.getPathComponent(1); openTable(tableName); } } } } } private class MyTreeKeyAdapter extends KeyAdapter { @Override public void keyPressed(KeyEvent e) { if (KeyEvent.VK_ENTER == e.getKeyCode()) { TreePath[] paths = tableTree.getSelectionModel().getSelectionPaths(); if (paths != null) { for (TreePath path : paths) { if (path.getPathCount() >= 2) { String tableName = (String)path.getPathComponent(1); openTable(tableName); } } } } } } }