
admin.astor.tools.DeviceHierarchy Maven / Gradle / Ivy
//+======================================================================
// $Source: $
//
// Project: Tango
//
// Description: java source code for Tango manager tool..
//
// $Author$
//
// Copyright (C) : 2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,
// European Synchrotron Radiation Facility
// BP 220, Grenoble 38043
// FRANCE
//
// This file is part of Tango.
//
// Tango 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.
//
// Tango 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 Tango. If not, see .
//
// $Revision$
//
//-======================================================================
package admin.astor.tools;
import admin.astor.*;
import static admin.astor.AstorDefs.all_ok;
import fr.esrf.Tango.DevFailed;
import fr.esrf.TangoApi.*;
import fr.esrf.TangoDs.Except;
import fr.esrf.tangoatk.widget.util.ErrorPane;
import javax.swing.*;
import javax.swing.tree.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
public class DeviceHierarchy extends JTree implements AstorDefs {
private static ImageIcon root_icon;
private Astor astor = null;
private boolean running = true;
private Device root = null;
private String rootname = null;
private DeviceHierarchyPopupMenu menu;
private DeviceHierarchyDialog parent;
private String[] deviceNames = new String[0];
@SuppressWarnings("InspectionUsingGrayColors")
private static final Color BACKGROUND = new Color(0xf0, 0xf0, 0xf0);
private static final String SUB_DEV_PROP_NAME = "__SubDevices";
//===============================================================
//===============================================================
public DeviceHierarchy(DeviceHierarchyDialog parent, Astor astor, String name) throws DevFailed {
super();
this.parent = parent;
this.astor = astor;
setBackground(BACKGROUND);
initNames(name);
buildTree();
menu = new DeviceHierarchyPopupMenu(this);
this.expandRow(0);
for(int i = 0; i < this.getRowCount(); i++){
TreePath tp = this.getPathForRow(i);
Device d = (Device)tp.getLastPathComponent();
if(d.isDeviceFromServer){
this.expandPath(tp);
}
}
}
//===============================================================
private void initNames(String name) throws DevFailed {
String [] nameSplied = name.split("/");
switch (nameSplied.length) {
case 2: // Is a server name
rootname = nameSplied[0] + "/" + nameSplied[1];
String admin = "dserver/" + rootname;
String[] tmp = new TangoServer(admin).queryDeviceFromDb();
deviceNames = new String[tmp.length + 1];
System.arraycopy(tmp, 0, deviceNames, 0, tmp.length);
deviceNames[tmp.length] = admin; // Add amdin dev in last position
break;
case 3: // Is a device name
rootname = "Device";
deviceNames = new String[1];
deviceNames[0] = nameSplied[0] + "/" + nameSplied[1]+ "/" + nameSplied[2];
break;
default:
Except.throw_exception("BAD_PARAMETER",
"Bad device or server name",
"DeviceHierarchy.initNames()");
}
root = new Device(rootname,true);
root.isParent = true;
Device[] devices = new Device[deviceNames.length];
ArrayList listOfChildren = new ArrayList<>();
//create each Device class for each String find in DeviceList
//browsed devices Create Devices class
for (int i = 0 ; i < deviceNames.length ; i++){
String deviceName = deviceNames[i];
devices[i] = new Device(deviceName,true);
//add Children to the large list
addChildrenIfIsNotAlready(listOfChildren,devices[i]);
}
//find Root Device of the Server
for (Device dev : devices){
if(!listOfChildren.contains(dev.name)){
dev.isRootDevice = true;
root.add(dev);
}
}
}
//===============================================================
//===============================================================
private void buildTree() {
// Create the tree that allows one selection at a time.
getSelectionModel().setSelectionMode
(TreeSelectionModel.SINGLE_TREE_SELECTION);
// Create Tree and Tree model
DefaultTreeModel treeModel = new DefaultTreeModel(root);
setModel(treeModel);
//Enable tool tips.
ToolTipManager.sharedInstance().registerComponent(this);
// Set the icon for leaf nodes.
TangoRenderer renderer = new TangoRenderer();
setCellRenderer(renderer);
// Add Action listener
addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
treeMouseClicked(evt); // for tree clicked, menu,...
}
});
}
//======================================================
/*
* Manage event on clicked mouse on JTree object.
*/
//======================================================
private void treeMouseClicked(java.awt.event.MouseEvent evt) {
// Set selection at mouse position
TreePath selectedPath = getPathForLocation(evt.getX(), evt.getY());
if (selectedPath == null)
return;
DefaultMutableTreeNode node =
(DefaultMutableTreeNode) selectedPath.getPathComponent(selectedPath.getPathCount() - 1);
Object o = node;
int mask = evt.getModifiers();
// Check button clicked
if (evt.getClickCount() == 2 && (mask & MouseEvent.BUTTON1_MASK) != 0) {
} else if ((mask & MouseEvent.BUTTON1_MASK) != 0) {
deviceInfo((Device)node);
} else if ((mask & MouseEvent.BUTTON3_MASK) != 0) {
if (node == root)
menu.showMenu(evt, (String) o);
else if (o instanceof Device)
menu.showMenu(evt, (Device) o);
}
}
//======================================================
//======================================================
private DefaultMutableTreeNode getSelectedNode() {
return (DefaultMutableTreeNode) getLastSelectedPathComponent();
}
//======================================================
//======================================================
Object getSelectedObject() {
DefaultMutableTreeNode node = getSelectedNode();
if (node == null)
return null;
return node;
}
//===============================================================
//===============================================================
private void testDevice(Device dev) {
AstorUtil.testDevice(parent, dev.name);
}
//===============================================================
//===============================================================
private void deviceInfo(Device dev) {
try {
String info = dev.getInfo();
parent.setText(info);
} catch (DevFailed e) {
parent.setText(Except.str_exception(e));
}
}
//===============================================================
//===============================================================
private void remoteShell(Device dev) {
try {
String hostname = dev.getHost();
new RemoteLoginThread(hostname).start();
} catch (DevFailed e) {
parent.setText(Except.str_exception(e));
}
}
//===============================================================
//===============================================================
private void hostPanel(Device dev) {
try {
astor.tree.displayHostInfoDialog(dev.getHost());
} catch (DevFailed e) {
ErrorPane.showErrorMessage(parent, null, e);
}
}
//===============================================================
//===============================================================
void stopThread() {
running = false;
}
//===============================================================
//===============================================================
@Override
public String toString() {
String str = "";
for(int i = 0 ; i < root.getChildCount(); i++){
Device dev = root.getDevice(i);
str += dev.toFullString();
for (int j = 0; j < dev.getChildCount(); j++){
str += dev.getDevice(j).toFullString();
}
}
return str;
}
private void addChildrenIfIsNotAlready(ArrayList listOfChildren, Device dev) {
for(String child : dev.childrenStr){
if(!listOfChildren.contains(child)){
if(!dev.name.equals(child)){
listOfChildren.add(child);
}
}
}
}
//==============================================================================
/*
* The Popup menu class
*/
//==============================================================================
static private final int UPDATE = 0;
static private final int TEST_DEVICE = 1;
static private final int HOST_PANEL = 2;
static private final int REM_LOGIN = 3;
static private final int OFFSET = 2; // Label And separator
static private String[] menuLabels = {
"Update Dependencies",
"Test Device",
"Host Panel",
"Remote Login",
};
private class DeviceHierarchyPopupMenu extends JPopupMenu {
private JTree tree;
private JLabel title;
//=======================================================
/*
* Create a Popup menu
*/
//=======================================================
private DeviceHierarchyPopupMenu(JTree tree) {
this.tree = tree;
buildBtnPopupMenu();
}
//=======================================================
//=======================================================
private void buildBtnPopupMenu() {
title = new JLabel();
title.setFont(new java.awt.Font("Dialog", Font.BOLD, 16));
add(title);
add(new JPopupMenu.Separator());
for (String menuLabel : menuLabels) {
if (menuLabel == null)
add(new Separator());
else {
JMenuItem btn = new JMenuItem(menuLabel);
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
deviceActionPerformed(evt);
}
});
add(btn);
}
}
}
//======================================================
/*
* Show menu on root
*/
//======================================================
public void showMenu(MouseEvent evt, String name) {
// Set selection at mouse position
TreePath selectedPath =
tree.getPathForLocation(evt.getX(), evt.getY());
if (selectedPath == null)
return;
tree.setSelectionPath(selectedPath);
title.setText(name);
// Reset all items
for (int i = 0; i < menuLabels.length; i++)
getComponent(OFFSET + i).setVisible(false);
getComponent(OFFSET /* +UPDATE*/).setVisible(true);
show(tree, evt.getX(), evt.getY());
}
//======================================================
/*
* Show menu on Collection
*/
//======================================================
public void showMenu(MouseEvent evt, Device dev) {
// Set selection at mouse position
TreePath selectedPath =
tree.getPathForLocation(evt.getX(), evt.getY());
if (selectedPath == null)
return;
tree.setSelectionPath(selectedPath);
deviceInfo(dev);
// Display menu only if new DeviceProxy did not failed.
if (dev.failed == null) {
title.setText(dev.toString());
// Reset all items
getComponent(OFFSET /* + UPDATE*/).setVisible(false);
for (int i = REM_LOGIN; i < menuLabels.length; i++)
getComponent(OFFSET + i).setEnabled(false);
getComponent(OFFSET + REM_LOGIN).setEnabled(AstorUtil.osIsUnix());
getComponent(OFFSET + HOST_PANEL).setEnabled(astor != null);
getComponent(OFFSET + TEST_DEVICE).setEnabled(dev.state == all_ok);
// Manage for READ_ONLY mode
if (Astor.rwMode==AstorDefs.READ_ONLY) {
getComponent(OFFSET + TEST_DEVICE).setVisible(false);
}
show(tree, evt.getX(), evt.getY());
}
}
//======================================================
private void deviceActionPerformed(ActionEvent evt) {
Device dev = (Device)getSelectedNode();
// Check component source
Object obj = evt.getSource();
int cmdidx = 0;
for (int i = 0; i < menuLabels.length; i++)
if (getComponent(OFFSET + i) == obj)
cmdidx = i;
switch (cmdidx) {
case UPDATE:
parent.update();
break;
case REM_LOGIN:
remoteShell(dev);
break;
case HOST_PANEL:
hostPanel(dev);
break;
case TEST_DEVICE:
testDevice(dev);
break;
}
}
}
//===============================================================
/*
* Device object definition, containing its subdevices
*/
//===============================================================
private class Device extends DefaultMutableTreeNode {
DeviceProxy proxy;
DevFailed failed = null;
String name;
boolean too_old = false;
boolean isParent = false;
boolean isPopulated = false;
boolean isRootDevice = false;
boolean isDeviceFromServer = false;
short state = unknown;
String[] childrenStr;
//===========================================================
private Device(String name, boolean isDeviceFromServer) {
super(name);
AstorUtil.increaseSplashProgress(1, "checking for " + name);
this.isDeviceFromServer = isDeviceFromServer;
try {
this.name = name;
proxy = new DeviceProxy(name);
new StateManager().start();
// If failed, check on property
DbDatum datum = proxy.get_property(SUB_DEV_PROP_NAME);
childrenStr = datum.extractStringArray();
if(childrenStr.length == 1 && childrenStr[0]==""){
childrenStr = new String[0];
}else{
isParent = true;
}
} catch (DevFailed e) {
System.err.println(e.errors[0].desc);
failed = e;
}
}
@Override
public boolean isLeaf() {
return !isParent; //To change body of generated methods, choose Tools | Templates.
}
//===========================================================
private Device getDevice(int i) {
return (Device)this.getChildAt(i);
}
//===========================================================
private String toFullString() {
String toReturn = (String)this.userObject;
toReturn += '\n';
for (int i = 0; i < this.getChildCount(); i++) {
Device d = this.getDevice(i);
toReturn = toReturn + '\t' + (String)d.userObject + '\n';
}
toReturn += "------------------------------------------------";
return toReturn;
}
@Override
public int getChildCount() {
if(isParent && this.childrenStr != null){
if(!isPopulated){
isPopulated = true;
for(String child : this.childrenStr){
boolean isDeviceFromServer = isDeviceFromServer(child);
Device dev = new Device(child,isDeviceFromServer);
this.add(dev);
}
}
}
return super.getChildCount();
}
private boolean isDeviceFromServer(String child) {
if(child.equals(this.name)){
return false;
}
for(String dev : deviceNames){
if(dev.equals(child)){
return true;
}
}
return false;
}
//===========================================================
private class StateManager extends Thread {
public void run() {
while (running) {
try {
proxy.ping();
state = all_ok;
} catch (DevFailed e) {
state = faulty;
}
repaint();
try { sleep(2000); } catch (InterruptedException e) { /* */ }
}
}
}
//===========================================================
private String getHost() throws DevFailed {
DeviceInfo info = proxy.get_info();
return info.hostname;
}
//===========================================================
private String getInfo() throws DevFailed {
if (failed != null)
return Except.str_exception(failed);
else {
StringBuilder sb = new StringBuilder();
if (too_old)
sb.append(" WARNING: Too Old TANGO Release \n")
.append(" To get dependencies !!!\n")
.append("\n========================================================\n");
sb.append(proxy.get_info().toString());
sb.append("\n========================================================\n");
try {
String s = proxy.status();
sb.append(s);
} catch (DevFailed e) {
sb.append(Except.str_exception(e));
}
return sb.toString();
}
}
//===========================================================
@Override
public String toString() {
return (String)this.userObject;
}
//===========================================================
}
//===========================================================
// End of Device class
//===========================================================
//===============================================================
/**
* Renderer Class
*/
//===============================================================
private class TangoRenderer extends DefaultTreeCellRenderer {
private Font[] fonts;
private final int TITLE = 0;
private final int COLLEC = 1;
private final int LEAF = 2;
private boolean firstPass = true;
//===============================================================
//===============================================================
public TangoRenderer() {
Utils utils = Utils.getInstance();
root_icon = Utils.getResizedIcon(Utils.getTangoClassIcon(), 0.33);
fonts = new Font[LEAF + 1];
fonts[TITLE] = new Font("Dialog", Font.BOLD, 18);
fonts[COLLEC] = new Font("Dialog", Font.BOLD, 12);
fonts[LEAF] = new Font("Dialog", Font.PLAIN, 12);
}
//===============================================================
//===============================================================
public Component getTreeCellRendererComponent(
JTree tree,
Object obj,
boolean sel,
boolean expanded,
boolean leaf,
int row,
boolean hasFocus) {
super.getTreeCellRendererComponent(
tree, obj, sel,
expanded, leaf, row,
hasFocus);
setBackgroundNonSelectionColor(BACKGROUND);
setForeground(Color.black);
setBackgroundSelectionColor(Color.lightGray);
if (row == 0) {
// ROOT
setFont(fonts[TITLE]);
setIcon(root_icon);
} else {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) obj;
if (node instanceof Device) {
setFont(fonts[COLLEC]);
Device device = (Device) node;
setIcon(AstorUtil.state_icons[device.state]);
if (device.too_old)
setBackgroundNonSelectionColor(Color.yellow);
}
}
return this;
}
}
//==============================================================================
// End of Renderer Class
//==============================================================================
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy