| /******************************************************************************* |
| * Copyright (c) 2000, 2011 IBM Corporation and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jdt.internal.corext.refactoring.participants; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.List; |
| |
| import org.eclipse.core.runtime.Assert; |
| import org.eclipse.core.runtime.IPath; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.resources.mapping.IResourceChangeDescriptionFactory; |
| |
| import org.eclipse.ltk.core.refactoring.RefactoringStatus; |
| import org.eclipse.ltk.core.refactoring.participants.CopyArguments; |
| import org.eclipse.ltk.core.refactoring.participants.CopyParticipant; |
| import org.eclipse.ltk.core.refactoring.participants.CreateArguments; |
| import org.eclipse.ltk.core.refactoring.participants.CreateParticipant; |
| import org.eclipse.ltk.core.refactoring.participants.DeleteArguments; |
| import org.eclipse.ltk.core.refactoring.participants.DeleteParticipant; |
| import org.eclipse.ltk.core.refactoring.participants.MoveArguments; |
| import org.eclipse.ltk.core.refactoring.participants.MoveParticipant; |
| import org.eclipse.ltk.core.refactoring.participants.ParticipantManager; |
| import org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant; |
| import org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor; |
| import org.eclipse.ltk.core.refactoring.participants.RenameArguments; |
| import org.eclipse.ltk.core.refactoring.participants.RenameParticipant; |
| import org.eclipse.ltk.core.refactoring.participants.SharableParticipants; |
| |
| |
| /** |
| * A data structure to collect resource modifications. |
| * |
| * @since 3.0 |
| */ |
| public class ResourceModifications { |
| |
| private List<IResource> fCreate; |
| private List<IResource> fDelete; |
| |
| private List<IResource> fMove; |
| private List<MoveArguments> fMoveArguments; |
| |
| private List<IResource> fRename; |
| private List<RenameArguments> fRenameArguments; |
| |
| private List<IResource> fCopy; |
| private List<CopyArguments> fCopyArguments; |
| |
| private int fIgnoreCount; |
| private List<DeltaDescription> fDeltaDescriptions; |
| |
| public static abstract class DeltaDescription { |
| protected IResource fResource; |
| public DeltaDescription(IResource resource) { |
| fResource= resource; |
| } |
| public abstract void buildDelta(IResourceChangeDescriptionFactory builder); |
| public abstract IPath getDestinationPath(); |
| |
| } |
| public static class DeleteDescription extends DeltaDescription { |
| public DeleteDescription(IResource resource) { |
| super(resource); |
| } |
| @Override |
| public void buildDelta(IResourceChangeDescriptionFactory builder) { |
| builder.delete(fResource); |
| } |
| @Override |
| public IPath getDestinationPath() { |
| return null; |
| } |
| } |
| public static class ChangedDescription extends DeltaDescription { |
| public ChangedDescription(IFile resource) { |
| super(resource); |
| } |
| @Override |
| public void buildDelta(IResourceChangeDescriptionFactory builder) { |
| builder.change((IFile)fResource); |
| } |
| @Override |
| public IPath getDestinationPath() { |
| return null; |
| } |
| } |
| public static class CreateDescription extends DeltaDescription { |
| public CreateDescription(IResource resource) { |
| super(resource); |
| } |
| @Override |
| public void buildDelta(IResourceChangeDescriptionFactory builder) { |
| builder.create(fResource); |
| } |
| @Override |
| public IPath getDestinationPath() { |
| return fResource.getFullPath(); |
| } |
| } |
| public static class MoveDescription extends DeltaDescription { |
| private IPath fDestination; |
| public MoveDescription(IResource resource, IPath destination) { |
| super(resource); |
| fDestination= destination; |
| } |
| @Override |
| public void buildDelta(IResourceChangeDescriptionFactory builder) { |
| IResource existing= ResourcesPlugin.getWorkspace().getRoot().findMember(fDestination); |
| if (existing != null && !existing.equals(fResource)) { |
| builder.delete(existing); |
| } |
| builder.move(fResource, fDestination); |
| } |
| @Override |
| public IPath getDestinationPath() { |
| return fDestination; |
| } |
| } |
| public static class CopyDescription extends DeltaDescription { |
| private IPath fDestination; |
| public CopyDescription(IResource resource, IPath destination) { |
| super(resource); |
| fDestination= destination; |
| } |
| @Override |
| public void buildDelta(IResourceChangeDescriptionFactory builder) { |
| IResource existing= ResourcesPlugin.getWorkspace().getRoot().findMember(fDestination); |
| if (existing != null && !existing.equals(fResource)) { |
| builder.delete(existing); |
| } |
| builder.copy(fResource, fDestination); |
| } |
| @Override |
| public IPath getDestinationPath() { |
| return fDestination; |
| } |
| } |
| |
| /** |
| * Adds the given file to the list of changed files. |
| * |
| * @param file the changed file |
| */ |
| public void addChanged(IFile file) { |
| if (fIgnoreCount == 0) { |
| internalAdd(new ChangedDescription(file)); |
| } |
| } |
| |
| /** |
| * Adds the given resource to the list of resources |
| * to be created. |
| * |
| * @param create the resource to be add to the list of |
| * resources to be created |
| */ |
| public void addCreate(IResource create) { |
| if (fCreate == null) |
| fCreate= new ArrayList<>(2); |
| fCreate.add(create); |
| if (fIgnoreCount == 0) { |
| internalAdd(new CreateDescription(create)); |
| } |
| } |
| |
| /** |
| * Adds the given resource to the list of resources |
| * to be deleted. |
| * |
| * @param delete the resource to be deleted |
| */ |
| public void addDelete(IResource delete) { |
| if (fDelete == null) |
| fDelete= new ArrayList<>(2); |
| fDelete.add(delete); |
| if (fIgnoreCount == 0) { |
| internalAdd(new DeleteDescription(delete)); |
| } |
| } |
| |
| /** |
| * Adds the given resource to the list of resources |
| * to be moved. |
| * |
| * @param move the resource to be moved |
| * @param arguments the move arguments |
| */ |
| public void addMove(IResource move, MoveArguments arguments) { |
| if (fMove == null) { |
| fMove= new ArrayList<>(2); |
| fMoveArguments= new ArrayList<>(2); |
| } |
| fMove.add(move); |
| fMoveArguments.add(arguments); |
| if (fIgnoreCount == 0) { |
| IPath destination= ((IResource)arguments.getDestination()).getFullPath().append(move.getName()); |
| internalAdd(new MoveDescription(move, destination)); |
| } |
| } |
| |
| /** |
| * Adds the given resource to the list of resources |
| * to be copied. |
| * |
| * @param copy the resource to be copied |
| * @param arguments the copy arguments |
| */ |
| public void addCopy(IResource copy, CopyArguments arguments) { |
| if (fCopy == null) { |
| fCopy= new ArrayList<>(2); |
| fCopyArguments= new ArrayList<>(2); |
| } |
| fCopy.add(copy); |
| fCopyArguments.add(arguments); |
| addCopyDelta(copy, arguments); |
| } |
| |
| /** |
| * Adds the given resource to the list of renamed |
| * resources. |
| * |
| * @param rename the resource to be renamed |
| * @param arguments the arguments of the rename |
| */ |
| public void addRename(IResource rename, RenameArguments arguments) { |
| Assert.isNotNull(rename); |
| Assert.isNotNull(arguments); |
| if (fRename == null) { |
| fRename= new ArrayList<>(2); |
| fRenameArguments= new ArrayList<>(2); |
| } |
| fRename.add(rename); |
| fRenameArguments.add(arguments); |
| if (fIgnoreCount == 0) { |
| IPath newPath= rename.getFullPath().removeLastSegments(1).append(arguments.getNewName()); |
| internalAdd(new MoveDescription(rename, newPath)); |
| } |
| } |
| |
| public RefactoringParticipant[] getParticipants(RefactoringStatus status, RefactoringProcessor processor, String[] natures, SharableParticipants shared) { |
| List<RefactoringParticipant> result= new ArrayList<>(5); |
| if (fDelete != null) { |
| DeleteArguments arguments= new DeleteArguments(); |
| for (IResource resource : fDelete) { |
| DeleteParticipant[] deletes= ParticipantManager.loadDeleteParticipants(status, |
| processor, resource, |
| arguments, natures, shared); |
| result.addAll(Arrays.asList(deletes)); |
| } |
| } |
| if (fCreate != null) { |
| CreateArguments arguments= new CreateArguments(); |
| for (IResource resource : fCreate) { |
| CreateParticipant[] creates= ParticipantManager.loadCreateParticipants(status, |
| processor, resource, |
| arguments, natures, shared); |
| result.addAll(Arrays.asList(creates)); |
| } |
| } |
| if (fMove != null) { |
| for (int i= 0; i < fMove.size(); i++) { |
| Object element= fMove.get(i); |
| MoveArguments arguments= fMoveArguments.get(i); |
| MoveParticipant[] moves= ParticipantManager.loadMoveParticipants(status, |
| processor, element, |
| arguments, natures, shared); |
| result.addAll(Arrays.asList(moves)); |
| |
| } |
| } |
| if (fCopy != null) { |
| for (int i= 0; i < fCopy.size(); i++) { |
| Object element= fCopy.get(i); |
| CopyArguments arguments= fCopyArguments.get(i); |
| CopyParticipant[] copies= ParticipantManager.loadCopyParticipants(status, |
| processor, element, |
| arguments, natures, shared); |
| result.addAll(Arrays.asList(copies)); |
| } |
| } |
| if (fRename != null) { |
| for (int i= 0; i < fRename.size(); i++) { |
| Object resource= fRename.get(i); |
| RenameArguments arguments= fRenameArguments.get(i); |
| RenameParticipant[] renames= ParticipantManager.loadRenameParticipants(status, |
| processor, resource, |
| arguments, natures, shared); |
| result.addAll(Arrays.asList(renames)); |
| } |
| } |
| return result.toArray(new RefactoringParticipant[result.size()]); |
| } |
| |
| public void ignoreForDelta() { |
| fIgnoreCount++; |
| } |
| |
| public void trackForDelta() { |
| fIgnoreCount--; |
| } |
| |
| public void addDelta(DeltaDescription description) { |
| if (fIgnoreCount > 0) |
| return; |
| internalAdd(description); |
| } |
| |
| public void addCopyDelta(IResource copy, CopyArguments arguments) { |
| if (fIgnoreCount == 0) { |
| IPath destination= ((IResource)arguments.getDestination()).getFullPath().append(copy.getName()); |
| internalAdd(new CopyDescription(copy, destination)); |
| } |
| } |
| |
| /** |
| * Checks if the resource will exist in the future based on |
| * the recorded resource modifications. |
| * |
| * @param resource the resource to check |
| * @return whether the resource will exist or not |
| */ |
| public boolean willExist(IResource resource) { |
| if (fDeltaDescriptions == null) |
| return false; |
| IPath fullPath= resource.getFullPath(); |
| for (DeltaDescription delta : fDeltaDescriptions) { |
| if (fullPath.equals(delta.getDestinationPath())) |
| return true; |
| } |
| return false; |
| } |
| |
| public void buildDelta(IResourceChangeDescriptionFactory builder) { |
| if (fDeltaDescriptions == null) |
| return; |
| for (DeltaDescription delta : fDeltaDescriptions) { |
| delta.buildDelta(builder); |
| } |
| } |
| |
| public static void buildMoveDelta(IResourceChangeDescriptionFactory builder, IResource resource, RenameArguments args) { |
| IPath newPath= resource.getFullPath().removeLastSegments(1).append(args.getNewName()); |
| new MoveDescription(resource, newPath).buildDelta(builder); |
| } |
| |
| public static void buildMoveDelta(IResourceChangeDescriptionFactory builder, IResource resource, MoveArguments args) { |
| IPath destination= ((IResource)args.getDestination()).getFullPath().append(resource.getName()); |
| new MoveDescription(resource, destination).buildDelta(builder); |
| } |
| |
| public static void buildCopyDelta(IResourceChangeDescriptionFactory builder, IResource resource, CopyArguments args) { |
| IPath destination= ((IResource)args.getDestination()).getFullPath().append(resource.getName()); |
| new CopyDescription(resource, destination).buildDelta(builder); |
| } |
| |
| private void internalAdd(DeltaDescription description) { |
| if (fDeltaDescriptions == null) |
| fDeltaDescriptions= new ArrayList<>(); |
| fDeltaDescriptions.add(description); |
| } |
| } |