1 11 package org.eclipse.jdt.internal.ui.text.java; 12 13 import java.util.Collections ; 14 import java.util.HashSet ; 15 import java.util.Iterator ; 16 import java.util.List ; 17 import java.util.Set ; 18 19 import org.eclipse.core.runtime.Assert; 20 import org.eclipse.core.runtime.CoreException; 21 import org.eclipse.core.runtime.IConfigurationElement; 22 import org.eclipse.core.runtime.IContributor; 23 import org.eclipse.core.runtime.IExtension; 24 import org.eclipse.core.runtime.IProgressMonitor; 25 import org.eclipse.core.runtime.IStatus; 26 import org.eclipse.core.runtime.InvalidRegistryObjectException; 27 import org.eclipse.core.runtime.PerformanceStats; 28 import org.eclipse.core.runtime.Platform; 29 import org.eclipse.core.runtime.Status; 30 31 import org.eclipse.jface.text.IDocument; 32 33 import org.eclipse.jdt.internal.corext.util.Messages; 34 35 import org.eclipse.jdt.ui.text.IJavaPartitions; 36 import org.eclipse.jdt.ui.text.java.ContentAssistInvocationContext; 37 import org.eclipse.jdt.ui.text.java.IJavaCompletionProposalComputer; 38 39 import org.eclipse.jdt.internal.ui.JavaPlugin; 40 41 import org.osgi.framework.Bundle; 42 43 51 final class CompletionProposalComputerDescriptor { 52 53 private static final String DEFAULT_CATEGORY_ID= "org.eclipse.jdt.ui.defaultProposalCategory"; 55 private static final String CATEGORY_ID= "categoryId"; 57 private static final String TYPE= "type"; 59 private static final String CLASS= "class"; 61 private static final String ACTIVATE= "activate"; 63 private static final String PARTITION= "partition"; 65 private static final Set PARTITION_SET; 66 67 private static final String PERFORMANCE_EVENT= JavaPlugin.getPluginId() + "/perf/content_assist/extensions"; 72 private static final boolean MEASURE_PERFORMANCE= PerformanceStats.isEnabled(PERFORMANCE_EVENT); 73 79 private static final long MAX_DELAY= 5000; 80 81 82 private static final String COMPUTE_COMPLETION_PROPOSALS= "computeCompletionProposals()"; private static final String COMPUTE_CONTEXT_INFORMATION= "computeContextInformation()"; private static final String SESSION_STARTED= "sessionStarted()"; private static final String SESSION_ENDED= "sessionEnded()"; 87 static { 88 Set partitions= new HashSet (); 89 partitions.add(IDocument.DEFAULT_CONTENT_TYPE); 90 partitions.add(IJavaPartitions.JAVA_DOC); 91 partitions.add(IJavaPartitions.JAVA_MULTI_LINE_COMMENT); 92 partitions.add(IJavaPartitions.JAVA_SINGLE_LINE_COMMENT); 93 partitions.add(IJavaPartitions.JAVA_STRING); 94 partitions.add(IJavaPartitions.JAVA_CHARACTER); 95 96 PARTITION_SET= Collections.unmodifiableSet(partitions); 97 } 98 99 100 private final String fId; 101 102 private final String fName; 103 104 private final String fClass; 105 106 private final boolean fActivate; 107 108 private final Set fPartitions; 109 110 private final IConfigurationElement fElement; 111 112 private final CompletionProposalComputerRegistry fRegistry; 113 114 private IJavaCompletionProposalComputer fComputer; 115 116 private final CompletionProposalCategory fCategory; 117 118 private String fLastError; 119 124 private boolean fIsReportingDelay= false; 125 126 private long fStart; 127 128 134 CompletionProposalComputerDescriptor(IConfigurationElement element, CompletionProposalComputerRegistry registry, List categories) throws InvalidRegistryObjectException { 135 Assert.isLegal(registry != null); 136 Assert.isLegal(element != null); 137 138 fRegistry= registry; 139 fElement= element; 140 IExtension extension= element.getDeclaringExtension(); 141 fId= extension.getUniqueIdentifier(); 142 checkNotNull(fId, "id"); 144 String name= extension.getLabel(); 145 if (name.length() == 0) 146 fName= fId; 147 else 148 fName= name; 149 150 Set partitions= new HashSet (); 151 IConfigurationElement[] children= element.getChildren(PARTITION); 152 if (children.length == 0) { 153 fPartitions= PARTITION_SET; } else { 155 for (int i= 0; i < children.length; i++) { 156 String type= children[i].getAttribute(TYPE); 157 checkNotNull(type, TYPE); 158 partitions.add(type); 159 } 160 fPartitions= Collections.unmodifiableSet(partitions); 161 } 162 163 String activateAttribute= element.getAttribute(ACTIVATE); 164 fActivate= Boolean.valueOf(activateAttribute).booleanValue(); 165 166 fClass= element.getAttribute(CLASS); 167 checkNotNull(fClass, CLASS); 168 169 String categoryId= element.getAttribute(CATEGORY_ID); 170 if (categoryId == null) 171 categoryId= DEFAULT_CATEGORY_ID; 172 CompletionProposalCategory category= null; 173 for (Iterator it= categories.iterator(); it.hasNext();) { 174 CompletionProposalCategory cat= (CompletionProposalCategory) it.next(); 175 if (cat.getId().equals(categoryId)) { 176 category= cat; 177 break; 178 } 179 } 180 if (category == null) { 181 fCategory= new CompletionProposalCategory(categoryId, fName, registry); 183 categories.add(fCategory); 184 } else { 185 fCategory= category; 186 } 187 } 188 189 195 private void checkNotNull(Object obj, String attribute) throws InvalidRegistryObjectException { 196 if (obj == null) { 197 Object [] args= { getId(), fElement.getContributor().getName(), attribute }; 198 String message= Messages.format(JavaTextMessages.CompletionProposalComputerDescriptor_illegal_attribute_message, args); 199 IStatus status= new Status(IStatus.WARNING, JavaPlugin.getPluginId(), IStatus.OK, message, null); 200 JavaPlugin.log(status); 201 throw new InvalidRegistryObjectException(); 202 } 203 } 204 205 210 public String getId() { 211 return fId; 212 } 213 214 219 public String getName() { 220 return fName; 221 } 222 223 228 public Set getPartitions() { 229 return fPartitions; 230 } 231 232 244 private synchronized IJavaCompletionProposalComputer getComputer() throws CoreException, InvalidRegistryObjectException { 245 if (fComputer == null && (fActivate || isPluginLoaded())) 246 fComputer= createComputer(); 247 return fComputer; 248 } 249 250 private boolean isPluginLoaded() { 251 Bundle bundle= getBundle(); 252 return bundle != null && bundle.getState() == Bundle.ACTIVE; 253 } 254 255 private Bundle getBundle() { 256 String namespace= fElement.getDeclaringExtension().getContributor().getName(); 257 Bundle bundle= Platform.getBundle(namespace); 258 return bundle; 259 } 260 261 277 public IJavaCompletionProposalComputer createComputer() throws CoreException, InvalidRegistryObjectException { 278 return (IJavaCompletionProposalComputer) fElement.createExecutableExtension(CLASS); 279 } 280 281 291 public List computeCompletionProposals(ContentAssistInvocationContext context, IProgressMonitor monitor) { 292 if (!isEnabled()) 293 return Collections.EMPTY_LIST; 294 295 IStatus status; 296 try { 297 IJavaCompletionProposalComputer computer= getComputer(); 298 if (computer == null) return Collections.EMPTY_LIST; 300 301 try { 302 PerformanceStats stats= startMeter(context, computer); 303 List proposals= computer.computeCompletionProposals(context, monitor); 304 stopMeter(stats, COMPUTE_COMPLETION_PROPOSALS); 305 306 if (proposals != null) { 307 fLastError= computer.getErrorMessage(); 308 return proposals; 309 } 310 } finally { 311 fIsReportingDelay= true; 312 } 313 status= createAPIViolationStatus(COMPUTE_COMPLETION_PROPOSALS); 314 } catch (InvalidRegistryObjectException x) { 315 status= createExceptionStatus(x); 316 } catch (CoreException x) { 317 status= createExceptionStatus(x); 318 } catch (RuntimeException x) { 319 status= createExceptionStatus(x); 320 } finally { 321 monitor.done(); 322 } 323 324 fRegistry.informUser(this, status); 325 326 return Collections.EMPTY_LIST; 327 } 328 329 339 public List computeContextInformation(ContentAssistInvocationContext context, IProgressMonitor monitor) { 340 if (!isEnabled()) 341 return Collections.EMPTY_LIST; 342 343 IStatus status; 344 try { 345 IJavaCompletionProposalComputer computer= getComputer(); 346 if (computer == null) return Collections.EMPTY_LIST; 348 349 PerformanceStats stats= startMeter(context, computer); 350 List proposals= computer.computeContextInformation(context, monitor); 351 stopMeter(stats, COMPUTE_CONTEXT_INFORMATION); 352 353 if (proposals != null) { 354 fLastError= computer.getErrorMessage(); 355 return proposals; 356 } 357 358 status= createAPIViolationStatus(COMPUTE_CONTEXT_INFORMATION); 359 } catch (InvalidRegistryObjectException x) { 360 status= createExceptionStatus(x); 361 } catch (CoreException x) { 362 status= createExceptionStatus(x); 363 } catch (RuntimeException x) { 364 status= createExceptionStatus(x); 365 } finally { 366 monitor.done(); 367 } 368 369 fRegistry.informUser(this, status); 370 371 return Collections.EMPTY_LIST; 372 } 373 374 375 382 public void sessionStarted() { 383 if (!isEnabled()) 384 return; 385 386 IStatus status; 387 try { 388 IJavaCompletionProposalComputer computer= getComputer(); 389 if (computer == null) return; 391 392 PerformanceStats stats= startMeter(SESSION_STARTED, computer); 393 computer.sessionStarted(); 394 stopMeter(stats, SESSION_ENDED); 395 396 return; 397 } catch (InvalidRegistryObjectException x) { 398 status= createExceptionStatus(x); 399 } catch (CoreException x) { 400 status= createExceptionStatus(x); 401 } catch (RuntimeException x) { 402 status= createExceptionStatus(x); 403 } 404 405 fRegistry.informUser(this, status); 406 } 407 408 415 public void sessionEnded() { 416 if (!isEnabled()) 417 return; 418 419 IStatus status; 420 try { 421 IJavaCompletionProposalComputer computer= getComputer(); 422 if (computer == null) return; 424 425 PerformanceStats stats= startMeter(SESSION_ENDED, computer); 426 computer.sessionEnded(); 427 stopMeter(stats, SESSION_ENDED); 428 429 return; 430 } catch (InvalidRegistryObjectException x) { 431 status= createExceptionStatus(x); 432 } catch (CoreException x) { 433 status= createExceptionStatus(x); 434 } catch (RuntimeException x) { 435 status= createExceptionStatus(x); 436 } 437 438 fRegistry.informUser(this, status); 439 } 440 441 private PerformanceStats startMeter(Object context, IJavaCompletionProposalComputer computer) { 442 final PerformanceStats stats; 443 if (MEASURE_PERFORMANCE) { 444 stats= PerformanceStats.getStats(PERFORMANCE_EVENT, computer); 445 stats.startRun(context.toString()); 446 } else { 447 stats= null; 448 } 449 450 if (fIsReportingDelay) { 451 fStart= System.currentTimeMillis(); 452 } 453 454 return stats; 455 } 456 457 private void stopMeter(final PerformanceStats stats, String operation) { 458 if (MEASURE_PERFORMANCE) { 459 stats.endRun(); 460 if (stats.isFailure()) { 461 IStatus status= createPerformanceStatus(operation); 462 fRegistry.informUser(this, status); 463 return; 464 } 465 } 466 467 if (fIsReportingDelay) { 468 long current= System.currentTimeMillis(); 469 if (current - fStart > MAX_DELAY) { 470 IStatus status= createPerformanceStatus(operation); 471 fRegistry.informUser(this, status); 472 } 473 } 474 } 475 476 private IStatus createExceptionStatus(InvalidRegistryObjectException x) { 477 String blame= createBlameMessage(); 479 String reason= JavaTextMessages.CompletionProposalComputerDescriptor_reason_invalid; 480 return new Status(IStatus.INFO, JavaPlugin.getPluginId(), IStatus.OK, blame + " " + reason, x); } 482 483 private IStatus createExceptionStatus(CoreException x) { 484 String blame= createBlameMessage(); 486 String reason= JavaTextMessages.CompletionProposalComputerDescriptor_reason_instantiation; 487 return new Status(IStatus.ERROR, JavaPlugin.getPluginId(), IStatus.OK, blame + " " + reason, x); } 489 490 private IStatus createExceptionStatus(RuntimeException x) { 491 String blame= createBlameMessage(); 493 String reason= JavaTextMessages.CompletionProposalComputerDescriptor_reason_runtime_ex; 494 return new Status(IStatus.WARNING, JavaPlugin.getPluginId(), IStatus.OK, blame + " " + reason, x); } 496 497 private IStatus createAPIViolationStatus(String operation) { 498 String blame= createBlameMessage(); 499 Object [] args= {operation}; 500 String reason= Messages.format(JavaTextMessages.CompletionProposalComputerDescriptor_reason_API, args); 501 return new Status(IStatus.WARNING, JavaPlugin.getPluginId(), IStatus.OK, blame + " " + reason, null); } 503 504 private IStatus createPerformanceStatus(String operation) { 505 String blame= createBlameMessage(); 506 Object [] args= {operation}; 507 String reason= Messages.format(JavaTextMessages.CompletionProposalComputerDescriptor_reason_performance, args); 508 return new Status(IStatus.WARNING, JavaPlugin.getPluginId(), IStatus.OK, blame + " " + reason, null); } 510 511 private String createBlameMessage() { 512 Object [] args= { getName(), fElement.getDeclaringExtension().getContributor().getName() }; 513 String disable= Messages.format( JavaTextMessages.CompletionProposalComputerDescriptor_blame_message, args); 514 return disable; 515 } 516 517 522 private boolean isEnabled() { 523 return fCategory.isEnabled(); 524 } 525 526 CompletionProposalCategory getCategory() { 527 return fCategory; 528 } 529 530 535 public String getErrorMessage() { 536 return fLastError; 537 } 538 539 544 IContributor getContributor() { 545 try { 546 return fElement.getContributor(); 547 } catch (InvalidRegistryObjectException e) { 548 return null; 549 } 550 } 551 552 } 553 | Popular Tags |