/* * Copyright to the original author or authors. * * 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 org.rioproject.cybernode.ui; import net.jini.core.lookup.ServiceItem; import org.rioproject.cybernode.Cybernode; import org.rioproject.cybernode.CybernodeAdmin; import org.rioproject.system.capability.PlatformCapability; import org.rioproject.system.capability.platform.ByteOrientedDevice; import javax.swing.*; import javax.swing.table.AbstractTableModel; import javax.swing.table.TableColumnModel; import java.awt.*; import java.awt.event.*; import java.util.Properties; import java.util.Vector; /** * The PlatformCapabilityUI displays PlatformCapability instances for a Cybernode and * allows administrators to enable/disable persistent provisioning * * @author Dennis Reedy */ @SuppressWarnings("unused") public class PlatformCapabilityUI extends JPanel { /** The CybernodeAdmin instance */ private CybernodeAdmin cybernodeAdmin; /** JTable for PlatformCapability display */ private final JTable capabilityTable; /** The model for the table */ private final PlatformCapabilityModel dataModel; /** Checkbox for persistent provisioning support */ private final JCheckBox supportsProvisioning; public PlatformCapabilityUI(final Object arg) { super(); getAccessibleContext().setAccessibleName("Platform Capabilities"); ServiceItem item = (ServiceItem)arg; Cybernode cybernode = (Cybernode) item.service; try { cybernodeAdmin = (CybernodeAdmin) cybernode.getAdmin(); } catch (Exception e) { showError(e); } setLayout(new BorderLayout(2, 4)); setBorder(BorderFactory.createCompoundBorder( BorderFactory.createRaisedBevelBorder(), BorderFactory.createEmptyBorder(8, 8, 8, 8))); JPanel provPanel = new JPanel(); provPanel.setLayout(new BorderLayout(8, 8)); provPanel.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createTitledBorder( BorderFactory.createEtchedBorder(), "Persistent Provisioning"), BorderFactory.createEmptyBorder(8, 8, 8, 8))); JLabel label = new JLabel("<html>Set whether the Cybernode supports "+ "persistent provisioning of qualitative "+ "capabilities</html>"); provPanel.add(label, BorderLayout.NORTH); JPanel subPanel = new JPanel(); subPanel.setLayout(new BoxLayout(subPanel, BoxLayout.X_AXIS)); supportsProvisioning = new JCheckBox("Supports persistent provisioning"); label.setLabelFor(supportsProvisioning); subPanel.add(supportsProvisioning); JButton apply = new JButton("Apply"); apply.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent ae) { try { cybernodeAdmin.setPersistentProvisioning(supportsProvisioning.isSelected()); } catch(Exception e) { showError(e); } } }); subPanel.add(Box.createHorizontalGlue()); subPanel.add(apply); provPanel.add(subPanel, BorderLayout.CENTER); add(provPanel, BorderLayout.NORTH); JPanel tablePanel = new JPanel(); tablePanel.setLayout(new BorderLayout(8, 8)); tablePanel.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createTitledBorder( BorderFactory.createEtchedBorder(), "Current Platform Capabilities"), BorderFactory.createEmptyBorder(8, 8, 8, 8))); capabilityTable = new JTable(); capabilityTable.addMouseListener(new RowListener()); dataModel = new PlatformCapabilityModel(); capabilityTable.setModel(dataModel); TableColumnModel cm = capabilityTable.getColumnModel(); cm.getColumn(0).setPreferredWidth(30); capabilityTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN); JScrollPane scroller = new JScrollPane(capabilityTable); tablePanel.add(scroller, BorderLayout.CENTER); JPanel buttons = new JPanel(); buttons.setLayout(new BoxLayout(buttons, BoxLayout.X_AXIS)); JButton details = new JButton("Details"); details.setToolTipText("Get details on the selected PlatformCapability"); details.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { int row = capabilityTable.getSelectedRow(); if(row==-1) return; showDetails(getPlatformCapability(row)); } }); buttons.add(details); tablePanel.add(buttons, BorderLayout.SOUTH); add(tablePanel, BorderLayout.CENTER); Thread thread = new Thread(new PlatformCapabilityInformationFetcher()); thread.start(); } private Component getComponent() { return this; } class PlatformCapabilityInformationFetcher implements Runnable { public void run() { try { getComponent().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); supportsProvisioning.setSelected(cybernodeAdmin.getPersistentProvisioning()); PlatformCapability[] pCaps = cybernodeAdmin.getResourceCapability().getPlatformCapabilities(); for (PlatformCapability pCap : pCaps) { addPlatformCapability(pCap); } getComponent().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); } catch(Exception e) { getComponent().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); showError(e); } } } void addPlatformCapability(PlatformCapability pCap) { dataModel.addOrReplace(pCap); dataModel.fireTableDataChanged(); } void removePlatformCapability(int row) { dataModel.removeItem(row); } void clearPlatformCapabilities() { dataModel.clear(); } PlatformCapability getPlatformCapability(int row) { if(row==-1) return(null); return((PlatformCapability)dataModel.getItem(row)); } class PlatformCapabilityModel extends AbstractTableModel { private final Vector<PlatformCapability> tableData = new Vector<PlatformCapability>(); final String[] columnNames = {"Name", "Description"}; public PlatformCapabilityModel() { super(); } public Object getValueAt(int index, int columnIndex) { try { PlatformCapability pCap = tableData.elementAt(index); if(columnIndex==0) { return (pCap.getValue(PlatformCapability.NAME)); } else if(columnIndex==1) { return(pCap.getDescription()); } else { return null; } } catch(Exception e) { e.printStackTrace(); } return(null); } void clear() { tableData.clear(); fireTableDataChanged(); } void addOrReplace(PlatformCapability item) { int ndx = tableData.indexOf(item); if(ndx!=-1) { setValueAt(item, ndx); } else { addItem(item); } } public void addItem(PlatformCapability item) { int rowNum = tableData.size(); tableData.insertElementAt(item, rowNum); fireTableRowsInserted(rowNum, rowNum); } public void removeItem(int row) { tableData.removeElementAt(row); fireTableDataChanged(); } public Object getItem(int row) { return(tableData.elementAt(row)); } public int getColumnCount() { return(columnNames.length); } public int getRowCount() { return(tableData.size()); } public String getColumnName(int column) { return(columnNames[column]); } public void setValueAt(PlatformCapability item, int rowNum) { tableData.setElementAt(item, rowNum); fireTableRowsUpdated(rowNum, rowNum); } } class RowListener extends MouseAdapter { public void mouseClicked(MouseEvent e) { int clickCount = e.getClickCount(); if(clickCount==2) { int row = capabilityTable.rowAtPoint(new Point(e.getX(), e.getY())); if(row==-1) return; showDetails(getPlatformCapability(row)); } } } private void showError(Exception e) { StringBuilder buffer = new StringBuilder(); StackTraceElement[] trace = e.getStackTrace(); for (StackTraceElement aTrace : trace) { buffer.append("at ").append(aTrace).append("<br>"); } showError("<html>Exception : <font color=red>"+ e.getClass().getName()+"</font><br>"+ buffer.toString()+"</html>"); } private void showError(String text) { JOptionPane.showMessageDialog(this, text, "System Error", JOptionPane.ERROR_MESSAGE); } private void showDetails(PlatformCapability pCap) { PlatformCapabilityDetails details = new PlatformCapabilityDetails(pCap, getComponent()); } /** * Shows the details of a PlatformCapability object */ class PlatformCapabilityDetails extends JDialog { private JPanel base; private PropertiesTable propsTable; PlatformCapabilityDetails(final PlatformCapability pCap, Component parent) { super((JFrame)null, "Platform PlatformCapabilityConfig Details", true); base = new JPanel(); base.setLayout(new BorderLayout(2, 4)); base.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createRaisedBevelBorder(), BorderFactory.createEmptyBorder(8, 8, 8, 8))); JPanel basics = new JPanel(); basics.setLayout(new GridLayout(3, 2, 4, 4)); basics.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createTitledBorder( BorderFactory.createEtchedBorder(), "General Information"), BorderFactory.createEmptyBorder(8, 8, 8, 8))); basics.add(new JLabel("Description")); basics.add(createTextField(pCap.getDescription())); basics.add(new JLabel("Class")); basics.add(createTextField(pCap.getClass().getSimpleName())); basics.add(new JLabel("Type")); basics.add(createTextField(pCap.getType()==PlatformCapability.STATIC? "STATIC":"PROVISIONABLE")); base.add(basics, BorderLayout.NORTH); JPanel capabilityPanel = new JPanel(); capabilityPanel.setLayout(new BorderLayout(4, 4)); capabilityPanel.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createTitledBorder( BorderFactory.createEtchedBorder(), "PlatformCapabilityConfig Support Mappings"), BorderFactory.createEmptyBorder(8, 8, 8, 8))); Properties props = new Properties(); String[] keys = pCap.getPlatformKeys(); for (String key : keys) { props.put(key, pCap.getValue(key)); } if(pCap.getPath()!=null) { props.put("Path", pCap.getPath()); } if(pCap instanceof ByteOrientedDevice) { formatByteOrientedDevice(pCap, props); } propsTable = new PropertiesTable(props); capabilityPanel.add(propsTable, BorderLayout.CENTER); base.add(capabilityPanel, BorderLayout.CENTER); JPanel buttonPanel = new JPanel(); buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS)); JButton dismiss = new JButton("Dismiss"); dismiss.setToolTipText("Dismiss the dialog"); dismiss.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { dispose(); } }); buttonPanel.add(dismiss); base.add(buttonPanel, BorderLayout.SOUTH); getContentPane().add(base); pack(); showDialog(parent); } private void formatByteOrientedDevice(PlatformCapability pCap, Properties props) { Double dVal = (Double)props.get("Available"); if(dVal!=null) props.put("Available", formatSizeValue(dVal)); dVal = (Double)props.get("Capacity"); if(dVal!=null) props.put("Capacity", formatSizeValue(dVal)); } /** * Create a JTextField * * @param text The text for the JTextField * * @return An un-editable JTextField */ private JTextField createTextField(String text) { JTextField tf = new JTextField(text); tf.setEditable(false); return(tf); } /** * Format a size value * * @param dVal The Double value to format * * @return A formatted String */ private String formatSizeValue(Double dVal) { String result = dVal.toString(); try { double value; String size; if(dVal>ByteOrientedDevice.MB) { if(dVal>ByteOrientedDevice.GB) { if(dVal>ByteOrientedDevice.TB) { value = dVal/ByteOrientedDevice.TB; size = "TB"; } else { value = dVal/ByteOrientedDevice.GB; size = "GB"; } } else { value = dVal/ByteOrientedDevice.MB; size = "MB"; } } else { value = dVal/ByteOrientedDevice.KB; size = "KB"; } result = new Double(value).intValue()+" "+size; } catch(Exception e) { System.err.println("Bad StorageCapability value ["+dVal+"]"); } return(result); } /** * Override show to determine size and placement */ private void showDialog(Component component) { int width = 400; int height = 370; pack(); setSize(width, height); setLocationRelativeTo(component); getContentPane().add(base); java.awt.event.WindowListener l = new WindowAdapter() { public void windowClosing(WindowEvent e) { dispose(); } }; addWindowListener(l); setVisible(true); } } /** * Add a Key and Value */ class KeyValueDialog extends JDialog { private JPanel base; private JTextField key; private JTextField value; /* * Create a KeyValueDialog instance */ KeyValueDialog(JDialog parent) { this(parent, "", ""); } /* * Create a KeyValueDialog instance */ KeyValueDialog(JDialog parent, String keyText, String valueText) { super(parent, "Platform PlatformCapabilityConfig Mapping", true); base = new JPanel(); base.setLayout(new BorderLayout(6, 6)); base.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createRaisedBevelBorder(), BorderFactory.createEmptyBorder(8, 8, 8, 8))); JPanel basics = new JPanel(); basics.setLayout(new GridLayout(4, 1, 8, 8)); JLabel keyLabel = new JLabel("<html>Enter a value for the key</html>"); key = new JTextField(); key.setText(keyText); keyLabel.setLabelFor(key); JLabel valueLabel = new JLabel("<html>Enter a value for the value"+ "</html>"); value = new JTextField(); value.setText(valueText); valueLabel.setLabelFor(value); JButton accept = new JButton("Accept"); accept.setToolTipText("Accept entries for key,value pair"); accept.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { if(key.getText().length()==0) { showError("You must provide a value for the key"); return; } if(value.getText().length()==0) { showError("You must provide a value for the value"); return; } dispose(); } }); JButton dismiss = new JButton("Dismiss"); dismiss.setToolTipText("Dismiss the dialog"); dismiss.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { dispose(); } }); JPanel buttonPanel = new JPanel(); buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS)); buttonPanel.add(accept); buttonPanel.add(Box.createHorizontalGlue()); buttonPanel.add(dismiss); basics.add(keyLabel); basics.add(key); basics.add(valueLabel); basics.add(value); basics.add(buttonPanel); base.add(basics, BorderLayout.CENTER); base.add(buttonPanel, BorderLayout.SOUTH); getContentPane().add(base); pack(); display(); } /** * Get the key * * @return The key */ public String getKey() { return(key.getText()); } /** * Get the value * * @return The value */ public String getValue() { return(value.getText()); } /** * Override show to determine size and placement */ private void display() { int width = 365; int height = 205; pack(); setSize(width, height); getContentPane().add(base); java.awt.event.WindowListener l = new WindowAdapter() { public void windowClosing(WindowEvent e) { dispose(); } }; addWindowListener(l); Rectangle rect = getParent().getBounds(); int widthLoc = ((int)rect.getWidth()/2)+getParent().getX() - width/2; setLocation(widthLoc, getParent().getY()+20); setVisible(true); } /** * Show a user input error * * @param text The text to display */ void showError(String text) { JOptionPane.showMessageDialog(this, text, "User Input Error", JOptionPane.ERROR_MESSAGE); } } }