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