1 /******************************************************************************* 2 * Copyright (c) 2000, 2015 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.ltk.internal.core.refactoring.resource; 15 16 import java.util.ArrayList; 17 import java.util.Collections; 18 import java.util.List; 19 20 import org.eclipse.core.runtime.Assert; 21 import org.eclipse.core.runtime.IPath; 22 23 import org.eclipse.core.resources.IFile; 24 import org.eclipse.core.resources.IResource; 25 import org.eclipse.core.resources.mapping.IResourceChangeDescriptionFactory; 26 27 import org.eclipse.ltk.core.refactoring.RefactoringStatus; 28 import org.eclipse.ltk.core.refactoring.participants.CopyArguments; 29 import org.eclipse.ltk.core.refactoring.participants.CopyParticipant; 30 import org.eclipse.ltk.core.refactoring.participants.CreateArguments; 31 import org.eclipse.ltk.core.refactoring.participants.CreateParticipant; 32 import org.eclipse.ltk.core.refactoring.participants.DeleteArguments; 33 import org.eclipse.ltk.core.refactoring.participants.DeleteParticipant; 34 import org.eclipse.ltk.core.refactoring.participants.MoveArguments; 35 import org.eclipse.ltk.core.refactoring.participants.MoveParticipant; 36 import org.eclipse.ltk.core.refactoring.participants.ParticipantManager; 37 import org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant; 38 import org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor; 39 import org.eclipse.ltk.core.refactoring.participants.RenameArguments; 40 import org.eclipse.ltk.core.refactoring.participants.RenameParticipant; 41 import org.eclipse.ltk.core.refactoring.participants.SharableParticipants; 42 43 /** 44 * A data structure to collect resource modifications. 45 * 46 * @since 3.4 47 */ 48 public class ResourceModifications { 49 50 private List<IResource> fCreate; 51 private List<IResource> fDelete; 52 53 private List<IResource> fMove; 54 private List<MoveArguments> fMoveArguments; 55 56 private List<IResource> fRename; 57 private List<RenameArguments> fRenameArguments; 58 59 private List<IResource> fCopy; 60 private List<CopyArguments> fCopyArguments; 61 62 private int fIgnoreCount; 63 private List<DeltaDescription> fDeltaDescriptions; 64 65 public static abstract class DeltaDescription { 66 protected IResource fResource; DeltaDescription(IResource resource)67 public DeltaDescription(IResource resource) { 68 fResource= resource; 69 } buildDelta(IResourceChangeDescriptionFactory builder)70 public abstract void buildDelta(IResourceChangeDescriptionFactory builder); getDestinationPath()71 public abstract IPath getDestinationPath(); 72 73 } 74 public static class DeleteDescription extends DeltaDescription { DeleteDescription(IResource resource)75 public DeleteDescription(IResource resource) { 76 super(resource); 77 } 78 @Override buildDelta(IResourceChangeDescriptionFactory builder)79 public void buildDelta(IResourceChangeDescriptionFactory builder) { 80 builder.delete(fResource); 81 } 82 @Override getDestinationPath()83 public IPath getDestinationPath() { 84 return null; 85 } 86 } 87 public static class ChangedDescription extends DeltaDescription { ChangedDescription(IFile resource)88 public ChangedDescription(IFile resource) { 89 super(resource); 90 } 91 @Override buildDelta(IResourceChangeDescriptionFactory builder)92 public void buildDelta(IResourceChangeDescriptionFactory builder) { 93 builder.change((IFile)fResource); 94 } 95 @Override getDestinationPath()96 public IPath getDestinationPath() { 97 return null; 98 } 99 } 100 public static class CreateDescription extends DeltaDescription { CreateDescription(IResource resource)101 public CreateDescription(IResource resource) { 102 super(resource); 103 } 104 @Override buildDelta(IResourceChangeDescriptionFactory builder)105 public void buildDelta(IResourceChangeDescriptionFactory builder) { 106 builder.create(fResource); 107 } 108 @Override getDestinationPath()109 public IPath getDestinationPath() { 110 return fResource.getFullPath(); 111 } 112 } 113 public static class MoveDescription extends DeltaDescription { 114 private IPath fDestination; MoveDescription(IResource resource, IPath destination)115 public MoveDescription(IResource resource, IPath destination) { 116 super(resource); 117 fDestination= destination; 118 } 119 @Override buildDelta(IResourceChangeDescriptionFactory builder)120 public void buildDelta(IResourceChangeDescriptionFactory builder) { 121 builder.move(fResource, fDestination); 122 } 123 @Override getDestinationPath()124 public IPath getDestinationPath() { 125 return fDestination; 126 } 127 } 128 public static class CopyDescription extends DeltaDescription { 129 private IPath fDestination; CopyDescription(IResource resource, IPath destination)130 public CopyDescription(IResource resource, IPath destination) { 131 super(resource); 132 fDestination= destination; 133 } 134 @Override buildDelta(IResourceChangeDescriptionFactory builder)135 public void buildDelta(IResourceChangeDescriptionFactory builder) { 136 builder.copy(fResource, fDestination); 137 } 138 @Override getDestinationPath()139 public IPath getDestinationPath() { 140 return fDestination; 141 } 142 } 143 144 /** 145 * Adds the given file to the list of changed files. 146 * 147 * @param file the changed file 148 */ addChanged(IFile file)149 public void addChanged(IFile file) { 150 if (fIgnoreCount == 0) { 151 internalAdd(new ChangedDescription(file)); 152 } 153 } 154 155 /** 156 * Adds the given resource to the list of resources 157 * to be created. 158 * 159 * @param create the resource to be add to the list of 160 * resources to be created 161 */ addCreate(IResource create)162 public void addCreate(IResource create) { 163 if (fCreate == null) 164 fCreate= new ArrayList<>(2); 165 fCreate.add(create); 166 if (fIgnoreCount == 0) { 167 internalAdd(new CreateDescription(create)); 168 } 169 } 170 171 /** 172 * Adds the given resource to the list of resources 173 * to be deleted. 174 * 175 * @param delete the resource to be deleted 176 */ addDelete(IResource delete)177 public void addDelete(IResource delete) { 178 if (fDelete == null) 179 fDelete= new ArrayList<>(2); 180 fDelete.add(delete); 181 if (fIgnoreCount == 0) { 182 internalAdd(new DeleteDescription(delete)); 183 } 184 } 185 186 /** 187 * Adds the given resource to the list of resources 188 * to be moved. 189 * 190 * @param move the resource to be moved 191 * @param arguments the move arguments 192 */ addMove(IResource move, MoveArguments arguments)193 public void addMove(IResource move, MoveArguments arguments) { 194 if (fMove == null) { 195 fMove= new ArrayList<>(2); 196 fMoveArguments= new ArrayList<>(2); 197 } 198 fMove.add(move); 199 fMoveArguments.add(arguments); 200 if (fIgnoreCount == 0) { 201 IPath destination= ((IResource)arguments.getDestination()).getFullPath().append(move.getName()); 202 internalAdd(new MoveDescription(move, destination)); 203 } 204 } 205 206 /** 207 * Adds the given resource to the list of resources 208 * to be copied. 209 * 210 * @param copy the resource to be copied 211 * @param arguments the copy arguments 212 */ addCopy(IResource copy, CopyArguments arguments)213 public void addCopy(IResource copy, CopyArguments arguments) { 214 if (fCopy == null) { 215 fCopy= new ArrayList<>(2); 216 fCopyArguments= new ArrayList<>(2); 217 } 218 fCopy.add(copy); 219 fCopyArguments.add(arguments); 220 addCopyDelta(copy, arguments); 221 } 222 223 /** 224 * Adds the given resource to the list of renamed 225 * resources. 226 * 227 * @param rename the resource to be renamed 228 * @param arguments the arguments of the rename 229 */ addRename(IResource rename, RenameArguments arguments)230 public void addRename(IResource rename, RenameArguments arguments) { 231 Assert.isNotNull(rename); 232 Assert.isNotNull(arguments); 233 if (fRename == null) { 234 fRename= new ArrayList<>(2); 235 fRenameArguments= new ArrayList<>(2); 236 } 237 fRename.add(rename); 238 fRenameArguments.add(arguments); 239 if (fIgnoreCount == 0) { 240 IPath newPath= rename.getFullPath().removeLastSegments(1).append(arguments.getNewName()); 241 internalAdd(new MoveDescription(rename, newPath)); 242 } 243 } 244 getParticipants(RefactoringStatus status, RefactoringProcessor processor, String[] natures, SharableParticipants shared)245 public RefactoringParticipant[] getParticipants(RefactoringStatus status, RefactoringProcessor processor, String[] natures, SharableParticipants shared) { 246 List<RefactoringParticipant> result= new ArrayList<>(5); 247 if (fDelete != null) { 248 DeleteArguments arguments= new DeleteArguments(); 249 for (IResource iResource : fDelete) { 250 DeleteParticipant[] deletes= ParticipantManager.loadDeleteParticipants(status, 251 processor, iResource, 252 arguments, natures, shared); 253 Collections.addAll(result, deletes); 254 } 255 } 256 if (fCreate != null) { 257 CreateArguments arguments= new CreateArguments(); 258 for (IResource iResource : fCreate) { 259 CreateParticipant[] creates= ParticipantManager.loadCreateParticipants(status, 260 processor, iResource, 261 arguments, natures, shared); 262 Collections.addAll(result, creates); 263 } 264 } 265 if (fMove != null) { 266 for (int i= 0; i < fMove.size(); i++) { 267 Object element= fMove.get(i); 268 MoveArguments arguments= fMoveArguments.get(i); 269 MoveParticipant[] moves= ParticipantManager.loadMoveParticipants(status, 270 processor, element, 271 arguments, natures, shared); 272 Collections.addAll(result, moves); 273 274 } 275 } 276 if (fCopy != null) { 277 for (int i= 0; i < fCopy.size(); i++) { 278 Object element= fCopy.get(i); 279 CopyArguments arguments= fCopyArguments.get(i); 280 CopyParticipant[] copies= ParticipantManager.loadCopyParticipants(status, 281 processor, element, 282 arguments, natures, shared); 283 Collections.addAll(result, copies); 284 } 285 } 286 if (fRename != null) { 287 for (int i= 0; i < fRename.size(); i++) { 288 Object resource= fRename.get(i); 289 RenameArguments arguments= fRenameArguments.get(i); 290 RenameParticipant[] renames= ParticipantManager.loadRenameParticipants(status, 291 processor, resource, 292 arguments, natures, shared); 293 Collections.addAll(result, renames); 294 } 295 } 296 return result.toArray(new RefactoringParticipant[result.size()]); 297 } 298 ignoreForDelta()299 public void ignoreForDelta() { 300 fIgnoreCount++; 301 } 302 trackForDelta()303 public void trackForDelta() { 304 fIgnoreCount--; 305 } 306 addDelta(DeltaDescription description)307 public void addDelta(DeltaDescription description) { 308 if (fIgnoreCount > 0) 309 return; 310 internalAdd(description); 311 } 312 addCopyDelta(IResource copy, CopyArguments arguments)313 public void addCopyDelta(IResource copy, CopyArguments arguments) { 314 if (fIgnoreCount == 0) { 315 IPath destination= ((IResource)arguments.getDestination()).getFullPath().append(copy.getName()); 316 internalAdd(new CopyDescription(copy, destination)); 317 } 318 } 319 320 /** 321 * Checks if the resource will exist in the future based on 322 * the recorded resource modifications. 323 * 324 * @param resource the resource to check 325 * @return whether the resource will exist or not 326 */ willExist(IResource resource)327 public boolean willExist(IResource resource) { 328 if (fDeltaDescriptions == null) 329 return false; 330 IPath fullPath= resource.getFullPath(); 331 for (DeltaDescription delta : fDeltaDescriptions) { 332 if (fullPath.equals(delta.getDestinationPath())) 333 return true; 334 } 335 return false; 336 } 337 buildDelta(IResourceChangeDescriptionFactory builder)338 public void buildDelta(IResourceChangeDescriptionFactory builder) { 339 if (fDeltaDescriptions == null) 340 return; 341 for (DeltaDescription deltaDescription : fDeltaDescriptions) { 342 deltaDescription.buildDelta(builder); 343 } 344 } 345 buildMoveDelta(IResourceChangeDescriptionFactory builder, IResource resource, RenameArguments args)346 public static void buildMoveDelta(IResourceChangeDescriptionFactory builder, IResource resource, RenameArguments args) { 347 IPath newPath= resource.getFullPath().removeLastSegments(1).append(args.getNewName()); 348 builder.move(resource, newPath); 349 } 350 buildMoveDelta(IResourceChangeDescriptionFactory builder, IResource resource, MoveArguments args)351 public static void buildMoveDelta(IResourceChangeDescriptionFactory builder, IResource resource, MoveArguments args) { 352 IPath destination= ((IResource)args.getDestination()).getFullPath().append(resource.getName()); 353 builder.move(resource, destination); 354 } 355 buildCopyDelta(IResourceChangeDescriptionFactory builder, IResource resource, CopyArguments args)356 public static void buildCopyDelta(IResourceChangeDescriptionFactory builder, IResource resource, CopyArguments args) { 357 IPath destination= ((IResource)args.getDestination()).getFullPath().append(resource.getName()); 358 builder.copy(resource, destination); 359 } 360 internalAdd(DeltaDescription description)361 private void internalAdd(DeltaDescription description) { 362 if (fDeltaDescriptions == null) 363 fDeltaDescriptions= new ArrayList<>(); 364 fDeltaDescriptions.add(description); 365 } 366 } 367