001: /*******************************************************************************
002: * Copyright (c) 2002, 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: *******************************************************************************/package org.eclipse.ui.internal.cheatsheets.registry;
011:
012: import org.eclipse.core.runtime.*;
013: import org.eclipse.ui.internal.cheatsheets.*;
014:
015: /**
016: * Template implementation of a registry reader that creates objects
017: * representing registry contents. Typically, an extension
018: * contains one element, but this reader handles multiple
019: * elements per extension.
020: *
021: * To start reading the extensions from the registry for an
022: * extension point, call the method <code>readRegistry</code>.
023: *
024: * To read children of an IConfigurationElement, call the
025: * method <code>readElementChildren</code> from your implementation
026: * of the method <code>readElement</code>, as it will not be
027: * done by default.
028: */
029: public abstract class RegistryReader {
030: protected static final String TAG_DESCRIPTION = "description"; //$NON-NLS-1$
031:
032: /**
033: * The constructor.
034: */
035: /*package*/RegistryReader() {
036: }
037:
038: /**
039: * This method extracts description as a subelement of
040: * the given element.
041: * @return description string if defined, or empty string
042: * if not.
043: */
044: /*package*/String getDescription(IConfigurationElement config) {
045: IConfigurationElement[] children = config
046: .getChildren(TAG_DESCRIPTION);
047: if (children.length >= 1) {
048: return children[0].getValue();
049: }
050: return ICheatSheetResource.EMPTY_STRING;
051: }
052:
053: /**
054: * Logs the error in the workbench log using the provided
055: * text and the information in the configuration element.
056: */
057: private void logError(IConfigurationElement element, String text) {
058: IExtension extension = element.getDeclaringExtension();
059: StringBuffer buf = new StringBuffer();
060: buf
061: .append("Plugin " + extension.getContributor().getName() + ", extension " + extension.getExtensionPointUniqueIdentifier()); //$NON-NLS-2$//$NON-NLS-1$
062: buf.append("\n" + text); //$NON-NLS-1$
063:
064: IStatus status = new Status(IStatus.ERROR,
065: ICheatSheetResource.CHEAT_SHEET_PLUGIN_ID, IStatus.OK,
066: buf.toString(), null);
067: CheatSheetPlugin.getPlugin().getLog().log(status);
068: }
069:
070: /**
071: * Logs a very common registry error when a required attribute is missing.
072: */
073: /*package*/void logMissingAttribute(IConfigurationElement element,
074: String attributeName) {
075: logError(
076: element,
077: "Required attribute '" + attributeName + "' not defined"); //$NON-NLS-2$//$NON-NLS-1$
078: }
079:
080: /**
081: * Logs a registry error when the configuration element is unknown.
082: */
083: private void logUnknownElement(IConfigurationElement element) {
084: logError(element,
085: "Unknown extension tag found: " + element.getName()); //$NON-NLS-1$
086: }
087:
088: /**
089: * Apply a reproducable order to the list of extensions
090: * provided, such that the order will not change as
091: * extensions are added or removed.
092: */
093: private IExtension[] orderExtensions(IExtension[] extensions) {
094: // By default, the order is based on plugin id sorted
095: // in ascending order. The order for a plugin providing
096: // more than one extension for an extension point is
097: // dependent in the order listed in the XML file.
098: Sorter sorter = new Sorter() {
099: public boolean compare(Object extension1, Object extension2) {
100: String s1 = ((IExtension) extension1).getContributor()
101: .getName().toUpperCase();
102: String s2 = ((IExtension) extension2).getContributor()
103: .getName().toUpperCase();
104: //Return true if elementTwo is 'greater than' elementOne
105: return s2.compareTo(s1) > 0;
106: }
107: };
108:
109: Object[] sorted = sorter.sort(extensions);
110: IExtension[] sortedExtension = new IExtension[sorted.length];
111: System.arraycopy(sorted, 0, sortedExtension, 0, sorted.length);
112: return sortedExtension;
113: }
114:
115: /**
116: * Implement this method to read element's attributes.
117: * If children should also be read, then implementor
118: * is responsible for calling <code>readElementChildren</code>.
119: * Implementor is also responsible for logging missing
120: * attributes.
121: *
122: * @return true if element was recognized, false if not.
123: */
124: /*package*/abstract boolean readElement(
125: IConfigurationElement element);
126:
127: /**
128: * Read the element's children. This is called by
129: * the subclass' readElement method when it wants
130: * to read the children of the element.
131: */
132: /*package*/void readElementChildren(IConfigurationElement element) {
133: readElements(element.getChildren());
134: }
135:
136: /**
137: * Read each element one at a time by calling the
138: * subclass implementation of <code>readElement</code>.
139: *
140: * Logs an error if the element was not recognized.
141: */
142: private void readElements(IConfigurationElement[] elements) {
143: for (int i = 0; i < elements.length; i++) {
144: if (!readElement(elements[i]))
145: logUnknownElement(elements[i]);
146: }
147: }
148:
149: /**
150: * Read one extension by looping through its
151: * configuration elements.
152: */
153: private void readExtension(IExtension extension) {
154: readElements(extension.getConfigurationElements());
155: }
156:
157: /**
158: * Start the registry reading process using the
159: * supplied plugin ID and extension point.
160: */
161: /*package*/void readRegistry(IExtensionRegistry registry,
162: String pluginId, String extensionPoint) {
163: IExtensionPoint point = registry.getExtensionPoint(pluginId,
164: extensionPoint);
165: if (point != null) {
166: IExtension[] extensions = point.getExtensions();
167: extensions = orderExtensions(extensions);
168: for (int i = 0; i < extensions.length; i++)
169: readExtension(extensions[i]);
170: }
171: }
172: }
|