/*******************************************************************************
* LogDruid : Generate charts and reports using data gathered in log files
* Copyright (C) 2016 Frederic Valente (frederic.valente@gmail.com)
*
* This program 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 (at your option) any later version.
*
* This program 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 logdruid.ui.mainpanel;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import javax.swing.JTable;
import javax.swing.BoxLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import javax.swing.border.BevelBorder;
import javax.swing.plaf.basic.BasicBorders.SplitPaneBorder;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.border.LineBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.Color;
import javax.swing.JButton;
import java.awt.Insets;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.FlowLayout;
import java.text.ParseException;
import org.apache.commons.lang3.time.FastDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import logdruid.data.Preferences;
import logdruid.data.Repository;
import logdruid.data.Source;
import logdruid.data.mine.DataVault;
import logdruid.data.record.EventRecording;
import logdruid.data.record.MetadataRecording;
import logdruid.data.record.Recording;
import logdruid.data.record.RecordingItem;
import logdruid.data.record.ReportRecording;
import logdruid.data.record.StatRecording;
import logdruid.ui.editor.EventRecordingEditor;
import logdruid.ui.editor.MetadataRecordingEditor;
import logdruid.ui.editor.ReportRecordingEditor;
import logdruid.ui.editor.StatRecordingEditor;
import logdruid.util.DataMiner;
import javax.swing.RowSorter;
import javax.swing.SortOrder;
import javax.swing.SwingConstants;
import javax.swing.JSeparator;
import javax.swing.JComboBox;
import javax.swing.JScrollPane;
import org.apache.log4j.Logger;
import javax.swing.JSplitPane;
public class RecordingList extends JPanel {
private static Logger logger = Logger.getLogger(DataMiner.class.getName());
public static JTable table;
JPanel jPanelDetail;
private RecordingList thiis = this;
boolean DEBUG = false;
static Matcher m;
static ArrayList records = null;
private String[] header ;
// 0-> sum of time for success matching of given
// recording ; 1-> sum of time for failed
// matching ; 2-> count of match attempts,
// 3->count of success attempts
private Vector<Object[]> data = new Vector<Object[]>();
private Repository repository = null;
private JPanel recEditor = null;
public MyTableModel2 model;
long[] stats;
/**
* Create the panel.
*/
public RecordingList(final Repository rep) {
if (Preferences.getPreference("timings").equals("true") && Preferences.getPreference("matches").equals("true") ) {
header = (String[]) new String[] { "name", "regexp", "type", "active", "success time", "failed time", "match attempt", "success match" };
} else if (Preferences.getPreference("timings").equals("false") && Preferences.getPreference("matches").equals("true") ) {
header = (String[]) new String[] { "name", "regexp", "type", "active", "match attempt", "success match" };
} else if (Preferences.getPreference("timings").equals("true") && Preferences.getPreference("matches").equals("false") ) {
header = (String[]) new String[] { "name", "regexp", "type", "active" ,"success time", "failed time", };
} else {
header = (String[]) new String[] { "name", "regexp", "type", "active" };
}
records = rep.getRecordings();
// Collections.sort(records);
Iterator it = records.iterator();
while (it.hasNext()) {
Recording record = (Recording) it.next();
logger.debug("about to call DataVault.getRecordingStats on :"+record.getName());
stats = DataVault.getRecordingStats(record.getName());
if (stats != null) {
if (Preferences.getPreference("timings").equals("false") && Preferences.getPreference("matches").equals("true") ) {
data.add(new Object[] { record.getName(), record.getRegexp(), record.getType(), record.getIsActive(), stats[2],
stats[3] });
} else if (Preferences.getPreference("timings").equals("true") && Preferences.getPreference("matches").equals("false") ) {
data.add(new Object[] { record.getName(), record.getRegexp(), record.getType(), record.getIsActive(), stats[0], stats[1]});
} else if (Preferences.getPreference("timings").equals("true") && Preferences.getPreference("matches").equals("true") ) {
data.add(new Object[] { record.getName(), record.getRegexp(), record.getType(), record.getIsActive(), stats[0], stats[1], stats[2],
stats[3] });
}
} else {
data.add(new Object[] { record.getName(), record.getRegexp(), record.getType(), record.getIsActive(), 0, 0, 0, 0 });
}
}
repository = rep;
model = new MyTableModel2(data, header);
JPanel panel_1 = new JPanel();
GridBagConstraints gbc_panel_1 = new GridBagConstraints();
gbc_panel_1.fill = GridBagConstraints.BOTH;
gbc_panel_1.insets = new Insets(5, 0, 5, 5);
gbc_panel_1.gridx = 1;
gbc_panel_1.gridy = 0;
panel_1.setLayout(new BorderLayout(0, 0));
table = new JTable(model);
JScrollPane scrollPane = new JScrollPane(table);int column;
panel_1.add(scrollPane);
table.setPreferredScrollableViewportSize(new Dimension(0, 150));
table.setFillsViewportHeight(true);
// Set up column sizes.
initColumnSizes(table);
table.setAutoCreateRowSorter(true);
// RowSorter sorter = table.getRowSorter();
// sorter.setSortKeys(Arrays.asList(new RowSorter.SortKey(0, SortOrder.ASCENDING)));
if (model.getRowCount()>0){
table.getRowSorter().toggleSortOrder(0);
table.getRowSorter().toggleSortOrder(2);
}
table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
int selectedRow = ((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1);
;
logger.debug("ListSelectionListener - selectedRow: " + selectedRow);
if (selectedRow >= 0) {
if (jPanelDetail != null) {
logger.debug("ListSelectionListener - valueChanged");
jPanelDetail.removeAll();
recEditor = getEditor(repository.getRecording(selectedRow));
if (recEditor != null) {
jPanelDetail.add(recEditor, BorderLayout.CENTER);
}
jPanelDetail.revalidate();
}
}
}
});
JPanel panel = new JPanel();
FlowLayout flowLayout = (FlowLayout) panel.getLayout();
flowLayout.setAlignment(FlowLayout.LEFT);
flowLayout.setVgap(2);
flowLayout.setHgap(2);
panel_1.add(panel, BorderLayout.SOUTH);
JButton btnNewMeta = new JButton("New File Grouping");
panel.add(btnNewMeta);
btnNewMeta.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
int rowCount = table.getRowCount();
jPanelDetail.removeAll();
Recording re = new MetadataRecording("name", "regex", "example line", "", true, true, null);
recEditor = new MetadataRecordingEditor(thiis, repository, "the line", "regex", (MetadataRecording) re,null);
jPanelDetail.add(recEditor, BorderLayout.CENTER);
repository.addRecording(re);
model.addRow(new Object[] { re.getName(), re.getRegexp(), re.getType(), re.getIsActive(), 0, 0, 0, 0 });
model.fireTableRowsInserted(rowCount, rowCount);
table.setRowSelectionInterval(rowCount, rowCount);
logger.debug("New record - row count : " + rowCount);
}
});
JButton btnDuplicate = new JButton("Duplicate");
btnDuplicate.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int rowCount = table.getRowCount();
int selectRow = ((table.getSelectedRow() != -1) ? table.getSelectedRow() : -1);
int selectedRow = ((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1);
rep.duplicateRecording(table.convertRowIndexToModel(table.getSelectedRow()));
model.fireTableRowsInserted(rowCount, rowCount);
table.setRowSelectionInterval(selectRow+1, selectRow+1);
}
});
JButton btnNewStat = new JButton("New Stat");
btnNewStat.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int rowCount = table.getRowCount();
jPanelDetail.removeAll();
Recording re = new StatRecording("name", "regex", "example line", "", true,true, true, null);
recEditor = new StatRecordingEditor(thiis, repository, "the line", "regex", (StatRecording) re);
jPanelDetail.add(recEditor, BorderLayout.CENTER);
repository.addRecording(re);
model.addRow(new Object[] { re.getName(), re.getRegexp(), re.getType(), re.getIsActive(), 0, 0, 0, 0 });
model.fireTableRowsInserted(rowCount, rowCount);
table.setRowSelectionInterval(rowCount, rowCount);
logger.debug("New record - row count : " + rowCount);
}
});
panel.add(btnNewStat);
JButton btnNewEvent = new JButton("New Event");
btnNewEvent.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int rowCount = table.getRowCount();
logger.debug("table.getRowCount()" + table.getRowCount());
jPanelDetail.removeAll();
Recording re = new EventRecording("name", "regex", "example line", "", true, true, true, null);
recEditor = new EventRecordingEditor(thiis, repository, "the line", "regex", (EventRecording) re);
jPanelDetail.add(recEditor, BorderLayout.CENTER);
repository.addRecording(re);
model.addRow(new Object[] { re.getName(), re.getRegexp(), re.getType(), re.getIsActive(), 0, 0, 0, 0 });
model.fireTableRowsInserted(rowCount, rowCount);
table.setRowSelectionInterval(rowCount, rowCount);
logger.debug("New record - row count : " + rowCount);
}
});
panel.add(btnNewEvent);
JButton btnNewReport = new JButton("New Report");
btnNewReport.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int rowCount = table.getRowCount();
logger.debug("table.getRowCount()" + table.getRowCount());
jPanelDetail.removeAll();
Recording re = new ReportRecording("name", "regex", "example line", "", true, true, null,"histogram",true);
recEditor = new ReportRecordingEditor(thiis, repository, "the line", "regex", (ReportRecording) re, "histogram");
jPanelDetail.add(recEditor, BorderLayout.CENTER);
repository.addRecording(re);
model.addRow(new Object[] { re.getName(), re.getRegexp(), re.getType(), re.getIsActive(), 0, 0, 0, 0 });
model.fireTableRowsInserted(rowCount, rowCount);
table.setRowSelectionInterval(rowCount, rowCount);
logger.debug("New record - row count : " + rowCount);
}
});
panel.add(btnNewReport);
panel.add(btnDuplicate);
JButton btnDelete = new JButton("Delete");
btnDelete.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int rowCount = table.getRowCount();
int selectedRow = ((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1);
;
int realSelectedRow=table.getSelectedRow() ;
logger.debug("selectedRow : " + selectedRow + ", row count: " + table.getRowCount());
if (rowCount!=0){
repository.deleteRecording(selectedRow);
model.fireTableRowsDeleted(selectedRow, selectedRow);
// table.remove(selectedRow);
if (realSelectedRow!= -1){
if (realSelectedRow!= 0)table.setRowSelectionInterval(realSelectedRow-1, realSelectedRow-1);
else if (realSelectedRow >0)table.setRowSelectionInterval(realSelectedRow, realSelectedRow);
else if (rowCount>1) table.setRowSelectionInterval(0, 0);
}
/* if (table.getRowCount() > 0) {
if (selectedRow == table.getRowCount()) {
table.setRowSelectionInterval(selectedRow - 1, selectedRow - 1);
} else
table.setRowSelectionInterval(selectedRow, selectedRow);
}*/
}}
});
panel.add(btnDelete);
setLayout(new BorderLayout(0, 0));
JSplitPane splitPane = new JSplitPane();
splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
add(splitPane, BorderLayout.CENTER);
jPanelDetail = new JPanel();
GridBagConstraints gbc_jPanelDetail = new GridBagConstraints();
gbc_jPanelDetail.insets = new Insets(0, 0, 0, 5);
gbc_jPanelDetail.fill = GridBagConstraints.BOTH;
gbc_jPanelDetail.gridx = 1;
gbc_jPanelDetail.gridy = 4;
splitPane.setBottomComponent(jPanelDetail);
splitPane.setTopComponent(panel_1);
jPanelDetail.setLayout(new BorderLayout(0, 0));
if (repository.getRecordingCount() > 0) {
//recEditor = getEditor(repository.getRecording(0));
//jPanelDetail.add(recEditor, BorderLayout.CENTER);
table.setRowSelectionInterval(0, 0);
}
jPanelDetail.revalidate();
}
private JPanel getEditor(Recording rec) {
JPanel editorPanel = null;
if (rec.getClass() == StatRecording.class) {
editorPanel = new StatRecordingEditor(thiis, repository, rec.getExampleLine(), rec.getRegexp(), ((StatRecording) rec));
} else if (rec.getClass() == MetadataRecording.class) {
editorPanel = new MetadataRecordingEditor(thiis, repository, rec.getExampleLine(), rec.getRegexp(),
((MetadataRecording) rec),null);
} else if (rec.getClass() == EventRecording.class) {
editorPanel = new EventRecordingEditor(thiis, repository, rec.getExampleLine(), rec.getRegexp(), ((EventRecording) rec));
} else if (rec.getClass() == ReportRecording.class) {
editorPanel = new ReportRecordingEditor(thiis, repository, rec.getExampleLine(), rec.getRegexp(), ((ReportRecording) rec), ((ReportRecording) rec).getSubType());
}
return editorPanel;
}
private void initColumnSizes(JTable theTable) {
MyTableModel2 model = (MyTableModel2) theTable.getModel();
TableColumn column = null;
Component comp = null;
int headerWidth = 0;
int cellWidth = 0;
// Object[] longValues = model.longValues;
TableCellRenderer headerRenderer = theTable.getTableHeader().getDefaultRenderer();
for (int i = 0; i < 4; i++) {
column = theTable.getColumnModel().getColumn(i);
comp = headerRenderer.getTableCellRendererComponent(null, column.getHeaderValue(), false, false, 0, 0);
headerWidth = comp.getPreferredSize().width;
cellWidth = comp.getPreferredSize().width;
column.setPreferredWidth(Math.max(headerWidth, cellWidth));
}
}
public class MyTableModel2 extends AbstractTableModel {
private String[] header;
private Vector data = new Vector();
public MyTableModel2(Vector<Object[]> data, String[] header) {
this.header = header;
this.data = data;
}
@Override
public int getColumnCount() {
if (header == null) {
return 0;
} else
return header.length;
}
@Override
public String getColumnName(int column) {
return header[column];
}
@Override
public int getRowCount() {
return repository.getRecordingCount();
}
public void addRow(Object[] obj) {
data.add(obj);
}
public void updateRow(int rowId, Object[] obj) {
data.set(rowId, obj);
}
@Override
public Object getValueAt(int row, int column) {
if (column == 0 ) {
return repository.getRecording(row).getName();
} else if (column == 1 ) {
return repository.getRecording(row).getRegexp();
} else if (column == 2 ) {
return repository.getRecording(row).getType();
} else if (column == 3 ) {
logger.debug("setValueAt calls setActiveRecording");
return repository.getRecording(row).getIsActive();
} else if (column >3 && column<9) {
stats = DataVault.getRecordingStats(repository.getRecording(row).getName());
if (stats != null) {
if (Preferences.getPreference("timings").equals("false") && Preferences.getPreference("matches").equals("true") ) {
return stats[column - 2];
} else {
return stats[column - 4];
}
} else return 0;
}
else return 0;
}
@Override
public void setValueAt(Object value, int row, int column) {
if (column == 3 ) {
logger.debug("setValueAt calls setActiveRecording");
repository.getRecording(row).setIsActive((Boolean)value);
//.toggleActiveRecording(repository.getRecording(MetadataRecording.class, row));
fireTableCellUpdated(row, column);
// logger.debug("control of setValueAt: "+source.isActiveRecordingOnSource(repository.getRecording(MetadataRecording.class,
// row)));
} else {
((Object[]) data.get(row))[column] = value;
// logger.debug("setValueAt"+row+","+column);
fireTableCellUpdated(row, column);
}
}
/*
* JTable uses this method to determine the default renderer/ editor for
* each cell. If we didn't implement this method, then the last column
* would contain text ("true"/"false"), rather than a check box.
*/
public Class getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
/*
* Don't need to implement this method unless your table's editable.
*/
public boolean isCellEditable(int row, int col) {
// Note that the data/cell address is constant,
// no matt&er where the cell appears onscreen.
if (col != 3) {
return false;
} else {
return true;
}
}
/*
* Don't need to implement this method unless your table's data can
* change.
*/
/*
* public void setValueAt(Object value, int row, int col) { if (DEBUG) {
* logger.debug("Setting value at " + row + "," + col + " to " + value +
* " (an instance of " + value.getClass() + ")"); }
*
* data[row][col] = value; fireTableCellUpdated(row, col);
*
* if (DEBUG) { logger.debug("New value of data:"); printDebugData(); } }
*
* private void printDebugData() { int numRows = getRowCount(); int
* numCols = getColumnCount();
*
* for (int i=0; i < numRows; i++) { System.out.print(" row " + i +
* ":"); for (int j=0; j < numCols; j++) { System.out.print(" " +
* data[i][j]); } logger.debug(); }
* logger.debug("--------------------------"); }
*/
}
/**
* Create the GUI and show it. For thread safety, this method should be
* invoked from the event-dispatching thread.
*
* private static void createAndShowGUI() { // Create and set up the window.
* JFrame frame = new JFrame("RecordingEditorTable");
* frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
*
* // Create and set up the content pane. ReportPanel newContentPane = new
* ReportPanel(null, repository); newContentPane.setOpaque(true); //
* content panes must be opaque frame.setContentPane(newContentPane);
*
* // Display the window. frame.pack(); frame.setVisible(true); }
*/
/*
* public ArrayList<RecordingItem> getRecordingItems() {
* ArrayList<RecordingItem> toReturn = new ArrayList<RecordingItem>(); for
* (int i = 0; i < data.size(); i++) { // model.getRowCount()
* toReturn.add(new RecordingItem((String) model.getValueAt(i, 0),(String)
* model.getValueAt(i, 1), (String) model.getValueAt(i, 2), (Boolean)
* model.getValueAt(i, 3)); } return toReturn; }
*/
/*
* public void Add() { data.add(new Object[] { " ", "", "long", "",
* Boolean.TRUE, "" }); table.repaint(); }
*/
public void Remove() {
data.remove(((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1));
repository.deleteRecording(((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1));
table.repaint();
}
}