001: /*******************************************************************************
002: * Copyright (c) 2007 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.texteditor;
011:
012: import java.util.ArrayList;
013: import java.util.List;
014:
015: import org.osgi.framework.Bundle;
016:
017: import org.eclipse.core.runtime.Assert;
018: import org.eclipse.core.runtime.CoreException;
019: import org.eclipse.core.runtime.IConfigurationElement;
020: import org.eclipse.core.runtime.IExtensionRegistry;
021: import org.eclipse.core.runtime.ISafeRunnable;
022: import org.eclipse.core.runtime.IStatus;
023: import org.eclipse.core.runtime.Platform;
024: import org.eclipse.core.runtime.SafeRunner;
025: import org.eclipse.core.runtime.Status;
026:
027: import org.eclipse.jface.util.SafeRunnable;
028:
029: import org.eclipse.jface.text.hyperlink.AbstractHyperlinkDetector;
030: import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
031:
032: import org.eclipse.ui.internal.texteditor.NLSUtility;
033: import org.eclipse.ui.internal.texteditor.TextEditorPlugin;
034:
035: /**
036: * Describes a contribution to the 'org.eclipse.ui.workbench.texteditor.hyperlinkDetectors'
037: * extension point.
038: *
039: * @since 3.3
040: */
041: public final class HyperlinkDetectorDescriptor {
042:
043: public static final String STATE_MASK_POSTFIX = "_stateMask"; //$NON-NLS-1$
044:
045: private static final String HYPERLINK_DETECTORS_EXTENSION_POINT = "org.eclipse.ui.workbench.texteditor.hyperlinkDetectors"; //$NON-NLS-1$
046: private static final String HYPERLINK_DETECTOR_ELEMENT = "hyperlinkDetector"; //$NON-NLS-1$
047: private static final String ID_ATTRIBUTE = "id"; //$NON-NLS-1$
048: private static final String NAME_ATTRIBUTE = "name"; //$NON-NLS-1$
049: private static final String DESCRIPTION_ATTRIBUTE = "description"; //$NON-NLS-1$
050: private static final String TARGET_ID_ATTRIBUTE = "targetId"; //$NON-NLS-1$
051: private static final String CLASS_ATTRIBUTE = "class"; //$NON-NLS-1$
052: private static final String ACTIVATE_PLUG_IN_ATTRIBUTE = "activate"; //$NON-NLS-1$
053: private static final String MODIFIER_KEYS = "modifierKeys"; //$NON-NLS-1$
054:
055: private IConfigurationElement fElement;
056: private HyperlinkDetectorTargetDescriptor fTarget;
057:
058: /**
059: * Returns descriptors for all hyperlink detector extensions.
060: *
061: * @return an array with the contributed hyperlink detectors
062: */
063: public static HyperlinkDetectorDescriptor[] getContributedHyperlinkDetectors() {
064: IExtensionRegistry registry = Platform.getExtensionRegistry();
065: IConfigurationElement[] elements = registry
066: .getConfigurationElementsFor(HYPERLINK_DETECTORS_EXTENSION_POINT);
067: HyperlinkDetectorDescriptor[] hyperlinkDetectorDescs = createDescriptors(elements);
068: return hyperlinkDetectorDescs;
069: }
070:
071: /**
072: * Creates a new descriptor from the given configuration element.
073: *
074: * @param element the configuration element
075: */
076: private HyperlinkDetectorDescriptor(IConfigurationElement element) {
077: Assert.isNotNull(element);
078: fElement = element;
079: }
080:
081: /**
082: * Creates a new {@link IHyperlinkDetector}.
083: *
084: * @return the hyperlink detector or <code>null</code> if the plug-in isn't loaded yet
085: * @throws CoreException if a failure occurred during creation
086: */
087: public AbstractHyperlinkDetector createHyperlinkDetector()
088: throws CoreException {
089: final Throwable[] exception = new Throwable[1];
090: final AbstractHyperlinkDetector[] result = new AbstractHyperlinkDetector[1];
091: String message = NLSUtility
092: .format(
093: EditorMessages.Editor_error_HyperlinkDetector_couldNotCreate_message,
094: new String[] { getId(),
095: fElement.getContributor().getName() });
096: ISafeRunnable code = new SafeRunnable(message) {
097: /*
098: * @see org.eclipse.core.runtime.ISafeRunnable#run()
099: */
100: public void run() throws Exception {
101: String pluginId = fElement.getContributor().getName();
102: boolean isPlugInActivated = Platform
103: .getBundle(pluginId).getState() == Bundle.ACTIVE;
104: if (isPlugInActivated || canActivatePlugIn())
105: result[0] = (AbstractHyperlinkDetector) fElement
106: .createExecutableExtension(CLASS_ATTRIBUTE);
107: }
108:
109: /*
110: * @see org.eclipse.jface.util.SafeRunnable#handleException(java.lang.Throwable)
111: */
112: public void handleException(Throwable ex) {
113: super .handleException(ex);
114: exception[0] = ex;
115: }
116:
117: };
118:
119: SafeRunner.run(code);
120:
121: if (exception[0] == null)
122: return result[0];
123: throw new CoreException(new Status(IStatus.ERROR,
124: TextEditorPlugin.PLUGIN_ID, IStatus.OK, message,
125: exception[0]));
126:
127: }
128:
129: private boolean isValid(HyperlinkDetectorTargetDescriptor[] targets) {
130: if (getId() == null || getName() == null
131: || getTargetId() == null)
132: return false;
133:
134: String targetId = getTargetId();
135: for (int i = 0; i < targets.length; i++) {
136: if (targetId.equals(targets[i].getId())) {
137: fTarget = targets[i];
138: return true;
139: }
140: }
141: return false;
142:
143: }
144:
145: //---- XML Attribute accessors ---------------------------------------------
146:
147: /**
148: * Returns the hyperlink detector's id.
149: *
150: * @return the hyperlink detector's id
151: */
152: public String getId() {
153: return fElement.getAttribute(ID_ATTRIBUTE);
154: }
155:
156: /**
157: * Returns the hyperlink detector's name.
158: *
159: * @return the hyperlink detector's name
160: */
161: public String getName() {
162: return fElement.getAttribute(NAME_ATTRIBUTE);
163: }
164:
165: /**
166: * Returns the hyperlink detector's target descriptor.
167: *
168: * @return the hyperlink detector's target descriptor
169: */
170: public HyperlinkDetectorTargetDescriptor getTarget() {
171: return fTarget;
172: }
173:
174: /**
175: * Returns the hyperlink detector's target id.
176: *
177: * @return the hyperlink detector's target id
178: */
179: public String getTargetId() {
180: return fElement.getAttribute(TARGET_ID_ATTRIBUTE);
181: }
182:
183: /**
184: * Returns the hyperlink detector's description.
185: *
186: * @return the hyperlink detector's description or <code>null</code> if not provided
187: */
188: public String getDescription() {
189: return fElement.getAttribute(DESCRIPTION_ATTRIBUTE);
190: }
191:
192: /**
193: * Returns the hyperlink detector's modifier keys that
194: * need to be pressed for this hyperlink detector.
195: *
196: * @return the hyperlink detector's description or <code>null</code> if not provided
197: */
198: public String getModifierKeys() {
199: return fElement.getAttribute(MODIFIER_KEYS);
200: }
201:
202: public boolean canActivatePlugIn() {
203: String value = fElement
204: .getAttribute(ACTIVATE_PLUG_IN_ATTRIBUTE);
205: if (value == null)
206: return true;
207: return Boolean.valueOf(value).booleanValue();
208: }
209:
210: public boolean equals(Object obj) {
211: if (obj == null || !obj.getClass().equals(this .getClass())
212: || getId() == null)
213: return false;
214: return getId().equals(
215: ((HyperlinkDetectorDescriptor) obj).getId());
216: }
217:
218: public int hashCode() {
219: return getId().hashCode();
220: }
221:
222: private static HyperlinkDetectorDescriptor[] createDescriptors(
223: IConfigurationElement[] elements) {
224: HyperlinkDetectorTargetDescriptor[] targets = HyperlinkDetectorTargetDescriptor
225: .getContributedHyperlinkDetectorTargets();
226: List result = new ArrayList(elements.length);
227: for (int i = 0; i < elements.length; i++) {
228: IConfigurationElement element = elements[i];
229: if (HYPERLINK_DETECTOR_ELEMENT.equals(element.getName())) {
230: HyperlinkDetectorDescriptor desc = new HyperlinkDetectorDescriptor(
231: element);
232: if (desc.isValid(targets))
233: result.add(desc);
234: else {
235: String message = NLSUtility
236: .format(
237: EditorMessages.Editor_error_HyperlinkDetector_invalidExtension_message,
238: new String[] {
239: desc.getId(),
240: element.getContributor()
241: .getName() });
242: TextEditorPlugin.getDefault().getLog().log(
243: new Status(IStatus.ERROR,
244: TextEditorPlugin.PLUGIN_ID,
245: IStatus.OK, message, null));
246: }
247: } else {
248: String message = NLSUtility
249: .format(
250: EditorMessages.Editor_error_HyperlinkDetector_invalidElementName_message,
251: new String[] {
252: element.getContributor()
253: .getName(),
254: element.getName() });
255: TextEditorPlugin.getDefault().getLog().log(
256: new Status(IStatus.ERROR,
257: TextEditorPlugin.PLUGIN_ID, IStatus.OK,
258: message, null));
259: }
260: }
261: return (HyperlinkDetectorDescriptor[]) result
262: .toArray(new HyperlinkDetectorDescriptor[result.size()]);
263: }
264:
265: }
|