KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > text > java > ProposalSorterHandle


1 /*******************************************************************************
2  * Copyright (c) 2005, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdt.internal.ui.text.java;
12
13 import java.util.Collections JavaDoc;
14 import java.util.List JavaDoc;
15
16 import org.eclipse.core.runtime.Assert;
17 import org.eclipse.core.runtime.CoreException;
18 import org.eclipse.core.runtime.IConfigurationElement;
19 import org.eclipse.core.runtime.IStatus;
20 import org.eclipse.core.runtime.InvalidRegistryObjectException;
21 import org.eclipse.core.runtime.PerformanceStats;
22 import org.eclipse.core.runtime.Platform;
23 import org.eclipse.core.runtime.Status;
24
25
26 import org.eclipse.jdt.internal.corext.util.Messages;
27
28 import org.eclipse.jdt.ui.text.java.AbstractProposalSorter;
29 import org.eclipse.jdt.ui.text.java.ContentAssistInvocationContext;
30
31 import org.eclipse.jdt.internal.ui.JavaPlugin;
32
33 import org.osgi.framework.Bundle;
34
35 /**
36  * The description of an extension to the
37  * <code>org.eclipse.jdt.ui.javaCompletionProposalSorters</code> extension point. Instances are
38  * immutable.
39  *
40  * @since 3.2
41  */

42 public final class ProposalSorterHandle {
43     /** The extension schema name of the id attribute. */
44     private static final String JavaDoc ID= "id"; //$NON-NLS-1$
45
/** The extension schema name of the name attribute. */
46     private static final String JavaDoc NAME= "name"; //$NON-NLS-1$
47
/** The extension schema name of the class attribute. */
48     private static final String JavaDoc CLASS= "class"; //$NON-NLS-1$
49
/** The extension schema name of the activate attribute. */
50     private static final String JavaDoc ACTIVATE= "activate"; //$NON-NLS-1$
51
/** The name of the performance event used to trace extensions. */
52     private static final String JavaDoc PERFORMANCE_EVENT= JavaPlugin.getPluginId() + "/perf/content_assist_sorters/extensions"; //$NON-NLS-1$
53
/**
54      * If <code>true</code>, execution time of extensions is measured and extensions may be
55      * disabled if execution takes too long.
56      */

57     private static final boolean MEASURE_PERFORMANCE= PerformanceStats.isEnabled(PERFORMANCE_EVENT);
58     /** The one and only operation name. */
59     private static final String JavaDoc SORT= "sort"; //$NON-NLS-1$
60

61     /** The identifier of the extension. */
62     private final String JavaDoc fId;
63     /** The name of the extension. */
64     private final String JavaDoc fName;
65     /** The class name of the provided <code>AbstractProposalSorter</code>. */
66     private final String JavaDoc fClass;
67     /** The activate attribute value. */
68     private final boolean fActivate;
69     /** The configuration element of this extension. */
70     private final IConfigurationElement fElement;
71     /** The computer, if instantiated, <code>null</code> otherwise. */
72     private AbstractProposalSorter fSorter;
73
74     /**
75      * Creates a new descriptor.
76      *
77      * @param element the configuration element to read
78      * @throws InvalidRegistryObjectException if the configuration element is not valid any longer
79      * or does not contain mandatory attributes
80      */

81     ProposalSorterHandle(IConfigurationElement element) throws InvalidRegistryObjectException {
82         Assert.isLegal(element != null);
83         
84         fElement= element;
85         fId= element.getAttribute(ID);
86         checkNotNull(fId, ID);
87
88         String JavaDoc name= element.getAttribute(NAME);
89         if (name == null)
90             fName= fId;
91         else
92             fName= name;
93         
94         String JavaDoc activateAttribute= element.getAttribute(ACTIVATE);
95         fActivate= Boolean.valueOf(activateAttribute).booleanValue();
96
97         fClass= element.getAttribute(CLASS);
98         checkNotNull(fClass, CLASS);
99     }
100
101     /**
102      * Checks an element that must be defined according to the extension
103      * point schema. Throws an
104      * <code>InvalidRegistryObjectException</code> if <code>obj</code>
105      * is <code>null</code>.
106      */

107     private void checkNotNull(Object JavaDoc obj, String JavaDoc attribute) throws InvalidRegistryObjectException {
108         if (obj == null) {
109             Object JavaDoc[] args= { getId(), fElement.getContributor().getName(), attribute };
110             String JavaDoc message= Messages.format(JavaTextMessages.CompletionProposalComputerDescriptor_illegal_attribute_message, args);
111             IStatus status= new Status(IStatus.WARNING, JavaPlugin.getPluginId(), IStatus.OK, message, null);
112             JavaPlugin.log(status);
113             throw new InvalidRegistryObjectException();
114         }
115     }
116
117     /**
118      * Returns the identifier of the described extension.
119      *
120      * @return Returns the id
121      */

122     public String JavaDoc getId() {
123         return fId;
124     }
125
126     /**
127      * Returns the name of the described extension.
128      *
129      * @return Returns the name
130      */

131     public String JavaDoc getName() {
132         return fName;
133     }
134     
135     /**
136      * Returns a cached instance of the sorter as described in the extension's xml. The sorter is
137      * {@link #createSorter() created} the first time that this method is called and then cached.
138      *
139      * @return a new instance of the proposal sorter as described by this descriptor
140      * @throws CoreException if the creation fails
141      * @throws InvalidRegistryObjectException if the extension is not valid any longer (e.g. due to
142      * plug-in unloading)
143      */

144     private synchronized AbstractProposalSorter getSorter() throws CoreException, InvalidRegistryObjectException {
145         if (fSorter == null && (fActivate || isPluginLoaded()))
146             fSorter= createSorter();
147         return fSorter;
148     }
149
150     private boolean isPluginLoaded() throws InvalidRegistryObjectException {
151         Bundle bundle= getBundle();
152         return bundle != null && bundle.getState() == Bundle.ACTIVE;
153     }
154
155     private Bundle getBundle() throws InvalidRegistryObjectException {
156         String JavaDoc symbolicName= fElement.getContributor().getName();
157         Bundle bundle= Platform.getBundle(symbolicName);
158         return bundle;
159     }
160
161     /**
162      * Returns a new instance of the sorter as described in the
163      * extension's xml.
164      *
165      * @return a new instance of the completion proposal computer as
166      * described by this descriptor
167      * @throws CoreException if the creation fails
168      * @throws InvalidRegistryObjectException if the extension is not
169      * valid any longer (e.g. due to plug-in unloading)
170      */

171     private AbstractProposalSorter createSorter() throws CoreException, InvalidRegistryObjectException {
172         return (AbstractProposalSorter) fElement.createExecutableExtension(CLASS);
173     }
174     
175     /**
176      * Safely computes completion proposals through the described extension. If the extension throws
177      * an exception or otherwise does not adhere to the contract described in
178      * {@link AbstractProposalSorter}, the list is returned as is.
179      *
180      * @param context the invocation context passed on to the extension
181      * @param proposals the list of computed completion proposals to be sorted (element type:
182      * {@link org.eclipse.jface.text.contentassist.ICompletionProposal}), must be writable
183      */

184     public void sortProposals(ContentAssistInvocationContext context, List JavaDoc proposals) {
185         IStatus status;
186         try {
187             AbstractProposalSorter sorter= getSorter();
188             
189             PerformanceStats stats= startMeter(SORT, sorter);
190             
191             sorter.beginSorting(context);
192             Collections.sort(proposals, sorter);
193             sorter.endSorting();
194             
195             status= stopMeter(stats, SORT);
196             
197             // valid result
198
if (status == null)
199                 return;
200             
201             status= createAPIViolationStatus(SORT);
202             
203         } catch (InvalidRegistryObjectException x) {
204             status= createExceptionStatus(x);
205         } catch (CoreException x) {
206             status= createExceptionStatus(x);
207         } catch (RuntimeException JavaDoc x) {
208             status= createExceptionStatus(x);
209         }
210
211         JavaPlugin.log(status);
212         return;
213     }
214
215     private IStatus stopMeter(final PerformanceStats stats, String JavaDoc operation) {
216         if (MEASURE_PERFORMANCE) {
217             stats.endRun();
218             if (stats.isFailure())
219                 return createPerformanceStatus(operation);
220         }
221         return null;
222     }
223
224     private PerformanceStats startMeter(String JavaDoc context, AbstractProposalSorter sorter) {
225         final PerformanceStats stats;
226         if (MEASURE_PERFORMANCE) {
227             stats= PerformanceStats.getStats(PERFORMANCE_EVENT, sorter);
228             stats.startRun(context);
229         } else {
230             stats= null;
231         }
232         return stats;
233     }
234
235     private Status createExceptionStatus(InvalidRegistryObjectException x) {
236         // extension has become invalid - log & disable
237
String JavaDoc disable= createBlameMessage();
238         String JavaDoc reason= JavaTextMessages.CompletionProposalComputerDescriptor_reason_invalid;
239         return new Status(IStatus.INFO, JavaPlugin.getPluginId(), IStatus.OK, disable + " " + reason, x); //$NON-NLS-1$
240
}
241
242     private Status createExceptionStatus(CoreException x) {
243         // unable to instantiate the extension - log & disable
244
String JavaDoc disable= createBlameMessage();
245         String JavaDoc reason= JavaTextMessages.CompletionProposalComputerDescriptor_reason_instantiation;
246         return new Status(IStatus.ERROR, JavaPlugin.getPluginId(), IStatus.OK, disable + " " + reason, x); //$NON-NLS-1$
247
}
248     
249     private Status createExceptionStatus(RuntimeException JavaDoc x) {
250         // misbehaving extension - log & disable
251
String JavaDoc disable= createBlameMessage();
252         String JavaDoc reason= JavaTextMessages.CompletionProposalComputerDescriptor_reason_runtime_ex;
253         return new Status(IStatus.WARNING, JavaPlugin.getPluginId(), IStatus.OK, disable + " " + reason, x); //$NON-NLS-1$
254
}
255
256     private Status createAPIViolationStatus(String JavaDoc operation) {
257         String JavaDoc disable= createBlameMessage();
258         Object JavaDoc[] args= {operation};
259         String JavaDoc reason= Messages.format(JavaTextMessages.CompletionProposalComputerDescriptor_reason_API, args);
260         return new Status(IStatus.WARNING, JavaPlugin.getPluginId(), IStatus.OK, disable + " " + reason, null); //$NON-NLS-1$
261
}
262
263     private Status createPerformanceStatus(String JavaDoc operation) {
264         String JavaDoc disable= createBlameMessage();
265         Object JavaDoc[] args= {operation};
266         String JavaDoc reason= Messages.format(JavaTextMessages.CompletionProposalComputerDescriptor_reason_performance, args);
267         return new Status(IStatus.WARNING, JavaPlugin.getPluginId(), IStatus.OK, disable + " " + reason, null); //$NON-NLS-1$
268
}
269
270     private String JavaDoc createBlameMessage() {
271         Object JavaDoc[] args= { getName(), getId() };
272         String JavaDoc disable= Messages.format(JavaTextMessages.ProposalSorterHandle_blame, args);
273         return disable;
274     }
275     
276     /**
277      * Returns the error message from the described extension, <code>null</code> for no error.
278      *
279      * @return the error message from the described extension, <code>null</code> for no error
280      */

281     public String JavaDoc getErrorMessage() {
282         return null;
283     }
284     
285 }
286
Popular Tags