KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2007 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 org.eclipse.text.edits.TextEdit;
14
15 import org.eclipse.core.runtime.Assert;
16 import org.eclipse.core.runtime.CoreException;
17 import org.eclipse.core.runtime.NullProgressMonitor;
18
19 import org.eclipse.jface.preference.IPreferenceStore;
20
21 import org.eclipse.jface.text.BadLocationException;
22 import org.eclipse.jface.text.IDocument;
23
24 import org.eclipse.jdt.core.CompletionProposal;
25 import org.eclipse.jdt.core.ICompilationUnit;
26 import org.eclipse.jdt.core.IJavaProject;
27 import org.eclipse.jdt.core.JavaCore;
28 import org.eclipse.jdt.core.Signature;
29 import org.eclipse.jdt.core.dom.CompilationUnit;
30 import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
31
32 import org.eclipse.jdt.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext;
33 import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility;
34 import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
35
36 import org.eclipse.jdt.ui.PreferenceConstants;
37 import org.eclipse.jdt.ui.text.java.JavaContentAssistInvocationContext;
38
39 import org.eclipse.jdt.internal.ui.JavaPlugin;
40 import org.eclipse.jdt.internal.ui.javaeditor.ASTProvider;
41
42
43 /**
44  * Completion proposal for required imports.
45  *
46  * @since 3.3
47   */

48 public class ImportCompletionProposal extends AbstractJavaCompletionProposal {
49
50     private final ICompilationUnit fCompilationUnit;
51     private final int fParentProposalKind;
52     private ImportRewrite fImportRewrite;
53     private ContextSensitiveImportRewriteContext fImportContext;
54     private final CompletionProposal fProposal;
55     private boolean fReplacementStringComputed;
56     
57
58     public ImportCompletionProposal(CompletionProposal proposal, JavaContentAssistInvocationContext context, int parentProposalKind) {
59         super(context);
60         fProposal= proposal;
61         fParentProposalKind= parentProposalKind;
62         fCompilationUnit= context.getCompilationUnit();
63     }
64
65     /*
66      * @see org.eclipse.jdt.internal.ui.text.java.AbstractJavaCompletionProposal#getReplacementString()
67      */

68     public final String JavaDoc getReplacementString() {
69         if (!fReplacementStringComputed)
70             setReplacementString(computeReplacementString());
71         return super.getReplacementString();
72     }
73     
74     /**
75      * Computes the replacement string.
76      *
77      * @return the replacement string
78      */

79     private String JavaDoc computeReplacementString() {
80         int proposalKind= fProposal.getKind();
81         String JavaDoc qualifiedTypeName= null;
82         char[] qualifiedType= null;
83         if (proposalKind == CompletionProposal.TYPE_IMPORT) {
84             qualifiedType= fProposal.getSignature();
85             qualifiedTypeName= String.valueOf(Signature.toCharArray(qualifiedType));
86         } else if (proposalKind == CompletionProposal.METHOD_IMPORT || proposalKind == CompletionProposal.FIELD_IMPORT) {
87             qualifiedType= fProposal.getDeclarationSignature();
88             qualifiedTypeName= String.valueOf(Signature.toCharArray(qualifiedType));
89         } else {
90             /*
91              * In 3.3 we only support the above import proposals, see
92              * CompletionProposal#getRequiredProposals()
93              */

94              Assert.isTrue(false);
95         }
96         
97         /* Add imports if the preference is on. */
98         fImportRewrite= createImportRewrite();
99         if (fImportRewrite != null) {
100             if (proposalKind == CompletionProposal.TYPE_IMPORT) {
101                 String JavaDoc simpleType= fImportRewrite.addImport(qualifiedTypeName, fImportContext);
102                 if (fParentProposalKind == CompletionProposal.METHOD_REF)
103                     return simpleType + "."; //$NON-NLS-1$
104
} else
105                 fImportRewrite.addStaticImport(qualifiedTypeName, String.valueOf(fProposal.getName()), proposalKind == CompletionProposal.FIELD_IMPORT, fImportContext);
106             return ""; //$NON-NLS-1$
107
}
108         
109         // Case where we don't have an import rewrite (see allowAddingImports)
110

111         if (fCompilationUnit != null && JavaModelUtil.isImplicitImport(Signature.getQualifier(qualifiedTypeName), fCompilationUnit)) {
112             /* No imports for implicit imports. */
113             
114             if (fProposal.getKind() == CompletionProposal.TYPE_IMPORT && fParentProposalKind == CompletionProposal.FIELD_REF)
115                 return ""; //$NON-NLS-1$
116
qualifiedTypeName= String.valueOf(Signature.getSignatureSimpleName(qualifiedType));
117         }
118         
119         return qualifiedTypeName + "."; //$NON-NLS-1$
120
}
121
122     /*
123      * @see org.eclipse.jdt.internal.ui.text.java.AbstractJavaCompletionProposal#apply(org.eclipse.jface.text.IDocument, char, int)
124      */

125     public void apply(IDocument document, char trigger, int offset) {
126         try {
127             super.apply(document, trigger, offset);
128
129             if (fImportRewrite != null && fImportRewrite.hasRecordedChanges()) {
130                 int oldLen= document.getLength();
131                 fImportRewrite.rewriteImports(new NullProgressMonitor()).apply(document, TextEdit.UPDATE_REGIONS);
132                 setReplacementOffset(getReplacementOffset() + document.getLength() - oldLen);
133             }
134         } catch (CoreException e) {
135             JavaPlugin.log(e);
136         } catch (BadLocationException e) {
137             JavaPlugin.log(e);
138         }
139     }
140     
141     /**
142      * Creates and returns the import rewrite
143      * if imports should be added at all.
144      *
145      * @return the import rewrite or <code>null</code> if no imports can or should be added
146      */

147     private ImportRewrite createImportRewrite() {
148         if (fCompilationUnit != null && shouldAddImports()) {
149             try {
150                 CompilationUnit cu= getASTRoot(fCompilationUnit);
151                 if (cu == null) {
152                     ImportRewrite rewrite= StubUtility.createImportRewrite(fCompilationUnit, true);
153                     fImportContext= null;
154                     return rewrite;
155                 } else {
156                     ImportRewrite rewrite= StubUtility.createImportRewrite(cu, true);
157                     fImportContext= new ContextSensitiveImportRewriteContext(cu, fInvocationContext.getInvocationOffset(), rewrite);
158                     return rewrite;
159                 }
160             } catch (CoreException x) {
161                 JavaPlugin.log(x);
162             }
163         }
164         return null;
165     }
166
167     private CompilationUnit getASTRoot(ICompilationUnit compilationUnit) {
168         return JavaPlugin.getDefault().getASTProvider().getAST(compilationUnit, ASTProvider.WAIT_NO, new NullProgressMonitor());
169     }
170
171     /**
172      * Returns <code>true</code> if imports should be added. The return value depends on the context
173      * and preferences only and does not take into account the contents of the compilation unit or
174      * the kind of proposal. Even if <code>true</code> is returned, there may be cases where no
175      * imports are added for the proposal. For example:
176      * <ul>
177      * <li>when completing within the import section</li>
178      * <li>when completing informal javadoc references (e.g. within <code>&lt;code&gt;</code>
179      * tags)</li>
180      * <li>when completing a type that conflicts with an existing import</li>
181      * <li>when completing an implicitly imported type (same package, <code>java.lang</code>
182      * types)</li>
183      * </ul>
184      * <p>
185      * The decision whether a qualified type or the simple type name should be inserted must take
186      * into account these different scenarios.
187      * </p>
188      *
189      * @return <code>true</code> if imports may be added, <code>false</code> if not
190      */

191     private boolean shouldAddImports() {
192         if (isInJavadoc() && !isJavadocProcessingEnabled())
193             return false;
194         
195         IPreferenceStore preferenceStore= JavaPlugin.getDefault().getPreferenceStore();
196         return preferenceStore.getBoolean(PreferenceConstants.CODEASSIST_ADDIMPORT);
197     }
198
199     /**
200      * Returns whether Javadoc processing is enabled.
201      *
202      * @return <code>true</code> if Javadoc processing is enabled, <code>false</code> otherwise
203      */

204     private boolean isJavadocProcessingEnabled() {
205         IJavaProject project= fCompilationUnit.getJavaProject();
206         boolean processJavadoc;
207         if (project == null)
208             processJavadoc= JavaCore.ENABLED.equals(JavaCore.getOption(JavaCore.COMPILER_DOC_COMMENT_SUPPORT));
209         else
210             processJavadoc= JavaCore.ENABLED.equals(project.getOption(JavaCore.COMPILER_DOC_COMMENT_SUPPORT, true));
211         return processJavadoc;
212     }
213 }
214
Popular Tags