1 11 package org.eclipse.team.internal.ccvs.ui.operations; 12 13 import java.io.*; 14 import java.util.*; 15 16 import org.eclipse.compare.patch.WorkspacePatcherUI; 17 import org.eclipse.core.resources.*; 18 import org.eclipse.core.resources.mapping.ResourceMapping; 19 import org.eclipse.core.runtime.*; 20 import org.eclipse.core.runtime.jobs.Job; 21 import org.eclipse.jface.dialogs.IDialogConstants; 22 import org.eclipse.jface.dialogs.MessageDialog; 23 import org.eclipse.osgi.util.NLS; 24 import org.eclipse.swt.widgets.Shell; 25 import org.eclipse.team.internal.ccvs.core.*; 26 import org.eclipse.team.internal.ccvs.core.client.*; 27 import org.eclipse.team.internal.ccvs.core.client.Command.LocalOption; 28 import org.eclipse.team.internal.ccvs.core.client.listeners.DiffListener; 29 import org.eclipse.team.internal.ccvs.core.connection.CVSCommunicationException; 30 import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; 31 import org.eclipse.team.internal.ccvs.ui.*; 32 import org.eclipse.team.internal.ccvs.ui.Policy; 33 import org.eclipse.ui.IWorkbenchPart; 34 35 public abstract class DiffOperation extends SingleCommandOperation { 36 37 private static final int UNIFIED_FORMAT = 0; 38 private static final int CONTEXT_FORMAT = 1; 39 private static final int STANDARD_FORMAT = 2; 40 41 protected boolean isMultiPatch; 42 protected boolean includeFullPathInformation; 43 protected PrintStream stream; 44 protected IPath patchRoot; 45 protected boolean patchHasContents; 46 protected boolean patchHasNewFiles; 47 48 49 private Object destination = null; 50 51 52 private class CustomizableEOLPrintStream extends PrintStream{ 53 54 private boolean error = false; 55 56 private String defaultLineEnding = "\n"; 58 public CustomizableEOLPrintStream(PrintStream openStream) { 59 super(openStream); 60 if(CVSProviderPlugin.getPlugin().isUsePlatformLineend()){ 61 defaultLineEnding = System.getProperty("line.separator"); } 63 } 64 65 public boolean checkError() { 66 return error || super.checkError(); 67 } 68 69 public void println() { 70 try{ 71 write(defaultLineEnding.getBytes()); 72 } catch (IOException e){ 73 error = true; 74 } 75 } 76 77 public void println(boolean x) { 78 print(x); 79 println(); 80 } 81 82 public void println(char x) { 83 print(x); 84 println(); 85 } 86 87 public void println(char[] x) { 88 print(x); 89 println(); 90 } 91 92 public void println(double x) { 93 print(x); 94 println(); 95 } 96 97 public void println(float x) { 98 print(x); 99 println(); 100 } 101 102 public void println(int x) { 103 print(x); 104 println(); 105 } 106 107 public void println(long x) { 108 print(x); 109 println(); 110 } 111 112 public void println(Object x) { 113 print(x); 114 println(); 115 } 116 117 public void println(String x) { 118 print(x); 119 println(); 120 } 121 } 122 123 public DiffOperation(IWorkbenchPart part, ResourceMapping[] mappings, LocalOption[] options, boolean isMultiPatch, boolean includeFullPathInformation, IPath patchRoot, Object destination) { 124 super(part, mappings, options); 125 this.isMultiPatch = isMultiPatch; 126 this.includeFullPathInformation=includeFullPathInformation; 127 this.patchRoot=patchRoot; 128 this.patchHasContents=false; 129 this.patchHasNewFiles=false; 130 this.destination = destination; 131 } 132 133 protected boolean shouldRun(){ 134 if (super.shouldRun() == false){ 135 return false; 136 } 137 Job[] jobs = Job.getJobManager().find(destination); 138 if(jobs.length != 0){ 139 MessageDialog question = new MessageDialog(getShell(), 140 CVSUIMessages.DiffOperation_CreatePatchConflictTitle, null, 141 NLS.bind(CVSUIMessages.DiffOperation_CreatePatchConflictMessage, destination.toString()), 142 MessageDialog.QUESTION, 143 new String []{IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL}, 144 1); 145 if(question.open() == 0){ 146 Job.getJobManager().cancel(destination); 147 } else { 148 return false; 149 } 150 } 151 return true; 152 } 153 154 public void execute(IProgressMonitor monitor) throws CVSException, InterruptedException { 155 try { 156 stream = new CustomizableEOLPrintStream(openStream()); 157 if (isMultiPatch){ 158 stream.println(WorkspacePatcherUI.getWorkspacePatchHeader()); 159 } 160 super.execute(monitor); 161 } finally { 162 if (stream != null) { 163 stream.close(); 164 } 165 } 166 } 167 168 172 protected abstract PrintStream openStream() throws CVSException; 173 174 protected void execute(CVSTeamProvider provider, IResource[] resources, boolean recurse, IProgressMonitor monitor) throws CVSException, InterruptedException { 175 176 final HashSet newFiles = new HashSet(); final HashSet existingFiles = new HashSet(); 180 monitor.beginTask(null,100); 181 final IProgressMonitor subMonitor = Policy.subMonitorFor(monitor,10); 182 for (int i = 0; i < resources.length; i++) { 183 IResource resource = resources[i]; 184 ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(resource); 185 cvsResource.accept(new ICVSResourceVisitor() { 186 public void visitFile(ICVSFile file) throws CVSException { 187 if (!(file.isIgnored())) { 188 if (!file.isManaged() || file.getSyncInfo().isAdded() ){ 189 if (file.exists()) 191 newFiles.add(file); 192 }else if (file.isModified(subMonitor)){ 193 existingFiles.add(file.getIResource()); 194 } 195 } 196 } 197 198 public void visitFolder(ICVSFolder folder) throws CVSException { 199 if (!folder.exists() || folder.isIgnored() ) { 202 return; 203 } 204 205 folder.acceptChildren(this); 206 207 } 208 }, recurse); 209 } 210 subMonitor.done(); 211 212 int format = STANDARD_FORMAT; 216 217 LocalOption[] localoptions = getLocalOptions(recurse); 218 for (int i = 0; i < localoptions.length; i++) { 219 LocalOption option = localoptions[i]; 220 if (option.equals(Diff.UNIFIED_FORMAT) || 221 isMultiPatch) { 222 format = UNIFIED_FORMAT; 223 } else if (option.equals(Diff.CONTEXT_FORMAT)) { 224 format = CONTEXT_FORMAT; 225 } 226 } 227 228 boolean haveAddedProjectHeader=false; 229 230 if (!existingFiles.isEmpty()){ 231 if (isMultiPatch && !haveAddedProjectHeader){ 232 haveAddedProjectHeader=true; 233 IProject project=resources[0].getProject(); 234 stream.println(WorkspacePatcherUI.getWorkspacePatchProjectHeader(project)); 235 } 236 try{ 237 super.execute(provider, (IResource[]) existingFiles.toArray(new IResource[existingFiles.size()]), recurse, Policy.subMonitorFor(monitor, 90)); 238 } catch(CVSCommunicationException ex){ CVSUIPlugin.openError(getShell(), null, null, ex, CVSUIPlugin.PERFORM_SYNC_EXEC | CVSUIPlugin.LOG_OTHER_EXCEPTIONS); 240 } catch (CVSException ex){ 241 } 243 } 244 245 if (!newFiles.isEmpty() && Diff.INCLUDE_NEWFILES.isElementOf(localoptions)){ 246 patchHasNewFiles=true; 248 249 if (isMultiPatch &&!haveAddedProjectHeader){ 250 haveAddedProjectHeader=true; 251 IProject project=resources[0].getProject(); 252 stream.println(WorkspacePatcherUI.getWorkspacePatchProjectHeader(project)); 253 } 254 255 for (Iterator iter = newFiles.iterator(); iter.hasNext();) { 256 ICVSFile cvsFile = (ICVSFile) iter.next(); 257 addFileToDiff(getNewFileRoot(cvsFile), cvsFile,stream,format); 258 } 259 } 260 261 monitor.done(); 262 } 263 264 private ICVSFolder getNewFileRoot(ICVSFile cvsFile) { 265 ICVSFolder patchRootFolder = getPatchRootFolder(); 266 if (patchRootFolder != null) 267 return patchRootFolder; 268 return CVSWorkspaceRoot.getCVSFolderFor(cvsFile.getIResource().getProject()); 269 } 270 271 protected IStatus executeCommand(Session session, CVSTeamProvider provider, ICVSResource[] resources, boolean recurse, IProgressMonitor monitor) throws CVSException, InterruptedException { 272 273 DiffListener diffListener = new DiffListener(stream); 274 275 IStatus status = Command.DIFF.execute(session, 276 Command.NO_GLOBAL_OPTIONS, 277 getLocalOptions(recurse), 278 resources, 279 diffListener, 280 monitor); 281 282 if (!patchHasContents) 285 patchHasContents = diffListener.wroteToStream(); 286 287 return status; 288 } 289 290 protected String getTaskName(CVSTeamProvider provider) { 291 return NLS.bind(CVSUIMessages.DiffOperation_0, new String []{provider.getProject().getName()}); 292 } 293 294 protected String getTaskName() { 295 return CVSUIMessages.DiffOperation_1; 296 } 297 298 private void addFileToDiff(ICVSFolder patchRoot, ICVSFile file, PrintStream printStream, int format) throws CVSException { 299 300 String nullFilePrefix = ""; String newFilePrefix = ""; String positionInfo = ""; String linePrefix = ""; 305 String pathString=""; 307 308 pathString= file.getRelativePath(patchRoot); 310 311 int lines = 0; 312 BufferedReader fileReader = new BufferedReader(new InputStreamReader(file.getContents())); 313 try { 314 while (fileReader.readLine() != null) { 315 lines++; 316 } 317 } catch (IOException e) { 318 throw CVSException.wrapException(file.getIResource(), NLS.bind(CVSMessages.CVSTeamProvider_errorAddingFileToDiff, new String [] { pathString }), e); 319 } finally { 320 try { 321 fileReader.close(); 322 } catch (IOException e1) { 323 } 325 } 326 327 if (lines == 0) 329 return; 330 331 switch (format) { 332 case UNIFIED_FORMAT: 333 nullFilePrefix = "--- "; newFilePrefix = "+++ "; positionInfo = "@@ -0,0 +1," + lines + " @@" ; linePrefix = "+"; break; 338 339 case CONTEXT_FORMAT : 340 nullFilePrefix = "*** "; newFilePrefix = "--- "; positionInfo = "--- 1," + lines + " ----"; linePrefix = "+ "; break; 345 346 default : 347 positionInfo = "0a1," + lines; linePrefix = "> "; break; 350 } 351 352 fileReader = new BufferedReader(new InputStreamReader(file.getContents())); 353 try { 354 355 printStream.println("Index: " + pathString); printStream.println("==================================================================="); printStream.println("RCS file: " + pathString); printStream.println("diff -N " + pathString); 360 361 if (format != STANDARD_FORMAT) { 362 printStream.println(nullFilePrefix + "/dev/null 1 Jan 1970 00:00:00 -0000"); printStream.println(newFilePrefix + pathString + " 1 Jan 1970 00:00:00 -0000"); } 366 367 if (format == CONTEXT_FORMAT) { 368 printStream.println("***************"); printStream.println("*** 0 ****"); } 371 372 printStream.println(positionInfo); 373 374 for (int i = 0; i < lines; i++) { 375 printStream.print(linePrefix); 376 printStream.println(fileReader.readLine()); 377 } 378 } catch (IOException e) { 379 throw CVSException.wrapException(file.getIResource(), NLS.bind(CVSMessages.CVSTeamProvider_errorAddingFileToDiff, new String [] { pathString }), e); 380 } finally { 381 try { 382 fileReader.close(); 383 } catch (IOException e1) { 384 } 385 } 386 } 387 388 public void setStream(PrintStream stream) { 389 this.stream = new CustomizableEOLPrintStream(stream); 390 } 391 392 protected void reportEmptyDiff() { 393 CVSUIPlugin.openDialog(getShell(), new CVSUIPlugin.IOpenableInShell() { 394 public void open(Shell shell) { 395 MessageDialog.openInformation( 396 shell, 397 CVSUIMessages.GenerateCVSDiff_noDiffsFoundTitle, 398 CVSUIMessages.GenerateCVSDiff_noDiffsFoundMsg); 399 } 400 }, CVSUIPlugin.PERFORM_SYNC_EXEC); 401 } 402 403 protected ICVSFolder getLocalRoot(CVSTeamProvider provider) throws CVSException { 404 ICVSFolder root = getPatchRootFolder(); 405 if (root != null) 406 return root; 407 return super.getLocalRoot(provider); 408 } 409 410 private ICVSFolder getPatchRootFolder() { 411 if (!isMultiPatch && 412 !includeFullPathInformation){ 413 416 IResource patchFolder = null; 417 IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); 418 if (patchRoot.segmentCount() > 1){ 419 patchFolder = root.getFolder(patchRoot); 420 } else { 421 patchFolder = root.getProject(patchRoot.toString()); 422 } 423 424 ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(patchFolder); 425 if (!cvsResource.isFolder()) { 426 cvsResource = cvsResource.getParent(); 427 } 428 return (ICVSFolder) cvsResource; 429 } 430 return null; 431 } 432 433 436 public boolean consultModelsForMappings() { 437 return false; 438 } 439 440 public boolean belongsTo(Object family){ 441 if(family != null && family.equals(destination)) 442 return true; 443 return super.belongsTo(family); 444 } 445 446 } 447 | Popular Tags |