Source Code Cross Referenced for MoveStaticMembersProcessor.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) 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:         *******************************************************************************/package org.eclipse.jdt.internal.corext.refactoring.structure;
0011:
0012:        import java.util.ArrayList;
0013:        import java.util.Arrays;
0014:        import java.util.Collections;
0015:        import java.util.Comparator;
0016:        import java.util.HashMap;
0017:        import java.util.HashSet;
0018:        import java.util.Iterator;
0019:        import java.util.List;
0020:        import java.util.Map;
0021:        import java.util.Set;
0022:
0023:        import org.eclipse.text.edits.TextEdit;
0024:        import org.eclipse.text.edits.TextEditGroup;
0025:
0026:        import org.eclipse.core.runtime.Assert;
0027:        import org.eclipse.core.runtime.CoreException;
0028:        import org.eclipse.core.runtime.IProgressMonitor;
0029:        import org.eclipse.core.runtime.NullProgressMonitor;
0030:        import org.eclipse.core.runtime.SubProgressMonitor;
0031:
0032:        import org.eclipse.core.resources.IFile;
0033:        import org.eclipse.core.resources.IResource;
0034:
0035:        import org.eclipse.jface.text.BadLocationException;
0036:        import org.eclipse.jface.text.Document;
0037:        import org.eclipse.jface.text.IDocument;
0038:
0039:        import org.eclipse.ltk.core.refactoring.Change;
0040:        import org.eclipse.ltk.core.refactoring.CompositeChange;
0041:        import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
0042:        import org.eclipse.ltk.core.refactoring.RefactoringStatus;
0043:        import org.eclipse.ltk.core.refactoring.RefactoringStatusContext;
0044:        import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
0045:        import org.eclipse.ltk.core.refactoring.participants.MoveArguments;
0046:        import org.eclipse.ltk.core.refactoring.participants.MoveProcessor;
0047:        import org.eclipse.ltk.core.refactoring.participants.ParticipantManager;
0048:        import org.eclipse.ltk.core.refactoring.participants.RefactoringArguments;
0049:        import org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant;
0050:        import org.eclipse.ltk.core.refactoring.participants.ResourceChangeChecker;
0051:        import org.eclipse.ltk.core.refactoring.participants.SharableParticipants;
0052:
0053:        import org.eclipse.jdt.core.Flags;
0054:        import org.eclipse.jdt.core.ICompilationUnit;
0055:        import org.eclipse.jdt.core.IField;
0056:        import org.eclipse.jdt.core.IInitializer;
0057:        import org.eclipse.jdt.core.IJavaElement;
0058:        import org.eclipse.jdt.core.IJavaProject;
0059:        import org.eclipse.jdt.core.IMember;
0060:        import org.eclipse.jdt.core.IMethod;
0061:        import org.eclipse.jdt.core.ISourceRange;
0062:        import org.eclipse.jdt.core.IType;
0063:        import org.eclipse.jdt.core.JavaModelException;
0064:        import org.eclipse.jdt.core.dom.ASTNode;
0065:        import org.eclipse.jdt.core.dom.ASTVisitor;
0066:        import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
0067:        import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
0068:        import org.eclipse.jdt.core.dom.BodyDeclaration;
0069:        import org.eclipse.jdt.core.dom.EnumDeclaration;
0070:        import org.eclipse.jdt.core.dom.FieldDeclaration;
0071:        import org.eclipse.jdt.core.dom.IBinding;
0072:        import org.eclipse.jdt.core.dom.IMethodBinding;
0073:        import org.eclipse.jdt.core.dom.ITypeBinding;
0074:        import org.eclipse.jdt.core.dom.IVariableBinding;
0075:        import org.eclipse.jdt.core.dom.MethodDeclaration;
0076:        import org.eclipse.jdt.core.dom.Modifier;
0077:        import org.eclipse.jdt.core.dom.SimpleName;
0078:        import org.eclipse.jdt.core.dom.TypeDeclaration;
0079:        import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
0080:        import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword;
0081:        import org.eclipse.jdt.core.dom.rewrite.ITrackedNodePosition;
0082:        import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
0083:        import org.eclipse.jdt.core.refactoring.IJavaRefactorings;
0084:        import org.eclipse.jdt.core.refactoring.descriptors.JavaRefactoringDescriptor;
0085:        import org.eclipse.jdt.core.refactoring.descriptors.MoveStaticMembersDescriptor;
0086:        import org.eclipse.jdt.core.search.IJavaSearchConstants;
0087:        import org.eclipse.jdt.core.search.SearchMatch;
0088:        import org.eclipse.jdt.core.search.SearchPattern;
0089:
0090:        import org.eclipse.jdt.internal.corext.codemanipulation.CodeGenerationSettings;
0091:        import org.eclipse.jdt.internal.corext.dom.ASTNodes;
0092:        import org.eclipse.jdt.internal.corext.dom.ModifierRewrite;
0093:        import org.eclipse.jdt.internal.corext.dom.NodeFinder;
0094:        import org.eclipse.jdt.internal.corext.refactoring.Checks;
0095:        import org.eclipse.jdt.internal.corext.refactoring.JDTRefactoringDescriptorComment;
0096:        import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringArguments;
0097:        import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringDescriptorUtil;
0098:        import org.eclipse.jdt.internal.corext.refactoring.RefactoringAvailabilityTester;
0099:        import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
0100:        import org.eclipse.jdt.internal.corext.refactoring.RefactoringScopeFactory;
0101:        import org.eclipse.jdt.internal.corext.refactoring.RefactoringSearchEngine2;
0102:        import org.eclipse.jdt.internal.corext.refactoring.SearchResultGroup;
0103:        import org.eclipse.jdt.internal.corext.refactoring.base.JavaStatusContext;
0104:        import org.eclipse.jdt.internal.corext.refactoring.changes.DynamicValidationRefactoringChange;
0105:        import org.eclipse.jdt.internal.corext.refactoring.code.ScriptableRefactoring;
0106:        import org.eclipse.jdt.internal.corext.refactoring.delegates.DelegateFieldCreator;
0107:        import org.eclipse.jdt.internal.corext.refactoring.delegates.DelegateMethodCreator;
0108:        import org.eclipse.jdt.internal.corext.refactoring.participants.JavaProcessors;
0109:        import org.eclipse.jdt.internal.corext.refactoring.structure.MemberVisibilityAdjustor.IncomingMemberVisibilityAdjustment;
0110:        import org.eclipse.jdt.internal.corext.refactoring.tagging.ICommentProvider;
0111:        import org.eclipse.jdt.internal.corext.refactoring.tagging.IDelegateUpdating;
0112:        import org.eclipse.jdt.internal.corext.refactoring.tagging.IScriptableRefactoring;
0113:        import org.eclipse.jdt.internal.corext.refactoring.util.JavaElementUtil;
0114:        import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
0115:        import org.eclipse.jdt.internal.corext.util.JdtFlags;
0116:        import org.eclipse.jdt.internal.corext.util.Messages;
0117:        import org.eclipse.jdt.internal.corext.util.SearchUtils;
0118:        import org.eclipse.jdt.internal.corext.util.Strings;
0119:
0120:        import org.eclipse.jdt.ui.JavaElementLabels;
0121:        import org.eclipse.jdt.ui.refactoring.IRefactoringProcessorIds;
0122:
0123:        import org.eclipse.jdt.internal.ui.JavaPlugin;
0124:        import org.eclipse.jdt.internal.ui.preferences.JavaPreferencesSettings;
0125:
0126:        public final class MoveStaticMembersProcessor extends MoveProcessor
0127:                implements  IDelegateUpdating, IScriptableRefactoring,
0128:                ICommentProvider {
0129:
0130:            private static final String ATTRIBUTE_DELEGATE = "delegate"; //$NON-NLS-1$
0131:            private static final String ATTRIBUTE_DEPRECATE = "deprecate"; //$NON-NLS-1$
0132:            private static final String TRACKED_POSITION_PROPERTY = "MoveStaticMembersProcessor.trackedPosition"; //$NON-NLS-1$
0133:
0134:            private IMember[] fMembersToMove;
0135:            private IType fDestinationType;
0136:            private String fDestinationTypeName;
0137:
0138:            private CodeGenerationSettings fPreferences;
0139:            private CompositeChange fChange;
0140:            private CompilationUnitRewrite fSource;
0141:            private ITypeBinding fSourceBinding;
0142:            private CompilationUnitRewrite fTarget;
0143:            private IBinding[] fMemberBindings;
0144:            private BodyDeclaration[] fMemberDeclarations;
0145:            private boolean fDelegateUpdating;
0146:            private boolean fDelegateDeprecation;
0147:            private String fComment;
0148:
0149:            private static class TypeReferenceFinder extends ASTVisitor {
0150:                List fResult = new ArrayList();
0151:                Set fDefined = new HashSet();
0152:
0153:                public static List perform(ASTNode root) {
0154:                    TypeReferenceFinder visitor = new TypeReferenceFinder();
0155:                    root.accept(visitor);
0156:                    return visitor.fResult;
0157:                }
0158:
0159:                public boolean visit(TypeDeclaration node) {
0160:                    fDefined.add(node.resolveBinding());
0161:                    return true;
0162:                }
0163:
0164:                public boolean visit(SimpleName node) {
0165:                    IBinding binding = node.resolveBinding();
0166:                    if (!(binding instanceof  ITypeBinding))
0167:                        return true;
0168:                    if (!fDefined.contains(binding))
0169:                        fResult.add(binding);
0170:                    return true;
0171:                }
0172:
0173:                public boolean visit(AnnotationTypeDeclaration node) {
0174:                    fDefined.add(node.resolveBinding());
0175:                    return true;
0176:                }
0177:
0178:                public boolean visit(EnumDeclaration node) {
0179:                    fDefined.add(node.resolveBinding());
0180:                    return true;
0181:                }
0182:            }
0183:
0184:            /**
0185:             * Creates a new move static members processor.
0186:             * @param members the members to move, or <code>null</code> if invoked by scripting
0187:             * @param settings the code generation settings, or <code>null</code> if invoked by scripting
0188:             */
0189:            public MoveStaticMembersProcessor(IMember[] members,
0190:                    CodeGenerationSettings settings) {
0191:                fMembersToMove = members;
0192:                fPreferences = settings;
0193:                fDelegateUpdating = false;
0194:                fDelegateDeprecation = true;
0195:            }
0196:
0197:            /**
0198:             * {@inheritDoc}
0199:             */
0200:            public boolean isApplicable() throws CoreException {
0201:                return RefactoringAvailabilityTester
0202:                        .isMoveStaticMembersAvailable(fMembersToMove);
0203:            }
0204:
0205:            /**
0206:             * {@inheritDoc}
0207:             */
0208:            public Object[] getElements() {
0209:                Object[] result = new Object[fMembersToMove.length];
0210:                System.arraycopy(fMembersToMove, 0, result, 0,
0211:                        fMembersToMove.length);
0212:                return result;
0213:            }
0214:
0215:            /**
0216:             * {@inheritDoc}
0217:             */
0218:            public String getIdentifier() {
0219:                return IRefactoringProcessorIds.MOVE_STATIC_MEMBERS_PROCESSOR;
0220:            }
0221:
0222:            /**
0223:             * {@inheritDoc}
0224:             */
0225:            public RefactoringParticipant[] loadParticipants(
0226:                    RefactoringStatus status,
0227:                    SharableParticipants sharedParticipants)
0228:                    throws CoreException {
0229:                List result = new ArrayList();
0230:                MoveArguments args = new MoveArguments(fDestinationType, true);
0231:                String[] natures = JavaProcessors
0232:                        .computeAffectedNaturs(fMembersToMove);
0233:                for (int i = 0; i < fMembersToMove.length; i++) {
0234:                    IMember member = fMembersToMove[i];
0235:                    result.addAll(Arrays.asList(ParticipantManager
0236:                            .loadMoveParticipants(status, this , member, args,
0237:                                    natures, sharedParticipants)));
0238:                }
0239:                return (RefactoringParticipant[]) result
0240:                        .toArray(new RefactoringParticipant[result.size()]);
0241:            }
0242:
0243:            //------------------- IDelegateUpdating ----------------------
0244:
0245:            public boolean canEnableDelegateUpdating() {
0246:                try {
0247:                    for (int i = 0; i < fMembersToMove.length; i++) {
0248:                        if (isDelegateCreationAvailable(fMembersToMove[i]))
0249:                            return true;
0250:                    }
0251:                } catch (JavaModelException e) {
0252:                    return false;
0253:                }
0254:                return false;
0255:            }
0256:
0257:            private boolean isDelegateCreationAvailable(IMember member)
0258:                    throws JavaModelException {
0259:                if (member instanceof  IMethod)
0260:                    return true;
0261:                if (member instanceof  IField
0262:                        && RefactoringAvailabilityTester
0263:                                .isDelegateCreationAvailable(((IField) member)))
0264:                    return true;
0265:                return false;
0266:            }
0267:
0268:            public boolean getDelegateUpdating() {
0269:                return fDelegateUpdating;
0270:            }
0271:
0272:            public void setDelegateUpdating(boolean updating) {
0273:                fDelegateUpdating = updating;
0274:            }
0275:
0276:            public boolean getDeprecateDelegates() {
0277:                return fDelegateDeprecation;
0278:            }
0279:
0280:            public void setDeprecateDelegates(boolean deprecate) {
0281:                fDelegateDeprecation = deprecate;
0282:            }
0283:
0284:            public String getProcessorName() {
0285:                return RefactoringCoreMessages.MoveMembersRefactoring_Move_Members;
0286:            }
0287:
0288:            public IType getDestinationType() {
0289:                return fDestinationType;
0290:            }
0291:
0292:            public void setDestinationTypeFullyQualifiedName(
0293:                    String fullyQualifiedTypeName) throws JavaModelException {
0294:                Assert.isNotNull(fullyQualifiedTypeName);
0295:                fDestinationType = resolveType(fullyQualifiedTypeName);
0296:                //workaround for bug 36032: IJavaProject#findType(..) doesn't find secondary type
0297:                fDestinationTypeName = fullyQualifiedTypeName;
0298:            }
0299:
0300:            public IMember[] getMembersToMove() {
0301:                return fMembersToMove;
0302:            }
0303:
0304:            public IType getDeclaringType() {
0305:                //all methods declared in same type - checked in precondition
0306:                return fMembersToMove[0].getDeclaringType(); //index safe - checked in areAllMoveable()
0307:            }
0308:
0309:            private IType resolveType(String qualifiedTypeName)
0310:                    throws JavaModelException {
0311:                IType type = getDeclaringType().getJavaProject().findType(
0312:                        qualifiedTypeName);
0313:                if (type == null)
0314:                    type = getDeclaringType().getJavaProject().findType(
0315:                            getDeclaringType().getPackageFragment()
0316:                                    .getElementName(), qualifiedTypeName);
0317:                return type;
0318:            }
0319:
0320:            //---- Activation checking ------------------------------------
0321:
0322:            public RefactoringStatus checkInitialConditions(IProgressMonitor pm)
0323:                    throws CoreException {
0324:                try {
0325:                    pm
0326:                            .beginTask(
0327:                                    RefactoringCoreMessages.MoveMembersRefactoring_checking,
0328:                                    1);
0329:                    RefactoringStatus result = new RefactoringStatus();
0330:                    result.merge(checkDeclaringType());
0331:                    pm.worked(1);
0332:                    if (result.hasFatalError())
0333:                        return result;
0334:
0335:                    fSource = new CompilationUnitRewrite(fMembersToMove[0]
0336:                            .getCompilationUnit());
0337:                    fSourceBinding = (ITypeBinding) ((SimpleName) NodeFinder
0338:                            .perform(fSource.getRoot(), fMembersToMove[0]
0339:                                    .getDeclaringType().getNameRange()))
0340:                            .resolveBinding();
0341:                    fMemberBindings = getMemberBindings();
0342:                    if (fSourceBinding == null || hasUnresolvedMemberBinding()) {
0343:                        result
0344:                                .addFatalError(Messages
0345:                                        .format(
0346:                                                RefactoringCoreMessages.MoveMembersRefactoring_compile_errors,
0347:                                                fSource.getCu()
0348:                                                        .getElementName()));
0349:                    }
0350:                    fMemberDeclarations = getASTMembers(result);
0351:                    return result;
0352:                } finally {
0353:                    pm.done();
0354:                }
0355:            }
0356:
0357:            private boolean hasUnresolvedMemberBinding() {
0358:                for (int i = 0; i < fMemberBindings.length; i++) {
0359:                    if (fMemberBindings[i] == null)
0360:                        return true;
0361:                }
0362:                return false;
0363:            }
0364:
0365:            private RefactoringStatus checkDeclaringType() {
0366:                IType declaringType = getDeclaringType();
0367:
0368:                if (JavaModelUtil.getFullyQualifiedName(declaringType).equals(
0369:                        "java.lang.Object")) //$NON-NLS-1$
0370:                    return RefactoringStatus
0371:                            .createFatalErrorStatus(RefactoringCoreMessages.MoveMembersRefactoring_Object);
0372:
0373:                if (declaringType.isBinary())
0374:                    return RefactoringStatus
0375:                            .createFatalErrorStatus(RefactoringCoreMessages.MoveMembersRefactoring_binary);
0376:
0377:                if (declaringType.isReadOnly())
0378:                    return RefactoringStatus
0379:                            .createFatalErrorStatus(RefactoringCoreMessages.MoveMembersRefactoring_read_only);
0380:
0381:                return null;
0382:            }
0383:
0384:            //---- Input checking ------------------------------------
0385:
0386:            public RefactoringStatus checkFinalConditions(IProgressMonitor pm,
0387:                    CheckConditionsContext context) throws CoreException {
0388:                fTarget = null;
0389:                try {
0390:                    pm
0391:                            .beginTask(
0392:                                    RefactoringCoreMessages.MoveMembersRefactoring_checking,
0393:                                    10);
0394:
0395:                    RefactoringStatus result = new RefactoringStatus();
0396:
0397:                    fSource.clearASTAndImportRewrites();
0398:
0399:                    result.merge(checkDestinationType());
0400:                    if (result.hasFatalError())
0401:                        return result;
0402:
0403:                    result.merge(checkDestinationInsideTypeToMove());
0404:                    if (result.hasFatalError())
0405:                        return result;
0406:
0407:                    result.merge(MemberCheckUtil.checkMembersInDestinationType(
0408:                            fMembersToMove, fDestinationType));
0409:                    if (result.hasFatalError())
0410:                        return result;
0411:
0412:                    result
0413:                            .merge(checkNativeMovedMethods(new SubProgressMonitor(
0414:                                    pm, 1)));
0415:
0416:                    if (result.hasFatalError())
0417:                        return result;
0418:
0419:                    List modifiedCus = new ArrayList();
0420:                    createChange(modifiedCus, result, new SubProgressMonitor(
0421:                            pm, 7));
0422:                    IFile[] changedFiles = getAllFilesToModify(modifiedCus);
0423:                    ResourceChangeChecker checker = (ResourceChangeChecker) context
0424:                            .getChecker(ResourceChangeChecker.class);
0425:                    for (int i = 0; i < changedFiles.length; i++) {
0426:                        checker.getDeltaFactory().change(changedFiles[i]);
0427:                    }
0428:
0429:                    return result;
0430:                } finally {
0431:                    pm.done();
0432:                }
0433:            }
0434:
0435:            private IFile[] getAllFilesToModify(List modifiedCus) {
0436:                Set result = new HashSet();
0437:                IResource resource = fDestinationType.getCompilationUnit()
0438:                        .getResource();
0439:                result.add(resource);
0440:                for (int i = 0; i < fMembersToMove.length; i++) {
0441:                    resource = fMembersToMove[i].getCompilationUnit()
0442:                            .getResource();
0443:                    if (resource != null)
0444:                        result.add(resource);
0445:                }
0446:                for (Iterator iter = modifiedCus.iterator(); iter.hasNext();) {
0447:                    ICompilationUnit unit = (ICompilationUnit) iter.next();
0448:                    if (unit.getResource() != null)
0449:                        result.add(unit.getResource());
0450:                }
0451:                return (IFile[]) result.toArray(new IFile[result.size()]);
0452:            }
0453:
0454:            private RefactoringStatus checkDestinationType()
0455:                    throws JavaModelException {
0456:                if (fDestinationType == null) {
0457:                    String message = Messages
0458:                            .format(
0459:                                    RefactoringCoreMessages.MoveMembersRefactoring_not_found,
0460:                                    fDestinationTypeName);
0461:                    return RefactoringStatus.createFatalErrorStatus(message);
0462:                }
0463:
0464:                if (fDestinationType.equals(getDeclaringType())) {
0465:                    String message = Messages
0466:                            .format(
0467:                                    RefactoringCoreMessages.MoveMembersRefactoring_same,
0468:                                    JavaElementUtil
0469:                                            .createSignature(fDestinationType));
0470:                    return RefactoringStatus.createFatalErrorStatus(message);
0471:                }
0472:
0473:                if (!fDestinationType.exists()) {
0474:                    String message = Messages
0475:                            .format(
0476:                                    RefactoringCoreMessages.MoveMembersRefactoring_not_exist,
0477:                                    JavaElementUtil
0478:                                            .createSignature(fDestinationType));
0479:                    return RefactoringStatus.createFatalErrorStatus(message);
0480:                }
0481:
0482:                if (fDestinationType.isBinary()) {
0483:                    String message = Messages
0484:                            .format(
0485:                                    RefactoringCoreMessages.MoveMembersRefactoring_dest_binary,
0486:                                    JavaElementUtil
0487:                                            .createSignature(fDestinationType));
0488:                    return RefactoringStatus.createFatalErrorStatus(message);
0489:                }
0490:
0491:                RefactoringStatus result = new RefactoringStatus();
0492:
0493:                if (fDestinationType.isInterface()
0494:                        && !getDeclaringType().isInterface())
0495:                    result.merge(checkFieldsForInterface());
0496:                if (result.hasFatalError())
0497:                    return result;
0498:
0499:                // no checking required for moving interface fields to classes
0500:
0501:                if (!((JdtFlags.isStatic(fDestinationType)) || (fDestinationType
0502:                        .getDeclaringType() == null))) {
0503:                    String message = RefactoringCoreMessages.MoveMembersRefactoring_static_declaration;
0504:                    result.addError(message);
0505:                }
0506:
0507:                return result;
0508:            }
0509:
0510:            private RefactoringStatus checkDestinationInsideTypeToMove()
0511:                    throws JavaModelException {
0512:                RefactoringStatus result = new RefactoringStatus();
0513:                for (int i = 0; i < fMembersToMove.length; i++) {
0514:                    if (!(fMembersToMove[i] instanceof  IType))
0515:                        continue;
0516:                    IType type = (IType) fMembersToMove[i];
0517:                    if (fDestinationType.equals(type)
0518:                            || JavaElementUtil.isAncestorOf(type,
0519:                                    fDestinationType)) {
0520:                        String message = Messages
0521:                                .format(
0522:                                        RefactoringCoreMessages.MoveMembersRefactoring_inside,
0523:                                        new String[] {
0524:                                                JavaModelUtil
0525:                                                        .getFullyQualifiedName(type),
0526:                                                JavaModelUtil
0527:                                                        .getFullyQualifiedName(fDestinationType) });
0528:                        RefactoringStatusContext context = JavaStatusContext
0529:                                .create(fDestinationType.getCompilationUnit(),
0530:                                        fDestinationType.getNameRange());
0531:                        result.addFatalError(message, context);
0532:                        return result;
0533:                    }
0534:                }
0535:                return result;
0536:            }
0537:
0538:            private RefactoringStatus checkFieldsForInterface()
0539:                    throws JavaModelException {
0540:                //could be more clever and make field final if it is only written once...
0541:                RefactoringStatus result = new RefactoringStatus();
0542:                for (int i = 0; i < fMembersToMove.length; i++) {
0543:                    if (!canMoveToInterface(fMembersToMove[i])) {
0544:                        String message = RefactoringCoreMessages.MoveMembersRefactoring_only_public_static;
0545:                        result.addError(message, JavaStatusContext
0546:                                .create(fMembersToMove[i]));
0547:                    }
0548:                }
0549:                return result;
0550:            }
0551:
0552:            private boolean canMoveToInterface(IMember member)
0553:                    throws JavaModelException {
0554:                int flags = member.getFlags();
0555:                switch (member.getElementType()) {
0556:                case IJavaElement.FIELD:
0557:                    if (!(Flags.isPublic(flags) && Flags.isStatic(flags) && Flags
0558:                            .isFinal(flags)))
0559:                        return false;
0560:                    if (Flags.isEnum(flags))
0561:                        return false;
0562:                    VariableDeclarationFragment declaration = ASTNodeSearchUtil
0563:                            .getFieldDeclarationFragmentNode((IField) member,
0564:                                    fSource.getRoot());
0565:                    if (declaration != null)
0566:                        return declaration.getInitializer() != null;
0567:                    return false;
0568:                case IJavaElement.TYPE: {
0569:                    IType type = (IType) member;
0570:                    if (type.isInterface() && !Checks.isTopLevel(type))
0571:                        return true;
0572:                    return (Flags.isPublic(flags) && Flags.isStatic(flags));
0573:                }
0574:                default:
0575:                    return false;
0576:                }
0577:            }
0578:
0579:            private RefactoringStatus checkMovedMemberAvailability(
0580:                    IMember memberToMove, IProgressMonitor pm)
0581:                    throws JavaModelException {
0582:                RefactoringStatus result = new RefactoringStatus();
0583:                if (memberToMove instanceof  IType) { // recursively check accessibility of member type's members
0584:                    IJavaElement[] typeMembers = ((IType) memberToMove)
0585:                            .getChildren();
0586:                    pm
0587:                            .beginTask(
0588:                                    RefactoringCoreMessages.MoveMembersRefactoring_checking,
0589:                                    typeMembers.length + 1);
0590:                    for (int i = 0; i < typeMembers.length; i++) {
0591:                        if (typeMembers[i] instanceof  IInitializer)
0592:                            pm.worked(1);
0593:                        else
0594:                            result.merge(checkMovedMemberAvailability(
0595:                                    (IMember) typeMembers[i],
0596:                                    new SubProgressMonitor(pm, 1)));
0597:                    }
0598:                } else {
0599:                    pm
0600:                            .beginTask(
0601:                                    RefactoringCoreMessages.MoveMembersRefactoring_checking,
0602:                                    1);
0603:                }
0604:
0605:                IType[] blindAccessorTypes = getTypesNotSeeingMovedMember(
0606:                        memberToMove, new SubProgressMonitor(pm, 1), result);
0607:                for (int k = 0; k < blindAccessorTypes.length; k++) {
0608:                    String message = createNonAccessibleMemberMessage(
0609:                            memberToMove, blindAccessorTypes[k],/*moved*/true);
0610:                    result.addError(message, JavaStatusContext
0611:                            .create(memberToMove));
0612:                }
0613:                pm.done();
0614:                return result;
0615:            }
0616:
0617:            private IType[] getTypesNotSeeingMovedMember(IMember member,
0618:                    IProgressMonitor pm, RefactoringStatus status)
0619:                    throws JavaModelException {
0620:                if (JdtFlags.isPublic(member)
0621:                        && JdtFlags.isPublic(fDestinationType))
0622:                    return new IType[0];
0623:
0624:                HashSet blindAccessorTypes = new HashSet(); // referencing, but access to destination type illegal
0625:                SearchResultGroup[] references = getReferences(member,
0626:                        new SubProgressMonitor(pm, 1), status);
0627:                for (int i = 0; i < references.length; i++) {
0628:                    SearchMatch[] searchResults = references[i]
0629:                            .getSearchResults();
0630:                    for (int k = 0; k < searchResults.length; k++) {
0631:                        SearchMatch searchResult = searchResults[k];
0632:                        IJavaElement element = SearchUtils
0633:                                .getEnclosingJavaElement(searchResult);
0634:                        IType type = (IType) element
0635:                                .getAncestor(IJavaElement.TYPE);
0636:                        if (type != null //reference can e.g. be an import declaration
0637:                                && !blindAccessorTypes.contains(type)
0638:                                && !isWithinMemberToMove(searchResult)
0639:                                && !isVisibleFrom(member, getDestinationType(),
0640:                                        type)) {
0641:                            blindAccessorTypes.add(type);
0642:                        }
0643:                    }
0644:                }
0645:
0646:                if (fDelegateUpdating && isDelegateCreationAvailable(member)) {
0647:                    // ensure moved member is visible from the delegate
0648:                    IType type = member.getDeclaringType();
0649:                    if (!blindAccessorTypes.contains(type)
0650:                            && !isVisibleFrom(member, getDestinationType(),
0651:                                    type))
0652:                        blindAccessorTypes.add(type);
0653:                }
0654:
0655:                return (IType[]) blindAccessorTypes
0656:                        .toArray(new IType[blindAccessorTypes.size()]);
0657:            }
0658:
0659:            private String createNonAccessibleMemberMessage(IMember member,
0660:                    IType accessingType, boolean moved) {
0661:                //Non-visibility can have various reasons and always displaying all visibility
0662:                //flags for all enclosing elements would be too heavy. Context reveals exact cause.
0663:                IType declaringType = moved ? getDestinationType()
0664:                        : getDeclaringType();
0665:                String message;
0666:                switch (member.getElementType()) {
0667:                case IJavaElement.FIELD: {
0668:                    if (moved)
0669:                        message = Messages
0670:                                .format(
0671:                                        RefactoringCoreMessages.MoveMembersRefactoring_moved_field,
0672:                                        new String[] {
0673:                                                JavaElementUtil
0674:                                                        .createFieldSignature((IField) member),
0675:                                                JavaModelUtil
0676:                                                        .getFullyQualifiedName(accessingType),
0677:                                                JavaModelUtil
0678:                                                        .getFullyQualifiedName(declaringType) });
0679:                    else
0680:                        message = Messages
0681:                                .format(
0682:                                        RefactoringCoreMessages.MoveMembersRefactoring_accessed_field,
0683:                                        new String[] {
0684:                                                JavaElementUtil
0685:                                                        .createFieldSignature((IField) member),
0686:                                                JavaModelUtil
0687:                                                        .getFullyQualifiedName(accessingType) });
0688:                    return message;
0689:                }
0690:                case IJavaElement.METHOD: {
0691:                    if (moved)
0692:                        message = Messages
0693:                                .format(
0694:                                        RefactoringCoreMessages.MoveMembersRefactoring_moved_method,
0695:                                        new String[] {
0696:                                                JavaElementUtil
0697:                                                        .createMethodSignature((IMethod) member),
0698:                                                JavaModelUtil
0699:                                                        .getFullyQualifiedName(accessingType),
0700:                                                JavaModelUtil
0701:                                                        .getFullyQualifiedName(declaringType) });
0702:                    else
0703:                        message = Messages
0704:                                .format(
0705:                                        RefactoringCoreMessages.MoveMembersRefactoring_accessed_method,
0706:                                        new String[] {
0707:                                                JavaElementUtil
0708:                                                        .createMethodSignature((IMethod) member),
0709:                                                JavaModelUtil
0710:                                                        .getFullyQualifiedName(accessingType) });
0711:
0712:                    return message;
0713:                }
0714:                case IJavaElement.TYPE: {
0715:                    if (moved)
0716:                        message = Messages
0717:                                .format(
0718:                                        RefactoringCoreMessages.MoveMembersRefactoring_moved_type,
0719:                                        new String[] {
0720:                                                JavaModelUtil
0721:                                                        .getFullyQualifiedName(((IType) member)),
0722:                                                JavaModelUtil
0723:                                                        .getFullyQualifiedName(accessingType),
0724:                                                JavaModelUtil
0725:                                                        .getFullyQualifiedName(declaringType) });
0726:                    else
0727:                        message = Messages
0728:                                .format(
0729:                                        RefactoringCoreMessages.MoveMembersRefactoring_accessed_type,
0730:                                        new String[] {
0731:                                                JavaModelUtil
0732:                                                        .getFullyQualifiedName(((IType) member)),
0733:                                                JavaModelUtil
0734:                                                        .getFullyQualifiedName(accessingType) });
0735:                    return message;
0736:                }
0737:                default:
0738:                    Assert.isTrue(false);
0739:                    return null;
0740:                }
0741:            }
0742:
0743:            private static SearchResultGroup[] getReferences(IMember member,
0744:                    IProgressMonitor monitor, RefactoringStatus status)
0745:                    throws JavaModelException {
0746:                final RefactoringSearchEngine2 engine = new RefactoringSearchEngine2(
0747:                        SearchPattern.createPattern(member,
0748:                                IJavaSearchConstants.REFERENCES,
0749:                                SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE));
0750:                engine.setFiltering(true, true);
0751:                engine.setScope(RefactoringScopeFactory.create(member));
0752:                engine.setStatus(status);
0753:                engine.searchPattern(new SubProgressMonitor(monitor, 1));
0754:                return (SearchResultGroup[]) engine.getResults();
0755:            }
0756:
0757:            private static boolean isVisibleFrom(IMember member,
0758:                    IType newMemberDeclaringType, IType accessingType)
0759:                    throws JavaModelException {
0760:                int memberVisibility = JdtFlags
0761:                        .getVisibilityCode(newMemberDeclaringType);
0762:
0763:                IType declaringType = newMemberDeclaringType.getDeclaringType();
0764:                while (declaringType != null) { //get lowest visibility in all parent types of newMemberDeclaringType
0765:                    memberVisibility = JdtFlags.getLowerVisibility(
0766:                            memberVisibility, JdtFlags
0767:                                    .getVisibilityCode(declaringType));
0768:                    declaringType = declaringType.getDeclaringType();
0769:                }
0770:
0771:                switch (memberVisibility) {
0772:                case Modifier.PRIVATE:
0773:                    return isEqualOrEnclosedType(accessingType,
0774:                            newMemberDeclaringType);
0775:
0776:                case Modifier.NONE:
0777:                    return JavaModelUtil.isSamePackage(accessingType
0778:                            .getPackageFragment(), newMemberDeclaringType
0779:                            .getPackageFragment());
0780:
0781:                case Modifier.PROTECTED:
0782:                    return JavaModelUtil.isSamePackage(accessingType
0783:                            .getPackageFragment(), newMemberDeclaringType
0784:                            .getPackageFragment())
0785:                            || accessingType.newSupertypeHierarchy(null)
0786:                                    .contains(newMemberDeclaringType);
0787:
0788:                case Modifier.PUBLIC:
0789:                    return true;
0790:
0791:                default:
0792:                    Assert.isTrue(false);
0793:                    return false;
0794:                }
0795:            }
0796:
0797:            private static boolean isEqualOrEnclosedType(IType inner,
0798:                    IType outer) {
0799:                while (inner != null) {
0800:                    if (inner.equals(outer))
0801:                        return true;
0802:                    else
0803:                        inner = inner.getDeclaringType();
0804:                }
0805:                return false;
0806:            }
0807:
0808:            private boolean isWithinMemberToMove(SearchMatch result)
0809:                    throws JavaModelException {
0810:                ICompilationUnit referenceCU = SearchUtils
0811:                        .getCompilationUnit(result);
0812:                if (!referenceCU.equals(fSource.getCu()))
0813:                    return false;
0814:                int referenceStart = result.getOffset();
0815:                for (int i = 0; i < fMembersToMove.length; i++) {
0816:                    ISourceRange range = fMembersToMove[i].getSourceRange();
0817:                    if (range.getOffset() <= referenceStart
0818:                            && range.getOffset() + range.getLength() >= referenceStart)
0819:                        return true;
0820:                }
0821:                return false;
0822:            }
0823:
0824:            private RefactoringStatus checkNativeMovedMethods(
0825:                    IProgressMonitor pm) throws JavaModelException {
0826:                pm
0827:                        .beginTask(
0828:                                RefactoringCoreMessages.MoveMembersRefactoring_checking,
0829:                                fMembersToMove.length);
0830:                RefactoringStatus result = new RefactoringStatus();
0831:                for (int i = 0; i < fMembersToMove.length; i++) {
0832:                    if (fMembersToMove[i].getElementType() != IJavaElement.METHOD)
0833:                        continue;
0834:                    if (!JdtFlags.isNative(fMembersToMove[i]))
0835:                        continue;
0836:                    String message = Messages
0837:                            .format(
0838:                                    RefactoringCoreMessages.MoveMembersRefactoring_native,
0839:                                    JavaElementUtil
0840:                                            .createMethodSignature((IMethod) fMembersToMove[i]));
0841:                    result.addWarning(message, JavaStatusContext
0842:                            .create(fMembersToMove[i]));
0843:                    pm.worked(1);
0844:                }
0845:                pm.done();
0846:                return result;
0847:            }
0848:
0849:            public Change createChange(IProgressMonitor pm)
0850:                    throws CoreException {
0851:                pm.done();
0852:                return fChange;
0853:            }
0854:
0855:            private void createChange(List modifiedCus,
0856:                    RefactoringStatus status, IProgressMonitor monitor)
0857:                    throws CoreException {
0858:                monitor
0859:                        .beginTask(
0860:                                RefactoringCoreMessages.MoveMembersRefactoring_creating,
0861:                                5);
0862:                final IMember[] members = getMembersToMove();
0863:                String project = null;
0864:                final IJavaProject javaProject = getDeclaringType()
0865:                        .getJavaProject();
0866:                if (javaProject != null)
0867:                    project = javaProject.getElementName();
0868:                String header = null;
0869:                if (members.length == 1)
0870:                    header = Messages
0871:                            .format(
0872:                                    RefactoringCoreMessages.MoveStaticMembersProcessor_descriptor_description_single,
0873:                                    new String[] {
0874:                                            JavaElementLabels
0875:                                                    .getElementLabel(
0876:                                                            members[0],
0877:                                                            JavaElementLabels.ALL_FULLY_QUALIFIED),
0878:                                            JavaElementLabels
0879:                                                    .getElementLabel(
0880:                                                            fDestinationType,
0881:                                                            JavaElementLabels.ALL_FULLY_QUALIFIED) });
0882:                else
0883:                    header = Messages
0884:                            .format(
0885:                                    RefactoringCoreMessages.MoveStaticMembersProcessor_descriptor_description_multi,
0886:                                    new String[] {
0887:                                            String.valueOf(members.length),
0888:                                            JavaElementLabels
0889:                                                    .getElementLabel(
0890:                                                            fDestinationType,
0891:                                                            JavaElementLabels.ALL_FULLY_QUALIFIED) });
0892:                int flags = JavaRefactoringDescriptor.JAR_MIGRATION
0893:                        | JavaRefactoringDescriptor.JAR_REFACTORING
0894:                        | RefactoringDescriptor.STRUCTURAL_CHANGE
0895:                        | RefactoringDescriptor.MULTI_CHANGE;
0896:                final IType declaring = members[0].getDeclaringType();
0897:                try {
0898:                    if (declaring.isLocal() || declaring.isAnonymous())
0899:                        flags |= JavaRefactoringDescriptor.JAR_SOURCE_ATTACHMENT;
0900:                } catch (JavaModelException exception) {
0901:                    JavaPlugin.log(exception);
0902:                }
0903:                final String description = members.length == 1 ? Messages
0904:                        .format(
0905:                                RefactoringCoreMessages.MoveStaticMembersProcessor_description_descriptor_short_multi,
0906:                                members[0].getElementName())
0907:                        : RefactoringCoreMessages.MoveMembersRefactoring_move_members;
0908:                final JDTRefactoringDescriptorComment comment = new JDTRefactoringDescriptorComment(
0909:                        project, this , header);
0910:                comment
0911:                        .addSetting(Messages
0912:                                .format(
0913:                                        RefactoringCoreMessages.MoveStaticMembersProcessor_target_element_pattern,
0914:                                        JavaElementLabels
0915:                                                .getElementLabel(
0916:                                                        fDestinationType,
0917:                                                        JavaElementLabels.ALL_FULLY_QUALIFIED)));
0918:                final MoveStaticMembersDescriptor descriptor = new MoveStaticMembersDescriptor();
0919:                descriptor.setProject(project);
0920:                descriptor.setDescription(description);
0921:                descriptor.setComment(comment.asString());
0922:                descriptor.setFlags(flags);
0923:                descriptor.setDestinationType(fDestinationType);
0924:                descriptor.setKeepOriginal(fDelegateUpdating);
0925:                descriptor.setDeprecateDelegate(fDelegateDeprecation);
0926:                descriptor.setMembers(members);
0927:                fChange = new DynamicValidationRefactoringChange(
0928:                        descriptor,
0929:                        RefactoringCoreMessages.MoveMembersRefactoring_move_members);
0930:                fTarget = getCuRewrite(fDestinationType.getCompilationUnit());
0931:                ITypeBinding targetBinding = getDestinationBinding();
0932:                if (targetBinding == null) {
0933:                    status
0934:                            .addFatalError(Messages
0935:                                    .format(
0936:                                            RefactoringCoreMessages.MoveMembersRefactoring_compile_errors,
0937:                                            fTarget.getCu().getElementName()));
0938:                    monitor.done();
0939:                    return;
0940:                }
0941:
0942:                try {
0943:                    Map adjustments = new HashMap();
0944:                    IMember member = null;
0945:                    SubProgressMonitor sub = new SubProgressMonitor(monitor, 1,
0946:                            SubProgressMonitor.SUPPRESS_SUBTASK_LABEL);
0947:                    sub
0948:                            .beginTask(
0949:                                    RefactoringCoreMessages.MoveMembersRefactoring_creating,
0950:                                    fMembersToMove.length);
0951:                    Set rewritten = new HashSet();
0952:                    for (int index = 0; index < fMembersToMove.length; index++) {
0953:                        member = fMembersToMove[index];
0954:                        final MemberVisibilityAdjustor adjustor = new MemberVisibilityAdjustor(
0955:                                fDestinationType, member);
0956:                        adjustor.setAdjustments(adjustments);
0957:                        adjustor.setStatus(status);
0958:                        adjustor
0959:                                .setVisibilitySeverity(RefactoringStatus.WARNING);
0960:                        adjustor.setFailureSeverity(RefactoringStatus.WARNING);
0961:                        adjustor.setRewrite(fSource.getASTRewrite(), fSource
0962:                                .getRoot());
0963:                        adjustor.adjustVisibility(new NullProgressMonitor());
0964:
0965:                        if (fDelegateUpdating
0966:                                && isDelegateCreationAvailable(member)) {
0967:                            // Add a visibility adjustment so the moved member
0968:                            // will be visible from within the delegate
0969:                            ModifierKeyword threshold = adjustor
0970:                                    .getVisibilityThreshold(member,
0971:                                            fDestinationType,
0972:                                            new NullProgressMonitor());
0973:                            IncomingMemberVisibilityAdjustment adjustment = (IncomingMemberVisibilityAdjustment) adjustments
0974:                                    .get(member);
0975:                            ModifierKeyword kw = (adjustment != null) ? adjustment
0976:                                    .getKeyword()
0977:                                    : ModifierKeyword.fromFlagValue(JdtFlags
0978:                                            .getVisibilityCode(member));
0979:                            if (MemberVisibilityAdjustor.hasLowerVisibility(kw,
0980:                                    threshold)) {
0981:                                adjustments
0982:                                        .put(
0983:                                                member,
0984:                                                new MemberVisibilityAdjustor.IncomingMemberVisibilityAdjustment(
0985:                                                        member,
0986:                                                        threshold,
0987:                                                        RefactoringStatus
0988:                                                                .createWarningStatus(
0989:                                                                        Messages
0990:                                                                                .format(
0991:                                                                                        MemberVisibilityAdjustor
0992:                                                                                                .getMessage(member),
0993:                                                                                        new String[] {
0994:                                                                                                MemberVisibilityAdjustor
0995:                                                                                                        .getLabel(member),
0996:                                                                                                MemberVisibilityAdjustor
0997:                                                                                                        .getLabel(threshold) }),
0998:                                                                        JavaStatusContext
0999:                                                                                .create(member))));
1000:                            }
1001:                        }
1002:
1003:                        // Check if destination type is visible from references ->
1004:                        // error message if not (for example, when moving into a private type)
1005:                        status.merge(checkMovedMemberAvailability(member,
1006:                                new SubProgressMonitor(sub, 1)));
1007:                        // Put rewrite info into code and into status
1008:                        for (final Iterator iterator = rewritten.iterator(); iterator
1009:                                .hasNext();) {
1010:                            adjustments.remove(iterator.next());
1011:                        }
1012:                        rewritten.addAll(adjustments.keySet());
1013:                        adjustor.rewriteVisibility(new NullProgressMonitor());
1014:                    }
1015:
1016:                    // First update references in moved members, in order to extract the
1017:                    // source.
1018:                    String[] memberSources = getUpdatedMemberSource(status,
1019:                            fMemberDeclarations, targetBinding);
1020:                    monitor.worked(1);
1021:                    if (status.hasFatalError())
1022:                        return;
1023:
1024:                    final RefactoringSearchEngine2 engine = new RefactoringSearchEngine2();
1025:                    engine.setPattern(fMembersToMove,
1026:                            IJavaSearchConstants.ALL_OCCURRENCES);
1027:                    engine
1028:                            .setGranularity(RefactoringSearchEngine2.GRANULARITY_COMPILATION_UNIT);
1029:                    engine.setFiltering(true, true);
1030:                    engine.setScope(RefactoringScopeFactory
1031:                            .create(fMembersToMove));
1032:                    engine.setStatus(status);
1033:                    engine.searchPattern(new NullProgressMonitor());
1034:                    ICompilationUnit[] units = engine
1035:                            .getAffectedCompilationUnits();
1036:                    modifiedCus.addAll(Arrays.asList(units));
1037:                    final MemberVisibilityAdjustor adjustor = new MemberVisibilityAdjustor(
1038:                            fDestinationType, fDestinationType);
1039:                    sub = new SubProgressMonitor(monitor, 1);
1040:                    sub
1041:                            .beginTask(
1042:                                    RefactoringCoreMessages.MoveMembersRefactoring_creating,
1043:                                    units.length);
1044:                    for (int index = 0; index < units.length; index++) {
1045:                        ICompilationUnit unit = units[index];
1046:                        CompilationUnitRewrite rewrite = getCuRewrite(unit);
1047:                        adjustor.setRewrites(Collections.singletonMap(unit,
1048:                                rewrite));
1049:                        adjustor.setAdjustments(adjustments);
1050:                        adjustor.rewriteVisibility(unit,
1051:                                new SubProgressMonitor(sub, 1));
1052:                        ReferenceAnalyzer analyzer = new ReferenceAnalyzer(
1053:                                rewrite, fMemberBindings, targetBinding,
1054:                                fSourceBinding);
1055:                        rewrite.getRoot().accept(analyzer);
1056:                        status.merge(analyzer.getStatus());
1057:                        if (status.hasFatalError()) {
1058:                            fChange = null;
1059:                            return;
1060:                        }
1061:                        if (!(fSource.getCu().equals(unit) || fTarget.getCu()
1062:                                .equals(unit)))
1063:                            fChange.add(rewrite.createChange());
1064:                    }
1065:                    status
1066:                            .merge(moveMembers(fMemberDeclarations,
1067:                                    memberSources));
1068:                    fChange.add(fSource.createChange());
1069:                    modifiedCus.add(fSource.getCu());
1070:                    if (!fSource.getCu().equals(fTarget.getCu())) {
1071:                        fChange.add(fTarget.createChange());
1072:                        modifiedCus.add(fTarget.getCu());
1073:                    }
1074:                    monitor.worked(1);
1075:                } catch (BadLocationException exception) {
1076:                    JavaPlugin.log(exception);
1077:                }
1078:            }
1079:
1080:            private CompilationUnitRewrite getCuRewrite(ICompilationUnit unit) {
1081:                if (fSource.getCu().equals(unit))
1082:                    return fSource;
1083:                if (fTarget != null && fTarget.getCu().equals(unit))
1084:                    return fTarget;
1085:                return new CompilationUnitRewrite(unit);
1086:            }
1087:
1088:            private ITypeBinding getDestinationBinding()
1089:                    throws JavaModelException {
1090:                ASTNode node = NodeFinder.perform(fTarget.getRoot(),
1091:                        fDestinationType.getNameRange());
1092:                if (!(node instanceof  SimpleName))
1093:                    return null;
1094:                IBinding binding = ((SimpleName) node).resolveBinding();
1095:                if (!(binding instanceof  ITypeBinding))
1096:                    return null;
1097:                return (ITypeBinding) binding;
1098:            }
1099:
1100:            private IBinding[] getMemberBindings() throws JavaModelException {
1101:                IBinding[] result = new IBinding[fMembersToMove.length];
1102:                for (int i = 0; i < fMembersToMove.length; i++) {
1103:                    IMember member = fMembersToMove[i];
1104:                    SimpleName name = (SimpleName) NodeFinder.perform(fSource
1105:                            .getRoot(), member.getNameRange());
1106:                    result[i] = name.resolveBinding();
1107:                }
1108:                return result;
1109:            }
1110:
1111:            private String[] getUpdatedMemberSource(RefactoringStatus status,
1112:                    BodyDeclaration[] members, ITypeBinding target)
1113:                    throws CoreException, BadLocationException {
1114:                List typeRefs = new ArrayList();
1115:                boolean targetNeedsSourceImport = false;
1116:                boolean isSourceNotTarget = fSource != fTarget;
1117:                Set exclude = new HashSet();
1118:                for (int i = 0; i < members.length; i++) {
1119:                    BodyDeclaration declaration = members[i];
1120:                    if (declaration instanceof  AbstractTypeDeclaration) {
1121:                        AbstractTypeDeclaration type = (AbstractTypeDeclaration) declaration;
1122:                        ITypeBinding binding = type.resolveBinding();
1123:                        if (binding != null)
1124:                            exclude.add(binding);
1125:                    } else if (declaration instanceof  MethodDeclaration) {
1126:                        MethodDeclaration method = (MethodDeclaration) declaration;
1127:                        IMethodBinding binding = method.resolveBinding();
1128:                        if (binding != null)
1129:                            exclude.add(binding);
1130:                    } else if (declaration instanceof  FieldDeclaration) {
1131:                        FieldDeclaration field = (FieldDeclaration) declaration;
1132:                        for (final Iterator iterator = field.fragments()
1133:                                .iterator(); iterator.hasNext();) {
1134:                            VariableDeclarationFragment fragment = (VariableDeclarationFragment) iterator
1135:                                    .next();
1136:                            IVariableBinding binding = fragment
1137:                                    .resolveBinding();
1138:                            if (binding != null)
1139:                                exclude.add(binding);
1140:                        }
1141:                    }
1142:                }
1143:                for (int i = 0; i < members.length; i++) {
1144:                    BodyDeclaration declaration = members[i];
1145:                    if (isSourceNotTarget)
1146:                        typeRefs.addAll(TypeReferenceFinder
1147:                                .perform(declaration));
1148:                    MovedMemberAnalyzer analyzer = new MovedMemberAnalyzer(
1149:                            fSource, fMemberBindings, fSourceBinding, target);
1150:                    declaration.accept(analyzer);
1151:                    ImportRewriteUtil.addImports(fTarget, declaration,
1152:                            new HashMap(), new HashMap(), exclude, false);
1153:                    if (getDeclaringType().isInterface()
1154:                            && !fDestinationType.isInterface()) {
1155:                        if (declaration instanceof  FieldDeclaration) {
1156:                            FieldDeclaration fieldDecl = (FieldDeclaration) declaration;
1157:                            int psfModifiers = Modifier.PUBLIC
1158:                                    | Modifier.STATIC | Modifier.FINAL;
1159:                            if ((fieldDecl.getModifiers() & psfModifiers) != psfModifiers) {
1160:                                ModifierRewrite.create(fSource.getASTRewrite(),
1161:                                        fieldDecl).setModifiers(psfModifiers,
1162:                                        null);
1163:                            }
1164:                        } else if (declaration instanceof  AbstractTypeDeclaration) {
1165:                            AbstractTypeDeclaration typeDecl = (AbstractTypeDeclaration) declaration;
1166:                            int psModifiers = Modifier.PUBLIC | Modifier.STATIC;
1167:                            if ((typeDecl.getModifiers() & psModifiers) != psModifiers) {
1168:                                ModifierRewrite.create(fSource.getASTRewrite(),
1169:                                        typeDecl).setModifiers(
1170:                                        typeDecl.getModifiers() | psModifiers,
1171:                                        null);
1172:                            }
1173:                        }
1174:                    }
1175:                    ITrackedNodePosition trackedPosition = fSource
1176:                            .getASTRewrite().track(declaration);
1177:                    declaration.setProperty(TRACKED_POSITION_PROPERTY,
1178:                            trackedPosition);
1179:                    targetNeedsSourceImport |= analyzer
1180:                            .targetNeedsSourceImport();
1181:                    status.merge(analyzer.getStatus());
1182:                }
1183:                // Adjust imports
1184:                if (targetNeedsSourceImport && isSourceNotTarget) {
1185:                    fTarget.getImportRewrite().addImport(fSourceBinding);
1186:                }
1187:                if (isSourceNotTarget) {
1188:                    for (Iterator iter = typeRefs.iterator(); iter.hasNext();) {
1189:                        ITypeBinding binding = (ITypeBinding) iter.next();
1190:                        fTarget.getImportRewrite().addImport(binding);
1191:                    }
1192:                }
1193:                // extract updated members
1194:                String[] updatedMemberSources = new String[members.length];
1195:                IDocument document = new Document(fSource.getCu().getBuffer()
1196:                        .getContents());
1197:                TextEdit edit = fSource.getASTRewrite().rewriteAST(document,
1198:                        fSource.getCu().getJavaProject().getOptions(true));
1199:                edit.apply(document, TextEdit.UPDATE_REGIONS);
1200:                for (int i = 0; i < members.length; i++) {
1201:                    updatedMemberSources[i] = getUpdatedMember(document,
1202:                            members[i]);
1203:                }
1204:                fSource.clearASTRewrite();
1205:                return updatedMemberSources;
1206:            }
1207:
1208:            private String getUpdatedMember(IDocument document,
1209:                    BodyDeclaration declaration) throws BadLocationException {
1210:                ITrackedNodePosition trackedPosition = (ITrackedNodePosition) declaration
1211:                        .getProperty(TRACKED_POSITION_PROPERTY);
1212:                return Strings.trimIndentation(document.get(trackedPosition
1213:                        .getStartPosition(), trackedPosition.getLength()),
1214:                        fPreferences.tabWidth, fPreferences.indentWidth, false);
1215:            }
1216:
1217:            private RefactoringStatus moveMembers(BodyDeclaration[] members,
1218:                    String[] sources) throws CoreException {
1219:                RefactoringStatus result = new RefactoringStatus();
1220:                AbstractTypeDeclaration destination = (AbstractTypeDeclaration) ASTNodes
1221:                        .getParent(NodeFinder.perform(fTarget.getRoot(),
1222:                                fDestinationType.getNameRange()),
1223:                                AbstractTypeDeclaration.class);
1224:                ListRewrite containerRewrite = fTarget.getASTRewrite()
1225:                        .getListRewrite(destination,
1226:                                destination.getBodyDeclarationsProperty());
1227:
1228:                TextEditGroup delete = fSource
1229:                        .createGroupDescription(RefactoringCoreMessages.MoveMembersRefactoring_deleteMembers);
1230:                TextEditGroup add = fTarget
1231:                        .createGroupDescription(RefactoringCoreMessages.MoveMembersRefactoring_addMembers);
1232:                for (int i = 0; i < members.length; i++) {
1233:                    BodyDeclaration declaration = members[i];
1234:                    ASTNode removeImportsOf = null;
1235:                    boolean addedDelegate = false;
1236:
1237:                    if (fDelegateUpdating) {
1238:                        if (declaration instanceof  MethodDeclaration) {
1239:
1240:                            DelegateMethodCreator creator = new DelegateMethodCreator();
1241:                            creator.setDeclaration(declaration);
1242:                            creator.setDeclareDeprecated(fDelegateDeprecation);
1243:                            creator.setSourceRewrite(fSource);
1244:                            creator.setCopy(false);
1245:                            creator.setNewLocation(getDestinationBinding());
1246:                            creator.prepareDelegate();
1247:                            creator.createEdit();
1248:
1249:                            removeImportsOf = ((MethodDeclaration) declaration)
1250:                                    .getBody();
1251:                            addedDelegate = true;
1252:                        }
1253:                        if (declaration instanceof  FieldDeclaration) {
1254:
1255:                            // Note: this FieldDeclaration only has one fragment (@see #getASTMembers(RefactoringStatus))
1256:                            final VariableDeclarationFragment frag = (VariableDeclarationFragment) ((FieldDeclaration) declaration)
1257:                                    .fragments().get(0);
1258:
1259:                            if (!Modifier.isFinal(declaration.getModifiers())) {
1260:                                // Don't create a delegate for non-final fields
1261:                                result
1262:                                        .addInfo(
1263:                                                Messages
1264:                                                        .format(
1265:                                                                RefactoringCoreMessages.DelegateCreator_cannot_create_field_delegate_not_final,
1266:                                                                frag.getName()),
1267:                                                null);
1268:                            } else if (frag.getInitializer() == null) {
1269:                                // Don't create a delegate without an initializer.
1270:                                result
1271:                                        .addInfo(
1272:                                                Messages
1273:                                                        .format(
1274:                                                                RefactoringCoreMessages.DelegateCreator_cannot_create_field_delegate_no_initializer,
1275:                                                                frag.getName()),
1276:                                                null);
1277:                            } else {
1278:                                DelegateFieldCreator creator = new DelegateFieldCreator();
1279:                                creator.setDeclaration(declaration);
1280:                                creator
1281:                                        .setDeclareDeprecated(fDelegateDeprecation);
1282:                                creator.setSourceRewrite(fSource);
1283:                                creator.setCopy(false);
1284:                                creator.setNewLocation(getDestinationBinding());
1285:                                creator.prepareDelegate();
1286:                                creator.createEdit();
1287:
1288:                                removeImportsOf = frag.getInitializer();
1289:                                addedDelegate = true;
1290:                            }
1291:                        }
1292:                        if (declaration instanceof  AbstractTypeDeclaration) {
1293:                            result
1294:                                    .addInfo(
1295:                                            Messages
1296:                                                    .format(
1297:                                                            RefactoringCoreMessages.DelegateCreator_cannot_create_delegate_for_type,
1298:                                                            ((AbstractTypeDeclaration) declaration)
1299:                                                                    .getName()
1300:                                                                    .getIdentifier()),
1301:                                            null);
1302:                        }
1303:                    }
1304:
1305:                    if (!addedDelegate) {
1306:                        fSource.getASTRewrite().remove(declaration, delete);
1307:                        removeImportsOf = declaration;
1308:                    }
1309:
1310:                    if (removeImportsOf != null && fSource != fTarget)
1311:                        fSource.getImportRemover().registerRemovedNode(
1312:                                removeImportsOf);
1313:
1314:                    ASTNode node = fTarget.getASTRewrite()
1315:                            .createStringPlaceholder(sources[i],
1316:                                    declaration.getNodeType());
1317:                    List container = containerRewrite.getRewrittenList();
1318:                    int insertionIndex = ASTNodes.getInsertionIndex(
1319:                            (BodyDeclaration) node, container);
1320:                    containerRewrite.insertAt(node, insertionIndex, add);
1321:                }
1322:                return result;
1323:            }
1324:
1325:            private BodyDeclaration[] getASTMembers(RefactoringStatus status)
1326:                    throws JavaModelException {
1327:                BodyDeclaration[] result = new BodyDeclaration[fMembersToMove.length];
1328:                for (int i = 0; i < fMembersToMove.length; i++) {
1329:                    IMember member = fMembersToMove[i];
1330:                    ASTNode node = NodeFinder.perform(fSource.getRoot(), member
1331:                            .getNameRange());
1332:                    result[i] = (BodyDeclaration) ASTNodes.getParent(node,
1333:                            BodyDeclaration.class);
1334:
1335:                    //Fix for bug 42383: exclude multiple VariableDeclarationFragments ("int a=1, b=2")
1336:                    //ReferenceAnalyzer#visit(FieldDeclaration node) depends on fragments().size() != 1 !
1337:                    if (result[i] instanceof  FieldDeclaration
1338:                            && ((FieldDeclaration) result[i]).fragments()
1339:                                    .size() != 1) {
1340:                        status
1341:                                .addFatalError(RefactoringCoreMessages.MoveMembersRefactoring_multi_var_fields);
1342:                        return result;
1343:                    }
1344:
1345:                }
1346:
1347:                //Sorting members is important for field declarations referring to previous fields.
1348:                Arrays.sort(result, new Comparator() {
1349:                    public int compare(Object o1, Object o2) {
1350:                        return ((BodyDeclaration) o1).getStartPosition()
1351:                                - ((BodyDeclaration) o2).getStartPosition();
1352:                    }
1353:                });
1354:                return result;
1355:            }
1356:
1357:            public RefactoringStatus initialize(
1358:                    final RefactoringArguments arguments) {
1359:                if (arguments instanceof  JavaRefactoringArguments) {
1360:                    final JavaRefactoringArguments extended = (JavaRefactoringArguments) arguments;
1361:                    String handle = extended
1362:                            .getAttribute(JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT);
1363:                    if (handle != null) {
1364:                        final IJavaElement element = JavaRefactoringDescriptorUtil
1365:                                .handleToElement(extended.getProject(), handle,
1366:                                        false);
1367:                        if (element == null
1368:                                || !element.exists()
1369:                                || element.getElementType() != IJavaElement.TYPE)
1370:                            return ScriptableRefactoring
1371:                                    .createInputFatalStatus(
1372:                                            element,
1373:                                            getRefactoring().getName(),
1374:                                            IJavaRefactorings.MOVE_STATIC_MEMBERS);
1375:                        else {
1376:                            fDestinationType = (IType) element;
1377:                            fDestinationTypeName = fDestinationType
1378:                                    .getFullyQualifiedName();
1379:                        }
1380:                    } else
1381:                        return RefactoringStatus
1382:                                .createFatalErrorStatus(Messages
1383:                                        .format(
1384:                                                RefactoringCoreMessages.InitializableRefactoring_argument_not_exist,
1385:                                                JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT));
1386:                    final String delegate = extended
1387:                            .getAttribute(ATTRIBUTE_DELEGATE);
1388:                    if (delegate != null) {
1389:                        fDelegateUpdating = Boolean.valueOf(delegate)
1390:                                .booleanValue();
1391:                    } else
1392:                        return RefactoringStatus
1393:                                .createFatalErrorStatus(Messages
1394:                                        .format(
1395:                                                RefactoringCoreMessages.InitializableRefactoring_argument_not_exist,
1396:                                                ATTRIBUTE_DELEGATE));
1397:                    final String deprecate = extended
1398:                            .getAttribute(ATTRIBUTE_DEPRECATE);
1399:                    if (deprecate != null) {
1400:                        fDelegateDeprecation = Boolean.valueOf(deprecate)
1401:                                .booleanValue();
1402:                    } else
1403:                        return RefactoringStatus
1404:                                .createFatalErrorStatus(Messages
1405:                                        .format(
1406:                                                RefactoringCoreMessages.InitializableRefactoring_argument_not_exist,
1407:                                                ATTRIBUTE_DEPRECATE));
1408:                    int count = 1;
1409:                    final List elements = new ArrayList();
1410:                    String attribute = JavaRefactoringDescriptorUtil.ATTRIBUTE_ELEMENT
1411:                            + count;
1412:                    final RefactoringStatus status = new RefactoringStatus();
1413:                    while ((handle = extended.getAttribute(attribute)) != null) {
1414:                        final IJavaElement element = JavaRefactoringDescriptorUtil
1415:                                .handleToElement(extended.getProject(), handle,
1416:                                        false);
1417:                        if (element == null || !element.exists())
1418:                            status
1419:                                    .merge(ScriptableRefactoring
1420:                                            .createInputWarningStatus(
1421:                                                    element,
1422:                                                    getRefactoring().getName(),
1423:                                                    IJavaRefactorings.MOVE_STATIC_MEMBERS));
1424:                        else
1425:                            elements.add(element);
1426:                        count++;
1427:                        attribute = JavaRefactoringDescriptorUtil.ATTRIBUTE_ELEMENT
1428:                                + count;
1429:                    }
1430:                    fMembersToMove = (IMember[]) elements
1431:                            .toArray(new IMember[elements.size()]);
1432:                    if (elements.isEmpty())
1433:                        return ScriptableRefactoring.createInputFatalStatus(
1434:                                null, getRefactoring().getName(),
1435:                                IJavaRefactorings.MOVE_STATIC_MEMBERS);
1436:                    IJavaProject project = null;
1437:                    if (fMembersToMove.length > 0)
1438:                        project = fMembersToMove[0].getJavaProject();
1439:                    fPreferences = JavaPreferencesSettings
1440:                            .getCodeGenerationSettings(project);
1441:                    if (!status.isOK())
1442:                        return status;
1443:                } else
1444:                    return RefactoringStatus
1445:                            .createFatalErrorStatus(RefactoringCoreMessages.InitializableRefactoring_inacceptable_arguments);
1446:                return new RefactoringStatus();
1447:            }
1448:
1449:            public boolean canEnableComment() {
1450:                return true;
1451:            }
1452:
1453:            public String getComment() {
1454:                return fComment;
1455:            }
1456:
1457:            public void setComment(String comment) {
1458:                fComment = comment;
1459:            }
1460:
1461:            public String getDelegateUpdatingTitle(boolean plural) {
1462:                if (plural)
1463:                    return RefactoringCoreMessages.DelegateMethodCreator_keep_original_moved_plural;
1464:                else
1465:                    return RefactoringCoreMessages.DelegateMethodCreator_keep_original_moved_singular;
1466:            }
1467:        }
w___w___w_._ja__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.