| /******************************************************************************* |
| * Copyright (c) 2007, 2011 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jdt.internal.corext.refactoring.structure; |
| |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.ListIterator; |
| |
| import org.eclipse.core.runtime.Assert; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Status; |
| |
| import org.eclipse.text.edits.TextEdit; |
| |
| import org.eclipse.jface.text.BadLocationException; |
| import org.eclipse.jface.text.Document; |
| |
| import org.eclipse.ltk.core.refactoring.resource.ResourceChange; |
| |
| import org.eclipse.jdt.core.Flags; |
| import org.eclipse.jdt.core.ICompilationUnit; |
| import org.eclipse.jdt.core.IJavaProject; |
| import org.eclipse.jdt.core.IPackageFragment; |
| import org.eclipse.jdt.core.IPackageFragmentRoot; |
| import org.eclipse.jdt.core.NamingConventions; |
| import org.eclipse.jdt.core.ToolFactory; |
| import org.eclipse.jdt.core.compiler.IScanner; |
| import org.eclipse.jdt.core.compiler.ITerminalSymbols; |
| import org.eclipse.jdt.core.compiler.InvalidInputException; |
| import org.eclipse.jdt.core.dom.AST; |
| import org.eclipse.jdt.core.dom.ASTNode; |
| import org.eclipse.jdt.core.dom.Assignment; |
| import org.eclipse.jdt.core.dom.Block; |
| import org.eclipse.jdt.core.dom.BodyDeclaration; |
| import org.eclipse.jdt.core.dom.CompilationUnit; |
| import org.eclipse.jdt.core.dom.Expression; |
| import org.eclipse.jdt.core.dom.ExpressionStatement; |
| import org.eclipse.jdt.core.dom.FieldAccess; |
| import org.eclipse.jdt.core.dom.FieldDeclaration; |
| import org.eclipse.jdt.core.dom.ITypeBinding; |
| import org.eclipse.jdt.core.dom.IVariableBinding; |
| import org.eclipse.jdt.core.dom.Javadoc; |
| import org.eclipse.jdt.core.dom.MethodDeclaration; |
| import org.eclipse.jdt.core.dom.MethodInvocation; |
| import org.eclipse.jdt.core.dom.Modifier; |
| import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword; |
| import org.eclipse.jdt.core.dom.Name; |
| import org.eclipse.jdt.core.dom.SimpleName; |
| import org.eclipse.jdt.core.dom.SingleVariableDeclaration; |
| import org.eclipse.jdt.core.dom.Statement; |
| import org.eclipse.jdt.core.dom.SuperFieldAccess; |
| import org.eclipse.jdt.core.dom.Type; |
| import org.eclipse.jdt.core.dom.TypeDeclaration; |
| import org.eclipse.jdt.core.dom.VariableDeclarationExpression; |
| import org.eclipse.jdt.core.dom.VariableDeclarationFragment; |
| import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; |
| import org.eclipse.jdt.core.dom.rewrite.ImportRewrite; |
| import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.ImportRewriteContext; |
| import org.eclipse.jdt.core.dom.rewrite.ListRewrite; |
| |
| import org.eclipse.jdt.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext; |
| import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility; |
| import org.eclipse.jdt.internal.corext.dom.ASTNodes; |
| import org.eclipse.jdt.internal.corext.dom.TokenScanner; |
| import org.eclipse.jdt.internal.corext.refactoring.ParameterInfo; |
| import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages; |
| import org.eclipse.jdt.internal.corext.refactoring.changes.CreateCompilationUnitChange; |
| import org.eclipse.jdt.internal.corext.refactoring.changes.CreatePackageChange; |
| import org.eclipse.jdt.internal.corext.refactoring.util.ResourceUtil; |
| import org.eclipse.jdt.internal.corext.util.JavaModelUtil; |
| |
| import org.eclipse.jdt.ui.CodeGeneration; |
| |
| import org.eclipse.jdt.internal.ui.JavaPlugin; |
| |
| public class ParameterObjectFactory { |
| |
| private String fClassName; |
| private boolean fCreateGetter; |
| private boolean fCreateSetter; |
| private String fEnclosingType; |
| private String fPackage; |
| private List<ParameterInfo> fVariables; |
| |
| public ParameterObjectFactory() { |
| super(); |
| } |
| |
| public static class CreationListener { |
| /** |
| * Notifies that a getter has been created |
| * @param cuRewrite the rewriter |
| * @param getter the new getter |
| * @param pi the parameter info |
| */ |
| public void getterCreated(CompilationUnitRewrite cuRewrite, MethodDeclaration getter, ParameterInfo pi){} |
| /** |
| * Notifies that a setter has been created |
| * @param cuRewrite the rewriter |
| * @param setter the new setter |
| * @param pi the parameter info |
| */ |
| public void setterCreated(CompilationUnitRewrite cuRewrite, MethodDeclaration setter, ParameterInfo pi){} |
| /** |
| * Notifies that a field has been created |
| * @param cuRewrite the rewriter |
| * @param field the new field |
| * @param pi the parameter info |
| */ |
| public void fieldCreated(CompilationUnitRewrite cuRewrite, FieldDeclaration field, ParameterInfo pi){} |
| /** |
| * Notifies that a constructor has been created |
| * @param cuRewrite the rewriter |
| * @param constructor the new constructor |
| */ |
| public void constructorCreated(CompilationUnitRewrite cuRewrite, MethodDeclaration constructor){} |
| /** |
| * Notifies that a type declaration has been created |
| * @param cuRewrite the rewriter |
| * @param declaration the new declaration |
| */ |
| public void typeCreated(CompilationUnitRewrite cuRewrite, TypeDeclaration declaration) {} |
| |
| protected static ASTNode moveNode(CompilationUnitRewrite cuRewrite, ASTNode node) { |
| ASTRewrite rewrite= cuRewrite.getASTRewrite(); |
| if (rewrite.getAST() != node.getAST()) { |
| String str= ASTNodes.getNodeSource(node, true, true); |
| if (str != null) { |
| return rewrite.createStringPlaceholder(str, node.getNodeType()); |
| } |
| return ASTNode.copySubtree(rewrite.getAST(), node); |
| } |
| return rewrite.createMoveTarget(node); |
| } |
| /** |
| * Return whether the setter should be created for this field. This method is only called when |
| * the global createSetters is set and the parameterInfo is marked for field creation. |
| * @param pi the parameter info |
| * @return <code>true</code> if a setter should be created |
| */ |
| public boolean isCreateSetter(ParameterInfo pi) { |
| return !Modifier.isFinal(pi.getOldBinding().getModifiers()); |
| } |
| /** |
| * Return whether the getter should be created for this field. This method is only called when |
| * the global createGetters is set and the parameterInfo is marked for field creation. |
| * @param pi the parameter info |
| * @return <code>true</code> if a getter should be created |
| */ |
| public boolean isCreateGetter(ParameterInfo pi) { |
| return true; |
| } |
| /** |
| * Return whether the field should appear in the constructor |
| * @param pi the parameter info |
| * @return <code>true</code> if the field should appear |
| */ |
| public boolean isUseInConstructor(ParameterInfo pi) { |
| return true; |
| } |
| } |
| |
| /** |
| * Creates a new TypeDeclaration for the parameterInfo objects. |
| * |
| * @param declaringType the fully qualified name of the type |
| * @param cuRewrite the {@link CompilationUnitRewrite} that will be used for creation |
| * @param listener the creation listener or null |
| * @return the new declaration |
| * @throws CoreException if creation failed |
| */ |
| public TypeDeclaration createClassDeclaration(String declaringType, CompilationUnitRewrite cuRewrite, CreationListener listener) throws CoreException { |
| AST ast= cuRewrite.getAST(); |
| if (listener == null) |
| listener= new CreationListener(); |
| TypeDeclaration typeDeclaration= ast.newTypeDeclaration(); |
| typeDeclaration.setName(ast.newSimpleName(fClassName)); |
| List<BodyDeclaration> body= typeDeclaration.bodyDeclarations(); |
| for (Iterator<ParameterInfo> iter= fVariables.iterator(); iter.hasNext();) { |
| ParameterInfo pi= iter.next(); |
| if (isValidField(pi)) { |
| FieldDeclaration declaration= createField(pi, cuRewrite); |
| listener.fieldCreated(cuRewrite, declaration, pi); |
| body.add(declaration); |
| } |
| } |
| MethodDeclaration constructor= createConstructor(declaringType, cuRewrite, listener); |
| listener.constructorCreated(cuRewrite, constructor); |
| body.add(constructor); |
| for (Iterator<ParameterInfo> iter= fVariables.iterator(); iter.hasNext();) { |
| ParameterInfo pi= iter.next(); |
| if (fCreateGetter && isValidField(pi) && listener.isCreateGetter(pi)) { |
| MethodDeclaration getter= createGetter(pi, declaringType, cuRewrite); |
| listener.getterCreated(cuRewrite, getter, pi); |
| body.add(getter); |
| } |
| if (fCreateSetter && isValidField(pi) && listener.isCreateSetter(pi)) { |
| MethodDeclaration setter= createSetter(pi, declaringType, cuRewrite); |
| listener.setterCreated(cuRewrite, setter, pi); |
| body.add(setter); |
| } |
| } |
| listener.typeCreated(cuRewrite, typeDeclaration); |
| return typeDeclaration; |
| } |
| |
| private MethodDeclaration createConstructor(String declaringTypeName, CompilationUnitRewrite cuRewrite, CreationListener listener) throws CoreException { |
| AST ast= cuRewrite.getAST(); |
| ICompilationUnit unit= cuRewrite.getCu(); |
| IJavaProject project= unit.getJavaProject(); |
| |
| MethodDeclaration methodDeclaration= ast.newMethodDeclaration(); |
| methodDeclaration.setName(ast.newSimpleName(fClassName)); |
| methodDeclaration.setConstructor(true); |
| methodDeclaration.modifiers().add(ast.newModifier(ModifierKeyword.PUBLIC_KEYWORD)); |
| String lineDelimiter= StubUtility.getLineDelimiterUsed(unit); |
| if (createComments(project)) { |
| String comment= CodeGeneration.getMethodComment(unit, declaringTypeName, methodDeclaration, null, lineDelimiter); |
| if (comment != null) { |
| Javadoc doc= (Javadoc) cuRewrite.getASTRewrite().createStringPlaceholder(comment, ASTNode.JAVADOC); |
| methodDeclaration.setJavadoc(doc); |
| } |
| } |
| List<SingleVariableDeclaration> parameters= methodDeclaration.parameters(); |
| Block block= ast.newBlock(); |
| methodDeclaration.setBody(block); |
| List<Statement> statements= block.statements(); |
| List<ParameterInfo> validParameter= new ArrayList<ParameterInfo>(); |
| for (Iterator<ParameterInfo> iter= fVariables.iterator(); iter.hasNext();) { |
| ParameterInfo pi= iter.next(); |
| if (isValidField(pi) && listener.isUseInConstructor(pi)) { |
| validParameter.add(pi); |
| } |
| } |
| |
| ArrayList<String> usedParameter= new ArrayList<String>(); |
| for (Iterator<ParameterInfo> iter= validParameter.iterator(); iter.hasNext();) { |
| ParameterInfo pi= iter.next(); |
| SingleVariableDeclaration svd= ast.newSingleVariableDeclaration(); |
| ITypeBinding typeBinding= pi.getNewTypeBinding(); |
| if (!iter.hasNext() && typeBinding.isArray() && pi.isOldVarargs()) { |
| int dimensions= typeBinding.getDimensions(); |
| if (dimensions == 1) { |
| typeBinding= typeBinding.getComponentType(); |
| } else { |
| typeBinding= typeBinding.createArrayType(dimensions - 1); |
| } |
| svd.setVarargs(true); |
| } |
| |
| String paramName= getParameterName(pi, project, usedParameter); |
| usedParameter.add(paramName); |
| |
| Type fieldType= importBinding(typeBinding, cuRewrite); |
| svd.setType(fieldType); |
| svd.setName(ast.newSimpleName(paramName)); |
| parameters.add(svd); |
| Expression leftHandSide; |
| if (paramName.equals(pi.getNewName()) || StubUtility.useThisForFieldAccess(project)) { |
| FieldAccess fieldAccess= ast.newFieldAccess(); |
| fieldAccess.setName(ast.newSimpleName(pi.getNewName())); |
| fieldAccess.setExpression(ast.newThisExpression()); |
| leftHandSide= fieldAccess; |
| } else { |
| leftHandSide= ast.newSimpleName(pi.getNewName()); |
| } |
| Assignment assignment= ast.newAssignment(); |
| assignment.setLeftHandSide(leftHandSide); |
| assignment.setRightHandSide(ast.newSimpleName(paramName)); |
| statements.add(ast.newExpressionStatement(assignment)); |
| } |
| return methodDeclaration; |
| } |
| |
| private String getParameterName(ParameterInfo pi, IJavaProject project, ArrayList<String> usedParameter) { |
| String fieldName= pi.getNewName(); |
| String strippedName= NamingConventions.getBaseName(NamingConventions.VK_INSTANCE_FIELD, fieldName, project); |
| String[] suggestions= StubUtility.getVariableNameSuggestions(NamingConventions.VK_PARAMETER, project, strippedName, 0, usedParameter, true); |
| return suggestions[0]; |
| } |
| |
| |
| public static Type importBinding(ITypeBinding typeBinding, CompilationUnitRewrite cuRewrite) { |
| int declaredModifiers= typeBinding.getDeclaredModifiers(); |
| AST ast= cuRewrite.getAST(); |
| if (Modifier.isPrivate(declaredModifiers) || Modifier.isProtected(declaredModifiers)) { |
| return ast.newSimpleType(ast.newSimpleName(typeBinding.getName())); |
| } |
| Type type= cuRewrite.getImportRewrite().addImport(typeBinding, cuRewrite.getAST()); |
| cuRewrite.getImportRemover().registerAddedImports(type); |
| return type; |
| } |
| |
| private FieldDeclaration createField(ParameterInfo pi, CompilationUnitRewrite cuRewrite) throws CoreException { |
| AST ast= cuRewrite.getAST(); |
| ICompilationUnit unit= cuRewrite.getCu(); |
| |
| VariableDeclarationFragment fragment= ast.newVariableDeclarationFragment(); |
| String lineDelim= StubUtility.getLineDelimiterUsed(unit); |
| SimpleName fieldName= ast.newSimpleName(pi.getNewName()); |
| fragment.setName(fieldName); |
| FieldDeclaration declaration= ast.newFieldDeclaration(fragment); |
| if (createComments(unit.getJavaProject())) { |
| String comment= StubUtility.getFieldComment(unit, pi.getNewTypeName(), pi.getNewName(), lineDelim); |
| if (comment != null) { |
| Javadoc doc= (Javadoc) cuRewrite.getASTRewrite().createStringPlaceholder(comment, ASTNode.JAVADOC); |
| declaration.setJavadoc(doc); |
| } |
| } |
| List<Modifier> modifiers= new ArrayList<Modifier>(); |
| if (fCreateGetter) { |
| modifiers.add(ast.newModifier(ModifierKeyword.PRIVATE_KEYWORD)); |
| } else { |
| modifiers.add(ast.newModifier(ModifierKeyword.PUBLIC_KEYWORD)); |
| } |
| declaration.modifiers().addAll(modifiers); |
| declaration.setType(importBinding(pi.getNewTypeBinding(), cuRewrite)); |
| return declaration; |
| } |
| |
| public Expression createFieldReadAccess(ParameterInfo pi, String paramName, AST ast, IJavaProject project, boolean useSuper, Expression qualifier) { |
| Expression completeQualifier= generateQualifier(paramName, ast, useSuper, qualifier); |
| if (fCreateGetter) { |
| MethodInvocation mi= ast.newMethodInvocation(); |
| mi.setName(ast.newSimpleName(getGetterName(pi, ast, project))); |
| mi.setExpression(completeQualifier); |
| return mi; |
| } |
| return createFieldAccess(pi, ast, completeQualifier); |
| } |
| |
| public Expression createFieldWriteAccess(ParameterInfo pi, String paramName, AST ast, IJavaProject project, Expression assignedValue, boolean useSuper, Expression qualifier) { |
| Expression completeQualifier= generateQualifier(paramName, ast, useSuper, qualifier); |
| if (fCreateSetter) { |
| MethodInvocation mi= ast.newMethodInvocation(); |
| mi.setName(ast.newSimpleName(getSetterName(pi, ast, project))); |
| mi.setExpression(completeQualifier); |
| mi.arguments().add(assignedValue); |
| return mi; |
| } |
| return createFieldAccess(pi, ast, completeQualifier); |
| } |
| |
| private Expression generateQualifier(String paramName, AST ast, boolean useSuper, Expression qualifier) { |
| SimpleName paramSimpleName= ast.newSimpleName(paramName); |
| if (useSuper) { |
| SuperFieldAccess sf= ast.newSuperFieldAccess(); |
| sf.setName(paramSimpleName); |
| if (qualifier instanceof Name) { |
| sf.setQualifier((Name) qualifier); |
| } |
| return sf; |
| } |
| if (qualifier != null) { |
| FieldAccess parameterAccess= ast.newFieldAccess(); |
| parameterAccess.setExpression(qualifier); |
| parameterAccess.setName(paramSimpleName); |
| return parameterAccess; |
| } |
| return paramSimpleName; |
| } |
| |
| |
| |
| private Expression createFieldAccess(ParameterInfo pi, AST ast, Expression qualifier) { |
| if (qualifier instanceof Name) { |
| Name name= (Name) qualifier; //create FQN for IPOR |
| return ast.newName(JavaModelUtil.concatenateName(name.getFullyQualifiedName(), pi.getNewName())); |
| } |
| FieldAccess fa= ast.newFieldAccess(); |
| fa.setName(ast.newSimpleName(pi.getNewName())); |
| fa.setExpression(qualifier); |
| return fa; |
| } |
| |
| private MethodDeclaration createGetter(ParameterInfo pi, String declaringType, CompilationUnitRewrite cuRewrite) throws CoreException { |
| AST ast= cuRewrite.getAST(); |
| ICompilationUnit cu= cuRewrite.getCu(); |
| IJavaProject project= cu.getJavaProject(); |
| |
| MethodDeclaration methodDeclaration= ast.newMethodDeclaration(); |
| String fieldName= pi.getNewName(); |
| String getterName= getGetterName(pi, ast, project); |
| String lineDelim= StubUtility.getLineDelimiterUsed(cu); |
| String bareFieldname= NamingConventions.getBaseName(NamingConventions.VK_INSTANCE_FIELD, fieldName, project); |
| if (createComments(project)) { |
| String comment= CodeGeneration.getGetterComment(cu, declaringType, getterName, fieldName, pi.getNewTypeName(), bareFieldname, lineDelim); |
| if (comment != null) |
| methodDeclaration.setJavadoc((Javadoc) cuRewrite.getASTRewrite().createStringPlaceholder(comment, ASTNode.JAVADOC)); |
| } |
| methodDeclaration.setName(ast.newSimpleName(getterName)); |
| methodDeclaration.setReturnType2(importBinding(pi.getNewTypeBinding(), cuRewrite)); |
| methodDeclaration.modifiers().add(ast.newModifier(ModifierKeyword.PUBLIC_KEYWORD)); |
| Block block= ast.newBlock(); |
| methodDeclaration.setBody(block); |
| boolean useThis= StubUtility.useThisForFieldAccess(project); |
| if (useThis) { |
| fieldName= "this." + fieldName; //$NON-NLS-1$ |
| } |
| String bodyContent= CodeGeneration.getGetterMethodBodyContent(cu, declaringType, getterName, fieldName, lineDelim); |
| ASTNode getterBody= cuRewrite.getASTRewrite().createStringPlaceholder(bodyContent, ASTNode.EXPRESSION_STATEMENT); |
| block.statements().add(getterBody); |
| return methodDeclaration; |
| } |
| |
| public ExpressionStatement createInitializer(ParameterInfo pi, String paramName, CompilationUnitRewrite cuRewrite) { |
| AST ast= cuRewrite.getAST(); |
| |
| VariableDeclarationFragment fragment= ast.newVariableDeclarationFragment(); |
| fragment.setName(ast.newSimpleName(pi.getOldName())); |
| fragment.setInitializer(createFieldReadAccess(pi, paramName, ast, cuRewrite.getCu().getJavaProject(), false, null)); |
| VariableDeclarationExpression declaration= ast.newVariableDeclarationExpression(fragment); |
| IVariableBinding variable= pi.getOldBinding(); |
| declaration.setType(importBinding(pi.getNewTypeBinding(), cuRewrite)); |
| int modifiers= variable.getModifiers(); |
| List<Modifier> newModifiers= ast.newModifiers(modifiers); |
| declaration.modifiers().addAll(newModifiers); |
| return ast.newExpressionStatement(declaration); |
| } |
| |
| private MethodDeclaration createSetter(ParameterInfo pi, String declaringType, CompilationUnitRewrite cuRewrite) throws CoreException { |
| AST ast= cuRewrite.getAST(); |
| ICompilationUnit cu= cuRewrite.getCu(); |
| IJavaProject project= cu.getJavaProject(); |
| |
| MethodDeclaration methodDeclaration= ast.newMethodDeclaration(); |
| String fieldName= pi.getNewName(); |
| String setterName= getSetterName(pi, ast, project); |
| String lineDelim= StubUtility.getLineDelimiterUsed(cu); |
| String bareFieldname= NamingConventions.getBaseName(NamingConventions.VK_INSTANCE_FIELD, fieldName, project); |
| String paramName= StubUtility.suggestArgumentName(project, bareFieldname, null); |
| if (createComments(project)) { |
| String comment= CodeGeneration.getSetterComment(cu, declaringType, setterName, fieldName, pi.getNewTypeName(), paramName, bareFieldname, lineDelim); |
| if (comment != null) |
| methodDeclaration.setJavadoc((Javadoc) cuRewrite.getASTRewrite().createStringPlaceholder(comment, ASTNode.JAVADOC)); |
| } |
| methodDeclaration.setName(ast.newSimpleName(setterName)); |
| methodDeclaration.modifiers().add(ast.newModifier(ModifierKeyword.PUBLIC_KEYWORD)); |
| SingleVariableDeclaration variable= ast.newSingleVariableDeclaration(); |
| variable.setType(importBinding(pi.getNewTypeBinding(), cuRewrite)); |
| variable.setName(ast.newSimpleName(paramName)); |
| methodDeclaration.parameters().add(variable); |
| Block block= ast.newBlock(); |
| methodDeclaration.setBody(block); |
| boolean useThis= StubUtility.useThisForFieldAccess(project); |
| if (useThis || fieldName.equals(paramName)) { |
| fieldName= "this." + fieldName; //$NON-NLS-1$ |
| } |
| String bodyContent= CodeGeneration.getSetterMethodBodyContent(cu, declaringType, setterName, fieldName, paramName, lineDelim); |
| ASTNode setterBody= cuRewrite.getASTRewrite().createStringPlaceholder(bodyContent, ASTNode.EXPRESSION_STATEMENT); |
| block.statements().add(setterBody); |
| return methodDeclaration; |
| } |
| |
| public Type createType(boolean asTopLevelClass, CompilationUnitRewrite cuRewrite, int position) { |
| String qualifier= asTopLevelClass ? fPackage : fEnclosingType; |
| String concatenateName= JavaModelUtil.concatenateName(qualifier, fClassName); |
| |
| ImportRewrite importRewrite= cuRewrite.getImportRewrite(); |
| ContextSensitiveImportRewriteContext context= createParameterClassAwareContext(asTopLevelClass, cuRewrite, position); |
| String addedImport= importRewrite.addImport(concatenateName, context); |
| cuRewrite.getImportRemover().registerAddedImport(addedImport); |
| AST ast= cuRewrite.getAST(); |
| return ast.newSimpleType(ast.newName(addedImport)); |
| } |
| |
| ContextSensitiveImportRewriteContext createParameterClassAwareContext(final boolean asTopLevelClass, final CompilationUnitRewrite cuRewrite, int position) { |
| ContextSensitiveImportRewriteContext context= new ContextSensitiveImportRewriteContext(cuRewrite.getRoot(), position, cuRewrite.getImportRewrite()) { |
| @Override |
| public int findInContext(String qualifier, String name, int kind) { |
| String parameterClassName= getClassName(); |
| if (kind == ImportRewriteContext.KIND_TYPE && parameterClassName.equals(name)) { |
| String parameterClassQualifier= asTopLevelClass ? getPackage() : getEnclosingType(); |
| if (super.findInContext(qualifier, "", kind) == ImportRewriteContext.RES_NAME_FOUND) { //$NON-NLS-1$ // TODO: should be "*", not " "! |
| if (parameterClassQualifier.equals(qualifier)) { |
| return ImportRewriteContext.RES_NAME_FOUND; |
| } else { |
| return ImportRewriteContext.RES_NAME_CONFLICT; |
| } |
| } |
| } |
| return super.findInContext(qualifier, name, kind); |
| } |
| }; |
| return context; |
| } |
| |
| public String getClassName() { |
| return fClassName; |
| } |
| |
| public String getEnclosingType() { |
| return fEnclosingType; |
| } |
| |
| private String getGetterName(ParameterInfo pi, AST ast, IJavaProject project) { |
| ITypeBinding type= pi.getNewTypeBinding(); |
| boolean isBoolean= ast.resolveWellKnownType("boolean").isEqualTo(type) || ast.resolveWellKnownType("java.lang.Boolean").isEqualTo(type); //$NON-NLS-1$//$NON-NLS-2$ |
| return NamingConventions.suggestGetterName(project, pi.getNewName(), Flags.AccPublic, isBoolean, null); |
| } |
| |
| public String getPackage() { |
| return fPackage; |
| } |
| |
| public ParameterInfo getParameterInfo(String identifier) { |
| for (Iterator<ParameterInfo> iter= fVariables.iterator(); iter.hasNext();) { |
| ParameterInfo pi= iter.next(); |
| if (pi.getOldName().equals(identifier)) |
| return pi; |
| } |
| return null; |
| } |
| |
| private String getSetterName(ParameterInfo pi, AST ast, IJavaProject project) { |
| ITypeBinding type= pi.getNewTypeBinding(); |
| boolean isBoolean= ast.resolveWellKnownType("boolean").isEqualTo(type) || ast.resolveWellKnownType("java.lang.Boolean").isEqualTo(type); //$NON-NLS-1$//$NON-NLS-2$ |
| return NamingConventions.suggestSetterName(project, pi.getNewName(), Flags.AccPublic, isBoolean, null); |
| } |
| |
| public boolean isCreateGetter() { |
| return fCreateGetter; |
| } |
| |
| public boolean isCreateSetter() { |
| return fCreateSetter; |
| } |
| |
| private boolean isValidField(ParameterInfo pi) { |
| return pi.isCreateField() && !pi.isAdded(); |
| } |
| |
| public void moveDown(ParameterInfo selected) { |
| int idx= fVariables.indexOf(selected); |
| Assert.isTrue(idx >= 0 && idx < fVariables.size() - 1); |
| int nextIdx= idx + 1; |
| ParameterInfo next= fVariables.get(nextIdx); |
| if (next.isAdded()) { |
| nextIdx++; |
| Assert.isTrue(nextIdx <= fVariables.size() - 1); |
| next= fVariables.get(nextIdx); |
| } |
| fVariables.set(idx, next); |
| fVariables.set(nextIdx, selected); |
| } |
| |
| public void moveUp(ParameterInfo selected) { |
| int idx= fVariables.indexOf(selected); |
| Assert.isTrue(idx > 0); |
| int prevIdx= idx - 1; |
| ParameterInfo prev= fVariables.get(prevIdx); |
| if (prev.isAdded()) { |
| prevIdx--; |
| Assert.isTrue(prevIdx >= 0); |
| prev= fVariables.get(prevIdx); |
| } |
| fVariables.set(idx, prev); |
| fVariables.set(prevIdx, selected); |
| } |
| |
| public void setClassName(String className) { |
| fClassName= className; |
| } |
| |
| public void setCreateGetter(boolean createGetter) { |
| fCreateGetter= createGetter; |
| } |
| |
| public void setCreateSetter(boolean createSetter) { |
| fCreateSetter= createSetter; |
| } |
| |
| public void setEnclosingType(String enclosingType) { |
| fEnclosingType= enclosingType; |
| } |
| |
| public void setPackage(String typeQualifier) { |
| fPackage= typeQualifier; |
| } |
| |
| public void setVariables(List<ParameterInfo> parameters) { |
| fVariables= parameters; |
| } |
| |
| /** |
| * Updates the position of the newly inserted parameterObject so that it is |
| * directly after the first checked parameter |
| * |
| * @param parameterObjectReference the inserted parameterObject |
| */ |
| public void updateParameterPosition(ParameterInfo parameterObjectReference) { |
| fVariables.remove(parameterObjectReference); |
| for (ListIterator<ParameterInfo> iterator= fVariables.listIterator(); iterator.hasNext();) { |
| ParameterInfo pi= iterator.next(); |
| if (isValidField(pi)) { |
| iterator.add(parameterObjectReference); |
| return; |
| } |
| } |
| } |
| |
| private boolean createComments(IJavaProject project) { |
| return StubUtility.doAddComments(project); |
| } |
| |
| |
| public List<ResourceChange> createTopLevelParameterObject(IPackageFragmentRoot packageFragmentRoot, CreationListener listener) throws CoreException { |
| List<ResourceChange> changes= new ArrayList<ResourceChange>(); |
| IPackageFragment packageFragment= packageFragmentRoot.getPackageFragment(getPackage()); |
| if (!packageFragment.exists()) { |
| changes.add(new CreatePackageChange(packageFragment)); |
| } |
| ICompilationUnit unit= packageFragment.getCompilationUnit(getClassName() + JavaModelUtil.DEFAULT_CU_SUFFIX); |
| Assert.isTrue(!unit.exists()); |
| IJavaProject javaProject= unit.getJavaProject(); |
| ICompilationUnit workingCopy= unit.getWorkingCopy(null); |
| |
| try { |
| // create stub with comments and dummy type |
| String lineDelimiter= StubUtility.getLineDelimiterUsed(javaProject); |
| String fileComment= getFileComment(workingCopy, lineDelimiter); |
| String typeComment= getTypeComment(workingCopy, lineDelimiter); |
| String content= CodeGeneration.getCompilationUnitContent(workingCopy, fileComment, typeComment, "class " + getClassName() + "{}", lineDelimiter); //$NON-NLS-1$ //$NON-NLS-2$ |
| workingCopy.getBuffer().setContents(content); |
| |
| CompilationUnitRewrite cuRewrite= new CompilationUnitRewrite(workingCopy); |
| ASTRewrite rewriter= cuRewrite.getASTRewrite(); |
| CompilationUnit root= cuRewrite.getRoot(); |
| AST ast= cuRewrite.getAST(); |
| ImportRewrite importRewrite= cuRewrite.getImportRewrite(); |
| |
| // retrieve&replace dummy type with real class |
| ListRewrite types= rewriter.getListRewrite(root, CompilationUnit.TYPES_PROPERTY); |
| ASTNode dummyType= (ASTNode) types.getOriginalList().get(0); |
| String newTypeName= JavaModelUtil.concatenateName(getPackage(), getClassName()); |
| TypeDeclaration classDeclaration= createClassDeclaration(newTypeName, cuRewrite, listener); |
| classDeclaration.modifiers().add(ast.newModifier(ModifierKeyword.PUBLIC_KEYWORD)); |
| Javadoc javadoc= (Javadoc) dummyType.getStructuralProperty(TypeDeclaration.JAVADOC_PROPERTY); |
| rewriter.set(classDeclaration, TypeDeclaration.JAVADOC_PROPERTY, javadoc, null); |
| types.replace(dummyType, classDeclaration, null); |
| |
| // Apply rewrites and discard workingcopy |
| // Using CompilationUnitRewrite.createChange() leads to strange |
| // results |
| String charset= ResourceUtil.getFile(unit).getCharset(false); |
| Document document= new Document(content); |
| try { |
| rewriter.rewriteAST().apply(document); |
| TextEdit rewriteImports= importRewrite.rewriteImports(null); |
| rewriteImports.apply(document); |
| } catch (BadLocationException e) { |
| throw new CoreException(new Status(IStatus.ERROR, JavaPlugin.getPluginId(), RefactoringCoreMessages.IntroduceParameterObjectRefactoring_parameter_object_creation_error, e)); |
| } |
| String docContent= document.get(); |
| CreateCompilationUnitChange compilationUnitChange= new CreateCompilationUnitChange(unit, docContent, charset); |
| changes.add(compilationUnitChange); |
| } finally { |
| workingCopy.discardWorkingCopy(); |
| } |
| return changes; |
| } |
| |
| public List<ResourceChange> createTopLevelParameterObject(IPackageFragmentRoot packageFragmentRoot) throws CoreException { |
| return createTopLevelParameterObject(packageFragmentRoot, null); |
| } |
| |
| protected String getFileComment(ICompilationUnit parentCU, String lineDelimiter) throws CoreException { |
| if (StubUtility.doAddComments(parentCU.getJavaProject())) { |
| return CodeGeneration.getFileComment(parentCU, lineDelimiter); |
| } |
| return null; |
| |
| } |
| |
| protected String getTypeComment(ICompilationUnit parentCU, String lineDelimiter) throws CoreException { |
| if (StubUtility.doAddComments(parentCU.getJavaProject())) { |
| StringBuffer typeName= new StringBuffer(); |
| typeName.append(getClassName()); |
| String[] typeParamNames= new String[0]; |
| String comment= CodeGeneration.getTypeComment(parentCU, typeName.toString(), typeParamNames, lineDelimiter); |
| if (comment != null && isValidComment(comment)) { |
| return comment; |
| } |
| } |
| return null; |
| } |
| |
| private boolean isValidComment(String template) { |
| IScanner scanner= ToolFactory.createScanner(true, false, false, false); |
| scanner.setSource(template.toCharArray()); |
| try { |
| int next= scanner.getNextToken(); |
| while (TokenScanner.isComment(next)) { |
| next= scanner.getNextToken(); |
| } |
| return next == ITerminalSymbols.TokenNameEOF; |
| } catch (InvalidInputException e) { |
| } |
| return false; |
| } |
| |
| } |