/******************************************************************************
* *
* Copyright 2016 Subterranean Security *
* *
* Licensed under the Apache License, Version 2.0 (the "License"); *
* you may not use this file except in compliance with the License. *
* You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, software *
* distributed under the License is distributed on an "AS IS" BASIS, *
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and *
* limitations under the License. *
* *
*****************************************************************************/
package com.subterranean_security.crimson.viewer.ui.screen.main;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableRowSorter;
import com.subterranean_security.crimson.core.attribute.keys.AKeySimple;
import com.subterranean_security.crimson.core.attribute.keys.AttributeKey;
import com.subterranean_security.crimson.sv.profile.ClientProfile;
import com.subterranean_security.crimson.universal.stores.DatabaseStore;
import com.subterranean_security.crimson.viewer.ui.screen.settings.ListHeaderPopup;
public class HostList extends JPanel {
private static final long serialVersionUID = 1L;
public static final AttributeKey[] defaultHeaders = new AttributeKey[] { AKeySimple.IPLOC_COUNTRY,
AKeySimple.OS_NAME, AKeySimple.USER_NAME, AKeySimple.NET_HOSTNAME, AKeySimple.OS_LANGUAGE };
private static JTable table = new JTable();
private TM tm = new TM();
private TR tr = new TR(tm);
public HostList() {
init();
initRowSorter();
}
public void init() {
setLayout(new BorderLayout());
table.setModel(tm);
table.setDefaultRenderer(Object.class, tr);
table.setRowHeight(18);
table.setFillsViewportHeight(true);
table.setShowVerticalLines(false);
table.addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent e) {
if (MainFrame.main.dp.isMoving()) {
return;
}
// get source of click
int sourceRow = table.rowAtPoint(e.getPoint());
if (sourceRow == -1) {
table.clearSelection();
MainFrame.main.dp.closeDetail();
return;
} else if (!table.isRowSelected(sourceRow)) {
// select row
table.changeSelection(sourceRow, 0, false, false);
}
ClientProfile selected = tm.getRow(sourceRow);
if (e.getButton() == MouseEvent.BUTTON1) {
// open up the detail
MainFrame.main.dp.showDetail(selected);
} else if (e.getButton() == MouseEvent.BUTTON3) {
ContextMenuFactory.getMenu(selected, "list").show(table, e.getX(), e.getY());
}
}
});
table.getTableHeader().addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON3) {
ListHeaderPopup popup = new ListHeaderPopup(DatabaseStore.getDatabase());
popup.show(table.getTableHeader(), e.getX(), e.getY());
}
}
});
JScrollPane jsp = new JScrollPane(table);
add(jsp, BorderLayout.CENTER);
}
public void addClient(ClientProfile cp) {
tm.add(cp);
}
// TODO only update cell
public void updateField(ClientProfile cp, AttributeKey aa) {
for (int i = 0; i < tm.getClientList().size(); i++) {
if (cp.getCvid() == tm.getClientList().get(i).getCvid()) {
tm.fireTableRowsUpdated(i, i);
return;
}
}
}
public void removeClient(ClientProfile cp) {
for (int i = 0; i < tm.getClientList().size(); i++) {
if (cp.getCvid() == tm.getClientList().get(i).getCvid()) {
tm.getClientList().remove(i);
tm.fireTableRowsDeleted(i, i);
return;
}
}
}
public void refreshHeaders() {
tm.refreshHeaders();
initRowSorter();
}
private void initRowSorter() {
TableRowSorter<TM> sorter = new TableRowSorter<TM>(tm);
sorter.toggleSortOrder(0);
for (int i = 0; i < tm.headers.length; i++) {
AttributeKey aa = tm.headers[i];
if (aa instanceof AKeySimple) {
AKeySimple sa = (AKeySimple) aa;
switch (sa) {
case CLIENT_CID:
sorter.setComparator(i, new ClientProfile.CidComparator());
default:
sorter.setComparator(i, new ClientProfile.SimpleAttributeComparator(sa));
}
} else {
// TODO complex attribute
}
}
table.setRowSorter(sorter);
}
public void select(ClientProfile cp) {
List<ClientProfile> profiles = tm.getClientList();
for (int i = 0; i < profiles.size(); i++) {
if (cp.getCvid() == profiles.get(i).getCvid()) {
table.setRowSelectionInterval(i, i);
return;
}
}
}
}
class TM extends AbstractTableModel {
private static final long serialVersionUID = 1L;
public AttributeKey[] headers = new AttributeKey[] {};
private ArrayList<ClientProfile> clients = new ArrayList<ClientProfile>();
public ArrayList<ClientProfile> getClientList() {
return clients;
}
public void add(ClientProfile cp) {
clients.add(cp);
fireTableRowsInserted(clients.size() - 1, clients.size() - 1);
}
public TM() {
refreshHeaders();
}
public void refreshHeaders() {
try {
headers = (AttributeKey[]) DatabaseStore.getDatabase().getObject("hostlist.headers");
} catch (Exception e) {
headers = HostList.defaultHeaders;
}
this.fireTableStructureChanged();
}
@Override
public int getColumnCount() {
return headers.length;
}
@Override
public int getRowCount() {
return clients.size();
}
@Override
public String getColumnName(int column) {
return headers[column].toString();
};
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
return clients.get(rowIndex);
}
public ClientProfile getRow(int selected) {
return clients.get(selected);
}
}
class TR extends DefaultTableCellRenderer {
private static final long serialVersionUID = 1L;
private TM tm;
public TR(TM tm) {
this.tm = tm;
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
super.getTableCellRendererComponent(table, setupCell(table, (ClientProfile) value, column), isSelected,
hasFocus, row, column);
return this;
}
/**
* Setup and return the data for the given cell
*
* @param table
* @param file
* @param viewColumn
* @return
*/
private Object setupCell(JTable table, ClientProfile profile, int viewColumn) {
setBorder(noFocusBorder);
AttributeKey aa = tm.headers[table.convertColumnIndexToModel(viewColumn)];
if (aa instanceof AKeySimple) {
AKeySimple sa = (AKeySimple) aa;
switch (sa) {
case IPLOC_COUNTRY:
return profile.getLocationIcon();
case OS_NAME:
return profile.getOsNameIcon();
default:
return profile.get(sa);
}
} else {
// TODO complex attribute
return null;
}
}
protected void setValue(Object value) {
if (value instanceof ImageIcon) {
ImageIcon ico = (ImageIcon) value;
setIcon(ico);
setText(ico.getDescription());
} else {
setIcon(null);
super.setValue(value);
}
}
}