diff options
Diffstat (limited to 'bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/contentassist/CompletionProposalComputerDescriptor.java')
-rw-r--r-- | bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/contentassist/CompletionProposalComputerDescriptor.java | 648 |
1 files changed, 0 insertions, 648 deletions
diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/contentassist/CompletionProposalComputerDescriptor.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/contentassist/CompletionProposalComputerDescriptor.java deleted file mode 100644 index d36cca04a3..0000000000 --- a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/contentassist/CompletionProposalComputerDescriptor.java +++ /dev/null @@ -1,648 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.wst.sse.ui.internal.contentassist; - -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IContributor; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.InvalidRegistryObjectException; -import org.eclipse.core.runtime.PerformanceStats; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.Status; -import org.eclipse.wst.sse.ui.contentassist.CompletionProposalInvocationContext; -import org.eclipse.wst.sse.ui.contentassist.ICompletionProposalComputer; -import org.eclipse.wst.sse.ui.internal.Logger; -import org.eclipse.wst.sse.ui.internal.SSEUIPlugin; -import org.osgi.framework.Bundle; - -/** - * Wraps an {@link ICompletionProposalComputer} provided by an extension to the - * <code>org.eclipse.wst.sse.ui.completionProposal</code> extension point. - * Instances are immutable. Instances can be obtained from a - * {@link CompletionProposalComputerRegistry}. - * - * @see CompletionProposalComputerRegistry - */ -final class CompletionProposalComputerDescriptor { - /** The default category id. */ - private static final String DEFAULT_CATEGORY_ID= "org.eclipse.wst.sse.ui.defaultProposalCategory"; //$NON-NLS-1$ - - /** The extension schema name of the category id attribute. */ - private static final String ATTR_CATEGORY_ID= "categoryId"; //$NON-NLS-1$ - - /** The extension schema name for element ID attributes */ - private static final String ATTR_ID= "id"; //$NON-NLS-1$ - - /** The extension schema name for element name attributes */ - private static final String ATTR_NAME= "name"; //$NON-NLS-1$ - - /** The extension schema name of the class attribute. */ - private static final String ATTR_CLASS= "class"; //$NON-NLS-1$ - - /** The extension schema name of the activate attribute. */ - private static final String ATTRACTIVATE= "activate"; //$NON-NLS-1$ - - /** The extension schema name of the content type child elements. */ - private static final String ELEM_CONTENT_TYPE = "contentType"; //$NON-NLS-1$ - - /** The extension schema name of the partition type child elements. */ - private static final String ELEM_PARTITION_TYPE= "partitionType"; //$NON-NLS-1$ - - /** The name of the performance event used to trace extensions. */ - private static final String PERFORMANCE_EVENT= SSEUIPlugin.ID + "/perf/content_assist/extensions"; //$NON-NLS-1$ - - /** - * If <code>true</code>, execution time of extensions is measured and the data forwarded to - * core's {@link PerformanceStats} service. - */ - private static final boolean MEASURE_PERFORMANCE= PerformanceStats.isEnabled(PERFORMANCE_EVENT); - - /** - * Independently of the {@link PerformanceStats} service, any operation that takes longer than - * {@value} milliseconds will be flagged as an violation. This timeout does not apply to the - * first invocation, as it may take longer due to plug-in initialization etc. See also - * {@link #fIsReportingDelay}. - */ - private static final long MAX_DELAY= 500000; - - /* log constants */ - private static final String COMPUTE_COMPLETION_PROPOSALS= "computeCompletionProposals()"; //$NON-NLS-1$ - private static final String COMPUTE_CONTEXT_INFORMATION= "computeContextInformation()"; //$NON-NLS-1$ - private static final String SESSION_STARTED= "sessionStarted()"; //$NON-NLS-1$ - private static final String SESSION_ENDED= "sessionEnded()"; //$NON-NLS-1$ - - /** The identifier of the extension. */ - private final String fId; - - /** The name of the extension. */ - private final String fName; - - /** The class name of the provided <code>ISSECompletionProposalComputer</code>. */ - private final String fClass; - - /** The activate attribute value. */ - private final boolean fActivate; - - /** The configuration element of this extension. */ - private final IConfigurationElement fElement; - - /** The computer, if instantiated, <code>null</code> otherwise. */ - private ICompletionProposalComputer fComputer; - - /** The UI category. */ - private final CompletionProposalCategory fCategory; - - /** The first error message in the most recent operation, or <code>null</code>. */ - private String fLastError; - - /** - * Tells whether to inform the user when <code>MAX_DELAY</code> has been exceeded. - * We start timing execution after the first session because the first may take - * longer due to plug-in activation and initialization. - */ - private boolean fIsReportingDelay = false; - - /** The start of the last operation. */ - private long fStart; - - /** - * Tells whether we tried to load the computer. - * @since 3.4 - */ - boolean fTriedLoadingComputer = false; - - /** - * <p>Creates a new descriptor.</p> - * <p><b>NOTE: </b> This will not add this new descriptor to the given - * {@link CompletionProposalComputerRegistry}. That can not be done - * until this descriptor is done being constructed. Therefore be sure - * to call {@link #addToRegistry()} after creating a new descriptor.</p> - * - * @param element the configuration element to read - * @param categories the categories - * - * @throws InvalidRegistryObjectException if this extension is no longer valid - * @throws CoreException if the extension contains invalid values - */ - CompletionProposalComputerDescriptor(IConfigurationElement element, List categories) throws InvalidRegistryObjectException, CoreException { - Assert.isLegal(element != null); - fElement = element; - - //get & verify ID - fId = fElement.getAttribute(ATTR_ID); - ContentAssistUtils.checkExtensionAttributeNotNull(fId, ATTR_ID, fElement); - - //get & verify optional name - String name= fElement.getAttribute(ATTR_NAME); - if (name == null) { - fName= fId; - } else { - fName= name; - } - - //get & verify activate plugin attribute - String activateAttribute= fElement.getAttribute(ATTRACTIVATE); - fActivate = Boolean.valueOf(activateAttribute).booleanValue(); - - //get & verify class - fClass= fElement.getAttribute(ATTR_CLASS); - ContentAssistUtils.checkExtensionAttributeNotNull(fClass, ATTR_CLASS, fElement); - - //get & verify optional category id - String categoryId= fElement.getAttribute(ATTR_CATEGORY_ID); - if (categoryId == null) { - categoryId= DEFAULT_CATEGORY_ID; - } - - //find the category with the determined category id - CompletionProposalCategory category= null; - for (Iterator it= categories.iterator(); it.hasNext();) { - CompletionProposalCategory cat= (CompletionProposalCategory) it.next(); - if (cat.getId().equals(categoryId)) { - category= cat; - break; - } - } - - /* create a category if it does not exist - * else just set the category - */ - if (category == null) { - fCategory = new CompletionProposalCategory(categoryId, fName); - - /* will add the new category to the registers list of categories, - * by the magic of object references - */ - categories.add(fCategory); - } else { - fCategory = category; - } - } - - /** - * <p>Adds this descriptor to the {@link CompletionProposalComputerRegistry}.</p> - * <p><b>NOTE: </b>Must be done after descriptor creation or the descriptor will - * not be added to the registry. Can not be done in constructor because - * descriptor must be constructed before it can be added to the registry</p> - * - * - * @throws InvalidRegistryObjectException - * @throws CoreException - */ - void addToRegistry() throws InvalidRegistryObjectException, CoreException { - parseActivationAndAddToRegistry(this.fElement, this); - } - - /** - * @return the category that the wrapped {@link ICompletionProposalComputer} is - * associated with. - */ - CompletionProposalCategory getCategory() { - return fCategory; - } - - /** - * @return the contributor of the described {@link ICompletionProposalComputer} - */ - IContributor getContributor() { - try { - return fElement.getContributor(); - } catch (InvalidRegistryObjectException e) { - return null; - } - } - - /** - * @return Returns the id of the described {@link ICompletionProposalComputer} - */ - public String getId() { - return fId; - } - - /** - * @return the name of the described {@link ICompletionProposalComputer} - */ - public String getName() { - return fName; - } - - /** - * Returns a new instance of the computer as described in the - * extension's xml. Note that the safest way to access the computer - * is by using the - * {@linkplain #computeCompletionProposals(ContentAssistInvocationContext, IProgressMonitor) computeCompletionProposals} - * and - * {@linkplain #computeContextInformation(ContentAssistInvocationContext, IProgressMonitor) computeContextInformation} - * methods. These delegate the functionality to the contributed - * computer, but handle instance creation and any exceptions thrown. - * - * @return a new instance of the completion proposal computer as - * described by this descriptor - * - * @throws CoreException if the creation fails - * @throws InvalidRegistryObjectException if the extension is not - * valid any longer (e.g. due to plug-in unloading) - */ - public ICompletionProposalComputer createComputer() throws CoreException, InvalidRegistryObjectException { - return (ICompletionProposalComputer) fElement.createExecutableExtension(ATTR_CLASS); - } - - /** - * <p>Safely computes completion proposals through the described extension.</p> - * - * @param context the invocation context passed on to the extension - * @param monitor the progress monitor passed on to the extension - * @return the list of computed completion proposals (element type: - * {@link org.eclipse.jface.text.contentassist.ICompletionProposal}) - */ - public List computeCompletionProposals(CompletionProposalInvocationContext context, IProgressMonitor monitor) { - List completionProposals = Collections.EMPTY_LIST; - if (isEnabled()) { - IStatus status = null; - try { - // plugin must be active to get computer - ICompletionProposalComputer computer = getComputer(true); - if (computer != null) { - try { - PerformanceStats stats= startMeter(context, computer); - //ask the computer for the proposals - List proposals = computer.computeCompletionProposals(context, monitor); - stopMeter(stats, COMPUTE_COMPLETION_PROPOSALS); - - if (proposals != null) { - fLastError = computer.getErrorMessage(); - completionProposals = proposals; - } else { - status = createAPIViolationStatus(COMPUTE_COMPLETION_PROPOSALS); - } - } finally { - fIsReportingDelay = true; - } - } - } catch (InvalidRegistryObjectException x) { - status= createExceptionStatus(x); - } catch (CoreException x) { - status= createExceptionStatus(x); - } catch (RuntimeException x) { - status= createExceptionStatus(x); - } finally { - monitor.done(); - } - - if(status != null) { - Logger.log(status); - } - } - - return completionProposals; - } - - /** - * <p>Safely computes context information objects through the described extension.</p> - * - * @param context the invocation context passed on to the extension - * @param monitor the progress monitor passed on to the extension - * @return the list of computed context information objects (element type: - * {@link org.eclipse.jface.text.contentassist.IContextInformation}) - */ - public List computeContextInformation(CompletionProposalInvocationContext context, IProgressMonitor monitor) { - List contextInformation = Collections.EMPTY_LIST; - if (isEnabled()) { - IStatus status = null; - try { - // plugin must be active to get computer - ICompletionProposalComputer computer = getComputer(true); - if (computer != null) { - PerformanceStats stats= startMeter(context, computer); - List proposals= computer.computeContextInformation(context, monitor); - stopMeter(stats, COMPUTE_CONTEXT_INFORMATION); - - if (proposals != null) { - fLastError= computer.getErrorMessage(); - contextInformation = proposals; - } else { - status = createAPIViolationStatus(COMPUTE_CONTEXT_INFORMATION); - } - } - } catch (InvalidRegistryObjectException x) { - status= createExceptionStatus(x); - } catch (CoreException x) { - status= createExceptionStatus(x); - } catch (RuntimeException x) { - status= createExceptionStatus(x); - } finally { - monitor.done(); - } - - if(status != null) { - Logger.log(status); - } - } - - return contextInformation; - } - - /** - * <p>Notifies the described extension of a proposal computation session start.</p> - * - * <p><b>Note: </b>This method is called every time code assist is invoked and - * is <strong>not</strong> filtered by content type or partition type.</p> - */ - public void sessionStarted() { - if (isEnabled()) { - IStatus status = null; - try { - // plugin must be active to get computer - ICompletionProposalComputer computer = getComputer(true); - if (computer != null) { - PerformanceStats stats = startMeter(SESSION_STARTED, computer); - computer.sessionStarted(); - stopMeter(stats, SESSION_ENDED); - } - } catch (InvalidRegistryObjectException x) { - status= createExceptionStatus(x); - } catch (CoreException x) { - status= createExceptionStatus(x); - } catch (RuntimeException x) { - status= createExceptionStatus(x); - } - - if(status != null) { - Logger.log(status); - } - } - } - - /** - * <p>Notifies the described extension of a proposal computation session end.</p> - * - * <p><b>Note: </b>This method is called every time code assist is invoked and - * is <strong>not</strong> filtered by content type or partition type.</p> - */ - public void sessionEnded() { - if (isEnabled()) { - IStatus status = null; - try { - // plugin must be active to get computer - ICompletionProposalComputer computer = getComputer(true); - if (computer != null) { - PerformanceStats stats= startMeter(SESSION_ENDED, computer); - computer.sessionEnded(); - stopMeter(stats, SESSION_ENDED); - } - } catch (InvalidRegistryObjectException x) { - status= createExceptionStatus(x); - } catch (CoreException x) { - status= createExceptionStatus(x); - } catch (RuntimeException x) { - status= createExceptionStatus(x); - } - - if(status != null) { - Logger.log(status); - } - } - } - - /** - * @return the error message from the described {@link ICompletionProposalComputer} - */ - public String getErrorMessage() { - return fLastError; - } - - /** - * @see java.lang.Object#toString() - */ - public String toString() { - return fId + ": " + fName; //$NON-NLS-1$ - } - - /** - * <p>Parses the given configuration element for its activation context, - * that is to say the content types and partiton types and updates the registry - * to associated the given computer descriptor with the parsed activation contexts.</P> - * - * <p>This is useful for parsing both <tt>proposalComputer</tt> elements and - * <tt>proposalComputerExtendedActivation</tt> elements.</p> - * - * @param element {@link IConfigurationElement} containing the activation context - * @param desc {@link CompletionProposalComputerDescriptor} to associate with the parsed activation context - * - * @throws InvalidRegistryObjectException - * @throws CoreException - */ - protected static void parseActivationAndAddToRegistry(IConfigurationElement element, - CompletionProposalComputerDescriptor desc) throws InvalidRegistryObjectException, CoreException { - - /* if this descriptor is specific to a content type/s add it to the registry as such - * else add to registry for all content types - */ - IConfigurationElement[] contentTypes = element.getChildren(ELEM_CONTENT_TYPE); - if(contentTypes.length > 0) { - for(int contentTypeIndex = 0; contentTypeIndex < contentTypes.length; ++contentTypeIndex) { - String contentTypeID = contentTypes[contentTypeIndex].getAttribute(ATTR_ID); - ContentAssistUtils.checkExtensionAttributeNotNull(contentTypeID, ATTR_ID, contentTypes[contentTypeIndex]); - - /* if this descriptor is for specific partition types in the content type - * add it to the registry as such - * else add to the registry for all partition types in the content type - */ - IConfigurationElement[] partitionTypes = contentTypes[contentTypeIndex].getChildren(ELEM_PARTITION_TYPE); - if(partitionTypes.length > 0) { - for (int partitionTypeIndex = 0; partitionTypeIndex < partitionTypes.length; ++partitionTypeIndex) { - String partitionTypeID = partitionTypes[partitionTypeIndex].getAttribute(ATTR_ID); - ContentAssistUtils.checkExtensionAttributeNotNull(partitionTypeID, ATTR_ID, partitionTypes[partitionTypeIndex]); - - CompletionProposalComputerRegistry.getDefault().putDescription(contentTypeID, partitionTypeID, desc); - CompletionProposalComputerRegistry.getDefault().putAutoActivator(contentTypeID, partitionTypeID, partitionTypes[partitionTypeIndex]); - } - } else { - CompletionProposalComputerRegistry.getDefault().putDescription(contentTypeID, null, desc); - } - } - } else { - Logger.log(Logger.WARNING, "The configuration element: " + element + " does not contain any content types."); //$NON-NLS-1$ //$NON-NLS-2$ - } - } - - /** - * @return <code>true</code> if the plugin that contains the {@link IConfigurationElement} - * associated with this descriptor is loaded, <code>false</code> otherwise. - */ - private boolean isPluginLoaded() { - Bundle bundle= getBundle(); - return bundle != null && bundle.getState() == Bundle.ACTIVE; - } - - /** - * @return the {@link Bundle} that contains the {@link IConfigurationElement} associated - * with this descriptor - */ - private Bundle getBundle() { - String namespace= fElement.getDeclaringExtension().getContributor().getName(); - Bundle bundle= Platform.getBundle(namespace); - return bundle; - } - - /** - * <p>Returns a cached instance of the computer as described in the - * extension's xml. If the computer is not yet created and - * <code>canCreate</code> is <code>true</code> then {@link #createComputer()} - * is called and the result cached.</p> - * - * @param canCreate <code>true</code> if the proposal computer can be created - * @return a new instance of the completion proposal computer as - * described by this descriptor - * - * @throws CoreException if the creation fails - * @throws InvalidRegistryObjectException if the extension is not - * valid any longer (e.g. due to plug-in unloading) - */ - private synchronized ICompletionProposalComputer getComputer(boolean canCreate) throws CoreException, InvalidRegistryObjectException { - if (fComputer == null && canCreate && !fTriedLoadingComputer && (fActivate || isPluginLoaded())) { - fTriedLoadingComputer= true; - fComputer= createComputer(); - } - return fComputer; - } - - /** - * @return the enablement state of the category this describer is associated with - */ - private boolean isEnabled() { - return fCategory.isEnabled(); - } - - /** - * <p>Starts the meter for measuring the computers performance</p> - * - * @param context - * @param computer - * @return - */ - private PerformanceStats startMeter(Object context, ICompletionProposalComputer computer) { - final PerformanceStats stats; - if (MEASURE_PERFORMANCE) { - stats= PerformanceStats.getStats(PERFORMANCE_EVENT, computer); - stats.startRun(context.toString()); - } else { - stats= null; - } - - if (fIsReportingDelay) { - fStart= System.currentTimeMillis(); - } - - return stats; - } - - /** - * <p>Stops the meter for measuring the computers performance</p> - * - * @param context - * @param computer - * @return - */ - private void stopMeter(final PerformanceStats stats, String operation) { - if (MEASURE_PERFORMANCE) { - stats.endRun(); - if (stats.isFailure()) { - IStatus status= createPerformanceStatus(operation); - Logger.log(status); - return; - } - } - - if (fIsReportingDelay) { - long current= System.currentTimeMillis(); - if (current - fStart > MAX_DELAY) { - IStatus status= createPerformanceStatus(operation); - Logger.log(status); - } - } - } - - /** - * @return A message explaining that the described {@link ICompletionProposalComputer} failed in some way - */ - private String createBlameMessage() { - return "The ''" + getName() + "'' proposal computer from the ''" + //$NON-NLS-1$ //$NON-NLS-2$ - fElement.getDeclaringExtension().getContributor().getName() + "'' plug-in did not complete normally."; //$NON-NLS-1$ - } - - /** - * <p>Create a status message describing that the extension has become invalid</p> - * - * @param x the associated {@link InvalidRegistryObjectException} - * @return the created {@link IStatus} - */ - private IStatus createExceptionStatus(InvalidRegistryObjectException x) { - String blame= createBlameMessage(); - String reason= "The extension has become invalid."; //$NON-NLS-1$ - return new Status(IStatus.INFO, SSEUIPlugin.ID, IStatus.OK, blame + " " + reason, x); //$NON-NLS-1$ - } - - /** - * <p>create a status message explaining that the extension could not be instantiated</p> - * - * @param x the associated {@link CoreException} - * @return the created {@link IStatus} - */ - private IStatus createExceptionStatus(CoreException x) { - String blame = createBlameMessage(); - String reason = "Unable to instantiate the extension."; //$NON-NLS-1$ - return new Status(IStatus.ERROR, SSEUIPlugin.ID, IStatus.OK, blame + " " + reason, x); //$NON-NLS-1$ - } - - /** - * <p>Create a status message explaining the extension has thrown a runtime exception</p> - * - * @param x the associated {@link RuntimeException} - * @return the created {@link IStatus} - */ - private IStatus createExceptionStatus(RuntimeException x) { - String blame= createBlameMessage(); - String reason= "The extension has thrown a runtime exception."; //$NON-NLS-1$ - return new Status(IStatus.WARNING, SSEUIPlugin.ID, IStatus.OK, blame + " " + reason, x); //$NON-NLS-1$ - } - - /** - * <p>Create a status message explaining the extension has violated the API of the extension point</p> - * - * @param operation the operation that created the API violation - * @return the created {@link IStatus} - */ - private IStatus createAPIViolationStatus(String operation) { - String blame = createBlameMessage(); - String reason = "The extension violated the API contract of the ''" + operation + "'' operation."; //$NON-NLS-1$ //$NON-NLS-2$ - return new Status(IStatus.WARNING, SSEUIPlugin.ID, IStatus.OK, blame + " " + reason, null); //$NON-NLS-1$ - } - - /** - * <p>Create a status message explaining that the extension took to long during an operation</p> - * - * @param operation the operation that took to long - * @return the created {@link IStatus} - */ - private IStatus createPerformanceStatus(String operation) { - String blame= createBlameMessage(); - String reason = "The extension took too long to return from the ''" + operation + "'' operation."; //$NON-NLS-1$ //$NON-NLS-2$ - return new Status(IStatus.WARNING, SSEUIPlugin.ID, IStatus.OK, blame + " " + reason, null); //$NON-NLS-1$ - } -} |