Package org.springframework.ide.eclipse.beans.ui.dialogs

Source Code of org.springframework.ide.eclipse.beans.ui.dialogs.BeanListSelectionDialog$BeanFilter

/*******************************************************************************
* Copyright (c) 2006, 2010 Spring IDE Developers
* All rights reserved. This program and the accompanying materials
* are 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:
*     Spring IDE Developers - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.beans.ui.dialogs;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.search.SearchPattern;
import org.eclipse.jface.dialogs.DialogSettings;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableContext;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.IOpenListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.OpenEvent;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.custom.ViewForm;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.SelectionStatusDialog;
import org.eclipse.ui.internal.misc.StringMatcher;
import org.springframework.ide.eclipse.beans.core.BeansCorePlugin;
import org.springframework.ide.eclipse.beans.core.internal.model.BeansModelUtils;
import org.springframework.ide.eclipse.beans.core.model.IBean;
import org.springframework.ide.eclipse.beans.core.model.IBeansModel;
import org.springframework.ide.eclipse.beans.ui.BeansUIActivationHistory;
import org.springframework.ide.eclipse.beans.ui.BeansUIPlugin;
import org.springframework.ide.eclipse.beans.ui.model.BeansModelLabelProvider;
import org.springframework.util.StringUtils;

/**
* Spring Bean selection dialog.
* @author Christian Dupuis
* @author Torsten Juergeleit
*/
@SuppressWarnings("restriction")
public class BeanListSelectionDialog extends SelectionStatusDialog {

  /**
   * Implements a {@link ViewFilter} based on content typed in the filter field
   */
  private static class BeanFilter extends ViewerFilter {

    private StringMatcher matcher;

    private boolean isUpperCasePattern;

    private String filterText;

    private List<IBean> beanActivationHistory;

    protected BeanFilter(List<IBean> historyBeans) {
      this.beanActivationHistory = historyBeans;
    }

    @Override
    public boolean select(Viewer viewer, Object parentElement, Object element) {
      if (matcher == null) {
        return beanActivationHistory.contains(element);
      }
      if (element instanceof IBean) {
        IBean bean = (IBean) element;
        if (matcher.match(bean.getElementName())) {
          return true;
        }
        if (matcher.match(bean.getClassName())) {
          return true;
        }
        String[] aliases = bean.getAliases();
        if (aliases != null) {
          for (String alias : aliases) {
            if (matcher.match(alias)) {
              return true;
            }
          }
        }
        if (isUpperCasePattern) {
          if (SearchPattern.camelCaseMatch(filterText, StringUtils.capitalize(bean.getElementName()))) {
            return true;
          }
          String className = bean.getClassName();
          if (className != null) {
            int i = className.lastIndexOf('.');
            if (i > 0 && i < className.length()) {
              if (SearchPattern.camelCaseMatch(filterText, 0, filterText.length(), className, i + 1,
                  className.length())) {
                return true;
              }
            }
            else {
              if (SearchPattern.camelCaseMatch(filterText, className)) {
                return true;
              }
            }
          }
        }
      }
      return false;
    }

    public void setFilterText(String filterText) {
      if (filterText.trim().equals("")) {
        this.matcher = null;
        this.isUpperCasePattern = false;
        this.filterText = null;
      }
      else {
        this.matcher = new StringMatcher(filterText + '*', true, false);
        this.isUpperCasePattern = true;
        for (char c : filterText.toCharArray()) {
          if (Character.isLowerCase(c)) {
            this.isUpperCasePattern = false;
            break;
          }
        }
        this.filterText = filterText;
      }
    }
  }

  private static final String DIALOG_SETTINGS = BeanListSelectionDialog.class.getName();

  private static final String HEIGHT = "height";

  private static final String WIDTH = "width";

  private int fHeight = 18;

  private CLabel fLabel;

  private Point fLocation;

  private IDialogSettings fSettings;

  private Point fSize;

  private int fWidth = 60;

  private final LabelProvider labelProvider = new BeansModelLabelProvider(true);

  private TableViewer viewer;

  public BeanListSelectionDialog(Shell parent) {
    super(parent);
    setTitle(BeansUIPlugin.getResourceString("BeanListSelectionDialog.title"));
    setStatusLineAboveButtons(true);
    setShellStyle(getShellStyle() | SWT.RESIZE);
    setBlockOnOpen(true);

    IDialogSettings settings = BeansUIPlugin.getDefault().getDialogSettings();
    fSettings = settings.getSection(DIALOG_SETTINGS);
    if (fSettings == null) {
      fSettings = new DialogSettings(DIALOG_SETTINGS);
      settings.addSection(fSettings);
      fSettings.put(WIDTH, 480);
      fSettings.put(HEIGHT, 320);
    }
  }

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

  @Override
  protected void computeResult() {
    setResult(((IStructuredSelection) viewer.getSelection()).toList());
  }

  @Override
  protected Control createDialogArea(Composite parent) {
    readSettings();
    Composite area = (Composite) super.createDialogArea(parent);

    Label message = new Label(area, SWT.NONE);
    message.setText(BeansUIPlugin.getResourceString("BeanListSelectionDialog.message"));
    final Text filterText = new Text(area, SWT.SINGLE | SWT.BORDER);
    filterText.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false));

    Label matches = new Label(area, SWT.NONE);
    matches.setText("&Matching beans:");
    viewer = new TableViewer(area, SWT.SINGLE | SWT.BORDER);
    Control control = viewer.getControl();
    GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
    gd.widthHint = convertWidthInCharsToPixels(fWidth);
    gd.heightHint = convertHeightInCharsToPixels(fHeight);
    gd.grabExcessVerticalSpace = true;
    gd.grabExcessHorizontalSpace = true;
    gd.horizontalAlignment = GridData.FILL;
    gd.verticalAlignment = GridData.FILL;
    control.setLayoutData(gd);

    viewer.setLabelProvider(labelProvider);
    viewer.setContentProvider(new ArrayContentProvider());

    final Set<IBean> beanList = new LinkedHashSet<IBean>();
    final List<IBean> historyList = new ArrayList<IBean>();
    final List<IBean> historyBeans = new ArrayList<IBean>();
    IRunnableWithProgress runnable = new IRunnableWithProgress() {
      public void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
        try {

          historyBeans.addAll(BeansUIActivationHistory.getBeanActivationHistory());
          Collections.reverse(historyBeans);
          historyList.addAll(historyBeans);

          Set<IBean> beans = new HashSet<IBean>();
          IBeansModel beansModel = BeansCorePlugin.getModel();
          beans.addAll(BeansModelUtils.getBeans(beansModel, monitor));

          beanList.addAll(historyBeans);
          beanList.addAll(beans);
        }
        catch (OperationCanceledException e) {
          throw new InterruptedException();
        }
      }
    };

    try {
      IRunnableContext context = new ProgressMonitorDialog(getShell());
      context.run(true, true, runnable);
    }
    catch (InvocationTargetException e) {
    }
    catch (InterruptedException e) {
    }

    viewer.setInput(beanList);

    final BeanListSelectionDialog.BeanFilter filter = new BeanListSelectionDialog.BeanFilter(historyBeans);
    viewer.addFilter(filter);
    viewer.setComparator(new ViewerComparator() {

      @Override
      public int compare(Viewer viewer, Object e1, Object e2) {
        IBean t1 = getCorrespondingTask(e1);
        IBean t2 = getCorrespondingTask(e2);
        boolean isInHistory1 = historyList.contains(t1);
        boolean isInHistory2 = historyList.contains(t2);

        // Being on task history takes precedence...
        if (isInHistory1 && !isInHistory2) {
          return -1;
        }
        if (!isInHistory1 && isInHistory2) {
          return 1;
        }

        // Both are in task history; who is more recent?
        if (isInHistory1 && isInHistory2) {
          return historyList.indexOf(t1) - historyList.indexOf(t2);
        }

        // Both are not in task history; sort by summary...
        return labelProvider.getText(e1).compareTo(labelProvider.getText(e2));
      }

      private IBean getCorrespondingTask(Object o) {
        if (o instanceof IBean) {
          return (IBean) o;
        }
        return null;
      }

    });
    viewer.addSelectionChangedListener(new ISelectionChangedListener() {

      public void selectionChanged(SelectionChangedEvent event) {
        handleSelectionChanged();
      }
    });

    viewer.addOpenListener(new IOpenListener() {

      public void open(OpenEvent event) {
        if (getOkButton().getEnabled()) {
          okPressed();
        }
      }

    });

    filterText.addKeyListener(new KeyAdapter() {

      @Override
      public void keyPressed(KeyEvent e) {
        if (e.keyCode == SWT.ARROW_DOWN) {
          viewer.getControl().setFocus();
        }
      }

    });
    filterText.addModifyListener(new ModifyListener() {

      public void modifyText(ModifyEvent e) {
        filter.setFilterText(filterText.getText());
        viewer.refresh(false);
        Object first = viewer.getElementAt(0);
        if (first != null) {
          viewer.setSelection(new StructuredSelection(first));
        }
      }

    });

    ViewForm fForm = new ViewForm(area, SWT.BORDER | SWT.FLAT);
    gd = new GridData(GridData.FILL_HORIZONTAL);
    gd.horizontalSpan = 2;
    fForm.setLayoutData(gd);
    fLabel = new CLabel(fForm, SWT.FLAT);
    fLabel.setFont(fForm.getFont());
    fForm.setContent(fLabel);

    IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
    ISelection selection = window.getSelectionService().getSelection();
    if (selection instanceof ITextSelection) {
      String text = ((ITextSelection) selection).getText();
      int n = text.indexOf('\n');
      if (n > -1) {
        text = text.substring(0, n);
      }
      filterText.setText(text);
      filterText.setSelection(0, text.length());
    }

    return area;
  }

  @Override
  protected Point getInitialLocation(Point initialSize) {
    Point result = super.getInitialLocation(initialSize);
    if (fLocation != null) {
      result.x = fLocation.x;
      result.y = fLocation.y;
      Rectangle display = getShell().getDisplay().getClientArea();
      int xe = result.x + initialSize.x;
      if (xe > display.width) {
        result.x -= xe - display.width;
      }
      int ye = result.y + initialSize.y;
      if (ye > display.height) {
        result.y -= ye - display.height;
      }
    }
    return result;
  }

  @Override
  protected Point getInitialSize() {
    Point result = super.getInitialSize();
    if (fSize != null) {
      result.x = Math.max(result.x, fSize.x);
      result.y = Math.max(result.y, fSize.y);
      Rectangle display = getShell().getDisplay().getClientArea();
      result.x = Math.min(result.x, display.width);
      result.y = Math.min(result.y, display.height);
    }
    return result;
  }

  /**
   * Handles a selection changed event:
   * <ol>
   * <li>validate the current selection
   * <li>if an element is selected then show the element's resource (full path and icon)
   * </ol>
   */
  protected void handleSelectionChanged() {
    validateCurrentSelection();
    if (!viewer.getSelection().isEmpty()) {
      ISelection sel = viewer.getSelection();
      if (sel instanceof IStructuredSelection) {
        IBean bean = (IBean) ((IStructuredSelection) sel).getFirstElement();
        fLabel.setImage(labelProvider.getImage(bean.getElementParent()));
        fLabel.setText(bean.getElementResource().getFullPath().toString().substring(1));
      }
    }
    else {
      fLabel.setImage(null);
      fLabel.setText(null);
    }
  }

  /**
   * Initializes itself from the dialog settings with the same state as at the previous invocation.
   */
  private void readSettings() {
    try {
      int x = fSettings.getInt("x");
      int y = fSettings.getInt("y");
      fLocation = new Point(x, y);
    }
    catch (NumberFormatException e) {
      fLocation = null;
    }
    try {
      int width = fSettings.getInt("width");
      int height = fSettings.getInt("height");
      fSize = new Point(width, height);

    }
    catch (NumberFormatException e) {
      fSize = null;
    }
  }

  /**
   * Validates the current selection and updates the status line accordingly.
   * @return boolean <code>true</code> if the current selection is valid.
   */
  protected boolean validateCurrentSelection() {
    IStatus status;
    if (viewer.getSelection().isEmpty()) {
      status = new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, IStatus.ERROR, "", null);
    }
    else {
      status = new Status(IStatus.OK, PlatformUI.PLUGIN_ID, IStatus.OK, "", //$NON-NLS-1$
          null);
    }

    updateStatus(status);
    return status.isOK();
  }

  /**
   * Stores it current configuration in the dialog store.
   */
  private void writeSettings() {
    Point location = getShell().getLocation();
    fSettings.put("x", location.x);
    fSettings.put("y", location.y);

    Point size = getShell().getSize();
    fSettings.put("width", size.x);
    fSettings.put("height", size.y);
  }
}
TOP

Related Classes of org.springframework.ide.eclipse.beans.ui.dialogs.BeanListSelectionDialog$BeanFilter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.