KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > subversion > ui > update > ResolveConflictsExecutor


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.subversion.ui.update;
21
22 import java.io.*;
23 import java.util.*;
24 import java.awt.*;
25 import javax.swing.*;
26 import org.netbeans.modules.subversion.ui.commit.ConflictResolvedAction;
27 import org.netbeans.spi.diff.*;
28
29 import org.openide.DialogDisplayer;
30 import org.openide.ErrorManager;
31 import org.openide.util.*;
32 import org.openide.windows.TopComponent;
33 import org.openide.filesystems.*;
34
35 import org.netbeans.api.diff.*;
36 import org.netbeans.modules.diff.EncodedReaderFactory;
37 import org.netbeans.modules.subversion.*;
38 import org.netbeans.modules.subversion.client.*;
39
40 import org.tigris.subversion.svnclientadapter.*;
41
42 /**
43  * Shows basic conflict resolver UI.
44  *
45  * This class is copy&pasted from javacvs
46  *
47  * @author Martin Entlicher
48  */

49 public class ResolveConflictsExecutor extends SvnProgressSupport {
50     
51     private static final String JavaDoc TMP_PREFIX = "merge"; // NOI18N
52

53     static final String JavaDoc CHANGE_LEFT = "<<<<<<< "; // NOI18N
54
static final String JavaDoc CHANGE_RIGHT = ">>>>>>> "; // NOI18N
55
static final String JavaDoc CHANGE_DELIMETER = "======="; // NOI18N
56

57     private String JavaDoc leftFileRevision = null;
58     private String JavaDoc rightFileRevision = null;
59
60     private final File file;
61
62     public ResolveConflictsExecutor(File file) {
63         super();
64         this.file = file;
65     }
66
67     public void exec() {
68         assert SwingUtilities.isEventDispatchThread();
69         MergeVisualizer merge = (MergeVisualizer) Lookup.getDefault().lookup(MergeVisualizer.class);
70         if (merge == null) {
71             throw new IllegalStateException JavaDoc("No Merge engine found."); // NOI18N
72
}
73         
74         try {
75             FileObject fo = FileUtil.toFileObject(file);
76             handleMergeFor(file, fo, fo.lock(), merge);
77         } catch (FileAlreadyLockedException e) {
78             Set components = TopComponent.getRegistry().getOpened();
79             for (Iterator i = components.iterator(); i.hasNext();) {
80                 TopComponent tc = (TopComponent) i.next();
81                 if (tc.getClientProperty(ResolveConflictsExecutor.class.getName()) != null) {
82                     tc.requestActive();
83                 }
84             }
85         } catch (IOException ioex) {
86             org.openide.ErrorManager.getDefault().notify(ioex);
87         }
88     }
89     
90     private void handleMergeFor(final File file, FileObject fo, FileLock lock,
91                                 final MergeVisualizer merge) throws IOException {
92         String JavaDoc mimeType = (fo == null) ? "text/plain" : fo.getMIMEType(); // NOI18N
93
String JavaDoc ext = "."+fo.getExt(); // NOI18N
94
File f1 = FileUtil.normalizeFile(File.createTempFile(TMP_PREFIX, ext));
95         File f2 = FileUtil.normalizeFile(File.createTempFile(TMP_PREFIX, ext));
96         File f3 = FileUtil.normalizeFile(File.createTempFile(TMP_PREFIX, ext));
97         f1.deleteOnExit();
98         f2.deleteOnExit();
99         f3.deleteOnExit();
100         
101         final Difference[] diffs = copyParts(true, file, f1, true);
102         if (diffs.length == 0) {
103             ConflictResolvedAction.perform(file); // remove conflict status
104
return;
105         }
106
107         copyParts(false, file, f2, false);
108         //GraphicalMergeVisualizer merge = new GraphicalMergeVisualizer();
109
String JavaDoc originalLeftFileRevision = leftFileRevision;
110         String JavaDoc originalRightFileRevision = rightFileRevision;
111         if (leftFileRevision != null) leftFileRevision.trim();
112         if (rightFileRevision != null) rightFileRevision.trim();
113         if (leftFileRevision == null || leftFileRevision.equals(file.getName())) {
114             leftFileRevision = org.openide.util.NbBundle.getMessage(ResolveConflictsExecutor.class, "Diff.titleWorkingFile"); // NOI18N
115
} else {
116             leftFileRevision = org.openide.util.NbBundle.getMessage(ResolveConflictsExecutor.class, "Diff.titleRevision", leftFileRevision); // NOI18N
117
}
118         if (rightFileRevision == null || rightFileRevision.equals(file.getName())) {
119             rightFileRevision = org.openide.util.NbBundle.getMessage(ResolveConflictsExecutor.class, "Diff.titleWorkingFile"); // NOI18N
120
} else {
121             rightFileRevision = org.openide.util.NbBundle.getMessage(ResolveConflictsExecutor.class, "Diff.titleRevision", rightFileRevision); // NOI18N
122
}
123         
124         final StreamSource s1;
125         final StreamSource s2;
126         String JavaDoc encoding = EncodedReaderFactory.getDefault().getEncoding(fo);
127         if (encoding != null) {
128             s1 = StreamSource.createSource(file.getName(), leftFileRevision, mimeType, new InputStreamReader(new FileInputStream(f1), encoding));
129             s2 = StreamSource.createSource(file.getName(), rightFileRevision, mimeType, new InputStreamReader(new FileInputStream(f2), encoding));
130         } else {
131             s1 = StreamSource.createSource(file.getName(), leftFileRevision, mimeType, f1);
132             s2 = StreamSource.createSource(file.getName(), rightFileRevision, mimeType, f2);
133         }
134         final StreamSource result = new MergeResultWriterInfo(f1, f2, f3, file, mimeType,
135                                                               originalLeftFileRevision,
136                                                               originalRightFileRevision,
137                                                               fo, lock, encoding);
138
139         try {
140             Component c = merge.createView(diffs, s1, s2, result);
141             if (c instanceof TopComponent) {
142                 ((TopComponent) c).putClientProperty(ResolveConflictsExecutor.class.getName(), Boolean.TRUE);
143             }
144         } catch (IOException ioex) {
145             org.openide.ErrorManager.getDefault().notify(ioex);
146         }
147     }
148
149     /**
150      * Copy the file and conflict parts into another file.
151      */

152     private Difference[] copyParts(boolean generateDiffs, File source,
153                                    File dest, boolean leftPart) throws IOException {
154         //System.out.println("copyParts("+generateDiffs+", "+source+", "+dest+", "+leftPart+")");
155
BufferedReader r = new BufferedReader(new FileReader(source));
156         BufferedWriter w = new BufferedWriter(new FileWriter(dest));
157         ArrayList<Difference> diffList = null;
158         if (generateDiffs) {
159             diffList = new ArrayList<Difference>();
160         }
161         try {
162             String JavaDoc line;
163             boolean isChangeLeft = false;
164             boolean isChangeRight = false;
165             int f1l1 = 0, f1l2 = 0, f2l1 = 0, f2l2 = 0;
166             StringBuffer JavaDoc text1 = new StringBuffer JavaDoc();
167             StringBuffer JavaDoc text2 = new StringBuffer JavaDoc();
168             int i = 1, j = 1;
169             while ((line = r.readLine()) != null) {
170                 if (line.startsWith(CHANGE_LEFT)) {
171                     if (generateDiffs) {
172                         if (leftFileRevision == null) {
173                             leftFileRevision = line.substring(CHANGE_LEFT.length());
174                         }
175                         if (isChangeLeft) {
176                             f1l2 = i - 1;
177                             diffList.add((f1l1 > f1l2) ? new Difference(Difference.ADD,
178                                                                         f1l1 - 1, 0, f2l1, f2l2,
179                                                                         text1.toString(),
180                                                                         text2.toString()) :
181                                          (f2l1 > f2l2) ? new Difference(Difference.DELETE,
182                                                                         f1l1, f1l2, f2l1 - 1, 0,
183                                                                         text1.toString(),
184                                                                         text2.toString())
185                                                        : new Difference(Difference.CHANGE,
186                                                                         f1l1, f1l2, f2l1, f2l2,
187                                                                         text1.toString(),
188                                                                         text2.toString()));
189                             f1l1 = f1l2 = f2l1 = f2l2 = 0;
190                             text1.delete(0, text1.length());
191                             text2.delete(0, text2.length());
192                         } else {
193                             f1l1 = i;
194                         }
195                     }
196                     isChangeLeft = !isChangeLeft;
197                     continue;
198                 } else if (line.startsWith(CHANGE_RIGHT)) {
199                     if (generateDiffs) {
200                         if (rightFileRevision == null) {
201                             rightFileRevision = line.substring(CHANGE_RIGHT.length());
202                         }
203                         if (isChangeRight) {
204                             f2l2 = j - 1;
205                             diffList.add((f1l1 > f1l2) ? new Difference(Difference.ADD,
206                                                                         f1l1 - 1, 0, f2l1, f2l2,
207                                                                         text1.toString(),
208                                                                         text2.toString()) :
209                                          (f2l1 > f2l2) ? new Difference(Difference.DELETE,
210                                                                         f1l1, f1l2, f2l1 - 1, 0,
211                                                                         text1.toString(),
212                                                                         text2.toString())
213                                                        : new Difference(Difference.CHANGE,
214                                                                         f1l1, f1l2, f2l1, f2l2,
215                                                                         text1.toString(),
216                                                                         text2.toString()));
217                                                        /*
218                             diffList.add(new Difference((f1l1 > f1l2) ? Difference.ADD :
219                                                         (f2l1 > f2l2) ? Difference.DELETE :
220                                                                         Difference.CHANGE,
221                                                         f1l1, f1l2, f2l1, f2l2));
222                                                         */

223                             f1l1 = f1l2 = f2l1 = f2l2 = 0;
224                             text1.delete(0, text1.length());
225                             text2.delete(0, text2.length());
226                         } else {
227                             f2l1 = j;
228                         }
229                     }
230                     isChangeRight = !isChangeRight;
231                     continue;
232                 } else if (isChangeRight && line.indexOf(CHANGE_RIGHT) != -1) {
233                     String JavaDoc lineText = line.substring(0, line.lastIndexOf(CHANGE_RIGHT));
234                     if (generateDiffs) {
235                         if (rightFileRevision == null) {
236                             rightFileRevision = line.substring(line.lastIndexOf(CHANGE_RIGHT) + CHANGE_RIGHT.length());
237                         }
238                         text2.append(lineText);
239                         f2l2 = j;
240                         diffList.add((f1l1 > f1l2) ? new Difference(Difference.ADD,
241                                                                     f1l1 - 1, 0, f2l1, f2l2,
242                                                                     text1.toString(),
243                                                                     text2.toString()) :
244                                      (f2l1 > f2l2) ? new Difference(Difference.DELETE,
245                                                                     f1l1, f1l2, f2l1 - 1, 0,
246                                                                     text1.toString(),
247                                                                     text2.toString())
248                                                    : new Difference(Difference.CHANGE,
249                                                                     f1l1, f1l2, f2l1, f2l2,
250                                                                     text1.toString(),
251                                                                     text2.toString()));
252                         f1l1 = f1l2 = f2l1 = f2l2 = 0;
253                         text1.delete(0, text1.length());
254                         text2.delete(0, text2.length());
255                     }
256                     if (!leftPart) {
257                         w.write(lineText);
258                         w.newLine();
259                     }
260                     isChangeRight = !isChangeRight;
261                     continue;
262                 } else if (line.equals(CHANGE_DELIMETER)) {
263                     if (isChangeLeft) {
264                         isChangeLeft = false;
265                         isChangeRight = true;
266                         f1l2 = i - 1;
267                         f2l1 = j;
268                         continue;
269                     } else if (isChangeRight) {
270                         isChangeRight = false;
271                         isChangeLeft = true;
272                         f2l2 = j - 1;
273                         f1l1 = i;
274                         continue;
275                     }
276                 } else if (line.endsWith(CHANGE_DELIMETER)) {
277                     String JavaDoc lineText = line.substring(0, line.length() - CHANGE_DELIMETER.length()) + "\n"; // NOI18N
278
if (isChangeLeft) {
279                         text1.append(lineText);
280                         if (leftPart) {
281                             w.write(lineText);
282                             w.newLine();
283                         }
284                         isChangeLeft = false;
285                         isChangeRight = true;
286                         f1l2 = i;
287                         f2l1 = j;
288                     } else if (isChangeRight) {
289                         text2.append(lineText);
290                         if (!leftPart) {
291                             w.write(lineText);
292                             w.newLine();
293                         }
294                         isChangeRight = false;
295                         isChangeLeft = true;
296                         f2l2 = j;
297                         f1l1 = i;
298                     }
299                     continue;
300                 }
301                 if (!isChangeLeft && !isChangeRight || leftPart == isChangeLeft) {
302                     w.write(line);
303                     w.newLine();
304                 }
305                 if (isChangeLeft) text1.append(line + "\n"); // NOI18N
306
if (isChangeRight) text2.append(line + "\n"); // NOI18N
307
if (generateDiffs) {
308                     if (isChangeLeft) i++;
309                     else if (isChangeRight) j++;
310                     else {
311                         i++;
312                         j++;
313                     }
314                 }
315             }
316         } finally {
317             try {
318                 r.close();
319             } finally {
320                 w.close();
321             }
322         }
323         if (generateDiffs) {
324             return diffList.toArray(new Difference[diffList.size()]);
325         } else {
326             return null;
327         }
328     }
329
330     public void perform() {
331         exec();
332     }
333
334     public void run() {
335         throw new RuntimeException JavaDoc("Not implemented"); // NOI18N
336
}
337     
338     
339     private static class MergeResultWriterInfo extends StreamSource {
340         
341         private File tempf1, tempf2, tempf3, outputFile;
342         private File fileToRepairEntriesOf;
343         private String JavaDoc mimeType;
344         private String JavaDoc leftFileRevision;
345         private String JavaDoc rightFileRevision;
346         private FileObject fo;
347         private FileLock lock;
348         private String JavaDoc encoding;
349         
350         public MergeResultWriterInfo(File tempf1, File tempf2, File tempf3,
351                                      File outputFile, String JavaDoc mimeType,
352                                      String JavaDoc leftFileRevision, String JavaDoc rightFileRevision,
353                                      FileObject fo, FileLock lock, String JavaDoc encoding) {
354             this.tempf1 = tempf1;
355             this.tempf2 = tempf2;
356             this.tempf3 = tempf3;
357             this.outputFile = outputFile;
358             this.mimeType = mimeType;
359             this.leftFileRevision = leftFileRevision;
360             this.rightFileRevision = rightFileRevision;
361             this.fo = fo;
362             this.lock = lock;
363             if (encoding == null) {
364                 encoding = EncodedReaderFactory.getDefault().getEncoding(tempf1);
365             }
366             this.encoding = encoding;
367         }
368         
369         public String JavaDoc getName() {
370             return outputFile.getName();
371         }
372         
373         public String JavaDoc getTitle() {
374             return org.openide.util.NbBundle.getMessage(ResolveConflictsExecutor.class, "Merge.titleResult"); // NOI18N
375
}
376         
377         public String JavaDoc getMIMEType() {
378             return mimeType;
379         }
380         
381         public Reader createReader() throws IOException {
382             throw new IOException("No reader of merge result"); // NOI18N
383
}
384         
385         /**
386          * Create a writer, that writes to the source.
387          * @param conflicts The list of conflicts remaining in the source.
388          * Can be <code>null</code> if there are no conflicts.
389          * @return The writer or <code>null</code>, when no writer can be created.
390          */

391         public Writer createWriter(Difference[] conflicts) throws IOException {
392             Writer w;
393             if (fo != null) {
394                 w = EncodedReaderFactory.getDefault().getWriter(fo, lock, encoding);
395             } else {
396                 w = EncodedReaderFactory.getDefault().getWriter(outputFile, mimeType, encoding);
397             }
398             if (conflicts == null || conflicts.length == 0) {
399                 fileToRepairEntriesOf = outputFile;
400                 return w;
401             } else {
402                 return new MergeConflictFileWriter(w, fo, conflicts,
403                                                    leftFileRevision, rightFileRevision);
404             }
405         }
406         
407         /**
408          * This method is called when the visual merging process is finished.
409          * All possible writting processes are finished before this method is called.
410          */

411         public void close() {
412             tempf1.delete();
413             tempf2.delete();
414             tempf3.delete();
415             if (lock != null) {
416                 lock.releaseLock();
417                 lock = null;
418             }
419             fo = null;
420             if (fileToRepairEntriesOf != null) {
421                 repairEntries(fileToRepairEntriesOf);
422                 fileToRepairEntriesOf = null;
423             }
424         }
425
426         private void repairEntries(File file) {
427             ConflictResolvedAction.perform(file);
428         }
429
430     }
431     
432     private static class MergeConflictFileWriter extends FilterWriter {
433         
434         private Difference[] conflicts;
435         private int lineNumber;
436         private int currentConflict;
437         private String JavaDoc leftName;
438         private String JavaDoc rightName;
439         private FileObject fo;
440         
441         public MergeConflictFileWriter(Writer delegate, FileObject fo,
442                                        Difference[] conflicts, String JavaDoc leftName,
443                                        String JavaDoc rightName) throws IOException {
444             super(delegate);
445             this.conflicts = conflicts;
446             this.leftName = leftName;
447             this.rightName = rightName;
448             this.lineNumber = 1;
449             this.currentConflict = 0;
450             if (lineNumber == conflicts[currentConflict].getFirstStart()) {
451                 writeConflict(conflicts[currentConflict]);
452                 currentConflict++;
453             }
454             this.fo = fo;
455         }
456         
457         public void write(String JavaDoc str) throws IOException {
458             //System.out.println("MergeConflictFileWriter.write("+str+")");
459
super.write(str);
460             lineNumber += numChars('\n', str);
461             //System.out.println(" lineNumber = "+lineNumber+", current conflict start = "+conflicts[currentConflict].getFirstStart());
462
if (currentConflict < conflicts.length && lineNumber >= conflicts[currentConflict].getFirstStart()) {
463                 writeConflict(conflicts[currentConflict]);
464                 currentConflict++;
465             }
466         }
467         
468         private void writeConflict(Difference conflict) throws IOException {
469             //System.out.println("MergeConflictFileWriter.writeConflict('"+conflict.getFirstText()+"', '"+conflict.getSecondText()+"')");
470
super.write(CHANGE_LEFT + leftName + "\n"); // NOI18N
471
super.write(conflict.getFirstText());
472             super.write(CHANGE_DELIMETER + "\n"); // NOI18N
473
super.write(conflict.getSecondText());
474             super.write(CHANGE_RIGHT + rightName + "\n"); // NOI18N
475
}
476         
477         private static int numChars(char c, String JavaDoc str) {
478             int n = 0;
479             for (int pos = str.indexOf(c); pos >= 0 && pos < str.length(); pos = str.indexOf(c, pos + 1)) {
480                 n++;
481             }
482             return n;
483         }
484         
485         public void close() throws IOException {
486             super.close();
487             if (fo != null) fo.refresh(true);
488         }
489     }
490 }
491
492
Popular Tags