blob: 669c823b6cbb71c83016c9016d515e1ad073885b [file] [log] [blame]
package org.eclipse.help.internal.contributors.xml;
/*
* Licensed Materials - Property of IBM,
* WebSphere Studio Workbench
* (c) Copyright IBM Corp 2000
*/
import java.util.*;
import org.w3c.dom.*;
import org.eclipse.core.runtime.*;
import org.eclipse.help.internal.contributions.*;
import org.eclipse.help.internal.contributors.*;
import org.eclipse.help.internal.contributors.xml.*;
import org.eclipse.help.*;
import org.eclipse.help.internal.HelpSystem;
import org.eclipse.help.internal.contributions.xml.*;
import org.eclipse.help.internal.util.*;
/**
* Maintains the list of contexts
* and performs look-ups.
*/
public class HelpContextManager implements ContextManager {
/** contexts are indexed by each plugin */
Map pluginsContexts = new Hashtable(/*of Map of Context*/);
/**
* HelpContextManager constructor.
*/
public HelpContextManager() {
super();
}
private void addMap(String plugin, Element map) {
/*
if (map == null) return;
Map pluginContexts = (Map)pluginsContexts.get(plugin);
if (pluginContexts == null)
{
pluginContexts = new Hashtable();
pluginsContexts.put(plugin, pluginContexts);
}
NodeList children = map.getChildNodes();
for (int i=0; i<children.getLength(); i++)
{
Node child = children.item(i);
if (child.getNodeType() != Node.ELEMENT_NODE) continue;
Element contextElement = (Element)child;
String id = contextElement.getAttribute(ContextContributor.ID_ATTR);
// Try merging an existing context with the same id
// with the new one. If none exists, just add it.
Context oldContext = (Context)pluginContexts.get(id);
if (oldContext == null)
{
Context newContext = new Context(contextElement);
pluginContexts.put(id, newContext);
}
else
{
oldContext.merge(contextElement);
}
}
*/
}
/**
* Finds the context, given context ID.
*/
public IContext getContext(String contextId) {
if (contextId == null)
return null;
String plugin = contextId;
String id = contextId;
int dot = contextId.lastIndexOf('.');
if (dot != -1) {
plugin = contextId.substring(0, dot);
id = contextId.substring(dot + 1);
}
Map contexts = (Map) pluginsContexts.get(plugin);
if (contexts == null) {
// parse the xml context contribution files and load the context
// defintion (NOTE: the side-effect is that all the contexts defined
// by this plugin get loaded)
contexts = loadContext(plugin);
}
return (IContext) contexts.get(id);
}
/**
* Get contributions of some type, like contexts, topics, actions
* or views from a specified plugin. If no contributors are found, or
* if errors are encountered, return an empty Iterator.
* @return java.util.Iterator
* @param typeName java.lang.String
* @param pluginId java.lang.String
*/
public Iterator getContributionsOfType(String pluginId, String typeName) {
List typedContributors = new ArrayList();
try {
// Get the help contributions for this plugin
IPluginDescriptor plugin =
Platform.getPluginRegistry().getPluginDescriptor(pluginId);
IExtension[] extensions = plugin.getExtensions();
IExtension helpContributions = null;
// Loop through all the contributions and find the help ones.
// Then, get the one specified by the typeName
for (int i = 0; extensions != null && i < extensions.length; i++) {
if (!ContextManager
.CONTEXT_EXTENSION
.equals(extensions[i].getExtensionPointUniqueIdentifier()))
continue;
helpContributions = extensions[i];
IConfigurationElement[] pluginContributions =
helpContributions.getConfigurationElements();
for (int j = 0; j < pluginContributions.length; j++) {
if (pluginContributions[j].getName().equals(typeName)) {
Contributor contributor =
ContributorFactory.getFactory().createContributor(
plugin,
pluginContributions[j]);
if (contributor != null)
typedContributors.add(contributor);
}
}
}
return typedContributors.iterator();
} catch (Exception e) {
// log failure.
String msg = Resources.getString("E011", pluginId);
Logger.logError(msg, e);
// this puts an empty Map in the pluginsContexts HashMap, which forces
// looking into nested Context objects.
return typedContributors.iterator();
}
}
/**
* Finds the context to display (text and related topics), given
* a an ordered list of (nested) context objects
*/
public String getDescription(Object[] contexts) {
if (contexts == null)
return null;
// Scan the list and return the description from the first context containing data
for (int i = 0; i < contexts.length; i++) {
String description = getDescription(contexts[i]);
if (description != null)
return description;
}
// worst case scenario. Could not find description from any context object.
return null;
}
/**
* Finds the context description to display, given
* a an ordered list of (nested) context objects.
*/
private String getDescription(Object context) {
if (context instanceof IContext)
return ((IContext) context).getText();
if (!(context instanceof String))
return null;
String contextId = (String) context;
String plugin = contextId;
String id = contextId;
int dot = contextId.lastIndexOf('.');
if (dot != -1) {
plugin = contextId.substring(0, dot);
id = contextId.substring(dot + 1);
}
Map contexts = (Map) pluginsContexts.get(plugin);
if (contexts == null) {
// parse the xml context contribution files and load the context
// defintion (NOTE: the side-effect is that all the contexts defined
// by this plugin get loaded)
contexts = loadContext(plugin);
}
IContext contextNode = (IContext) contexts.get(id);
if (contextNode != null)
return contextNode.getText();
else
// no context defined for this object. return null to enable
// lookup of description from other Contexts.
return null;
}
/**
* Finds the context related topics to display, given
* a an ordered list of (nested) context objects.
* Finds rest of the topics not returned by
* getRelatedTopics(Object[]). May take long to execute.
*/
public IHelpTopic[] getMoreRelatedTopics(Object[] contexts) {
if (contexts == null)
return null;
ArrayList relatedTopics = new ArrayList();
// Skip the first one the list and return the related topics from the other contexts
for (int i = 1; i < contexts.length; i++) {
IHelpTopic[] topics = getRelatedTopics(contexts[i]);
if (topics != null) {
for (int j = 0; j < topics.length; j++)
relatedTopics.add(topics[j]);
}
}
IHelpTopic[] moreRelated = new IHelpTopic[relatedTopics.size()];
return (IHelpTopic[]) relatedTopics.toArray(moreRelated);
}
// NL enables a description string.
private String getNLdescription(String pluginID, String description) {
// if description starts with %, need to translate.
if (description.indexOf('%') == 0) {
// strip off the leading %
description = description.substring(1);
// now translate
description = DocResources.getPluginString(pluginID, description);
}
return description;
}
/**
* Finds the context to display (text and related topics), given
* a an ordered list of (nested) context objects
*/
public IHelpTopic[] getRelatedTopics(Object[] contexts) {
if (contexts == null)
return null;
// Scan the list and return the related topics from the first context containing data
for (int i = 0; i < contexts.length; i++) {
IHelpTopic[] topics = getRelatedTopics(contexts[i]);
if (topics != null)
return topics;
}
// worst case scenario. Could not find related Topics in any context object.
return null;
}
/**
* Finds the context related topics to display, given
* a an ordered list of (nested) context objects
* Finds only some of the topics.
*/
private IHelpTopic[] getRelatedTopics(Object context) {
if (context instanceof IContext)
return ((IContext) context).getRelatedTopics();
if (!(context instanceof String))
return null;
String contextId = (String) context;
String plugin = contextId;
String id = contextId;
int dot = contextId.lastIndexOf('.');
if (dot != -1) {
plugin = contextId.substring(0, dot);
id = contextId.substring(dot + 1);
}
Map contexts = (Map) pluginsContexts.get(plugin);
if (contexts == null) {
// parse the xml context contribution files and load the context
// defintion (NOTE: the side-effect is that all the contexts defined
// by this plugin get loaded)
contexts = loadContext(plugin);
}
IContext contextNode = (IContext) contexts.get(id);
if (contextNode != null)
return contextNode.getRelatedTopics();
else
// no context defined for this object. return null to enable
// lookup of description from other Contexts.
return null;
}
/**
* Finds the context to display (text and related topics), given
* a an ordered list of (nested) context objects
*/
private Map loadContext(String plugin) {
Map contexts = (Map) pluginsContexts.get(plugin);
if (contexts == null) {
// read the context info from the XML contributions
Iterator contextsContributors =
getContributionsOfType(plugin, ContextContributor.CONTEXTS_ELEM);
contexts = new HashMap();
pluginsContexts.put(plugin, contexts);
// iterator over all contexts contributors and add all the contexts
// defined by this plugin
// NOTE: if performance is a problem, this can be improved by a better
// use of the SAX parser
while (contextsContributors.hasNext()) {
Contributor contextContributor = (Contributor) contextsContributors.next();
Contribution contrib = contextContributor.getContribution();
// contrib could be null if there was an error parsing the manifest file!
if (contrib == null);
// do nothing here because we need to load other Context files.
else {
for (Iterator contextIterator = contrib.getChildren();
contextIterator.hasNext();
) {
HelpContext contextNode = (HelpContext) contextIterator.next();
String description = contextNode.getDescription();
description = getNLdescription(plugin, description);
contextNode.setDescription(description);
contexts.put(contextNode.getID(), contextNode);
}
}
}
}
return contexts;
}
}