001: /*******************************************************************************
002: * Copyright (c) 2005, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.ui.text.java;
011:
012: import java.util.ArrayList;
013: import java.util.Arrays;
014: import java.util.Collections;
015: import java.util.HashSet;
016: import java.util.List;
017: import java.util.Set;
018:
019: import org.eclipse.core.runtime.IProgressMonitor;
020:
021: import org.eclipse.jdt.core.ICompilationUnit;
022:
023: import org.eclipse.jdt.ui.text.java.ContentAssistInvocationContext;
024: import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal;
025: import org.eclipse.jdt.ui.text.java.IJavaCompletionProposalComputer;
026: import org.eclipse.jdt.ui.text.java.JavaContentAssistInvocationContext;
027:
028: import org.eclipse.jdt.internal.ui.text.template.contentassist.TemplateEngine;
029: import org.eclipse.jdt.internal.ui.text.template.contentassist.TemplateProposal;
030:
031: /**
032: * An template completion proposal computer can generate template completion proposals
033: * from a given TemplateEngine.
034: *
035: * Subclasses must implement {@link #computeCompletionEngine(JavaContentAssistInvocationContext)}
036: *
037: * @since 3.4
038: */
039: public abstract class AbstractTemplateCompletionProposalComputer
040: implements IJavaCompletionProposalComputer {
041:
042: /**
043: * The engine for the current session, if any
044: */
045: private TemplateEngine fEngine;
046:
047: /*
048: * @see org.eclipse.jface.text.contentassist.ICompletionProposalComputer#computeCompletionProposals(org.eclipse.jface.text.contentassist.TextContentAssistInvocationContext, org.eclipse.core.runtime.IProgressMonitor)
049: */
050: public List computeCompletionProposals(
051: ContentAssistInvocationContext context,
052: IProgressMonitor monitor) {
053: if (!(context instanceof JavaContentAssistInvocationContext))
054: return Collections.EMPTY_LIST;
055:
056: JavaContentAssistInvocationContext javaContext = (JavaContentAssistInvocationContext) context;
057: ICompilationUnit unit = javaContext.getCompilationUnit();
058: if (unit == null)
059: return Collections.EMPTY_LIST;
060:
061: fEngine = computeCompletionEngine(javaContext);
062: if (fEngine != null) {
063:
064: fEngine.reset();
065: fEngine.complete(javaContext.getViewer(), javaContext
066: .getInvocationOffset(), unit);
067:
068: TemplateProposal[] templateProposals = fEngine.getResults();
069: List result = new ArrayList(Arrays
070: .asList(templateProposals));
071:
072: IJavaCompletionProposal[] keyWordResults = javaContext
073: .getKeywordProposals();
074: if (keyWordResults.length > 0) {
075: List removals = new ArrayList();
076:
077: // update relevance of template proposals that match with a keyword
078: // give those templates slightly more relevance than the keyword to
079: // sort them first
080: // remove keyword templates that don't have an equivalent
081: // keyword proposal
082: if (keyWordResults.length > 0) {
083: outer: for (int k = 0; k < templateProposals.length; k++) {
084: TemplateProposal curr = templateProposals[k];
085: String name = curr.getTemplate().getName();
086: for (int i = 0; i < keyWordResults.length; i++) {
087: String keyword = keyWordResults[i]
088: .getDisplayString();
089: if (name.startsWith(keyword)) {
090: curr.setRelevance(keyWordResults[i]
091: .getRelevance() + 1);
092: continue outer;
093: }
094: }
095: if (isKeyword(name))
096: removals.add(curr);
097: }
098: }
099:
100: result.removeAll(removals);
101: }
102: return result;
103: }
104:
105: return Collections.EMPTY_LIST;
106: }
107:
108: /**
109: * Compute the engine used to retrieve completion proposals in the given context
110: *
111: * @param context the context where proposals will be made
112: * @return the engine or <code>null</code> if no engine available in the context
113: */
114: protected abstract TemplateEngine computeCompletionEngine(
115: JavaContentAssistInvocationContext context);
116:
117: /*
118: * @see org.eclipse.jface.text.contentassist.ICompletionProposalComputer#computeContextInformation(org.eclipse.jface.text.contentassist.TextContentAssistInvocationContext, org.eclipse.core.runtime.IProgressMonitor)
119: */
120: public List computeContextInformation(
121: ContentAssistInvocationContext context,
122: IProgressMonitor monitor) {
123: return Collections.EMPTY_LIST;
124: }
125:
126: private static final Set KEYWORDS;
127:
128: static {
129: Set keywords = new HashSet(42);
130: keywords.add("abstract"); //$NON-NLS-1$
131: keywords.add("assert"); //$NON-NLS-1$
132: keywords.add("break"); //$NON-NLS-1$
133: keywords.add("case"); //$NON-NLS-1$
134: keywords.add("catch"); //$NON-NLS-1$
135: keywords.add("class"); //$NON-NLS-1$
136: keywords.add("continue"); //$NON-NLS-1$
137: keywords.add("default"); //$NON-NLS-1$
138: keywords.add("do"); //$NON-NLS-1$
139: keywords.add("else"); //$NON-NLS-1$
140: keywords.add("elseif"); //$NON-NLS-1$
141: keywords.add("extends"); //$NON-NLS-1$
142: keywords.add("final"); //$NON-NLS-1$
143: keywords.add("finally"); //$NON-NLS-1$
144: keywords.add("for"); //$NON-NLS-1$
145: keywords.add("if"); //$NON-NLS-1$
146: keywords.add("implements"); //$NON-NLS-1$
147: keywords.add("import"); //$NON-NLS-1$
148: keywords.add("instanceof"); //$NON-NLS-1$
149: keywords.add("interface"); //$NON-NLS-1$
150: keywords.add("native"); //$NON-NLS-1$
151: keywords.add("new"); //$NON-NLS-1$
152: keywords.add("package"); //$NON-NLS-1$
153: keywords.add("private"); //$NON-NLS-1$
154: keywords.add("protected"); //$NON-NLS-1$
155: keywords.add("public"); //$NON-NLS-1$
156: keywords.add("return"); //$NON-NLS-1$
157: keywords.add("static"); //$NON-NLS-1$
158: keywords.add("strictfp"); //$NON-NLS-1$
159: keywords.add("super"); //$NON-NLS-1$
160: keywords.add("switch"); //$NON-NLS-1$
161: keywords.add("synchronized"); //$NON-NLS-1$
162: keywords.add("this"); //$NON-NLS-1$
163: keywords.add("throw"); //$NON-NLS-1$
164: keywords.add("throws"); //$NON-NLS-1$
165: keywords.add("transient"); //$NON-NLS-1$
166: keywords.add("try"); //$NON-NLS-1$
167: keywords.add("volatile"); //$NON-NLS-1$
168: keywords.add("while"); //$NON-NLS-1$
169: keywords.add("true"); //$NON-NLS-1$
170: keywords.add("false"); //$NON-NLS-1$
171: keywords.add("null"); //$NON-NLS-1$
172: KEYWORDS = Collections.unmodifiableSet(keywords);
173: }
174:
175: private boolean isKeyword(String name) {
176: return KEYWORDS.contains(name);
177: }
178:
179: /*
180: * @see org.eclipse.jface.text.contentassist.ICompletionProposalComputer#getErrorMessage()
181: */
182: public String getErrorMessage() {
183: return null;
184: }
185:
186: /*
187: * @see org.eclipse.jdt.ui.text.java.IJavaCompletionProposalComputer#sessionStarted()
188: */
189: public void sessionStarted() {
190: }
191:
192: /* (non-Javadoc)
193: * @see org.eclipse.jdt.ui.text.java.IJavaCompletionProposalComputer#sessionEnded()
194: */
195: public void sessionEnded() {
196: if (fEngine != null) {
197: fEngine.reset();
198: fEngine = null;
199: }
200: }
201:
202: }
|