1 11 package org.eclipse.jdt.internal.corext.codemanipulation; 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.IProgressMonitor; 18 import org.eclipse.core.runtime.IStatus; 19 import org.eclipse.core.runtime.NullProgressMonitor; 20 import org.eclipse.core.runtime.OperationCanceledException; 21 import org.eclipse.core.runtime.Status; 22 import org.eclipse.core.runtime.SubProgressMonitor; 23 import org.eclipse.core.runtime.jobs.ISchedulingRule; 24 25 import org.eclipse.core.resources.IWorkspaceRunnable; 26 import org.eclipse.core.resources.ResourcesPlugin; 27 28 import org.eclipse.jdt.core.Flags; 29 import org.eclipse.jdt.core.ICompilationUnit; 30 import org.eclipse.jdt.core.IField; 31 import org.eclipse.jdt.core.IJavaElement; 32 import org.eclipse.jdt.core.IMethod; 33 import org.eclipse.jdt.core.IType; 34 import org.eclipse.jdt.core.JavaModelException; 35 import org.eclipse.jdt.core.dom.ASTNode; 36 import org.eclipse.jdt.core.dom.AbstractTypeDeclaration; 37 import org.eclipse.jdt.core.dom.AnonymousClassDeclaration; 38 import org.eclipse.jdt.core.dom.ClassInstanceCreation; 39 import org.eclipse.jdt.core.dom.CompilationUnit; 40 import org.eclipse.jdt.core.dom.FieldDeclaration; 41 import org.eclipse.jdt.core.dom.MethodDeclaration; 42 import org.eclipse.jdt.core.dom.Modifier; 43 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; 44 import org.eclipse.jdt.core.dom.rewrite.ListRewrite; 45 import org.eclipse.jdt.core.formatter.CodeFormatter; 46 47 import org.eclipse.jdt.internal.corext.dom.ASTNodes; 48 import org.eclipse.jdt.internal.corext.dom.ModifierRewrite; 49 import org.eclipse.jdt.internal.corext.dom.NodeFinder; 50 import org.eclipse.jdt.internal.corext.util.CodeFormatterUtil; 51 import org.eclipse.jdt.internal.corext.util.JavaModelUtil; 52 53 import org.eclipse.jdt.ui.JavaUI; 54 55 60 public final class AddGetterSetterOperation implements IWorkspaceRunnable { 61 62 63 private static final String [] EMPTY_STRINGS= new String [0]; 64 65 66 private final IField[] fAccessorFields; 67 68 69 private boolean fApply= true; 70 71 72 private TextEdit fEdit= null; 73 74 75 private final IField[] fGetterFields; 76 77 78 private final IJavaElement fInsert; 79 80 81 private final boolean fSave; 82 83 84 private final IField[] fSetterFields; 85 86 87 private final CodeGenerationSettings fSettings; 88 89 90 private boolean fSkipAllExisting= false; 91 92 93 private final IRequestQuery fSkipExistingQuery; 94 95 96 private boolean fSort= false; 97 98 99 private final IType fType; 100 101 102 private final CompilationUnit fASTRoot; 103 104 105 private int fVisibility= Modifier.PUBLIC; 106 107 121 public AddGetterSetterOperation(final IType type, final IField[] getters, final IField[] setters, final IField[] accessors, final CompilationUnit unit, final IRequestQuery skipExistingQuery, final IJavaElement insert, final CodeGenerationSettings settings, final boolean apply, final boolean save) { 122 Assert.isNotNull(type); 123 Assert.isNotNull(unit); 124 Assert.isNotNull(settings); 125 fType= type; 126 fGetterFields= getters; 127 fSetterFields= setters; 128 fAccessorFields= accessors; 129 fASTRoot= unit; 130 fSkipExistingQuery= skipExistingQuery; 131 fInsert= insert; 132 fSettings= settings; 133 fSave= save; 134 fApply= apply; 135 } 136 137 147 private void addNewAccessor(final IType type, final IField field, final String contents, final ListRewrite rewrite, final ASTNode insertion) throws JavaModelException { 148 final String delimiter= StubUtility.getLineDelimiterUsed(type); 149 final MethodDeclaration declaration= (MethodDeclaration) rewrite.getASTRewrite().createStringPlaceholder(CodeFormatterUtil.format(CodeFormatter.K_CLASS_BODY_DECLARATIONS, contents, 0, null, delimiter, field.getJavaProject()), ASTNode.METHOD_DECLARATION); 150 if (insertion != null) 151 rewrite.insertBefore(declaration, insertion, null); 152 else 153 rewrite.insertLast(declaration, null); 154 } 155 156 164 private void generateGetterMethod(final IField field, final ListRewrite rewrite) throws CoreException, OperationCanceledException { 165 final IType type= field.getDeclaringType(); 166 final String name= GetterSetterUtil.getGetterName(field, null); 167 final IMethod existing= JavaModelUtil.findMethod(name, EMPTY_STRINGS, false, type); 168 if (existing == null || !querySkipExistingMethods(existing)) { 169 IJavaElement sibling= null; 170 if (existing != null) { 171 sibling= StubUtility.findNextSibling(existing); 172 removeExistingAccessor(existing, rewrite); 173 } else 174 sibling= fInsert; 175 ASTNode insertion= null; 176 if (sibling instanceof IMethod) 177 insertion= ASTNodes.getParent(NodeFinder.perform(rewrite.getParent().getRoot(), ((IMethod) fInsert).getNameRange()), MethodDeclaration.class); 178 addNewAccessor(type, field, GetterSetterUtil.getGetterStub(field, name, fSettings.createComments, fVisibility | (field.getFlags() & Flags.AccStatic)), rewrite, insertion); 179 } 180 } 181 182 191 private void generateSetterMethod(final IField field, ASTRewrite astRewrite, final ListRewrite rewrite) throws CoreException, OperationCanceledException { 192 final IType type= field.getDeclaringType(); 193 final String name= GetterSetterUtil.getSetterName(field, null); 194 final IMethod existing= JavaModelUtil.findMethod(name, new String [] { field.getTypeSignature()}, false, type); 195 if (existing == null || querySkipExistingMethods(existing)) { 196 IJavaElement sibling= null; 197 if (existing != null) { 198 sibling= StubUtility.findNextSibling(existing); 199 removeExistingAccessor(existing, rewrite); 200 } else 201 sibling= fInsert; 202 ASTNode insertion= null; 203 if (sibling instanceof IMethod) 204 insertion= ASTNodes.getParent(NodeFinder.perform(fASTRoot, ((IMethod) fInsert).getNameRange()), MethodDeclaration.class); 205 addNewAccessor(type, field, GetterSetterUtil.getSetterStub(field, name, fSettings.createComments, fVisibility | (field.getFlags() & Flags.AccStatic)), rewrite, insertion); 206 if (Flags.isFinal(field.getFlags())) { 207 ASTNode fieldDecl= ASTNodes.getParent(NodeFinder.perform(fASTRoot, field.getNameRange()), FieldDeclaration.class); 208 if (fieldDecl != null) { 209 ModifierRewrite.create(astRewrite, fieldDecl).setModifiers(0, Modifier.FINAL, null); 210 } 211 } 212 213 } 214 } 215 216 221 public final TextEdit getResultingEdit() { 222 return fEdit; 223 } 224 225 230 public final ISchedulingRule getSchedulingRule() { 231 return ResourcesPlugin.getWorkspace().getRoot(); 232 } 233 234 239 public final int getVisibility() { 240 return fVisibility; 241 } 242 243 248 public final boolean isSkipAllExisting() { 249 return fSkipAllExisting; 250 } 251 252 259 private boolean querySkipExistingMethods(final IMethod method) throws OperationCanceledException { 260 if (!fSkipAllExisting) { 261 switch (fSkipExistingQuery.doQuery(method)) { 262 case IRequestQuery.CANCEL: 263 throw new OperationCanceledException(); 264 case IRequestQuery.NO: 265 return false; 266 case IRequestQuery.YES_ALL: 267 fSkipAllExisting= true; 268 } 269 } 270 return true; 271 } 272 273 280 private void removeExistingAccessor(final IMethod accessor, final ListRewrite rewrite) throws JavaModelException { 281 final MethodDeclaration declaration= (MethodDeclaration) ASTNodes.getParent(NodeFinder.perform(rewrite.getParent().getRoot(), accessor.getNameRange()), MethodDeclaration.class); 282 if (declaration != null) 283 rewrite.remove(declaration, null); 284 } 285 286 289 public final void run(IProgressMonitor monitor) throws CoreException { 290 if (monitor == null) 291 monitor= new NullProgressMonitor(); 292 try { 293 monitor.setTaskName(CodeGenerationMessages.AddGetterSetterOperation_description); 294 monitor.beginTask("", fGetterFields.length + fSetterFields.length); final ICompilationUnit unit= fType.getCompilationUnit(); 296 final ASTRewrite astRewrite= ASTRewrite.create(fASTRoot.getAST()); 297 ListRewrite listRewriter= null; 298 if (fType.isAnonymous()) { 299 final ClassInstanceCreation creation= (ClassInstanceCreation) ASTNodes.getParent(NodeFinder.perform(fASTRoot, fType.getNameRange()), ClassInstanceCreation.class); 300 if (creation != null) { 301 final AnonymousClassDeclaration declaration= creation.getAnonymousClassDeclaration(); 302 if (declaration != null) 303 listRewriter= astRewrite.getListRewrite(declaration, AnonymousClassDeclaration.BODY_DECLARATIONS_PROPERTY); 304 } 305 } else { 306 final AbstractTypeDeclaration declaration= (AbstractTypeDeclaration) ASTNodes.getParent(NodeFinder.perform(fASTRoot, fType.getNameRange()), AbstractTypeDeclaration.class); 307 if (declaration != null) 308 listRewriter= astRewrite.getListRewrite(declaration, declaration.getBodyDeclarationsProperty()); 309 } 310 if (listRewriter == null) { 311 throw new CoreException(new Status(IStatus.ERROR, JavaUI.ID_PLUGIN, IStatus.ERROR, CodeGenerationMessages.AddGetterSetterOperation_error_input_type_not_found, null)); 312 } 313 314 fSkipAllExisting= (fSkipExistingQuery == null); 315 if (!fSort) { 316 for (int index= 0; index < fAccessorFields.length; index++) { 317 generateGetterMethod(fAccessorFields[index], listRewriter); 318 generateSetterMethod(fAccessorFields[index], astRewrite, listRewriter); 319 monitor.worked(1); 320 if (monitor.isCanceled()) { 321 throw new OperationCanceledException(); 322 } 323 } 324 } 325 for (int index= 0; index < fGetterFields.length; index++) { 326 generateGetterMethod(fGetterFields[index], listRewriter); 327 monitor.worked(1); 328 if (monitor.isCanceled()) { 329 throw new OperationCanceledException(); 330 } 331 } 332 for (int index= 0; index < fSetterFields.length; index++) { 333 generateSetterMethod(fSetterFields[index], astRewrite, listRewriter); 334 monitor.worked(1); 335 if (monitor.isCanceled()) { 336 throw new OperationCanceledException(); 337 } 338 } 339 fEdit= astRewrite.rewriteAST(); 340 if (fApply) { 341 JavaModelUtil.applyEdit(unit, fEdit, fSave, new SubProgressMonitor(monitor, 1)); 342 } 343 } finally { 344 monitor.done(); 345 } 346 } 347 348 353 public final void setSkipAllExisting(final boolean skip) { 354 fSkipAllExisting= skip; 355 } 356 357 public void setSort(boolean sort) { 358 fSort= sort; 359 } 360 361 366 public final void setVisibility(final int visibility) { 367 fVisibility= visibility; 368 } 369 } 370 | Popular Tags |