package sandbox.experimento.utils; import br.ic.uff.gems.oceano.ourico.experimento.VCS.type.VCS; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.util.Arrays; import java.util.Comparator; import java.util.SortedSet; import java.util.TreeSet; import java.util.logging.Logger; public abstract class FileBasedVCS implements VCS { /** * Generic merge for File based VCS */ public void merge(File workspace, File studyWorkspace) { if (workspace.isDirectory()) { // "Note: this comparator imposes orderings that are inconsistent with equals." Comparator<File> comparator = new Comparator<File>() { public int compare(File f1, File f2) { int result = (f1.isDirectory() ? 0 : 1) - (f2.isDirectory() ? 0 : 1); if (result == 0) { result = f1.getName().compareTo(f2.getName()); } return result; } }; // New Workspace SortedSet<File> newWorkspace = new TreeSet<File>(comparator); newWorkspace.addAll(Arrays.asList(workspace.listFiles())); // Old Workspace SortedSet<File> oldWorkspace = new TreeSet<File>(comparator); oldWorkspace.addAll(Arrays.asList(studyWorkspace.listFiles())); // Remove control directories from old workspace (.svn and CVS) File svnControlDirectory = new File(studyWorkspace, ".svn"); File cvsControlDirectory = new File(studyWorkspace, "CVS"); // File gitControlDirectory = new File(studyWorkspace, ".git"); oldWorkspace.remove(svnControlDirectory); oldWorkspace.remove(cvsControlDirectory); // oldWorkspace.remove(gitControlDirectory); // Removed Files SortedSet<File> removedFiles = new TreeSet<File>(comparator); removedFiles.addAll(oldWorkspace); removedFiles.removeAll(newWorkspace); // Added Files SortedSet<File> addedFiles = new TreeSet<File>(comparator); addedFiles.addAll(newWorkspace); addedFiles.removeAll(oldWorkspace); // Keeped Source Files SortedSet<File> keepedSourceFiles = new TreeSet<File>(comparator); keepedSourceFiles.addAll(newWorkspace); keepedSourceFiles.retainAll(oldWorkspace); // Keeped Target Files SortedSet<File> keepedTargetFiles = new TreeSet<File>(comparator); keepedTargetFiles.addAll(oldWorkspace); keepedTargetFiles.retainAll(newWorkspace); // Remove all "Removed Files" for (File fileToRemove : removedFiles) { try { remove(fileToRemove.getPath()); } catch (Exception e) { Logger.global.info("Could not remove file " + fileToRemove + ": " + e.getMessage()); } } // Add all "Added Files" for (File fileToAdd : addedFiles) { File newFile = new File(studyWorkspace, fileToAdd.getName()); try { // if (fileToAdd.renameTo(newFile)) { // add(newFile.getPath()); //// System.out.println("add " + newFile.getPath()); // } else { // throw new RuntimeException("Could not rename file " + fileToAdd + " to " + newFile); // } while (!fileToAdd.renameTo(newFile)) { String nameFile = newFile.getAbsolutePath(); nameFile = nameFile.substring(0, nameFile.lastIndexOf("\\")); new File(nameFile).mkdir(); } add(newFile.getPath()); System.out.println("add " + newFile.getPath()); } catch (Exception e) { Logger.global.info("Could not add file " + newFile + ": " + e.getMessage()); } } // Run recursivelly for "Keeped Files" for (File sourceFile : keepedSourceFiles) { File targetFile = keepedTargetFiles.tailSet(sourceFile).first(); merge(sourceFile, targetFile); } } else { studyWorkspace.delete(); workspace.renameTo(studyWorkspace); } } /** * Add a file to version control. */ protected abstract void add(String path) throws IOException; /** * Remove a file from version control. */ protected abstract void remove(String path) throws IOException; /** * Run a specific command with a input redirected from a file */ protected void run(String[] command, final File inputFile, File outputFile, File workDirectory) throws IOException { FileOutputStream fileOut = null; BufferedInputStream inputStream = null; BufferedReader reader = null; try { ProcessBuilder processBuilder = new ProcessBuilder(command); processBuilder.directory(workDirectory); processBuilder.redirectErrorStream(outputFile == null); final Process process = processBuilder.start(); // Input Stream if (inputFile != null) { Thread thread = new Thread(new Runnable() { public void run() { BufferedOutputStream outputStream = null; FileInputStream fileIn = null; try { outputStream = new BufferedOutputStream(process.getOutputStream()); fileIn = new FileInputStream(inputFile); byte[] buffer = new byte[8 * 1024]; int length = fileIn.read(buffer); while (length != -1) { outputStream.write(buffer, 0, length); length = fileIn.read(buffer); } } catch (Exception e) { Logger.global.warning("Could not redirect input from " + inputFile); throw new RuntimeException(e); } finally { try { fileIn.close(); } catch (Exception e) { } try { outputStream.close(); } catch (Exception e) { } } } }); thread.start(); } // Output Stream if (outputFile != null) { fileOut = new FileOutputStream(outputFile); } inputStream = new BufferedInputStream(process.getInputStream()); byte[] buffer = new byte[8 * 1024]; int length = inputStream.read(buffer); while (length != -1) { if (fileOut != null) { fileOut.write(buffer, 0, length); } else { System.out.print(new String(buffer, 0, length)); } length = inputStream.read(buffer); } // Error Stream reader = new BufferedReader(new InputStreamReader(process.getErrorStream())); String message = reader.readLine(); while (message != null) { System.out.print(message); message = reader.readLine(); } } catch (IOException e) { Logger.global.warning("Could not run command " + Arrays.asList(command)); throw e; } finally { try { inputStream.close(); } catch (Exception e) { } try { fileOut.close(); } catch (Exception e) { } try { reader.close(); } catch (Exception e) { } } } /** * @return the outputWindow */ }