package ch.rakudave.jnetmap.view.components;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.net.InetAddress;
import java.text.DateFormat;
import java.util.Map;
import java.util.TreeSet;
import java.util.Vector;
import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.border.Border;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import ch.rakudave.jnetmap.controller.Scheduler;
import ch.rakudave.jnetmap.model.IF.NetworkIF;
import ch.rakudave.jnetmap.model.device.Device;
import ch.rakudave.jnetmap.model.device.Device.Type;
import ch.rakudave.jnetmap.net.PortScan;
import ch.rakudave.jnetmap.net.SNMP;
import ch.rakudave.jnetmap.util.Icons;
import ch.rakudave.jnetmap.util.Lang;
import ch.rakudave.jnetmap.view.properties.DeviceProperties;
import edu.uci.ics.jung.visualization.control.GraphMouseListener;
@SuppressWarnings("serial")
public class InfoPanel extends JPanel implements GraphMouseListener<Device> {
private Device current;
private JLabel icon, status;
private JTextArea description;
private JList snmpLeft, snmpRight;
private JButton prefs, ports;
/**
* Context-sentitive sidebar-panel, show details of selected device
* @param owner
*/
public InfoPanel(final Frame owner) {
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
JPanel infoPanel = new JPanel(new BorderLayout(5, 5));
infoPanel.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
infoPanel.setMaximumSize(new Dimension(2000, 135));
icon = new JLabel("", Icons.getCisco("workstation"), JLabel.LEADING);
icon.setBorder(BorderFactory.createEmptyBorder(2,2,2,2));
description = new JTextArea();
description.setLineWrap(true);
description.setWrapStyleWord(true);
description.setFocusable(false);
description.setBackground(new Color(getBackground().getRGB()));
JScrollPane sp = new JScrollPane(description);
sp.setViewportBorder(BorderFactory.createEmptyBorder());
status = new JLabel();
infoPanel.add(icon, BorderLayout.NORTH);
infoPanel.add(sp, BorderLayout.CENTER);
infoPanel.add(status, BorderLayout.SOUTH);
JPanel snmpPanel = new JPanel(new BorderLayout());
Border b = BorderFactory.createTitledBorder("SNMP");
JPanel inner = new JPanel(new BorderLayout());
snmpPanel.setBorder(b);
snmpLeft = new JList();
snmpRight = new JList();
snmpLeft.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
snmpRight.setSelectedIndex(snmpLeft.getSelectedIndex());
}
});
snmpRight.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
snmpLeft.setSelectedIndex(snmpRight.getSelectedIndex());
}
});
inner.add(snmpLeft, BorderLayout.WEST);
inner.add(snmpRight, BorderLayout.CENTER);
snmpPanel.add(new JScrollPane(inner), BorderLayout.CENTER);
JPanel buttons = new JPanel(new GridLayout(0, 2, 5, 5));
buttons.setMaximumSize(new Dimension(2000, 30));
prefs = new JButton(new AbstractAction(Lang.get("menu.file.properties"), Icons.get("properties")) {
@Override
public void actionPerformed(ActionEvent e) {
if (current != null)
new DeviceProperties(owner, current, false);
}
});
prefs.setEnabled(false);
ports = new JButton(new AbstractAction(Lang.getNoHTML("port.scan"), Icons.get("find")) {
@Override
public void actionPerformed(ActionEvent e) {
if (current != null && current.getInterfaces().size() > 0) {
try {
new PortScanner(owner, current.getInterfaces().get(0).
getAddress().getHostAddress());
} catch (Exception ex) {/*meh*/}
}
}
});
ports.setEnabled(false);
buttons.add(prefs);
buttons.add(ports);
add(Box.createVerticalStrut(5));
add(infoPanel);
add(snmpPanel);
add(buttons);
}
@Override public void graphReleased(Device arg0, MouseEvent arg1) {}
@Override public void graphPressed(Device arg0, MouseEvent arg1) {}
@Override
public void graphClicked(final Device arg0, MouseEvent arg1) {
prefs.setEnabled(true);
ports.setEnabled(true);
current = arg0;
icon.setIcon((Type.Other.equals(arg0.getType()))?Icons.fromBase64(arg0.getOtherID()):Icons.getCisco(arg0.getType().toString().toLowerCase()));
StringBuffer sb = new StringBuffer();
sb.append("<html>").append(arg0.getName());
if (!arg0.getVendor().isEmpty()) sb.append("<br>").append(arg0.getVendor());
if (!arg0.getModel().isEmpty()) sb.append(", ").append(arg0.getModel());
if (!arg0.getLocation().isEmpty()) sb.append("<br>").append(arg0.getLocation());
sb.append("</html>");
icon.setText(sb.toString());
description.setText(arg0.getDesctription());
if (arg0.getLastSeen() == null) {
status.setText(arg0.getStatus().getMessage());
} else {
status.setText(arg0.getStatus().getMessage() + " " + Lang.getNoHTML("since") + ": " +
DateFormat.getInstance().format(arg0.getLastSeen()));
}
Scheduler.execute(new Runnable() {
@Override
public void run() {
snmpScan(arg0);
}
});
}
private void snmpScan(Device d) {
if (d == null) return;
InetAddress address = null;
for (NetworkIF nif : d.getInterfaces()) {
if (PortScan.isOpen(nif.getAddress(), 161)) {
address = nif.getAddress();
break;
}
}
Map<String, String> map = SNMP.getValues(address);
if (map == null) {
snmpLeft.setListData(new String[]{""});
snmpRight.setListData(new String[]{""});
return;
}
Vector<String> left = new Vector<String>(), right = new Vector<String>();
for (String s : new TreeSet<String>(map.keySet())) {
left.add(s);
right.add(map.get(s));
}
if (d != current) return; //abort is selection has changes
snmpLeft.setListData(left);
snmpRight.setListData(right);
}
}