Skip to main content
aboutsummaryrefslogblamecommitdiffstats
blob: f93359d9d20b00ff6399c8442244e230869be484 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11










                                                                                 
                                                 


                             
                               


                     
                                             



                                                 
                                                                   











                                                           







                                                            
                                                 
                                                    







                                             



                                         






                                         
                                   






















                                                           










                                                                             


                

                                                                                              


                

                                                                                              


                





























































                                                                                          






                                                      














                                                                                                           

















































                                                                                                                                                    



























































                                                                                                         
                                                                  




                                                                                                          
                                                                    











                                                             
                                                         

                                                                                             
                                                    
































                                                                      


                                                                                        













                                                                                                                   
                                                                                                                                                 













                                                                                                                         



































































































































































                                                                                                                                                                                                                   
/*******************************************************************************
 * Copyright (c) 2008-2010 Sonatype, Inc.
 * 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:
 *      Sonatype, Inc. - initial API and implementation
 *******************************************************************************/

package org.eclipse.m2e.core.ui.internal.wizards;

import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

import org.apache.lucene.search.BooleanQuery;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider;
import org.eclipse.jface.viewers.IColorProvider;
import org.eclipse.jface.viewers.IDecoration;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.m2e.core.MavenPlugin;
import org.eclipse.m2e.core.core.IMavenConstants;
import org.eclipse.m2e.core.embedder.ArtifactKey;
import org.eclipse.m2e.core.index.IIndex;
import org.eclipse.m2e.core.index.IndexManager;
import org.eclipse.m2e.core.index.IndexedArtifact;
import org.eclipse.m2e.core.index.IndexedArtifactFile;
import org.eclipse.m2e.core.index.UserInputSearchExpression;
import org.eclipse.m2e.core.ui.internal.Messages;
import org.eclipse.m2e.core.ui.internal.MavenImages;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
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.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;

import com.ibm.icu.text.DateFormat;


/**
 * MavenPomSelectionComposite
 * 
 * @author Eugene Kuleshov
 */
public class MavenPomSelectionComponent extends Composite {

  /* (non-Javadoc)
   * @see org.eclipse.swt.widgets.Widget#dispose()
   */
  public void dispose() {
    if(searchJob != null) {
      searchJob.cancel();
    }
    super.dispose();
  }

  Text searchText = null;

  TreeViewer searchResultViewer = null;

  /**
   * One of {@link IIndex#SEARCH_ARTIFACT}, {@link IIndex#SEARCH_CLASS_NAME},
   */
  String queryType;

  SearchJob searchJob;

  private IStatus status;

  private ISelectionChangedListener selectionListener;

  /**
   * @deprecated
   */
  public static final String P_SEARCH_INCLUDE_JAVADOC = "searchIncludesJavadoc"; //$NON-NLS-1$

  /**
   * @deprecated
   */
  public static final String P_SEARCH_INCLUDE_SOURCES = "searchIncludesSources"; //$NON-NLS-1$

  /**
   * @deprecated
   */
  public static final String P_SEARCH_INCLUDE_TESTS = "searchIncludesTests"; //$NON-NLS-1$

  private static final long SHORT_DELAY = 150L;

  private static final long LONG_DELAY = 500L;
  
  final HashSet<String> artifactKeys = new HashSet<String>();
  final HashSet<String> managedKeys = new HashSet<String>();

  public MavenPomSelectionComponent(Composite parent, int style) {
    super(parent, style);
    createSearchComposite();
  }

  private void createSearchComposite() {
    GridLayout gridLayout = new GridLayout(2, false);
    gridLayout.marginWidth = 0;
    gridLayout.marginHeight = 0;
    setLayout(gridLayout);

    Label searchTextlabel = new Label(this, SWT.NONE);
    searchTextlabel.setText(Messages.MavenPomSelectionComponent_search_title);
    searchTextlabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));

    searchText = new Text(this, SWT.BORDER | SWT.SEARCH);
    searchText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 2, 1));
    searchText.addKeyListener(new KeyAdapter() {
      public void keyPressed(KeyEvent e) {
        if(e.keyCode == SWT.ARROW_DOWN) {
          searchResultViewer.getTree().setFocus();
          selectFirstElementInTheArtifactTreeIfNoSelectionHasBeenMade();
        }
      }
    });

    searchText.addModifyListener(new ModifyListener() {
      public void modifyText(ModifyEvent e) {
        scheduleSearch(searchText.getText(), true);
      }
    });

    Label searchResultsLabel = new Label(this, SWT.NONE);
    searchResultsLabel.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 2, 1));
    searchResultsLabel.setText(Messages.MavenPomSelectionComponent_lblResults);

    Tree tree = new Tree(this, SWT.BORDER | SWT.SINGLE);
    tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
    tree.setData("name", "searchResultTree"); //$NON-NLS-1$ //$NON-NLS-2$
    tree.addFocusListener(new FocusListener() {

      public void focusGained(FocusEvent e) {
        selectFirstElementInTheArtifactTreeIfNoSelectionHasBeenMade();
      }

      public void focusLost(FocusEvent e) {

      }
    });

    searchResultViewer = new TreeViewer(tree);
  }

  /* (non-Javadoc)
   * @see org.eclipse.swt.widgets.Composite#setFocus()
   */
  public boolean setFocus() {
    return searchText.setFocus();
  }

  void selectFirstElementInTheArtifactTreeIfNoSelectionHasBeenMade() {
    //
    // If we have started a new search when focus is passed to the tree viewer we will automatically select
    // the first element if no element has been selected from a previous expedition into the tree viewer.
    //
    if(searchResultViewer.getTree().getItemCount() > 0 && searchResultViewer.getSelection().isEmpty()) {
      Object artifact = searchResultViewer.getTree().getTopItem().getData();
      searchResultViewer.setSelection(new StructuredSelection(artifact), true);
    }
  }

  protected boolean showClassifiers() {
    return (queryType != null && IIndex.SEARCH_ARTIFACT.equals(queryType));
  }


  public void init(String queryText, String queryType, Set<ArtifactKey> artifacts, Set<ArtifactKey> managed) {
    this.queryType = queryType;

    if(queryText != null) {
      searchText.setText(queryText);
    }

    if(artifacts != null) {
      for(ArtifactKey a : artifacts) {
        artifactKeys.add(a.getGroupId() + ":" + a.getArtifactId()); //$NON-NLS-1$
        artifactKeys.add(a.getGroupId() + ":" + a.getArtifactId() + ":" + a.getVersion()); //$NON-NLS-1$ //$NON-NLS-2$
      }
    }
    if (managed != null) {
      for (ArtifactKey a : managed) {
        managedKeys.add(a.getGroupId() + ":" + a.getArtifactId()); //$NON-NLS-1$
        managedKeys.add(a.getGroupId() + ":" + a.getArtifactId() + ":" + a.getVersion()); //$NON-NLS-1$ //$NON-NLS-2$
      }
    }
    
    searchResultViewer.setContentProvider(new SearchResultContentProvider());
    searchResultViewer.setLabelProvider(new DelegatingStyledCellLabelProvider(new SearchResultLabelProvider(artifactKeys, managedKeys, queryType)));
    searchResultViewer.addSelectionChangedListener(new ISelectionChangedListener() {
      public void selectionChanged(SelectionChangedEvent event) {
        IStructuredSelection selection = (IStructuredSelection) event.getSelection();
        if(!selection.isEmpty()) {
          if(selection.size() == 1) {
            IndexedArtifactFile f = getSelectedIndexedArtifactFile(selection.getFirstElement());
            // int severity = artifactKeys.contains(f.group + ":" + f.artifact) ? IStatus.ERROR : IStatus.OK;
            int severity = IStatus.OK;
            String date = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT).format(f.date);
            setStatus(
                severity,
                NLS.bind(Messages.MavenPomSelectionComponent_detail1, f.fname,
                    (f.size != -1 ? NLS.bind(Messages.MavenPomSelectionComponent_details2, date, f.size) : date)));
          } else {
            setStatus(IStatus.OK, NLS.bind(Messages.MavenPomSelectionComponent_selected, selection.size()));
          }
        } else {
          setStatus(IStatus.ERROR, Messages.MavenPomSelectionComponent_nosel);
        }
      }
    });
    setupClassifiers();
    setStatus(IStatus.ERROR, ""); //$NON-NLS-1$
    scheduleSearch(queryText, false);
  }

  protected void setupClassifiers() {
  }

  public IStatus getStatus() {
    return this.status;
  }

  public void addDoubleClickListener(IDoubleClickListener listener) {
    searchResultViewer.addDoubleClickListener(listener);
  }

  public void addSelectionChangedListener(ISelectionChangedListener listener) {
    this.selectionListener = listener;
  }

  void setStatus(int severity, String message) {
    this.status = new Status(severity, IMavenConstants.PLUGIN_ID, 0, message, null);
    if(selectionListener != null) {
      selectionListener.selectionChanged(new SelectionChangedEvent(searchResultViewer, searchResultViewer
          .getSelection()));
    }
  }

  public IndexedArtifact getIndexedArtifact() {
    IStructuredSelection selection = (IStructuredSelection) searchResultViewer.getSelection();
    Object element = selection.getFirstElement();
    if(element instanceof IndexedArtifact) {
      return (IndexedArtifact) element;
    }
    TreeItem[] treeItems = searchResultViewer.getTree().getSelection();
    if(treeItems.length == 0) {
      return null;
    }
    return (IndexedArtifact) treeItems[0].getParentItem().getData();
  }

  public IndexedArtifactFile getIndexedArtifactFile() {
    IStructuredSelection selection = (IStructuredSelection) searchResultViewer.getSelection();
    return getSelectedIndexedArtifactFile(selection.getFirstElement());
  }

  IndexedArtifactFile getSelectedIndexedArtifactFile(Object element) {
    if(element instanceof IndexedArtifact) {
      //the idea here is that if we have a managed version for something, then the IndexedArtifact shall
      //represent that value..
      IndexedArtifact ia = (IndexedArtifact)element;
      if (managedKeys.contains(getKey(ia))) {
        for (IndexedArtifactFile file : ia.getFiles()) {
          if (managedKeys.contains(getKey(file))) {
            return file;
          }
        }
      }
      return ia.getFiles().iterator().next();
    }
    return (IndexedArtifactFile) element;
  }

  void scheduleSearch(String query, boolean delay) {
    if(query != null && query.length() > 2) {
      if(searchJob == null) {
        IndexManager indexManager = MavenPlugin.getIndexManager();
        searchJob = new SearchJob(queryType, indexManager);
      } else {
        if(!searchJob.cancel()) {
          //for already running ones, just create new instance so that the previous one can piecefully die
          //without preventing the new one from completing first
          IndexManager indexManager = MavenPlugin.getIndexManager();
          searchJob = new SearchJob(queryType, indexManager);
        }
      }
      searchJob.setQuery(query.toLowerCase());
      searchJob.schedule(delay ? LONG_DELAY : SHORT_DELAY);
    } else {
      if(searchJob != null) {
        searchJob.cancel();
      }
    }
  }
  
  public static String getKey(IndexedArtifactFile file) {
    return file.group + ":" + file.artifact + ":" + file.version; //$NON-NLS-1$ //$NON-NLS-2$
  }
  public static String getKey(IndexedArtifact art) {
    return art.getGroupId() + ":" + art.getArtifactId(); //$NON-NLS-1$
  }
  

  /**
   * Search Job
   */
  private class SearchJob extends Job {

    private IndexManager indexManager;

    private String query;

    private String field;

    private volatile boolean stop = false;

    public SearchJob(String field, IndexManager indexManager) {
      super(Messages.MavenPomSelectionComponent_searchJob);
      this.field = field;
      this.indexManager = indexManager;
    }

    public void setQuery(String query) {
      this.query = query;
    }

    public boolean shouldRun() {
      stop = false;
      return super.shouldRun();
    }

    public int getClassifier() {
      // mkleint: no more allowing people to opt in/out displaying javadoc and sources..
      // allow tests and every other classifier..
      return IIndex.SEARCH_JARS + IIndex.SEARCH_TESTS;
    }

    protected IStatus run(IProgressMonitor monitor) {
      int classifier = showClassifiers() ? getClassifier() : IIndex.SEARCH_ALL;
      if(searchResultViewer == null || searchResultViewer.getControl() == null
          || searchResultViewer.getControl().isDisposed()) {
        return Status.CANCEL_STATUS;
      }
      if(query != null) {
        String activeQuery = query;
        try {
          setResult(IStatus.OK, NLS.bind(Messages.MavenPomSelectionComponent_searching, activeQuery.toLowerCase()),
              null);

          Map<String, IndexedArtifact> res = indexManager.getAllIndexes().search( new UserInputSearchExpression(activeQuery), field, classifier);
          
          //335139 have the managed entries always come up as first results
          LinkedHashMap<String, IndexedArtifact> managed = new LinkedHashMap<String, IndexedArtifact>();
          LinkedHashMap<String, IndexedArtifact> nonManaged = new LinkedHashMap<String, IndexedArtifact>();
          for (Map.Entry<String, IndexedArtifact> art : res.entrySet()) {
            String key = art.getValue().getGroupId() + ":" + art.getValue().getArtifactId();
            if (managedKeys.contains(key)) {
              managed.put(art.getKey(), art.getValue());
            } else {
              nonManaged.put(art.getKey(), art.getValue());
            }
          }
          managed.putAll(nonManaged);
          setResult(IStatus.OK, NLS.bind(Messages.MavenPomSelectionComponent_results, activeQuery, res.size()), managed);
        } catch(BooleanQuery.TooManyClauses ex) {
          setResult(IStatus.ERROR, Messages.MavenPomSelectionComponent_toomany,
              Collections.<String, IndexedArtifact> emptyMap());
        } catch(final RuntimeException ex) {
          setResult(IStatus.ERROR, NLS.bind(Messages.MavenPomSelectionComponent_error, ex.toString()),
              Collections.<String, IndexedArtifact> emptyMap());
        } catch(final Exception ex) {
          setResult(IStatus.ERROR, NLS.bind(Messages.MavenPomSelectionComponent_error, ex.getMessage()),
              Collections.<String, IndexedArtifact> emptyMap());
        }
      }
      return Status.OK_STATUS;
    }

    protected void canceling() {
      stop = true;
    }

    private void setResult(final int severity, final String message, final Map<String, IndexedArtifact> result) {
      if(stop)
        return;
      Display.getDefault().syncExec(new Runnable() {
        public void run() {
          setStatus(severity, message);
          if(result != null) {
            if(!searchResultViewer.getControl().isDisposed()) {
              searchResultViewer.setInput(result);
            }
          }
        }
      });
    }
  }

  public static class SearchResultLabelProvider extends LabelProvider implements IColorProvider, DelegatingStyledCellLabelProvider.IStyledLabelProvider {
    private final Set<String> artifactKeys;

    private final String queryType;
    private final Set<String> managedKeys;

    /**
     * both managedkeys and artifctkeys are supposed to hold both gr:art:ver combos and gr:art combos
     * @param artifactKeys
     * @param managedKeys
     * @param queryType
     */
    public SearchResultLabelProvider(Set<String> artifactKeys, Set<String> managedKeys, String queryType) {
      this.artifactKeys = artifactKeys;
      this.queryType = queryType;
      this.managedKeys = managedKeys;
    }

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

    protected String getRepoDisplayName(String repo) {
      return repo;
    }

    public Color getForeground(Object element) {
      if(element instanceof IndexedArtifactFile) {
        IndexedArtifactFile f = (IndexedArtifactFile) element;
        if(artifactKeys.contains(getKey(f))) { 
          return Display.getDefault().getSystemColor(SWT.COLOR_DARK_GRAY);
        }
      } else if(element instanceof IndexedArtifact) {
        IndexedArtifact i = (IndexedArtifact) element;
        if(artifactKeys.contains(getKey(i))) {
          return Display.getDefault().getSystemColor(SWT.COLOR_DARK_GRAY);
        }
      }
      return null;
    }

    public Color getBackground(Object element) {
      return null;
    }

    public Image getImage(Object element) {
      if(element instanceof IndexedArtifactFile) {
        IndexedArtifactFile f = (IndexedArtifactFile) element;
        if (managedKeys.contains(getKey(f))) {
          return MavenImages.getOverlayImage(f.sourcesExists==IIndex.PRESENT ? MavenImages.PATH_VERSION_SRC : MavenImages.PATH_VERSION, 
              MavenImages.PATH_LOCK, IDecoration.BOTTOM_LEFT);
        }
        
        if(f.sourcesExists==IIndex.PRESENT) {
          return MavenImages.IMG_VERSION_SRC;
        }
        return MavenImages.IMG_VERSION;
      } else if(element instanceof IndexedArtifact) {
        IndexedArtifact i = (IndexedArtifact) element;
        if (managedKeys.contains(getKey(i))) {
          return MavenImages.getOverlayImage(MavenImages.PATH_JAR, MavenImages.PATH_LOCK, IDecoration.BOTTOM_LEFT);
        }
        return MavenImages.IMG_JAR;
      }
      return null;
    }

    /* (non-Javadoc)
     * @see org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider#getStyledText(java.lang.Object)
     */
    public StyledString getStyledText(Object element) {
      if(element instanceof IndexedArtifact) {
        IndexedArtifact a = (IndexedArtifact) element;
        String name = (a.getClassname() == null ? "" : a.getClassname() + "   " + a.getPackageName() + "   ") + a.getGroupId() + "   " + a.getArtifactId(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
        StyledString ss = new StyledString();
        ss.append(name);
        if (managedKeys.contains(getKey(a))) {
          ss.append(Messages.MavenPomSelectionComponent_managed_decoration, StyledString.DECORATIONS_STYLER);
        }
        return ss;
      } else if(element instanceof IndexedArtifactFile) {
        IndexedArtifactFile f = (IndexedArtifactFile) element;
        StyledString ss = new StyledString();
        String name = f.version + " [" + (f.type == null ? "jar" : f.type) + (f.classifier != null ? ", " + f.classifier : "") +  "]";  //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
        ss.append(name);
        if (managedKeys.contains(getKey(f))) {
          ss.append(Messages.MavenPomSelectionComponent_managed_decoration, StyledString.DECORATIONS_STYLER);
        }
        return ss;
      }
      return new StyledString();
    }

  }

  public static class SearchResultContentProvider implements ITreeContentProvider {
    private static Object[] EMPTY = new Object[0];

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

    public Object[] getElements(Object inputElement) {
      if(inputElement instanceof Map) {
        return ((Map<?, ?>) inputElement).values().toArray();
      }
      return EMPTY;
    }

    public Object[] getChildren(Object parentElement) {
      if(parentElement instanceof IndexedArtifact) {
        IndexedArtifact a = (IndexedArtifact) parentElement;
        return a.getFiles().toArray();
      }
      return EMPTY;
    }

    public boolean hasChildren(Object element) {
      return element instanceof IndexedArtifact;
    }

    public Object getParent(Object element) {
      return null;
    }

    public void dispose() {

    }

  }
}

Back to the top