package org.erlide.ui.internal.search; import java.util.ArrayList; import java.util.List; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.Path; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.search.ui.ISearchQuery; import org.eclipse.search.ui.text.AbstractTextSearchResult; import org.eclipse.search.ui.text.IEditorMatchAdapter; import org.eclipse.search.ui.text.IFileMatchAdapter; import org.eclipse.search.ui.text.Match; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IFileEditorInput; import org.erlide.engine.model.root.IErlModule; import org.erlide.engine.services.search.LimitTo; import org.erlide.engine.util.ResourceUtil; import org.erlide.ui.ErlideImage; import org.erlide.ui.editors.erl.AbstractErlangEditor; import org.erlide.ui.editors.erl.ErlangEditor; public class ErlangSearchResult extends AbstractTextSearchResult implements IEditorMatchAdapter, IFileMatchAdapter { private List<ErlangSearchElement> result; private final ErlSearchQuery query; public ErlangSearchResult(final ErlSearchQuery query) { this.query = query; result = new ArrayList<>(); } @Override public synchronized void removeAll() { result = new ArrayList<>(); super.removeAll(); } @Override public void removeMatch(final Match match) { final Object element = match.getElement(); if (getMatchCount(element) == 1) { removeElement(element); } super.removeMatch(match); } @Override public void removeMatches(final Match[] matches) { for (final Match match : matches) { final Object element = match.getElement(); final int matchCount = getMatchCount(element); if (matchCount == 1) { removeElement(element); } else if (matchCount == countMatches(element, matches)) { removeElement(element); } } super.removeMatches(matches); } private synchronized void removeElement(final Object element) { result.remove(element); } private int countMatches(final Object element, final Match[] matches) { int theResult = 0; for (final Match match : matches) { if (match.getElement().equals(element)) { theResult++; } } return theResult; } @Override public IEditorMatchAdapter getEditorMatchAdapter() { return this; } @Override public IFileMatchAdapter getFileMatchAdapter() { return this; } @Override public ImageDescriptor getImageDescriptor() { // return ErlideUIPluginImages.DESC_EXTERNAL; return ErlideImage.ERLANG_SEARCH_RESULTS.getDescriptor(); } @Override public String getLabel() { final int matchCount = getMatchCount(); final String occurrences = getOccurrencesLabel(matchCount); final String scope = query.getScopeDescription(); return query.getLabel() + " - " + matchCount + " " + occurrences + " in " + scope + "."; } private String getOccurrencesLabel(final int matchCount) { final LimitTo limitTo = query.getPattern().getLimitTo(); switch (limitTo) { case ALL_OCCURRENCES: return matchCount == 1 ? "occurrence" : "occurrences"; case DEFINITIONS: return matchCount == 1 ? "definition" : "definitions"; case REFERENCES: return matchCount == 1 ? "reference" : "references"; } Assert.isTrue(false, "shouldNeverHappen"); //$NON-NLS-1$ return null; } @Override public ISearchQuery getQuery() { return query; } @Override public String getTooltip() { return null; } public synchronized List<ErlangSearchElement> getResult() { return new ArrayList<>(result); } public synchronized void setResult(final List<ErlangSearchElement> result) { this.result = result; } private static final Match[] NO_MATCHES = new Match[0]; @Override public Match[] computeContainedMatches(final AbstractTextSearchResult aResult, final IEditorPart editor) { final IEditorInput editorInput = editor.getEditorInput(); if (editorInput instanceof IFileEditorInput) { final IFileEditorInput fileEditorInput = (IFileEditorInput) editorInput; return computeContainedMatches(aResult, fileEditorInput.getFile()); } return NO_MATCHES; } @Override public boolean isShownInEditor(final Match match, final IEditorPart editor) { final ErlangSearchElement ese = (ErlangSearchElement) match.getElement(); final IFile file = ResourceUtil.getFileFromLocation(ese.getModuleName()); if (editor instanceof ErlangEditor) { final AbstractErlangEditor erlangEditor = (AbstractErlangEditor) editor; final IErlModule module = erlangEditor.getModule(); if (module != null) { if (file != null) { return file.equals(module.getResource()); } return ese.getModuleName().equals(module.getFilePath()); } } return false; } @Override public Match[] computeContainedMatches(final AbstractTextSearchResult aResult, final IFile file) { final ErlangSearchResult esr = (ErlangSearchResult) aResult; final List<Match> l = new ArrayList<>(); final List<ErlangSearchElement> eses = esr.getResult(); final String name = file.getName(); if (eses == null) {// || !ErlideUtil.hasModuleExtension(name)) { return NO_MATCHES; } for (final ErlangSearchElement ese : eses) { final String moduleName = new Path(ese.getModuleName()).lastSegment(); if (moduleName.equals(name)) { final Match[] matches = getMatches(ese); for (final Match match : matches) { l.add(match); } } } return l.toArray(new Match[l.size()]); } @Override public IFile getFile(final Object element) { if (element instanceof ErlangSearchElement) { final ErlangSearchElement ese = (ErlangSearchElement) element; return ResourceUtil.getFileFromLocation(ese.getModuleName()); } return null; } }