package rocks.inspectit.ui.rcp.property; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.ArrayUtils; import org.eclipse.jface.preference.IPreferenceNode; import org.eclipse.jface.preference.IPreferencePage; import org.eclipse.jface.preference.PreferenceManager; import org.eclipse.jface.preference.PreferenceNode; import org.eclipse.jface.viewers.ViewerFilter; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.internal.dialogs.FilteredPreferenceDialog; import org.eclipse.ui.internal.dialogs.PreferenceNodeFilter; import rocks.inspectit.shared.cs.cmr.property.configuration.AbstractProperty; import rocks.inspectit.shared.cs.cmr.property.configuration.GroupedProperty; import rocks.inspectit.shared.cs.cmr.property.configuration.PropertySection; import rocks.inspectit.shared.cs.cmr.property.configuration.SingleProperty; import rocks.inspectit.shared.cs.cmr.property.update.IPropertyUpdate; import rocks.inspectit.shared.cs.cmr.property.update.configuration.ConfigurationUpdate; import rocks.inspectit.ui.rcp.repository.CmrRepositoryDefinition; import rocks.inspectit.ui.rcp.repository.CmrRepositoryDefinition.OnlineStatus; /** * Dialog for displaying the CMR configuration. * * @author Ivan Senic * */ @SuppressWarnings("restriction") public class CmrConfigurationDialog extends FilteredPreferenceDialog { /** * CMR to configure. */ private CmrRepositoryDefinition cmrRepositoryDefinition; /** * Configuration update that will be available after OK has been clicked if any updates were * made. */ private ConfigurationUpdate configurationUpdate; /** * If updates defined in the dialog need a server restart. */ private boolean serverRestartRequired; /** * Filter for the advanced pages. */ private ViewerFilter preferenceNodeFilter = new PreferenceNodeFilter(new String[0]); /** * Default constructor. * * @param parentShell * Shell to use. * @param cmrRepositoryDefinition * {@link CmrRepositoryDefinition} to create dialog for. */ public CmrConfigurationDialog(Shell parentShell, CmrRepositoryDefinition cmrRepositoryDefinition) { super(parentShell, getPreferenceManager(cmrRepositoryDefinition)); this.cmrRepositoryDefinition = cmrRepositoryDefinition; } /** * {@inheritDoc} */ @Override protected void configureShell(Shell shell) { super.configureShell(shell); shell.setText("Configure CMR '" + cmrRepositoryDefinition.getName() + "' (" + cmrRepositoryDefinition.getIp() + ":" + cmrRepositoryDefinition.getPort() + ")"); } /** * {@inheritDoc} */ @Override protected Control createButtonBar(Composite parent) { Composite composite = new Composite(parent, SWT.NONE); GridLayout layout = new GridLayout(2, false); layout.marginWidth = 0; layout.marginHeight = 0; layout.horizontalSpacing = 0; composite.setLayout(layout); composite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); final Button showAdv = new Button(composite, SWT.CHECK); showAdv.setText("Show advanced properties"); showAdv.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, true, false)); showAdv.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { showAdvanced(showAdv.getSelection()); } }); super.createButtonBar(composite); // executed to handle hiding of pages with only advanced properties filteredTree.getViewer().setExpandPreCheckFilters(true); showAdvanced(false); return composite; } /** * {@inheritDoc} */ @Override @SuppressWarnings("unchecked") protected void okPressed() { Set<IPropertyUpdate<?>> propertyUpdates = new HashSet<>(); Iterator<IPreferenceNode> nodes = getPreferenceManager().getElements(PreferenceManager.PRE_ORDER).iterator(); while (nodes.hasNext()) { IPreferenceNode node = nodes.next(); IPreferencePage page = node.getPage(); if (page instanceof PropertyPreferencePage) { PropertyPreferencePage propertyPreferencePage = (PropertyPreferencePage) page; propertyUpdates.addAll(propertyPreferencePage.getPropertyUpdates()); if (propertyPreferencePage.isServerRestartRequired()) { serverRestartRequired = true; } } } if (CollectionUtils.isNotEmpty(propertyUpdates)) { configurationUpdate = new ConfigurationUpdate(); configurationUpdate.setPropertyUpdates(propertyUpdates); } super.okPressed(); } /** * Show/hide advanced properties on the pages. * * @param show * True if advanced should be shown, false otherwise. */ @SuppressWarnings("unchecked") private void showAdvanced(boolean show) { List<String> idsToShow = new ArrayList<>(); Iterator<IPreferenceNode> nodes = getPreferenceManager().getElements(PreferenceManager.PRE_ORDER).iterator(); while (nodes.hasNext()) { IPreferenceNode node = nodes.next(); IPreferencePage page = node.getPage(); if (page instanceof PropertyPreferencePage) { PropertyPreferencePage preferencePage = (PropertyPreferencePage) page; preferencePage.showAdvanced(show); if (show || showIfNoAdvanced(node)) { idsToShow.add(node.getId()); } } } if (null != preferenceNodeFilter) { filteredTree.getViewer().removeFilter(preferenceNodeFilter); } preferenceNodeFilter = new PreferenceNodeFilter(idsToShow.toArray(new String[idsToShow.size()])); filteredTree.getViewer().addFilter(preferenceNodeFilter); // switch to another page if currently displayed has only advanced properties Collections.sort(idsToShow); PropertyPreferencePage currentPage = (PropertyPreferencePage) getCurrentPage(); if (null != currentPage) { if (!show && currentPage.isAllAdvancedProperties()) { // display first page setCurrentPageId(idsToShow.get(0)); } } } /** * Defines if node should be displayed if no advanced is selected. This method is recursive. * * @param node * Node to check. * @return <code>true</code> this node should be displayed if only normal properties are * defined. */ private boolean showIfNoAdvanced(IPreferenceNode node) { if (node.getPage() instanceof PropertyPreferencePage) { if (!((PropertyPreferencePage) node.getPage()).isAllAdvancedProperties()) { return true; } } if (ArrayUtils.isNotEmpty(node.getSubNodes())) { for (IPreferenceNode subNode : node.getSubNodes()) { if (showIfNoAdvanced(subNode)) { return true; } } } return false; } /** * Gets {@link #configurationUpdate}. Note that this method will return <code>null</code> if no * updates were created in the dialog. * * @return {@link #configurationUpdate} */ public ConfigurationUpdate getConfigurationUpdate() { return configurationUpdate; } /** * Gets {@link #serverRestartRequired}. * * @return {@link #serverRestartRequired} */ public boolean isServerRestartRequired() { return serverRestartRequired; } /** * Creates preference manager for the given {@link CmrRepositoryDefinition}. * * @param cmrRepositoryDefinition * {@link CmrRepositoryDefinition}. * @return {@link PreferenceManager}. * @throw {@link IllegalArgumentException} If given CMR is <code>null</code>, off-line or can * not provide active properties. */ public static PreferenceManager getPreferenceManager(CmrRepositoryDefinition cmrRepositoryDefinition) { if (null == cmrRepositoryDefinition) { throw new IllegalArgumentException("Can not create Preference Manager because repository is null."); } else if (cmrRepositoryDefinition.getOnlineStatus() == OnlineStatus.OFFLINE) { throw new IllegalArgumentException("Can not create Preference Manager because repository is off-line."); } Collection<PropertySection> sections = cmrRepositoryDefinition.getCmrManagementService().getConfigurationPropertySections(); if (CollectionUtils.isEmpty(sections)) { throw new IllegalArgumentException("Can not create CMR Preference Manager because repository can not provide active properties."); } PreferenceManager preferenceManager = new PreferenceManager(); for (PropertySection section : sections) { List<IPreferenceNode> subNodes = new ArrayList<>(); List<SingleProperty<?>> singleProperties = new ArrayList<>(); for (AbstractProperty property : section.getProperties()) { if (property instanceof GroupedProperty) { GroupedProperty groupedProperty = (GroupedProperty) property; GroupedPropertyPreferencePage preferencePage = new GroupedPropertyPreferencePage(groupedProperty); PreferenceNode preferenceNode = new PreferenceNode(groupedProperty.getName(), preferencePage); subNodes.add(preferenceNode); } else if (property instanceof SingleProperty<?>) { singleProperties.add((SingleProperty<?>) property); } } PropertyPreferencePage preferencePage = new PropertyPreferencePage(section.getName(), singleProperties); PreferenceNode preferenceNode = new PreferenceNode(section.getName(), preferencePage); preferenceManager.addToRoot(preferenceNode); for (IPreferenceNode subNode : subNodes) { preferenceManager.addTo(section.getName(), subNode); } } return preferenceManager; } }