/* * ==================================================================== * Copyright (c) 2004-2012 TMate Software Ltd. All rights reserved. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at http://svnkit.com/license.html * If newer versions of this license are posted there, you may use a * newer version instead, at your option. * ==================================================================== */ package org.tmatesoft.svn.core.io.diff; import java.io.File; import java.io.InputStream; import java.io.OutputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.internal.wc.SVNFileUtil; /** * The <b>SVNDeltaProcessor</b> is used to get a full text of a file * in series applying diff windows being passed to a processor. * * @version 1.3 * @author TMate Software Ltd. * @since 1.2 */ public class SVNDeltaProcessor { private SVNDiffWindowApplyBaton myApplyBaton; /** * Creates a processor. */ public SVNDeltaProcessor() { } /** * Starts processing deltas given a base file stream and an output stream * to write resultant target bytes to. * * <p> * If a target full text is a newly added file (text deltas would be vs. empty), * then source bytes are not needed and <code>base</code> may be passed as * <span class="javakeyword">null</span>. * * <p> * If <code>computeChecksum</code> is <span class="javakeyword">true</span>, then * an MD5 checksum will be calculated for target bytes. The calculated checksum is * returned by {@link #textDeltaEnd()}. * * @param base an input stream to take base file contents * from * @param target an output stream to write the resultant target * contents to * @param computeCheksum <span class="javakeyword">true</span> to calculate * checksum */ public void applyTextDelta(InputStream base, OutputStream target, boolean computeCheksum) { reset(); MessageDigest digest = null; try { digest = computeCheksum ? MessageDigest.getInstance("MD5") : null; } catch (NoSuchAlgorithmException e1) { } base = base == null ? SVNFileUtil.DUMMY_IN : base; myApplyBaton = SVNDiffWindowApplyBaton.create(base, target, digest); } /** * Starts processing deltas given a base file and a one * to write resultant target bytes to. * * <p> * If a target full text is a newly added file (text deltas would be vs. empty), * then source bytes are not needed and <code>baseFile</code> may be passed as * <span class="javakeyword">null</span>. * * <p> * If a file represented by <code>targetFile</code> does not exist * yet, first tries to create an empty file. * * <p> * If <code>computeChecksum</code> is <span class="javakeyword">true</span>, then * an MD5 checksum will be calculated for target bytes. The calculated checksum is * returned by {@link #textDeltaEnd()}. * * @param baseFile a base file to read base file contents * from * @param targetFile a destination file where resultant * target bytes will be written * @param computeCheksum <span class="javakeyword">true</span> to calculate * checksum * @throws SVNException */ public void applyTextDelta(File baseFile, File targetFile, boolean computeCheksum) throws SVNException { if (!targetFile.exists()) { SVNFileUtil.createEmptyFile(targetFile); } InputStream base = baseFile != null && baseFile.exists() ? SVNFileUtil.openFileForReading(baseFile) : SVNFileUtil.DUMMY_IN; applyTextDelta(base, SVNFileUtil.openFileForWriting(targetFile), computeCheksum); } /** * Starts processing deltas given a base file and a one * to write resultant target bytes to. * * <p> * If a target full text is a newly added file (text deltas would be vs. empty), * then source bytes are not needed and <code>baseIS</code> may be passed as * <span class="javakeyword">null</span>. * * <p> * If a file represented by <code>targetFile</code> does not exist * yet, first tries to create an empty file. * * <p> * If <code>computeTargetChecksum</code> is <span class="javakeyword">true</span>, then * an MD5 checksum will be calculated for target bytes. The calculated checksum is * returned by {@link #textDeltaEnd()}. * * @param baseIS an input stream to take base file contents * from * @param targetFile a destination file where resultant * target bytes will be written * @param computeTargetCheksum <span class="javakeyword">true</span> to calculate * checksum of the target text * @throws SVNException * @since 1.3 */ public void applyTextDelta(InputStream baseIS, File targetFile, boolean computeTargetCheksum) throws SVNException { if (!targetFile.exists()) { SVNFileUtil.createEmptyFile(targetFile); } applyTextDelta(baseIS, SVNFileUtil.openFileForWriting(targetFile), computeTargetCheksum); } /** * Receives a next diff window to be applied. The return value is a * dummy stream (left for backward compatibility) since new data should * come within a diff window. * * @param window a diff window * @return a dummy output stream * @throws SVNException */ public OutputStream textDeltaChunk(SVNDiffWindow window) throws SVNException { window.apply(myApplyBaton); return SVNFileUtil.DUMMY_OUT; } private void reset() { if (myApplyBaton != null) { myApplyBaton.close(); myApplyBaton = null; } } /** * Performs delta processing finalizing steps. Applies the last * window left (if any) and finalizes checksum calculation (if a * checksum was required). * * @return a string representing a hex form of the calculated * MD5 checksum or <span class="javakeyword">null</span> * if checksum calculation was not required */ public String textDeltaEnd() { try { return myApplyBaton.close(); } finally { reset(); } } }