package org.eclipse.ui.examples.readmetool; | |
/* | |
* (c) Copyright IBM Corp. 2000, 2001. | |
* All Rights Reserved. | |
*/ | |
import org.eclipse.core.runtime.*; | |
import org.eclipse.core.resources.IFile; | |
import org.eclipse.jface.viewers.ISelection; | |
import org.eclipse.jface.viewers.IStructuredSelection; | |
import java.util.Enumeration; | |
import java.util.Iterator; | |
/** | |
* Creates the sections used in the <code>ContentOutline</code> | |
* | |
* @see ReadmeContentOutlinePage#getContentOutline(IAdaptable) | |
*/ | |
public class ReadmeModelFactory { | |
private static ReadmeModelFactory instance = new ReadmeModelFactory(); | |
private boolean registryLoaded = false; | |
IReadmeFileParser parser = null; | |
/** | |
* Creates a new ReadmeModelFactory. | |
*/ | |
private ReadmeModelFactory() { | |
} | |
/** | |
* Adds all mark elements to the list for the subtree rooted | |
* at the given mark element. | |
*/ | |
protected void addSections(AdaptableList list, MarkElement element) { | |
list.add(element); | |
Object[] children = element.getChildren(element); | |
for (int i = 0; i < children.length; ++i) { | |
addSections(list, (MarkElement) children[i]); | |
} | |
} | |
/** | |
* Returns the content outline for the given Readme file. | |
* | |
* @param adaptable the element for which to return the content outline | |
* @return the content outline for the argument | |
*/ | |
public AdaptableList getContentOutline(IAdaptable adaptable) { | |
return new AdaptableList(getToc((IFile)adaptable)); | |
} | |
/** | |
* Returns the singleton readme adapter. | |
*/ | |
public static ReadmeModelFactory getInstance() { | |
return instance; | |
} | |
/** | |
* Returns a list of all sections in this readme file. | |
* | |
* @param file the file for which to return section heading and subheadings | |
* @return A list containing headings and subheadings | |
*/ | |
public AdaptableList getSections(IFile file) { | |
MarkElement[] topLevel = getToc(file); | |
AdaptableList list = new AdaptableList(); | |
for (int i = 0; i < topLevel.length; i++) { | |
addSections(list, topLevel[i]); | |
} | |
return list; | |
} | |
/** | |
* Convenience method. Looks for a readme file in the selection, | |
* and if one is found, returns the sections for it. Returns null | |
* if there is no readme file in the selection. | |
*/ | |
public AdaptableList getSections(ISelection sel) { | |
// If sel is not a structured selection just return. | |
if (!(sel instanceof IStructuredSelection)) | |
return null; | |
IStructuredSelection structured = (IStructuredSelection)sel; | |
//if the selection is a readme file, get its sections. | |
Object object = structured.getFirstElement(); | |
if (object instanceof IFile) { | |
IFile file = (IFile) object; | |
String extension = file.getFileExtension(); | |
if (extension != null && extension.equals(IReadmeConstants.EXTENSION)) { | |
return getSections(file); | |
} | |
} | |
//the selected object is not a readme file | |
return null; | |
} | |
/** | |
* Parses the contents of the Readme file by looking for lines | |
* that start with a number. | |
* | |
* @param file the file representing the Readme file | |
* @return an element collection representing the table of contents | |
*/ | |
private MarkElement[] getToc(IFile file) { | |
if (registryLoaded == false) loadParser(); | |
return parser.parse(file); | |
} | |
/** | |
* Loads the parser from the registry by searching for | |
* extensions that satisfy our published extension point. | |
* For the sake of simplicity, we will pick the last extension, | |
* allowing tools to override what is used. In a more | |
* elaborate tool, all the extensions would be processed. | |
*/ | |
private void loadParser() { | |
IPluginRegistry pluginRegistry = Platform.getPluginRegistry(); | |
IExtensionPoint point = pluginRegistry.getExtensionPoint(IReadmeConstants.PLUGIN_ID, IReadmeConstants.PP_SECTION_PARSER); | |
if (point != null) { | |
IExtension[] extensions = point.getExtensions(); | |
for (int i = 0; i < extensions.length; i++) { | |
IExtension currentExtension = extensions[i]; | |
// in a real application, we would collection | |
// the entire list and probably expose it | |
// as a drop-down list. For the sake | |
// of simplicity, we will pick the last extension only. | |
if (i == extensions.length - 1) { | |
IConfigurationElement[] configElements = currentExtension.getConfigurationElements(); | |
for (int j = 0; j < configElements.length; j++) { | |
IConfigurationElement config = configElements[i]; | |
if (config.getName().equals(IReadmeConstants.TAG_PARSER)) { | |
// process the first 'parser' element and stop | |
processParserElement(config); | |
break; | |
} | |
} | |
} | |
} | |
} | |
if (parser == null) | |
parser = new DefaultSectionsParser(); | |
registryLoaded = true; | |
} | |
/** | |
* Tries to create the Readme file parser. If an error occurs during | |
* the creation of the parser, print an error and set the parser | |
* to null. | |
* | |
* @param element the element to process | |
*/ | |
private void processParserElement(IConfigurationElement element) { | |
try { | |
parser = (IReadmeFileParser)element.createExecutableExtension(IReadmeConstants.ATT_CLASS); | |
} catch (CoreException e) { | |
// since this is an example just write to the console | |
System.out.println(MessageUtil.getString("Unable_to_create_file_parser") + e.getStatus().getMessage()); //$NON-NLS-1$ | |
parser = null; | |
} | |
} | |
} |