1 11 package org.eclipse.compare.internal.patch; 12 13 import java.util.*; 14 15 import org.eclipse.compare.internal.Utilities; 16 import org.eclipse.compare.structuremergeviewer.Differencer; 17 import org.eclipse.core.resources.*; 18 import org.eclipse.core.runtime.*; 19 import org.eclipse.core.runtime.jobs.ISchedulingRule; 20 import org.eclipse.core.runtime.jobs.MultiRule; 21 import org.eclipse.swt.widgets.Shell; 22 23 29 public class WorkspacePatcher extends Patcher { 30 31 private DiffProject[] fDiffProjects; 32 private boolean fIsWorkspacePatch= false; 33 private final Map retargetedDiffs = new HashMap(); 34 35 public WorkspacePatcher() { 36 } 38 39 public WorkspacePatcher(IResource target) { 40 setTarget(target); 41 } 42 43 protected void patchParsed(PatchReader patchReader) { 44 super.patchParsed(patchReader); 45 fDiffProjects = patchReader.getDiffProjects(); 46 fIsWorkspacePatch = patchReader.isWorkspacePatch(); 47 } 48 49 public DiffProject[] getDiffProjects() { 50 return fDiffProjects; 51 } 52 53 boolean isWorkspacePatch() { 54 return fIsWorkspacePatch; 55 } 56 57 59 public void applyAll(IProgressMonitor pm, Shell shell, String title) throws CoreException { 60 if (!fIsWorkspacePatch) { 61 super.applyAll(pm, shell, title); 62 } else { 63 final int WORK_UNIT= 10; 64 65 List list= new ArrayList(); 67 for (int j= 0; j < fDiffProjects.length; j++) { 68 DiffProject diffProject= fDiffProjects[j]; 69 if (diffProject.getProject().isAccessible()) 70 list.addAll(Arrays.asList(getTargetFiles(diffProject))); 71 } 72 if (!Utilities.validateResources(list, shell, title)) 74 return; 75 76 FileDiff[] diffs = getDiffs(); 77 if (pm != null) { 78 String message= PatchMessages.Patcher_Task_message; 79 pm.beginTask(message, diffs.length * WORK_UNIT); 80 } 81 82 for (int i= 0; i < diffs.length; i++) { 83 84 int workTicks= WORK_UNIT; 85 86 FileDiff diff= diffs[i]; 87 if (isAccessible(diff)) { 88 IFile file= getTargetFile(diff); 89 IPath path= file.getProjectRelativePath(); 90 if (pm != null) 91 pm.subTask(path.toString()); 92 createPath(file.getProject(), path); 93 94 List failed= new ArrayList(); 95 96 int type= diff.getDiffType(isReversed()); 97 switch (type) { 98 case Differencer.ADDITION : 99 List result= apply(diff, file, true, failed); 101 if (result != null) 102 store(createString(isPreserveLineDelimeters(), result), file, new SubProgressMonitor(pm, workTicks)); 103 workTicks -= WORK_UNIT; 104 break; 105 case Differencer.DELETION : 106 file.delete(true, true, new SubProgressMonitor(pm, workTicks)); 107 workTicks -= WORK_UNIT; 108 break; 109 case Differencer.CHANGE : 110 result= apply(diff, file, false, failed); 112 if (result != null) 113 store(createString(isPreserveLineDelimeters(), result), file, new SubProgressMonitor(pm, workTicks)); 114 workTicks -= WORK_UNIT; 115 break; 116 } 117 118 if (isGenerateRejectFile() && failed.size() > 0) { 119 IPath pp= null; 120 if (path.segmentCount() > 1) { 121 pp= path.removeLastSegments(1); 122 pp= pp.append(path.lastSegment() + REJECT_FILE_EXTENSION); 123 } else 124 pp= new Path(path.lastSegment() + REJECT_FILE_EXTENSION); 125 file= createPath(file.getProject(), pp); 126 if (file != null) { 127 store(getRejected(failed), file, pm); 128 try { 129 IMarker marker= file.createMarker(MARKER_TYPE); 130 marker.setAttribute(IMarker.MESSAGE, PatchMessages.Patcher_Marker_message); 131 marker.setAttribute(IMarker.PRIORITY, IMarker.PRIORITY_HIGH); 132 } catch (CoreException ex) { 133 } 135 } 136 } 137 } 138 139 if (pm != null) { 140 if (pm.isCanceled()) 141 break; 142 if (workTicks > 0) 143 pm.worked(workTicks); 144 } 145 } 146 } 147 } 148 149 private boolean isAccessible(FileDiff diff) { 150 return isEnabled(diff) && diff.getProject().getProject().isAccessible(); 151 } 152 153 159 public IFile[] getTargetFiles(DiffProject project) { 160 List files= new ArrayList(); 161 FileDiff[] diffs = project.getFileDiffs(); 162 for (int i = 0; i < diffs.length; i++) { 163 FileDiff diff = diffs[i]; 164 if (isEnabled(diff)) { 165 files.add(getTargetFile(diff)); 166 } 167 } 168 return (IFile[]) files.toArray(new IFile[files.size()]); 169 } 170 171 protected IFile getTargetFile(FileDiff diff) { 172 IPath path = diff.getStrippedPath(getStripPrefixSegments(), isReversed()); 173 DiffProject project = getProject(diff); 174 if (project != null) 175 return project.getFile(path); 176 return super.getTargetFile(diff); 177 } 178 179 private IPath getFullPath(FileDiff diff) { 180 IPath path = diff.getStrippedPath(getStripPrefixSegments(), isReversed()); 181 DiffProject project = getProject(diff); 182 if (project != null) 183 return project.getFile(path).getFullPath(); 184 return getTarget().getFullPath().append(path); 185 } 186 187 public ISchedulingRule[] getTargetProjects() { 188 List projects= new ArrayList(); 189 IResourceRuleFactory ruleFactory= ResourcesPlugin.getWorkspace().getRuleFactory(); 190 for (int i= 0; i < fDiffProjects.length; i++) { 192 IProject tempProject= fDiffProjects[i].getProject(); 193 ISchedulingRule scheduleRule= ruleFactory.modifyRule(tempProject.getFile(IProjectDescription.DESCRIPTION_FILE_NAME)); 199 MultiRule multiRule= new MultiRule(new ISchedulingRule[] { scheduleRule, tempProject } ); 200 projects.add(multiRule); 201 } 202 203 return (ISchedulingRule[]) projects.toArray(new ISchedulingRule[projects.size()]); 204 } 205 206 public void setDiffProjects(DiffProject[] newProjectArray) { 207 fDiffProjects = new DiffProject[newProjectArray.length]; 208 System.arraycopy(newProjectArray,0, fDiffProjects, 0, newProjectArray.length); 209 } 210 211 public void removeProject(DiffProject project) { 212 DiffProject[] temp = new DiffProject[fDiffProjects.length - 1]; 213 int counter = 0; 214 for (int i = 0; i < fDiffProjects.length; i++) { 215 if (fDiffProjects[i] != project){ 216 temp[counter++] = fDiffProjects[i]; 217 } 218 } 219 fDiffProjects = temp; 220 } 221 222 protected Object getElementParent(Object element) { 223 if (element instanceof FileDiff && fDiffProjects != null) { 224 FileDiff diff = (FileDiff) element; 225 for (int i = 0; i < fDiffProjects.length; i++) { 226 DiffProject project = fDiffProjects[i]; 227 if (project.contains(diff)) 228 return project; 229 } 230 } 231 return null; 232 } 233 234 public boolean isRetargeted(Object object) { 235 return retargetedDiffs.containsKey(object); 236 } 237 238 public IPath getOriginalPath(Object object) { 239 return (IPath)retargetedDiffs.get(object); 240 } 241 242 public void retargetDiff(FileDiff diff, IFile file) { 243 retargetedDiffs.put(diff, diff.getPath(false)); 244 Hunk[] hunks = diff.getHunks(); 245 246 if (isWorkspacePatch()){ 247 diff.getProject().remove(diff); 249 } 250 removeDiff(diff); 251 FileDiff newDiff = getDiffForFile(file); 252 for (int i = 0; i < hunks.length; i++) { 253 Hunk hunk = hunks[i]; 254 newDiff.add(hunk); 255 } 256 } 257 258 private FileDiff getDiffForFile(IFile file) { 259 DiffProject diffProject = null; 260 FileDiff[] diffsToCheck; 261 if (isWorkspacePatch()){ 262 IProject project = file.getProject(); 264 DiffProject[] diffProjects = getDiffProjects(); 265 for (int i = 0; i < diffProjects.length; i++) { 266 if (diffProjects[i].getProject().equals(project)){ 267 diffProject = diffProjects[i]; 268 break; 269 } 270 } 271 if (diffProject == null){ 273 diffProject = addDiffProjectForProject(project); 274 } 275 diffsToCheck = diffProject.getFileDiffs(); 276 } else { 277 diffsToCheck = getDiffs(); 278 } 279 for (int i = 0; i < diffsToCheck.length; i++) { 281 FileDiff fileDiff = diffsToCheck[i]; 282 if (isDiffForFile(fileDiff, file)) { 283 return fileDiff; 284 } 285 } 286 287 IPath path = getDiffPath(file); 289 FileDiff newDiff = new FileDiff(path, 0, path, 0); 290 if (diffProject != null){ 291 diffProject.add(newDiff); 292 } 293 addDiff(newDiff); 294 return newDiff; 295 } 296 297 private IPath getDiffPath(IFile file) { 298 DiffProject project = getDiffProject(file.getProject()); 299 if (project != null) { 300 return file.getProjectRelativePath(); 301 } 302 return file.getFullPath().removeFirstSegments(getTarget().getFullPath().segmentCount()); 303 } 304 305 private boolean isDiffForFile(FileDiff fileDiff, IFile file) { 306 return getFullPath(fileDiff).equals(file.getFullPath()); 307 } 308 309 private DiffProject addDiffProjectForProject(IProject project) { 310 DiffProject[] diffProjects = getDiffProjects(); 311 DiffProject diffProject = new DiffProject(project); 312 DiffProject[] newProjectArray = new DiffProject[diffProjects.length + 1]; 313 System.arraycopy(diffProjects, 0, newProjectArray, 0, diffProjects.length); 314 newProjectArray[diffProjects.length] = diffProject; 315 setDiffProjects(newProjectArray); 316 return diffProject; 317 } 318 319 public void retargetHunk(Hunk hunk, IFile file) { 320 FileDiff newDiff = getDiffForFile(file); 321 newDiff.add(hunk); 322 } 323 324 public void retargetProject(DiffProject project, IProject targetProject) { 325 retargetedDiffs.put(project, project.getProject().getFullPath()); 326 FileDiff[] diffs = project.getFileDiffs(); 327 DiffProject selectedProject = getDiffProject(targetProject); 328 if (selectedProject == null) 329 selectedProject = addDiffProjectForProject(targetProject); 330 for (int i = 0; i < diffs.length; i++) { 332 selectedProject.add(diffs[i]); 333 } 334 removeProject(project); 336 } 337 338 346 private DiffProject getDiffProject(IProject project) { 347 if (!isWorkspacePatch()) 348 return null; 349 DiffProject[] projects = getDiffProjects(); 350 for (int i = 0; i < projects.length; i++) { 351 if (projects[i].getProject().equals(project)) 352 return projects[i]; 353 } 354 return null; 355 } 356 357 int getStripPrefixSegments() { 358 if (isWorkspacePatch()) 360 return 0; 361 return super.getStripPrefixSegments(); 362 } 363 364 } 365 | Popular Tags |