1 11 package org.eclipse.jdt.internal.corext.refactoring.structure; 12 13 import java.util.ArrayList ; 14 import java.util.Iterator ; 15 import java.util.List ; 16 import java.util.ListIterator ; 17 18 import org.eclipse.core.runtime.Assert; 19 import org.eclipse.core.runtime.CoreException; 20 21 import org.eclipse.ltk.core.refactoring.RefactoringStatus; 22 23 import org.eclipse.jdt.core.Flags; 24 import org.eclipse.jdt.core.ICompilationUnit; 25 import org.eclipse.jdt.core.IJavaProject; 26 import org.eclipse.jdt.core.NamingConventions; 27 import org.eclipse.jdt.core.dom.AST; 28 import org.eclipse.jdt.core.dom.ASTNode; 29 import org.eclipse.jdt.core.dom.Assignment; 30 import org.eclipse.jdt.core.dom.Block; 31 import org.eclipse.jdt.core.dom.Expression; 32 import org.eclipse.jdt.core.dom.ExpressionStatement; 33 import org.eclipse.jdt.core.dom.FieldAccess; 34 import org.eclipse.jdt.core.dom.FieldDeclaration; 35 import org.eclipse.jdt.core.dom.ITypeBinding; 36 import org.eclipse.jdt.core.dom.IVariableBinding; 37 import org.eclipse.jdt.core.dom.Javadoc; 38 import org.eclipse.jdt.core.dom.MethodDeclaration; 39 import org.eclipse.jdt.core.dom.MethodInvocation; 40 import org.eclipse.jdt.core.dom.Modifier; 41 import org.eclipse.jdt.core.dom.SimpleName; 42 import org.eclipse.jdt.core.dom.SingleVariableDeclaration; 43 import org.eclipse.jdt.core.dom.Type; 44 import org.eclipse.jdt.core.dom.TypeDeclaration; 45 import org.eclipse.jdt.core.dom.VariableDeclarationExpression; 46 import org.eclipse.jdt.core.dom.VariableDeclarationFragment; 47 import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword; 48 import org.eclipse.jdt.core.dom.rewrite.ImportRewrite; 49 50 import org.eclipse.jdt.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext; 51 import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility; 52 import org.eclipse.jdt.internal.corext.refactoring.Checks; 53 import org.eclipse.jdt.internal.corext.refactoring.ParameterInfo; 54 import org.eclipse.jdt.internal.corext.util.JavaModelUtil; 55 56 import org.eclipse.jdt.ui.CodeGeneration; 57 58 public class ParameterObjectFactory { 59 60 private String fClassName; 61 private ICompilationUnit fCompilationUnit; 62 private boolean fCreateComments; private boolean fCreateGetter; 64 private boolean fCreateSetter; 65 private String fEnclosingType; 66 private String fPackage; 67 private List fVariables; 68 69 public ParameterObjectFactory(ICompilationUnit cu) { 70 super(); 71 this.fCompilationUnit= cu; 72 this.fCreateComments= StubUtility.doAddComments(cu.getJavaProject()); 73 } 74 75 public RefactoringStatus checkConditions() { 76 RefactoringStatus result= new RefactoringStatus(); 77 result.merge(Checks.checkTypeName(fClassName)); 78 return result; 80 } 81 82 public TypeDeclaration createClassDeclaration(ICompilationUnit unit, String declaringType, CompilationUnitRewrite cuRewrite) throws CoreException { 83 AST ast= cuRewrite.getAST(); 84 TypeDeclaration typeDeclaration= ast.newTypeDeclaration(); 85 typeDeclaration.setName(ast.newSimpleName(fClassName)); 86 List body= typeDeclaration.bodyDeclarations(); 87 for (Iterator iter= fVariables.iterator(); iter.hasNext();) { 88 ParameterInfo pi= (ParameterInfo) iter.next(); 89 if (isValidField(pi)) { 90 FieldDeclaration declaration= createField(pi, unit, cuRewrite); 91 body.add(declaration); 92 } 93 } 94 MethodDeclaration constructor= createConstructor(unit, declaringType, cuRewrite); 95 body.add(constructor); 96 for (Iterator iter= fVariables.iterator(); iter.hasNext();) { 97 ParameterInfo pi= (ParameterInfo) iter.next(); 98 if (fCreateGetter && isValidField(pi)) { 99 ASTNode getter= createGetter(pi, declaringType, unit, cuRewrite); 100 body.add(getter); 101 } 102 if (fCreateSetter && isValidField(pi)) { 103 if (!Modifier.isFinal(pi.getOldBinding().getModifiers())) { 104 ASTNode setter= createSetter(pi, declaringType, unit, cuRewrite); 105 body.add(setter); 106 } 107 } 108 } 109 110 return typeDeclaration; 111 } 112 113 private MethodDeclaration createConstructor(ICompilationUnit unit, String declaringTypeName, CompilationUnitRewrite cuRewrite) throws CoreException { 114 AST ast= cuRewrite.getAST(); 115 MethodDeclaration methodDeclaration= ast.newMethodDeclaration(); 116 methodDeclaration.setName(ast.newSimpleName(fClassName)); 117 methodDeclaration.setConstructor(true); 118 methodDeclaration.modifiers().add(ast.newModifier(ModifierKeyword.PUBLIC_KEYWORD)); 119 String lineDelimiter= StubUtility.getLineDelimiterUsed(unit); 120 if (fCreateComments) { 121 String comment= CodeGeneration.getMethodComment(unit, declaringTypeName, methodDeclaration, null, lineDelimiter); 122 if (comment != null) { 123 Javadoc doc= (Javadoc) cuRewrite.getASTRewrite().createStringPlaceholder(comment, ASTNode.JAVADOC); 124 methodDeclaration.setJavadoc(doc); 125 } 126 } 127 List parameters= methodDeclaration.parameters(); 128 Block block= ast.newBlock(); 129 methodDeclaration.setBody(block); 130 List statements= block.statements(); 131 List validParameter= new ArrayList (); 132 for (Iterator iter= fVariables.iterator(); iter.hasNext();) { 133 ParameterInfo pi= (ParameterInfo) iter.next(); 134 if (isValidField(pi)) { 135 validParameter.add(pi); 136 } 137 } 138 139 IJavaProject project= fCompilationUnit.getJavaProject(); 140 141 for (Iterator iter= validParameter.iterator(); iter.hasNext();) { 142 ParameterInfo pi= (ParameterInfo) iter.next(); 143 SingleVariableDeclaration svd= ast.newSingleVariableDeclaration(); 144 ITypeBinding typeBinding= pi.getNewTypeBinding(); 145 if (!iter.hasNext() && typeBinding.isArray() && pi.isOldVarargs()) { 146 int dimensions= typeBinding.getDimensions(); 147 if (dimensions == 1) { 148 typeBinding= typeBinding.getComponentType(); 149 } else { 150 typeBinding= typeBinding.createArrayType(dimensions - 1); 151 } 152 svd.setVarargs(true); 153 } 154 155 String paramName= getParameterName(pi); 156 157 Type fieldType= importBinding(typeBinding, cuRewrite); 158 svd.setType(fieldType); 159 svd.setName(ast.newSimpleName(paramName)); 160 parameters.add(svd); 161 Expression leftHandSide; 162 if (paramName.equals(pi.getNewName()) || StubUtility.useThisForFieldAccess(project)) { 163 FieldAccess fieldAccess= ast.newFieldAccess(); 164 fieldAccess.setName(ast.newSimpleName(pi.getNewName())); 165 fieldAccess.setExpression(ast.newThisExpression()); 166 leftHandSide= fieldAccess; 167 } else { 168 leftHandSide= ast.newSimpleName(pi.getNewName()); 169 } 170 Assignment assignment= ast.newAssignment(); 171 assignment.setLeftHandSide(leftHandSide); 172 assignment.setRightHandSide(ast.newSimpleName(paramName)); 173 statements.add(ast.newExpressionStatement(assignment)); 174 } 175 return methodDeclaration; 176 } 177 178 private String getParameterName(ParameterInfo pi) { 179 String fieldName = pi.getNewName(); 180 String strippedName= NamingConventions.removePrefixAndSuffixForFieldName(fCompilationUnit.getJavaProject(), fieldName, 0); 181 String [] suggestions= StubUtility.getVariableNameSuggestions(StubUtility.PARAMETER, fCompilationUnit.getJavaProject(), strippedName, 0, null, true); 182 return suggestions[0]; 183 } 184 185 186 private Type importBinding(ITypeBinding typeBinding, CompilationUnitRewrite cuRewrite) { 187 Type type= cuRewrite.getImportRewrite().addImport(typeBinding, cuRewrite.getAST()); 188 cuRewrite.getImportRemover().registerAddedImports(type); 189 return type; 190 } 191 192 private FieldDeclaration createField(ParameterInfo pi, ICompilationUnit unit, CompilationUnitRewrite cuRewrite) throws CoreException { 193 AST ast= cuRewrite.getAST(); 194 VariableDeclarationFragment fragment= ast.newVariableDeclarationFragment(); 195 String lineDelim= StubUtility.getLineDelimiterUsed(unit); 196 SimpleName fieldName= ast.newSimpleName(pi.getNewName()); 197 fragment.setName(fieldName); 198 FieldDeclaration declaration= ast.newFieldDeclaration(fragment); 199 if (fCreateComments) { 200 String comment= StubUtility.getFieldComment(unit, pi.getNewTypeName(), pi.getNewName(), lineDelim); 201 if (comment != null) { 202 Javadoc doc= (Javadoc) cuRewrite.getASTRewrite().createStringPlaceholder(comment, ASTNode.JAVADOC); 203 declaration.setJavadoc(doc); 204 } 205 } 206 int visibility= Modifier.PUBLIC; 207 if (fCreateGetter) { 208 visibility= Modifier.PRIVATE; 209 } 210 List modifiers= ast.newModifiers(visibility); 211 declaration.modifiers().addAll(modifiers); 212 declaration.setType(importBinding(pi.getNewTypeBinding(), cuRewrite)); 213 return declaration; 214 } 215 216 public Expression createFieldReadAccess(ParameterInfo pi, String paramName, AST ast) { 217 if (!fCreateGetter) { 218 return ast.newName(new String [] { paramName, pi.getNewName() }); 219 } else { 220 MethodInvocation method= ast.newMethodInvocation(); 221 method.setName(ast.newSimpleName(getGetterName(pi, ast))); 222 method.setExpression(ast.newSimpleName(paramName)); 223 return method; 224 } 225 } 226 227 private ASTNode createGetter(ParameterInfo pi, String declaringType, ICompilationUnit cu, CompilationUnitRewrite cuRewrite) throws CoreException { 228 AST ast= cuRewrite.getAST(); 229 MethodDeclaration methodDeclaration= ast.newMethodDeclaration(); 230 String fieldName= pi.getNewName(); 231 String getterName= getGetterName(pi, ast); 232 String lineDelim= StubUtility.getLineDelimiterUsed(cu); 233 String bareFieldname= NamingConventions.removePrefixAndSuffixForFieldName(cu.getJavaProject(), fieldName, Flags.AccPrivate); 234 if (fCreateComments) { 235 String comment= CodeGeneration.getGetterComment(cu, declaringType, getterName, fieldName, pi.getNewTypeName(), bareFieldname, lineDelim); 236 if (comment != null) 237 methodDeclaration.setJavadoc((Javadoc) cuRewrite.getASTRewrite().createStringPlaceholder(comment, ASTNode.JAVADOC)); 238 } 239 methodDeclaration.setName(ast.newSimpleName(getterName)); 240 methodDeclaration.setReturnType2(importBinding(pi.getNewTypeBinding(), cuRewrite)); 241 methodDeclaration.modifiers().add(ast.newModifier(ModifierKeyword.PUBLIC_KEYWORD)); 242 Block block= ast.newBlock(); 243 methodDeclaration.setBody(block); 244 boolean useThis= StubUtility.useThisForFieldAccess(cu.getJavaProject()); 245 if (useThis) { 246 fieldName= "this." + fieldName; } 248 String bodyContent= CodeGeneration.getGetterMethodBodyContent(cu, declaringType, getterName, fieldName, lineDelim); 249 ASTNode getterBody= cuRewrite.getASTRewrite().createStringPlaceholder(bodyContent, ASTNode.EXPRESSION_STATEMENT); 250 block.statements().add(getterBody); 251 return methodDeclaration; 252 } 253 254 public ExpressionStatement createInitializer(ParameterInfo pi, String paramName, CompilationUnitRewrite cuRewrite) { 255 AST ast= cuRewrite.getAST(); 256 VariableDeclarationFragment fragment= ast.newVariableDeclarationFragment(); 257 fragment.setName(ast.newSimpleName(pi.getOldName())); 258 fragment.setInitializer(createFieldReadAccess(pi, paramName, ast)); 259 VariableDeclarationExpression declaration= ast.newVariableDeclarationExpression(fragment); 260 IVariableBinding variable= pi.getOldBinding(); 261 declaration.setType(importBinding(pi.getNewTypeBinding(), cuRewrite)); 262 int modifiers= variable.getModifiers(); 263 List newModifiers= ast.newModifiers(modifiers); 264 declaration.modifiers().addAll(newModifiers); 265 return ast.newExpressionStatement(declaration); 266 } 267 268 private ASTNode createSetter(ParameterInfo pi, String declaringType, ICompilationUnit cu, CompilationUnitRewrite cuRewrite) throws CoreException { 269 AST ast= cuRewrite.getAST(); 270 MethodDeclaration methodDeclaration= ast.newMethodDeclaration(); 271 String fieldName= pi.getNewName(); 272 String setterName= getSetterName(pi, ast); 273 String lineDelim= StubUtility.getLineDelimiterUsed(cu); 274 String bareFieldname= NamingConventions.removePrefixAndSuffixForFieldName(cu.getJavaProject(), fieldName, Flags.AccPrivate); 275 String paramName= StubUtility.suggestArgumentName(cu.getJavaProject(), bareFieldname, null); 276 if (fCreateComments) { 277 String comment= CodeGeneration.getSetterComment(cu, declaringType, setterName, fieldName, pi.getNewTypeName(), paramName, bareFieldname, lineDelim); 278 if (comment != null) 279 methodDeclaration.setJavadoc((Javadoc) cuRewrite.getASTRewrite().createStringPlaceholder(comment, ASTNode.JAVADOC)); 280 } 281 methodDeclaration.setName(ast.newSimpleName(setterName)); 282 methodDeclaration.modifiers().add(ast.newModifier(ModifierKeyword.PUBLIC_KEYWORD)); 283 SingleVariableDeclaration variable= ast.newSingleVariableDeclaration(); 284 variable.setType(importBinding(pi.getNewTypeBinding(), cuRewrite)); 285 variable.setName(ast.newSimpleName(paramName)); 286 methodDeclaration.parameters().add(variable); 287 Block block= ast.newBlock(); 288 methodDeclaration.setBody(block); 289 boolean useThis= StubUtility.useThisForFieldAccess(cu.getJavaProject()); 290 if (useThis || fieldName.equals(paramName)) { 291 fieldName= "this." + fieldName; } 293 String bodyContent= CodeGeneration.getSetterMethodBodyContent(fCompilationUnit, declaringType, setterName, fieldName, paramName, lineDelim); 294 ASTNode setterBody= cuRewrite.getASTRewrite().createStringPlaceholder(bodyContent, ASTNode.EXPRESSION_STATEMENT); 295 block.statements().add(setterBody); 296 return methodDeclaration; 297 } 298 299 public Type createType(final boolean asTopLevelClass, final CompilationUnitRewrite cuRewrite, final int position) { 300 String concatenateName= null; 301 if (asTopLevelClass) { 302 concatenateName= JavaModelUtil.concatenateName(fPackage, fClassName); 303 } else { 304 concatenateName= JavaModelUtil.concatenateName(fEnclosingType, fClassName); 305 } 306 ImportRewrite importRewrite= cuRewrite.getImportRewrite(); 307 ContextSensitiveImportRewriteContext context= new ContextSensitiveImportRewriteContext(cuRewrite.getRoot(), position, importRewrite); 308 String addedImport= importRewrite.addImport(concatenateName, context); 309 cuRewrite.getImportRemover().registerAddedImport(addedImport); 310 AST ast= cuRewrite.getAST(); 311 return ast.newSimpleType(ast.newName(addedImport)); 312 } 313 314 public String getClassName() { 315 return fClassName; 316 } 317 318 public String getEnclosingType() { 319 return fEnclosingType; 320 } 321 322 private String getGetterName(ParameterInfo pi, AST ast) { 323 return suggestGetterName(pi, ast); 324 } 325 326 public String getPackage() { 327 return fPackage; 328 } 329 330 public ParameterInfo getParameterInfo(String identifier) { 331 for (Iterator iter= fVariables.iterator(); iter.hasNext();) { 332 ParameterInfo pi= (ParameterInfo) iter.next(); 333 if (pi.getOldName().equals(identifier)) 334 return pi; 335 } 336 return null; 337 } 338 339 private String getSetterName(ParameterInfo pi, AST ast) { 340 return suggestSetterName(pi, ast); 341 } 342 343 public boolean isCreateComments() { 344 return fCreateComments; 345 } 346 347 public boolean isCreateGetter() { 348 return fCreateGetter; 349 } 350 351 public boolean isCreateSetter() { 352 return fCreateSetter; 353 } 354 355 private boolean isValidField(ParameterInfo pi) { 356 return pi.isCreateField() && !pi.isAdded(); 357 } 358 359 public void moveDown(ParameterInfo selected) { 360 int idx= fVariables.indexOf(selected); 361 Assert.isTrue(idx >= 0 && idx < fVariables.size() - 1); 362 int nextIdx= idx + 1; 363 ParameterInfo next= (ParameterInfo) fVariables.get(nextIdx); 364 if (next.isAdded()) { 365 nextIdx++; 366 Assert.isTrue(nextIdx <= fVariables.size() - 1); 367 next= (ParameterInfo) fVariables.get(nextIdx); 368 } 369 fVariables.set(idx, next); 370 fVariables.set(nextIdx, selected); 371 } 372 373 public void moveUp(ParameterInfo selected) { 374 int idx= fVariables.indexOf(selected); 375 Assert.isTrue(idx > 0); 376 int prevIdx= idx - 1; 377 ParameterInfo prev= (ParameterInfo) fVariables.get(prevIdx); 378 if (prev.isAdded()) { 379 prevIdx--; 380 Assert.isTrue(prevIdx >= 0); 381 prev= (ParameterInfo) fVariables.get(prevIdx); 382 } 383 fVariables.set(idx, prev); 384 fVariables.set(prevIdx, selected); 385 } 386 387 public void setClassName(String className) { 388 this.fClassName= className; 389 } 390 391 public void setCreateComments(boolean selection) { 392 fCreateComments= selection; 393 } 394 395 public void setCreateGetter(boolean createGetter) { 396 this.fCreateGetter= createGetter; 397 } 398 399 public void setCreateSetter(boolean createSetter) { 400 this.fCreateSetter= createSetter; 401 } 402 403 public void setEnclosingType(String enclosingType) { 404 fEnclosingType= enclosingType; 405 } 406 407 public void setPackage(String typeQualifier) { 408 this.fPackage= typeQualifier; 409 } 410 411 public void setVariables(List parameters) { 412 fVariables= parameters; 413 } 414 415 private String suggestGetterName(ParameterInfo pi, AST ast) { 416 ITypeBinding type= pi.getNewTypeBinding(); 417 boolean isBoolean= ast.resolveWellKnownType("boolean").isEqualTo(type) || ast.resolveWellKnownType("java.lang.Boolean").isEqualTo(type); return NamingConventions.suggestGetterName(fCompilationUnit.getJavaProject(), pi.getNewName(), Flags.AccPublic, isBoolean, null); 419 } 420 421 private String suggestSetterName(ParameterInfo pi, AST ast) { 422 ITypeBinding type= pi.getNewTypeBinding(); 423 boolean isBoolean= ast.resolveWellKnownType("boolean").isEqualTo(type) || ast.resolveWellKnownType("java.lang.Boolean").isEqualTo(type); return NamingConventions.suggestSetterName(fCompilationUnit.getJavaProject(), pi.getNewName(), Flags.AccPublic, isBoolean, null); 425 } 426 427 433 public void updateParameterPosition(ParameterInfo parameterObjectReference) { 434 fVariables.remove(parameterObjectReference); 435 for (ListIterator iterator= fVariables.listIterator(); iterator.hasNext();) { 436 ParameterInfo pi= (ParameterInfo) iterator.next(); 437 if (isValidField(pi)) { 438 iterator.add(parameterObjectReference); 439 return; 440 } 441 } 442 } 443 444 } 445 | Popular Tags |