001: /*******************************************************************************
002: * Copyright (c) 2000, 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.jdt.internal.ui.text.java.hover;
011:
012: import java.util.ArrayList;
013: import java.util.HashMap;
014: import java.util.List;
015: import java.util.StringTokenizer;
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.IStatus;
022: import org.eclipse.core.runtime.Platform;
023: import org.eclipse.core.runtime.Status;
024:
025: import org.eclipse.swt.SWT;
026:
027: import org.eclipse.jdt.ui.PreferenceConstants;
028: import org.eclipse.jdt.ui.text.java.hover.IJavaEditorTextHover;
029:
030: import org.eclipse.jdt.internal.ui.JavaPlugin;
031: import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility;
032:
033: import org.osgi.framework.Bundle;
034:
035: /**
036: * Describes a Java editor text hover.
037: *
038: * @since 2.1
039: */
040: public class JavaEditorTextHoverDescriptor {
041:
042: private static final String JAVA_EDITOR_TEXT_HOVER_EXTENSION_POINT = "org.eclipse.jdt.ui.javaEditorTextHovers"; //$NON-NLS-1$
043: private static final String HOVER_TAG = "hover"; //$NON-NLS-1$
044: private static final String ID_ATTRIBUTE = "id"; //$NON-NLS-1$
045: private static final String CLASS_ATTRIBUTE = "class"; //$NON-NLS-1$
046: private static final String LABEL_ATTRIBUTE = "label"; //$NON-NLS-1$
047: private static final String ACTIVATE_PLUG_IN_ATTRIBUTE = "activate"; //$NON-NLS-1$
048: private static final String DESCRIPTION_ATTRIBUTE = "description"; //$NON-NLS-1$
049:
050: public static final String NO_MODIFIER = "0"; //$NON-NLS-1$
051: public static final String DISABLED_TAG = "!"; //$NON-NLS-1$
052: public static final String VALUE_SEPARATOR = ";"; //$NON-NLS-1$
053:
054: private int fStateMask;
055: private String fModifierString;
056: private boolean fIsEnabled;
057:
058: private IConfigurationElement fElement;
059:
060: /**
061: * Returns all Java editor text hovers contributed to the workbench.
062: *
063: * @return an array with the contributed text hovers
064: */
065: public static JavaEditorTextHoverDescriptor[] getContributedHovers() {
066: IExtensionRegistry registry = Platform.getExtensionRegistry();
067: IConfigurationElement[] elements = registry
068: .getConfigurationElementsFor(JAVA_EDITOR_TEXT_HOVER_EXTENSION_POINT);
069: JavaEditorTextHoverDescriptor[] hoverDescs = createDescriptors(elements);
070: initializeFromPreferences(hoverDescs);
071: return hoverDescs;
072: }
073:
074: /**
075: * Computes the state mask for the given modifier string.
076: *
077: * @param modifiers the string with the modifiers, separated by '+', '-', ';', ',' or '.'
078: * @return the state mask or -1 if the input is invalid
079: */
080: public static int computeStateMask(String modifiers) {
081: if (modifiers == null)
082: return -1;
083:
084: if (modifiers.length() == 0)
085: return SWT.NONE;
086:
087: int stateMask = 0;
088: StringTokenizer modifierTokenizer = new StringTokenizer(
089: modifiers, ",;.:+-* "); //$NON-NLS-1$
090: while (modifierTokenizer.hasMoreTokens()) {
091: int modifier = EditorUtility
092: .findLocalizedModifier(modifierTokenizer
093: .nextToken());
094: if (modifier == 0 || (stateMask & modifier) == modifier)
095: return -1;
096: stateMask = stateMask | modifier;
097: }
098: return stateMask;
099: }
100:
101: /**
102: * Creates a new Java Editor text hover descriptor from the given configuration element.
103: *
104: * @param element the configuration element
105: */
106: private JavaEditorTextHoverDescriptor(IConfigurationElement element) {
107: Assert.isNotNull(element);
108: fElement = element;
109: }
110:
111: /**
112: * Creates the Java editor text hover.
113: *
114: * @return the text hover
115: */
116: public IJavaEditorTextHover createTextHover() {
117: String pluginId = fElement.getContributor().getName();
118: boolean isHoversPlugInActivated = Platform.getBundle(pluginId)
119: .getState() == Bundle.ACTIVE;
120: if (isHoversPlugInActivated || canActivatePlugIn()) {
121: try {
122: return (IJavaEditorTextHover) fElement
123: .createExecutableExtension(CLASS_ATTRIBUTE);
124: } catch (CoreException x) {
125: JavaPlugin
126: .log(new Status(
127: IStatus.ERROR,
128: JavaPlugin.getPluginId(),
129: 0,
130: JavaHoverMessages.JavaTextHover_createTextHover,
131: null));
132: }
133: }
134:
135: return null;
136: }
137:
138: //---- XML Attribute accessors ---------------------------------------------
139:
140: /**
141: * Returns the hover's id.
142: *
143: * @return the id
144: */
145: public String getId() {
146: return fElement.getAttribute(ID_ATTRIBUTE);
147: }
148:
149: /**
150: * Returns the hover's class name.
151: *
152: * @return the class name
153: */
154: public String getHoverClassName() {
155: return fElement.getAttribute(CLASS_ATTRIBUTE);
156: }
157:
158: /**
159: * Returns the hover's label.
160: *
161: * @return the label
162: */
163: public String getLabel() {
164: String label = fElement.getAttribute(LABEL_ATTRIBUTE);
165: if (label != null)
166: return label;
167:
168: // Return simple class name
169: label = getHoverClassName();
170: int lastDot = label.lastIndexOf('.');
171: if (lastDot >= 0 && lastDot < label.length() - 1)
172: return label.substring(lastDot + 1);
173: else
174: return label;
175: }
176:
177: /**
178: * Returns the hover's description.
179: *
180: * @return the hover's description or <code>null</code> if not provided
181: */
182: public String getDescription() {
183: return fElement.getAttribute(DESCRIPTION_ATTRIBUTE);
184: }
185:
186: public boolean canActivatePlugIn() {
187: return Boolean.valueOf(
188: fElement.getAttribute(ACTIVATE_PLUG_IN_ATTRIBUTE))
189: .booleanValue();
190: }
191:
192: public boolean equals(Object obj) {
193: if (obj == null || !obj.getClass().equals(this .getClass())
194: || getId() == null)
195: return false;
196: return getId().equals(
197: ((JavaEditorTextHoverDescriptor) obj).getId());
198: }
199:
200: public int hashCode() {
201: return getId().hashCode();
202: }
203:
204: private static JavaEditorTextHoverDescriptor[] createDescriptors(
205: IConfigurationElement[] elements) {
206: List result = new ArrayList(elements.length);
207: for (int i = 0; i < elements.length; i++) {
208: IConfigurationElement element = elements[i];
209: if (HOVER_TAG.equals(element.getName())) {
210: JavaEditorTextHoverDescriptor desc = new JavaEditorTextHoverDescriptor(
211: element);
212: result.add(desc);
213: }
214: }
215: return (JavaEditorTextHoverDescriptor[]) result
216: .toArray(new JavaEditorTextHoverDescriptor[result
217: .size()]);
218: }
219:
220: private static void initializeFromPreferences(
221: JavaEditorTextHoverDescriptor[] hovers) {
222: String compiledTextHoverModifiers = JavaPlugin
223: .getDefault()
224: .getPreferenceStore()
225: .getString(
226: PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIERS);
227:
228: StringTokenizer tokenizer = new StringTokenizer(
229: compiledTextHoverModifiers, VALUE_SEPARATOR);
230: HashMap idToModifier = new HashMap(tokenizer.countTokens() / 2);
231:
232: while (tokenizer.hasMoreTokens()) {
233: String id = tokenizer.nextToken();
234: if (tokenizer.hasMoreTokens())
235: idToModifier.put(id, tokenizer.nextToken());
236: }
237:
238: String compiledTextHoverModifierMasks = JavaPlugin
239: .getDefault()
240: .getPreferenceStore()
241: .getString(
242: PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIER_MASKS);
243:
244: tokenizer = new StringTokenizer(compiledTextHoverModifierMasks,
245: VALUE_SEPARATOR);
246: HashMap idToModifierMask = new HashMap(
247: tokenizer.countTokens() / 2);
248:
249: while (tokenizer.hasMoreTokens()) {
250: String id = tokenizer.nextToken();
251: if (tokenizer.hasMoreTokens())
252: idToModifierMask.put(id, tokenizer.nextToken());
253: }
254:
255: for (int i = 0; i < hovers.length; i++) {
256: String modifierString = (String) idToModifier.get(hovers[i]
257: .getId());
258: boolean enabled = true;
259: if (modifierString == null)
260: modifierString = DISABLED_TAG;
261:
262: if (modifierString.startsWith(DISABLED_TAG)) {
263: enabled = false;
264: modifierString = modifierString.substring(1);
265: }
266:
267: if (modifierString.equals(NO_MODIFIER))
268: modifierString = ""; //$NON-NLS-1$
269:
270: hovers[i].fModifierString = modifierString;
271: hovers[i].fIsEnabled = enabled;
272: hovers[i].fStateMask = computeStateMask(modifierString);
273: if (hovers[i].fStateMask == -1) {
274: // Fallback: use stored modifier masks
275: try {
276: hovers[i].fStateMask = Integer
277: .parseInt((String) idToModifierMask
278: .get(hovers[i].getId()));
279: } catch (NumberFormatException ex) {
280: hovers[i].fStateMask = -1;
281: }
282: // Fix modifier string
283: int stateMask = hovers[i].fStateMask;
284: if (stateMask == -1)
285: hovers[i].fModifierString = ""; //$NON-NLS-1$
286: else
287: hovers[i].fModifierString = EditorUtility
288: .getModifierString(stateMask);
289: }
290: }
291: }
292:
293: /**
294: * Returns the configured modifier getStateMask for this hover.
295: *
296: * @return the hover modifier stateMask or -1 if no hover is configured
297: */
298: public int getStateMask() {
299: return fStateMask;
300: }
301:
302: /**
303: * Returns the modifier String as set in the preference store.
304: *
305: * @return the modifier string
306: */
307: public String getModifierString() {
308: return fModifierString;
309: }
310:
311: /**
312: * Returns whether this hover is enabled or not.
313: *
314: * @return <code>true</code> if enabled
315: */
316: public boolean isEnabled() {
317: return fIsEnabled;
318: }
319:
320: /**
321: * Returns this hover descriptors configuration element.
322: *
323: * @return the configuration element
324: * @since 3.0
325: */
326: public IConfigurationElement getConfigurationElement() {
327: return fElement;
328: }
329: }
|