001/*
002 * Syncany, www.syncany.org
003 * Copyright (C) 2011-2016 Philipp C. Heckel <philipp.heckel@gmail.com> 
004 *
005 * This program is free software: you can redistribute it and/or modify
006 * it under the terms of the GNU General Public License as published by
007 * the Free Software Foundation, either version 3 of the License, or
008 * (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013 * GNU General Public License for more details.
014 *
015 * You should have received a copy of the GNU General Public License
016 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
017 */
018package org.syncany.config.to;
019
020import java.security.SecureRandom;
021import java.util.ArrayList;
022import java.util.HashMap;
023import java.util.List;
024import java.util.Map;
025
026import org.syncany.chunk.Chunker;
027import org.syncany.chunk.CipherTransformer;
028import org.syncany.chunk.FixedChunker;
029import org.syncany.chunk.GzipTransformer;
030import org.syncany.chunk.MultiChunker;
031import org.syncany.chunk.ZipMultiChunker;
032import org.syncany.config.to.RepoTO.ChunkerTO;
033import org.syncany.config.to.RepoTO.MultiChunkerTO;
034import org.syncany.config.to.RepoTO.TransformerTO;
035import org.syncany.crypto.CipherSpec;
036import org.syncany.util.StringUtil;
037import org.syncany.util.StringUtil.StringJoinListener;
038
039/**
040 * This class produces {@link RepoTO}s with some sensible defaults for the Chunkers and
041 * MultiChunkers. The transformers are configurable, namely whether or not compression is used
042 * and how it is encrypted.
043 * 
044 * @author Pim Otte (otte.pim@gmail.com)
045 */
046public class DefaultRepoTOFactory implements RepoTOFactory {
047        private ChunkerTO chunkerTO;
048        private MultiChunkerTO multiChunkerTO;
049        private List<TransformerTO> transformersTO;
050
051        public DefaultRepoTOFactory(boolean gzipEnabled, List<CipherSpec> cipherSpecs) {
052                chunkerTO = getDefaultChunkerTO();
053                multiChunkerTO = getDefaultMultiChunkerTO();
054                transformersTO = getTransformersTO(gzipEnabled, cipherSpecs);
055        }
056
057        public RepoTO createRepoTO() {
058                return createRepoTO(chunkerTO, multiChunkerTO, transformersTO);
059        }
060
061        public List<TransformerTO> getTransformersTO(boolean gzipEnabled, List<CipherSpec> cipherSpecs) {
062                List<TransformerTO> transformersTO = new ArrayList<TransformerTO>();
063
064                if (gzipEnabled) {
065                        transformersTO.add(getGzipTransformerTO());
066                }
067
068                if (cipherSpecs.size() > 0) {
069                        TransformerTO cipherTransformerTO = getCipherTransformerTO(cipherSpecs);
070                        transformersTO.add(cipherTransformerTO);
071                }
072
073                return transformersTO;
074        }
075
076        public RepoTO createRepoTO(ChunkerTO chunkerTO, MultiChunkerTO multiChunkerTO, List<TransformerTO> transformersTO) {
077                // Make transfer object
078                RepoTO repoTO = new RepoTO();
079
080                // Create random repo identifier
081                byte[] newRepoId = new byte[32];
082                new SecureRandom().nextBytes(newRepoId);
083
084                repoTO.setRepoId(newRepoId);
085
086                // Add to repo transfer object
087                repoTO.setChunkerTO(chunkerTO);
088                repoTO.setMultiChunker(multiChunkerTO);
089                repoTO.setTransformers(transformersTO);
090
091                return repoTO;
092        }
093
094        protected ChunkerTO getDefaultChunkerTO() {
095                ChunkerTO chunkerTO = new ChunkerTO();
096
097                chunkerTO.setType(FixedChunker.TYPE);
098                chunkerTO.setSettings(new HashMap<String, String>());
099                chunkerTO.getSettings().put(Chunker.PROPERTY_SIZE, "16");
100
101                return chunkerTO;
102        }
103
104        protected MultiChunkerTO getDefaultMultiChunkerTO() {
105                MultiChunkerTO multichunkerTO = new MultiChunkerTO();
106
107                multichunkerTO.setType(ZipMultiChunker.TYPE);
108                multichunkerTO.setSettings(new HashMap<String, String>());
109                multichunkerTO.getSettings().put(MultiChunker.PROPERTY_SIZE, "4096");
110
111                return multichunkerTO;
112        }
113
114        protected TransformerTO getGzipTransformerTO() {
115                TransformerTO gzipTransformerTO = new TransformerTO();
116                gzipTransformerTO.setType(GzipTransformer.TYPE);
117
118                return gzipTransformerTO;
119        }
120
121        protected TransformerTO getCipherTransformerTO(List<CipherSpec> cipherSpec) {
122                String cipherSuitesIdStr = StringUtil.join(cipherSpec, ",", new StringJoinListener<CipherSpec>() {
123                        @Override
124                        public String getString(CipherSpec cipherSpec) {
125                                return "" + cipherSpec.getId();
126                        }
127                });
128
129                Map<String, String> cipherTransformerSettings = new HashMap<String, String>();
130                cipherTransformerSettings.put(CipherTransformer.PROPERTY_CIPHER_SPECS, cipherSuitesIdStr);
131                // Note: Property 'password' is added dynamically by CommandLineClient
132
133                TransformerTO cipherTransformerTO = new TransformerTO();
134                cipherTransformerTO.setType(CipherTransformer.TYPE);
135                cipherTransformerTO.setSettings(cipherTransformerSettings);
136
137                return cipherTransformerTO;
138        }
139}