Source Code Cross Referenced for ExtractClassRefactoring.java in  » IDE-Eclipse » jdt » org » eclipse » jdt » internal » corext » refactoring » structure » 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.structure 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*******************************************************************************
0002:         * Copyright (c) 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:         *******************************************************************************/package org.eclipse.jdt.internal.corext.refactoring.structure;
0011:
0012:        import java.util.ArrayList;
0013:        import java.util.Arrays;
0014:        import java.util.HashSet;
0015:        import java.util.Iterator;
0016:        import java.util.LinkedHashMap;
0017:        import java.util.List;
0018:        import java.util.Map;
0019:        import java.util.Set;
0020:
0021:        import org.eclipse.text.edits.TextEditGroup;
0022:
0023:        import org.eclipse.core.runtime.Assert;
0024:        import org.eclipse.core.runtime.CoreException;
0025:        import org.eclipse.core.runtime.IProgressMonitor;
0026:        import org.eclipse.core.runtime.OperationCanceledException;
0027:        import org.eclipse.core.runtime.SubProgressMonitor;
0028:
0029:        import org.eclipse.ltk.core.refactoring.Change;
0030:        import org.eclipse.ltk.core.refactoring.Refactoring;
0031:        import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
0032:        import org.eclipse.ltk.core.refactoring.RefactoringStatus;
0033:
0034:        import org.eclipse.jdt.core.Flags;
0035:        import org.eclipse.jdt.core.ICompilationUnit;
0036:        import org.eclipse.jdt.core.IField;
0037:        import org.eclipse.jdt.core.IJavaElement;
0038:        import org.eclipse.jdt.core.IJavaProject;
0039:        import org.eclipse.jdt.core.IPackageFragment;
0040:        import org.eclipse.jdt.core.IPackageFragmentRoot;
0041:        import org.eclipse.jdt.core.IType;
0042:        import org.eclipse.jdt.core.ITypeRoot;
0043:        import org.eclipse.jdt.core.JavaModelException;
0044:        import org.eclipse.jdt.core.Signature;
0045:        import org.eclipse.jdt.core.dom.AST;
0046:        import org.eclipse.jdt.core.dom.ASTNode;
0047:        import org.eclipse.jdt.core.dom.ASTVisitor;
0048:        import org.eclipse.jdt.core.dom.ArrayCreation;
0049:        import org.eclipse.jdt.core.dom.ArrayInitializer;
0050:        import org.eclipse.jdt.core.dom.Assignment;
0051:        import org.eclipse.jdt.core.dom.ClassInstanceCreation;
0052:        import org.eclipse.jdt.core.dom.CompilationUnit;
0053:        import org.eclipse.jdt.core.dom.Expression;
0054:        import org.eclipse.jdt.core.dom.FieldAccess;
0055:        import org.eclipse.jdt.core.dom.FieldDeclaration;
0056:        import org.eclipse.jdt.core.dom.IExtendedModifier;
0057:        import org.eclipse.jdt.core.dom.IPackageBinding;
0058:        import org.eclipse.jdt.core.dom.ITypeBinding;
0059:        import org.eclipse.jdt.core.dom.IVariableBinding;
0060:        import org.eclipse.jdt.core.dom.Javadoc;
0061:        import org.eclipse.jdt.core.dom.Modifier;
0062:        import org.eclipse.jdt.core.dom.NullLiteral;
0063:        import org.eclipse.jdt.core.dom.QualifiedName;
0064:        import org.eclipse.jdt.core.dom.SimpleName;
0065:        import org.eclipse.jdt.core.dom.SuperFieldAccess;
0066:        import org.eclipse.jdt.core.dom.Type;
0067:        import org.eclipse.jdt.core.dom.TypeDeclaration;
0068:        import org.eclipse.jdt.core.dom.VariableDeclaration;
0069:        import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
0070:        import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword;
0071:        import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
0072:        import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
0073:        import org.eclipse.jdt.core.refactoring.descriptors.ExtractClassDescriptor;
0074:        import org.eclipse.jdt.core.refactoring.descriptors.JavaRefactoringDescriptor;
0075:        import org.eclipse.jdt.core.refactoring.descriptors.ExtractClassDescriptor.Field;
0076:        import org.eclipse.jdt.core.search.IJavaSearchConstants;
0077:        import org.eclipse.jdt.core.search.SearchMatch;
0078:        import org.eclipse.jdt.core.search.SearchPattern;
0079:
0080:        import org.eclipse.jdt.internal.corext.codemanipulation.GetterSetterUtil;
0081:        import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility;
0082:        import org.eclipse.jdt.internal.corext.dom.ASTNodes;
0083:        import org.eclipse.jdt.internal.corext.dom.Bindings;
0084:        import org.eclipse.jdt.internal.corext.dom.NodeFinder;
0085:        import org.eclipse.jdt.internal.corext.dom.TypeBindingVisitor;
0086:        import org.eclipse.jdt.internal.corext.refactoring.Checks;
0087:        import org.eclipse.jdt.internal.corext.refactoring.JDTRefactoringDescriptorComment;
0088:        import org.eclipse.jdt.internal.corext.refactoring.ParameterInfo;
0089:        import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
0090:        import org.eclipse.jdt.internal.corext.refactoring.RefactoringScopeFactory;
0091:        import org.eclipse.jdt.internal.corext.refactoring.RefactoringSearchEngine;
0092:        import org.eclipse.jdt.internal.corext.refactoring.SearchResultGroup;
0093:        import org.eclipse.jdt.internal.corext.refactoring.base.JavaStatusContext;
0094:        import org.eclipse.jdt.internal.corext.refactoring.changes.DynamicValidationRefactoringChange;
0095:        import org.eclipse.jdt.internal.corext.refactoring.structure.ParameterObjectFactory.CreationListener;
0096:        import org.eclipse.jdt.internal.corext.refactoring.util.TextChangeManager;
0097:        import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
0098:        import org.eclipse.jdt.internal.corext.util.Messages;
0099:
0100:        import org.eclipse.jdt.internal.ui.JavaPlugin;
0101:        import org.eclipse.jdt.internal.ui.text.correction.ASTResolving;
0102:
0103:        public class ExtractClassRefactoring extends Refactoring {
0104:
0105:            public static class ExtractClassDescriptorVerification {
0106:                private ExtractClassDescriptor fDescriptor;
0107:
0108:                public ExtractClassDescriptorVerification(
0109:                        ExtractClassDescriptor descriptor) {
0110:                    fDescriptor = descriptor;
0111:                }
0112:
0113:                public RefactoringStatus validateClassName() {
0114:                    RefactoringStatus status = new RefactoringStatus();
0115:                    status.merge(Checks.checkTypeName(fDescriptor
0116:                            .getClassName(), fDescriptor.getType()));
0117:                    status.merge(checkClass());
0118:                    return status;
0119:                }
0120:
0121:                private RefactoringStatus checkClass() {
0122:                    RefactoringStatus status = new RefactoringStatus();
0123:                    IType type = fDescriptor.getType();
0124:                    if (!fDescriptor.isCreateTopLevel()) {
0125:                        if (type.getType(fDescriptor.getClassName()).exists()) {
0126:                            status
0127:                                    .addError(Messages
0128:                                            .format(
0129:                                                    RefactoringCoreMessages.ExtractClassRefactoring_errror_nested_name_clash,
0130:                                                    new Object[] {
0131:                                                            fDescriptor
0132:                                                                    .getClassName(),
0133:                                                            type
0134:                                                                    .getElementName() }));
0135:                        }
0136:                    } else {
0137:                        status.merge(checkPackageClass());
0138:                    }
0139:                    return status;
0140:                }
0141:
0142:                private RefactoringStatus checkPackageClass() {
0143:                    RefactoringStatus status = new RefactoringStatus();
0144:                    IType type = fDescriptor.getType();
0145:                    IPackageFragmentRoot ancestor = (IPackageFragmentRoot) type
0146:                            .getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
0147:                    IPackageFragment packageFragment = ancestor
0148:                            .getPackageFragment(fDescriptor.getPackage());
0149:                    if (packageFragment.getCompilationUnit(
0150:                            fDescriptor.getClassName()
0151:                                    + JavaModelUtil.DEFAULT_CU_SUFFIX).exists())
0152:                        status
0153:                                .addError(Messages
0154:                                        .format(
0155:                                                RefactoringCoreMessages.ExtractClassRefactoring_error_toplevel_name_clash,
0156:                                                new Object[] {
0157:                                                        fDescriptor
0158:                                                                .getClassName(),
0159:                                                        fDescriptor
0160:                                                                .getPackage() }));
0161:                    return status;
0162:                }
0163:
0164:                public RefactoringStatus validateTopLevel() {
0165:                    return checkClass();
0166:                }
0167:
0168:                public RefactoringStatus validateParameterName() {
0169:                    RefactoringStatus status = new RefactoringStatus();
0170:                    String parameterName = fDescriptor.getFieldName();
0171:                    IType type = fDescriptor.getType();
0172:                    status.merge(Checks.checkFieldName(parameterName, type));
0173:                    validateFieldNames(status, parameterName, type);
0174:                    return status;
0175:                }
0176:
0177:                private void validateFieldNames(RefactoringStatus status,
0178:                        String parameterName, IType type) {
0179:                    if (type.getField(parameterName).exists()) {
0180:                        Field[] fields = fDescriptor.getFields();
0181:                        for (int i = 0; i < fields.length; i++) {
0182:                            Field field = fields[i];
0183:                            if (parameterName.equals(field.getFieldName())) {
0184:                                if (!field.isCreateField())
0185:                                    status
0186:                                            .addError(Messages
0187:                                                    .format(
0188:                                                            RefactoringCoreMessages.ExtractClassRefactoring_error_field_already_exists,
0189:                                                            parameterName));
0190:                            }
0191:                        }
0192:                    }
0193:                }
0194:
0195:                public RefactoringStatus validateFields() {
0196:                    RefactoringStatus status = new RefactoringStatus();
0197:                    Field[] fields = fDescriptor.getFields();
0198:                    Set names = new HashSet();
0199:                    for (int i = 0; i < fields.length; i++) {
0200:                        Field field = fields[i];
0201:                        if (field.isCreateField()) {
0202:                            if (names.contains(field.getNewFieldName())) {
0203:                                status
0204:                                        .addError(Messages
0205:                                                .format(
0206:                                                        RefactoringCoreMessages.ExtractClassRefactoring_error_duplicate_field_name,
0207:                                                        field.getNewFieldName()));
0208:                            }
0209:                            names.add(field.getNewFieldName());
0210:                            status.merge(Checks.checkFieldName(field
0211:                                    .getNewFieldName(), fDescriptor.getType()));
0212:                        }
0213:                    }
0214:                    if (names.size() == 0) {
0215:                        status
0216:                                .addError(RefactoringCoreMessages.ExtractClassRefactoring_error_msg_one_field);
0217:                    }
0218:                    validateFieldNames(status, fDescriptor.getFieldName(),
0219:                            fDescriptor.getType());
0220:                    return status;
0221:                }
0222:
0223:                public RefactoringStatus validateAll() {
0224:                    RefactoringStatus status = new RefactoringStatus();
0225:                    status.merge(validateClassName()); //also validates toplevel
0226:                    status.merge(validateFields());
0227:                    status.merge(validateParameterName());
0228:                    return status;
0229:                }
0230:            }
0231:
0232:            private final class FieldReferenceFinder extends ASTVisitor {
0233:                public boolean fFieldRefFound = false;
0234:
0235:                private FieldReferenceFinder() {
0236:                }
0237:
0238:                public boolean visit(FieldAccess node) {
0239:                    IVariableBinding fieldBinding = node.resolveFieldBinding();
0240:                    return checkVariableBinding(fieldBinding);
0241:                }
0242:
0243:                public boolean visit(SimpleName node) {
0244:                    IVariableBinding variableBinding = ASTNodes
0245:                            .getVariableBinding(node);
0246:                    return checkVariableBinding(variableBinding);
0247:                }
0248:
0249:                private boolean checkVariableBinding(
0250:                        IVariableBinding fieldBinding) {
0251:                    if (fieldBinding != null) {
0252:                        if (fieldBinding.isField()) {
0253:                            ITypeBinding declaringClass = fieldBinding
0254:                                    .getDeclaringClass();
0255:                            if ((declaringClass != null)
0256:                                    && declaringClass
0257:                                            .getQualifiedName()
0258:                                            .equals(
0259:                                                    fDescriptor
0260:                                                            .getType()
0261:                                                            .getFullyQualifiedName())) {
0262:                                FieldInfo fi = (FieldInfo) fVariables
0263:                                        .get(fieldBinding.getName());
0264:                                if (fi != null
0265:                                        && isCreateField(fi)
0266:                                        && Bindings.equals(fieldBinding, fi.pi
0267:                                                .getOldBinding())) {
0268:                                    fFieldRefFound = true;
0269:                                    return false;
0270:                                }
0271:                            }
0272:                        }
0273:                    }
0274:                    return true;
0275:                }
0276:            }
0277:
0278:            private final class FieldInfo {
0279:                ParameterInfo pi;
0280:                VariableDeclarationFragment declaration;
0281:                IField ifield;
0282:                String name;
0283:                Expression initializer;
0284:                private Boolean hasFieldReferences = null;
0285:
0286:                public boolean hasFieldReference() {
0287:                    if (hasFieldReferences == null) {
0288:                        if (initializer != null) {
0289:                            FieldReferenceFinder frf = new FieldReferenceFinder();
0290:                            initializer.accept(frf);
0291:                            hasFieldReferences = Boolean
0292:                                    .valueOf(frf.fFieldRefFound);
0293:                        } else {
0294:                            hasFieldReferences = Boolean.FALSE;
0295:                        }
0296:                    }
0297:                    return hasFieldReferences.booleanValue();
0298:                }
0299:
0300:                private FieldInfo(ParameterInfo parameterInfo, IField ifield) {
0301:                    super ();
0302:                    this .pi = parameterInfo;
0303:                    this .ifield = ifield;
0304:                    this .name = ifield.getElementName();
0305:                }
0306:            }
0307:
0308:            private ExtractClassDescriptor fDescriptor;
0309:            private Map fVariables;
0310:            private CompilationUnitRewrite fBaseCURewrite;
0311:            private TextChangeManager fChangeManager;
0312:            private ParameterObjectFactory fParameterObjectFactory;
0313:            private ExtractClassDescriptorVerification fVerification;
0314:
0315:            public ExtractClassRefactoring(ExtractClassDescriptor descriptor) {
0316:                fDescriptor = descriptor;
0317:                IType type = fDescriptor.getType();
0318:                if (fDescriptor.getPackage() == null) {
0319:                    fDescriptor.setPackage(type.getPackageFragment()
0320:                            .getElementName());
0321:                }
0322:                if (fDescriptor.getClassName() == null) {
0323:                    fDescriptor.setClassName(type.getElementName() + "Data"); //$NON-NLS-1$
0324:                }
0325:                if (fDescriptor.getFieldName() == null) {
0326:                    fDescriptor.setFieldName(StubUtility
0327:                            .getVariableNameSuggestions(
0328:                                    StubUtility.INSTANCE_FIELD, type
0329:                                            .getJavaProject(),
0330:                                    "data", 0, null, true)[0]); //$NON-NLS-1$
0331:                }
0332:                if (fDescriptor.getFields() == null) {
0333:                    try {
0334:                        fDescriptor.setFields(ExtractClassDescriptor
0335:                                .getFields(type));
0336:                    } catch (JavaModelException e) {
0337:                        JavaPlugin.log(e);
0338:                    }
0339:                }
0340:                fVerification = new ExtractClassDescriptorVerification(
0341:                        descriptor);
0342:            }
0343:
0344:            public RefactoringStatus checkInitialConditions(IProgressMonitor pm)
0345:                    throws CoreException, OperationCanceledException {
0346:                RefactoringStatus result = new RefactoringStatus();
0347:                pm
0348:                        .beginTask(
0349:                                RefactoringCoreMessages.ExtractClassRefactoring_progress_msg_check_initial_condition,
0350:                                5);
0351:                try {
0352:                    result.merge(fDescriptor.validateDescriptor());
0353:                    if (!result.isOK())
0354:                        return result;
0355:                    IType type = fDescriptor.getType();
0356:                    result.merge(Checks.checkAvailability(type));
0357:                    if (!result.isOK())
0358:                        return result;
0359:                    pm.worked(1);
0360:                    Field[] fields = ExtractClassDescriptor
0361:                            .getFields(fDescriptor.getType());
0362:                    pm.worked(1);
0363:                    if (pm.isCanceled())
0364:                        throw new OperationCanceledException();
0365:                    fVariables = new LinkedHashMap();
0366:                    if (fields.length == 0) {
0367:                        result
0368:                                .addFatalError(
0369:                                        RefactoringCoreMessages.ExtractClassRefactoring_error_no_usable_fields,
0370:                                        JavaStatusContext.create(type));
0371:                        return result;
0372:                    }
0373:                    for (int i = 0; i < fields.length; i++) {
0374:                        Field field = fields[i];
0375:                        String fieldName = field.getFieldName();
0376:                        IField declField = type.getField(fieldName);
0377:                        ParameterInfo info = new ParameterInfo(Signature
0378:                                .toString(declField.getTypeSignature()),
0379:                                fieldName, i);
0380:                        fVariables.put(fieldName,
0381:                                new FieldInfo(info, declField));
0382:                        if (pm.isCanceled())
0383:                            throw new OperationCanceledException();
0384:                    }
0385:                    pm.worked(3);
0386:                } finally {
0387:                    pm.done();
0388:                }
0389:                return result;
0390:            }
0391:
0392:            public RefactoringStatus checkFinalConditions(IProgressMonitor pm)
0393:                    throws CoreException, OperationCanceledException {
0394:                RefactoringStatus result = new RefactoringStatus();
0395:                result.merge(fVerification.validateAll());
0396:                try {
0397:                    pm
0398:                            .beginTask(
0399:                                    RefactoringCoreMessages.ExtractClassRefactoring_progress_final_conditions,
0400:                                    95);
0401:                    for (Iterator iter = fVariables.values().iterator(); iter
0402:                            .hasNext();) {
0403:                        FieldInfo fi = (FieldInfo) iter.next();
0404:                        boolean createField = isCreateField(fi);
0405:                        if (createField) {
0406:                            IField field = fi.ifield;
0407:                            int flags = field.getFlags();
0408:                            if (Flags.isStatic(flags)) {
0409:                                result
0410:                                        .addFatalError(
0411:                                                Messages
0412:                                                        .format(
0413:                                                                RefactoringCoreMessages.ExtractClassRefactoring_error_field_is_static,
0414:                                                                field
0415:                                                                        .getElementName()),
0416:                                                JavaStatusContext.create(field));
0417:                                return result;
0418:                            }
0419:                            if (Flags.isTransient(flags)) {
0420:                                result
0421:                                        .addWarning(
0422:                                                Messages
0423:                                                        .format(
0424:                                                                RefactoringCoreMessages.ExtractClassRefactoring_warning_field_is_transient,
0425:                                                                field
0426:                                                                        .getElementName()),
0427:                                                JavaStatusContext.create(field));
0428:                            }
0429:                            if (Flags.isVolatile(flags)) {
0430:                                result
0431:                                        .addWarning(
0432:                                                Messages
0433:                                                        .format(
0434:                                                                RefactoringCoreMessages.ExtractClassRefactoring_warning_field_is_volatile,
0435:                                                                field
0436:                                                                        .getElementName()),
0437:                                                JavaStatusContext.create(field));
0438:                            }
0439:                        }
0440:                    }
0441:                    pm.worked(5);
0442:                    fChangeManager = new TextChangeManager();
0443:                    fParameterObjectFactory = initializeFactory();
0444:                    IType type = fDescriptor.getType();
0445:                    pm.worked(5);
0446:
0447:                    FieldDeclaration field = performFieldRewrite(type,
0448:                            fParameterObjectFactory, result);
0449:                    int flags = RefactoringDescriptor.STRUCTURAL_CHANGE
0450:                            | JavaRefactoringDescriptor.JAR_MIGRATION
0451:                            | JavaRefactoringDescriptor.JAR_REFACTORING
0452:                            | JavaRefactoringDescriptor.JAR_SOURCE_ATTACHMENT;
0453:                    if (!Modifier.isPrivate(field.getModifiers()))
0454:                        flags |= RefactoringDescriptor.MULTI_CHANGE;
0455:
0456:                    result.merge(updateReferences(type,
0457:                            fParameterObjectFactory, new SubProgressMonitor(pm,
0458:                                    65)));
0459:
0460:                } finally {
0461:                    pm.done();
0462:                }
0463:                return result;
0464:            }
0465:
0466:            public Change createChange(IProgressMonitor pm)
0467:                    throws CoreException, OperationCanceledException {
0468:                pm
0469:                        .beginTask(
0470:                                RefactoringCoreMessages.ExtractClassRefactoring_progress_create_change,
0471:                                10);
0472:                try {
0473:                    ICompilationUnit typeCU = fDescriptor.getType()
0474:                            .getCompilationUnit();
0475:                    IPackageFragmentRoot packageRoot = (IPackageFragmentRoot) typeCU
0476:                            .getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
0477:                    ArrayList changes = new ArrayList();
0478:
0479:                    changes.addAll(createParameterObject(
0480:                            fParameterObjectFactory, packageRoot));
0481:                    fChangeManager.manage(typeCU, fBaseCURewrite.createChange(
0482:                            true, pm));
0483:                    changes.addAll(Arrays
0484:                            .asList(fChangeManager.getAllChanges()));
0485:                    String project = fDescriptor.getType().getJavaProject()
0486:                            .getElementName();
0487:                    fDescriptor.setProject(project);
0488:                    fDescriptor.setDescription(getName());
0489:                    fDescriptor.setComment(createComment());
0490:                    DynamicValidationRefactoringChange change = new DynamicValidationRefactoringChange(
0491:                            fDescriptor,
0492:                            RefactoringCoreMessages.ExtractClassRefactoring_change_name,
0493:                            (Change[]) changes.toArray(new Change[changes
0494:                                    .size()]));
0495:                    return change;
0496:                } finally {
0497:                    pm.done();
0498:                }
0499:            }
0500:
0501:            private String createComment() {
0502:                String header = Messages
0503:                        .format(
0504:                                RefactoringCoreMessages.ExtractClassRefactoring_change_comment_header,
0505:                                new Object[] { fDescriptor.getClassName(),
0506:                                        fDescriptor.getType().getElementName() });
0507:                JDTRefactoringDescriptorComment comment = new JDTRefactoringDescriptorComment(
0508:                        fDescriptor.getType().getJavaProject().getElementName(),
0509:                        this , header);
0510:                comment
0511:                        .addSetting(Messages
0512:                                .format(
0513:                                        RefactoringCoreMessages.ExtractClassRefactoring_comment_extracted_class,
0514:                                        fDescriptor.getClassName()));
0515:
0516:                if (fDescriptor.isCreateTopLevel())
0517:                    comment
0518:                            .addSetting(Messages
0519:                                    .format(
0520:                                            RefactoringCoreMessages.ExtractClassRefactoring_comment_package,
0521:                                            fDescriptor.getPackage()));
0522:
0523:                Field[] fields = fDescriptor.getFields();
0524:                ArrayList strings = new ArrayList();
0525:                for (int i = 0; i < fields.length; i++) {
0526:                    Field field = fields[i];
0527:                    if (field.isCreateField()) {
0528:                        strings
0529:                                .add(Messages
0530:                                        .format(
0531:                                                RefactoringCoreMessages.ExtractClassRefactoring_comment_field_renamed,
0532:                                                new Object[] {
0533:                                                        field.getFieldName(),
0534:                                                        field.getNewFieldName() }));
0535:                    }
0536:                }
0537:                String fieldString = JDTRefactoringDescriptorComment
0538:                        .createCompositeSetting(
0539:                                RefactoringCoreMessages.ExtractClassRefactoring_comment_move_field,
0540:                                (String[]) strings.toArray(new String[strings
0541:                                        .size()]));
0542:                comment.addSetting(fieldString);
0543:
0544:                if (fDescriptor.isCreateGetterSetter())
0545:                    comment
0546:                            .addSetting(RefactoringCoreMessages.ExtractClassRefactoring_comment_getters);
0547:
0548:                comment
0549:                        .addSetting(Messages
0550:                                .format(
0551:                                        RefactoringCoreMessages.ExtractClassRefactoring_comment_fieldname,
0552:                                        fDescriptor.getFieldName()));
0553:                return comment.asString();
0554:            }
0555:
0556:            private class FieldUpdate extends CreationListener {
0557:                public void fieldCreated(CompilationUnitRewrite cuRewrite,
0558:                        FieldDeclaration field, ParameterInfo pi) {
0559:                    FieldInfo fieldInfo = getFieldInfo(pi.getOldName());
0560:                    FieldDeclaration parent = (FieldDeclaration) fieldInfo.declaration
0561:                            .getParent();
0562:                    List modifiers = parent.modifiers();
0563:                    ListRewrite listRewrite = cuRewrite.getASTRewrite()
0564:                            .getListRewrite(field,
0565:                                    FieldDeclaration.MODIFIERS2_PROPERTY);
0566:                    for (Iterator iterator = modifiers.iterator(); iterator
0567:                            .hasNext();) {
0568:                        IExtendedModifier mod = (IExtendedModifier) iterator
0569:                                .next();
0570:                        //Temporarily disabled until initialization of final fields is handled correctly
0571:                        //				if (mod.isModifier()) {
0572:                        //					Modifier modifier= (Modifier) mod;
0573:                        //					if (modifier.isFinal())
0574:                        //						listRewrite.insertLast(moveNode(cuRewrite, modifier), null);
0575:                        //				}
0576:                        if (mod.isAnnotation()) {
0577:                            listRewrite.insertFirst(moveNode(cuRewrite,
0578:                                    (ASTNode) mod), null);
0579:                        }
0580:                    }
0581:                    if (fieldInfo.initializer != null
0582:                            && fieldInfo.hasFieldReference()) {
0583:                        List fragments = field.fragments();
0584:                        for (Iterator iterator = fragments.iterator(); iterator
0585:                                .hasNext();) {
0586:                            VariableDeclarationFragment vdf = (VariableDeclarationFragment) iterator
0587:                                    .next();
0588:                            vdf.setInitializer((Expression) moveNode(cuRewrite,
0589:                                    fieldInfo.initializer));
0590:                        }
0591:                    }
0592:                    if (parent.getJavadoc() != null) {
0593:                        field.setJavadoc((Javadoc) moveNode(cuRewrite, parent
0594:                                .getJavadoc()));
0595:                    }
0596:                }
0597:
0598:                public boolean isCreateSetter(ParameterInfo pi) {
0599:                    return true; //ignore that the original variable was final
0600:                }
0601:
0602:                public boolean isUseInConstructor(ParameterInfo pi) {
0603:                    FieldInfo fi = getFieldInfo(pi.getOldName());
0604:                    return fi.initializer != null && !fi.hasFieldReference();
0605:                }
0606:            }
0607:
0608:            private List createParameterObject(ParameterObjectFactory pof,
0609:                    IPackageFragmentRoot packageRoot) throws CoreException {
0610:                FieldUpdate fieldUpdate = new FieldUpdate();
0611:                if (fDescriptor.isCreateTopLevel())
0612:                    return pof.createTopLevelParameterObject(packageRoot,
0613:                            fieldUpdate);
0614:                else {
0615:                    CompilationUnit root = fBaseCURewrite.getRoot();
0616:                    TypeDeclaration typeDecl = (TypeDeclaration) NodeFinder
0617:                            .perform(root, fDescriptor.getType()
0618:                                    .getSourceRange());
0619:                    ASTRewrite rewrite = fBaseCURewrite.getASTRewrite();
0620:                    ListRewrite listRewrite = rewrite.getListRewrite(typeDecl,
0621:                            TypeDeclaration.BODY_DECLARATIONS_PROPERTY);
0622:                    TypeDeclaration paramClass = pof.createClassDeclaration(
0623:                            typeDecl.getName().getFullyQualifiedName(),
0624:                            fBaseCURewrite, fieldUpdate);
0625:                    paramClass.modifiers().add(
0626:                            rewrite.getAST().newModifier(
0627:                                    ModifierKeyword.PUBLIC_KEYWORD));
0628:                    paramClass.modifiers().add(
0629:                            rewrite.getAST().newModifier(
0630:                                    ModifierKeyword.STATIC_KEYWORD));
0631:                    listRewrite
0632:                            .insertFirst(
0633:                                    paramClass,
0634:                                    fBaseCURewrite
0635:                                            .createGroupDescription(RefactoringCoreMessages.ExtractClassRefactoring_group_insert_parameter));
0636:                    return new ArrayList(); //Change will be generated later for fBaseCURewrite
0637:                }
0638:
0639:            }
0640:
0641:            private ParameterObjectFactory initializeFactory() {
0642:                ParameterObjectFactory pof = new ParameterObjectFactory();
0643:                pof.setClassName(fDescriptor.getClassName());
0644:                pof.setPackage(fDescriptor.getPackage());
0645:                pof.setEnclosingType(fDescriptor.getType()
0646:                        .getFullyQualifiedName());
0647:                pof.setCreateGetter(fDescriptor.isCreateGetterSetter());
0648:                pof.setCreateSetter(fDescriptor.isCreateGetterSetter());
0649:                List variables = new ArrayList();
0650:                for (Iterator iterator = fVariables.values().iterator(); iterator
0651:                        .hasNext();) {
0652:                    FieldInfo info = (FieldInfo) iterator.next();
0653:                    boolean createField = isCreateField(info);
0654:                    info.pi.setCreateField(createField);
0655:                    if (createField) {
0656:                        Field field = getField(info.name);
0657:                        info.pi.setNewName(field.getNewFieldName());
0658:                    }
0659:                    variables.add(info.pi);
0660:                }
0661:                pof.setVariables(variables);
0662:                return pof;
0663:            }
0664:
0665:            private Field getField(String name) {
0666:                Field[] fields = fDescriptor.getFields();
0667:                for (int i = 0; i < fields.length; i++) {
0668:                    Field field = fields[i];
0669:                    if (field.getFieldName().equals(name))
0670:                        return field;
0671:                }
0672:                return null;
0673:            }
0674:
0675:            private RefactoringStatus updateReferences(IType type,
0676:                    ParameterObjectFactory pof, IProgressMonitor pm)
0677:                    throws CoreException {
0678:                RefactoringStatus status = new RefactoringStatus();
0679:                pm
0680:                        .beginTask(
0681:                                RefactoringCoreMessages.ExtractClassRefactoring_progress_updating_references,
0682:                                100);
0683:                try {
0684:                    pm.worked(10);
0685:                    if (pm.isCanceled())
0686:                        throw new OperationCanceledException();
0687:                    List validIFields = new ArrayList();
0688:                    for (Iterator iterator = fVariables.values().iterator(); iterator
0689:                            .hasNext();) {
0690:                        FieldInfo info = (FieldInfo) iterator.next();
0691:                        if (isCreateField(info))
0692:                            validIFields.add(info.ifield);
0693:                    }
0694:                    if (validIFields.size() == 0) {
0695:                        status
0696:                                .addWarning(
0697:                                        RefactoringCoreMessages.ExtractClassRefactoring_warning_no_fields_moved,
0698:                                        JavaStatusContext.create(type));
0699:                        return status;
0700:                    }
0701:                    SearchPattern pattern = RefactoringSearchEngine
0702:                            .createOrPattern((IField[]) validIFields
0703:                                    .toArray(new IField[validIFields.size()]),
0704:                                    IJavaSearchConstants.ALL_OCCURRENCES);
0705:                    SearchResultGroup[] results = RefactoringSearchEngine
0706:                            .search(pattern, RefactoringScopeFactory
0707:                                    .create(type), pm, status);
0708:                    SubProgressMonitor spm = new SubProgressMonitor(pm, 90);
0709:                    spm
0710:                            .beginTask(
0711:                                    RefactoringCoreMessages.ExtractClassRefactoring_progress_updating_references,
0712:                                    results.length * 10);
0713:                    try {
0714:                        for (int i = 0; i < results.length; i++) {
0715:                            SearchResultGroup group = results[i];
0716:                            ICompilationUnit unit = group.getCompilationUnit();
0717:
0718:                            CompilationUnitRewrite cuRewrite;
0719:                            if (unit.equals(fBaseCURewrite.getCu()))
0720:                                cuRewrite = fBaseCURewrite;
0721:                            else
0722:                                cuRewrite = new CompilationUnitRewrite(unit);
0723:                            spm.worked(1);
0724:
0725:                            status.merge(replaceReferences(pof, group,
0726:                                    cuRewrite));
0727:                            if (cuRewrite != fBaseCURewrite) //Change for fBaseCURewrite will be generated later 
0728:                                fChangeManager
0729:                                        .manage(unit, cuRewrite.createChange(
0730:                                                true, new SubProgressMonitor(
0731:                                                        spm, 9)));
0732:                            if (spm.isCanceled())
0733:                                throw new OperationCanceledException();
0734:                        }
0735:                    } finally {
0736:                        spm.done();
0737:                    }
0738:                } finally {
0739:                    pm.done();
0740:                }
0741:                return status;
0742:            }
0743:
0744:            private RefactoringStatus replaceReferences(
0745:                    ParameterObjectFactory pof, SearchResultGroup group,
0746:                    CompilationUnitRewrite cuRewrite) {
0747:                TextEditGroup writeGroup = cuRewrite
0748:                        .createGroupDescription(RefactoringCoreMessages.ExtractClassRefactoring_group_replace_write);
0749:                TextEditGroup readGroup = cuRewrite
0750:                        .createGroupDescription(RefactoringCoreMessages.ExtractClassRefactoring_group_replace_read);
0751:                ITypeRoot typeRoot = cuRewrite.getCu();
0752:                IJavaProject javaProject = typeRoot.getJavaProject();
0753:                AST ast = cuRewrite.getAST();
0754:
0755:                RefactoringStatus status = new RefactoringStatus();
0756:                String parameterName = fDescriptor.getFieldName();
0757:
0758:                SearchMatch[] searchResults = group.getSearchResults();
0759:                for (int j = 0; j < searchResults.length; j++) {
0760:                    SearchMatch searchMatch = searchResults[j];
0761:                    ASTNode node = NodeFinder.perform(cuRewrite.getRoot(),
0762:                            searchMatch.getOffset(), searchMatch.getLength());
0763:                    ASTNode parent = node.getParent();
0764:                    boolean isDeclaration = parent instanceof  VariableDeclaration
0765:                            && ((VariableDeclaration) parent).getInitializer() != node;
0766:                    if (!isDeclaration && node instanceof  SimpleName) {
0767:                        ASTRewrite rewrite = cuRewrite.getASTRewrite();
0768:                        if (parent.getNodeType() == ASTNode.SWITCH_CASE)
0769:                            status
0770:                                    .addError(
0771:                                            RefactoringCoreMessages.ExtractClassRefactoring_error_switch,
0772:                                            JavaStatusContext.create(typeRoot,
0773:                                                    node));
0774:
0775:                        SimpleName name = (SimpleName) node;
0776:                        ParameterInfo pi = getFieldInfo(name.getIdentifier()).pi;
0777:                        boolean writeAccess = ASTResolving.isWriteAccess(name);
0778:                        if (writeAccess && fDescriptor.isCreateGetterSetter()) {
0779:                            boolean useSuper = parent.getNodeType() == ASTNode.SUPER_FIELD_ACCESS;
0780:                            Expression qualifier = getQualifier(parent);
0781:                            ASTNode replaceNode = getReplacementNode(parent,
0782:                                    useSuper, qualifier);
0783:                            Expression assignedValue = getAssignedValue(pof,
0784:                                    parameterName, javaProject, status,
0785:                                    rewrite, pi, useSuper, name
0786:                                            .resolveTypeBinding(), qualifier,
0787:                                    replaceNode, typeRoot);
0788:                            if (assignedValue == null) {
0789:                                status
0790:                                        .addError(
0791:                                                RefactoringCoreMessages.ExtractClassRefactoring_error_unable_to_convert_node,
0792:                                                JavaStatusContext.create(
0793:                                                        typeRoot, replaceNode));
0794:                            } else {
0795:                                NullLiteral marker = qualifier == null ? null
0796:                                        : ast.newNullLiteral();
0797:                                Expression access = pof.createFieldWriteAccess(
0798:                                        pi, parameterName, ast, javaProject,
0799:                                        assignedValue, useSuper, marker);
0800:                                replaceMarker(rewrite, qualifier, access,
0801:                                        marker);
0802:                                rewrite
0803:                                        .replace(replaceNode, access,
0804:                                                writeGroup);
0805:                            }
0806:                        } else {
0807:                            Expression fieldReadAccess = pof
0808:                                    .createFieldReadAccess(pi, parameterName,
0809:                                            ast, javaProject, false, null); //qualifier is already there
0810:                            rewrite.replace(name, fieldReadAccess, readGroup);
0811:                        }
0812:                    }
0813:                }
0814:                return status;
0815:            }
0816:
0817:            private Expression getAssignedValue(ParameterObjectFactory pof,
0818:                    String parameterName, IJavaProject javaProject,
0819:                    RefactoringStatus status, ASTRewrite rewrite,
0820:                    ParameterInfo pi, boolean useSuper,
0821:                    ITypeBinding typeBinding, Expression qualifier,
0822:                    ASTNode replaceNode, ITypeRoot typeRoot) {
0823:                AST ast = rewrite.getAST();
0824:                boolean is50OrHigher = JavaModelUtil.is50OrHigher(javaProject);
0825:                Expression assignedValue = handleSimpleNameAssignment(
0826:                        replaceNode, pof, parameterName, ast, javaProject,
0827:                        useSuper);
0828:                if (assignedValue == null) {
0829:                    NullLiteral marker = qualifier == null ? null : ast
0830:                            .newNullLiteral();
0831:                    Expression fieldReadAccess = pof.createFieldReadAccess(pi,
0832:                            parameterName, ast, javaProject, useSuper, marker);
0833:                    assignedValue = GetterSetterUtil.getAssignedValue(
0834:                            replaceNode, rewrite, fieldReadAccess, typeBinding,
0835:                            is50OrHigher);
0836:                    boolean markerReplaced = replaceMarker(rewrite, qualifier,
0837:                            assignedValue, marker);
0838:                    if (markerReplaced) {
0839:                        switch (qualifier.getNodeType()) {
0840:                        case ASTNode.METHOD_INVOCATION:
0841:                        case ASTNode.CLASS_INSTANCE_CREATION:
0842:                        case ASTNode.SUPER_METHOD_INVOCATION:
0843:                        case ASTNode.PARENTHESIZED_EXPRESSION:
0844:                            status
0845:                                    .addWarning(
0846:                                            RefactoringCoreMessages.ExtractClassRefactoring_warning_semantic_change,
0847:                                            JavaStatusContext.create(typeRoot,
0848:                                                    replaceNode));
0849:                            break;
0850:                        }
0851:                    }
0852:                }
0853:                return assignedValue;
0854:            }
0855:
0856:            private ASTNode getReplacementNode(ASTNode parent,
0857:                    boolean useSuper, Expression qualifier) {
0858:                if (qualifier != null || useSuper) {
0859:                    return parent.getParent();
0860:                } else {
0861:                    return parent;
0862:                }
0863:            }
0864:
0865:            private Expression getQualifier(ASTNode parent) {
0866:                switch (parent.getNodeType()) {
0867:                case ASTNode.FIELD_ACCESS:
0868:                    return ((FieldAccess) parent).getExpression();
0869:                case ASTNode.QUALIFIED_NAME:
0870:                    return ((QualifiedName) parent).getQualifier();
0871:                case ASTNode.SUPER_FIELD_ACCESS:
0872:                    return ((SuperFieldAccess) parent).getQualifier();
0873:                default:
0874:                    return null;
0875:                }
0876:            }
0877:
0878:            /*
0879:             * Replaces the NullLiteral dummy with the copied qualifier
0880:             */
0881:            private boolean replaceMarker(final ASTRewrite rewrite,
0882:                    final Expression qualifier, Expression assignedValue,
0883:                    final NullLiteral marker) {
0884:                class MarkerReplacer extends ASTVisitor {
0885:
0886:                    private boolean fReplaced = false;
0887:
0888:                    public boolean visit(NullLiteral node) {
0889:                        if (node == marker) {
0890:                            rewrite.replace(node, rewrite
0891:                                    .createCopyTarget(qualifier), null);
0892:                            fReplaced = true;
0893:                            return false;
0894:                        }
0895:                        return true;
0896:                    }
0897:                }
0898:                if (assignedValue != null && qualifier != null) {
0899:                    MarkerReplacer visitor = new MarkerReplacer();
0900:                    assignedValue.accept(visitor);
0901:                    return visitor.fReplaced;
0902:                }
0903:                return false;
0904:            }
0905:
0906:            private Expression handleSimpleNameAssignment(ASTNode replaceNode,
0907:                    ParameterObjectFactory pof, String parameterName, AST ast,
0908:                    IJavaProject javaProject, boolean useSuper) {
0909:                if (replaceNode instanceof  Assignment) {
0910:                    Assignment assignment = (Assignment) replaceNode;
0911:                    Expression rightHandSide = assignment.getRightHandSide();
0912:                    if (rightHandSide.getNodeType() == ASTNode.SIMPLE_NAME) {
0913:                        SimpleName sn = (SimpleName) rightHandSide;
0914:                        IVariableBinding binding = ASTNodes
0915:                                .getVariableBinding(sn);
0916:                        if (binding != null && binding.isField()) {
0917:                            if (fDescriptor.getType().getFullyQualifiedName()
0918:                                    .equals(
0919:                                            binding.getDeclaringClass()
0920:                                                    .getQualifiedName())) {
0921:                                FieldInfo fieldInfo = getFieldInfo(binding
0922:                                        .getName());
0923:                                if (fieldInfo != null
0924:                                        && binding == fieldInfo.pi
0925:                                                .getOldBinding()) {
0926:                                    return pof.createFieldReadAccess(
0927:                                            fieldInfo.pi, parameterName, ast,
0928:                                            javaProject, useSuper, null);
0929:                                }
0930:                            }
0931:                        }
0932:                    }
0933:                }
0934:                return null;
0935:            }
0936:
0937:            private FieldInfo getFieldInfo(String identifier) {
0938:                return (FieldInfo) fVariables.get(identifier);
0939:            }
0940:
0941:            private FieldDeclaration performFieldRewrite(IType type,
0942:                    ParameterObjectFactory pof, RefactoringStatus status)
0943:                    throws CoreException {
0944:                fBaseCURewrite = new CompilationUnitRewrite(type
0945:                        .getCompilationUnit());
0946:                SimpleName name = (SimpleName) NodeFinder.perform(
0947:                        fBaseCURewrite.getRoot(), type.getNameRange());
0948:                TypeDeclaration typeNode = (TypeDeclaration) ASTNodes
0949:                        .getParent(name, ASTNode.TYPE_DECLARATION);
0950:                ASTRewrite rewrite = fBaseCURewrite.getASTRewrite();
0951:                int modifier = Modifier.PRIVATE;
0952:                TextEditGroup removeFieldGroup = fBaseCURewrite
0953:                        .createGroupDescription(RefactoringCoreMessages.ExtractClassRefactoring_group_remove_field);
0954:                FieldDeclaration lastField = null;
0955:                initializeDeclaration(typeNode);
0956:                for (Iterator iter = fVariables.values().iterator(); iter
0957:                        .hasNext();) {
0958:                    FieldInfo pi = (FieldInfo) iter.next();
0959:                    if (isCreateField(pi)) {
0960:                        VariableDeclarationFragment vdf = pi.declaration;
0961:                        FieldDeclaration parent = (FieldDeclaration) vdf
0962:                                .getParent();
0963:                        if (lastField == null)
0964:                            lastField = parent;
0965:                        else if (lastField.getStartPosition() < parent
0966:                                .getStartPosition())
0967:                            lastField = parent;
0968:
0969:                        ListRewrite listRewrite = rewrite.getListRewrite(
0970:                                parent, FieldDeclaration.FRAGMENTS_PROPERTY);
0971:                        removeNode(vdf, removeFieldGroup, fBaseCURewrite);
0972:                        if (listRewrite.getRewrittenList().size() == 0) {
0973:                            removeNode(parent, removeFieldGroup, fBaseCURewrite);
0974:                        }
0975:
0976:                        if (fDescriptor.isCreateTopLevel()) {
0977:                            IVariableBinding binding = vdf.resolveBinding();
0978:                            ITypeRoot typeRoot = fBaseCURewrite.getCu();
0979:                            if (binding == null || binding.getType() == null) {
0980:                                status
0981:                                        .addFatalError(
0982:                                                Messages
0983:                                                        .format(
0984:                                                                RefactoringCoreMessages.ExtractClassRefactoring_fatal_error_cannot_resolve_binding,
0985:                                                                pi.name),
0986:                                                JavaStatusContext.create(
0987:                                                        typeRoot, vdf));
0988:                            } else {
0989:                                ITypeBinding typeBinding = binding.getType();
0990:                                if (Modifier.isPrivate(typeBinding
0991:                                        .getDeclaredModifiers())) {
0992:                                    status
0993:                                            .addError(
0994:                                                    Messages
0995:                                                            .format(
0996:                                                                    RefactoringCoreMessages.ExtractClassRefactoring_error_referencing_private_class,
0997:                                                                    typeBinding
0998:                                                                            .getName()),
0999:                                                    JavaStatusContext.create(
1000:                                                            typeRoot, vdf));
1001:                                } else if (Modifier.isProtected(typeBinding
1002:                                        .getDeclaredModifiers())) {
1003:                                    ITypeBinding declaringClass = typeBinding
1004:                                            .getDeclaringClass();
1005:                                    if (declaringClass != null) {
1006:                                        IPackageBinding package1 = declaringClass
1007:                                                .getPackage();
1008:                                        if (package1 != null
1009:                                                && !fDescriptor
1010:                                                        .getPackage()
1011:                                                        .equals(
1012:                                                                package1
1013:                                                                        .getName())) {
1014:                                            status
1015:                                                    .addError(
1016:                                                            Messages
1017:                                                                    .format(
1018:                                                                            RefactoringCoreMessages.ExtractClassRefactoring_error_referencing_protected_class,
1019:                                                                            new String[] {
1020:                                                                                    typeBinding
1021:                                                                                            .getName(),
1022:                                                                                    fDescriptor
1023:                                                                                            .getPackage() }),
1024:                                                            JavaStatusContext
1025:                                                                    .create(
1026:                                                                            typeRoot,
1027:                                                                            vdf));
1028:                                        }
1029:                                    }
1030:                                }
1031:                            }
1032:                        }
1033:                        Expression initializer = vdf.getInitializer();
1034:                        if (initializer != null)
1035:                            pi.initializer = initializer;
1036:                        int modifiers = parent.getModifiers();
1037:                        if (!MemberVisibilityAdjustor.hasLowerVisibility(
1038:                                modifiers, modifier)) {
1039:                            modifier = modifiers;
1040:                        }
1041:                    }
1042:                }
1043:                FieldDeclaration fieldDeclaration = createParameterObjectField(
1044:                        pof, typeNode, modifier);
1045:                ListRewrite bodyDeclList = rewrite.getListRewrite(typeNode,
1046:                        TypeDeclaration.BODY_DECLARATIONS_PROPERTY);
1047:                if (lastField != null)
1048:                    bodyDeclList.insertAfter(fieldDeclaration, lastField, null);
1049:                else
1050:                    bodyDeclList.insertFirst(fieldDeclaration, null);
1051:                return fieldDeclaration;
1052:            }
1053:
1054:            private void initializeDeclaration(TypeDeclaration node) {
1055:                FieldDeclaration[] fields = node.getFields();
1056:                for (int i = 0; i < fields.length; i++) {
1057:                    FieldDeclaration fieldDeclaration = fields[i];
1058:                    List fragments = fieldDeclaration.fragments();
1059:                    for (Iterator iterator = fragments.iterator(); iterator
1060:                            .hasNext();) {
1061:                        VariableDeclarationFragment vdf = (VariableDeclarationFragment) iterator
1062:                                .next();
1063:                        FieldInfo fieldInfo = getFieldInfo(vdf.getName()
1064:                                .getIdentifier());
1065:                        if (fieldInfo != null) {
1066:                            Assert.isNotNull(vdf);
1067:                            fieldInfo.declaration = vdf;
1068:                            fieldInfo.pi.setOldBinding(vdf.resolveBinding());
1069:                        }
1070:                    }
1071:                }
1072:            }
1073:
1074:            private void removeNode(ASTNode parent,
1075:                    TextEditGroup removeFieldGroup,
1076:                    CompilationUnitRewrite baseCURewrite) {
1077:                baseCURewrite.getASTRewrite().remove(parent, removeFieldGroup);
1078:                baseCURewrite.getImportRemover().registerRemovedNode(parent);
1079:            }
1080:
1081:            private FieldDeclaration createParameterObjectField(
1082:                    ParameterObjectFactory pof, TypeDeclaration typeNode,
1083:                    int modifier) {
1084:                AST ast = fBaseCURewrite.getAST();
1085:                ClassInstanceCreation creation = ast.newClassInstanceCreation();
1086:                creation.setType(pof.createType(fDescriptor.isCreateTopLevel(),
1087:                        fBaseCURewrite, typeNode.getStartPosition()));
1088:                ListRewrite listRewrite = fBaseCURewrite.getASTRewrite()
1089:                        .getListRewrite(creation,
1090:                                ClassInstanceCreation.ARGUMENTS_PROPERTY);
1091:                for (Iterator iter = fVariables.values().iterator(); iter
1092:                        .hasNext();) {
1093:                    FieldInfo fi = (FieldInfo) iter.next();
1094:                    if (isCreateField(fi)) {
1095:                        Expression expression = fi.initializer;
1096:                        if (expression != null && !fi.hasFieldReference()) {
1097:                            importNodeTypes(expression, fBaseCURewrite);
1098:                            ASTNode createMoveTarget = fBaseCURewrite
1099:                                    .getASTRewrite().createMoveTarget(
1100:                                            expression);
1101:                            if (expression instanceof  ArrayInitializer) {
1102:                                ArrayInitializer ai = (ArrayInitializer) expression;
1103:                                ITypeBinding componentType = ai
1104:                                        .resolveTypeBinding()
1105:                                        .getComponentType();
1106:                                ArrayCreation arrayCreation = ast
1107:                                        .newArrayCreation();
1108:                                Type addImport = fBaseCURewrite
1109:                                        .getImportRewrite().addImport(
1110:                                                componentType, ast);
1111:                                fBaseCURewrite.getImportRemover()
1112:                                        .registerAddedImports(addImport);
1113:                                arrayCreation.setType(ast
1114:                                        .newArrayType(addImport));
1115:                                arrayCreation
1116:                                        .setInitializer((ArrayInitializer) createMoveTarget);
1117:                                listRewrite.insertLast(arrayCreation, null);
1118:                            } else {
1119:                                listRewrite.insertLast(createMoveTarget, null);
1120:                            }
1121:                        }
1122:                    }
1123:                }
1124:
1125:                VariableDeclarationFragment fragment = ast
1126:                        .newVariableDeclarationFragment();
1127:                fragment.setName(ast.newSimpleName(fDescriptor.getFieldName()));
1128:                fragment.setInitializer(creation);
1129:
1130:                ModifierKeyword acc = null;
1131:                if (Modifier.isPublic(modifier)) {
1132:                    acc = ModifierKeyword.PUBLIC_KEYWORD;
1133:                } else if (Modifier.isProtected(modifier)) {
1134:                    acc = ModifierKeyword.PROTECTED_KEYWORD;
1135:                } else if (Modifier.isPrivate(modifier)) {
1136:                    acc = ModifierKeyword.PRIVATE_KEYWORD;
1137:                }
1138:
1139:                FieldDeclaration fieldDeclaration = ast
1140:                        .newFieldDeclaration(fragment);
1141:                fieldDeclaration.setType(pof.createType(fDescriptor
1142:                        .isCreateTopLevel(), fBaseCURewrite, typeNode
1143:                        .getStartPosition()));
1144:                if (acc != null)
1145:                    fieldDeclaration.modifiers().add(ast.newModifier(acc));
1146:                return fieldDeclaration;
1147:            }
1148:
1149:            private void importNodeTypes(ASTNode node,
1150:                    final CompilationUnitRewrite cuRewrite) {
1151:                ASTResolving.visitAllBindings(node, new TypeBindingVisitor() {
1152:                    public boolean visit(ITypeBinding nodeBinding) {
1153:                        ParameterObjectFactory.importBinding(nodeBinding,
1154:                                cuRewrite);
1155:                        return false;
1156:                    }
1157:                });
1158:            }
1159:
1160:            private boolean isCreateField(FieldInfo fi) {
1161:                return getField(fi.name).isCreateField();
1162:            }
1163:
1164:            public String getName() {
1165:                return RefactoringCoreMessages.ExtractClassRefactoring_refactoring_name;
1166:            }
1167:
1168:            /* (non-Javadoc)
1169:             * @see org.eclipse.ltk.core.refactoring.Refactoring#getAdapter(java.lang.Class)
1170:             */
1171:            public Object getAdapter(Class adapter) {
1172:                if (adapter == ExtractClassDescriptorVerification.class) {
1173:                    return fVerification;
1174:                }
1175:                return super.getAdapter(adapter);
1176:            }
1177:        }
ww_w._j___a__v__a2_s.co__m_ | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.