|
What this is
Other links
The source code/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun * Microsystems, Inc. All Rights Reserved. */ package org.netbeans.modules.vcs.profiles.cvsprofiles.commands; import java.beans.PropertyChangeEvent; import java.beans.VetoableChangeListener; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.Reader; import java.io.Writer; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.Hashtable; import javax.swing.SwingUtilities; import org.openide.DialogDisplayer; import org.openide.ErrorManager; import org.openide.filesystems.FileLock; import org.openide.filesystems.FileObject; import org.openide.util.Lookup; import org.netbeans.api.diff.Difference; import org.netbeans.api.diff.StreamSource; import org.netbeans.spi.diff.MergeVisualizer; //import org.netbeans.modules.merge.builtin.visualizer.GraphicalMergeVisualizer; import org.netbeans.modules.vcscore.VcsFileSystem; import org.netbeans.modules.vcscore.commands.CommandOutputListener; import org.netbeans.modules.vcscore.commands.CommandDataOutputListener; import org.netbeans.modules.vcscore.cmdline.*; /** * This class is used to resolve merge conflicts in a graphical way using a merge visualizer. * We parse the file with merge conflicts marked, let the conflicts resolve by the * visual merging tool and after successfull conflicts resolution save it back * to the original file. * * @author Martin Entlicher */ public class CvsResolveConflicts implements VcsAdditionalCommand { private static final String TMP_PREFIX = "merge"; // NOI18N private static final String TMP_SUFFIX = "tmp"; // NOI18N private static final String CHANGE_LEFT = "<<<<<<< "; // NOI18N private static final String CHANGE_RIGHT = ">>>>>>> "; // NOI18N private static final String CHANGE_DELIMETER = "======="; // NOI18N private VcsFileSystem fileSystem = null; private String leftFileRevision = null; private String rightFileRevision = null; public void setFileSystem(VcsFileSystem fileSystem) { this.fileSystem = fileSystem; } public boolean exec(Hashtable vars, String[] args, CommandOutputListener stdoutNRListener, CommandOutputListener stderrNRListener, CommandDataOutputListener stdoutListener, String dataRegex, CommandDataOutputListener stderrListener, String errorRegex) { /* if (fileSystem instanceof CvsFileSystem) { CvsFileSystem cvsFileSystem = (CvsFileSystem) fileSystem; */ Collection files = ExecuteCommand.createProcessingFiles(fileSystem, vars); MergeVisualizer merge = null; for (Iterator it = files.iterator(); it.hasNext(); ) { String fileName = (String) it.next(); File file = fileSystem.getFile(fileName); if (file != null) { FileObject fo = fileSystem.findResource(fileName); if (merge == null) { merge = (MergeVisualizer) Lookup.getDefault().lookup(MergeVisualizer.class); if (merge == null) { DialogDisplayer.getDefault().notify( new org.openide.NotifyDescriptor.Message( org.openide.util.NbBundle.getMessage(CvsResolveConflicts.class, "Merge.noMergeAvailable"))); return false; } } try { handleMergeFor(file, fo, merge); } catch (IOException ioex) { org.openide.ErrorManager.getDefault().notify(ioex); } } } return true; } private void handleMergeFor(final File file, FileObject fo, final MergeVisualizer merge) throws IOException { String mimeType = (fo == null) ? "text/plain" : fo.getMIMEType(); File f1 = File.createTempFile(TMP_PREFIX, TMP_SUFFIX); File f2 = File.createTempFile(TMP_PREFIX, TMP_SUFFIX); File f3 = File.createTempFile(TMP_PREFIX, TMP_SUFFIX); final Difference[] diffs = copyParts(true, file, f1, true); if (diffs.length == 0) { DialogDisplayer.getDefault ().notify (new org.openide.NotifyDescriptor.Message( org.openide.util.NbBundle.getMessage(CvsResolveConflicts.class, "NoConflictsInFile", file))); return ; } copyParts(false, file, f2, false); //GraphicalMergeVisualizer merge = new GraphicalMergeVisualizer(); String originalLeftFileRevision = leftFileRevision; String originalRightFileRevision = rightFileRevision; if (leftFileRevision != null) leftFileRevision.trim(); if (rightFileRevision != null) rightFileRevision.trim(); if (leftFileRevision == null || leftFileRevision.equals(file.getName())) { leftFileRevision = org.openide.util.NbBundle.getMessage(CvsResolveConflicts.class, "Diff.titleWorkingFile"); } else { leftFileRevision = org.openide.util.NbBundle.getMessage(CvsResolveConflicts.class, "Diff.titleRevision", leftFileRevision); } if (rightFileRevision == null || rightFileRevision.equals(file.getName())) { rightFileRevision = org.openide.util.NbBundle.getMessage(CvsResolveConflicts.class, "Diff.titleWorkingFile"); } else { rightFileRevision = org.openide.util.NbBundle.getMessage(CvsResolveConflicts.class, "Diff.titleRevision", rightFileRevision); } String resultTitle = org.openide.util.NbBundle.getMessage(CvsResolveConflicts.class, "Merge.titleResult"); final StreamSource s1 = StreamSource.createSource(file.getName(), leftFileRevision, mimeType, f1); final StreamSource s2 = StreamSource.createSource(file.getName(), rightFileRevision, mimeType, f2); final StreamSource result = new MergeResultWriterInfo(f1, f2, f3, file, mimeType, originalLeftFileRevision, originalRightFileRevision, fo); SwingUtilities.invokeLater(new Runnable() { public void run() { try { merge.createView(diffs, s1, s2, result); } catch (IOException ioex) { org.openide.ErrorManager.getDefault().notify(ioex); } } }); } /** * Copy the file and conflict parts into another file. */ private Difference[] copyParts(boolean generateDiffs, File source, File dest, boolean leftPart) throws IOException { //System.out.println("copyParts("+generateDiffs+", "+source+", "+dest+", "+leftPart+")"); BufferedReader r = new BufferedReader(new FileReader(source)); BufferedWriter w = new BufferedWriter(new FileWriter(dest)); ArrayList diffList = null; if (generateDiffs) { diffList = new ArrayList(); } try { String line; boolean isChangeLeft = false; boolean isChangeRight = false; int f1l1 = 0, f1l2 = 0, f2l1 = 0, f2l2 = 0; StringBuffer text1 = new StringBuffer(); StringBuffer text2 = new StringBuffer(); int i = 1, j = 1; while ((line = r.readLine()) != null) { if (line.startsWith(CHANGE_LEFT)) { if (generateDiffs) { if (leftFileRevision == null) { leftFileRevision = line.substring(CHANGE_LEFT.length()); } if (isChangeLeft) { f1l2 = i - 1; diffList.add((f1l1 > f1l2) ? new Difference(Difference.ADD, f1l1 - 1, 0, f2l1, f2l2, text1.toString(), text2.toString()) : (f2l1 > f2l2) ? new Difference(Difference.DELETE, f1l1, f1l2, f2l1 - 1, 0, text1.toString(), text2.toString()) : new Difference(Difference.CHANGE, f1l1, f1l2, f2l1, f2l2, text1.toString(), text2.toString())); f1l1 = f1l2 = f2l1 = f2l2 = 0; text1.delete(0, text1.length()); text2.delete(0, text2.length()); } else { f1l1 = i; } } isChangeLeft = !isChangeLeft; continue; } else if (line.startsWith(CHANGE_RIGHT)) { if (generateDiffs) { if (rightFileRevision == null) { rightFileRevision = line.substring(CHANGE_RIGHT.length()); } if (isChangeRight) { f2l2 = j - 1; diffList.add((f1l1 > f1l2) ? new Difference(Difference.ADD, f1l1 - 1, 0, f2l1, f2l2, text1.toString(), text2.toString()) : (f2l1 > f2l2) ? new Difference(Difference.DELETE, f1l1, f1l2, f2l1 - 1, 0, text1.toString(), text2.toString()) : new Difference(Difference.CHANGE, f1l1, f1l2, f2l1, f2l2, text1.toString(), text2.toString())); /* diffList.add(new Difference((f1l1 > f1l2) ? Difference.ADD : (f2l1 > f2l2) ? Difference.DELETE : Difference.CHANGE, f1l1, f1l2, f2l1, f2l2)); */ f1l1 = f1l2 = f2l1 = f2l2 = 0; text1.delete(0, text1.length()); text2.delete(0, text2.length()); } else { f2l1 = j; } } isChangeRight = !isChangeRight; continue; } else if (isChangeRight && line.indexOf(CHANGE_RIGHT) != -1) { String lineText = line.substring(0, line.lastIndexOf(CHANGE_RIGHT)) + "\n"; if (generateDiffs) { if (rightFileRevision == null) { rightFileRevision = line.substring(line.lastIndexOf(CHANGE_RIGHT) + CHANGE_RIGHT.length()); } text2.append(lineText); f2l2 = j; diffList.add((f1l1 > f1l2) ? new Difference(Difference.ADD, f1l1 - 1, 0, f2l1, f2l2, text1.toString(), text2.toString()) : (f2l1 > f2l2) ? new Difference(Difference.DELETE, f1l1, f1l2, f2l1 - 1, 0, text1.toString(), text2.toString()) : new Difference(Difference.CHANGE, f1l1, f1l2, f2l1, f2l2, text1.toString(), text2.toString())); f1l1 = f1l2 = f2l1 = f2l2 = 0; text1.delete(0, text1.length()); text2.delete(0, text2.length()); } if (!leftPart) w.write(lineText); isChangeRight = !isChangeRight; continue; } else if (line.equals(CHANGE_DELIMETER)) { if (isChangeLeft) { isChangeLeft = false; isChangeRight = true; f1l2 = i - 1; f2l1 = j; continue; } else if (isChangeRight) { isChangeRight = false; isChangeLeft = true; f2l2 = j - 1; f1l1 = i; continue; } } else if (line.endsWith(CHANGE_DELIMETER)) { String lineText = line.substring(0, line.length() - CHANGE_DELIMETER.length()) + "\n"; if (isChangeLeft) { text1.append(lineText); if (leftPart) w.write(lineText); isChangeLeft = false; isChangeRight = true; f1l2 = i; f2l1 = j; } else if (isChangeRight) { text2.append(lineText); if (!leftPart) w.write(lineText); isChangeRight = false; isChangeLeft = true; f2l2 = j; f1l1 = i; } continue; } if (!isChangeLeft && !isChangeRight || leftPart == isChangeLeft) { w.write(line); w.newLine(); } if (isChangeLeft) text1.append(line + "\n"); if (isChangeRight) text2.append(line + "\n"); if (generateDiffs) { if (isChangeLeft) i++; else if (isChangeRight) j++; else { i++; j++; } } } } finally { try { r.close(); } finally { w.close(); } } if (generateDiffs) { return (Difference[]) diffList.toArray(new Difference[diffList.size()]); } else { return null; } } /** * Repair the CVS/Entries of the file - remove the conflict. * @param file The file to remove the conflict for */ private static void repairEntries(File file) throws IOException { String name = file.getName(); File entries = new File(file.getParentFile(), "CVS"+File.separator+"Entries"); File backup = new File(entries.getAbsolutePath()+".Backup"); int attemps = 100; while (backup.exists() && attemps-- > 0) { // Someone else is occupying Entries, wait a while... try { Thread.currentThread().sleep(500); } catch (InterruptedException intrex) { attemps = 0; } } if (attemps <= 0) return ; // Give up, someone else is occupying Entries backup.createNewFile(); try { BufferedReader reader = null; BufferedWriter writer = null; try { reader = new BufferedReader(new FileReader(entries)); writer = new BufferedWriter(new FileWriter(backup)); String line; String pattern = "/"+name; while ((line = reader.readLine()) != null) { if (line.startsWith(pattern)) { line = removeConflict(line); } writer.write(line+"\n"); } } finally { if (reader != null) reader.close(); if (writer != null) writer.close(); } if (!backup.renameTo(entries)) { entries.delete(); backup.renameTo(entries); } } finally { if (backup.exists()) backup.delete(); } } private static String removeConflict(String line) { StringBuffer result = new StringBuffer(); int n = line.length(); int slashNum = 0; boolean ignoreField = false; for (int i = 0; i < n; i++) { char c = line.charAt(i); if (!ignoreField) result.append(c); if (c == '/') { ignoreField = false; slashNum++; if (slashNum == 3) { result.append("Result of merge/"); // NOI18N ignoreField = true; } } } return result.toString(); } private static class MergeResultWriterInfo extends StreamSource { private File tempf1, tempf2, tempf3, outputFile; private File fileToRepairEntriesOf; private String mimeType; private String leftFileRevision; private String rightFileRevision; private FileObject fo; private FileLock lock; public MergeResultWriterInfo(File tempf1, File tempf2, File tempf3, File outputFile, String mimeType, String leftFileRevision, String rightFileRevision, FileObject fo) { this.tempf1 = tempf1; this.tempf2 = tempf2; this.tempf3 = tempf3; this.outputFile = outputFile; this.mimeType = mimeType; this.leftFileRevision = leftFileRevision; this.rightFileRevision = rightFileRevision; this.fo = fo; if (fo != null) { try { // Lock the file, so that nobody can overwrite it during the merge process. lock = fo.lock(); } catch (IOException ioex) {} } } public String getName() { return outputFile.getName(); } public String getTitle() { return org.openide.util.NbBundle.getMessage(CvsResolveConflicts.class, "Merge.titleResult"); } public String getMIMEType() { return mimeType; } public Reader createReader() throws IOException { throw new IOException("No reader of merge result"); // NOI18N } /** * Create a writer, that writes to the source. * @param conflicts The list of conflicts remaining in the source. * Can be |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.