| /******************************************************************************* |
| * Copyright (c) 2005, 2007 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.core.search; |
| |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.ProjectScope; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IConfigurationElement; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.dltk.core.DLTKCore; |
| import org.eclipse.dltk.core.DLTKLanguageManager; |
| import org.eclipse.dltk.core.IDLTKLanguageToolkit; |
| import org.eclipse.dltk.core.IScriptProject; |
| import org.eclipse.dltk.core.ISourceModule; |
| import org.eclipse.dltk.core.search.indexing.IProjectIndexer; |
| import org.eclipse.osgi.util.NLS; |
| |
| public class ProjectIndexerManager { |
| |
| private final static String EXTPOINT = DLTKCore.PLUGIN_ID |
| + ".projectIndexer"; //$NON-NLS-1$ |
| |
| private final static String NATURE_ATTR = "nature"; //$NON-NLS-1$ |
| private static final String CLASS_ATTR = "class"; //$NON-NLS-1$ |
| private static final String ID_ATTR = "id"; //$NON-NLS-1$ |
| private static final String INDEXER_ATTR = "indexer"; //$NON-NLS-1$ |
| private static final String ENABLE_ELEM = "enable"; //$NON-NLS-1$ |
| private static final String DISABLE_ELEM = "disable"; //$NON-NLS-1$ |
| private static final String INDEXER_ELEM = "projectIndexer"; //$NON-NLS-1$ |
| |
| // Contains list of indexers for selected nature. |
| private static Map<String, ProjectIndexerDescriptor> indexers; |
| private static final Map<String, Set<String>> enabledIndexers = new HashMap<String, Set<String>>(); |
| private static final Map<String, Set<String>> disabledIndexers = new HashMap<String, Set<String>>(); |
| |
| private static class ProjectIndexerDescriptor { |
| private final String id; |
| private IConfigurationElement element; |
| private IProjectIndexer projectIndexer; |
| |
| ProjectIndexerDescriptor(String id, IConfigurationElement element) { |
| this.id = id; |
| this.element = element; |
| } |
| |
| public IProjectIndexer getObject() { |
| if (projectIndexer == null) { |
| try { |
| projectIndexer = (IProjectIndexer) element |
| .createExecutableExtension(CLASS_ATTR); |
| } catch (CoreException e) { |
| DLTKCore.error("Error initializing project indexer", e); //$NON-NLS-1$ |
| synchronized (ProjectIndexerManager.class) { |
| indexers.remove(id); |
| } |
| return null; |
| } |
| } |
| return projectIndexer; |
| } |
| } |
| |
| private synchronized static void initialize() { |
| if (indexers != null) { |
| return; |
| } |
| |
| indexers = new HashMap<String, ProjectIndexerDescriptor>(); |
| for (IConfigurationElement element : Platform.getExtensionRegistry() |
| .getConfigurationElementsFor(EXTPOINT)) { |
| if (DISABLE_ELEM.equals(element.getName())) { |
| final String nature = element.getAttribute(NATURE_ATTR); |
| Set<String> disabledForNature = disabledIndexers.get(nature); |
| if (disabledForNature == null) { |
| disabledForNature = new HashSet<String>(); |
| disabledIndexers.put(nature, disabledForNature); |
| } |
| disabledForNature.add(element.getAttribute(INDEXER_ATTR)); |
| } else if (ENABLE_ELEM.equals(element.getName())) { |
| final String nature = element.getAttribute(NATURE_ATTR); |
| Set<String> enabledForNature = enabledIndexers.get(nature); |
| if (enabledForNature == null) { |
| enabledForNature = new HashSet<String>(); |
| enabledIndexers.put(nature, enabledForNature); |
| } |
| enabledForNature.add(element.getAttribute(INDEXER_ATTR)); |
| } else if (INDEXER_ELEM.equals(element.getName())) { |
| final String id = element.getAttribute(ID_ATTR); |
| if (id == null) { |
| DLTKCore.warn(NLS |
| .bind("{0} contributed by {1} does not have \"{2}\" attribute", //$NON-NLS-1$ |
| new Object[] { INDEXER_ELEM, |
| element.getContributor().getName(), |
| ID_ATTR })); |
| continue; |
| } |
| if (indexers.containsKey(id)) { |
| DLTKCore.warn(NLS |
| .bind("Duplicate {0} contribution from {1} (previous one is from \"{2}\")", //$NON-NLS-1$ |
| new Object[] { |
| INDEXER_ELEM, |
| element.getContributor().getName(), |
| indexers.get(id).element.getContributor() |
| .getName() })); |
| continue; |
| } |
| indexers.put(id, new ProjectIndexerDescriptor(id, element)); |
| } |
| } |
| } |
| |
| private static boolean enabled = true; |
| |
| public static boolean isEnabled() { |
| return enabled; |
| } |
| |
| public static void setEnabled(boolean value) { |
| enabled = value; |
| } |
| |
| /** |
| * Return merged with all elements with nature # |
| * |
| * @param natureId |
| * @return |
| * @throws CoreException |
| */ |
| public static IProjectIndexer[] getIndexers(String natureId) { |
| initialize(); |
| IProjectIndexer[] nature = getByNature(natureId, natureId); |
| IProjectIndexer[] all = getByNature("#", natureId); //$NON-NLS-1$ |
| if (all == null) { |
| return nature; |
| } |
| if (nature == null) { |
| return all; |
| } |
| final IProjectIndexer[] result = new IProjectIndexer[nature.length |
| + all.length]; |
| System.arraycopy(nature, 0, result, 0, nature.length); |
| System.arraycopy(all, 0, result, nature.length, all.length); |
| return result; |
| } |
| |
| public static IProjectIndexer[] getAllIndexers() { |
| initialize(); |
| |
| final Set<String> indexerIds = new HashSet<String>(); |
| for (Set<String> ids : enabledIndexers.values()) { |
| indexerIds.addAll(ids); |
| } |
| return getIndexers(indexerIds, null); |
| } |
| |
| private static IProjectIndexer[] getByNature(String natureId, |
| String disabledNature) { |
| Set<String> indexerIds = enabledIndexers.get(natureId); |
| if (indexerIds != null) { |
| return getIndexers(indexerIds, disabledNature); |
| } else { |
| return null; |
| } |
| } |
| |
| private static IProjectIndexer[] getIndexers(Set<String> indexerIds, |
| String disabledNature) { |
| final List<IProjectIndexer> result = new ArrayList<IProjectIndexer>( |
| indexerIds.size()); |
| final Set<String> disabled = disabledIndexers.get(disabledNature); |
| for (String indexerId : indexerIds) { |
| if (disabled != null && disabled.contains(indexerId)) { |
| continue; |
| } |
| final ProjectIndexerDescriptor descriptor = indexers.get(indexerId); |
| if (descriptor != null) { |
| final IProjectIndexer indexer = descriptor.getObject(); |
| if (indexer != null) { |
| result.add(indexer); |
| } |
| } |
| } |
| if (!result.isEmpty()) { |
| return result.toArray(new IProjectIndexer[result.size()]); |
| } else { |
| return null; |
| } |
| } |
| |
| private static IProjectIndexer[] getIndexers(IScriptProject project) { |
| return getIndexers(project, true); |
| } |
| |
| private static IProjectIndexer[] getIndexers(IScriptProject project, |
| boolean checkEnable) { |
| if (!enabled) { |
| return null; |
| } |
| if (checkEnable && !isIndexerEnabled(project.getProject())) { |
| return null; |
| } |
| final IDLTKLanguageToolkit toolkit = DLTKLanguageManager |
| .getLanguageToolkit(project); |
| if (toolkit == null) { |
| return null; |
| } |
| return getIndexers(toolkit.getNatureId()); |
| } |
| |
| public static boolean isIndexerEnabled(final IProject project) { |
| if (!enabled) { |
| return false; |
| } |
| return new ProjectScope(project).getNode(DLTKCore.PLUGIN_ID) |
| .getBoolean(DLTKCore.INDEXER_ENABLED, true); |
| } |
| |
| /** |
| * Removes the indexes for a given path. This is a no-op if the index did |
| * not exist. |
| * |
| * @param project |
| * |
| * @param path |
| */ |
| public static void removeLibrary(IScriptProject project, IPath path) { |
| final IProjectIndexer[] indexers = getIndexers(project); |
| if (indexers != null) { |
| for (int i = 0; i < indexers.length; ++i) { |
| indexers[i].removeLibrary(project, path); |
| } |
| } |
| } |
| |
| /** |
| * @param projectPath |
| */ |
| public static void removeProject(IPath projectPath) { |
| final IProjectIndexer[] indexers = getAllIndexers(); |
| if (indexers != null) { |
| for (int i = 0; i < indexers.length; ++i) { |
| indexers[i].removeProject(projectPath); |
| } |
| } |
| } |
| |
| /** |
| * @param project |
| * @param path |
| */ |
| public static void indexLibrary(IScriptProject project, IPath path) { |
| final IProjectIndexer[] indexers = getIndexers(project); |
| if (indexers != null) { |
| for (int i = 0; i < indexers.length; ++i) { |
| indexers[i].indexLibrary(project, path); |
| } |
| } |
| } |
| |
| /** |
| * @param project |
| * @param path |
| */ |
| public static void removeProjectFragment(IScriptProject project, IPath path) { |
| final IProjectIndexer[] indexers = getIndexers(project); |
| if (indexers != null) { |
| for (int i = 0; i < indexers.length; ++i) { |
| indexers[i].removeProjectFragment(project, path); |
| } |
| } |
| } |
| |
| /** |
| * @param project |
| * @param path |
| */ |
| public static void indexProjectFragment(IScriptProject project, IPath path) { |
| final IProjectIndexer[] indexers = getIndexers(project); |
| if (indexers != null) { |
| for (int i = 0; i < indexers.length; ++i) { |
| indexers[i].indexProjectFragment(project, path); |
| } |
| } |
| } |
| |
| /** |
| * @param res |
| */ |
| public static void indexProject(IProject project) { |
| if (isIndexerEnabled(project)) { |
| indexProject(project, DLTKCore.create(project)); |
| } |
| } |
| |
| public static void indexProject(IScriptProject scriptProject) { |
| final IProject project = scriptProject.getProject(); |
| if (isIndexerEnabled(project)) { |
| indexProject(project, scriptProject); |
| } |
| } |
| |
| /** |
| * @param scriptProject |
| */ |
| private static void indexProject(IProject project, |
| IScriptProject scriptProject) { |
| final IProjectIndexer[] indexers = getIndexers(scriptProject, false); |
| if (indexers != null) { |
| for (int i = 0; i < indexers.length; ++i) { |
| indexers[i].indexProject(scriptProject); |
| } |
| } |
| } |
| |
| /** |
| * @param project |
| * @param path |
| */ |
| public static void removeSourceModule(IScriptProject project, String path) { |
| final IProjectIndexer[] indexers = getIndexers(project); |
| if (indexers != null) { |
| for (int i = 0; i < indexers.length; ++i) { |
| indexers[i].removeSourceModule(project, path); |
| } |
| } |
| } |
| |
| /** |
| * @param module |
| * @param toolkit |
| */ |
| public static void indexSourceModule(ISourceModule module, |
| IDLTKLanguageToolkit toolkit) { |
| if (!enabled) { |
| return; |
| } |
| final IProjectIndexer[] indexers = getIndexers(toolkit.getNatureId()); |
| if (indexers != null) { |
| for (int i = 0; i < indexers.length; ++i) { |
| indexers[i].indexSourceModule(module, toolkit); |
| } |
| } |
| } |
| |
| /** |
| * @param workingCopy |
| */ |
| public static void reconciled(ISourceModule workingCopy) { |
| final IScriptProject project = workingCopy.getScriptProject(); |
| if (project == null) { |
| return; |
| } |
| if (!isIndexerEnabled(project.getProject())) { |
| return; |
| } |
| final IDLTKLanguageToolkit toolkit = DLTKLanguageManager |
| .getLanguageToolkit(project); |
| if (toolkit == null) { |
| return; |
| } |
| final IProjectIndexer[] indexers = getIndexers(toolkit.getNatureId()); |
| if (indexers != null) { |
| for (int i = 0; i < indexers.length; ++i) { |
| indexers[i].reconciled(workingCopy, toolkit); |
| } |
| } |
| } |
| |
| public static void startIndexing() { |
| final IProjectIndexer[] indexers = getAllIndexers(); |
| if (indexers == null) { |
| return; |
| } |
| boolean wantRefresh = false; |
| for (int i = 0; i < indexers.length; ++i) { |
| indexers[i].startIndexing(); |
| wantRefresh |= indexers[i].wantRefreshOnStart(); |
| } |
| if (wantRefresh) { |
| final IScriptProject[] projects; |
| try { |
| projects = DLTKCore.create( |
| ResourcesPlugin.getWorkspace().getRoot()) |
| .getScriptProjects(); |
| } catch (Exception e) { |
| DLTKCore.error(e); |
| return; |
| } |
| for (int i = 0; i < projects.length; ++i) { |
| final IScriptProject project = projects[i]; |
| final IProjectIndexer[] projectIndexers = getIndexers(project); |
| if (projectIndexers != null) { |
| for (IProjectIndexer projectIndexer : projectIndexers) { |
| if (projectIndexer.wantRefreshOnStart()) { |
| projectIndexer.indexProject(project); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| } |