tikhomirov@539: /*
tikhomirov@539:  * Copyright (c) 2013 TMate Software Ltd
tikhomirov@539:  *  
tikhomirov@539:  * This program is free software; you can redistribute it and/or modify
tikhomirov@539:  * it under the terms of the GNU General Public License as published by
tikhomirov@539:  * the Free Software Foundation; version 2 of the License.
tikhomirov@539:  *
tikhomirov@539:  * This program is distributed in the hope that it will be useful,
tikhomirov@539:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
tikhomirov@539:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
tikhomirov@539:  * GNU General Public License for more details.
tikhomirov@539:  *
tikhomirov@539:  * For information on how to redistribute this software under
tikhomirov@539:  * the terms of a license other than GNU General Public License
tikhomirov@539:  * contact TMate Software at support@hg4j.com
tikhomirov@539:  */
tikhomirov@539: package org.tmatesoft.hg.internal;
tikhomirov@539: 
tikhomirov@539: import java.io.File;
tikhomirov@539: import java.io.FileOutputStream;
tikhomirov@539: import java.io.IOException;
tikhomirov@539: import java.nio.charset.Charset;
tikhomirov@539: import java.util.ArrayList;
tikhomirov@559: import java.util.List;
tikhomirov@539: 
tikhomirov@539: import org.tmatesoft.hg.util.Path;
tikhomirov@539: 
tikhomirov@539: /**
tikhomirov@559:  * Append-only fncache support
tikhomirov@559:  * 
tikhomirov@539:  * 
tikhomirov@539:  * The fncache file contains the paths of all filelog files in the store as encoded by mercurial.filelog.encodedir. The paths are separated by '\n' (LF).
tikhomirov@539:  * 
tikhomirov@539:  * @see http://mercurial.selenic.com/wiki/fncacheRepoFormat
tikhomirov@559:  * 
tikhomirov@559:  * 
tikhomirov@539:  * @author Artem Tikhomirov
tikhomirov@539:  * @author TMate Software Ltd.
tikhomirov@539:  */
tikhomirov@539: public class FNCacheFile {
tikhomirov@539: 	
tikhomirov@539: 	private final Internals repo;
tikhomirov@559: //	private final List files;
tikhomirov@559: 	private List added;
tikhomirov@539: 
tikhomirov@539: 	public FNCacheFile(Internals internalRepo) {
tikhomirov@539: 		repo = internalRepo;
tikhomirov@559: //		files = new ArrayList();
tikhomirov@539: 	}
tikhomirov@539: 
tikhomirov@559: 	/*
tikhomirov@559: 	 * For append-only option, we don't care reading the original content
tikhomirov@539: 	public void read(Path.Source pathFactory) throws IOException {
tikhomirov@539: 		File f = fncacheFile();
tikhomirov@539: 		files.clear();
tikhomirov@539: 		if (!f.exists()) {
tikhomirov@539: 			return;
tikhomirov@539: 		}
tikhomirov@539: 		ArrayList entries = new ArrayList();
tikhomirov@539: 		// names in fncache are in local encoding, shall translate to unicode
tikhomirov@539: 		new LineReader(f, repo.getSessionContext().getLog(), repo.getFilenameEncoding()).read(new LineReader.SimpleLineCollector(), entries);
tikhomirov@539: 		for (String e : entries) {
tikhomirov@559: 			// FIXME plain wrong, need either to decode paths and strip off .i/.d or (if keep names as is) change write()
tikhomirov@539: 			files.add(pathFactory.path(e));
tikhomirov@539: 		}
tikhomirov@539: 	}
tikhomirov@559: 	*/
tikhomirov@539: 	
tikhomirov@539: 	public void write() throws IOException {
tikhomirov@559: 		if (added == null || added.isEmpty()) {
tikhomirov@539: 			return;
tikhomirov@539: 		}
tikhomirov@539: 		File f = fncacheFile();
tikhomirov@539: 		f.getParentFile().mkdirs();
tikhomirov@539: 		final Charset filenameEncoding = repo.getFilenameEncoding();
tikhomirov@559: 		FileOutputStream fncacheFile = new FileOutputStream(f, true);
tikhomirov@559: 		for (Path p : added) {
tikhomirov@559: 			String s = "data/" + p.toString() + ".i"; // TODO post-1.0 this is plain wrong. (a) need .d files, too; (b) what about dh/ location? 
tikhomirov@539: 			fncacheFile.write(s.getBytes(filenameEncoding));
tikhomirov@539: 			fncacheFile.write(0x0A); // http://mercurial.selenic.com/wiki/fncacheRepoFormat
tikhomirov@539: 		}
tikhomirov@539: 		fncacheFile.close();
tikhomirov@539: 	}
tikhomirov@539: 
tikhomirov@539: 	public void add(Path p) {
tikhomirov@559: 		if (added == null) {
tikhomirov@559: 			added = new ArrayList();
tikhomirov@559: 		}
tikhomirov@559: 		added.add(p);
tikhomirov@539: 	}
tikhomirov@539: 
tikhomirov@539: 	private File fncacheFile() {
tikhomirov@539: 		return repo.getFileFromStoreDir("fncache");
tikhomirov@539: 	}
tikhomirov@539: }