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