1 /******************************************************************************* 2 * Copyright (c) 2000, 2016 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 *******************************************************************************/ 14 package org.eclipse.jdt.internal.corext.refactoring.changes; 15 16 import org.eclipse.core.runtime.Assert; 17 import org.eclipse.core.runtime.CoreException; 18 import org.eclipse.core.runtime.IPath; 19 import org.eclipse.core.runtime.IProgressMonitor; 20 import org.eclipse.core.runtime.SubProgressMonitor; 21 22 import org.eclipse.core.resources.IProject; 23 import org.eclipse.core.resources.IProjectDescription; 24 import org.eclipse.core.resources.IResource; 25 26 import org.eclipse.ltk.core.refactoring.Change; 27 28 import org.eclipse.jdt.core.IClasspathEntry; 29 import org.eclipse.jdt.core.IJavaProject; 30 import org.eclipse.jdt.core.JavaCore; 31 import org.eclipse.jdt.core.JavaModelException; 32 33 import org.eclipse.jdt.internal.corext.refactoring.AbstractJavaElementRenameChange; 34 import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages; 35 import org.eclipse.jdt.internal.corext.util.Messages; 36 37 import org.eclipse.jdt.internal.core.manipulation.util.BasicElementLabels; 38 39 public final class RenameJavaProjectChange extends AbstractJavaElementRenameChange { 40 41 private boolean fUpdateReferences; 42 RenameJavaProjectChange(IJavaProject project, String newName, boolean updateReferences)43 public RenameJavaProjectChange(IJavaProject project, String newName, boolean updateReferences) { 44 this(project.getPath(), project.getElementName(), newName, IResource.NULL_STAMP, updateReferences); 45 Assert.isTrue(!project.isReadOnly(), "should not be read only"); //$NON-NLS-1$ 46 } 47 RenameJavaProjectChange(IPath resourcePath, String oldName, String newName, long stampToRestore, boolean updateReferences)48 private RenameJavaProjectChange(IPath resourcePath, String oldName, String newName, long stampToRestore, boolean updateReferences) { 49 super(resourcePath, oldName, newName, stampToRestore); 50 fUpdateReferences= updateReferences; 51 52 setValidationMethod(VALIDATE_NOT_DIRTY); 53 } 54 createModifiedEntry(IClasspathEntry oldEntry)55 private IClasspathEntry createModifiedEntry(IClasspathEntry oldEntry) { 56 return JavaCore.newProjectEntry(createNewPath(), oldEntry.getAccessRules(), oldEntry.combineAccessRules(), oldEntry.getExtraAttributes(), oldEntry.isExported()); 57 } 58 59 @Override createNewPath()60 protected IPath createNewPath() { 61 return getResourcePath().removeLastSegments(1).append(getNewName()); 62 } 63 64 @Override createUndoChange(long stampToRestore)65 protected Change createUndoChange(long stampToRestore) throws JavaModelException { 66 return new RenameJavaProjectChange(createNewPath(), getNewName(), getOldName(), stampToRestore, fUpdateReferences); 67 } 68 69 @Override doRename(IProgressMonitor pm)70 protected void doRename(IProgressMonitor pm) throws CoreException { 71 try { 72 pm.beginTask(getName(), 2); 73 if (fUpdateReferences) 74 modifyClassPaths(new SubProgressMonitor(pm, 1)); 75 IProject project= getProject(); 76 if (project != null) { 77 IProjectDescription description= project.getDescription(); 78 description.setName(getNewName()); 79 project.move(description, IResource.FORCE | IResource.SHALLOW, new SubProgressMonitor(pm, 1)); 80 } 81 } finally { 82 pm.done(); 83 } 84 } 85 getJavaProject()86 private IJavaProject getJavaProject() { 87 return (IJavaProject) getModifiedElement(); 88 } 89 90 @Override getName()91 public String getName() { 92 String[] keys= new String[] { BasicElementLabels.getJavaElementName(getOldName()), BasicElementLabels.getJavaElementName(getNewName())}; 93 return Messages.format(RefactoringCoreMessages.RenameJavaProjectChange_rename, keys); 94 } 95 getProject()96 private IProject getProject() { 97 IJavaProject jp= getJavaProject(); 98 if (jp == null) 99 return null; 100 return jp.getProject(); 101 } 102 isOurEntry(IClasspathEntry cpe)103 private boolean isOurEntry(IClasspathEntry cpe) { 104 if (cpe.getEntryKind() != IClasspathEntry.CPE_PROJECT) 105 return false; 106 if (!cpe.getPath().equals(getResourcePath())) 107 return false; 108 return true; 109 } 110 modifyClassPath(IJavaProject referencingProject, IProgressMonitor pm)111 private void modifyClassPath(IJavaProject referencingProject, IProgressMonitor pm) throws JavaModelException { 112 pm.beginTask("", 1); //$NON-NLS-1$ 113 IClasspathEntry[] oldEntries= referencingProject.getRawClasspath(); 114 IClasspathEntry[] newEntries= new IClasspathEntry[oldEntries.length]; 115 for (int i= 0; i < newEntries.length; i++) { 116 if (isOurEntry(oldEntries[i])) 117 newEntries[i]= createModifiedEntry(oldEntries[i]); 118 else 119 newEntries[i]= oldEntries[i]; 120 } 121 referencingProject.setRawClasspath(newEntries, pm); 122 pm.done(); 123 } 124 modifyClassPaths(IProgressMonitor pm)125 private void modifyClassPaths(IProgressMonitor pm) throws JavaModelException { 126 IProject[] referencing= getProject().getReferencingProjects(); 127 pm.beginTask(RefactoringCoreMessages.RenameJavaProjectChange_update, referencing.length); 128 for (IProject p : referencing) { 129 IJavaProject jp= JavaCore.create(p); 130 if (jp != null && jp.exists()) { 131 modifyClassPath(jp, new SubProgressMonitor(pm, 1)); 132 } else { 133 pm.worked(1); 134 } 135 } 136 pm.done(); 137 } 138 } 139