/* * Copyright 2008 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.tools.ui.serviceui; import net.jini.admin.Administrable; import net.jini.core.entry.Entry; import net.jini.core.lookup.ServiceItem; import net.jini.lookup.entry.ServiceInfo; import net.jini.lookup.entry.ServiceType; import net.jini.lookup.ui.factory.JComponentFactory; import net.jini.lookup.ui.factory.JDialogFactory; import net.jini.lookup.ui.factory.JFrameFactory; import net.jini.lookup.ui.factory.JWindowFactory; import org.rioproject.entry.ComputeResourceInfo; import org.rioproject.serviceui.UILoader; import org.rioproject.ui.Util; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import java.util.ArrayList; import java.util.Date; import java.util.TimerTask; /** * The ServiceUIPanel class aggregates service ui objects that have been * added as attributes to a service's attribute set using a JTabbedPane. * The ServiceUIPanel looks for all UI entries that have a role of Admin set. * * <p> The ServiceUIPanel class additionally has some built in panels that it * displays via tabs that provide: * <br> * <ul> * <li>ServiceType details * <li>ServiceInfo details * <li>Join details * </ul> * * @author Dennis Reedy */ public class ServiceUIPanel extends JPanel { /** Various push buttons */ JButton dismissB, terminateB; /** The ServiceItem for the service */ ServiceItem item=null; /** A tabbed pane to display JComponents */ JTabbedPane tabpane; /** Optional image to display */ Image image=null; /** base JPanel to layout components onto */ JPanel base; Object[] uiComponents; /* List of loaded JComponent instances */ java.util.List<JComponent> jComponentList = new ArrayList<JComponent>(); Container parent; public ServiceUIPanel(ServiceItem item, long startupDelay, Container parent) throws Exception { super(new BorderLayout()); this.item = item; this.parent = parent; Entry[] attrs = item.attributeSets; base = new JPanel(); base.setLayout(new BorderLayout(8, 8)); tabpane = new JTabbedPane(); String svcName; ServiceType type = getServiceType(attrs); if(type!=null) { svcName = type.getDisplayName(); } else { svcName = item.service.getClass().getName(); } ComputeResourceInfo computeResourceInfo = getComputeResourceInfo(attrs); java.util.Timer taskTimer = new java.util.Timer(true); long now = System.currentTimeMillis(); UIComponentFetcher uiFetcher = new UIComponentFetcher(); WaitingToLoadTask waitingToLoadTask; if(computeResourceInfo!=null) waitingToLoadTask = new WaitingToLoadTask(svcName, computeResourceInfo.hostName, computeResourceInfo.hostAddress); else waitingToLoadTask = new WaitingToLoadTask(svcName, "unknown", "unknown"); TimeoutTask timeoutTask = new TimeoutTask(uiFetcher); taskTimer.schedule(waitingToLoadTask, new Date(now+Math.min(1000*5, startupDelay))); taskTimer.schedule(timeoutTask, new Date(now+startupDelay)); uiFetcher.start(); try { uiFetcher.join(startupDelay); } catch(InterruptedException e) { throw new Exception("Unable to obtain Service UI attributes for "+ svcName+" in allotted time of "+ (startupDelay/1000)+" seconds"); } waitingToLoadTask.cancel(); if(waitingToLoadTask.dialog!=null) waitingToLoadTask.dialog.dispose(); if(uiFetcher.isInterrupted()) throw new Exception("Unable to obtain Service UI attributes for "+ svcName+" in allotted time of "+ (startupDelay/1000)+" seconds"); timeoutTask.cancel(); if(uiFetcher.exception!=null) throw uiFetcher.exception; ServiceInfo info = getServiceInfo(attrs); if(type!=null || info!=null) { JPanel svcTypePanel = new JPanel(); svcTypePanel.setLayout(new BoxLayout(svcTypePanel, BoxLayout.Y_AXIS)); ServiceTypePanel typePanel = new ServiceTypePanel(); typePanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, 200)); if(type!=null) { image = type.getIcon(0); typePanel.setServiceType(type); } svcTypePanel.add(Box.createVerticalStrut(8)); svcTypePanel.add(typePanel); ServiceInfoPanel sInfoPanel = new ServiceInfoPanel(); sInfoPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, 300)); svcTypePanel.add(Box.createVerticalStrut(8)); svcTypePanel.add(sInfoPanel); if(info!=null) sInfoPanel.setServiceInfo(info); svcTypePanel.add(Box.createVerticalGlue()); tabpane.add("Service Information", svcTypePanel); } if(computeResourceInfo!=null) { ComputeResourceInfoPanel computeResourceInfoPanel = new ComputeResourceInfoPanel(); computeResourceInfoPanel.setComputeResourceInfo(computeResourceInfo); tabpane.add("Host Attributes", computeResourceInfoPanel); } JPanel buttonPanel = new JPanel(); //buttonPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, 50)); buttonPanel.setLayout(new FlowLayout(FlowLayout.CENTER)); if(!(parent instanceof JInternalFrame)) { dismissB = new JButton("Close"); dismissB.setToolTipText("Close the dialog"); dismissB.addActionListener(new DismissHandler()); buttonPanel.add(dismissB); if(item.service instanceof Administrable) { terminateB = new JButton("Terminate"); terminateB.setToolTipText("Terminate (destroy) the service"); terminateB.addActionListener(new ServiceTerminator(item, parent)); buttonPanel.add(terminateB); } } base.add(tabpane,BorderLayout.CENTER); base.add(buttonPanel, BorderLayout.SOUTH); add("Center", base); add("South", buttonPanel); } public Object[] getUIComponents() { if(uiComponents==null) return(new Object[0]); Object[] comps = new Object[uiComponents.length]; System.arraycopy(uiComponents, 0, comps, 0, uiComponents.length); return(comps); } public class DismissHandler implements ActionListener { public void actionPerformed(ActionEvent e) { Util.dispose(parent); } } private JComponent getComponent(Object factory, Object item) throws Exception { JComponent uiComponent = null; Class factoryClass = factory.getClass(); if(JFrameFactory.class.isAssignableFrom(factoryClass)) uiComponent = new LaunchPanel(factory, item); else if(JWindowFactory.class.isAssignableFrom(factoryClass)) uiComponent = new LaunchPanel(factory, item); else if(JComponentFactory.class.isAssignableFrom(factoryClass)) { JComponentFactory fac = (JComponentFactory)factory; uiComponent = fac.getJComponent(item); String name = uiComponent.getAccessibleContext().getAccessibleName(); if(name==null) uiComponent.getAccessibleContext().setAccessibleName( uiComponent.getClass().getName()); } else if(JDialogFactory.class.isAssignableFrom(factoryClass)) uiComponent = new LaunchPanel(factory, item); return(uiComponent); } class UIComponentFetcher extends Thread { Exception exception; public void run() { try { uiComponents = UILoader.loadUI(item); if(uiComponents!=null) { String name; for(int i=uiComponents.length-1; i>=0; i--) { if(isInterrupted()) break; JComponent jComp = getComponent(uiComponents[i], item); if(jComp instanceof JPanel) { name = jComp.getAccessibleContext().getAccessibleName(); tabpane.add(name, jComp); jComponentList.add(jComp); } else { System.err.println("Unsupported UI class"); } } } } catch(Exception e) { exception = e; } } } class TimeoutTask extends TimerTask { Thread thread; TimeoutTask(Thread thread) { super(); this.thread = thread; } /** * The action to be performed by this timer task. */ public void run() { thread.interrupt(); System.out.println("Cancelled Admin Viewer startup"); } } class WaitingToLoadTask extends TimerTask { String svcName; String hostName; String hostAddress; JDialog dialog; WaitingToLoadTask(String svcName, String hostName, String hostAddress) { super(); this.svcName = svcName; this.hostName = hostName; this.hostAddress = hostAddress; } /** * The action to be performed by this timer task. */ public void run() { JOptionPane pane = new JOptionPane("<html>"+ "<font color=black>"+ "Waiting to load UI Components for "+ "the </font><br>"+ "<font color=blue>"+svcName+"</font>"+ "<font color=black> service running "+ "on<br>"+ "machine: <font color=blue>"+ hostName+ "</font><font color=black> address: "+ "</font><font color=blue>"+ hostAddress+"</font><br>"+ "<font color=black>"+ "The timeframe is longer then "+ "expected,<br>"+ "verify network connections."+ "</font></html>", JOptionPane.WARNING_MESSAGE); dialog = pane.createDialog(null, "Network Delay"); dialog.setModal(false); dialog.setVisible(true); } } class LaunchPanel extends JPanel { Object uiObj; LaunchPanel(final Object factory, final Object item) { super(); String info=factory.getClass().getName(); getAccessibleContext().setAccessibleName(info); JButton button = new JButton("Launch "+info); button.addActionListener( new ActionListener() { final Class factoryClass = factory.getClass(); public void actionPerformed(ActionEvent ae) { try { if(JFrameFactory.class.isAssignableFrom(factoryClass)) launchFrameUI(factory, item); else if(JWindowFactory.class.isAssignableFrom(factoryClass)) launchWindowUI(factory, item); else if(JDialogFactory.class.isAssignableFrom(factoryClass)) launchDialogUI(factory, item); } catch(Exception e) { e.printStackTrace(); Util.showError("Exception loading "+ "["+factoryClass.getName()+"]\n"+ e.getMessage(), null, "Could not launch " + "["+factoryClass.getName()+"]"); } } }); add(button); } private void launchFrameUI(Object factory, Object item) throws IOException, ClassNotFoundException { JFrameFactory fac = (JFrameFactory)factory; JFrame frame = fac.getJFrame(item); frame.validate(); frame.setSize(frame.getSize()); frame.setLocation(frame.getLocation()); frame.pack(); frame.setVisible(true); uiObj = frame; } private void launchWindowUI(Object factory, Object item) throws IOException, ClassNotFoundException { JWindowFactory fac = (JWindowFactory)factory; JWindow win = fac.getJWindow(item); win.validate(); win.pack(); win.setVisible(true); uiObj = win; } private void launchDialogUI(Object factory, Object item) throws IOException, ClassNotFoundException { JDialogFactory fac = (JDialogFactory)factory; JDialog d = fac.getJDialog(item); d.validate(); d.pack(); d.setVisible(true); uiObj = d; } } private ComputeResourceInfo getComputeResourceInfo(Entry[] attrs) { for (Entry attr : attrs) { if (attr instanceof ComputeResourceInfo) { return (ComputeResourceInfo) attr; } } return(null); } private ServiceInfo getServiceInfo(Entry[] attrs) { for (Entry attr : attrs) { if (attr instanceof ServiceInfo) { return (ServiceInfo) attr; } } return(null); } private ServiceType getServiceType(Entry[] attrs) { for (Entry attr : attrs) { if (attr instanceof ServiceType) { return (ServiceType) attr; } } return(null); } }