org.jboss.tools.cdi.text.ext.hyperlink.AssignableBeansDialog.java Source code

Java tutorial

Introduction

Here is the source code for org.jboss.tools.cdi.text.ext.hyperlink.AssignableBeansDialog.java

Source

/******************************************************************************* 
 * Copyright (c) 2011 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.cdi.text.ext.hyperlink;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import org.eclipse.jdt.core.IMethod;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.PopupDialog;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ICheckStateProvider;
import org.eclipse.jface.viewers.IOpenListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.OpenEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StyledCellLabelProvider;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.jface.viewers.StyledString.Styler;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.graphics.TextStyle;
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.Group;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.dialogs.SearchPattern;
import org.jboss.tools.cdi.core.CDIImages;
import org.jboss.tools.cdi.core.IBean;
import org.jboss.tools.cdi.core.ICDIElement;
import org.jboss.tools.cdi.core.IInjectionPoint;
import org.jboss.tools.cdi.core.IInjectionPointParameter;
import org.jboss.tools.cdi.core.IQualifierDeclaration;
import org.jboss.tools.cdi.core.util.BeanPresentationUtil;
import org.jboss.tools.cdi.text.ext.CDIExtensionsMessages;
import org.jboss.tools.cdi.text.ext.CDIExtensionsPlugin;
import org.jboss.tools.cdi.text.ext.hyperlink.AssignableBeanFilters.Checkbox;
import org.jboss.tools.cdi.text.ext.hyperlink.AssignableBeanFilters.Filter;
import org.jboss.tools.common.java.IParametedType;

/**
 * 
 * @author Viacheslav Kabanovich
 *
 */
public class AssignableBeansDialog extends PopupDialog {// TitleAreaDialog {
    IInjectionPoint injectionPoint;
    AssignableBeanFilters filters = null;
    Set<IBean> beans = new HashSet<IBean>();
    Set<IBean> eligibleBeans = new HashSet<IBean>();
    Set<IBean> resolvedBeans = new HashSet<IBean>();

    Composite composite;

    boolean showHideOptions = true;
    Group filterPanel;
    CheckboxTreeViewer filterView;

    private Text fFilterText;
    TableViewer list;

    public AssignableBeansDialog(Shell parentShell) {
        // TitleAreaDialog
        //      super(parentShell);
        //PopupDialog
        super(parentShell, 0, true, true, true, true, true, "title", null);
        setShellStyle(getShellStyle() | SWT.RESIZE);
        filters = new AssignableBeanFilters();
    }

    protected void initSettings() {
        IDialogSettings settings = getDialogSettings();
        showHideOptions = settings.getBoolean(SHOW_HIDE_PANEL);
        for (Checkbox c : filters.getAllOptions().values()) {
            String name = FILTER_OPTION + c.id;
            c.state = !"false".equals(settings.get(name));
        }
        filters.getRoot().state = true;
    }

    public void setInjectionPoint(IInjectionPoint injectionPoint) {
        this.injectionPoint = injectionPoint;
        filters.init(injectionPoint);
        initSettings();
        beans = new HashSet<IBean>(injectionPoint.getCDIProject().getBeans(false, injectionPoint));
        eligibleBeans = new HashSet<IBean>(beans);
        for (int i = AssignableBeanFilters.OPTION_UNAVAILABLE_BEANS
                + 1; i < AssignableBeanFilters.OPTION_ELIMINATED_AMBIGUOUS; i++) {
            Filter f = filters.getFilter(i);
            if (f != null) {
                f.filter(eligibleBeans);
            }
        }
        resolvedBeans = new HashSet<IBean>(injectionPoint.getCDIProject().getBeans(true, injectionPoint));
    }

    String computeTitle() {
        StringBuffer result = new StringBuffer();
        result.append("@Inject ");

        if (injectionPoint instanceof IInjectionPointParameter) {
            IMethod m = ((IInjectionPointParameter) injectionPoint).getBeanMethod().getMethod();
            result.append(m.getElementName()).append("(");
        }
        for (IQualifierDeclaration d : injectionPoint.getQualifierDeclarations()) {
            result.append("@").append(d.getType().getElementName()).append(" ");
        }

        IParametedType type = injectionPoint.getMemberType();
        result.append(type.getType().getElementName()).append(" ");

        if (injectionPoint instanceof IInjectionPointParameter) {
            result.append(((IInjectionPointParameter) injectionPoint).getName());
            result.append(")");
        } else {
            result.append(injectionPoint.getSourceMember().getElementName());
        }

        return result.toString();
    }

    protected void buttonPressed(int buttonId) {
        if (buttonId == IDialogConstants.CLOSE_ID) {
            // TitleAreaDialog
            //         cancelPressed();
        }
    }

    @Override
    protected Control createTitleMenuArea(Composite parent) {
        Composite fViewMenuButtonComposite = (Composite) super.createTitleMenuArea(parent);
        fFilterText = createFilterText(parent);
        return fViewMenuButtonComposite;
    }

    @Override
    protected void configureShell(Shell newShell) {
        super.configureShell(newShell);
        newShell.setText(CDIExtensionsMessages.ASSIGNABLE_BEANS_DIALOG_TITLE);
    }

    @Override
    protected Control createDialogArea(Composite parent) {
        composite = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout(2, false);
        layout.marginHeight = 0;
        layout.marginWidth = 0;
        layout.verticalSpacing = 0;
        layout.horizontalSpacing = 0;
        composite.setLayout(layout);
        composite.setLayoutData(new GridData(GridData.FILL_BOTH));
        composite.setFont(parent.getFont());
        // TitleAreaDialog
        //      setTitle(computeTitle());
        // PopupDialog
        setTitleText(computeTitle());
        createListView(composite);
        if (showHideOptions) {
            createFilterView(composite);
        }
        installFilter();
        return composite;
    }

    protected void createButtonsForButtonBar(Composite parent) {
        // TitleAreaDialog
        //      createButton(parent, IDialogConstants.CLOSE_ID, IDialogConstants.CLOSE_LABEL, true);
    }

    void createListView(Composite parent) {
        list = new TableViewer(parent, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER/* | SWT.VIRTUAL*/);
        GridData g = new GridData(GridData.FILL_BOTH);
        list.getControl().setLayoutData(g);
        list.setContentProvider(new ListContent());
        list.setLabelProvider(new LP());
        list.setInput(injectionPoint);
        list.addOpenListener(new IOpenListener() {
            @Override
            public void open(OpenEvent event) {
                ISelection s = event.getSelection();
                if (!s.isEmpty() && s instanceof IStructuredSelection) {
                    Object o = ((IStructuredSelection) s).getFirstElement();
                    if (o instanceof IBean) {
                        ((IBean) o).open();
                        close();
                    }
                }
            }
        });

        // PopupDialog
        list.getTable().addMouseMoveListener(new MouseMoveListener() {
            @Override
            public void mouseMove(MouseEvent e) {
                ViewerCell cell = list.getCell(new Point(e.x, e.y));
                if (cell != null) {
                    Widget w = cell.getItem();
                    if (w != null && w.getData() != null) {
                        list.setSelection(new StructuredSelection(w.getData()));
                    }
                }
                list.getTable().setCursor(
                        cell == null ? null : list.getTable().getDisplay().getSystemCursor(SWT.CURSOR_HAND));
            }
        });
        list.getTable().addMouseListener(new MouseAdapter() {
            @Override
            public void mouseUp(MouseEvent e) {
                gotoSelectedElement();
            }
        });

        list.refresh();
    }

    protected void gotoSelectedElement() {
        ISelection s = list.getSelection();
        if (!s.isEmpty() && s instanceof IStructuredSelection) {
            IBean b = (IBean) ((IStructuredSelection) s).getFirstElement();
            b.open();
            close();
        }
    }

    void createFilterView(Composite parent) {
        Group g = filterPanel = new Group(parent, 0);
        g.setBackground(parent.getBackground());
        g.setText("Show/Hide");
        g.setLayoutData(new GridData(GridData.FILL_VERTICAL | GridData.VERTICAL_ALIGN_BEGINNING));
        g.setLayout(new GridLayout(1, false));
        filterView = new CheckboxTreeViewer(g, 0);
        filterView.setAutoExpandLevel(3);
        filterView.setContentProvider(checkboxContentProvider);
        filterView.setInput(filters.getRoot());
        for (Checkbox c : filters.getAllOptions().values()) {
            filterView.setChecked(c, true);
        }
        filterView.getControl().setBackground(g.getBackground());
        g.setData(new GridData(GridData.FILL_BOTH));
        filterView.addCheckStateListener(new ICheckStateListener() {
            @Override
            public void checkStateChanged(CheckStateChangedEvent event) {
                ((Checkbox) event.getElement()).state = event.getChecked();
                filterView.refresh();
                list.refresh();
            }
        });
        filterView.setCheckStateProvider(new ICheckStateProvider() {
            @Override
            public boolean isGrayed(Object element) {
                Checkbox c = (Checkbox) element;
                return c.parent != null && !c.parent.state;
            }

            @Override
            public boolean isChecked(Object element) {
                Checkbox c = (Checkbox) element;
                return c.state;
            }
        });
    }

    @Override
    protected Control getFocusControl() {
        return getFilterText();
    }

    protected Text getFilterText() {
        return fFilterText;
    }

    protected Text createFilterText(Composite parent) {
        fFilterText = new Text(parent, SWT.NONE);
        Dialog.applyDialogFont(fFilterText);

        GridData data = new GridData(GridData.FILL_HORIZONTAL);
        data.horizontalAlignment = GridData.FILL;
        data.verticalAlignment = GridData.CENTER;
        fFilterText.setLayoutData(data);

        fFilterText.addKeyListener(new KeyListener() {
            @Override
            public void keyPressed(KeyEvent e) {
                if (e.keyCode == 0x0D) // return
                    gotoSelectedElement();
                if (e.keyCode == SWT.ARROW_DOWN)
                    list.getTable().setFocus();
                if (e.keyCode == SWT.ARROW_UP)
                    list.getTable().setFocus();
                if (e.character == 0x1B) // ESC
                    close();
            }

            @Override
            public void keyReleased(KeyEvent e) {
                // do nothing
            }
        });
        return fFilterText;
    }

    private void installFilter() {
        fFilterText.setText(""); //$NON-NLS-1$

        fFilterText.addModifyListener(new ModifyListener() {
            @Override
            public void modifyText(ModifyEvent e) {
                list.refresh();
            }
        });
    }

    protected String getId() {
        return AssignableBeansDialog.class.getName();
    }

    @Override
    protected Point getDefaultSize() {
        return new Point(700, 400);
    }

    @Override
    protected Point getDefaultLocation(Point size) {
        Display display = Display.getCurrent();
        if (display == null) {
            display = Display.getDefault();
        }
        if (display.getActiveShell() == null) {
            return super.getDefaultLocation(size);
        }
        Rectangle b = display.getActiveShell().getBounds();
        int x = b.x + (b.width - size.x) / 2;
        int y = b.y + (b.height - size.y) / 2;
        return new Point(x, y);
    }

    // PopupDialog
    @Override
    protected void fillDialogMenu(IMenuManager dialogMenu) {
        super.fillDialogMenu(dialogMenu);
        dialogMenu.add(new ShowHideAction());
    }

    @Override
    protected IDialogSettings getDialogSettings() {
        IDialogSettings settings = CDIExtensionsPlugin.getDefault().getDialogSettings().getSection(getId());
        if (settings == null && filters != null && injectionPoint != null) {
            settings = CDIExtensionsPlugin.getDefault().getDialogSettings().addNewSection(getId());
            settings.put(SHOW_HIDE_PANEL, true);
            for (Checkbox c : filters.getAllOptions().values()) {
                settings.put(FILTER_OPTION + c.id, "" + c.state);
            }
        }
        return settings;
    }

    @Override
    public boolean close() {
        saveFilterOptions();
        return super.close();
    }

    private static final String SHOW_HIDE_PANEL = "SHOW_HIDE_PANEL";
    private static final String FILTER_OPTION = "FILTER_OPTION_";

    private void saveFilterOptions() {
        IDialogSettings settings = getDialogSettings();
        settings.put(SHOW_HIDE_PANEL, showHideOptions);
        for (Checkbox c : filters.getAllOptions().values()) {
            settings.put(FILTER_OPTION + c.id, "" + c.state);
        }
    }

    public List<IBean> getDisplayedBeans() {
        List<IBean> bs = new ArrayList<IBean>();
        int index = 0;
        while (true) {
            Object o = list.getElementAt(index);
            if (o instanceof IBean) {
                bs.add((IBean) o);
            } else {
                break;
            }
            index++;
        }
        return bs;
    }

    public boolean isFilterEnabled(int index) {
        Checkbox c = filters.getOption(index);
        return c != null && c.state;
    }

    public void setFilterEnabled(int index, boolean value) {
        Checkbox c = filters.getOption(index);
        if (c == null)
            return;
        c.state = value;
        filterView.refresh();
        //      filterView.setChecked(AssignableBeanFilters.ALL_OPTIONS[index], value);
        list.refresh();
    }

    public Collection<Checkbox> getOptions() {
        return filters.getAllOptions().values();
    }

    class ShowHideAction extends Action {
        public ShowHideAction() {
            super("Show/Hide panel", Action.AS_CHECK_BOX);
            setChecked(showHideOptions);
        }

        @Override
        public void run() {
            setFiltersEnabled(isChecked());
        }
    }

    protected void setFiltersEnabled(boolean enabled) {
        if (enabled != showHideOptions) {
            showHideOptions = enabled;
            if (!enabled && filterPanel != null) {
                filterPanel.dispose();
                filterPanel = null;
                filterView = null;
            } else if (enabled && filterPanel == null) {
                createFilterView(composite);
            }
            composite.update();
            composite.layout(true);
        }
    }

    static CheckboxContentProvider checkboxContentProvider = new CheckboxContentProvider();

    static class CheckboxContentProvider implements ITreeContentProvider {

        @Override
        public void dispose() {
        }

        @Override
        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
        }

        @Override
        public Object[] getElements(Object inputElement) {
            return getChildren(inputElement);
        }

        @Override
        public Object[] getChildren(Object parentElement) {
            return ((Checkbox) parentElement).children.toArray(new Checkbox[0]);
        }

        @Override
        public Object getParent(Object element) {
            return ((Checkbox) element).parent;
        }

        @Override
        public boolean hasChildren(Object element) {
            return !((Checkbox) element).children.isEmpty();
        }
    }

    TextFilter textFilter = new TextFilter();

    class TextFilter implements Filter {
        SearchPattern patternMatcher = new SearchPattern();

        @Override
        public void filter(Set<IBean> beans) {
            if (fFilterText != null && !fFilterText.isDisposed()) {
                String text = fFilterText.getText();
                if (text.length() > 0) {
                    patternMatcher.setPattern(text);
                    Iterator<IBean> it = beans.iterator();
                    while (it.hasNext()) {
                        IBean bean = it.next();
                        if (!patternMatcher.matches(bean.getElementName())) {
                            it.remove();
                        }
                    }
                }
            }
        }
    }

    class ListContent implements IStructuredContentProvider {

        @Override
        public void dispose() {
        }

        @Override
        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
        }

        @Override
        public Object[] getElements(Object inputElement) {
            Set<IBean> bs = new HashSet<IBean>(beans);
            Set<String> keys = new HashSet<String>();
            LP p = new LP();
            filters.getRoot().filter(bs);
            textFilter.filter(bs);
            Map<String, IBean> map = new TreeMap<String, IBean>();
            for (IBean b : bs) {
                if (resolvedBeans.contains(b)) {
                    String key = p.getText(b);
                    if (!keys.contains(key)) {
                        map.put(key, b);
                        keys.add(key);
                    }
                }
            }
            List<IBean> sorted = new ArrayList<IBean>();
            sorted.addAll(map.values());
            bs.removeAll(map.values());
            map.clear();

            for (IBean b : bs) {
                if (eligibleBeans.contains(b)) {
                    String key = p.getText(b);
                    if (!keys.contains(key)) {
                        map.put(key, b);
                        keys.add(key);
                    }
                }
            }
            sorted.addAll(map.values());
            bs.removeAll(map.values());
            map.clear();

            for (IBean b : bs) {
                String key = p.getText(b);
                if (!keys.contains(key)) {
                    map.put(key, b);
                    keys.add(key);
                }
            }
            sorted.addAll(map.values());

            return sorted.toArray(new IBean[0]);
        }
    }

    static Color gray = new Color(null, 128, 128, 128);
    static Color black = Display.getDefault().getSystemColor(SWT.COLOR_INFO_FOREGROUND);

    static Styler RESOLVED_NAME = new DefaultStyler(black, true, false);
    static Styler ELIGIBLE_NAME = new DefaultStyler(black, false, false);
    static Styler ELIGIBLE_QUALIFIER = new DefaultStyler(gray, false, false);
    static Styler DISABLED = new DefaultStyler(gray, false, false);

    private static class DefaultStyler extends Styler {
        private Color foreground;
        private boolean bold;
        private boolean italic;

        public DefaultStyler(Color foreground, boolean bold, boolean italic) {
            this.foreground = foreground;
            this.italic = italic;
            this.bold = bold;
        }

        @Override
        public void applyStyles(TextStyle textStyle) {
            if (foreground != null) {
                textStyle.foreground = foreground;
            }
            if (italic) {
                textStyle.font = JFaceResources.getFontRegistry().getItalic(JFaceResources.DEFAULT_FONT);
            }
            if (bold) {
                textStyle.font = JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT);
            }
        }
    }

    class LP extends StyledCellLabelProvider implements DelegatingStyledCellLabelProvider.IStyledLabelProvider {
        @Override
        public void update(ViewerCell cell) {
            ELIGIBLE_QUALIFIER = DISABLED;
            Object element = cell.getElement();
            StyledString styledString = getStyledText(element);
            cell.setText(styledString.getString());
            cell.setStyleRanges(styledString.getStyleRanges());
            cell.setImage(getImage(element));

            super.update(cell);
        }

        public String getText(Object element) {
            return getStyledText(element).getString();
        }

        @Override
        public StyledString getStyledText(Object element) {
            IBean b = (IBean) element;
            RESOLVED_NAME = new DefaultStyler(black, true, false);
            Styler nameStyler = resolvedBeans.contains(b) ? RESOLVED_NAME
                    : eligibleBeans.contains(b) ? ELIGIBLE_NAME : DISABLED;
            StyledString sb = new StyledString();

            //1.bean kind
            String kind = BeanPresentationUtil.getBeanKind(b);
            if (kind != null) {
                sb.append(kind, nameStyler).append(' ');
            }
            //2. bean element name
            sb.append(b.getElementName(), nameStyler);

            //3. bean location
            Styler qualifierStyler = eligibleBeans.contains(b) ? ELIGIBLE_QUALIFIER : DISABLED;
            sb.append(BeanPresentationUtil.getBeanLocation(b, false), qualifierStyler);
            return sb;
        }

        @Override
        public Image getImage(Object element) {
            return CDIImages.getImageByElement((ICDIElement) element);
        }
    }
}