KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2000, 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.ArrayList JavaDoc;
14 import java.util.List JavaDoc;
15
16 import org.eclipse.text.edits.MalformedTreeException;
17 import org.eclipse.text.edits.TextEdit;
18
19 import org.eclipse.core.runtime.Assert;
20 import org.eclipse.core.runtime.CoreException;
21 import org.eclipse.core.runtime.IProgressMonitor;
22 import org.eclipse.core.runtime.NullProgressMonitor;
23
24 import org.eclipse.swt.graphics.Image;
25
26 import org.eclipse.jface.window.Window;
27
28 import org.eclipse.jface.text.BadLocationException;
29 import org.eclipse.jface.text.Document;
30 import org.eclipse.jface.text.IDocument;
31 import org.eclipse.jface.text.IRegion;
32 import org.eclipse.jface.text.TextUtilities;
33 import org.eclipse.jface.text.contentassist.ICompletionProposalExtension4;
34
35 import org.eclipse.jdt.core.ICompilationUnit;
36 import org.eclipse.jdt.core.IJavaProject;
37 import org.eclipse.jdt.core.ISourceRange;
38 import org.eclipse.jdt.core.IType;
39 import org.eclipse.jdt.core.JavaModelException;
40 import org.eclipse.jdt.core.Signature;
41 import org.eclipse.jdt.core.dom.AST;
42 import org.eclipse.jdt.core.dom.ASTParser;
43 import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
44 import org.eclipse.jdt.core.dom.CompilationUnit;
45 import org.eclipse.jdt.core.dom.IBinding;
46 import org.eclipse.jdt.core.dom.IMethodBinding;
47 import org.eclipse.jdt.core.dom.ITypeBinding;
48 import org.eclipse.jdt.core.dom.MethodDeclaration;
49 import org.eclipse.jdt.core.dom.Modifier;
50 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
51 import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
52 import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
53 import org.eclipse.jdt.core.formatter.CodeFormatter;
54
55 import org.eclipse.jdt.internal.corext.codemanipulation.CodeGenerationSettings;
56 import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility2;
57 import org.eclipse.jdt.internal.corext.dom.ASTNodes;
58 import org.eclipse.jdt.internal.corext.dom.NodeFinder;
59 import org.eclipse.jdt.internal.corext.template.java.SignatureUtil;
60 import org.eclipse.jdt.internal.corext.util.CodeFormatterUtil;
61 import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
62 import org.eclipse.jdt.internal.corext.util.Strings;
63
64 import org.eclipse.jdt.internal.ui.JavaPlugin;
65 import org.eclipse.jdt.internal.ui.JavaPluginImages;
66 import org.eclipse.jdt.internal.ui.dialogs.OverrideMethodDialog;
67 import org.eclipse.jdt.internal.ui.preferences.JavaPreferencesSettings;
68
69 public class AnonymousTypeCompletionProposal extends JavaTypeCompletionProposal implements ICompletionProposalExtension4 {
70
71     private String JavaDoc fDeclarationSignature;
72     private IType fSuperType;
73
74     public AnonymousTypeCompletionProposal(IJavaProject jproject, ICompilationUnit cu, int start, int length, String JavaDoc constructorCompletion, String JavaDoc displayName, String JavaDoc declarationSignature, int relevance) {
75         super(constructorCompletion, cu, start, length, null, displayName, relevance);
76         Assert.isNotNull(declarationSignature);
77         Assert.isNotNull(jproject);
78         Assert.isNotNull(cu);
79
80         fDeclarationSignature= declarationSignature;
81         fSuperType= getDeclaringType(jproject, SignatureUtil.stripSignatureToFQN(String.valueOf(declarationSignature)));
82
83         setImage(getImageForType(fSuperType));
84         setCursorPosition(constructorCompletion.indexOf('(') + 1);
85     }
86
87     private int createDummy(String JavaDoc name, StringBuffer JavaDoc buffer) throws JavaModelException {
88         String JavaDoc lineDelim= "\n"; // Using newline is ok since source is used in dummy compilation unit //$NON-NLS-1$
89
buffer.append("class "); //$NON-NLS-1$
90
buffer.append(name);
91         if (fSuperType.isInterface())
92             buffer.append(" implements "); //$NON-NLS-1$
93
else
94             buffer.append(" extends "); //$NON-NLS-1$
95
if (fDeclarationSignature != null)
96             buffer.append(Signature.toString(fDeclarationSignature));
97         else
98             buffer.append(fSuperType.getFullyQualifiedParameterizedName());
99         int start= buffer.length();
100         buffer.append("{"); //$NON-NLS-1$
101
buffer.append(lineDelim);
102         buffer.append(lineDelim);
103         buffer.append("}"); //$NON-NLS-1$
104
return start;
105     }
106
107     private boolean createStubs(StringBuffer JavaDoc buffer, ImportRewrite importRewrite) throws CoreException {
108         if (importRewrite == null)
109             return false;
110         if (fSuperType == null)
111             return true;
112         ICompilationUnit copy= null;
113         try {
114             final String JavaDoc name= "Type" + System.currentTimeMillis(); //$NON-NLS-1$
115
copy= fCompilationUnit.getPrimary().getWorkingCopy(null);
116             final StringBuffer JavaDoc contents= new StringBuffer JavaDoc();
117             int start= 0;
118             int end= 0;
119             ISourceRange range= fSuperType.getSourceRange();
120             final boolean sameUnit= range != null && fCompilationUnit.equals(fSuperType.getCompilationUnit());
121             final StringBuffer JavaDoc dummy= new StringBuffer JavaDoc();
122             final int length= createDummy(name, dummy);
123             contents.append(fCompilationUnit.getBuffer().getContents());
124             if (sameUnit) {
125                 final int size= range.getOffset() + range.getLength();
126                 start= size + length;
127                 end= contents.length() - size;
128                 contents.insert(size, dummy.toString());
129             } else {
130                 range= fCompilationUnit.getTypes()[0].getSourceRange();
131                 start= range.getOffset() + length;
132                 end= contents.length() - range.getOffset();
133                 contents.insert(range.getOffset(), dummy.toString());
134             }
135             copy.getBuffer().setContents(contents.toString());
136             JavaModelUtil.reconcile(copy);
137             final ASTParser parser= ASTParser.newParser(AST.JLS3);
138             parser.setResolveBindings(true);
139             parser.setSource(copy);
140             final CompilationUnit unit= (CompilationUnit) parser.createAST(new NullProgressMonitor());
141             IType type= null;
142             IType[] types= copy.getAllTypes();
143             for (int index= 0; index < types.length; index++) {
144                 IType result= types[index];
145                 if (result.getElementName().equals(name)) {
146                     type= result;
147                     break;
148                 }
149             }
150             if (type != null && type.exists()) {
151                 ITypeBinding binding= null;
152                 final AbstractTypeDeclaration declaration= (AbstractTypeDeclaration) ASTNodes.getParent(NodeFinder.perform(unit, type.getNameRange()), AbstractTypeDeclaration.class);
153                 if (declaration != null) {
154                     binding= declaration.resolveBinding();
155                     if (binding != null) {
156                         IMethodBinding[] bindings= StubUtility2.getOverridableMethods(unit.getAST(), binding, true);
157                         CodeGenerationSettings settings= JavaPreferencesSettings.getCodeGenerationSettings(fSuperType.getJavaProject());
158                         String JavaDoc[] keys= null;
159                         if (!fSuperType.isInterface() && !fSuperType.isAnnotation()) {
160                             OverrideMethodDialog dialog= new OverrideMethodDialog(JavaPlugin.getActiveWorkbenchShell(), null, type, true);
161                             dialog.setGenerateComment(false);
162                             dialog.setElementPositionEnabled(false);
163                             if (dialog.open() == Window.OK) {
164                                 Object JavaDoc[] selection= dialog.getResult();
165                                 if (selection != null) {
166                                     ArrayList JavaDoc result= new ArrayList JavaDoc(selection.length);
167                                     for (int index= 0; index < selection.length; index++) {
168                                         if (selection[index] instanceof IMethodBinding)
169                                             result.add(((IBinding) selection[index]).getKey());
170                                     }
171                                     keys= (String JavaDoc[]) result.toArray(new String JavaDoc[result.size()]);
172                                     settings.createComments= dialog.getGenerateComment();
173                                 }
174                             }
175                         } else {
176                             settings.createComments= false;
177                             List JavaDoc list= new ArrayList JavaDoc();
178                             for (int index= 0; index < bindings.length; index++) {
179                                 if (Modifier.isAbstract(bindings[index].getModifiers()))
180                                     list.add(bindings[index].getKey());
181                             }
182                             keys= (String JavaDoc[]) list.toArray(new String JavaDoc[list.size()]);
183                         }
184                         if (keys == null) {
185                             setReplacementString(""); //$NON-NLS-1$
186
setReplacementLength(0);
187                             return false;
188                         }
189                         ASTRewrite rewrite= ASTRewrite.create(unit.getAST());
190                         ListRewrite rewriter= rewrite.getListRewrite(declaration, declaration.getBodyDeclarationsProperty());
191                         String JavaDoc key= null;
192                         MethodDeclaration stub= null;
193                         for (int index= 0; index < keys.length; index++) {
194                             key= keys[index];
195                             for (int offset= 0; offset < bindings.length; offset++) {
196                                 if (key.equals(bindings[offset].getKey())) {
197                                     stub= StubUtility2.createImplementationStub(copy, rewrite, importRewrite, bindings[offset], binding.getName(), binding.isInterface(), settings);
198                                     if (stub != null)
199                                         rewriter.insertFirst(stub, null);
200                                     break;
201                                 }
202                             }
203                         }
204                         IDocument document= new Document(copy.getBuffer().getContents());
205                         try {
206                             rewrite.rewriteAST(document, fCompilationUnit.getJavaProject().getOptions(true)).apply(document, TextEdit.UPDATE_REGIONS);
207                             buffer.append(document.get(start, document.getLength() - start - end));
208                         } catch (MalformedTreeException exception) {
209                             JavaPlugin.log(exception);
210                         } catch (BadLocationException exception) {
211                             JavaPlugin.log(exception);
212                         }
213                     }
214                 }
215             }
216             return true;
217         } finally {
218             if (copy != null)
219                 copy.discardWorkingCopy();
220         }
221     }
222
223     private IType getDeclaringType(IJavaProject project, String JavaDoc typeName) {
224         try {
225             return project.findType(typeName, (IProgressMonitor) null);
226         } catch (JavaModelException e) {
227             JavaPlugin.log(e);
228         }
229         return null;
230     }
231
232     private Image getImageForType(IType type) {
233         String JavaDoc imageName= JavaPluginImages.IMG_OBJS_CLASS; // default
234
if (type != null) {
235             try {
236                 if (type.isAnnotation()) {
237                     imageName= JavaPluginImages.IMG_OBJS_ANNOTATION;
238                 } else if (type.isInterface()) {
239                     imageName= JavaPluginImages.IMG_OBJS_INTERFACE;
240                 }
241             } catch (JavaModelException e) {
242                 JavaPlugin.log(e);
243             }
244         }
245         return JavaPluginImages.get(imageName);
246     }
247
248     /*
249      * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension4#isAutoInsertable()
250      */

251     public boolean isAutoInsertable() {
252         return false;
253     }
254
255     protected boolean updateReplacementString(IDocument document, char trigger, int offset, ImportRewrite impRewrite) throws CoreException, BadLocationException {
256         String JavaDoc replacementString= getReplacementString();
257
258         // construct replacement text: an expression to be formatted
259
StringBuffer JavaDoc buf= new StringBuffer JavaDoc("new A("); //$NON-NLS-1$
260
buf.append(replacementString);
261
262         if (!replacementString.endsWith(")")) { //$NON-NLS-1$
263
buf.append(')');
264         }
265
266         if (!createStubs(buf, impRewrite)) {
267             return false;
268         }
269         if (document.getChar(offset) != ')')
270             buf.append(';');
271
272         // use the code formatter
273
String JavaDoc lineDelim= TextUtilities.getDefaultLineDelimiter(document);
274         final IJavaProject project= fCompilationUnit.getJavaProject();
275         IRegion region= document.getLineInformationOfOffset(getReplacementOffset());
276         int indent= Strings.computeIndentUnits(document.get(region.getOffset(), region.getLength()), project);
277
278         String JavaDoc replacement= CodeFormatterUtil.format(CodeFormatter.K_EXPRESSION, buf.toString(), 0, null, lineDelim, project);
279         replacement= Strings.changeIndent(replacement, 0, project, CodeFormatterUtil.createIndentString(indent, project), lineDelim);
280         setReplacementString(replacement.substring(replacement.indexOf('(') + 1));
281
282         int pos= offset;
283         while (pos < document.getLength() && Character.isWhitespace(document.getChar(pos))) {
284             pos++;
285         }
286
287         if (pos < document.getLength() && document.getChar(pos) == ')') {
288             setReplacementLength(pos - offset + 1);
289         }
290         return true;
291     }
292 }
293
Popular Tags