org.jboss.tools.windup.ui.internal.editor.RulesetEditorRulesSection.java Source code

Java tutorial

Introduction

Here is the source code for org.jboss.tools.windup.ui.internal.editor.RulesetEditorRulesSection.java

Source

/*******************************************************************************
 * Copyright (c) 2019 Red Hat, Inc.
 * Distributed under license by Red Hat, Inc. All rights reserved.
 * This program is made available under the terms of the
 * Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *   Red Hat, Inc. - initial API and implementation
 ******************************************************************************/
package org.jboss.tools.windup.ui.internal.editor;

import static org.jboss.tools.windup.model.domain.WindupConstants.CONFIG_CREATED;
import static org.jboss.tools.windup.model.domain.WindupConstants.CONFIG_DELETED;

import java.util.Iterator;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.inject.Inject;

import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.e4.core.di.annotations.Optional;
import org.eclipse.e4.core.services.events.IEventBroker;
import org.eclipse.e4.ui.di.UIEventTopic;
import org.eclipse.e4.ui.workbench.UIEvents;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ContributionManager;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.layout.PixelConverter;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.pde.internal.ui.PDEPluginImages;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ViewForm;
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.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.menus.IMenuService;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
import org.jboss.tools.windup.model.domain.ModelService;
import org.jboss.tools.windup.ui.internal.Messages;
import org.jboss.tools.windup.ui.internal.editor.RulesetElementUiDelegateFactory.IElementUiDelegate;
import org.jboss.tools.windup.ui.internal.editor.RulesetElementUiDelegateFactory.RulesetConstants;
import org.jboss.tools.windup.ui.internal.rules.xml.XMLRulesetModelUtil;
import org.jboss.tools.windup.ui.internal.services.RulesetDOMService;
import org.jboss.tools.windup.windup.ConfigurationElement;
import org.jboss.tools.windup.windup.CustomRuleProvider;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import com.google.common.collect.Lists;

/**
 * The composite containing Windup's configurations.
 */
@SuppressWarnings("restriction")
public class RulesetEditorRulesSection {

    private static final String TOOLBAR_ID = "toolbar:org.jboss.tools.windup.toolbar.configurations.table"; //$NON-NLS-1$

    private static final String SELECTED_CONFIGURATION = "selectedConfiguration";

    @Inject
    private IEventBroker broker;
    @Inject
    private IMenuService menuService;
    @Inject
    private ModelService modelService;
    @Inject
    private FormToolkit toolkit;
    @Inject
    private IEclipsePreferences preferences;

    @Inject
    private RulesetDOMService domService;

    @Inject
    private RulesetElementUiDelegateRegistry elementUiDelegateRegistry;

    @Inject
    RulesSectionContentProvider provider;

    private ToolBarManager toolBarManager;
    private TreeViewer treeViewer;

    private Button removeButton;
    private Button upButton;
    private Button downButton;

    private RulesetElementsView elementsView;

    public ISelectionProvider getSelectionProvider() {
        return treeViewer;
    }

    public TreeViewer getTableViewer() {
        return treeViewer;
    }

    public void selectAndReveal(Element element) {
        treeViewer.expandToLevel(element, TreeViewer.ALL_LEVELS);
        treeViewer.setSelection(new StructuredSelection(element), true);
    }

    public void setDocument(Document document) {
        if (document == treeViewer.getInput()) {
            treeViewer.refresh(document, true);
        } else {
            treeViewer.setInput(document);
        }
    }

    public void init(CustomRuleProvider ruleProvider) {
        List<Node> ruleNodes = XMLRulesetModelUtil.getRules(ruleProvider.getLocationURI());
        treeViewer.setInput(ruleNodes.toArray(new Node[ruleNodes.size()]));
    }

    @PostConstruct
    private void createRulesetElementArea(Composite parent) {
        Composite comp = new Composite(parent, SWT.FLAT);
        GridLayout gridLayout = new GridLayout(1, false);
        gridLayout.marginHeight = 0;
        gridLayout.marginWidth = 0;
        comp.setLayout(gridLayout);
        comp.setLayoutData(new GridData(GridData.FILL_BOTH));

        ViewForm viewForm = new ViewForm(comp, SWT.FLAT | SWT.BORDER);
        ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT);
        ToolBar toolBar = toolBarManager.createControl(viewForm);
        toolBar.setBackground(parent.getBackground());
        viewForm.setTopLeft(toolBar);
        viewForm.setLayoutData(new GridData(GridData.FILL_BOTH));

        Composite viewFormContents = new Composite(viewForm, SWT.FLAT);
        gridLayout = new GridLayout();
        gridLayout.marginHeight = 5;
        gridLayout.marginWidth = 5;
        viewFormContents.setLayout(gridLayout);
        viewFormContents.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
        elementsView = new RulesetElementsView();
        elementsView.init(this, domService);
        elementsView.createControls(viewFormContents, toolBarManager);
        Text filterText = elementsView.getFilteringTextControl();
        if (filterText != null) {
            filterText.setFocus();
        }

        this.treeViewer = (TreeViewer) elementsView.getViewer();

        DelegatingStyledCellLabelProvider styleProvider = new DelegatingStyledCellLabelProvider(provider);
        provider.setFilterText(elementsView.getFilteringTextControl());
        treeViewer.setContentProvider(provider);
        treeViewer.setLabelProvider(styleProvider);
        createViewerContextMenu();

        Control control = treeViewer.getControl();
        GridData gd = new GridData(GridData.FILL_BOTH);
        control.setLayoutData(gd);
        viewForm.setContent(viewFormContents);
    }

    //@PostConstruct
    private void create(Composite parent) {
        //parent.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_WHITE));

        Composite container = toolkit.createComposite(parent);
        GridLayoutFactory.fillDefaults().margins(0, 0).applyTo(container);
        GridDataFactory.fillDefaults().grab(true, true).applyTo(container);

        //      Section section = toolkit.createSection(container, Section.TITLE_BAR);
        //      section.setText(rulesSectionTitle);
        //      GridDataFactory.fillDefaults().grab(true, true).applyTo(section);

        createToolbar(container);

        Composite client = toolkit.createComposite(/*section*/container);
        toolkit.paintBordersFor(client);
        GridLayoutFactory.fillDefaults().numColumns(2).equalWidth(false).applyTo(client);
        GridDataFactory.fillDefaults().grab(true, true).applyTo(client);
        //section.setClient(client);

        createControls(client);

        focus();
    }

    private void createControls(Composite parent/*, Section section*/) {
        //createToolbar(section);
        this.treeViewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
        treeViewer.addSelectionChangedListener((e) -> {
            Element selectedElement = (Element) ((StructuredSelection) e.getSelection()).getFirstElement();
            update();
            boolean enabled = selectedElement != null;
            removeButton.setEnabled(enabled);
            if (enabled) {
                enabled = RulesetConstants.RULE_NAME.equals(selectedElement.getNodeName()) ? true : false;
            }
            upButton.setEnabled(enabled);
            downButton.setEnabled(enabled);
        });

        GridDataFactory.fillDefaults().grab(true, true).applyTo(treeViewer.getTree());

        treeViewer.setContentProvider(provider);
        treeViewer.setLabelProvider(provider);
        createViewerContextMenu();

        createButtons(parent);
    }

    private void createButtons(Composite parent) {
        Composite container = toolkit.createComposite(parent);
        toolkit.paintBordersFor(container);
        GridLayoutFactory.fillDefaults().applyTo(container);
        GridDataFactory.fillDefaults().grab(false, true).applyTo(container);

        Button addButton = createButton(container, Messages.RulesetEditor_AddRule);
        addButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                Document document = (Document) treeViewer.getInput();
                Element rulesetElement = domService.findOrCreateRulesetElement(document);
                Element rulesElement = domService.findOrCreateRulesElement(rulesetElement);
                //createRule(rulesElement);
            }
        });
        this.removeButton = createButton(container, Messages.RulesetEditor_remove);
        removeButton.addSelectionListener(new SelectionAdapter() {
            @SuppressWarnings("unchecked")
            @Override
            public void widgetSelected(SelectionEvent e) {
                removeNodes(((IStructuredSelection) treeViewer.getSelection()).toList());
            }
        });

        createPlaceholder(container);
        createPlaceholder(container);
        createPlaceholder(container);

        this.upButton = createButton(container, Messages.RulesetEditor_Rules_up);
        this.downButton = createButton(container, Messages.RulesetEditor_Rules_down);

        upButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                StructuredSelection ss = (StructuredSelection) treeViewer.getSelection();
                if (!ss.isEmpty() && ss.size() == 1) {
                    Node node = (Node) ss.getFirstElement();
                    if (node instanceof Element && node.getParentNode() instanceof Element) {
                        ISelection selection = treeViewer.getSelection();
                        domService.insertBeforePreviousSibling(node);
                        treeViewer.setSelection(selection);
                    }
                }
            }
        });

        downButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                StructuredSelection ss = (StructuredSelection) treeViewer.getSelection();
                if (!ss.isEmpty() && ss.size() == 1) {
                    Node node = (Node) ss.getFirstElement();
                    if (node instanceof Element && node.getParentNode() instanceof Element) {
                        ISelection selection = treeViewer.getSelection();
                        domService.insertAfterNextSibling(node);
                        treeViewer.setSelection(selection);
                    }
                }
            }
        });
    }

    private void createPlaceholder(Composite parent) {
        Label label = toolkit.createLabel(parent, null);
        GridData gd = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
        gd.horizontalSpan = 1;
        gd.widthHint = 0;
        gd.heightHint = 0;
        label.setLayoutData(gd);
    }

    private Button createButton(Composite parent, String label) {
        Button button = toolkit.createButton(parent, label, SWT.PUSH);
        GridData gd = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING);
        button.setLayoutData(gd);
        button.setFont(JFaceResources.getDialogFont());
        PixelConverter converter = new PixelConverter(button);
        int widthHint = converter.convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
        gd.widthHint = Math.max(widthHint, button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
        return button;
    }

    private void createToolbar(Composite parent) {
        this.toolBarManager = new ToolBarManager(SWT.FLAT);
        ToolBar toolBar = this.toolBarManager.createControl(parent);
        //      section.setTextClient(toolBar);
        menuService.populateContributionManager((ContributionManager) toolBarManager, TOOLBAR_ID);
    }

    @Inject
    @Optional
    private void configCreated(@UIEventTopic(CONFIG_CREATED) ConfigurationElement configuration) {
        treeViewer.setSelection(new StructuredSelection(configuration), true);
    }

    @Inject
    @Optional
    private void configDeleted(@UIEventTopic(CONFIG_DELETED) ConfigurationElement configuration) {
    }

    private void update() {
        broker.post(UIEvents.REQUEST_ENABLEMENT_UPDATE_TOPIC, UIEvents.ALL_ELEMENT_ID);
    }

    private void focus() {
        String previouslySelected = preferences.get(SELECTED_CONFIGURATION, null);
        if (previouslySelected != null) {
            ConfigurationElement configuration = modelService.findConfiguration(previouslySelected);
            if (configuration != null) {
                treeViewer.setSelection(new StructuredSelection(configuration), true);
            }
        }
        treeViewer.getTree().setFocus();
    }

    private void createViewerContextMenu() {
        MenuManager popupMenuManager = new MenuManager();
        IMenuListener listener = new IMenuListener() {
            @Override
            public void menuAboutToShow(IMenuManager mng) {
                fillContextMenu(mng);
            }
        };
        popupMenuManager.addMenuListener(listener);
        popupMenuManager.setRemoveAllWhenShown(true);
        Control control = treeViewer.getControl();
        Menu menu = popupMenuManager.createContextMenu(control);
        control.setMenu(menu);
    }

    @SuppressWarnings("unchecked")
    private void fillContextMenu(IMenuManager manager) {
        ISelection selection = treeViewer.getSelection();
        IStructuredSelection ssel = (IStructuredSelection) selection;
        if (!ssel.isEmpty()) {
            if (ssel.toList().size() == 1) {
                Element element = (Element) ssel.getFirstElement();
                IElementUiDelegate delegate = elementUiDelegateRegistry.getUiDelegate(element);
                if (delegate != null) {
                    delegate.fillContextMenu(manager, treeViewer);
                }
            }
            Action deleteAction = new Action() {
                @Override
                public ImageDescriptor getImageDescriptor() {
                    return PDEPluginImages.DESC_DELETE;
                }

                @Override
                public ImageDescriptor getDisabledImageDescriptor() {
                    return PDEPluginImages.DESC_REMOVE_ATT_DISABLED;
                }

                @Override
                public void run() {
                    removeNodes(ssel.toList());
                }
            };
            deleteAction.setText(Messages.RulesetEditor_RemoveElement);
            manager.add(deleteAction);
        }
        this.treeViewer.getControl().update();
    }

    public void removeNodes(List<Element> elements) {
        if (elements.isEmpty()) {
            return;
        }
        IStructuredModel model = ((IDOMDocument) treeViewer.getInput()).getModel();
        try {
            model.aboutToChangeModel();

            filterChildElements(elements);

            Node nextSelection = findElementForSelection(elements);

            new DeleteNodeAction(model, elements).run();

            if (nextSelection != null) {
                treeViewer.setSelection(new StructuredSelection(nextSelection));
            }
        } finally {
            model.changedModel();
        }
    }

    private Node findElementForSelection(List<Element> toBeDeleted) {
        if (toBeDeleted.size() > 1) {
            return null;
        }
        Element firstElement = toBeDeleted.get(0);
        Element parent = (Element) firstElement.getParentNode();

        Node nextSelection = domService.findNextSibling(toBeDeleted.get(toBeDeleted.size() - 1), 1);
        if (nextSelection == null || toBeDeleted.contains(nextSelection)) {
            // no next node, use previous node
            nextSelection = domService.findPreviousSibling(firstElement);
        }

        if (nextSelection == null || toBeDeleted.contains(nextSelection)) {
            // next or previous null, use parent
            nextSelection = parent;
        }
        return nextSelection;
    }

    private void filterChildElements(List<Element> elements) {
        for (Iterator<Element> iter = Lists.newArrayList(elements).iterator(); iter.hasNext();) {
            Element element = iter.next();
            // climb parent hierarchy, and remove element if one of parents is in list.
            while (true) {
                Node parent = element.getParentNode();
                if (parent == null) {
                    break;
                }
                if (elements.contains(parent)) {
                    iter.remove();
                    break;
                }
                parent = element.getParentNode();
                if (!(parent instanceof Element)) {
                    break;
                }
                element = (Element) parent;
            }
        }
    }
}