tikhomirov@490: /* tikhomirov@637: * Copyright (c) 2012-2013 TMate Software Ltd tikhomirov@490: * tikhomirov@490: * This program is free software; you can redistribute it and/or modify tikhomirov@490: * it under the terms of the GNU General Public License as published by tikhomirov@490: * the Free Software Foundation; version 2 of the License. tikhomirov@490: * tikhomirov@490: * This program is distributed in the hope that it will be useful, tikhomirov@490: * but WITHOUT ANY WARRANTY; without even the implied warranty of tikhomirov@490: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the tikhomirov@490: * GNU General Public License for more details. tikhomirov@490: * tikhomirov@490: * For information on how to redistribute this software under tikhomirov@490: * the terms of a license other than GNU General Public License tikhomirov@490: * contact TMate Software at support@hg4j.com tikhomirov@490: */ tikhomirov@490: package org.tmatesoft.hg.internal; tikhomirov@490: tikhomirov@490: import static org.tmatesoft.hg.internal.RequiresFile.*; tikhomirov@490: tikhomirov@490: import java.io.File; tikhomirov@490: import java.io.FileOutputStream; tikhomirov@490: import java.io.IOException; tikhomirov@490: import java.nio.charset.Charset; tikhomirov@490: tikhomirov@622: import org.tmatesoft.hg.core.HgIOException; tikhomirov@490: import org.tmatesoft.hg.core.SessionContext; tikhomirov@493: import org.tmatesoft.hg.repo.HgInvalidControlFileException; tikhomirov@490: import org.tmatesoft.hg.util.PathRewrite; tikhomirov@490: tikhomirov@490: /** tikhomirov@490: * Responsible of `requires` processing both on repo read and repo write tikhomirov@490: * XXX needs better name, perhaps tikhomirov@490: * tikhomirov@637: * @see http://mercurial.selenic.com/wiki/RequiresFile tikhomirov@490: * @author Artem Tikhomirov tikhomirov@490: * @author TMate Software Ltd. tikhomirov@490: */ tikhomirov@490: public class RepoInitializer { tikhomirov@490: private int requiresFlags; tikhomirov@490: tikhomirov@490: public RepoInitializer() { tikhomirov@490: } tikhomirov@490: tikhomirov@493: public RepoInitializer initRequiresFromFile(File repoDir) throws HgInvalidControlFileException { tikhomirov@493: File requiresFile = new File(repoDir, "requires"); // not #getFileFromRepoDir() just in case it gets modified later tikhomirov@493: try { tikhomirov@493: int flags = new RequiresFile().parse(requiresFile); tikhomirov@493: return setRequires(flags); tikhomirov@493: } catch (IOException ex) { tikhomirov@493: throw new HgInvalidControlFileException("Parse failed", ex, requiresFile); tikhomirov@493: } tikhomirov@493: } tikhomirov@493: tikhomirov@490: public RepoInitializer setRequires(int flags) { tikhomirov@490: requiresFlags = flags; tikhomirov@490: return this; tikhomirov@490: } tikhomirov@490: tikhomirov@490: public int getRequires() { tikhomirov@490: return requiresFlags; tikhomirov@490: } tikhomirov@490: tikhomirov@622: public void initEmptyRepository(File repoDir) throws HgIOException { tikhomirov@493: repoDir.mkdirs(); tikhomirov@622: final File requiresFile = new File(repoDir, "requires"); tikhomirov@622: try { tikhomirov@622: FileOutputStream requiresStream = new FileOutputStream(requiresFile); tikhomirov@622: StringBuilder sb = new StringBuilder(40); tikhomirov@637: if ((requiresFlags & REVLOGV1) != 0) { tikhomirov@637: sb.append("revlogv1\n"); tikhomirov@637: } tikhomirov@622: if ((requiresFlags & STORE) != 0) { tikhomirov@622: sb.append("store\n"); tikhomirov@622: } tikhomirov@622: if ((requiresFlags & FNCACHE) != 0) { tikhomirov@622: sb.append("fncache\n"); tikhomirov@622: } tikhomirov@622: if ((requiresFlags & DOTENCODE) != 0) { tikhomirov@622: sb.append("dotencode\n"); tikhomirov@622: } tikhomirov@622: requiresStream.write(sb.toString().getBytes()); tikhomirov@622: requiresStream.close(); tikhomirov@622: } catch (IOException ex) { tikhomirov@622: throw new HgIOException("Failed to initialize empty repo", ex, requiresFile); tikhomirov@490: } tikhomirov@637: if ((requiresFlags & STORE) != 0) { tikhomirov@637: new File(repoDir, "store").mkdir(); // with that, hg verify says ok. tikhomirov@637: } tikhomirov@490: } tikhomirov@490: tikhomirov@490: public PathRewrite buildDataFilesHelper(SessionContext ctx) { tikhomirov@490: Charset cs = Internals.getFileEncoding(ctx); tikhomirov@490: // StoragePathHelper needs fine-grained control over char encoding, hence doesn't use EncodingHelper tikhomirov@490: return new StoragePathHelper((requiresFlags & STORE) != 0, (requiresFlags & FNCACHE) != 0, (requiresFlags & DOTENCODE) != 0, cs); tikhomirov@490: } tikhomirov@493: tikhomirov@493: public PathRewrite buildStoreFilesHelper() { tikhomirov@493: if ((requiresFlags & STORE) != 0) { tikhomirov@493: return new PathRewrite() { tikhomirov@493: public CharSequence rewrite(CharSequence path) { tikhomirov@493: return "store/" + path; tikhomirov@493: } tikhomirov@493: }; tikhomirov@493: } else { tikhomirov@493: return new PathRewrite.Empty(); tikhomirov@493: } tikhomirov@493: } tikhomirov@490: }