All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jadex.base.gui.componentviewer.ComponentViewerPlugin Maven / Gradle / Ivy

There is a newer version: 4.0.267
Show newest version
package jadex.base.gui.componentviewer;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.lang.reflect.Constructor;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.UIDefaults;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.TreePath;

import jadex.base.gui.asynctree.INodeListener;
import jadex.base.gui.asynctree.ISwingNodeHandler;
import jadex.base.gui.asynctree.ISwingTreeNode;
import jadex.base.gui.asynctree.ITreeNode;
import jadex.base.gui.componenttree.ComponentTreePanel;
import jadex.base.gui.componenttree.IActiveComponentTreeNode;
import jadex.base.gui.componenttree.ProvidedServiceInfoNode;
import jadex.base.gui.plugin.AbstractJCCPlugin;
import jadex.bridge.IComponentIdentifier;
import jadex.bridge.IExternalAccess;
import jadex.bridge.service.IService;
import jadex.bridge.service.IServiceIdentifier;
import jadex.bridge.service.RequiredServiceInfo;
import jadex.bridge.service.search.SServiceProvider;
import jadex.bridge.service.types.cms.IComponentManagementService;
import jadex.bridge.service.types.library.ILibraryService;
import jadex.commons.Properties;
import jadex.commons.SReflect;
import jadex.commons.SUtil;
import jadex.commons.future.CounterResultListener;
import jadex.commons.future.Future;
import jadex.commons.future.IFuture;
import jadex.commons.gui.CombiIcon;
import jadex.commons.gui.ObjectCardLayout;
import jadex.commons.gui.SGUI;
import jadex.commons.gui.future.SwingDefaultResultListener;
import jadex.commons.gui.future.SwingDelegationResultListener;
import jadex.commons.gui.future.SwingExceptionDelegationResultListener;


/**
 *  The service viewer allows to introspect details of services.
 */
public class ComponentViewerPlugin extends AbstractJCCPlugin
{
	// -------- constants --------

	/**
	 * The image icons.
	 */
	protected static final UIDefaults	icons	= new UIDefaults(new Object[]{
		"componentviewer", SGUI.makeIcon(ComponentViewerPlugin.class, "/jadex/base/gui/images/configure.png"), 
		"componentviewer_sel", SGUI.makeIcon(ComponentViewerPlugin.class, "/jadex/base/gui/images/configure_sel.png"), 
		"open_viewer", SGUI.makeIcon(ComponentViewerPlugin.class, "/jadex/base/gui/images/new_introspector.png"),
		"close_viewer", SGUI.makeIcon(ComponentViewerPlugin.class, "/jadex/base/gui/images/close_introspector.png"),
		"viewer_empty", SGUI.makeIcon(ComponentViewerPlugin.class, "/jadex/base/gui/images/viewer_empty.png"),
		"overlay_viewable", SGUI.makeIcon(ComponentViewerPlugin.class, "/jadex/base/gui/images/overlay_edit.png"),
		"overlay_viewed", SGUI.makeIcon(ComponentViewerPlugin.class, "/jadex/base/gui/images/overlay_introspected.png"),
		"overlay_notviewed", SGUI.makeIcon(ComponentViewerPlugin.class, "/jadex/base/gui/images/overlay_notintrospected.png")
	});
	
	//-------- attributes --------

	/** The split panel. */
	protected JSplitPane	split;

	/** The agent tree table. */
	protected ComponentTreePanel	comptree;

	/** The detail panel. */
	protected JPanel	detail;

	/** The detail layout. */
	protected ObjectCardLayout	cards;
	
	/** The service viewer panels. */
	protected Map	panels;
	
	/** Loaded properties. */
	protected Properties	props;
	
	/** The active component node viewable state. */
	protected Map> viewables;
	
	//-------- constructors --------
	
	/**
	 *  Create a new plugin.
	 */
	public ComponentViewerPlugin()
	{
		this.panels	= new HashMap();
		this.viewables = Collections.synchronizedMap(new HashMap>());
	}
	
	//-------- IControlCenterPlugin interface --------
	
	/**
	 *  @return The plugin name 
	 *  @see jadex.tools.common.plugin.IControlCenterPlugin#getName()
	 */
	public String getName()
	{
		return "Component Viewer";
	}

	/**
	 *  @return The icon of plugin
	 *  @see jadex.tools.common.plugin.IControlCenterPlugin#getToolIcon()
	 */
	public Icon getToolIcon(boolean selected)
	{
		return selected? icons.getIcon("componentviewer_sel"): icons.getIcon("componentviewer");
	}

	/**
	 *  Create tool bar.
	 *  @return The tool bar.
	 */
	public JComponent[] createToolBar()
	{
		JButton b1 = new JButton(START_VIEWER);
		b1.setBorder(null);
		b1.setToolTipText(b1.getText());
		b1.setText(null);
		b1.setEnabled(true);

		JButton b2 = new JButton(STOP_VIEWER);
		b2.setBorder(null);
		b2.setToolTipText(b2.getText());
		b2.setText(null);
		b2.setEnabled(true);
		
		return new JComponent[]{b1, b2};
	}
		
	/**
	 *  Create main panel.
	 *  @return The main panel.
	 */
	public JComponent createView()
	{
		this.split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true);
		split.setOneTouchExpandable(true);

		comptree = new ComponentTreePanel(getJCC().getPlatformAccess(), getJCC().getJCCAccess(), getJCC().getCMSHandler(),  getJCC().getPropertyHandler(), getJCC().getIconCache());
		comptree.setMinimumSize(new Dimension(0, 0));
		split.add(comptree);

		comptree.getTree().getSelectionModel().addTreeSelectionListener(new TreeSelectionListener()
		{
			public void valueChanged(TreeSelectionEvent e)
			{
				JTree tree = comptree.getTree();
				if(tree.getSelectionPath()!=null)
				{
					ISwingTreeNode node = (ISwingTreeNode)tree.getSelectionPath().getLastPathComponent();
					Object nodeid = node.getId();
					if(nodeid!=null)
					{
						if(cards.getComponent(nodeid)!=null)
						{
							storeCurrentPanelSettings();
							IAbstractViewerPanel panel = panels.get(nodeid);
							panel.setProperties(props!=null ? props.getSubproperty(panel.getId()) : null);
							cards.show(nodeid);
						}
					}
				}
			}
		});
		
		comptree.addNodeHandler(new ShowRemoteControlCenterHandler(getJCC(), getView()));
		
		comptree.addNodeHandler(new ISwingNodeHandler()
		{
			public Action[] getPopupActions(ISwingTreeNode[] nodes)
			{
				Action[]	ret	= null;
				
				boolean	allviewable	= true;
				for(int i=0; allviewable && i fut = SServiceProvider.getService(getJCC().getJCCAccess(), node.getServiceIdentifier());
						fut.addResultListener(new SwingDefaultResultListener(comptree)
						{
							public void customResultAvailable(final IService service)
							{
								SServiceProvider.getService(getJCC().getJCCAccess(), ILibraryService.class, RequiredServiceInfo.SCOPE_PLATFORM)
//								AbstractJCCPlugin.getClassLoader(((IActiveComponentTreeNode)node.getParent().getParent()).getComponentIdentifier(), getJCC())
									.addResultListener(new SwingDefaultResultListener(comptree)
								{
									public void customResultAvailable(ILibraryService ls)
									{
										ls.getClassLoader(null).addResultListener(new SwingDefaultResultListener(comptree)
										{
											public void customResultAvailable(ClassLoader cl)
											{
												Object clid = service.getPropertyMap()!=null? service.getPropertyMap().get(IAbstractViewerPanel.PROPERTY_VIEWERCLASS) : null;
												
												if(clid instanceof String[]) 
												{
													// use first gui class found
													for(String classname : (String[])clid) 
													{
														Class clazz = SReflect.classForName0(classname, cl);
														if(clazz != null)
														{
															clid = clazz;
															break;
														}
													}
												}
												
												final Class clazz = clid instanceof Class? (Class)clid: clid instanceof String? SReflect.classForName0((String)clid, cl): null;
												
												if(clid!=null)
												{
													try
													{
														storeCurrentPanelSettings();
														final IServiceViewerPanel	panel = (IServiceViewerPanel)clazz.newInstance();
														panel.init(getJCC(), service).addResultListener(new SwingDefaultResultListener(comptree)
														{
															public void customResultAvailable(Void result)
															{
																Properties	sub	= props!=null ? props.getSubproperty(panel.getId()) : null;
																if(sub!=null)
																	panel.setProperties(sub);
																JComponent comp = panel.getComponent();
																
																// todo: help 
																//SHelp.setupHelp(comp, getHelpID());
																panels.put(node.getServiceIdentifier(), panel);
																detail.add(comp, node.getServiceIdentifier());
																comptree.getModel().fireNodeChanged(node);
															}
														});
													}
													catch(Exception e)
													{
														e.printStackTrace();
														getJCC().displayError("Error initializing service viewer panel.", "Component viewer panel class: "+SUtil.arrayToString(clid), e);
													}
												}
												
											}
										});
									}
								});
							}
						});
					}
					else if(tmp instanceof IActiveComponentTreeNode)
					{
						final IActiveComponentTreeNode node = (IActiveComponentTreeNode)tmp;
						final IComponentIdentifier cid = node.getComponentIdentifier();
						
						IFuture fut = SServiceProvider.getService(getJCC().getJCCAccess(), IComponentManagementService.class, RequiredServiceInfo.SCOPE_PLATFORM);
						fut.addResultListener(new SwingDefaultResultListener(comptree)
						{
							public void customResultAvailable(IComponentManagementService cms)
							{
								cms.getExternalAccess(cid).addResultListener(new SwingDefaultResultListener(comptree)
								{
									public void customResultAvailable(final IExternalAccess exta)
									{
										SServiceProvider.getService(getJCC().getJCCAccess(), ILibraryService.class, RequiredServiceInfo.SCOPE_PLATFORM)
//										AbstractJCCPlugin.getClassLoader(cid, getJCC())
											.addResultListener(new SwingDefaultResultListener(comptree)
										{
											public void customResultAvailable(ILibraryService ls)
											{
												ls.getClassLoader(null).addResultListener(new SwingDefaultResultListener(comptree)
												{
													public void customResultAvailable(ClassLoader cl)
													{
														Object clid = exta.getModel().getProperty(IAbstractViewerPanel.PROPERTY_VIEWERCLASS, cl);
														
														if(clid instanceof String[]) 
														{
															// use first gui class found
															for(String classname : (String[])clid) 
															{
																Class clazz = SReflect.classForName0(classname, cl);
																if(clazz != null)
																{
																	clid = clazz;
																	break;
																}
															}
														}
														
														if(clid instanceof String)
														{
															Class clazz	= SReflect.classForName0((String)clid, cl);
															createPanel(clazz, exta, node);
														}
														else if(clid instanceof Class)
														{
															createPanel((Class)clid, exta, node);
														}
													}
												});
											}
										});
									}
								});
							}
						});
					}
				}
			}
		}
	};
	
	/**
	 * 
	 */
	protected void createPanel(Class clazz, final IExternalAccess exta, final IActiveComponentTreeNode node)
	{
		try
		{
			storeCurrentPanelSettings();
//			final IComponentViewerPanel panel = (IComponentViewerPanel)clazz.newInstance();
//			System.out.println(SUtil.arrayToString(clazz.getConstructors()));
			Constructor con = clazz.getDeclaredConstructor(new Class[0]);
			con.setAccessible(true);
			final IComponentViewerPanel panel = (IComponentViewerPanel)con.newInstance(new Object[0]);
			panel.init(getJCC(), exta).addResultListener(new SwingDefaultResultListener(comptree)
			{
				public void customResultAvailable(Void result)
				{
					Properties	sub	= props!=null ? props.getSubproperty(panel.getId()) : null;
					if(sub!=null)
						panel.setProperties(sub);
					JComponent comp = panel.getComponent();
					// todo: help
					//SHelp.setupHelp(comp, getHelpID());
					panels.put(exta.getComponentIdentifier(), panel);
					detail.add(comp, exta.getComponentIdentifier());
					comptree.getModel().fireNodeChanged(node);
				}
			});
		}
		catch(Exception e)
		{
			e.printStackTrace();
			getJCC().displayError("Error initializing component viewer panel.", "Component viewer panel class: "+clazz, e);
		}
	}

	final AbstractAction STOP_VIEWER = new AbstractAction("Close service viewer", icons.getIcon("close_viewer"))
	{
		public void actionPerformed(ActionEvent e)
		{
			TreePath[]	paths	= comptree.getTree().getSelectionPaths();
			for(int i=0; paths!=null && i(comptree)
					{
						public void customResultAvailable(Void result)
						{
							comptree.getModel().fireNodeChanged(node);
						}
					});
				}
			}
		}
	};

	/**
	 *  Test if a node is viewable.
	 *  @param node	The node.
	 *  @return True, if the node is viewable.
	 */
	protected boolean isNodeViewable(final ISwingTreeNode node)
	{
		assert SwingUtilities.isEventDispatchThread();
		
//		if(node.getId().toString().indexOf("SecurityService")!=-1)
//			System.out.println("called isVis: "+node.getId());
		boolean ret = false;
		if(node instanceof ProvidedServiceInfoNode)
		{
			final IServiceIdentifier sid = ((ProvidedServiceInfoNode)node).getServiceIdentifier();
			if(sid!=null)
			{
				IFuture viewable = viewables.get(sid);
				if(viewable!=null)
				{
					if(viewable.isDone() && viewable.getException()==null)
					{
						ret = viewable.get().booleanValue();
//						System.out.println("isVis result: "+node.getId()+" "+ret+" "+sid);
					}
				}
				else
				{
					final Future	fut	= new Future();
					viewables.put(sid, fut);
//					final long start	= System.currentTimeMillis();
					// Unknown -> start search to find out asynchronously
					SServiceProvider.getService(getJCC().getJCCAccess(), sid)
						.addResultListener(new SwingExceptionDelegationResultListener(fut)
					{
						public void customResultAvailable(Object result)
						{
							IService service = (IService)result;
							Map	props = service.getPropertyMap();
							boolean vis = props!=null && props.get(IAbstractViewerPanel.PROPERTY_VIEWERCLASS)!=null;
							fut.setResult(vis? Boolean.TRUE: Boolean.FALSE);
							node.refresh(false);
						}
					});
				}
			}
//			Map	props	= ((ProvidedServiceInfoNode)node).getServiceIdentifier().get.getPropertyMap();
//			ret = props!=null && props.get(IAbstractViewerPanel.PROPERTY_VIEWERCLASS)!=null;
		}
		else if(node instanceof IActiveComponentTreeNode)
		{
			final IComponentIdentifier cid = ((IActiveComponentTreeNode)node).getComponentIdentifier();
			
			// For proxy components the cid could be null if the remote cid has not yet been retrieved
			// Using a IFuture as return value in not very helpful because this method can't directly
			// return a result, even if known.
			// todo: how to initiate a repaint in case the the cid is null
			if(cid!=null)
			{
				IFuture viewable = viewables.get(cid);
				if(viewable!=null)
				{
					if(viewable.isDone() && viewable.getException()==null)
					{
						ret = viewable.get().booleanValue();
//						System.out.println("isVis result: "+node.getId()+" "+ret);
					}
				}
				else
				{
					final Future	fut	= new Future();
					viewables.put(cid, fut);
					// Unknown -> start search to find out asynchronously
					SServiceProvider.getService(getJCC().getJCCAccess(), IComponentManagementService.class, RequiredServiceInfo.SCOPE_PLATFORM)
						.addResultListener(new SwingExceptionDelegationResultListener(fut)
					{
						public void customResultAvailable(final IComponentManagementService cms)
						{
							cms.getExternalAccess(cid).addResultListener(new SwingExceptionDelegationResultListener(fut)
							{
								public void customResultAvailable(final IExternalAccess exta)
								{
									getJCC().getClassLoader(exta.getModel().getResourceIdentifier())
										.addResultListener(new SwingExceptionDelegationResultListener(fut)
									{
										public void customResultAvailable(ClassLoader cl)
										{
											final Object clid = exta.getModel().getProperty(IAbstractViewerPanel.PROPERTY_VIEWERCLASS, cl);
											fut.setResult(clid==null? Boolean.FALSE: Boolean.TRUE);
//											System.out.println("isVis first res: "+viewables.get(cid));
											node.refresh(false);
										}
									});
								}
							});
						}
					});
				}
			}
		}
		return ret;
	}
	
	/** 
	 *  Shutdown the plugin.
	 */
	public IFuture shutdown()
	{
		final Future ret = new Future();
		comptree.dispose();
		CounterResultListener lis = new CounterResultListener(panels.size(), 
			true, new SwingDelegationResultListener(ret));
		for(Iterator it=panels.values().iterator(); it.hasNext(); )
		{
			it.next().shutdown().addResultListener(lis);
		}
		return ret;
	}

	//-------- loading / saving --------
	
	/**
	 *  Return properties to be saved in project.
	 */
	public IFuture getProperties()
	{
		storeCurrentPanelSettings();
		
		return new Future(props);
	}
	
	/**
	 *  Set properties loaded from project.
	 */
	public IFuture setProperties(Properties ps)
	{
		Future ret = new Future();
		this.props	=	ps;
		
		IAbstractViewerPanel[] pans = (IAbstractViewerPanel[])panels.values().toArray(new IAbstractViewerPanel[0]);
		CounterResultListener lis = new CounterResultListener(pans.length, true, new SwingDelegationResultListener(ret));
		
		for(int i=0; i storeCurrentPanelSettings()
	{
		final Future ret = new Future();
		
		Object	old	= cards.getCurrentKey();
		if(old!=null)
		{
			final IAbstractViewerPanel panel = (IAbstractViewerPanel)panels.get(old);
			if(panel!=null)
			{
				if(props==null)
					props	= new Properties();
				panel.getProperties().addResultListener(new SwingDelegationResultListener(ret)
				{
					public void customResultAvailable(Properties sub) 
					{
//						Properties sub = (Properties)result;
						props.removeSubproperties(panel.getId());
						if(sub!=null)
						{
							sub.setType(panel.getId());
							props.addSubproperties(sub);
						}
						ret.setResult(props);
					};
				});
			}
		}
		
		return ret;
	}
	
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy