1 11 package org.eclipse.ui; 12 13 import java.lang.reflect.InvocationTargetException ; 14 import java.lang.reflect.Method ; 15 import java.util.ArrayList ; 16 import java.util.Iterator ; 17 import java.util.List ; 18 19 import org.eclipse.core.runtime.IAdaptable; 20 import org.eclipse.core.runtime.IConfigurationElement; 21 import org.eclipse.core.runtime.Platform; 22 import org.eclipse.jface.viewers.ISelection; 23 import org.eclipse.jface.viewers.IStructuredSelection; 24 import org.eclipse.jface.viewers.StructuredSelection; 25 import org.eclipse.ui.actions.SimpleWildcardTester; 26 import org.eclipse.ui.internal.ActionExpression; 27 import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants; 28 import org.eclipse.ui.internal.util.Util; 29 import org.eclipse.ui.model.IWorkbenchAdapter; 30 import org.osgi.framework.Bundle; 31 32 50 public final class SelectionEnabler { 51 52 static class SelectionClass { 53 public String className; 54 55 public String nameFilter; 56 57 public boolean recursive; 58 } 59 60 public static final int ANY_NUMBER = -2; 61 62 66 private static final int HASH_CODE_NOT_COMPUTED = -1; 67 68 71 private static final int HASH_FACTOR = 89; 72 73 76 private static final int HASH_INITIAL = SelectionEnabler.class.getName() 77 .hashCode(); 78 79 83 private static Class iTextSelectionClass = null; 84 85 88 private static final String JFACE_TEXT_PLUG_IN = "org.eclipse.jface.text"; 90 public static final int MULTIPLE = -5; 91 92 public static final int NONE = -4; 93 94 public static final int NONE_OR_ONE = -3; 95 96 public static final int ONE_OR_MORE = -1; 97 98 102 private static final String TEXT_SELECTION_CLASS = "org.eclipse.jface.text.ITextSelection"; 104 108 private static boolean textSelectionPossible = true; 109 110 public static final int UNKNOWN = 0; 111 112 120 private static Class getTextSelectionClass() { 121 if (iTextSelectionClass != null) { 122 return iTextSelectionClass; 124 } 125 if (!textSelectionPossible) { 126 return null; 128 } 129 130 Bundle bundle = Platform.getBundle(JFACE_TEXT_PLUG_IN); 135 if (bundle == null || bundle.getState() == Bundle.UNINSTALLED) { 136 textSelectionPossible = false; 139 return null; 140 } 141 142 if (bundle.getState() == Bundle.INSTALLED) { 145 textSelectionPossible = true; 147 return null; 148 } 149 150 try { 151 Class c = bundle.loadClass(TEXT_SELECTION_CLASS); 152 iTextSelectionClass = c; 154 return iTextSelectionClass; 155 } catch (ClassNotFoundException e) { 156 textSelectionPossible = false; 159 return null; 160 } 161 } 162 163 171 public static boolean verifyNameMatch(String name, String filter) { 172 return SimpleWildcardTester.testWildcardIgnoreCase(filter, name); 173 } 174 175 private List classes = new ArrayList (); 176 177 private ActionExpression enablementExpression; 178 179 183 private transient int hashCode = HASH_CODE_NOT_COMPUTED; 184 185 private int mode = UNKNOWN; 186 187 192 public SelectionEnabler(IConfigurationElement configElement) { 193 super(); 194 if (configElement == null) { 195 throw new IllegalArgumentException (); 196 } 197 parseClasses(configElement); 198 } 199 200 public final boolean equals(final Object object) { 201 if (object instanceof SelectionEnabler) { 202 final SelectionEnabler that = (SelectionEnabler) object; 203 return Util.equals(this.classes, that.classes) 204 && Util.equals(this.enablementExpression, 205 that.enablementExpression) 206 && Util.equals(this.mode, that.mode); 207 } 208 209 return false; 210 } 211 212 217 public final int hashCode() { 218 if (hashCode == HASH_CODE_NOT_COMPUTED) { 219 hashCode = HASH_INITIAL * HASH_FACTOR + Util.hashCode(classes); 220 hashCode = hashCode * HASH_FACTOR 221 + Util.hashCode(enablementExpression); 222 hashCode = hashCode * HASH_FACTOR + Util.hashCode(mode); 223 if (hashCode == HASH_CODE_NOT_COMPUTED) { 224 hashCode++; 225 } 226 } 227 return hashCode; 228 } 229 230 234 private boolean isEnabledFor(ISelection sel) { 235 Object obj = sel; 236 int count = sel.isEmpty() ? 0 : 1; 237 238 if (verifySelectionCount(count) == false) { 239 return false; 240 } 241 242 if (enablementExpression != null) { 244 return enablementExpression.isEnabledFor(obj); 245 } 246 247 if (classes.isEmpty()) { 249 return true; 250 } 251 if (obj instanceof IAdaptable) { 252 IAdaptable element = (IAdaptable) obj; 253 if (verifyElement(element) == false) { 254 return false; 255 } 256 } else { 257 return false; 258 } 259 260 return true; 261 } 262 263 267 private boolean isEnabledFor(ISelection sel, int count) { 268 if (verifySelectionCount(count) == false) { 269 return false; 270 } 271 272 if (enablementExpression != null) { 274 return enablementExpression.isEnabledFor(sel); 275 } 276 277 if (classes.isEmpty()) { 279 return true; 280 } 281 for (int i = 0; i < classes.size(); i++) { 282 SelectionClass sc = (SelectionClass) classes.get(i); 283 if (verifyClass(sel, sc.className)) { 284 return true; 285 } 286 } 287 return false; 288 } 289 290 294 private boolean isEnabledFor(IStructuredSelection ssel) { 295 int count = ssel.size(); 296 297 if (verifySelectionCount(count) == false) { 298 return false; 299 } 300 301 if (enablementExpression != null) { 303 return enablementExpression.isEnabledFor(ssel); 304 } 305 306 if (classes.isEmpty()) { 308 return true; 309 } 310 for (Iterator elements = ssel.iterator(); elements.hasNext();) { 311 Object obj = elements.next(); 312 if (obj instanceof IAdaptable) { 313 IAdaptable element = (IAdaptable) obj; 314 if (verifyElement(element) == false) { 315 return false; 316 } 317 } else { 318 return false; 319 } 320 } 321 322 return true; 323 } 324 325 332 public boolean isEnabledForSelection(ISelection selection) { 333 if (mode == UNKNOWN) { 335 return false; 336 } 337 338 if (selection == null) { 340 selection = StructuredSelection.EMPTY; 341 } 342 343 347 if (selection instanceof IStructuredSelection) { 349 return isEnabledFor((IStructuredSelection) selection); 350 } 351 352 Class tselClass = getTextSelectionClass(); 361 if (tselClass != null && tselClass.isInstance(selection)) { 362 try { 363 Method m = tselClass.getDeclaredMethod( 364 "getLength", new Class [0]); Object r = m.invoke(selection, new Object [0]); 366 if (r instanceof Integer ) { 367 return isEnabledFor(selection, ((Integer ) r).intValue()); 368 } 369 return true; 371 } catch (NoSuchMethodException e) { 372 } catch (IllegalAccessException e) { 374 } catch (InvocationTargetException e) { 376 } 378 } 379 380 return isEnabledFor(selection); 382 } 383 384 388 private void parseClasses(IConfigurationElement config) { 389 String enablesFor = config 391 .getAttribute(IWorkbenchRegistryConstants.ATT_ENABLES_FOR); 392 if (enablesFor == null) { 393 enablesFor = "*"; } 395 if (enablesFor.equals("*")) { mode = ANY_NUMBER; 397 } else if (enablesFor.equals("?")) { mode = NONE_OR_ONE; 399 } else if (enablesFor.equals("!")) { mode = NONE; 401 } else if (enablesFor.equals("+")) { mode = ONE_OR_MORE; 403 } else if (enablesFor.equals("multiple") || enablesFor.equals("2+")) { mode = MULTIPLE; 406 } else { 407 try { 408 mode = Integer.parseInt(enablesFor); 409 } catch (NumberFormatException e) { 410 mode = UNKNOWN; 411 } 412 } 413 414 IConfigurationElement[] children = config 416 .getChildren(IWorkbenchRegistryConstants.TAG_ENABLEMENT); 417 if (children.length > 0) { 418 enablementExpression = new ActionExpression(children[0]); 419 return; 420 } 421 422 children = config 424 .getChildren(IWorkbenchRegistryConstants.TAG_SELECTION); 425 if (children.length > 0) { 426 classes = new ArrayList (); 427 for (int i = 0; i < children.length; i++) { 428 IConfigurationElement sel = children[i]; 429 String cname = sel 430 .getAttribute(IWorkbenchRegistryConstants.ATT_CLASS); 431 String name = sel 432 .getAttribute(IWorkbenchRegistryConstants.ATT_NAME); 433 SelectionClass sclass = new SelectionClass(); 434 sclass.className = cname; 435 sclass.nameFilter = name; 436 classes.add(sclass); 437 } 438 } 439 } 440 441 446 private boolean verifyClass(Object element, String className) { 447 Class eclass = element.getClass(); 448 Class clazz = eclass; 449 boolean match = false; 450 while (clazz != null) { 451 if (clazz.getName().equals(className)) { 453 match = true; 454 break; 455 } 456 Class [] interfaces = clazz.getInterfaces(); 458 for (int i = 0; i < interfaces.length; i++) { 459 if (interfaces[i].getName().equals(className)) { 460 match = true; 461 break; 462 } 463 } 464 if (match == true) { 465 break; 466 } 467 clazz = clazz.getSuperclass(); 469 } 470 return match; 471 } 472 473 478 private boolean verifyElement(IAdaptable element) { 479 if (classes.isEmpty()) { 480 return true; 481 } 482 for (int i = 0; i < classes.size(); i++) { 483 SelectionClass sc = (SelectionClass) classes.get(i); 484 if (verifyClass(element, sc.className) == false) { 485 continue; 486 } 487 if (sc.nameFilter == null) { 488 return true; 489 } 490 IWorkbenchAdapter de = (IWorkbenchAdapter) Util.getAdapter(element, IWorkbenchAdapter.class); 491 if ((de != null) 492 && verifyNameMatch(de.getLabel(element), sc.nameFilter)) { 493 return true; 494 } 495 } 496 return false; 497 } 498 499 502 private boolean verifySelectionCount(int count) { 503 if (count > 0 && mode == NONE) { 504 return false; 505 } 506 if (count == 0 && mode == ONE_OR_MORE) { 507 return false; 508 } 509 if (count > 1 && mode == NONE_OR_ONE) { 510 return false; 511 } 512 if (count < 2 && mode == MULTIPLE) { 513 return false; 514 } 515 if (mode > 0 && count != mode) { 516 return false; 517 } 518 return true; 519 } 520 } 521 | Popular Tags |