| /******************************************************************************* |
| * Copyright (c) 2000, 2006 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 |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.help.internal.context; |
| import java.util.*; |
| |
| import org.eclipse.core.runtime.*; |
| import org.eclipse.help.*; |
| import org.eclipse.help.internal.*; |
| /** |
| * Maintains the list of contexts and performs look-ups. |
| */ |
| public class ContextManager implements IRegistryChangeListener { |
| public static final String CONTEXTS_XP_NAME = "contexts"; //$NON-NLS-1$ |
| public static final String CONTEXTS_XP_FULLNAME = HelpPlugin.PLUGIN_ID |
| + "." + CONTEXTS_XP_NAME; //$NON-NLS-1$ |
| PluginsContexts pluginsContexts = new PluginsContexts(); |
| /** |
| * Context contributions |
| */ |
| Map contextsFiles = new HashMap(/* |
| * of List ContextsFile indexed by plugin ID |
| * the context apply to |
| */ |
| ); |
| // Dynamic context IDs (generated by help) |
| // indexed by dynamic context objects (not read from files) |
| Map dynamicContextIDs = new HashMap(); |
| private int idCounter = 0; |
| /** |
| * HelpContextManager constructor. |
| */ |
| public ContextManager() { |
| super(); |
| createContextsFiles(); |
| Platform.getExtensionRegistry().addRegistryChangeListener(this, |
| HelpPlugin.PLUGIN_ID); |
| } |
| /** |
| * Finds the context, given context ID. |
| */ |
| public IContext getContext(String contextId) { |
| if (HelpPlugin.DEBUG_CONTEXT) { |
| System.out.println("ContextManager.getContext(" + contextId + ")"); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| if (contextId == null) |
| return null; |
| String plugin = contextId; |
| String id = contextId; |
| int dot = contextId.lastIndexOf('.'); |
| if (dot <= 0 || dot >= contextId.length() - 1) { |
| // no dot in the middle of context ID |
| return null; |
| } |
| plugin = contextId.substring(0, dot); |
| id = contextId.substring(dot + 1); |
| PluginContexts contexts = pluginsContexts.get(plugin); |
| if (contexts == null) { |
| contexts = loadPluginContexts(plugin); |
| } |
| return contexts.get(id); |
| } |
| /** |
| * Loads context.xml with context for a specified plugin, creates context |
| * nodes and adds to pluginContext map. |
| */ |
| public synchronized PluginContexts loadPluginContexts(String plugin) { |
| PluginContexts contexts = pluginsContexts.get(plugin); |
| if (contexts == null) { |
| contexts = new PluginContexts(); |
| // read the context info from the XML contributions |
| List pluginContextsFiles = (List) contextsFiles.get(plugin); |
| if (pluginContextsFiles == null) { |
| pluginContextsFiles = new ArrayList(); |
| } |
| ContextsBuilder builder = new ContextsBuilder(contexts); |
| builder.build(pluginContextsFiles); |
| pluginsContexts.put(plugin, contexts); |
| } |
| return contexts; |
| } |
| /** |
| * Creates a list of context files. |
| */ |
| private void createContextsFiles() { |
| // read extension point and retrieve all context contributions |
| IExtensionPoint xpt = Platform.getExtensionRegistry() |
| .getExtensionPoint(CONTEXTS_XP_FULLNAME); |
| if (xpt == null) |
| return; // no contributions... |
| IExtension[] extensions = xpt.getExtensions(); |
| for (int i = 0; i < extensions.length; i++) { |
| createContextFile(extensions[i]); |
| } |
| } |
| /** |
| * @param extension |
| * @return Collection of String (plugin IDs that have new contexts |
| * contributed) |
| */ |
| private Collection createContextFile(IExtension extension) { |
| Collection plugins = new HashSet(); |
| String definingPlugin = extension.getContributor().getName(); |
| IConfigurationElement[] contextContributions = extension |
| .getConfigurationElements(); |
| for (int j = 0; j < contextContributions.length; j++) { |
| if ("contexts".equals(contextContributions[j].getName())) { //$NON-NLS-1$ |
| String plugin = contextContributions[j].getAttribute("plugin"); //$NON-NLS-1$ |
| if (plugin == null || "".equals(plugin)) //$NON-NLS-1$ |
| plugin = definingPlugin; |
| String fileName = contextContributions[j].getAttribute("file"); //$NON-NLS-1$ |
| // in v1 file attribute was called name |
| if (fileName == null) |
| fileName = contextContributions[j].getAttribute("name"); //$NON-NLS-1$ |
| if (fileName == null) { |
| String msg = "\"context\" element in extension of " //$NON-NLS-1$ |
| + CONTEXTS_XP_FULLNAME |
| + ", contributed in plug-in " + definingPlugin //$NON-NLS-1$ |
| + ", is missing required \"file\" attribute."; //$NON-NLS-1$ |
| HelpPlugin.logError(msg, null); |
| continue; |
| } |
| List pluginContextsFiles = (List) contextsFiles.get(plugin); |
| if (pluginContextsFiles == null) { |
| pluginContextsFiles = new ArrayList(); |
| contextsFiles.put(plugin, pluginContextsFiles); |
| } |
| pluginContextsFiles.add(new ContextsFile(definingPlugin, |
| fileName, plugin)); |
| plugins.add(plugin); |
| } |
| } |
| return plugins; |
| } |
| /** |
| * Registers context in the manager. |
| * |
| * @return context ID assigned to the context |
| */ |
| public String addContext(IContext context) { |
| String plugin = HelpPlugin.PLUGIN_ID; |
| String id = (String) dynamicContextIDs.get(context); |
| if (id != null) { |
| // context already registered |
| } else { |
| // generate ID and register the context |
| id = "ID" + idCounter++; //$NON-NLS-1$ |
| dynamicContextIDs.put(context, id); |
| PluginContexts contexts = pluginsContexts.get(plugin); |
| if (contexts == null) { |
| contexts = loadPluginContexts(plugin); |
| } |
| contexts.put(id, context); |
| } |
| return plugin + "." + id; //$NON-NLS-1$ |
| } |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.core.runtime.IRegistryChangeListener#registryChanged(org.eclipse.core.runtime.IRegistryChangeEvent) |
| */ |
| public synchronized void registryChanged(IRegistryChangeEvent event) { |
| IExtensionDelta[] deltas = event.getExtensionDeltas( |
| HelpPlugin.PLUGIN_ID, CONTEXTS_XP_NAME); |
| for (int i = 0; i < deltas.length; i++) { |
| if (deltas[i].getKind() == IExtensionDelta.ADDED) { |
| IExtension extension = deltas[i].getExtension(); |
| Collection affectedPlugins = createContextFile(extension); |
| // reset contexts for affected plugins, |
| // they will be recreated on demand |
| for (Iterator it = affectedPlugins.iterator(); it.hasNext();) { |
| String pluginId = (String) it.next(); |
| pluginsContexts.remove(pluginId); |
| } |
| } |
| } |
| } |
| } |