tikhomirov@617: /*
tikhomirov@617:  * Copyright (c) 2013 TMate Software Ltd
tikhomirov@617:  *  
tikhomirov@617:  * This program is free software; you can redistribute it and/or modify
tikhomirov@617:  * it under the terms of the GNU General Public License as published by
tikhomirov@617:  * the Free Software Foundation; version 2 of the License.
tikhomirov@617:  *
tikhomirov@617:  * This program is distributed in the hope that it will be useful,
tikhomirov@617:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
tikhomirov@617:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
tikhomirov@617:  * GNU General Public License for more details.
tikhomirov@617:  *
tikhomirov@617:  * For information on how to redistribute this software under
tikhomirov@617:  * the terms of a license other than GNU General Public License
tikhomirov@617:  * contact TMate Software at support@hg4j.com
tikhomirov@617:  */
tikhomirov@617: package org.tmatesoft.hg.internal;
tikhomirov@617: 
tikhomirov@617: import java.io.File;
tikhomirov@617: import java.io.IOException;
tikhomirov@617: 
tikhomirov@617: import org.tmatesoft.hg.core.HgIOException;
tikhomirov@617: import org.tmatesoft.hg.core.SessionContext;
tikhomirov@617: import org.tmatesoft.hg.repo.HgInvalidStateException;
tikhomirov@617: 
tikhomirov@617: /**
tikhomirov@617:  * Implementation strategies possible:
tikhomirov@617:  * -  Get a copy, write changes to origin, keep copy as backup till #commit
tikhomirov@617:  *   
(-) doesn't break hard links 
tikhomirov@617:  * 
 -  Get a copy, write changes to a copy, on commit rename copy to origin. 
tikhomirov@617:  *   
(-) What if we read newly written data (won't find it);
tikhomirov@617:  *   
(-) complex #commit
tikhomirov@617:  *   
(+) simple rollback
tikhomirov@617:  * 
 -  Get a copy, rename origin to backup (breaks hard links), rename copy to origin, write changes 
tikhomirov@617:  *   
(+) Modified file is in place right away;
tikhomirov@617:  *   
(+) easy #commit
tikhomirov@617:  * 
 -  Do not copy, just record file size, truncate to that size on rollback
tikhomirov@617:  * 
 -  ...?
tikhomirov@617:  * 
 
 
tikhomirov@617:  * @author Artem Tikhomirov
tikhomirov@617:  * @author TMate Software Ltd.
tikhomirov@617:  */
tikhomirov@617: public abstract class Transaction {
tikhomirov@617: 	/**
tikhomirov@617: 	 * Record the file is going to be modified during this transaction, obtain actual
tikhomirov@617: 	 * destination to write to.
tikhomirov@621: 	 * The file to be modified not necessarily exists, might be just a name of an added file  
tikhomirov@617: 	 */
tikhomirov@617: 	public abstract File prepare(File f) throws HgIOException;
tikhomirov@617: 	/**
tikhomirov@617: 	 * overwrites backup if exists, backup is kept after successful {@link #commit()}
tikhomirov@617: 	 */
tikhomirov@617: 	public abstract File prepare(File origin, File backup) throws HgIOException;
tikhomirov@617: 	/**
tikhomirov@617: 	 * Tell that file was successfully processed
tikhomirov@617: 	 */
tikhomirov@617: 	public abstract void done(File f) throws HgIOException;
tikhomirov@617: 	/**
tikhomirov@617: 	 * optional?
tikhomirov@617: 	 */
tikhomirov@617: 	public abstract void failure(File f, IOException ex);
tikhomirov@617: 	/**
tikhomirov@617: 	 * Complete the transaction
tikhomirov@617: 	 */
tikhomirov@617: 	public abstract void commit() throws HgIOException;
tikhomirov@617: 	/**
tikhomirov@617: 	 * Undo all the changes
tikhomirov@617: 	 */
tikhomirov@617: 	public abstract void rollback() throws HgIOException;
tikhomirov@617: 
tikhomirov@617: 	public interface Factory {
tikhomirov@617: 		public Transaction create(SessionContext.Source ctxSource);
tikhomirov@617: 	}
tikhomirov@617: 
tikhomirov@617: 	public static class NoRollback extends Transaction {
tikhomirov@617: 
tikhomirov@617: 		@Override
tikhomirov@617: 		public File prepare(File f) throws HgIOException {
tikhomirov@617: 			return f;
tikhomirov@617: 		}
tikhomirov@617: 
tikhomirov@617: 		@Override
tikhomirov@617: 		public File prepare(File origin, File backup) throws HgIOException {
tikhomirov@617: 			return origin;
tikhomirov@617: 		}
tikhomirov@617: 
tikhomirov@617: 		@Override
tikhomirov@617: 		public void done(File f) throws HgIOException {
tikhomirov@617: 			// no-op
tikhomirov@617: 		}
tikhomirov@617: 
tikhomirov@617: 		@Override
tikhomirov@617: 		public void failure(File f, IOException ex) {
tikhomirov@617: 			// no-op
tikhomirov@617: 		}
tikhomirov@617: 
tikhomirov@617: 		@Override
tikhomirov@617: 		public void commit() throws HgIOException {
tikhomirov@617: 			// no-op
tikhomirov@617: 		}
tikhomirov@617: 
tikhomirov@617: 		@Override
tikhomirov@617: 		public void rollback() throws HgIOException {
tikhomirov@617: 			throw new HgInvalidStateException("This transaction doesn't support rollback");
tikhomirov@617: 		}
tikhomirov@617: 	}
tikhomirov@617: }