/* * 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 net.jini.io.UnsupportedConstraintException; import org.rioproject.deploy.ServiceRecord; import org.rioproject.cybernode.Cybernode; import org.rioproject.cybernode.CybernodeAdmin; import org.rioproject.system.ComputeResourceUtilization; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.rmi.RemoteException; /** * A ServiceUI for the Cybernode * * @author Dennis Reedy */ @SuppressWarnings("unused") public class CybernodeUI extends JPanel implements Runnable { private ServiceTable serviceTable; private ServiceTable execServiceTable; private JTextField maxSvcCount, currentSvcCount, utilizationTF; private Cybernode cybernode; private CybernodeAdmin cybernodeAdmin; private JButton apply; private Integer svcCount, maxCount; private boolean keepAlive=true; private transient Thread thread; public CybernodeUI(final Object arg) { super(); getAccessibleContext().setAccessibleName("Cybernode admin"); ServiceItem item = (ServiceItem) arg; cybernode = (Cybernode) item.service; ComputeResourceUtilization computeResource; try { cybernodeAdmin = (CybernodeAdmin)cybernode.getAdmin(); computeResource = getComputeResourceUtilization(cybernodeAdmin); } catch (Exception e) { e.printStackTrace(); return; } //idTable = new Hashtable(); JPanel qPanel = new JPanel(); qPanel.setLayout(new BoxLayout(qPanel, BoxLayout.X_AXIS)); qPanel.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Compute Resource"), BorderFactory.createEmptyBorder(6, 6, 6, 6))); qPanel.add(new JLabel("Description")); qPanel.add(Box.createHorizontalStrut(8)); String field="unknown: system error"; if(computeResource!=null) field = computeResource.getDescription(); JTextField descTF = new JTextField(field); descTF.setEnabled(false); qPanel.add(descTF); qPanel.add(Box.createHorizontalStrut(8)); qPanel.add(new JLabel("Utilization")); qPanel.add(Box.createHorizontalStrut(8)); if(computeResource!=null) field = computeResource.getUtilization().toString(); utilizationTF = new JTextField(field); utilizationTF.setEnabled(false); qPanel.add(utilizationTF); JPanel cPanel = new JPanel(); cPanel.setLayout(new GridLayout(0, 3, 4, 4)); cPanel.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Cybernode Attributes"), BorderFactory.createEmptyBorder(6, 6, 6, 6))); maxSvcCount = new JTextField(); currentSvcCount = new JTextField(); currentSvcCount.setEnabled(false); apply = new JButton("Apply"); apply.addActionListener(new ApplyHandler()); maxCount = 0; svcCount = 0; try { maxCount = cybernodeAdmin.getServiceLimit(); maxSvcCount.setText(maxCount.toString()); svcCount = cybernodeAdmin.getServiceCount(); currentSvcCount.setText(svcCount.toString()); } catch(RemoteException re) { re.printStackTrace(); } cPanel.add(new JLabel("Services Created")); cPanel.add(currentSvcCount); cPanel.add(new JLabel("")); cPanel.add(new JLabel("Service Limit")); cPanel.add(maxSvcCount); cPanel.add(apply); JPanel cq = new JPanel(); cq.setLayout(new BorderLayout()); cq.add(BorderLayout.NORTH, qPanel); cq.add(BorderLayout.CENTER, cPanel); serviceTable = new ServiceTable("Contained Services", false); execServiceTable = new ServiceTable("Forked/Exec'd Services", true); setLayout(new BorderLayout(8, 8)); setBorder(BorderFactory.createEmptyBorder(8,8,8,8)); /* JPanel tablePanel = new JPanel(); tablePanel.setLayout(new BoxLayout(tablePanel, BoxLayout.Y_AXIS)); tablePanel.add(serviceTable); tablePanel.add(Box.createHorizontalStrut(8)); tablePanel.add(execServiceTable); */ JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT); splitPane.setContinuousLayout(true); splitPane.setTopComponent(serviceTable); splitPane.setBottomComponent(execServiceTable); splitPane.setDividerLocation(150); add(BorderLayout.NORTH, cq); //add(BorderLayout.CENTER, tablePanel); add(BorderLayout.CENTER, splitPane); thread = new Thread(this); thread.start(); } /** * Override to ensure the thread that is created is interrupted */ public void removeNotify() { terminate(); } public void run() { if(cybernode==null) { showError("Reference to Cybernode is null"); return; } while(!thread.isInterrupted() && keepAlive) { try { setUIFields(); try { Thread.sleep(1000*60); } catch(InterruptedException e) { if(!keepAlive) break; } } catch(Exception e) { if(!keepAlive) break; e.printStackTrace(); showError("Cybernode Connectivity Error",e); if(apply!=null) apply.setEnabled(false); break; } } } void setUIFields() throws RemoteException { serviceTable.clear(); execServiceTable.clear(); ServiceRecord[] records = cybernode.getServiceRecords(ServiceRecord.ACTIVE_SERVICE_RECORD); for (ServiceRecord record : records) { if(record.getServiceElement().forkService() || record.getServiceElement().getExecDescriptor()!=null) { execServiceTable.addService(record); } else { serviceTable.addService(record); } } currentSvcCount.setText(getCybernodeCount().toString()); Double utilization = cybernodeAdmin.getResourceCapability().getUtilization(); utilizationTF.setText(utilization.toString()); } public void terminate() { keepAlive=false; if(thread!=null) { thread.interrupt(); thread = null; } if(apply!=null) apply.setEnabled(false); } protected void showInformation(String text) { JOptionPane.showMessageDialog(this, text, "Information Message", JOptionPane.INFORMATION_MESSAGE); } protected void showError(String text) { Toolkit.getDefaultToolkit().beep(); JOptionPane.showMessageDialog(this, text, "System Error", JOptionPane.ERROR_MESSAGE); } protected void showError(String title, Throwable t) { Toolkit.getDefaultToolkit().beep(); showError(t, this, title); } JTextField createAttrTextField() { JTextField tf = new JTextField(); tf.setEnabled(false); return(tf); } Integer getCybernodeCount() { try { svcCount = cybernodeAdmin.getServiceCount(); } catch(RemoteException re) { re.printStackTrace(); } return(svcCount); } private ComputeResourceUtilization getComputeResourceUtilization(CybernodeAdmin cAdmin) throws RemoteException { return(cAdmin.getComputeResourceUtilization()); } class ApplyHandler implements ActionListener { public void actionPerformed(ActionEvent ae) { try { Integer newCount; Integer count = cybernodeAdmin.getServiceLimit(); String s = maxSvcCount.getText(); try { newCount = Integer.valueOf(s); } catch(Exception e) { showError("You must enter a valid number"); return; } if(count.equals(newCount)) return; String message = "Set service limit to ["+s+"] ?"; String title = "Cybernode Service Configuration Change Confirmation"; int answer = JOptionPane.showConfirmDialog( null, message, title, JOptionPane.YES_NO_OPTION); if(answer==JOptionPane.NO_OPTION) return; cybernodeAdmin.setServiceLimit(newCount); maxCount = cybernodeAdmin.getServiceLimit(); } catch(RemoteException e) { e.printStackTrace(); showError("Cybernode Connectivity Error", e); } } } /** * Show an exception in a Dialog * * @param e The exception * @param comp The parent component * @param title The title to use */ public static void showError(Throwable e, Component comp, String title) { if (e.getCause() != null && e.getCause() instanceof UnsupportedConstraintException) { Throwable cause = e.getCause(); JOptionPane.showMessageDialog(null, "<html>" + "Exception: <font color=red>" + cause.getClass().getName() + "</font><br><br> " + "You do not have permission to perform " + "the action</html>", "Action Denied", JOptionPane.ERROR_MESSAGE); return; } StringBuilder buffer = new StringBuilder(); Throwable thrown = e; if (thrown.getCause() != null) thrown = thrown.getCause(); StackTraceElement[] trace = e.getStackTrace(); for (StackTraceElement aTrace : trace) { buffer.append("at ").append(aTrace).append("<br>"); } showError("<html>Exception : <font color=red>" + thrown.getClass().getName() + "</font>" + " : " + "<font color=blue>" + thrown.getLocalizedMessage() + "</font>" + "<br>" + buffer.toString() + "</html>", comp, title); } /** * Show an error in a Dialog * * @param text The text to show * @param comp The parent component * @param title The title to use */ public static void showError(String text, Component comp, String title) { JDialog dialog; if (comp instanceof Dialog) { dialog = new JDialog((Dialog) comp); } else if (comp instanceof Frame) { dialog = new JDialog((Frame) comp); } else { dialog = new JDialog(); } JEditorPane errorPane = new JEditorPane(); errorPane.setEditable(false); errorPane.setContentType("text/html"); errorPane.setText(text); errorPane.setCaretPosition(0); errorPane.moveCaretPosition(0); JPanel pane = new JPanel(); pane.setLayout(new BorderLayout(8, 8)); pane.add(new JScrollPane(errorPane), BorderLayout.CENTER); JButton dismiss = new JButton("Close"); dismiss.addActionListener(new DisposeActionListener(dialog)); JPanel buttonPane = new JPanel(); buttonPane.add(dismiss); pane.add(buttonPane, BorderLayout.SOUTH); dialog.getContentPane().add(pane); int width = 650; int height = 300; dialog.pack(); dialog.setSize(width, height); if(comp==null) { Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); int widthLoc = screenSize.width / 2 - width / 2; int heightLoc = screenSize.height / 2 - height / 2; dialog.setLocation(widthLoc, heightLoc); } else { dialog.setLocationRelativeTo(comp); } dialog.setTitle(title); dialog.setVisible(true); } public static class DisposeActionListener implements ActionListener { JDialog dialog; public DisposeActionListener(JDialog dialog) { this.dialog = dialog; } public void actionPerformed(ActionEvent ae) { dialog.dispose(); } } }