blob: 0fcdc9cbb77ca77c20d10d62e1a5098712a31c8d [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2018 IBM Corporation and others.
* 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
*
*******************************************************************************/
package org.eclipse.dltk.internal.ui.search;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.dltk.core.DLTKCore;
import org.eclipse.dltk.core.IBuildpathContainer;
import org.eclipse.dltk.core.IBuildpathEntry;
import org.eclipse.dltk.core.IDLTKLanguageToolkit;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.IProjectFragment;
import org.eclipse.dltk.core.IScriptFolder;
import org.eclipse.dltk.core.IScriptProject;
import org.eclipse.dltk.core.IType;
import org.eclipse.dltk.core.ModelException;
import org.eclipse.dltk.core.search.IDLTKSearchScope;
import org.eclipse.dltk.core.search.SearchEngine;
import org.eclipse.dltk.internal.corext.util.Messages;
import org.eclipse.dltk.internal.ui.browsing.LogicalPackage;
import org.eclipse.dltk.ui.DLTKUIPlugin;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.IWorkingSetSelectionDialog;
public class DLTKSearchScopeFactory {
private static DLTKSearchScopeFactory fgInstance;
private final IDLTKSearchScope EMPTY_SCOPE = SearchEngine
.createSearchScope(new IModelElement[] {}, null);
private DLTKSearchScopeFactory() {
}
public static synchronized DLTKSearchScopeFactory getInstance() {
if (fgInstance == null)
fgInstance = new DLTKSearchScopeFactory();
return fgInstance;
}
public IWorkingSet[] queryWorkingSets() throws ModelException {
Shell shell = DLTKUIPlugin.getActiveWorkbenchShell();
if (shell == null)
return null;
IWorkingSetSelectionDialog dialog = PlatformUI.getWorkbench()
.getWorkingSetManager()
.createWorkingSetSelectionDialog(shell, true);
if (dialog.open() == Window.OK) {
IWorkingSet[] workingSets = dialog.getSelection();
if (workingSets.length > 0)
return workingSets;
}
return null;
}
public IDLTKSearchScope createSearchScope(IWorkingSet[] workingSets,
boolean includeInterp, IDLTKLanguageToolkit toolkit) {
if (workingSets == null || workingSets.length < 1)
return EMPTY_SCOPE;
Set modelElements = new HashSet(workingSets.length * 10);
for (int i = 0; i < workingSets.length; i++) {
IWorkingSet workingSet = workingSets[i];
if (workingSet.isEmpty() && workingSet.isAggregateWorkingSet()) {
return createWorkspaceScope(includeInterp, toolkit);
}
addModelElements(modelElements, workingSet);
}
return createSearchScope(modelElements, includeInterp, toolkit);
}
public IDLTKSearchScope createSearchScope(IWorkingSet workingSet,
boolean includeInterp, IDLTKLanguageToolkit toolkit) {
Set modelElements = new HashSet(10);
if (workingSet.isEmpty() && workingSet.isAggregateWorkingSet()) {
return createWorkspaceScope(includeInterp, toolkit);
}
addModelElements(modelElements, workingSet);
return createSearchScope(modelElements, includeInterp, toolkit);
}
public IDLTKSearchScope createSearchScope(IResource[] resources,
boolean includeInterp, IDLTKLanguageToolkit toolkit) {
if (resources == null)
return EMPTY_SCOPE;
Set modelElements = new HashSet(resources.length);
addModelElements(modelElements, resources);
return createSearchScope(modelElements, includeInterp, toolkit);
}
public IDLTKSearchScope createSearchScope(ISelection selection,
boolean includeInterp, IDLTKLanguageToolkit toolkit) {
return createSearchScope(getModelElements(selection), includeInterp,
toolkit);
}
public IDLTKSearchScope createProjectSearchScope(String[] projectNames,
boolean includeInterp, IDLTKLanguageToolkit toolkit) {
ArrayList res = new ArrayList();
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
for (int i = 0; i < projectNames.length; i++) {
IScriptProject project = DLTKCore
.create(root.getProject(projectNames[i]));
if (project.exists()) {
res.add(project);
}
}
return createSearchScope(res, includeInterp, toolkit);
}
public IDLTKSearchScope createProjectSearchScope(IScriptProject project,
boolean includeInterp) {
return SearchEngine.createSearchScope(project,
getSearchFlags(includeInterp));
}
public IDLTKSearchScope createProjectSearchScope(IEditorInput editorInput,
boolean includeInterp) {
IModelElement elem = DLTKUIPlugin
.getEditorInputModelElement(editorInput);
if (elem != null) {
IScriptProject project = elem.getScriptProject();
if (project != null) {
return createProjectSearchScope(project, includeInterp);
}
}
return EMPTY_SCOPE;
}
public String getWorkspaceScopeDescription(boolean includeInterp) {
return includeInterp ? SearchMessages.WorkspaceScope
: SearchMessages.WorkspaceScopeNoInterpreterEnvironment;
}
public String getProjectScopeDescription(String[] projectNames,
boolean includeInterp) {
if (projectNames.length == 0) {
return SearchMessages.DLTKSearchScopeFactory_undefined_projects;
}
String scopeDescription;
if (projectNames.length == 1) {
String label = includeInterp ? SearchMessages.EnclosingProjectScope
: SearchMessages.EnclosingProjectScopeNoInterpreterEnvironment;
scopeDescription = Messages.format(label, projectNames[0]);
} else if (projectNames.length == 2) {
String label = includeInterp
? SearchMessages.EnclosingProjectsScope2
: SearchMessages.EnclosingProjectsScope2NoInterpreterEnvironment;
scopeDescription = Messages.format(label, projectNames[0],
projectNames[1]);
} else {
String label = includeInterp ? SearchMessages.EnclosingProjectsScope
: SearchMessages.EnclosingProjectsScopeNoInterpreterEnvironment;
scopeDescription = Messages.format(label, projectNames[0],
projectNames[1]);
}
return scopeDescription;
}
public String getProjectScopeDescription(IScriptProject project,
boolean includeInterp) {
if (includeInterp) {
return Messages.format(SearchMessages.ProjectScope,
project.getElementName());
}
return Messages.format(
SearchMessages.ProjectScopeNoInterpreterEnvironment,
project.getElementName());
}
public String getProjectScopeDescription(IEditorInput editorInput,
boolean includeInterp) {
IModelElement elem = DLTKUIPlugin
.getEditorInputModelElement(editorInput);
if (elem != null) {
IScriptProject project = elem.getScriptProject();
if (project != null) {
return getProjectScopeDescription(project, includeInterp);
}
}
return Messages.format(SearchMessages.ProjectScope, ""); //$NON-NLS-1$
}
public String getHierarchyScopeDescription(IType type) {
return Messages.format(SearchMessages.HierarchyScope,
type.getElementName());
}
public String getSelectionScopeDescription(IModelElement[] modelElements,
boolean includeInterp) {
if (modelElements.length == 0) {
return SearchMessages.DLTKSearchScopeFactory_undefined_selection;
}
String scopeDescription;
if (modelElements.length == 1) {
String label = includeInterp ? SearchMessages.SingleSelectionScope
: SearchMessages.SingleSelectionScopeNoInterpreterEnvironment;
scopeDescription = Messages.format(label,
modelElements[0].getElementName());
} else if (modelElements.length == 1) {
String label = includeInterp ? SearchMessages.DoubleSelectionScope
: SearchMessages.DoubleSelectionScopeNoInterpreterEnvironment;
scopeDescription = Messages.format(label,
modelElements[0].getElementName(),
modelElements[1].getElementName());
} else {
String label = includeInterp ? SearchMessages.SelectionScope
: SearchMessages.SelectionScopeNoInterpreterEnvironment;
scopeDescription = Messages.format(label,
modelElements[0].getElementName(),
modelElements[1].getElementName());
}
return scopeDescription;
}
public String getWorkingSetScopeDescription(IWorkingSet[] workingSets,
boolean includeInterp) {
if (workingSets.length == 0) {
return SearchMessages.DLTKSearchScopeFactory_undefined_workingsets;
}
if (workingSets.length == 1) {
String label = includeInterp ? SearchMessages.SingleWorkingSetScope
: SearchMessages.SingleWorkingSetScopeNoInterpreterEnvironment;
return Messages.format(label, workingSets[0].getLabel());
}
Arrays.sort(workingSets, new WorkingSetComparator());
if (workingSets.length == 2) {
String label = includeInterp ? SearchMessages.DoubleWorkingSetScope
: SearchMessages.DoubleWorkingSetScopeNoInterpreterEnvironment;
return Messages.format(label, workingSets[0].getLabel(),
workingSets[1].getLabel());
}
String label = includeInterp ? SearchMessages.WorkingSetsScope
: SearchMessages.WorkingSetsScopeNoInterpreterEnvironment;
return Messages.format(label, workingSets[0].getLabel(),
workingSets[1].getLabel());
}
public IProject[] getProjects(IDLTKSearchScope scope) {
IPath[] paths = scope.enclosingProjectsAndZips();
HashSet<IProject> temp = new HashSet<>();
for (int i = 0; i < paths.length; i++) {
IResource resource = ResourcesPlugin.getWorkspace().getRoot()
.findMember(paths[i]);
if (resource != null && resource.getType() == IResource.PROJECT)
temp.add((IProject) resource);
}
return temp.toArray(new IProject[temp.size()]);
}
public IModelElement[] getModelElements(ISelection selection) {
if (selection instanceof IStructuredSelection && !selection.isEmpty()) {
return getModelElements(
((IStructuredSelection) selection).toArray());
}
return new IModelElement[0];
}
private IModelElement[] getModelElements(Object[] elements) {
if (elements.length == 0)
return new IModelElement[0];
Set<IModelElement> result = new HashSet<>(elements.length);
for (int i = 0; i < elements.length; i++) {
Object selectedElement = elements[i];
if (selectedElement instanceof IModelElement) {
addModelElements(result, (IModelElement) selectedElement);
} else if (selectedElement instanceof IResource) {
addModelElements(result, (IResource) selectedElement);
} else if (selectedElement instanceof LogicalPackage) {
addModelElements(result, (LogicalPackage) selectedElement);
} else if (selectedElement instanceof IWorkingSet) {
IWorkingSet ws = (IWorkingSet) selectedElement;
addModelElements(result, ws);
} else if (selectedElement instanceof IAdaptable) {
IResource resource = ((IAdaptable) selectedElement)
.getAdapter(IResource.class);
if (resource != null)
addModelElements(result, resource);
IModelElement modelElement = ((IAdaptable) selectedElement)
.getAdapter(IModelElement.class);
if (modelElement != null)
addModelElements(result, modelElement);
}
}
return result.toArray(new IModelElement[result.size()]);
}
public IDLTKSearchScope createSearchScope(IModelElement[] modelElements,
boolean includeInterp, IDLTKLanguageToolkit toolkit) {
if (modelElements.length == 0)
return EMPTY_SCOPE;
return SearchEngine.createSearchScope(modelElements,
getSearchFlags(includeInterp), toolkit);
}
private IDLTKSearchScope createSearchScope(
Collection<IModelElement> modelElements, boolean includeInterp,
IDLTKLanguageToolkit toolkit) {
if (modelElements.isEmpty())
return EMPTY_SCOPE;
IModelElement[] elementArray = modelElements
.toArray(new IModelElement[modelElements.size()]);
return SearchEngine.createSearchScope(elementArray,
getSearchFlags(includeInterp), toolkit);
}
private static int getSearchFlags(boolean includeInterp) {
int flags = IDLTKSearchScope.SOURCES
| IDLTKSearchScope.APPLICATION_LIBRARIES;
if (includeInterp)
flags |= IDLTKSearchScope.SYSTEM_LIBRARIES;
return flags;
}
private void addModelElements(Set modelElements, IResource[] resources) {
for (int i = 0; i < resources.length; i++)
addModelElements(modelElements, resources[i]);
}
private void addModelElements(Set modelElements, IResource resource) {
IModelElement modelElement = resource.getAdapter(IModelElement.class);
if (modelElement == null)
// not a Script resource
return;
if (modelElement.getElementType() == IModelElement.SCRIPT_FOLDER) {
// add other possible package fragments
try {
addModelElements(modelElements, ((IFolder) resource).members());
} catch (CoreException ex) {
// don't add elements
}
}
modelElements.add(modelElement);
}
private void addModelElements(Set modelElements,
IModelElement modelElement) {
modelElements.add(modelElement);
}
private void addModelElements(Set modelElements, IWorkingSet workingSet) {
if (workingSet == null)
return;
if (workingSet.isAggregateWorkingSet() && workingSet.isEmpty()) {
try {
IScriptProject[] projects = DLTKCore
.create(ResourcesPlugin.getWorkspace().getRoot())
.getScriptProjects();
modelElements.addAll(Arrays.asList(projects));
} catch (ModelException e) {
DLTKUIPlugin.log(e);
}
return;
}
IAdaptable[] elements = workingSet.getElements();
for (int i = 0; i < elements.length; i++) {
IModelElement modelElement = elements[i]
.getAdapter(IModelElement.class);
if (modelElement != null) {
addModelElements(modelElements, modelElement);
continue;
}
IResource resource = elements[i].getAdapter(IResource.class);
if (resource != null) {
addModelElements(modelElements, resource);
}
// else we don't know what to do with it, ignore.
}
}
public void addModelElements(Set modelElements,
LogicalPackage selectedElement) {
IScriptFolder[] packages = selectedElement.getFragments();
for (int i = 0; i < packages.length; i++)
addModelElements(modelElements, packages[i]);
}
public IDLTKSearchScope createWorkspaceScope(boolean includeInterp,
IDLTKLanguageToolkit toolkit) {
if (!includeInterp) {
try {
IScriptProject[] projects = DLTKCore
.create(ResourcesPlugin.getWorkspace().getRoot())
.getScriptProjects();
return SearchEngine.createSearchScope(projects,
getSearchFlags(includeInterp), toolkit);
} catch (ModelException e) {
// ignore, use workspace scope instead
}
}
return SearchEngine.createWorkspaceScope(toolkit);
}
public boolean isInsideInterpreter(IModelElement element) {
IProjectFragment root = (IProjectFragment) element
.getAncestor(IModelElement.PROJECT_FRAGMENT);
if (root != null) {
try {
IBuildpathEntry entry = root.getRawBuildpathEntry();
if (entry != null && entry
.getEntryKind() == IBuildpathEntry.BPE_CONTAINER) {
IBuildpathContainer container = DLTKCore
.getBuildpathContainer(entry.getPath(),
root.getScriptProject());
return container != null && container
.getKind() == IBuildpathContainer.K_DEFAULT_SYSTEM;
}
return false;
} catch (ModelException e) {
DLTKUIPlugin.log(e);
}
}
return true; // include InterpreterEnvironment in doubt
}
}