blob: 37a12ebf1e76573d24b9378ba7ab4385666d9ce2 [file] [log] [blame]
/*******************************************************************************
* 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);
}
}
}
}
}