package rocks.inspectit.ui.rcp.view.impl; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import org.apache.commons.collections.CollectionUtils; import org.eclipse.core.commands.Command; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.expressions.IEvaluationContext; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.IJobChangeEvent; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.runtime.jobs.JobChangeAdapter; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.viewers.ColumnViewerToolTipSupport; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.StyledString; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerComparator; import org.eclipse.jface.window.ToolTip; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.events.ControlAdapter; import org.eclipse.swt.events.ControlEvent; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Tree; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.commands.ICommandService; import org.eclipse.ui.forms.widgets.Form; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.handlers.IHandlerService; import org.eclipse.ui.part.ViewPart; import org.eclipse.ui.progress.IProgressConstants; import org.eclipse.ui.progress.UIJob; import rocks.inspectit.shared.all.cmr.model.PlatformIdent; import rocks.inspectit.shared.all.communication.data.cmr.AgentStatusData; import rocks.inspectit.shared.all.util.ObjectUtils; import rocks.inspectit.ui.rcp.InspectIT; import rocks.inspectit.ui.rcp.InspectITImages; import rocks.inspectit.ui.rcp.editor.tree.DeferredTreeViewer; import rocks.inspectit.ui.rcp.editor.viewers.StyledCellIndexLabelProvider; import rocks.inspectit.ui.rcp.form.CmrRepositoryPropertyForm; import rocks.inspectit.ui.rcp.formatter.ImageFormatter; import rocks.inspectit.ui.rcp.formatter.TextFormatter; import rocks.inspectit.ui.rcp.handlers.ShowRepositoryHandler; import rocks.inspectit.ui.rcp.model.AgentLeaf; import rocks.inspectit.ui.rcp.model.Component; import rocks.inspectit.ui.rcp.model.DeferredAgentsComposite; import rocks.inspectit.ui.rcp.provider.ICmrRepositoryProvider; import rocks.inspectit.ui.rcp.repository.CmrRepositoryChangeListener; import rocks.inspectit.ui.rcp.repository.CmrRepositoryDefinition; import rocks.inspectit.ui.rcp.repository.CmrRepositoryDefinition.OnlineStatus; import rocks.inspectit.ui.rcp.repository.CmrRepositoryManager; import rocks.inspectit.ui.rcp.repository.CmrRepositoryManager.UpdateRepositoryJob; import rocks.inspectit.ui.rcp.repository.RepositoryDefinition; import rocks.inspectit.ui.rcp.util.SafeExecutor; import rocks.inspectit.ui.rcp.view.IRefreshableView; import rocks.inspectit.ui.rcp.view.tree.TreeContentProvider; /** * Repository manager view where user can work with repositories, check agents, and give input for * the data explorer view. * * @author Ivan Senic * */ public class RepositoryManagerView extends ViewPart implements IRefreshableView, CmrRepositoryChangeListener { /** * ID of this view. */ public static final String VIEW_ID = "rocks.inspectit.ui.rcp.view.repositoryManager"; /** * ID for tree menu. */ private static final String MENU_ID = "rocks.inspectit.ui.rcp.view.repositoryManager.repositoryTree"; /** * {@link CmrRepositoryManager}. */ private final CmrRepositoryManager cmrRepositoryManager; /** * Input list. */ private final List<DeferredAgentsComposite> inputList = new ArrayList<>(); /** * Online statuses map. */ private final Map<CmrRepositoryDefinition, OnlineStatus> cachedStatusMap = new ConcurrentHashMap<>(); /** * Toolkit. */ private FormToolkit toolkit; /** * Form for the view. */ private Form mainForm; /** * Tree Viewer. */ private DeferredTreeViewer treeViewer; /** * Composite for displaying the messages. */ private Composite messageComposite; /** * CMR property form. */ private CmrRepositoryPropertyForm cmrPropertyForm; /** * Views main composite. */ private SashForm mainComposite; /** * Boolean for layout of view. */ private boolean verticaLayout = true; /** * Last selected repository, so that the selection can be maintained after the view is * refreshed. */ private DeferredAgentsComposite lastSelectedRepository = null; /** * Defines if agents are shown in the tree which have not sent any data since the CMR was * started. */ private boolean showOldAgents = false; /** * {@link AgentStatusUpdateJob}. */ private AgentStatusUpdateJob agentStatusUpdateJob; /** * List of the objects that is expanded in the tree. */ private List<Object> expandedList; /** * Default constructor. */ public RepositoryManagerView() { cmrRepositoryManager = InspectIT.getDefault().getCmrRepositoryManager(); cmrRepositoryManager.addCmrRepositoryChangeListener(this); createInputList(); } /** * {@inheritDoc} */ @Override public void createPartControl(Composite parent) { createViewToolbar(); toolkit = new FormToolkit(parent.getDisplay()); mainComposite = new SashForm(parent, SWT.VERTICAL); GridLayout mainLayout = new GridLayout(1, true); mainLayout.marginWidth = 0; mainLayout.marginHeight = 0; mainComposite.setLayout(mainLayout); mainForm = toolkit.createForm(mainComposite); mainForm.getBody().setLayout(new GridLayout(1, true)); mainForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); toolkit.decorateFormHeading(mainForm); int borderStyle = toolkit.getBorderStyle(); toolkit.setBorderStyle(SWT.NULL); Tree tree = toolkit.createTree(mainForm.getBody(), SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI); toolkit.setBorderStyle(borderStyle); treeViewer = new DeferredTreeViewer(tree); // create tree content provider TreeContentProvider treeContentProvider = new TreeContentProvider() { @SuppressWarnings("unchecked") @Override public Object[] getElements(Object inputElement) { if (inputElement instanceof Object[]) { return (Object[]) inputElement; } if (inputElement instanceof Collection) { return ((Collection<Object>) inputElement).toArray(); } return new Object[0]; } }; // add the listener that will expand all levels of the agent tree that were expanded before // the update treeContentProvider.addUpdateCompleteListener(new ExpandFoldersUpdateCompleteListener()); treeViewer.setContentProvider(treeContentProvider); treeViewer.setLabelProvider(new RepositoryTreeLabelProvider()); treeViewer.setComparator(new ViewerComparator() { @Override public int compare(Viewer viewer, Object e1, Object e2) { if ((e1 instanceof rocks.inspectit.ui.rcp.model.Composite) && !(e2 instanceof rocks.inspectit.ui.rcp.model.Composite)) { return -1; } else if (!(e1 instanceof rocks.inspectit.ui.rcp.model.Composite) && (e2 instanceof rocks.inspectit.ui.rcp.model.Composite)) { return 1; } else if ((e1 instanceof Component) && (e2 instanceof Component)) { return ((Component) e1).getName().compareToIgnoreCase(((Component) e2).getName()); } else if (e1 instanceof Component) { return 1; } else if (e2 instanceof Component) { return -1; } else { return 0; } } }); treeViewer.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { StructuredSelection structuredSelection = (StructuredSelection) event.getSelection(); if (structuredSelection.getFirstElement() instanceof DeferredAgentsComposite) { lastSelectedRepository = (DeferredAgentsComposite) structuredSelection.getFirstElement(); } } }); treeViewer.addDoubleClickListener(new RepositoryManagerDoubleClickListener()); ColumnViewerToolTipSupport.enableFor(treeViewer, ToolTip.NO_RECREATE); treeViewer.setInput(inputList); cmrPropertyForm = new CmrRepositoryPropertyForm(mainComposite); cmrPropertyForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); treeViewer.addSelectionChangedListener(cmrPropertyForm); MenuManager menuManager = new MenuManager(); menuManager.setRemoveAllWhenShown(true); getSite().registerContextMenu(MENU_ID, menuManager, treeViewer); Control control = treeViewer.getControl(); Menu menu = menuManager.createContextMenu(control); control.setMenu(menu); mainComposite.addControlListener(new ControlAdapter() { @Override public void controlResized(ControlEvent e) { int width = mainComposite.getBounds().width; int height = mainComposite.getBounds().height; if ((width > height) && verticaLayout) { verticaLayout = false; mainComposite.setOrientation(SWT.HORIZONTAL); } else if ((width < height) && !verticaLayout) { verticaLayout = true; mainComposite.setOrientation(SWT.VERTICAL); } mainComposite.layout(); } }); updateFormBody(); mainComposite.setWeights(new int[] { 2, 3 }); agentStatusUpdateJob = new AgentStatusUpdateJob(); getSite().setSelectionProvider(treeViewer); } /** * Creates the view tool-bar. */ private void createViewToolbar() { IToolBarManager toolBarManager = getViewSite().getActionBars().getToolBarManager(); toolBarManager.add(new ShowAgentsAction()); toolBarManager.add(new ShowPropertiesAction()); toolBarManager.add(new Separator()); } /** * Updates the repository map. */ private void createInputList() { inputList.clear(); List<CmrRepositoryDefinition> repositories = cmrRepositoryManager.getCmrRepositoryDefinitions(); for (CmrRepositoryDefinition cmrRepositoryDefinition : repositories) { inputList.add(new DeferredAgentsComposite(cmrRepositoryDefinition, showOldAgents)); OnlineStatus onlineStatus = cmrRepositoryDefinition.getOnlineStatus(); if ((onlineStatus == OnlineStatus.ONLINE) || (onlineStatus == OnlineStatus.OFFLINE)) { cachedStatusMap.put(cmrRepositoryDefinition, onlineStatus); } } } /** * Updates body. */ private void updateFormBody() { clearFormBody(); if (!inputList.isEmpty()) { treeViewer.getTree().setVisible(true); treeViewer.getTree().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); treeViewer.setInput(inputList); treeViewer.expandAll(); if ((null != lastSelectedRepository) && inputList.contains(lastSelectedRepository)) { StructuredSelection ss = new StructuredSelection(lastSelectedRepository); treeViewer.setSelection(ss, true); } } else { displayMessage("No CMR repository present. Please add the CMR repository via 'Add CMR repository' action.", Display.getDefault().getSystemImage(SWT.ICON_INFORMATION)); } mainForm.getBody().layout(); } /** * Clears the look of the forms body. */ private void clearFormBody() { if ((messageComposite != null) && !messageComposite.isDisposed()) { messageComposite.dispose(); } treeViewer.setInput(Collections.emptyList()); treeViewer.getTree().setVisible(false); treeViewer.getTree().setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false)); } /** * Displays the message on the provided composite. * * @param text * Text of message. * @param image * Image to show. */ private void displayMessage(String text, Image image) { if ((null == messageComposite) || messageComposite.isDisposed()) { messageComposite = toolkit.createComposite(mainForm.getBody()); } else { for (Control c : messageComposite.getChildren()) { if (!c.isDisposed()) { c.dispose(); } } } messageComposite.setLayout(new GridLayout(2, false)); messageComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); toolkit.createLabel(messageComposite, null).setImage(image); toolkit.createLabel(messageComposite, text, SWT.WRAP).setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true)); } /** * {@inheritDoc} */ @Override public void setFocus() { if (treeViewer.getTree().isVisible()) { treeViewer.getTree().setFocus(); } else { mainForm.setFocus(); } } /** * {@inheritDoc} */ @Override public void repositoryOnlineStatusUpdated(final CmrRepositoryDefinition repositoryDefinition, OnlineStatus oldStatus, OnlineStatus newStatus) { if (newStatus != OnlineStatus.CHECKING) { OnlineStatus cachedStatus = cachedStatusMap.get(repositoryDefinition); if (null != cachedStatus) { if (cachedStatus != newStatus) { // NOPMD SafeExecutor.asyncExec(new Runnable() { @Override public void run() { mainForm.setBusy(true); for (DeferredAgentsComposite composite : inputList) { if (ObjectUtils.equals(composite.getRepositoryDefinition(), repositoryDefinition)) { treeViewer.refresh(composite, true); treeViewer.expandAll(); if (ObjectUtils.equals(composite, lastSelectedRepository)) { if ((null != lastSelectedRepository) && inputList.contains(lastSelectedRepository)) { treeViewer.setSelection(StructuredSelection.EMPTY); StructuredSelection ss = new StructuredSelection(lastSelectedRepository); treeViewer.setSelection(ss, true); } } } } mainForm.setBusy(false); } }, mainForm, treeViewer.getTree()); } } cachedStatusMap.put(repositoryDefinition, newStatus); } } /** * {@inheritDoc} */ @Override public void repositoryDataUpdated(final CmrRepositoryDefinition cmrRepositoryDefinition) { SafeExecutor.asyncExec(new Runnable() { @Override public void run() { mainForm.setBusy(true); for (DeferredAgentsComposite composite : inputList) { if (ObjectUtils.equals(composite.getRepositoryDefinition(), cmrRepositoryDefinition)) { treeViewer.refresh(composite); break; } } mainForm.setBusy(false); } }, mainForm, treeViewer.getTree()); } /** * {@inheritDoc} */ @Override public void repositoryAdded(CmrRepositoryDefinition cmrRepositoryDefinition) { final DeferredAgentsComposite newComposite = new DeferredAgentsComposite(cmrRepositoryDefinition, showOldAgents); inputList.add(newComposite); OnlineStatus onlineStatus = cmrRepositoryDefinition.getOnlineStatus(); cachedStatusMap.put(cmrRepositoryDefinition, onlineStatus); SafeExecutor.asyncExec(new Runnable() { @Override public void run() { mainForm.setBusy(true); if (inputList.size() > 1) { treeViewer.refresh(); if ((null != lastSelectedRepository) && inputList.contains(lastSelectedRepository)) { StructuredSelection ss = new StructuredSelection(lastSelectedRepository); treeViewer.setSelection(ss, true); } } else { updateFormBody(); } mainForm.setBusy(false); } }, mainForm, treeViewer.getTree()); } /** * {@inheritDoc} */ @Override public void repositoryRemoved(final CmrRepositoryDefinition cmrRepositoryDefinition) { DeferredAgentsComposite toRemove = null; for (DeferredAgentsComposite composite : inputList) { if (ObjectUtils.equals(composite.getRepositoryDefinition(), cmrRepositoryDefinition)) { toRemove = composite; break; } } if (null != toRemove) { inputList.remove(toRemove); } cachedStatusMap.remove(cmrRepositoryDefinition); SafeExecutor.asyncExec(new Runnable() { @Override public void run() { if (ObjectUtils.equals(cmrRepositoryDefinition, lastSelectedRepository.getRepositoryDefinition())) { // reset selection if removed repository is selected treeViewer.setSelection(StructuredSelection.EMPTY); } if (inputList.isEmpty()) { updateFormBody(); } else { treeViewer.refresh(); } } }, treeViewer.getTree(), mainForm.getBody()); } /** * {@inheritDoc} */ @Override public void repositoryAgentDeleted(CmrRepositoryDefinition cmrRepositoryDefinition, PlatformIdent agent) { DeferredAgentsComposite toUpdate = null; for (DeferredAgentsComposite composite : inputList) { if (ObjectUtils.equals(composite.getRepositoryDefinition(), cmrRepositoryDefinition)) { toUpdate = composite; break; } } if (null != toUpdate) { final DeferredAgentsComposite finalToUpdate = toUpdate; SafeExecutor.asyncExec(new Runnable() { @Override public void run() { treeViewer.refresh(finalToUpdate, true); if (ObjectUtils.equals(finalToUpdate, lastSelectedRepository)) { treeViewer.setSelection(StructuredSelection.EMPTY); StructuredSelection ss = new StructuredSelection(finalToUpdate); treeViewer.setSelection(ss, true); if ((null != cmrPropertyForm) && !cmrPropertyForm.isDisposed()) { cmrPropertyForm.refresh(); } } } }, treeViewer.getTree()); } } /** * {@inheritDoc} * <p> * Refreshes all repositories. */ @Override public synchronized void refresh() { // preserve what elements need to be expanded after refresh Object[] expandedElements = treeViewer.getExpandedElements(); Set<Object> parents = new HashSet<>(); for (Object expanded : expandedElements) { Object parent = ((ITreeContentProvider) treeViewer.getContentProvider()).getParent(expanded); while (parent != null) { parents.add(parent); parent = ((ITreeContentProvider) treeViewer.getContentProvider()).getParent(parent); } } expandedList = new ArrayList<>(Arrays.asList(expandedElements)); expandedList.removeAll(parents); // execute refresh Collection<UpdateRepositoryJob> jobs = cmrRepositoryManager.forceAllCmrRepositoriesOnlineStatusUpdate(); for (final UpdateRepositoryJob updateRepositoryJob : jobs) { updateRepositoryJob.addJobChangeListener(new JobChangeAdapter() { @Override public void done(IJobChangeEvent event) { CmrRepositoryDefinition cmrRepositoryDefinition = updateRepositoryJob.getCmrRepositoryDefinition(); DeferredAgentsComposite toUpdate = null; for (DeferredAgentsComposite composite : inputList) { if (ObjectUtils.equals(composite.getRepositoryDefinition(), cmrRepositoryDefinition)) { toUpdate = composite; break; } } if (null != toUpdate) { final DeferredAgentsComposite finalToUpdate = toUpdate; SafeExecutor.asyncExec(new Runnable() { @Override public void run() { treeViewer.refresh(finalToUpdate, true); if (ObjectUtils.equals(finalToUpdate, lastSelectedRepository)) { if ((null != cmrPropertyForm) && !cmrPropertyForm.isDisposed()) { cmrPropertyForm.refresh(); } } } }, treeViewer.getTree()); } updateRepositoryJob.removeJobChangeListener(this); } }); } } /** * {@inheritDoc} */ @Override public boolean canRefresh() { return !inputList.isEmpty() || !cmrRepositoryManager.getCmrRepositoryDefinitions().isEmpty(); } /** * Show or hides properties. * * @param show * Should properties be shown. */ public void setShowProperties(boolean show) { if (show) { CmrRepositoryDefinition cmrRepositoryDefinition = null; StructuredSelection selection = (StructuredSelection) treeViewer.getSelection(); if (!selection.isEmpty()) { if (selection.getFirstElement() instanceof ICmrRepositoryProvider) { cmrRepositoryDefinition = ((ICmrRepositoryProvider) selection.getFirstElement()).getCmrRepositoryDefinition(); } } cmrPropertyForm = new CmrRepositoryPropertyForm(mainComposite, cmrRepositoryDefinition); cmrPropertyForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); treeViewer.addSelectionChangedListener(cmrPropertyForm); mainComposite.setWeights(new int[] { 2, 3 }); mainComposite.layout(); } else { if ((null != cmrPropertyForm) && !cmrPropertyForm.isDisposed()) { treeViewer.removeSelectionChangedListener(cmrPropertyForm); cmrPropertyForm.dispose(); cmrPropertyForm = null; // NOPMD } mainComposite.setWeights(new int[] { 1 }); mainComposite.layout(); } } /** * {@inheritDoc} */ @Override public void dispose() { cmrRepositoryManager.removeCmrRepositoryChangeListener(this); agentStatusUpdateJob.cancel(); super.dispose(); } /** * Action for show hide properties. * * @author Ivan Senic * */ private class ShowPropertiesAction extends Action { /** * Default constructor. */ public ShowPropertiesAction() { super(null, AS_CHECK_BOX); setImageDescriptor(InspectIT.getDefault().getImageDescriptor(InspectITImages.IMG_PROPERTIES)); setChecked(true); setToolTipText("Hide Properties"); } /** * {@inheritDoc} */ @Override public void run() { if (isChecked()) { setShowProperties(true); setToolTipText("Hide Properties"); } else { setShowProperties(false); setToolTipText("Show Properties"); } }; } /** * Action for show hide agents which have not sent any data. * * @author Patrice Bouillet * */ private class ShowAgentsAction extends Action { /** * Default constructor. */ public ShowAgentsAction() { super(null, AS_CHECK_BOX); setImageDescriptor(InspectIT.getDefault().getImageDescriptor(InspectITImages.IMG_AGENT)); setChecked(showOldAgents); updateToolTipText(); } /** * {@inheritDoc} */ @Override public void run() { showOldAgents = isChecked(); updateToolTipText(); createInputList(); updateFormBody(); }; /** * Updates tool-tip text based on the current state. */ private void updateToolTipText() { if (isChecked()) { setToolTipText("Hide Agents which have not sent any data yet."); } else { setToolTipText("Show Agents which have not sent any data yet."); } } } /** * Double click listener for the view. * * @author Ivan Senic * */ private class RepositoryManagerDoubleClickListener implements IDoubleClickListener { /** * {@inheritDoc} */ @Override public void doubleClick(final DoubleClickEvent event) { UIJob openDataExplorerJob = new UIJob("Opening Data Explorer..") { @Override public IStatus runInUIThread(IProgressMonitor monitor) { process(); return Status.OK_STATUS; } }; openDataExplorerJob.setUser(true); openDataExplorerJob.schedule(); } /** * Processes the double-click. * */ private void process() { RepositoryDefinition repositoryDefinition = null; PlatformIdent platformIdent = null; StructuredSelection selection = (StructuredSelection) treeViewer.getSelection(); // if selection is empty do nothing if (selection.isEmpty()) { return; } Object firstElement = selection.getFirstElement(); if (firstElement instanceof DeferredAgentsComposite) { repositoryDefinition = ((DeferredAgentsComposite) firstElement).getRepositoryDefinition(); } else if (firstElement instanceof AgentLeaf) { platformIdent = ((AgentLeaf) firstElement).getPlatformIdent(); Component parent = ((AgentLeaf) firstElement).getParent(); while (null != parent) { if (parent instanceof DeferredAgentsComposite) { repositoryDefinition = ((DeferredAgentsComposite) parent).getRepositoryDefinition(); break; } parent = parent.getParent(); } } if (null != repositoryDefinition) { IHandlerService handlerService = (IHandlerService) PlatformUI.getWorkbench().getService(IHandlerService.class); ICommandService commandService = (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class); Command command = commandService.getCommand(ShowRepositoryHandler.COMMAND); ExecutionEvent executionEvent = handlerService.createExecutionEvent(command, new Event()); IEvaluationContext context = (IEvaluationContext) executionEvent.getApplicationContext(); context.addVariable(ShowRepositoryHandler.REPOSITORY_DEFINITION, repositoryDefinition); if (null != platformIdent) { context.addVariable(ShowRepositoryHandler.AGENT, platformIdent); } try { command.executeWithChecks(executionEvent); } catch (Exception e) { throw new RuntimeException(e); } } else { if (treeViewer.getExpandedState(firstElement)) { treeViewer.collapseToLevel(firstElement, 1); } else { treeViewer.expandToLevel(firstElement, 1); } } } } /** * Label provider for the tree. * * @author Ivan Senic * */ private static class RepositoryTreeLabelProvider extends StyledCellIndexLabelProvider { /** * {@inheritDoc} */ @Override protected Image getColumnImage(Object element, int index) { if (element instanceof DeferredAgentsComposite) { CmrRepositoryDefinition cmrRepositoryDefinition = (CmrRepositoryDefinition) ((DeferredAgentsComposite) element).getRepositoryDefinition(); return ImageFormatter.getCmrRepositoryImage(cmrRepositoryDefinition, true); } else if (element instanceof AgentLeaf) { return ImageFormatter.getAgentImage(((AgentLeaf) element).getAgentStatusData()); } else if (element instanceof Component) { return ((Component) element).getImage(); } return null; } /** * {@inheritDoc} */ @Override protected StyledString getStyledText(Object element, int index) { if (element instanceof DeferredAgentsComposite) { CmrRepositoryDefinition cmrRepositoryDefinition = (CmrRepositoryDefinition) ((DeferredAgentsComposite) element).getRepositoryDefinition(); return new StyledString(cmrRepositoryDefinition.getName()); } else if (element instanceof AgentLeaf) { return TextFormatter.getStyledAgentLeafString((AgentLeaf) element); } else if (element instanceof Component) { return new StyledString(((Component) element).getName()); } return null; } /** * {@inheritDoc} */ @Override public String getToolTipText(Object element) { if (element instanceof AgentLeaf) { return "Double click to explore Agent in the Data Explorer"; } return null; } /** * {@inheritDoc} */ @Override public Point getToolTipShift(Object object) { int x = 5; int y = 5; return new Point(x, y); } /** * {@inheritDoc} */ @Override public int getToolTipDisplayDelayTime(Object object) { return 500; } } /** * Job for auto-update of view. * * @author Ivan Senic * */ private final class AgentStatusUpdateJob extends Job { /** * Update rate in milliseconds. Currently every 60 seconds. */ private static final long UPDATE_RATE = 60 * 1000L; /** * Default constructor. */ public AgentStatusUpdateJob() { super("Agents status auto-update"); setUser(false); setProperty(IProgressConstants.ICON_PROPERTY, InspectIT.getDefault().getImageDescriptor(InspectITImages.IMG_AGENT)); schedule(UPDATE_RATE); } /** * {@inheritDoc} */ @Override protected IStatus run(IProgressMonitor monitor) { updateAgentsAndCmrStatus(); schedule(UPDATE_RATE); return Status.OK_STATUS; } /** * Updates the agent status for each CMR and updates the displayed CMR repository. */ private void updateAgentsAndCmrStatus() { if ((null != cmrPropertyForm) && !cmrPropertyForm.isDisposed()) { cmrPropertyForm.refresh(); } if (null != inputList) { final List<Object> toUpdate = new ArrayList<>(); for (DeferredAgentsComposite agentsComposite : inputList) { CmrRepositoryDefinition cmrRepositoryDefinition = agentsComposite.getCmrRepositoryDefinition(); List<?> leafs = agentsComposite.getChildren(); if (CollectionUtils.isNotEmpty(leafs) && (cmrRepositoryDefinition.getOnlineStatus() != OnlineStatus.OFFLINE)) { Map<PlatformIdent, AgentStatusData> statusMap = cmrRepositoryDefinition.getGlobalDataAccessService().getAgentsOverview(); for (Object child : leafs) { if (child instanceof AgentLeaf) { AgentLeaf agentLeaf = (AgentLeaf) child; AgentStatusData agentStatusData = statusMap.get(agentLeaf.getPlatformIdent()); agentLeaf.setAgentStatusData(agentStatusData); toUpdate.add(agentLeaf); } } } } if (CollectionUtils.isNotEmpty(toUpdate)) { SafeExecutor.asyncExec(new Runnable() { @Override public void run() { treeViewer.update(toUpdate.toArray(), null); } }, treeViewer.getTree()); } } } } /** * Listener that is added to the {@link TreeContentProvider} and is invoked when job of updating * the tree elements is done. At this point this listener will re-expand all the before expanded * elements. * * @author Ivan Senic * */ private class ExpandFoldersUpdateCompleteListener extends JobChangeAdapter { /** * {@inheritDoc} */ @Override public void done(IJobChangeEvent event) { synchronized (RepositoryManagerView.this) { if (CollectionUtils.isNotEmpty(expandedList) && CollectionUtils.isNotEmpty(inputList)) { for (Iterator<?> it = expandedList.iterator(); it.hasNext();) { Object o = it.next(); if (treeViewer.isExpandable(o) && !treeViewer.getExpandedState(o)) { treeViewer.expandObject(o, 1); it.remove(); } } } } } } }