001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: * Joe Bowbeer (jozart@blarg.net) - removed dependency on runtime compatibility layer (bug 74526)
011: *******************************************************************************/package org.eclipse.ui.examples.readmetool;
012:
013: import org.eclipse.core.resources.IFile;
014: import org.eclipse.core.runtime.CoreException;
015: import org.eclipse.core.runtime.IAdaptable;
016: import org.eclipse.core.runtime.IConfigurationElement;
017: import org.eclipse.core.runtime.IExtension;
018: import org.eclipse.core.runtime.IExtensionPoint;
019: import org.eclipse.core.runtime.Platform;
020: import org.eclipse.jface.viewers.ISelection;
021: import org.eclipse.jface.viewers.IStructuredSelection;
022:
023: /**
024: * Creates the sections used in the <code>ContentOutline</code>
025: *
026: * @see ReadmeContentOutlinePage#getContentOutline(IAdaptable)
027: */
028: public class ReadmeModelFactory {
029: private static ReadmeModelFactory instance = new ReadmeModelFactory();
030:
031: private boolean registryLoaded = false;
032:
033: IReadmeFileParser parser = null;
034:
035: /**
036: * Creates a new ReadmeModelFactory.
037: */
038: private ReadmeModelFactory() {
039: // do nothing
040: }
041:
042: /**
043: * Adds all mark elements to the list for the subtree rooted
044: * at the given mark element.
045: */
046: protected void addSections(AdaptableList list, MarkElement element) {
047: list.add(element);
048: Object[] children = element.getChildren(element);
049: for (int i = 0; i < children.length; ++i) {
050: addSections(list, (MarkElement) children[i]);
051: }
052: }
053:
054: /**
055: * Returns the content outline for the given Readme file.
056: *
057: * @param adaptable the element for which to return the content outline
058: * @return the content outline for the argument
059: */
060: public AdaptableList getContentOutline(IAdaptable adaptable) {
061: return new AdaptableList(getToc((IFile) adaptable));
062: }
063:
064: /**
065: * Returns the singleton readme adapter.
066: */
067: public static ReadmeModelFactory getInstance() {
068: return instance;
069: }
070:
071: /**
072: * Returns a list of all sections in this readme file.
073: *
074: * @param file the file for which to return section heading and subheadings
075: * @return A list containing headings and subheadings
076: */
077: public AdaptableList getSections(IFile file) {
078: MarkElement[] topLevel = getToc(file);
079: AdaptableList list = new AdaptableList();
080: for (int i = 0; i < topLevel.length; i++) {
081: addSections(list, topLevel[i]);
082: }
083: return list;
084: }
085:
086: /**
087: * Convenience method. Looks for a readme file in the selection,
088: * and if one is found, returns the sections for it. Returns null
089: * if there is no readme file in the selection.
090: */
091: public AdaptableList getSections(ISelection sel) {
092: // If sel is not a structured selection just return.
093: if (!(sel instanceof IStructuredSelection))
094: return null;
095: IStructuredSelection structured = (IStructuredSelection) sel;
096:
097: //if the selection is a readme file, get its sections.
098: Object object = structured.getFirstElement();
099: if (object instanceof IFile) {
100: IFile file = (IFile) object;
101: String extension = file.getFileExtension();
102: if (extension != null
103: && extension.equals(IReadmeConstants.EXTENSION)) {
104: return getSections(file);
105: }
106: }
107:
108: //the selected object is not a readme file
109: return null;
110: }
111:
112: /**
113: * Parses the contents of the Readme file by looking for lines
114: * that start with a number.
115: *
116: * @param file the file representing the Readme file
117: * @return an element collection representing the table of contents
118: */
119: private MarkElement[] getToc(IFile file) {
120: if (registryLoaded == false)
121: loadParser();
122: return parser.parse(file);
123: }
124:
125: /**
126: * Loads the parser from the registry by searching for
127: * extensions that satisfy our published extension point.
128: * For the sake of simplicity, we will pick the last extension,
129: * allowing tools to override what is used. In a more
130: * elaborate tool, all the extensions would be processed.
131: */
132: private void loadParser() {
133: IExtensionPoint point = Platform.getExtensionRegistry()
134: .getExtensionPoint(IReadmeConstants.PLUGIN_ID,
135: IReadmeConstants.PP_SECTION_PARSER);
136: if (point != null) {
137: IExtension[] extensions = point.getExtensions();
138: for (int i = 0; i < extensions.length; i++) {
139: IExtension currentExtension = extensions[i];
140: // in a real application, we would collection
141: // the entire list and probably expose it
142: // as a drop-down list. For the sake
143: // of simplicity, we will pick the last extension only.
144: if (i == extensions.length - 1) {
145: IConfigurationElement[] configElements = currentExtension
146: .getConfigurationElements();
147: for (int j = 0; j < configElements.length; j++) {
148: IConfigurationElement config = configElements[i];
149: if (config.getName().equals(
150: IReadmeConstants.TAG_PARSER)) {
151: // process the first 'parser' element and stop
152: processParserElement(config);
153: break;
154: }
155: }
156: }
157: }
158: }
159: if (parser == null)
160: parser = new DefaultSectionsParser();
161: registryLoaded = true;
162: }
163:
164: /**
165: * Tries to create the Readme file parser. If an error occurs during
166: * the creation of the parser, print an error and set the parser
167: * to null.
168: *
169: * @param element the element to process
170: */
171: private void processParserElement(IConfigurationElement element) {
172: try {
173: parser = (IReadmeFileParser) element
174: .createExecutableExtension(IReadmeConstants.ATT_CLASS);
175: } catch (CoreException e) {
176: // since this is an example just write to the console
177: System.out
178: .println(MessageUtil
179: .getString("Unable_to_create_file_parser") + e.getStatus().getMessage()); //$NON-NLS-1$
180: parser = null;
181: }
182: }
183: }
|