refactory: added UI removed from core plugin.
[phpeclipse.git] / net.sourceforge.phpeclipse.ui / src / net / sourceforge / phpdt / internal / ui / text / java / hover / JavaEditorTextHoverDescriptor.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2003 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11
12 package net.sourceforge.phpdt.internal.ui.text.java.hover;
13
14 import java.text.Collator;
15 import java.util.ArrayList;
16 import java.util.Collections;
17 import java.util.HashMap;
18 import java.util.List;
19 import java.util.StringTokenizer;
20
21 import net.sourceforge.phpdt.ui.PreferenceConstants;
22 import net.sourceforge.phpdt.ui.text.java.hover.IJavaEditorTextHover;
23 //import net.sourceforge.phpeclipse.PHPeclipsePlugin;
24 import net.sourceforge.phpeclipse.phpeditor.EditorUtility;
25 import net.sourceforge.phpeclipse.ui.WebUI;
26
27 import org.eclipse.core.runtime.CoreException;
28 import org.eclipse.core.runtime.IConfigurationElement;
29 import org.eclipse.core.runtime.IExtensionRegistry;
30 import org.eclipse.core.runtime.IStatus;
31 import org.eclipse.core.runtime.Platform;
32 import org.eclipse.core.runtime.Status;
33 import org.eclipse.jface.text.Assert;
34 import org.eclipse.swt.SWT;
35 import org.osgi.framework.Bundle;
36
37 /**
38  * Describes a Java editor text hover.
39  * 
40  * @since 2.1
41  */
42 public class JavaEditorTextHoverDescriptor implements Comparable {
43
44         private static final String JAVA_EDITOR_TEXT_HOVER_EXTENSION_POINT = "net.sourceforge.phpeclipse.phpEditorTextHovers"; //$NON-NLS-1$
45
46         private static final String HOVER_TAG = "hover"; //$NON-NLS-1$
47
48         private static final String ID_ATTRIBUTE = "id"; //$NON-NLS-1$
49
50         private static final String CLASS_ATTRIBUTE = "class"; //$NON-NLS-1$
51
52         private static final String LABEL_ATTRIBUTE = "label"; //$NON-NLS-1$
53
54         private static final String ACTIVATE_PLUG_IN_ATTRIBUTE = "activate"; //$NON-NLS-1$
55
56         private static final String DESCRIPTION_ATTRIBUTE = "description"; //$NON-NLS-1$
57
58         public static final String NO_MODIFIER = "0"; //$NON-NLS-1$
59
60         public static final String DISABLED_TAG = "!"; //$NON-NLS-1$
61
62         public static final String VALUE_SEPARATOR = ";"; //$NON-NLS-1$
63
64         private int fStateMask;
65
66         private String fModifierString;
67
68         private boolean fIsEnabled;
69
70         private IConfigurationElement fElement;
71
72         /**
73          * Returns all Java editor text hovers contributed to the workbench.
74          */
75         public static JavaEditorTextHoverDescriptor[] getContributedHovers() {
76                 IExtensionRegistry registry = Platform.getExtensionRegistry();
77                 IConfigurationElement[] elements = registry
78                                 .getConfigurationElementsFor(JAVA_EDITOR_TEXT_HOVER_EXTENSION_POINT);
79                 JavaEditorTextHoverDescriptor[] hoverDescs = createDescriptors(elements);
80                 initializeFromPreferences(hoverDescs);
81                 return hoverDescs;
82         }
83
84         /**
85          * Computes the state mask for the given modifier string.
86          * 
87          * @param modifiers
88          *            the string with the modifiers, separated by '+', '-', ';', ','
89          *            or '.'
90          * @return the state mask or -1 if the input is invalid
91          */
92         public static int computeStateMask(String modifiers) {
93                 if (modifiers == null)
94                         return -1;
95
96                 if (modifiers.length() == 0)
97                         return SWT.NONE;
98
99                 int stateMask = 0;
100                 StringTokenizer modifierTokenizer = new StringTokenizer(modifiers,
101                                 ",;.:+-* "); //$NON-NLS-1$
102                 while (modifierTokenizer.hasMoreTokens()) {
103                         int modifier = EditorUtility
104                                         .findLocalizedModifier(modifierTokenizer.nextToken());
105                         if (modifier == 0 || (stateMask & modifier) == modifier)
106                                 return -1;
107                         stateMask = stateMask | modifier;
108                 }
109                 return stateMask;
110         }
111
112         /**
113          * Creates a new Java Editor text hover descriptor from the given
114          * configuration element.
115          */
116         private JavaEditorTextHoverDescriptor(IConfigurationElement element) {
117                 Assert.isNotNull(element);
118                 fElement = element;
119         }
120
121         /**
122          * Creates the Java editor text hover.
123          */
124         public IJavaEditorTextHover createTextHover() {
125                 String pluginId = fElement.getDeclaringExtension().getNamespace();
126                 boolean isHoversPlugInActivated = Platform.getBundle(pluginId)
127                                 .getState() == Bundle.ACTIVE;
128                 if (isHoversPlugInActivated || canActivatePlugIn()) {
129                         try {
130                                 return (IJavaEditorTextHover) fElement
131                                                 .createExecutableExtension(CLASS_ATTRIBUTE);
132                         } catch (CoreException x) {
133                                 WebUI.log(new Status(IStatus.ERROR, WebUI
134                                                 .getPluginId(), 0, JavaHoverMessages
135                                                 .getString("JavaTextHover.createTextHover"), null)); //$NON-NLS-1$
136                         }
137                 }
138
139                 return null;
140         }
141
142         // ---- XML Attribute accessors
143         // ---------------------------------------------
144
145         /**
146          * Returns the hover's id.
147          */
148         public String getId() {
149                 return fElement.getAttribute(ID_ATTRIBUTE);
150         }
151
152         /**
153          * Returns the hover's class name.
154          */
155         public String getHoverClassName() {
156                 return fElement.getAttribute(CLASS_ATTRIBUTE);
157         }
158
159         /**
160          * Returns the hover's label.
161          */
162         public String getLabel() {
163                 String label = fElement.getAttribute(LABEL_ATTRIBUTE);
164                 if (label != null)
165                         return label;
166
167                 // Return simple class name
168                 label = getHoverClassName();
169                 int lastDot = label.lastIndexOf('.');
170                 if (lastDot >= 0 && lastDot < label.length() - 1)
171                         return label.substring(lastDot + 1);
172                 else
173                         return label;
174         }
175
176         /**
177          * Returns the hover's description.
178          * 
179          * @return the hover's description or <code>null</code> if not provided
180          */
181         public String getDescription() {
182                 return fElement.getAttribute(DESCRIPTION_ATTRIBUTE);
183         }
184
185         public boolean canActivatePlugIn() {
186                 return Boolean.valueOf(
187                                 fElement.getAttribute(ACTIVATE_PLUG_IN_ATTRIBUTE))
188                                 .booleanValue();
189         }
190
191         public boolean equals(Object obj) {
192                 if (obj == null || !obj.getClass().equals(this.getClass())
193                                 || getId() == null)
194                         return false;
195                 return getId().equals(((JavaEditorTextHoverDescriptor) obj).getId());
196         }
197
198         public int hashCode() {
199                 return getId().hashCode();
200         }
201
202         /*
203          * Implements a method from IComparable
204          */
205         public int compareTo(Object o) {
206                 return Collator.getInstance().compare(getLabel(),
207                                 ((JavaEditorTextHoverDescriptor) o).getLabel());
208         }
209
210         // /**
211         // * @param descriptor a JavaEditorTextHoverDescriptor
212         // * @return <code>true</code> if this contributed hover depends on the
213         // other one
214         // */
215         // public boolean dependsOn(JavaEditorTextHoverDescriptor descriptor) {
216         // if (descriptor == null)
217         // return false;
218         //              
219         // IPluginDescriptor thisPluginDescriptor=
220         // fElement.getDeclaringExtension().getDeclaringPluginDescriptor();
221         // IPluginDescriptor otherPluginDescriptor=
222         // descriptor.fElement.getDeclaringExtension().getDeclaringPluginDescriptor();
223         // return dependsOn(thisPluginDescriptor, otherPluginDescriptor);
224         // }
225
226         // private boolean dependsOn(IPluginDescriptor descriptor0,
227         // IPluginDescriptor descriptor1) {
228         //
229         // IPluginRegistry registry= Platform.getPluginRegistry();
230         // IPluginPrerequisite[] prerequisites=
231         // descriptor0.getPluginPrerequisites();
232         //
233         // for (int i= 0; i < prerequisites.length; i++) {
234         // IPluginPrerequisite prerequisite= prerequisites[i];
235         // String id= prerequisite.getUniqueIdentifier();
236         // IPluginDescriptor descriptor= registry.getPluginDescriptor(id);
237         //                      
238         // if (descriptor != null && (descriptor.equals(descriptor1) ||
239         // dependsOn(descriptor, descriptor1)))
240         // return true;
241         // }
242         //              
243         // return false;
244         // }
245
246         private static JavaEditorTextHoverDescriptor[] createDescriptors(
247                         IConfigurationElement[] elements) {
248                 List result = new ArrayList(elements.length);
249                 for (int i = 0; i < elements.length; i++) {
250                         IConfigurationElement element = elements[i];
251                         if (HOVER_TAG.equals(element.getName())) {
252                                 JavaEditorTextHoverDescriptor desc = new JavaEditorTextHoverDescriptor(
253                                                 element);
254                                 result.add(desc);
255                         }
256                 }
257                 Collections.sort(result);
258                 return (JavaEditorTextHoverDescriptor[]) result
259                                 .toArray(new JavaEditorTextHoverDescriptor[result.size()]);
260         }
261
262         private static void initializeFromPreferences(
263                         JavaEditorTextHoverDescriptor[] hovers) {
264                 String compiledTextHoverModifiers = WebUI.getDefault()
265                                 .getPreferenceStore().getString(
266                                                 PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIERS);
267
268                 StringTokenizer tokenizer = new StringTokenizer(
269                                 compiledTextHoverModifiers, VALUE_SEPARATOR);
270                 HashMap idToModifier = new HashMap(tokenizer.countTokens() / 2);
271
272                 while (tokenizer.hasMoreTokens()) {
273                         String id = tokenizer.nextToken();
274                         if (tokenizer.hasMoreTokens())
275                                 idToModifier.put(id, tokenizer.nextToken());
276                 }
277
278                 String compiledTextHoverModifierMasks = WebUI.getDefault()
279                                 .getPreferenceStore().getString(
280                                                 PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIER_MASKS);
281
282                 tokenizer = new StringTokenizer(compiledTextHoverModifierMasks,
283                                 VALUE_SEPARATOR);
284                 HashMap idToModifierMask = new HashMap(tokenizer.countTokens() / 2);
285
286                 while (tokenizer.hasMoreTokens()) {
287                         String id = tokenizer.nextToken();
288                         if (tokenizer.hasMoreTokens())
289                                 idToModifierMask.put(id, tokenizer.nextToken());
290                 }
291
292                 for (int i = 0; i < hovers.length; i++) {
293                         String modifierString = (String) idToModifier
294                                         .get(hovers[i].getId());
295                         boolean enabled = true;
296                         if (modifierString == null)
297                                 modifierString = DISABLED_TAG;
298
299                         if (modifierString.startsWith(DISABLED_TAG)) {
300                                 enabled = false;
301                                 modifierString = modifierString.substring(1);
302                         }
303
304                         if (modifierString.equals(NO_MODIFIER))
305                                 modifierString = ""; //$NON-NLS-1$
306
307                         hovers[i].fModifierString = modifierString;
308                         hovers[i].fIsEnabled = enabled;
309                         hovers[i].fStateMask = computeStateMask(modifierString);
310                         if (hovers[i].fStateMask == -1) {
311                                 // Fallback: use stored modifier masks
312                                 try {
313                                         hovers[i].fStateMask = Integer
314                                                         .parseInt((String) idToModifierMask.get(hovers[i]
315                                                                         .getId()));
316                                 } catch (NumberFormatException ex) {
317                                         hovers[i].fStateMask = -1;
318                                 }
319                                 // Fix modifier string
320                                 int stateMask = hovers[i].fStateMask;
321                                 if (stateMask == -1)
322                                         hovers[i].fModifierString = ""; //$NON-NLS-1$
323                                 else
324                                         hovers[i].fModifierString = EditorUtility
325                                                         .getModifierString(stateMask);
326                         }
327                 }
328         }
329
330         /**
331          * Returns the configured modifier getStateMask for this hover.
332          * 
333          * @return the hover modifier stateMask or -1 if no hover is configured
334          */
335         public int getStateMask() {
336                 return fStateMask;
337         }
338
339         /**
340          * Returns the modifier String as set in the preference store.
341          * 
342          * @return the modifier string
343          */
344         public String getModifierString() {
345                 return fModifierString;
346         }
347
348         /**
349          * Returns whether this hover is enabled or not.
350          * 
351          * @return <code>true</code> if enabled
352          */
353         public boolean isEnabled() {
354                 return fIsEnabled;
355         }
356
357         /**
358          * Returns this hover descriptors configuration element.
359          * 
360          * @return the configuration element
361          * @since 3.0
362          */
363         public IConfigurationElement getConfigurationElement() {
364                 return fElement;
365         }
366 }