package com.redhat.ceylon.eclipse.code.search; import static com.redhat.ceylon.eclipse.ui.CeylonResources.CEYLON_SEARCH_RESULTS; import static java.util.Arrays.asList; import static org.eclipse.jdt.core.IJavaElement.CLASS_FILE; import java.net.URI; import java.util.ArrayList; import java.util.List; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IPath; import org.eclipse.jdt.core.IClassFile; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.internal.ui.javaeditor.IClassFileEditorInput; 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.eclipse.ui.ide.FileStoreEditorInput; import com.redhat.ceylon.compiler.typechecker.io.VirtualFile; import com.redhat.ceylon.eclipse.code.editor.SourceArchiveEditorInput; import com.redhat.ceylon.eclipse.ui.CeylonPlugin; import com.redhat.ceylon.eclipse.util.EditorUtil; public class CeylonSearchResult extends AbstractTextSearchResult implements IEditorMatchAdapter, IFileMatchAdapter { private static final ImageDescriptor IMAGE = CeylonPlugin.imageRegistry() .getDescriptor(CEYLON_SEARCH_RESULTS); ISearchQuery query; CeylonSearchResult(ISearchQuery query) { this.query = query; } @Override public String getTooltip() { return getLabel(); } @Override public ISearchQuery getQuery() { return query; } @Override public String getLabel() { return query.getLabel(); } @Override public ImageDescriptor getImageDescriptor() { return IMAGE; } @Override public IFileMatchAdapter getFileMatchAdapter() { return this; } @Override public IEditorMatchAdapter getEditorMatchAdapter() { return this; } @Override public Match[] computeContainedMatches( AbstractTextSearchResult atsr, IFile file) { return getMatchesForFile(file); } public Match[] getMatchesForFile(IFile file) { List<Match> matches = new ArrayList<Match>(); for (Object element: this.getElements()) { IFile elementFile = getFile(element); if (elementFile!=null && elementFile.equals(file)) { matches.addAll(asList(getMatches(element))); } } return matches.toArray(new Match[matches.size()]); } public Match[] getMatchesForSourceArchive( SourceArchiveEditorInput input) { List<Match> matches = new ArrayList<Match>(); IPath inputPath = input.getPath(); if (inputPath!=null) { //the file could have been deleted String path = inputPath.toOSString(); for (Object element: this.getElements()) { if (element instanceof CeylonElement) { CeylonElement ce = (CeylonElement) element; VirtualFile file = ce.getVirtualFile(); if (path.equals(file.getPath())) { matches.addAll(asList(getMatches(element))); } } } } return matches.toArray(new Match[matches.size()]); } private Match[] getMatchesForClassFile(IClassFile classFile) { List<Match> matches = new ArrayList<Match>(); for (Object element: this.getElements()) { if (element instanceof IJavaElement) { IJavaElement je = (IJavaElement) element; IJavaElement elementClassFile = je.getAncestor(CLASS_FILE); if (elementClassFile!=null && elementClassFile.equals(classFile)) { matches.addAll(asList(getMatches(element))); } } } return matches.toArray(new Match[matches.size()]); } private Match[] getMatchesForURI(URI uri) { List<Match> matches = new ArrayList<Match>(); for (Object element: this.getElements()) { if (element instanceof CeylonElement) { CeylonElement ce = (CeylonElement) element; VirtualFile file = ce.getVirtualFile(); if (uri.toString().endsWith(file.getPath())) { matches.addAll(asList(getMatches(element))); } } else if (element instanceof IJavaElement) { IJavaElement je = (IJavaElement) element; IResource resource = je.getResource(); if (resource!=null) { URI path = resource.getLocationURI(); if (uri.toString().endsWith(path.toString())) { matches.addAll(asList(getMatches(element))); } } } } return matches.toArray(new Match[matches.size()]); } @Override public IFile getFile(Object element) { if (element instanceof IFile) { return (IFile) element; } else if (element instanceof CeylonElement) { CeylonElement ce = (CeylonElement) element; return ce.getFile(); } else if (element instanceof IJavaElement) { IJavaElement je = (IJavaElement) element; return (IFile) je.getResource(); } else { return null; } } @Override public Match[] computeContainedMatches( AbstractTextSearchResult atsr, IEditorPart editor) { IEditorInput ei = editor.getEditorInput(); if (ei instanceof SourceArchiveEditorInput) { SourceArchiveEditorInput saei = (SourceArchiveEditorInput) ei; return getMatchesForSourceArchive(saei); } else if (ei instanceof IFileEditorInput) { return getMatchesForFile(EditorUtil.getFile(ei)); } else if (ei instanceof FileStoreEditorInput) { FileStoreEditorInput fsei = (FileStoreEditorInput) ei; return getMatchesForURI(fsei.getURI()); } else if (ei instanceof IClassFileEditorInput) { IClassFileEditorInput cfei = (IClassFileEditorInput) ei; return getMatchesForClassFile(cfei.getClassFile()); } else { return new Match[0]; } } @Override public boolean isShownInEditor(Match match, IEditorPart editor) { IEditorInput ei = editor.getEditorInput(); Object element = match.getElement(); if (ei instanceof IFileEditorInput) { IFile file = getFile(element); return file!=null && file.equals(EditorUtil.getFile(ei)); } else if (ei instanceof FileStoreEditorInput) { FileStoreEditorInput fsei = (FileStoreEditorInput) ei; String uri = fsei.getURI().toString(); if (element instanceof CeylonElement) { CeylonElement ce = (CeylonElement) element; VirtualFile file = ce.getVirtualFile(); return uri.endsWith(file.getPath()); } else if (element instanceof IJavaElement) { IJavaElement je = (IJavaElement) element; URI path = je.getResource().getLocationURI(); return uri.endsWith(path.toString()); } else { return false; } } else if (ei instanceof IClassFileEditorInput) { if (element instanceof IJavaElement) { IClassFileEditorInput cfei = (IClassFileEditorInput) ei; IJavaElement je = (IJavaElement) element; return je.getAncestor(IJavaElement.CLASS_FILE) == cfei.getClassFile(); } else { return false; } } else { return false; } } }