/* * Syncany, www.syncany.org * Copyright (C) 2011-2015 Philipp C. Heckel <philipp.heckel@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.syncany.config.to; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileOutputStream; import java.util.ArrayList; import java.util.List; import org.apache.commons.io.output.ByteArrayOutputStream; import org.simpleframework.xml.Element; import org.simpleframework.xml.ElementList; import org.simpleframework.xml.Root; import org.simpleframework.xml.Serializer; import org.simpleframework.xml.core.Commit; import org.simpleframework.xml.core.Complete; import org.simpleframework.xml.core.Persist; import org.simpleframework.xml.core.Persister; import org.syncany.config.ConfigException; import org.syncany.crypto.CipherSpec; import org.syncany.crypto.CipherUtil; import org.syncany.crypto.SaltedSecretKey; import org.syncany.util.StringUtil; /** * The repo transfer object is used to create and load the repo file * from/to XML. The repo file identifies the repository with a unique * repo ID, and defines the chunking framework settings. It is * stored locally and on the remote storage. * * <p>It uses the Simple framework for XML serialization, and its corresponding * annotation-based configuration. * * @see <a href="http://simple.sourceforge.net/">Simple framework</a> * @author Philipp C. Heckel <philipp.heckel@gmail.com> */ @Root(name = "repo", strict = false) public class RepoTO { @Element(name = "repoid", required = true) private String repoIdEncoded; private byte[] repoId; @Element(name = "chunker", required = false) private ChunkerTO chunker; @Element(name = "multichunker", required = false) private MultiChunkerTO multiChunker; @ElementList(name = "transformers", required = false, entry = "transformer") private ArrayList<TransformerTO> transformers; public byte[] getRepoId() { return repoId; } public void setRepoId(byte[] repoId) { this.repoId = repoId; } public void save(File file) throws ConfigException { try { new Persister().write(this, file); } catch (Exception e) { throw new ConfigException("Cannot write repoTO to file " + file, e); } } public void save(File file, List<CipherSpec> cipherSpecs, SaltedSecretKey masterKey) throws ConfigException { try { ByteArrayOutputStream plaintextRepoOutputStream = new ByteArrayOutputStream(); Serializer serializer = new Persister(); serializer.write(this, plaintextRepoOutputStream); CipherUtil.encrypt(new ByteArrayInputStream(plaintextRepoOutputStream.toByteArray()), new FileOutputStream(file), cipherSpecs, masterKey); } catch (Exception e) { throw new ConfigException("Cannot write repoTO (encrypted) to file " + file, e); } } @Persist public void prepare() { repoIdEncoded = (repoId != null) ? StringUtil.toHex(repoId) : null; } @Complete public void release() { repoIdEncoded = null; } @Commit public void commit() { repoId = (repoIdEncoded != null) ? StringUtil.fromHex(repoIdEncoded) : null; } public ChunkerTO getChunkerTO() { return chunker; } public void setChunkerTO(ChunkerTO chunker) { this.chunker = chunker; } public MultiChunkerTO getMultiChunker() { return multiChunker; } public void setMultiChunker(MultiChunkerTO multiChunker) { this.multiChunker = multiChunker; } public List<TransformerTO> getTransformers() { return transformers; } public void setTransformers(List<TransformerTO> transformers) { this.transformers = (transformers != null) ? new ArrayList<TransformerTO>(transformers) : null; } /** * Configuration object for the deduplication chunker. As of * today, this is a key/value based configuration. */ public static class ChunkerTO extends TypedPropertyListTO { // Nothing special about this } /** * Configuration object for the deduplication multi-chunker. As of * today, this is a key/value based configuration. */ public static class MultiChunkerTO extends TypedPropertyListTO { // Nothing special about this } /** * Configuration object for the deduplication transformer. As of * today, this is a key/value based configuration. */ public static class TransformerTO extends TypedPropertyListTO { // Nothing special about this } }