Source Code Cross Referenced for ConvertAnonymousToNestedRefactoring.java in  » IDE-Eclipse » jdt » org » eclipse » jdt » internal » corext » refactoring » code » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Eclipse » jdt » org.eclipse.jdt.internal.corext.refactoring.code 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*******************************************************************************
0002:         * Copyright (c) 2000, 2007 IBM Corporation and others.
0003:         * All rights reserved. This program and the accompanying materials
0004:         * are made available under the terms of the Eclipse Public License v1.0
0005:         * which accompanies this distribution, and is available at
0006:         * http://www.eclipse.org/legal/epl-v10.html
0007:         *
0008:         * Contributors:
0009:         *     IBM Corporation - initial API and implementation
0010:         *     N.Metchev@teamphone.com - contributed fixes for
0011:         *     - convert anonymous to nested should sometimes declare class as static [refactoring] 
0012:         *       (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=43360)
0013:         *     - Convert anonymous to nested: should show error if field form outer anonymous type is references [refactoring]
0014:         *       (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=48282)
0015:         *******************************************************************************/package org.eclipse.jdt.internal.corext.refactoring.code;
0016:
0017:        import java.util.ArrayList;
0018:        import java.util.Arrays;
0019:        import java.util.Collections;
0020:        import java.util.HashMap;
0021:        import java.util.HashSet;
0022:        import java.util.Iterator;
0023:        import java.util.List;
0024:        import java.util.Map;
0025:        import java.util.Set;
0026:        import java.util.StringTokenizer;
0027:
0028:        import org.eclipse.core.runtime.Assert;
0029:        import org.eclipse.core.runtime.CoreException;
0030:        import org.eclipse.core.runtime.IProgressMonitor;
0031:
0032:        import org.eclipse.ltk.core.refactoring.Change;
0033:        import org.eclipse.ltk.core.refactoring.RefactoringChangeDescriptor;
0034:        import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
0035:        import org.eclipse.ltk.core.refactoring.RefactoringStatus;
0036:        import org.eclipse.ltk.core.refactoring.participants.RefactoringArguments;
0037:
0038:        import org.eclipse.jdt.core.ICompilationUnit;
0039:        import org.eclipse.jdt.core.IJavaElement;
0040:        import org.eclipse.jdt.core.IJavaProject;
0041:        import org.eclipse.jdt.core.JavaModelException;
0042:        import org.eclipse.jdt.core.dom.AST;
0043:        import org.eclipse.jdt.core.dom.ASTNode;
0044:        import org.eclipse.jdt.core.dom.ASTVisitor;
0045:        import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
0046:        import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
0047:        import org.eclipse.jdt.core.dom.ArrayCreation;
0048:        import org.eclipse.jdt.core.dom.ArrayInitializer;
0049:        import org.eclipse.jdt.core.dom.ArrayType;
0050:        import org.eclipse.jdt.core.dom.Assignment;
0051:        import org.eclipse.jdt.core.dom.BodyDeclaration;
0052:        import org.eclipse.jdt.core.dom.ClassInstanceCreation;
0053:        import org.eclipse.jdt.core.dom.CompilationUnit;
0054:        import org.eclipse.jdt.core.dom.Expression;
0055:        import org.eclipse.jdt.core.dom.FieldAccess;
0056:        import org.eclipse.jdt.core.dom.FieldDeclaration;
0057:        import org.eclipse.jdt.core.dom.IBinding;
0058:        import org.eclipse.jdt.core.dom.IMethodBinding;
0059:        import org.eclipse.jdt.core.dom.ITypeBinding;
0060:        import org.eclipse.jdt.core.dom.IVariableBinding;
0061:        import org.eclipse.jdt.core.dom.Initializer;
0062:        import org.eclipse.jdt.core.dom.Javadoc;
0063:        import org.eclipse.jdt.core.dom.MethodDeclaration;
0064:        import org.eclipse.jdt.core.dom.Modifier;
0065:        import org.eclipse.jdt.core.dom.Name;
0066:        import org.eclipse.jdt.core.dom.ParameterizedType;
0067:        import org.eclipse.jdt.core.dom.QualifiedName;
0068:        import org.eclipse.jdt.core.dom.SimpleName;
0069:        import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
0070:        import org.eclipse.jdt.core.dom.Statement;
0071:        import org.eclipse.jdt.core.dom.SuperConstructorInvocation;
0072:        import org.eclipse.jdt.core.dom.SuperFieldAccess;
0073:        import org.eclipse.jdt.core.dom.Type;
0074:        import org.eclipse.jdt.core.dom.TypeDeclaration;
0075:        import org.eclipse.jdt.core.dom.TypeParameter;
0076:        import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
0077:        import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
0078:        import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
0079:        import org.eclipse.jdt.core.refactoring.IJavaRefactorings;
0080:        import org.eclipse.jdt.core.refactoring.descriptors.ConvertAnonymousDescriptor;
0081:        import org.eclipse.jdt.core.refactoring.descriptors.JavaRefactoringDescriptor;
0082:
0083:        import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility;
0084:        import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory;
0085:        import org.eclipse.jdt.internal.corext.dom.ASTNodes;
0086:        import org.eclipse.jdt.internal.corext.dom.Bindings;
0087:        import org.eclipse.jdt.internal.corext.dom.LinkedNodeFinder;
0088:        import org.eclipse.jdt.internal.corext.dom.NodeFinder;
0089:        import org.eclipse.jdt.internal.corext.fix.LinkedProposalModel;
0090:        import org.eclipse.jdt.internal.corext.fix.LinkedProposalPositionGroup;
0091:        import org.eclipse.jdt.internal.corext.refactoring.Checks;
0092:        import org.eclipse.jdt.internal.corext.refactoring.JDTRefactoringDescriptorComment;
0093:        import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringArguments;
0094:        import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringDescriptorUtil;
0095:        import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
0096:        import org.eclipse.jdt.internal.corext.refactoring.changes.CompilationUnitChange;
0097:        import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite;
0098:        import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser;
0099:        import org.eclipse.jdt.internal.corext.refactoring.util.ResourceUtil;
0100:        import org.eclipse.jdt.internal.corext.util.JdtFlags;
0101:        import org.eclipse.jdt.internal.corext.util.Messages;
0102:
0103:        import org.eclipse.jdt.ui.CodeGeneration;
0104:        import org.eclipse.jdt.ui.JavaElementLabels;
0105:
0106:        import org.eclipse.jdt.internal.ui.text.correction.ModifierCorrectionSubProcessor;
0107:        import org.eclipse.jdt.internal.ui.viewsupport.BindingLabelProvider;
0108:
0109:        public class ConvertAnonymousToNestedRefactoring extends
0110:                ScriptableRefactoring {
0111:
0112:            private static final String ATTRIBUTE_VISIBILITY = "visibility"; //$NON-NLS-1$
0113:            private static final String ATTRIBUTE_FINAL = "final"; //$NON-NLS-1$
0114:            private static final String ATTRIBUTE_STATIC = "static"; //$NON-NLS-1$
0115:
0116:            private static final String KEY_TYPE_NAME = "type_name"; //$NON-NLS-1$
0117:            private static final String KEY_PARAM_NAME_EXT = "param_name_ext"; //$NON-NLS-1$
0118:            private static final String KEY_PARAM_NAME_CONST = "param_name_const"; //$NON-NLS-1$
0119:            private static final String KEY_FIELD_NAME_EXT = "field_name_ext"; //$NON-NLS-1$
0120:
0121:            public static class TypeVariableFinder extends ASTVisitor {
0122:
0123:                private final Map fBindings = new HashMap();
0124:                private final List fFound = new ArrayList();
0125:
0126:                public final boolean visit(final SimpleName node) {
0127:                    Assert.isNotNull(node);
0128:                    final ITypeBinding binding = node.resolveTypeBinding();
0129:                    if (binding != null && binding.isTypeVariable()
0130:                            && !fBindings.containsKey(binding.getKey())) {
0131:                        fBindings.put(binding.getKey(), binding);
0132:                        fFound.add(binding);
0133:                    }
0134:                    return true;
0135:                }
0136:
0137:                public final ITypeBinding[] getResult() {
0138:                    final ITypeBinding[] result = new ITypeBinding[fFound
0139:                            .size()];
0140:                    fFound.toArray(result);
0141:                    return result;
0142:                }
0143:            }
0144:
0145:            private int fSelectionStart;
0146:            private int fSelectionLength;
0147:            private ICompilationUnit fCu;
0148:
0149:            private int fVisibility; /* see Modifier */
0150:            private boolean fDeclareFinal = true;
0151:            private boolean fDeclareStatic;
0152:            private String fClassName = ""; //$NON-NLS-1$
0153:
0154:            private CompilationUnit fCompilationUnitNode;
0155:            private AnonymousClassDeclaration fAnonymousInnerClassNode;
0156:            private Set fClassNamesUsed;
0157:            private boolean fSelfInitializing = false;
0158:
0159:            private LinkedProposalModel fLinkedProposalModel;
0160:
0161:            /**
0162:             * Creates a new convert anonymous to nested refactoring
0163:             * @param unit the compilation unit, or <code>null</code> if invoked by scripting
0164:             * @param selectionStart
0165:             * @param selectionLength
0166:             */
0167:            public ConvertAnonymousToNestedRefactoring(ICompilationUnit unit,
0168:                    int selectionStart, int selectionLength) {
0169:                Assert.isTrue(selectionStart >= 0);
0170:                Assert.isTrue(selectionLength >= 0);
0171:                Assert.isTrue(unit == null || unit.exists());
0172:                fSelectionStart = selectionStart;
0173:                fSelectionLength = selectionLength;
0174:                fCu = unit;
0175:                fAnonymousInnerClassNode = null;
0176:                fCompilationUnitNode = null;
0177:            }
0178:
0179:            public ConvertAnonymousToNestedRefactoring(
0180:                    AnonymousClassDeclaration declaration) {
0181:                Assert.isTrue(declaration != null);
0182:
0183:                ASTNode astRoot = declaration.getRoot();
0184:                Assert.isTrue(astRoot instanceof  CompilationUnit);
0185:                fCompilationUnitNode = (CompilationUnit) astRoot;
0186:
0187:                IJavaElement javaElement = fCompilationUnitNode
0188:                        .getJavaElement();
0189:                Assert.isTrue(javaElement instanceof  ICompilationUnit);
0190:
0191:                fCu = (ICompilationUnit) javaElement;
0192:                fSelectionStart = declaration.getStartPosition();
0193:                fSelectionLength = declaration.getLength();
0194:            }
0195:
0196:            public void setLinkedProposalModel(
0197:                    LinkedProposalModel linkedProposalModel) {
0198:                fLinkedProposalModel = linkedProposalModel;
0199:            }
0200:
0201:            public int[] getAvailableVisibilities() {
0202:                if (isLocalInnerType()) {
0203:                    return new int[] { Modifier.NONE };
0204:                } else {
0205:                    return new int[] { Modifier.PUBLIC, Modifier.PROTECTED,
0206:                            Modifier.NONE, Modifier.PRIVATE };
0207:                }
0208:            }
0209:
0210:            public boolean isLocalInnerType() {
0211:                return ASTNodes.getParent(ASTNodes
0212:                        .getParent(fAnonymousInnerClassNode,
0213:                                AbstractTypeDeclaration.class),
0214:                        ASTNode.ANONYMOUS_CLASS_DECLARATION) != null;
0215:            }
0216:
0217:            public int getVisibility() {
0218:                return fVisibility;
0219:            }
0220:
0221:            public void setVisibility(int visibility) {
0222:                Assert.isTrue(visibility == Modifier.PRIVATE
0223:                        || visibility == Modifier.NONE
0224:                        || visibility == Modifier.PROTECTED
0225:                        || visibility == Modifier.PUBLIC);
0226:                fVisibility = visibility;
0227:            }
0228:
0229:            public void setClassName(String className) {
0230:                Assert.isNotNull(className);
0231:                fClassName = className;
0232:            }
0233:
0234:            public boolean canEnableSettingFinal() {
0235:                return true;
0236:            }
0237:
0238:            public boolean getDeclareFinal() {
0239:                return fDeclareFinal;
0240:            }
0241:
0242:            public boolean getDeclareStatic() {
0243:                return fDeclareStatic;
0244:            }
0245:
0246:            public void setDeclareFinal(boolean declareFinal) {
0247:                fDeclareFinal = declareFinal;
0248:            }
0249:
0250:            public void setDeclareStatic(boolean declareStatic) {
0251:                fDeclareStatic = declareStatic;
0252:            }
0253:
0254:            public String getName() {
0255:                return RefactoringCoreMessages.ConvertAnonymousToNestedRefactoring_name;
0256:            }
0257:
0258:            private boolean useThisForFieldAccess() {
0259:                return StubUtility.useThisForFieldAccess(fCu.getJavaProject());
0260:            }
0261:
0262:            private boolean doAddComments() {
0263:                return StubUtility.doAddComments(fCu.getJavaProject());
0264:            }
0265:
0266:            public RefactoringStatus checkInitialConditions(IProgressMonitor pm)
0267:                    throws CoreException {
0268:                RefactoringStatus result = Checks.validateModifiesFiles(
0269:                        ResourceUtil.getFiles(new ICompilationUnit[] { fCu }),
0270:                        getValidationContext());
0271:                if (result.hasFatalError())
0272:                    return result;
0273:
0274:                initAST(pm);
0275:
0276:                if (fAnonymousInnerClassNode == null)
0277:                    return RefactoringStatus
0278:                            .createFatalErrorStatus(RefactoringCoreMessages.ConvertAnonymousToNestedRefactoring_place_caret);
0279:                if (!fSelfInitializing)
0280:                    initializeDefaults();
0281:                if (getSuperConstructorBinding() == null)
0282:                    return RefactoringStatus
0283:                            .createFatalErrorStatus(RefactoringCoreMessages.ConvertAnonymousToNestedRefactoring_compile_errors);
0284:                if (getSuperTypeBinding().isLocal())
0285:                    return RefactoringStatus
0286:                            .createFatalErrorStatus(RefactoringCoreMessages.ConvertAnonymousToNestedRefactoring_extends_local_class);
0287:                return new RefactoringStatus();
0288:            }
0289:
0290:            private void initializeDefaults() {
0291:                fVisibility = isLocalInnerType() ? Modifier.NONE
0292:                        : Modifier.PRIVATE;
0293:                fDeclareStatic = mustInnerClassBeStatic();
0294:            }
0295:
0296:            private void initAST(IProgressMonitor pm) {
0297:                if (fCompilationUnitNode == null) {
0298:                    fCompilationUnitNode = RefactoringASTParser
0299:                            .parseWithASTProvider(fCu, true, pm);
0300:                }
0301:                if (fAnonymousInnerClassNode == null) {
0302:                    fAnonymousInnerClassNode = getAnonymousInnerClass(NodeFinder
0303:                            .perform(fCompilationUnitNode, fSelectionStart,
0304:                                    fSelectionLength));
0305:                }
0306:                if (fAnonymousInnerClassNode != null) {
0307:                    final AbstractTypeDeclaration declaration = (AbstractTypeDeclaration) ASTNodes
0308:                            .getParent(fAnonymousInnerClassNode,
0309:                                    AbstractTypeDeclaration.class);
0310:                    if (declaration instanceof  TypeDeclaration) {
0311:                        final AbstractTypeDeclaration[] nested = ((TypeDeclaration) declaration)
0312:                                .getTypes();
0313:                        fClassNamesUsed = new HashSet(nested.length);
0314:                        for (int index = 0; index < nested.length; index++)
0315:                            fClassNamesUsed.add(nested[index].getName()
0316:                                    .getIdentifier());
0317:                    } else
0318:                        fClassNamesUsed = Collections.EMPTY_SET;
0319:                }
0320:            }
0321:
0322:            private static AnonymousClassDeclaration getAnonymousInnerClass(
0323:                    ASTNode node) {
0324:                if (node == null)
0325:                    return null;
0326:                if (node instanceof  AnonymousClassDeclaration)
0327:                    return (AnonymousClassDeclaration) node;
0328:                if (node instanceof  ClassInstanceCreation) {
0329:                    AnonymousClassDeclaration anon = ((ClassInstanceCreation) node)
0330:                            .getAnonymousClassDeclaration();
0331:                    if (anon != null)
0332:                        return anon;
0333:                }
0334:                node = ASTNodes.getNormalizedNode(node);
0335:                if (node.getLocationInParent() == ClassInstanceCreation.TYPE_PROPERTY) {
0336:                    AnonymousClassDeclaration anon = ((ClassInstanceCreation) node
0337:                            .getParent()).getAnonymousClassDeclaration();
0338:                    if (anon != null)
0339:                        return anon;
0340:                }
0341:                return (AnonymousClassDeclaration) ASTNodes.getParent(node,
0342:                        AnonymousClassDeclaration.class);
0343:            }
0344:
0345:            public RefactoringStatus validateInput() {
0346:                RefactoringStatus result = Checks
0347:                        .checkTypeName(fClassName, fCu);
0348:                if (result.hasFatalError())
0349:                    return result;
0350:
0351:                if (fClassNamesUsed.contains(fClassName))
0352:                    return RefactoringStatus
0353:                            .createFatalErrorStatus(RefactoringCoreMessages.ConvertAnonymousToNestedRefactoring_type_exists);
0354:                IMethodBinding super ConstructorBinding = getSuperConstructorBinding();
0355:                if (super ConstructorBinding == null)
0356:                    return RefactoringStatus
0357:                            .createFatalErrorStatus(RefactoringCoreMessages.ConvertAnonymousToNestedRefactoring_compile_errors);
0358:                if (fClassName.equals(super ConstructorBinding
0359:                        .getDeclaringClass().getName()))
0360:                    return RefactoringStatus
0361:                            .createFatalErrorStatus(RefactoringCoreMessages.ConvertAnonymousToNestedRefactoring_another_name);
0362:                if (classNameHidesEnclosingType())
0363:                    return RefactoringStatus
0364:                            .createFatalErrorStatus(RefactoringCoreMessages.ConvertAnonymousToNestedRefactoring_name_hides);
0365:                return result;
0366:            }
0367:
0368:            private boolean accessesAnonymousFields() {
0369:                List anonymousInnerFieldTypes = getAllEnclosingAnonymousTypesField();
0370:                List accessedField = getAllAccessedFields();
0371:                final Iterator it = anonymousInnerFieldTypes.iterator();
0372:                while (it.hasNext()) {
0373:                    final IVariableBinding variableBinding = (IVariableBinding) it
0374:                            .next();
0375:                    final Iterator it2 = accessedField.iterator();
0376:                    while (it2.hasNext()) {
0377:                        IVariableBinding variableBinding2 = (IVariableBinding) it2
0378:                                .next();
0379:                        if (Bindings.equals(variableBinding, variableBinding2)) {
0380:                            return true;
0381:                        }
0382:                    }
0383:                }
0384:                return false;
0385:            }
0386:
0387:            private List getAllAccessedFields() {
0388:                final List accessedFields = new ArrayList();
0389:
0390:                ASTVisitor visitor = new ASTVisitor() {
0391:
0392:                    public boolean visit(FieldAccess node) {
0393:                        final IVariableBinding binding = node
0394:                                .resolveFieldBinding();
0395:                        if (binding != null && !binding.isEnumConstant())
0396:                            accessedFields.add(binding);
0397:                        return super .visit(node);
0398:                    }
0399:
0400:                    public boolean visit(QualifiedName node) {
0401:                        final IBinding binding = node.resolveBinding();
0402:                        if (binding != null
0403:                                && binding instanceof  IVariableBinding) {
0404:                            IVariableBinding variable = (IVariableBinding) binding;
0405:                            if (!variable.isEnumConstant()
0406:                                    && variable.isField())
0407:                                accessedFields.add(binding);
0408:                        }
0409:                        return super .visit(node);
0410:                    }
0411:
0412:                    public boolean visit(SimpleName node) {
0413:                        final IBinding binding = node.resolveBinding();
0414:                        if (binding != null
0415:                                && binding instanceof  IVariableBinding) {
0416:                            IVariableBinding variable = (IVariableBinding) binding;
0417:                            if (!variable.isEnumConstant()
0418:                                    && variable.isField())
0419:                                accessedFields.add(binding);
0420:                        }
0421:                        return super .visit(node);
0422:                    }
0423:
0424:                    public boolean visit(SuperFieldAccess node) {
0425:                        final IVariableBinding binding = node
0426:                                .resolveFieldBinding();
0427:                        if (binding != null && !binding.isEnumConstant())
0428:                            accessedFields.add(binding);
0429:                        return super .visit(node);
0430:                    }
0431:                };
0432:                fAnonymousInnerClassNode.accept(visitor);
0433:
0434:                return accessedFields;
0435:            }
0436:
0437:            private List getAllEnclosingAnonymousTypesField() {
0438:                final List ans = new ArrayList();
0439:                final AbstractTypeDeclaration declaration = (AbstractTypeDeclaration) ASTNodes
0440:                        .getParent(fAnonymousInnerClassNode,
0441:                                AbstractTypeDeclaration.class);
0442:                AnonymousClassDeclaration anonymous = (AnonymousClassDeclaration) ASTNodes
0443:                        .getParent(fAnonymousInnerClassNode,
0444:                                ASTNode.ANONYMOUS_CLASS_DECLARATION);
0445:                while (anonymous != null) {
0446:                    if (ASTNodes.isParent(anonymous, declaration)) {
0447:                        ITypeBinding binding = anonymous.resolveBinding();
0448:                        if (binding != null) {
0449:                            ans.addAll(Arrays.asList(binding
0450:                                    .getDeclaredFields()));
0451:                        }
0452:                    } else {
0453:                        break;
0454:                    }
0455:                    anonymous = (AnonymousClassDeclaration) ASTNodes.getParent(
0456:                            anonymous, ASTNode.ANONYMOUS_CLASS_DECLARATION);
0457:                }
0458:                return ans;
0459:            }
0460:
0461:            private boolean classNameHidesEnclosingType() {
0462:                ITypeBinding type = ((AbstractTypeDeclaration) ASTNodes
0463:                        .getParent(fAnonymousInnerClassNode,
0464:                                AbstractTypeDeclaration.class))
0465:                        .resolveBinding();
0466:                while (type != null) {
0467:                    if (fClassName.equals(type.getName()))
0468:                        return true;
0469:                    type = type.getDeclaringClass();
0470:                }
0471:                return false;
0472:            }
0473:
0474:            /*
0475:             * @see org.eclipse.jdt.internal.corext.refactoring.base.Refactoring#checkInput(org.eclipse.core.runtime.IProgressMonitor)
0476:             */
0477:            public RefactoringStatus checkFinalConditions(IProgressMonitor pm)
0478:                    throws CoreException {
0479:                try {
0480:                    RefactoringStatus status = validateInput();
0481:                    if (accessesAnonymousFields())
0482:                        status
0483:                                .merge(RefactoringStatus
0484:                                        .createErrorStatus(RefactoringCoreMessages.ConvertAnonymousToNestedRefactoring_anonymous_field_access));
0485:                    return status;
0486:                } finally {
0487:                    pm.done();
0488:                }
0489:            }
0490:
0491:            public CompilationUnitChange createCompilationUnitChange(
0492:                    IProgressMonitor pm) throws CoreException {
0493:                final CompilationUnitRewrite rewrite = new CompilationUnitRewrite(
0494:                        fCu, fCompilationUnitNode);
0495:                final ITypeBinding[] typeParameters = getTypeParameters();
0496:                addNestedClass(rewrite, typeParameters);
0497:                modifyConstructorCall(rewrite, typeParameters);
0498:                return rewrite
0499:                        .createChange(
0500:                                RefactoringCoreMessages.ConvertAnonymousToNestedRefactoring_name,
0501:                                false, pm);
0502:            }
0503:
0504:            /*
0505:             * @see org.eclipse.jdt.internal.corext.refactoring.base.IRefactoring#createChange(org.eclipse.core.runtime.IProgressMonitor)
0506:             */
0507:            public Change createChange(IProgressMonitor pm)
0508:                    throws CoreException {
0509:                final CompilationUnitChange result = createCompilationUnitChange(pm);
0510:                result.setDescriptor(createRefactoringDescriptor());
0511:                return result;
0512:            }
0513:
0514:            private ITypeBinding[] getTypeParameters() {
0515:                final List parameters = new ArrayList(4);
0516:                final ClassInstanceCreation creation = (ClassInstanceCreation) fAnonymousInnerClassNode
0517:                        .getParent();
0518:                if (fDeclareStatic) {
0519:                    final TypeVariableFinder finder = new TypeVariableFinder();
0520:                    creation.accept(finder);
0521:                    return finder.getResult();
0522:                } else {
0523:                    final MethodDeclaration declaration = getEnclosingMethodDeclaration(creation);
0524:                    if (declaration != null) {
0525:                        ITypeBinding binding = null;
0526:                        TypeParameter parameter = null;
0527:                        for (final Iterator iterator = declaration
0528:                                .typeParameters().iterator(); iterator
0529:                                .hasNext();) {
0530:                            parameter = (TypeParameter) iterator.next();
0531:                            binding = parameter.resolveBinding();
0532:                            if (binding != null)
0533:                                parameters.add(binding);
0534:                        }
0535:                    }
0536:                }
0537:                final TypeVariableFinder finder = new TypeVariableFinder();
0538:                creation.accept(finder);
0539:                final ITypeBinding[] variables = finder.getResult();
0540:                final List remove = new ArrayList(4);
0541:                boolean match = false;
0542:                ITypeBinding binding = null;
0543:                ITypeBinding variable = null;
0544:                for (final Iterator iterator = parameters.iterator(); iterator
0545:                        .hasNext();) {
0546:                    match = false;
0547:                    binding = (ITypeBinding) iterator.next();
0548:                    for (int index = 0; index < variables.length; index++) {
0549:                        variable = variables[index];
0550:                        if (variable.equals(binding))
0551:                            match = true;
0552:                    }
0553:                    if (!match)
0554:                        remove.add(binding);
0555:                }
0556:                parameters.removeAll(remove);
0557:                final ITypeBinding[] result = new ITypeBinding[parameters
0558:                        .size()];
0559:                parameters.toArray(result);
0560:                return result;
0561:            }
0562:
0563:            private MethodDeclaration getEnclosingMethodDeclaration(ASTNode node) {
0564:                ASTNode parent = node.getParent();
0565:                if (parent != null) {
0566:                    if (parent instanceof  AbstractTypeDeclaration)
0567:                        return null;
0568:                    else if (parent instanceof  MethodDeclaration)
0569:                        return (MethodDeclaration) parent;
0570:                    return getEnclosingMethodDeclaration(parent);
0571:                }
0572:                return null;
0573:            }
0574:
0575:            private RefactoringChangeDescriptor createRefactoringDescriptor() {
0576:                final ITypeBinding binding = fAnonymousInnerClassNode
0577:                        .resolveBinding();
0578:                final String[] labels = new String[] {
0579:                        BindingLabelProvider.getBindingLabel(binding,
0580:                                JavaElementLabels.ALL_FULLY_QUALIFIED),
0581:                        BindingLabelProvider.getBindingLabel(binding
0582:                                .getDeclaringMethod(),
0583:                                JavaElementLabels.ALL_FULLY_QUALIFIED) };
0584:                final Map arguments = new HashMap();
0585:                final String projectName = fCu.getJavaProject()
0586:                        .getElementName();
0587:                final int flags = RefactoringDescriptor.STRUCTURAL_CHANGE
0588:                        | JavaRefactoringDescriptor.JAR_REFACTORING
0589:                        | JavaRefactoringDescriptor.JAR_SOURCE_ATTACHMENT;
0590:                final String description = RefactoringCoreMessages.ConvertAnonymousToNestedRefactoring_descriptor_description_short;
0591:                final String header = Messages
0592:                        .format(
0593:                                RefactoringCoreMessages.ConvertAnonymousToNestedRefactoring_descriptor_description,
0594:                                labels);
0595:                final JDTRefactoringDescriptorComment comment = new JDTRefactoringDescriptorComment(
0596:                        projectName, this , header);
0597:                comment
0598:                        .addSetting(Messages
0599:                                .format(
0600:                                        RefactoringCoreMessages.ConvertAnonymousToNestedRefactoring_original_pattern,
0601:                                        BindingLabelProvider
0602:                                                .getBindingLabel(
0603:                                                        binding,
0604:                                                        JavaElementLabels.ALL_FULLY_QUALIFIED)));
0605:                comment
0606:                        .addSetting(Messages
0607:                                .format(
0608:                                        RefactoringCoreMessages.ConvertAnonymousToNestedRefactoring_class_name_pattern,
0609:                                        fClassName));
0610:                String visibility = JdtFlags.getVisibilityString(fVisibility);
0611:                if (visibility.length() == 0)
0612:                    visibility = RefactoringCoreMessages.ConvertAnonymousToNestedRefactoring_default_visibility;
0613:                comment
0614:                        .addSetting(Messages
0615:                                .format(
0616:                                        RefactoringCoreMessages.ConvertAnonymousToNestedRefactoring_visibility_pattern,
0617:                                        visibility));
0618:                if (fDeclareFinal && fDeclareStatic)
0619:                    comment
0620:                            .addSetting(RefactoringCoreMessages.ConvertAnonymousToNestedRefactoring_declare_final_static);
0621:                else if (fDeclareFinal)
0622:                    comment
0623:                            .addSetting(RefactoringCoreMessages.ConvertAnonymousToNestedRefactoring_declare_final);
0624:                else if (fDeclareStatic)
0625:                    comment
0626:                            .addSetting(RefactoringCoreMessages.ConvertAnonymousToNestedRefactoring_declare_static);
0627:                arguments.put(JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT,
0628:                        JavaRefactoringDescriptorUtil.elementToHandle(
0629:                                projectName, fCu));
0630:                arguments.put(JavaRefactoringDescriptorUtil.ATTRIBUTE_NAME,
0631:                        fClassName);
0632:                arguments.put(
0633:                        JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION,
0634:                        new Integer(fSelectionStart).toString() + ' '
0635:                                + new Integer(fSelectionLength).toString());
0636:                arguments.put(ATTRIBUTE_FINAL, Boolean.valueOf(fDeclareFinal)
0637:                        .toString());
0638:                arguments.put(ATTRIBUTE_STATIC, Boolean.valueOf(fDeclareStatic)
0639:                        .toString());
0640:                arguments.put(ATTRIBUTE_VISIBILITY, new Integer(fVisibility)
0641:                        .toString());
0642:
0643:                ConvertAnonymousDescriptor descriptor = new ConvertAnonymousDescriptor(
0644:                        projectName, description, comment.asString(),
0645:                        arguments, flags);
0646:                return new RefactoringChangeDescriptor(descriptor);
0647:            }
0648:
0649:            private void modifyConstructorCall(CompilationUnitRewrite rewrite,
0650:                    ITypeBinding[] parameters) {
0651:                rewrite.getASTRewrite().replace(
0652:                        fAnonymousInnerClassNode.getParent(),
0653:                        createNewClassInstanceCreation(rewrite, parameters),
0654:                        null);
0655:            }
0656:
0657:            private ASTNode createNewClassInstanceCreation(
0658:                    CompilationUnitRewrite rewrite, ITypeBinding[] parameters) {
0659:                AST ast = fAnonymousInnerClassNode.getAST();
0660:                ClassInstanceCreation newClassCreation = ast
0661:                        .newClassInstanceCreation();
0662:                newClassCreation.setAnonymousClassDeclaration(null);
0663:                Type type = null;
0664:                SimpleName newNameNode = ast.newSimpleName(fClassName);
0665:                if (parameters.length > 0) {
0666:                    final ParameterizedType parameterized = ast
0667:                            .newParameterizedType(ast
0668:                                    .newSimpleType(newNameNode));
0669:                    for (int index = 0; index < parameters.length; index++)
0670:                        parameterized.typeArguments().add(
0671:                                ast.newSimpleType(ast
0672:                                        .newSimpleName(parameters[index]
0673:                                                .getName())));
0674:                    type = parameterized;
0675:                } else
0676:                    type = ast.newSimpleType(newNameNode);
0677:                newClassCreation.setType(type);
0678:                copyArguments(rewrite, newClassCreation);
0679:                addArgumentsForLocalsUsedInInnerClass(rewrite, newClassCreation);
0680:
0681:                addLinkedPosition(KEY_TYPE_NAME, newNameNode, rewrite
0682:                        .getASTRewrite(), true);
0683:
0684:                return newClassCreation;
0685:            }
0686:
0687:            private void addArgumentsForLocalsUsedInInnerClass(
0688:                    CompilationUnitRewrite rewrite,
0689:                    ClassInstanceCreation newClassCreation) {
0690:                IVariableBinding[] usedLocals = getUsedLocalVariables();
0691:                for (int i = 0; i < usedLocals.length; i++) {
0692:                    final AST ast = fAnonymousInnerClassNode.getAST();
0693:                    final IVariableBinding binding = usedLocals[i];
0694:                    Name name = null;
0695:                    if (binding.isEnumConstant())
0696:                        name = ast.newQualifiedName(ast.newSimpleName(binding
0697:                                .getDeclaringClass().getName()), ast
0698:                                .newSimpleName(binding.getName()));
0699:                    else
0700:                        name = ast.newSimpleName(binding.getName());
0701:                    newClassCreation.arguments().add(name);
0702:                }
0703:            }
0704:
0705:            private void copyArguments(CompilationUnitRewrite rewrite,
0706:                    ClassInstanceCreation newClassCreation) {
0707:                Iterator iter = ((ClassInstanceCreation) fAnonymousInnerClassNode
0708:                        .getParent()).arguments().iterator();
0709:                if (!iter.hasNext())
0710:                    return;
0711:
0712:                IMethodBinding super ConstructorBinding = getSuperConstructorBinding();
0713:                ITypeBinding[] parameterTypes = super ConstructorBinding
0714:                        .getParameterTypes();
0715:
0716:                List arguments = newClassCreation.arguments();
0717:                ASTRewrite astRewrite = rewrite.getASTRewrite();
0718:                int last = parameterTypes.length - 1;
0719:
0720:                for (int i = 0; i < last; i++) {
0721:                    arguments.add(astRewrite.createCopyTarget((Expression) iter
0722:                            .next()));
0723:                }
0724:                if (super ConstructorBinding.isVarargs()) {
0725:                    AST ast = astRewrite.getAST();
0726:                    ArrayCreation arrayCreation = ast.newArrayCreation();
0727:                    arrayCreation.setType((ArrayType) rewrite
0728:                            .getImportRewrite().addImport(parameterTypes[last],
0729:                                    ast));
0730:                    ArrayInitializer initializer = ast.newArrayInitializer();
0731:                    arrayCreation.setInitializer(initializer);
0732:                    arguments.add(arrayCreation);
0733:                    arguments = initializer.expressions();
0734:                }
0735:                while (iter.hasNext()) {
0736:                    arguments.add(astRewrite.createCopyTarget((Expression) iter
0737:                            .next()));
0738:                }
0739:            }
0740:
0741:            private void addNestedClass(CompilationUnitRewrite rewrite,
0742:                    ITypeBinding[] typeParameters) throws CoreException {
0743:                final AbstractTypeDeclaration declarations = (AbstractTypeDeclaration) ASTNodes
0744:                        .getParent(fAnonymousInnerClassNode,
0745:                                AbstractTypeDeclaration.class);
0746:                int index = findIndexOfFistNestedClass(declarations
0747:                        .bodyDeclarations());
0748:                if (index == -1)
0749:                    index = 0;
0750:                rewrite.getASTRewrite().getListRewrite(declarations,
0751:                        declarations.getBodyDeclarationsProperty()).insertAt(
0752:                        createNewNestedClass(rewrite, typeParameters), index,
0753:                        null);
0754:            }
0755:
0756:            private static int findIndexOfFistNestedClass(List bodyDeclarations) {
0757:                for (int i = 0, n = bodyDeclarations.size(); i < n; i++) {
0758:                    BodyDeclaration each = (BodyDeclaration) bodyDeclarations
0759:                            .get(i);
0760:                    if (isNestedType(each))
0761:                        return i;
0762:                }
0763:                return -1;
0764:            }
0765:
0766:            private static boolean isNestedType(BodyDeclaration each) {
0767:                if (!(each instanceof  AbstractTypeDeclaration))
0768:                    return false;
0769:                return (each.getParent() instanceof  AbstractTypeDeclaration);
0770:            }
0771:
0772:            private AbstractTypeDeclaration createNewNestedClass(
0773:                    CompilationUnitRewrite rewrite,
0774:                    ITypeBinding[] typeParameters) throws CoreException {
0775:                final AST ast = fAnonymousInnerClassNode.getAST();
0776:
0777:                final TypeDeclaration newDeclaration = ast.newTypeDeclaration();
0778:                newDeclaration.setInterface(false);
0779:                newDeclaration.setJavadoc(null);
0780:                newDeclaration.modifiers().addAll(
0781:                        ASTNodeFactory.newModifiers(ast,
0782:                                createModifiersForNestedClass()));
0783:                newDeclaration.setName(ast.newSimpleName(fClassName));
0784:
0785:                TypeParameter parameter = null;
0786:                for (int index = 0; index < typeParameters.length; index++) {
0787:                    parameter = ast.newTypeParameter();
0788:                    parameter.setName(ast.newSimpleName(typeParameters[index]
0789:                            .getName()));
0790:                    newDeclaration.typeParameters().add(parameter);
0791:                }
0792:                setSuperType(newDeclaration);
0793:
0794:                IJavaProject project = fCu.getJavaProject();
0795:
0796:                IVariableBinding[] bindings = getUsedLocalVariables();
0797:                ArrayList fieldNames = new ArrayList();
0798:                for (int i = 0; i < bindings.length; i++) {
0799:                    String name = StubUtility.removePrefixAndSuffixForVariable(
0800:                            project, bindings[i]);
0801:                    String[] fieldNameProposals = StubUtility
0802:                            .getVariableNameSuggestions(
0803:                                    StubUtility.INSTANCE_FIELD, project, name,
0804:                                    0, fieldNames, true);
0805:                    fieldNames.add(fieldNameProposals[0]);
0806:
0807:                    if (fLinkedProposalModel != null) {
0808:                        LinkedProposalPositionGroup positionGroup = fLinkedProposalModel
0809:                                .getPositionGroup(KEY_FIELD_NAME_EXT + i, true);
0810:                        for (int k = 0; k < fieldNameProposals.length; k++) {
0811:                            positionGroup.addProposal(fieldNameProposals[k],
0812:                                    null, fieldNameProposals.length - k);
0813:                        }
0814:                    }
0815:                }
0816:                String[] allFieldNames = (String[]) fieldNames
0817:                        .toArray(new String[fieldNames.size()]);
0818:
0819:                List newBodyDeclarations = newDeclaration.bodyDeclarations();
0820:
0821:                createFieldsForAccessedLocals(rewrite, bindings, allFieldNames,
0822:                        newBodyDeclarations);
0823:
0824:                MethodDeclaration newConstructorDecl = createNewConstructor(
0825:                        rewrite, bindings, allFieldNames);
0826:                if (newConstructorDecl != null) {
0827:                    newBodyDeclarations.add(newConstructorDecl);
0828:                }
0829:
0830:                updateAndMoveBodyDeclarations(rewrite, bindings, allFieldNames,
0831:                        newBodyDeclarations, newConstructorDecl);
0832:
0833:                if (doAddComments()) {
0834:                    String[] parameterNames = new String[typeParameters.length];
0835:                    for (int index = 0; index < parameterNames.length; index++) {
0836:                        parameterNames[index] = typeParameters[index].getName();
0837:                    }
0838:                    String string = CodeGeneration.getTypeComment(rewrite
0839:                            .getCu(), fClassName, parameterNames, StubUtility
0840:                            .getLineDelimiterUsed(fCu));
0841:                    if (string != null) {
0842:                        Javadoc javadoc = (Javadoc) rewrite.getASTRewrite()
0843:                                .createStringPlaceholder(string,
0844:                                        ASTNode.JAVADOC);
0845:                        newDeclaration.setJavadoc(javadoc);
0846:                    }
0847:                }
0848:                if (fLinkedProposalModel != null) {
0849:                    addLinkedPosition(KEY_TYPE_NAME, newDeclaration.getName(),
0850:                            rewrite.getASTRewrite(), false);
0851:                    ModifierCorrectionSubProcessor
0852:                            .installLinkedVisibilityProposals(
0853:                                    fLinkedProposalModel, rewrite
0854:                                            .getASTRewrite(), newDeclaration
0855:                                            .modifiers(), false);
0856:                }
0857:
0858:                return newDeclaration;
0859:            }
0860:
0861:            private void updateAndMoveBodyDeclarations(
0862:                    CompilationUnitRewrite rewriter,
0863:                    IVariableBinding[] bindings, String[] fieldNames,
0864:                    List newBodyDeclarations,
0865:                    MethodDeclaration newConstructorDecl)
0866:                    throws JavaModelException {
0867:                final ASTRewrite astRewrite = rewriter.getASTRewrite();
0868:                final AST ast = astRewrite.getAST();
0869:
0870:                final boolean useThisAccess = useThisForFieldAccess();
0871:
0872:                int fieldInsertIndex = newConstructorDecl != null ? newBodyDeclarations
0873:                        .lastIndexOf(newConstructorDecl)
0874:                        : newBodyDeclarations.size();
0875:
0876:                for (Iterator iterator = fAnonymousInnerClassNode
0877:                        .bodyDeclarations().iterator(); iterator.hasNext();) {
0878:                    BodyDeclaration body = (BodyDeclaration) iterator.next();
0879:
0880:                    for (int i = 0; i < bindings.length; i++) {
0881:                        SimpleName[] names = LinkedNodeFinder.findByBinding(
0882:                                body, bindings[i]);
0883:                        String fieldName = fieldNames[i];
0884:                        for (int k = 0; k < names.length; k++) {
0885:                            SimpleName newNode = ast.newSimpleName(fieldName);
0886:                            if (useThisAccess) {
0887:                                FieldAccess access = ast.newFieldAccess();
0888:                                access.setExpression(ast.newThisExpression());
0889:                                access.setName(newNode);
0890:                                astRewrite.replace(names[k], access, null);
0891:                            } else {
0892:                                astRewrite.replace(names[k], newNode, null);
0893:                            }
0894:                            addLinkedPosition(KEY_FIELD_NAME_EXT + i, newNode,
0895:                                    astRewrite, false);
0896:                        }
0897:                    }
0898:                    if (body instanceof  Initializer
0899:                            || body instanceof  FieldDeclaration) {
0900:                        newBodyDeclarations.add(fieldInsertIndex++, astRewrite
0901:                                .createMoveTarget(body));
0902:                    } else {
0903:                        newBodyDeclarations.add(astRewrite
0904:                                .createMoveTarget(body));
0905:                    }
0906:                }
0907:
0908:                if (newConstructorDecl != null) {
0909:                    // move initialization of existing fields to constructor if an outer is referenced 
0910:                    List bodyStatements = newConstructorDecl.getBody()
0911:                            .statements();
0912:
0913:                    List fieldsToInitializeInConstructor = getFieldsToInitializeInConstructor();
0914:                    for (Iterator iter = fieldsToInitializeInConstructor
0915:                            .iterator(); iter.hasNext();) {
0916:                        VariableDeclarationFragment fragment = (VariableDeclarationFragment) iter
0917:                                .next();
0918:                        Expression initializer = fragment.getInitializer();
0919:                        Expression replacement = (Expression) astRewrite
0920:                                .get(
0921:                                        fragment,
0922:                                        VariableDeclarationFragment.INITIALIZER_PROPERTY);
0923:                        if (replacement == initializer) {
0924:                            replacement = (Expression) astRewrite
0925:                                    .createMoveTarget(initializer);
0926:                        }
0927:                        astRewrite.remove(initializer, null);
0928:                        SimpleName fieldNameNode = ast.newSimpleName(fragment
0929:                                .getName().getIdentifier());
0930:                        bodyStatements.add(newFieldAssignment(ast,
0931:                                fieldNameNode, replacement, useThisAccess));
0932:                    }
0933:                }
0934:            }
0935:
0936:            private void createFieldsForAccessedLocals(
0937:                    CompilationUnitRewrite rewrite,
0938:                    IVariableBinding[] varBindings, String[] fieldNames,
0939:                    List newBodyDeclarations) throws JavaModelException {
0940:                final ImportRewrite importRewrite = rewrite.getImportRewrite();
0941:                final ASTRewrite astRewrite = rewrite.getASTRewrite();
0942:                final AST ast = astRewrite.getAST();
0943:
0944:                for (int i = 0; i < varBindings.length; i++) {
0945:                    VariableDeclarationFragment fragment = ast
0946:                            .newVariableDeclarationFragment();
0947:                    fragment.setExtraDimensions(0);
0948:                    fragment.setInitializer(null);
0949:                    fragment.setName(ast.newSimpleName(fieldNames[i]));
0950:                    FieldDeclaration field = ast.newFieldDeclaration(fragment);
0951:                    ITypeBinding varType = varBindings[i].getType();
0952:                    field.setType(importRewrite.addImport(varType, ast));
0953:                    field.modifiers().addAll(
0954:                            ASTNodeFactory.newModifiers(ast, Modifier.PRIVATE
0955:                                    | Modifier.FINAL));
0956:                    if (doAddComments()) {
0957:                        try {
0958:                            String string = CodeGeneration.getFieldComment(
0959:                                    rewrite.getCu(), varType.getName(),
0960:                                    fieldNames[i], StubUtility
0961:                                            .getLineDelimiterUsed(fCu));
0962:                            if (string != null) {
0963:                                Javadoc javadoc = (Javadoc) astRewrite
0964:                                        .createStringPlaceholder(string,
0965:                                                ASTNode.JAVADOC);
0966:                                field.setJavadoc(javadoc);
0967:                            }
0968:                        } catch (CoreException exception) {
0969:                            throw new JavaModelException(exception);
0970:                        }
0971:                    }
0972:
0973:                    newBodyDeclarations.add(field);
0974:
0975:                    addLinkedPosition(KEY_FIELD_NAME_EXT + i, fragment
0976:                            .getName(), astRewrite, false);
0977:                }
0978:            }
0979:
0980:            private void addLinkedPosition(String key, ASTNode nodeToTrack,
0981:                    ASTRewrite rewrite, boolean isFirst) {
0982:                if (fLinkedProposalModel != null) {
0983:                    fLinkedProposalModel.getPositionGroup(key, true)
0984:                            .addPosition(rewrite.track(nodeToTrack), isFirst);
0985:                }
0986:            }
0987:
0988:            private IVariableBinding[] getUsedLocalVariables() {
0989:                final Set result = new HashSet(0);
0990:                collectRefrencedVariables(fAnonymousInnerClassNode, result);
0991:                ArrayList usedLocals = new ArrayList();
0992:                for (Iterator iterator = result.iterator(); iterator.hasNext();) {
0993:                    IVariableBinding next = (IVariableBinding) iterator.next();
0994:                    if (isBindingToTemp(next)) {
0995:                        usedLocals.add(next);
0996:                    }
0997:                }
0998:                return (IVariableBinding[]) usedLocals
0999:                        .toArray(new IVariableBinding[usedLocals.size()]);
1000:            }
1001:
1002:            private void collectRefrencedVariables(ASTNode root,
1003:                    final Set result) {
1004:                root.accept(new ASTVisitor() {
1005:                    public boolean visit(SimpleName node) {
1006:                        IBinding binding = node.resolveBinding();
1007:                        if (binding instanceof  IVariableBinding)
1008:                            result.add(binding);
1009:                        return true;
1010:                    }
1011:                });
1012:            }
1013:
1014:            private boolean isBindingToTemp(IVariableBinding variable) {
1015:                if (variable.isField())
1016:                    return false;
1017:                if (!Modifier.isFinal(variable.getModifiers()))
1018:                    return false;
1019:                ASTNode declaringNode = fCompilationUnitNode
1020:                        .findDeclaringNode(variable);
1021:                if (declaringNode == null)
1022:                    return false;
1023:                if (ASTNodes.isParent(declaringNode, fAnonymousInnerClassNode))
1024:                    return false;
1025:                return true;
1026:            }
1027:
1028:            private MethodDeclaration createNewConstructor(
1029:                    CompilationUnitRewrite rewrite,
1030:                    IVariableBinding[] bindings, String[] fieldNames)
1031:                    throws JavaModelException {
1032:                ClassInstanceCreation instanceCreation = (ClassInstanceCreation) fAnonymousInnerClassNode
1033:                        .getParent();
1034:
1035:                if (instanceCreation.arguments().isEmpty()
1036:                        && bindings.length == 0)
1037:                    return null;
1038:
1039:                IJavaProject project = fCu.getJavaProject();
1040:                AST ast = rewrite.getAST();
1041:                ImportRewrite importRewrite = rewrite.getImportRewrite();
1042:                ASTRewrite astRewrite = rewrite.getASTRewrite();
1043:
1044:                MethodDeclaration newConstructor = ast.newMethodDeclaration();
1045:                newConstructor.setConstructor(true);
1046:                newConstructor.setExtraDimensions(0);
1047:                newConstructor.setJavadoc(null);
1048:                newConstructor.modifiers().addAll(
1049:                        ASTNodeFactory.newModifiers(ast, fVisibility));
1050:                newConstructor.setName(ast.newSimpleName(fClassName));
1051:                addLinkedPosition(KEY_TYPE_NAME, newConstructor.getName(),
1052:                        astRewrite, false);
1053:
1054:                newConstructor.setBody(ast.newBlock());
1055:
1056:                List newStatements = newConstructor.getBody().statements();
1057:
1058:                List newParameters = newConstructor.parameters();
1059:                List newParameterNames = new ArrayList();
1060:
1061:                // add parameters for elements passed with the instance creation
1062:                if (!instanceCreation.arguments().isEmpty()) {
1063:                    IMethodBinding constructorBinding = getSuperConstructorBinding();
1064:                    if (constructorBinding != null) {
1065:                        SuperConstructorInvocation super ConstructorInvocation = ast
1066:                                .newSuperConstructorInvocation();
1067:                        ITypeBinding[] parameterTypes = constructorBinding
1068:                                .getParameterTypes();
1069:                        String[][] parameterNames = StubUtility
1070:                                .suggestArgumentNamesWithProposals(project,
1071:                                        constructorBinding);
1072:                        for (int i = 0; i < parameterNames.length; i++) {
1073:                            String[] nameProposals = parameterNames[i];
1074:                            String paramName = nameProposals[0];
1075:
1076:                            SingleVariableDeclaration param = newParameterDeclaration(
1077:                                    ast, importRewrite, paramName,
1078:                                    parameterTypes[i]);
1079:                            newParameters.add(param);
1080:                            newParameterNames.add(paramName);
1081:
1082:                            SimpleName newSIArgument = ast
1083:                                    .newSimpleName(paramName);
1084:                            super ConstructorInvocation.arguments().add(
1085:                                    newSIArgument);
1086:
1087:                            if (fLinkedProposalModel != null) {
1088:                                LinkedProposalPositionGroup positionGroup = fLinkedProposalModel
1089:                                        .getPositionGroup(KEY_PARAM_NAME_CONST
1090:                                                + String.valueOf(i), true);
1091:                                positionGroup.addPosition(astRewrite
1092:                                        .track(param.getName()), false);
1093:                                positionGroup.addPosition(astRewrite
1094:                                        .track(newSIArgument), false);
1095:                                for (int k = 0; k < nameProposals.length; k++) {
1096:                                    positionGroup.addProposal(nameProposals[k],
1097:                                            null, nameProposals.length - k);
1098:                                }
1099:                            }
1100:                        }
1101:                        newStatements.add(super ConstructorInvocation);
1102:                    }
1103:                }
1104:                // add parameters for all outer variables used
1105:                boolean useThisAccess = useThisForFieldAccess();
1106:                for (int i = 0; i < bindings.length; i++) {
1107:                    String baseName = StubUtility
1108:                            .removePrefixAndSuffixForVariable(project,
1109:                                    bindings[i]);
1110:                    String[] paramNameProposals = StubUtility
1111:                            .getVariableNameSuggestions(StubUtility.PARAMETER,
1112:                                    project, baseName, 0, newParameterNames,
1113:                                    true);
1114:                    String paramName = paramNameProposals[0];
1115:
1116:                    SingleVariableDeclaration param = newParameterDeclaration(
1117:                            ast, importRewrite, paramName, bindings[i]
1118:                                    .getType());
1119:                    newParameters.add(param);
1120:                    newParameterNames.add(paramName);
1121:
1122:                    String fieldName = fieldNames[i];
1123:                    SimpleName fieldNameNode = ast.newSimpleName(fieldName);
1124:                    SimpleName paramNameNode = ast.newSimpleName(paramName);
1125:                    newStatements.add(newFieldAssignment(ast, fieldNameNode,
1126:                            paramNameNode, useThisAccess
1127:                                    || newParameterNames.contains(fieldName)));
1128:
1129:                    if (fLinkedProposalModel != null) {
1130:                        LinkedProposalPositionGroup positionGroup = fLinkedProposalModel
1131:                                .getPositionGroup(KEY_PARAM_NAME_EXT
1132:                                        + String.valueOf(i), true);
1133:                        positionGroup.addPosition(astRewrite.track(param
1134:                                .getName()), false);
1135:                        positionGroup.addPosition(astRewrite
1136:                                .track(paramNameNode), false);
1137:                        for (int k = 0; k < paramNameProposals.length; k++) {
1138:                            positionGroup.addProposal(paramNameProposals[k],
1139:                                    null, paramNameProposals.length - k);
1140:                        }
1141:
1142:                        fLinkedProposalModel.getPositionGroup(
1143:                                KEY_FIELD_NAME_EXT + i, true).addPosition(
1144:                                astRewrite.track(fieldNameNode), false);
1145:                    }
1146:                }
1147:
1148:                addExceptionsToNewConstructor(newConstructor);
1149:
1150:                if (doAddComments()) {
1151:                    try {
1152:                        String[] allParamNames = (String[]) newParameterNames
1153:                                .toArray(new String[newParameterNames.size()]);
1154:                        String string = CodeGeneration.getMethodComment(fCu,
1155:                                fClassName, fClassName, allParamNames,
1156:                                new String[0], null, new String[0], null,
1157:                                StubUtility.getLineDelimiterUsed(fCu));
1158:                        if (string != null) {
1159:                            Javadoc javadoc = (Javadoc) astRewrite
1160:                                    .createStringPlaceholder(string,
1161:                                            ASTNode.JAVADOC);
1162:                            newConstructor.setJavadoc(javadoc);
1163:                        }
1164:                    } catch (CoreException exception) {
1165:                        throw new JavaModelException(exception);
1166:                    }
1167:                }
1168:                return newConstructor;
1169:            }
1170:
1171:            private Statement newFieldAssignment(AST ast,
1172:                    SimpleName fieldNameNode, Expression initializer,
1173:                    boolean useThisAccess) {
1174:                Assignment assignment = ast.newAssignment();
1175:                if (useThisAccess) {
1176:                    FieldAccess access = ast.newFieldAccess();
1177:                    access.setExpression(ast.newThisExpression());
1178:                    access.setName(fieldNameNode);
1179:                    assignment.setLeftHandSide(access);
1180:                } else {
1181:                    assignment.setLeftHandSide(fieldNameNode);
1182:                }
1183:                assignment.setOperator(Assignment.Operator.ASSIGN);
1184:                assignment.setRightHandSide(initializer);
1185:
1186:                return ast.newExpressionStatement(assignment);
1187:            }
1188:
1189:            // live List of VariableDeclarationFragments
1190:            private List getFieldsToInitializeInConstructor() {
1191:                List result = new ArrayList(0);
1192:                for (Iterator iter = fAnonymousInnerClassNode
1193:                        .bodyDeclarations().iterator(); iter.hasNext();) {
1194:                    Object element = iter.next();
1195:                    if (element instanceof  FieldDeclaration) {
1196:                        List fragments = ((FieldDeclaration) element)
1197:                                .fragments();
1198:                        for (Iterator fragmentIter = fragments.iterator(); fragmentIter
1199:                                .hasNext();) {
1200:                            VariableDeclarationFragment fragment = (VariableDeclarationFragment) fragmentIter
1201:                                    .next();
1202:                            if (isToBeInitializerInConstructor(fragment, result))
1203:                                result.add(fragment);
1204:                        }
1205:                    }
1206:                }
1207:                return result;
1208:            }
1209:
1210:            private boolean isToBeInitializerInConstructor(
1211:                    VariableDeclarationFragment fragment,
1212:                    List fieldsToInitialize) {
1213:                return fragment.getInitializer() != null
1214:                        && areLocalsUsedIn(fragment.getInitializer(),
1215:                                fieldsToInitialize);
1216:            }
1217:
1218:            private boolean areLocalsUsedIn(Expression fieldInitializer,
1219:                    List fieldsToInitialize) {
1220:                Set localsUsed = new HashSet(0);
1221:                collectRefrencedVariables(fieldInitializer, localsUsed);
1222:
1223:                ITypeBinding anonType = fAnonymousInnerClassNode
1224:                        .resolveBinding();
1225:
1226:                for (Iterator iterator = localsUsed.iterator(); iterator
1227:                        .hasNext();) {
1228:                    IVariableBinding curr = (IVariableBinding) iterator.next();
1229:                    if (isBindingToTemp(curr)) { // reference a local from outside
1230:                        return true;
1231:                    } else if (curr.isField()
1232:                            && (curr.getDeclaringClass() == anonType)
1233:                            && fieldsToInitialize.contains(fCompilationUnitNode
1234:                                    .findDeclaringNode(curr))) {
1235:                        return true; // references a field that references a local from outside
1236:                    }
1237:                }
1238:                return false;
1239:            }
1240:
1241:            private IMethodBinding getSuperConstructorBinding() {
1242:                //workaround for missing java core functionality - finding a
1243:                // super constructor for an anonymous class creation
1244:                IMethodBinding anonConstr = ((ClassInstanceCreation) fAnonymousInnerClassNode
1245:                        .getParent()).resolveConstructorBinding();
1246:                if (anonConstr == null)
1247:                    return null;
1248:                ITypeBinding super Class = anonConstr.getDeclaringClass()
1249:                        .getSuperclass();
1250:                IMethodBinding[] super Methods = super Class.getDeclaredMethods();
1251:                for (int i = 0; i < super Methods.length; i++) {
1252:                    IMethodBinding super Method = super Methods[i];
1253:                    if (super Method.isConstructor()
1254:                            && parameterTypesMatch(super Method, anonConstr))
1255:                        return super Method;
1256:                }
1257:                Assert.isTrue(false);//there's no way - it must be there
1258:                return null;
1259:            }
1260:
1261:            private static boolean parameterTypesMatch(IMethodBinding m1,
1262:                    IMethodBinding m2) {
1263:                ITypeBinding[] m1Params = m1.getParameterTypes();
1264:                ITypeBinding[] m2Params = m2.getParameterTypes();
1265:                if (m1Params.length != m2Params.length)
1266:                    return false;
1267:                for (int i = 0; i < m2Params.length; i++) {
1268:                    if (!m1Params[i].equals(m2Params[i]))
1269:                        return false;
1270:                }
1271:                return true;
1272:            }
1273:
1274:            private void addExceptionsToNewConstructor(
1275:                    MethodDeclaration newConstructor) {
1276:                IMethodBinding constructorBinding = getSuperConstructorBinding();
1277:                if (constructorBinding == null)
1278:                    return;
1279:                ITypeBinding[] exceptions = constructorBinding
1280:                        .getExceptionTypes();
1281:                for (int i = 0; i < exceptions.length; i++) {
1282:                    Name exceptionTypeName = fAnonymousInnerClassNode.getAST()
1283:                            .newName(Bindings.getNameComponents(exceptions[i]));
1284:                    newConstructor.thrownExceptions().add(exceptionTypeName);
1285:                }
1286:            }
1287:
1288:            private SingleVariableDeclaration newParameterDeclaration(AST ast,
1289:                    ImportRewrite importRewrite, String paramName,
1290:                    ITypeBinding paramType) {
1291:                SingleVariableDeclaration param = ast
1292:                        .newSingleVariableDeclaration();
1293:                param.setExtraDimensions(0);
1294:                param.setInitializer(null);
1295:                param.setType(importRewrite.addImport(paramType, ast));
1296:                param.setName(ast.newSimpleName(paramName));
1297:                return param;
1298:            }
1299:
1300:            private void setSuperType(TypeDeclaration declaration)
1301:                    throws JavaModelException {
1302:                ClassInstanceCreation classInstanceCreation = (ClassInstanceCreation) fAnonymousInnerClassNode
1303:                        .getParent();
1304:                ITypeBinding binding = classInstanceCreation
1305:                        .resolveTypeBinding();
1306:                if (binding == null)
1307:                    return;
1308:                Type newType = (Type) ASTNode.copySubtree(
1309:                        fAnonymousInnerClassNode.getAST(),
1310:                        classInstanceCreation.getType());
1311:                if (binding.getSuperclass().getQualifiedName().equals(
1312:                        "java.lang.Object")) { //$NON-NLS-1$
1313:                    Assert.isTrue(binding.getInterfaces().length <= 1);
1314:                    if (binding.getInterfaces().length == 0)
1315:                        return;
1316:                    declaration.super InterfaceTypes().add(0, newType);
1317:                } else {
1318:                    declaration.setSuperclassType(newType);
1319:                }
1320:            }
1321:
1322:            private ITypeBinding getSuperTypeBinding() {
1323:                ITypeBinding types = fAnonymousInnerClassNode.resolveBinding();
1324:                ITypeBinding[] interfaces = types.getInterfaces();
1325:                if (interfaces.length > 0)
1326:                    return interfaces[0];
1327:                else
1328:                    return types.getSuperclass();
1329:            }
1330:
1331:            private int createModifiersForNestedClass() {
1332:                int flags = fVisibility;
1333:                if (fDeclareFinal)
1334:                    flags |= Modifier.FINAL;
1335:                if (mustInnerClassBeStatic() || fDeclareStatic)
1336:                    flags |= Modifier.STATIC;
1337:                return flags;
1338:            }
1339:
1340:            public boolean mustInnerClassBeStatic() {
1341:                ITypeBinding typeBinding = ((AbstractTypeDeclaration) ASTNodes
1342:                        .getParent(fAnonymousInnerClassNode,
1343:                                AbstractTypeDeclaration.class))
1344:                        .resolveBinding();
1345:                ASTNode current = fAnonymousInnerClassNode.getParent();
1346:                boolean ans = false;
1347:                while (current != null) {
1348:                    switch (current.getNodeType()) {
1349:                    case ASTNode.ANONYMOUS_CLASS_DECLARATION: {
1350:                        AnonymousClassDeclaration enclosingAnonymousClassDeclaration = (AnonymousClassDeclaration) current;
1351:                        ITypeBinding binding = enclosingAnonymousClassDeclaration
1352:                                .resolveBinding();
1353:                        if (binding != null
1354:                                && Bindings.isSuperType(typeBinding, binding
1355:                                        .getSuperclass())) {
1356:                            return false;
1357:                        }
1358:                        break;
1359:                    }
1360:                    case ASTNode.FIELD_DECLARATION: {
1361:                        FieldDeclaration enclosingFieldDeclaration = (FieldDeclaration) current;
1362:                        if (Modifier.isStatic(enclosingFieldDeclaration
1363:                                .getModifiers())) {
1364:                            ans = true;
1365:                        }
1366:                        break;
1367:                    }
1368:                    case ASTNode.METHOD_DECLARATION: {
1369:                        MethodDeclaration enclosingMethodDeclaration = (MethodDeclaration) current;
1370:                        if (Modifier.isStatic(enclosingMethodDeclaration
1371:                                .getModifiers())) {
1372:                            ans = true;
1373:                        }
1374:                        break;
1375:                    }
1376:                    case ASTNode.TYPE_DECLARATION: {
1377:                        return ans;
1378:                    }
1379:                    }
1380:                    current = current.getParent();
1381:                }
1382:                return ans;
1383:            }
1384:
1385:            public RefactoringStatus initialize(
1386:                    final RefactoringArguments arguments) {
1387:                fSelfInitializing = true;
1388:                if (arguments instanceof  JavaRefactoringArguments) {
1389:                    final JavaRefactoringArguments extended = (JavaRefactoringArguments) arguments;
1390:                    final String handle = extended
1391:                            .getAttribute(JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT);
1392:                    if (handle != null) {
1393:                        final IJavaElement element = JavaRefactoringDescriptorUtil
1394:                                .handleToElement(extended.getProject(), handle,
1395:                                        false);
1396:                        if (element == null
1397:                                || !element.exists()
1398:                                || element.getElementType() != IJavaElement.COMPILATION_UNIT)
1399:                            return createInputFatalStatus(element,
1400:                                    IJavaRefactorings.CONVERT_ANONYMOUS);
1401:                        else {
1402:                            fCu = (ICompilationUnit) element;
1403:                        }
1404:                    } else
1405:                        return RefactoringStatus
1406:                                .createFatalErrorStatus(Messages
1407:                                        .format(
1408:                                                RefactoringCoreMessages.InitializableRefactoring_argument_not_exist,
1409:                                                JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT));
1410:                    final String name = extended
1411:                            .getAttribute(JavaRefactoringDescriptorUtil.ATTRIBUTE_NAME);
1412:                    if (name != null && !"".equals(name)) //$NON-NLS-1$
1413:                        fClassName = name;
1414:                    else
1415:                        return RefactoringStatus
1416:                                .createFatalErrorStatus(Messages
1417:                                        .format(
1418:                                                RefactoringCoreMessages.InitializableRefactoring_argument_not_exist,
1419:                                                JavaRefactoringDescriptorUtil.ATTRIBUTE_NAME));
1420:                    final String visibility = extended
1421:                            .getAttribute(ATTRIBUTE_VISIBILITY);
1422:                    if (visibility != null && !"".equals(visibility)) {//$NON-NLS-1$
1423:                        int flag = 0;
1424:                        try {
1425:                            flag = Integer.parseInt(visibility);
1426:                        } catch (NumberFormatException exception) {
1427:                            return RefactoringStatus
1428:                                    .createFatalErrorStatus(Messages
1429:                                            .format(
1430:                                                    RefactoringCoreMessages.InitializableRefactoring_argument_not_exist,
1431:                                                    ATTRIBUTE_VISIBILITY));
1432:                        }
1433:                        fVisibility = flag;
1434:                    }
1435:                    final String selection = extended
1436:                            .getAttribute(JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION);
1437:                    if (selection != null) {
1438:                        int offset = -1;
1439:                        int length = -1;
1440:                        final StringTokenizer tokenizer = new StringTokenizer(
1441:                                selection);
1442:                        if (tokenizer.hasMoreTokens())
1443:                            offset = Integer.valueOf(tokenizer.nextToken())
1444:                                    .intValue();
1445:                        if (tokenizer.hasMoreTokens())
1446:                            length = Integer.valueOf(tokenizer.nextToken())
1447:                                    .intValue();
1448:                        if (offset >= 0 && length >= 0) {
1449:                            fSelectionStart = offset;
1450:                            fSelectionLength = length;
1451:                        } else
1452:                            return RefactoringStatus
1453:                                    .createFatalErrorStatus(Messages
1454:                                            .format(
1455:                                                    RefactoringCoreMessages.InitializableRefactoring_illegal_argument,
1456:                                                    new Object[] {
1457:                                                            selection,
1458:                                                            JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION }));
1459:                    } else
1460:                        return RefactoringStatus
1461:                                .createFatalErrorStatus(Messages
1462:                                        .format(
1463:                                                RefactoringCoreMessages.InitializableRefactoring_argument_not_exist,
1464:                                                JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION));
1465:                    final String declareStatic = extended
1466:                            .getAttribute(ATTRIBUTE_STATIC);
1467:                    if (declareStatic != null) {
1468:                        fDeclareStatic = Boolean.valueOf(declareStatic)
1469:                                .booleanValue();
1470:                    } else
1471:                        return RefactoringStatus
1472:                                .createFatalErrorStatus(Messages
1473:                                        .format(
1474:                                                RefactoringCoreMessages.InitializableRefactoring_argument_not_exist,
1475:                                                ATTRIBUTE_STATIC));
1476:                    final String declareFinal = extended
1477:                            .getAttribute(ATTRIBUTE_FINAL);
1478:                    if (declareFinal != null) {
1479:                        fDeclareFinal = Boolean.valueOf(declareStatic)
1480:                                .booleanValue();
1481:                    } else
1482:                        return RefactoringStatus
1483:                                .createFatalErrorStatus(Messages
1484:                                        .format(
1485:                                                RefactoringCoreMessages.InitializableRefactoring_argument_not_exist,
1486:                                                ATTRIBUTE_FINAL));
1487:                } else
1488:                    return RefactoringStatus
1489:                            .createFatalErrorStatus(RefactoringCoreMessages.InitializableRefactoring_inacceptable_arguments);
1490:                return new RefactoringStatus();
1491:            }
1492:        }
w_w__w__.__j___a__v__a___2___s._c___o_m_ | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.