1 /******************************************************************************* 2 * Copyright (c) 2011 BestSolution.at 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 * Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation 13 * Wim Jongman <wim.jongman@remainsoftware.com> Bug 432892: Eclipse 4 Application does not work after renaming the 14 * project name 15 ******************************************************************************/ 16 package org.eclipse.e4.tools.emf.editor3x.refactorparticipants; 17 18 import java.util.HashMap; 19 import java.util.Map; 20 21 import org.eclipse.core.resources.IFile; 22 import org.eclipse.core.resources.IProject; 23 import org.eclipse.core.runtime.CoreException; 24 import org.eclipse.core.runtime.IPath; 25 import org.eclipse.core.runtime.IProgressMonitor; 26 import org.eclipse.core.runtime.OperationCanceledException; 27 import org.eclipse.e4.tools.emf.editor3x.RefactorModel; 28 import org.eclipse.ltk.core.refactoring.CompositeChange; 29 import org.eclipse.ltk.core.refactoring.TextChange; 30 import org.eclipse.ltk.core.refactoring.TextFileChange; 31 import org.eclipse.pde.internal.ui.refactoring.MovedTextFileChange; 32 import org.eclipse.search.core.text.TextSearchEngine; 33 import org.eclipse.search.core.text.TextSearchMatchAccess; 34 import org.eclipse.search.core.text.TextSearchRequestor; 35 import org.eclipse.search.ui.text.FileTextSearchScope; 36 import org.eclipse.text.edits.MultiTextEdit; 37 import org.eclipse.text.edits.ReplaceEdit; 38 import org.eclipse.text.edits.TextEditGroup; 39 40 @SuppressWarnings("restriction") 41 class RefactorParticipantDelegate { 42 43 private static final String E4_MODEL_CHANGES = "Eclipse 4 Application Model Changes"; //$NON-NLS-1$ 44 45 /** 46 * Creates a set of changes and returns a new {@link CompositeChange} or 47 * adds the changes to the passed {@link CompositeChange}. 48 * 49 * @param pProgressMonitor 50 * @param pModel 51 * 52 * @return a set of changes in a {@link CompositeChange} 53 * @throws CoreException 54 * @throws OperationCanceledException 55 */ createChange(IProgressMonitor pProgressMonitor, final RefactorModel pModel)56 public static CompositeChange createChange(IProgressMonitor pProgressMonitor, final RefactorModel pModel) 57 throws CoreException, OperationCanceledException { 58 59 final String[] filenames = { "*.e4xmi" }; //$NON-NLS-1$ 60 final FileTextSearchScope scope = FileTextSearchScope.newWorkspaceScope(filenames, false); 61 62 final Map<IFile, TextFileChange> changes = new HashMap<>(); 63 final TextSearchRequestor searchRequestor = new TextSearchRequestor() { 64 65 @Override 66 public boolean acceptPatternMatch(TextSearchMatchAccess matchAccess) throws CoreException { 67 final IFile file = matchAccess.getFile(); 68 TextFileChange change = changes.get(file); 69 70 if (change == null) { 71 final TextChange textChange = pModel.getTextChange(file); 72 if (textChange != null) { 73 return false; 74 } 75 76 if (pModel.isProjectRename() 77 && file.getProject().equals(pModel.getOldProject())) { 78 // The project/resources get refactored before the 79 // TextChange is applied, therefore we need their 80 // future locations 81 final IProject newProject = pModel.getNewProject(); 82 83 // If the model is in a non-standard location the 84 // new project will keep that location, only the project 85 // will be changed 86 final IPath oldFile = file.getFullPath().removeFirstSegments( 87 1); 88 final IFile newFile = newProject.getFile(oldFile); 89 90 change = new MovedTextFileChange(file.getName(), 91 newFile, file); 92 change.setEdit(new MultiTextEdit()); 93 changes.put(file, change); 94 95 } else { 96 change = new TextFileChange(file.getName(), file); 97 change.setEdit(new MultiTextEdit()); 98 changes.put(file, change); 99 } 100 } 101 102 final ReplaceEdit edit = new ReplaceEdit( 103 matchAccess.getMatchOffset(), 104 matchAccess.getMatchLength(), 105 pModel.getNewTextCurrentIndex()); 106 change.addEdit(edit); 107 change.addTextEditGroup(new TextEditGroup(E4_MODEL_CHANGES, 108 edit)); 109 return true; 110 } 111 }; 112 113 CompositeChange result; 114 final TextSearchEngine searchEngine = TextSearchEngine.create(); 115 int count = pModel.getRenameCount(); 116 while (count > 0) { 117 pModel.setIndex(count - 1); 118 searchEngine.search( 119 scope, 120 searchRequestor, 121 TextSearchEngine.createPattern( 122 pModel.getOldTextCurrentIndex(), true, false), 123 pProgressMonitor); 124 count--; 125 } 126 127 if (changes.isEmpty()) { 128 return null; 129 } 130 131 result = new CompositeChange(E4_MODEL_CHANGES); 132 for (final TextFileChange c : changes.values()) { 133 result.add(c); 134 } 135 return result; 136 } 137 } 138