KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > corext > codemanipulation > AddDelegateMethodsOperation


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.corext.codemanipulation;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.List JavaDoc;
15
16 import org.eclipse.text.edits.TextEdit;
17
18 import org.eclipse.core.runtime.Assert;
19 import org.eclipse.core.runtime.CoreException;
20 import org.eclipse.core.runtime.IProgressMonitor;
21 import org.eclipse.core.runtime.IStatus;
22 import org.eclipse.core.runtime.NullProgressMonitor;
23 import org.eclipse.core.runtime.Status;
24 import org.eclipse.core.runtime.SubProgressMonitor;
25 import org.eclipse.core.runtime.jobs.ISchedulingRule;
26
27 import org.eclipse.core.filebuffers.ITextFileBuffer;
28
29 import org.eclipse.core.resources.IWorkspaceRunnable;
30 import org.eclipse.core.resources.ResourcesPlugin;
31
32 import org.eclipse.jface.text.Document;
33 import org.eclipse.jface.text.IDocument;
34
35 import org.eclipse.ltk.core.refactoring.Change;
36
37 import org.eclipse.jdt.core.Flags;
38 import org.eclipse.jdt.core.ICompilationUnit;
39 import org.eclipse.jdt.core.IField;
40 import org.eclipse.jdt.core.IJavaElement;
41 import org.eclipse.jdt.core.IMember;
42 import org.eclipse.jdt.core.IMethod;
43 import org.eclipse.jdt.core.ISourceReference;
44 import org.eclipse.jdt.core.IType;
45 import org.eclipse.jdt.core.dom.ASTNode;
46 import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
47 import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
48 import org.eclipse.jdt.core.dom.ClassInstanceCreation;
49 import org.eclipse.jdt.core.dom.CompilationUnit;
50 import org.eclipse.jdt.core.dom.EnumConstantDeclaration;
51 import org.eclipse.jdt.core.dom.IBinding;
52 import org.eclipse.jdt.core.dom.ITypeBinding;
53 import org.eclipse.jdt.core.dom.MethodDeclaration;
54 import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
55
56 import org.eclipse.jdt.internal.corext.dom.ASTNodes;
57 import org.eclipse.jdt.internal.corext.dom.NodeFinder;
58 import org.eclipse.jdt.internal.corext.refactoring.changes.CompilationUnitChange;
59 import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite;
60 import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringFileBuffers;
61 import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
62
63 import org.eclipse.jdt.internal.ui.JavaPlugin;
64
65 /**
66  * Workspace runnable to add delegate methods.
67  *
68  * @since 3.1
69  */

70 public final class AddDelegateMethodsOperation implements IWorkspaceRunnable {
71
72     /** Should the resulting edit be applied? */
73     private boolean fApply= true;
74
75     /** The method binding keys for which a method was generated */
76     private final List JavaDoc fCreated= new ArrayList JavaDoc();
77
78     /** The resulting text edit */
79     private TextEdit fEdit= null;
80
81     /** The insertion point, or <code>null</code> */
82     private final IJavaElement fInsert;
83
84     /** The method binding keys to implement */
85     private final String JavaDoc[] fMethodKeys;
86
87     /** Should the compilation unit content be saved? */
88     private final boolean fSave;
89
90     /** The code generation settings to use */
91     private final CodeGenerationSettings fSettings;
92
93     /** The type declaration to add the methods to */
94     private final IType fType;
95
96     /** The compilation unit ast node */
97     private final CompilationUnit fUnit;
98
99     /** The variable binding keys to implement */
100     private final String JavaDoc[] fVariableKeys;
101
102     /**
103      * Creates a new add delegate methods operation.
104      *
105      * @param type the type to add the methods to
106      * @param insert the insertion point, or <code>null</code>
107      * @param variableKeys the variable binding keys to implement
108      * @param methodKeys the method binding keys to implement
109      * @param settings the code generation settings to use
110      * @param apply <code>true</code> if the resulting edit should be applied, <code>false</code> otherwise
111      * @param save <code>true</code> if the changed compilation unit should be saved, <code>false</code> otherwise
112      */

113     public AddDelegateMethodsOperation(final IType type, final IJavaElement insert, final CompilationUnit unit, final String JavaDoc[] variableKeys, final String JavaDoc[] methodKeys, final CodeGenerationSettings settings, final boolean apply, final boolean save) {
114         Assert.isNotNull(type);
115         Assert.isNotNull(unit);
116         Assert.isNotNull(variableKeys);
117         Assert.isNotNull(methodKeys);
118         Assert.isNotNull(settings);
119         Assert.isTrue(variableKeys.length == methodKeys.length);
120         fType= type;
121         fInsert= insert;
122         fUnit= unit;
123         fVariableKeys= variableKeys;
124         fMethodKeys= methodKeys;
125         fSettings= settings;
126         fSave= save;
127         fApply= apply;
128     }
129
130     /**
131      * Returns the method binding keys for which a method has been generated.
132      *
133      * @return the method binding keys
134      */

135     public final String JavaDoc[] getCreatedMethods() {
136         final String JavaDoc[] keys= new String JavaDoc[fCreated.size()];
137         fCreated.toArray(keys);
138         return keys;
139     }
140
141     /**
142      * Returns the resulting text edit.
143      *
144      * @return the resulting text edit
145      */

146     public final TextEdit getResultingEdit() {
147         return fEdit;
148     }
149
150     /**
151      * Returns the scheduling rule for this operation.
152      *
153      * @return the scheduling rule
154      */

155     public final ISchedulingRule getSchedulingRule() {
156         return ResourcesPlugin.getWorkspace().getRoot();
157     }
158
159     /*
160      * @see org.eclipse.core.resources.IWorkspaceRunnable#run(org.eclipse.core.runtime.IProgressMonitor)
161      */

162     public final void run(IProgressMonitor monitor) throws CoreException {
163         if (monitor == null)
164             monitor= new NullProgressMonitor();
165         try {
166             monitor.beginTask("", 1); //$NON-NLS-1$
167
monitor.setTaskName(CodeGenerationMessages.AddDelegateMethodsOperation_monitor_message);
168             fCreated.clear();
169             final ICompilationUnit unit= fType.getCompilationUnit();
170             final CompilationUnitRewrite rewrite= new CompilationUnitRewrite(unit, fUnit);
171             ITypeBinding binding= null;
172             ListRewrite rewriter= null;
173             if (fType.isAnonymous()) {
174                 final IJavaElement parent= fType.getParent();
175                 if (parent instanceof IField && Flags.isEnum(((IMember) parent).getFlags())) {
176                     final EnumConstantDeclaration constant= (EnumConstantDeclaration) NodeFinder.perform(rewrite.getRoot(), ((ISourceReference) parent).getSourceRange());
177                     if (constant != null) {
178                         final AnonymousClassDeclaration declaration= constant.getAnonymousClassDeclaration();
179                         if (declaration != null) {
180                             binding= declaration.resolveBinding();
181                             if (binding != null)
182                                 rewriter= rewrite.getASTRewrite().getListRewrite(declaration, AnonymousClassDeclaration.BODY_DECLARATIONS_PROPERTY);
183                         }
184                     }
185                 } else {
186                     final ClassInstanceCreation creation= (ClassInstanceCreation) ASTNodes.getParent(NodeFinder.perform(rewrite.getRoot(), fType.getNameRange()), ClassInstanceCreation.class);
187                     if (creation != null) {
188                         binding= creation.resolveTypeBinding();
189                         final AnonymousClassDeclaration declaration= creation.getAnonymousClassDeclaration();
190                         if (declaration != null)
191                             rewriter= rewrite.getASTRewrite().getListRewrite(declaration, AnonymousClassDeclaration.BODY_DECLARATIONS_PROPERTY);
192                     }
193                 }
194             } else {
195                 final AbstractTypeDeclaration declaration= (AbstractTypeDeclaration) ASTNodes.getParent(NodeFinder.perform(rewrite.getRoot(), fType.getNameRange()), AbstractTypeDeclaration.class);
196                 if (declaration != null) {
197                     binding= declaration.resolveBinding();
198                     rewriter= rewrite.getASTRewrite().getListRewrite(declaration, declaration.getBodyDeclarationsProperty());
199                 }
200             }
201             if (binding != null && rewriter != null) {
202                 final IBinding[][] bindings= StubUtility2.getDelegatableMethods(rewrite.getAST(), binding);
203                 if (bindings != null && bindings.length > 0) {
204                     ITextFileBuffer buffer= null;
205                     IDocument document= null;
206                     try {
207                         if (!JavaModelUtil.isPrimary(unit))
208                             document= new Document(unit.getBuffer().getContents());
209                         else {
210                             buffer= RefactoringFileBuffers.acquire(unit);
211                             document= buffer.getDocument();
212                         }
213                         ASTNode insertion= null;
214                         if (fInsert instanceof IMethod)
215                             insertion= ASTNodes.getParent(NodeFinder.perform(rewrite.getRoot(), ((IMethod) fInsert).getNameRange()), MethodDeclaration.class);
216                         String JavaDoc variableKey= null;
217                         String JavaDoc methodKey= null;
218                         MethodDeclaration stub= null;
219                         for (int index= 0; index < fMethodKeys.length; index++) {
220                             methodKey= fMethodKeys[index];
221                             variableKey= fVariableKeys[index];
222                             if (monitor.isCanceled())
223                                 break;
224                             for (int offset= 0; offset < bindings.length; offset++) {
225                                 if (bindings[offset][0].getKey().equals(variableKey) && bindings[offset][1].getKey().equals(methodKey)) {
226                                     stub= StubUtility2.createDelegationStub(rewrite.getCu(), rewrite.getASTRewrite(), rewrite.getImportRewrite(), rewrite.getAST(), bindings[offset], fSettings);
227                                     if (stub != null) {
228                                         fCreated.add(methodKey);
229                                         if (insertion != null)
230                                             rewriter.insertBefore(stub, insertion, null);
231                                         else
232                                             rewriter.insertLast(stub, null);
233                                     }
234                                     break;
235                                 }
236                             }
237                         }
238                         final Change result= rewrite.createChange();
239                         if (result instanceof CompilationUnitChange) {
240                             final CompilationUnitChange change= (CompilationUnitChange) result;
241                             final TextEdit edit= change.getEdit();
242                             if (edit != null) {
243                                 try {
244                                     fEdit= edit;
245                                     if (fApply)
246                                         edit.apply(document, TextEdit.UPDATE_REGIONS);
247                                     if (fSave) {
248                                         if (buffer != null)
249                                             buffer.commit(new SubProgressMonitor(monitor, 1), true);
250                                         else
251                                             unit.getBuffer().setContents(document.get());
252                                     }
253                                 } catch (Exception JavaDoc exception) {
254                                     throw new CoreException(new Status(IStatus.ERROR, JavaPlugin.getPluginId(), 0, exception.getLocalizedMessage(), exception));
255                                 }
256                             }
257                         }
258                     } finally {
259                         if (buffer != null)
260                             RefactoringFileBuffers.release(unit);
261                     }
262                 }
263             }
264         } finally {
265             monitor.done();
266         }
267     }
268 }
269
Popular Tags