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