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.io.File; 021 022import org.simpleframework.xml.Element; 023import org.simpleframework.xml.Root; 024import org.simpleframework.xml.convert.Convert; 025import org.simpleframework.xml.convert.Registry; 026import org.simpleframework.xml.convert.RegistryStrategy; 027import org.simpleframework.xml.core.Persister; 028import org.simpleframework.xml.strategy.Strategy; 029import org.syncany.config.ConfigException; 030import org.syncany.crypto.SaltedSecretKey; 031import org.syncany.crypto.SaltedSecretKeyConverter; 032import org.syncany.plugins.transfer.EncryptedTransferSettingsConverter; 033import org.syncany.plugins.transfer.TransferSettings; 034 035/** 036 * The config transfer object is used to create and load the local config 037 * file from/to XML. The config file contains local config settings of a client, 038 * namely the machine and display name, the master key as well as connection 039 * information (for the connection plugin). 040 * 041 * <p>It uses the Simple framework for XML serialization, and its corresponding 042 * annotation-based configuration. 043 * 044 * @see <a href="http://simple.sourceforge.net/">Simple framework</a> 045 * @author Philipp C. Heckel (philipp.heckel@gmail.com) 046 */ 047@Root(name = "config", strict = false) 048public class ConfigTO { 049 @Element(name = "machineName", required = true) 050 private String machineName; 051 052 @Element(name = "displayName", required = false) 053 private String displayName; 054 055 @Element(name = "masterKey", required = false) 056 @Convert(SaltedSecretKeyConverter.class) 057 private SaltedSecretKey masterKey; 058 059 @Element(name = "connection", required = false) 060 // TODO [high] Workaround for 'connect' via GUI and syncany://link; field not needed when link is supplied 061 private TransferSettings transferSettings; 062 063 @Element(name = "cacheKeepBytes", required = false) 064 private Long cacheKeepBytes; 065 066 public static ConfigTO load(File file) throws ConfigException { 067 try { 068 Registry registry = new Registry(); 069 Strategy strategy = new RegistryStrategy(registry); 070 registry.bind(SaltedSecretKey.class, new SaltedSecretKeyConverter()); 071 registry.bind(String.class, new EncryptedTransferSettingsConverter()); 072 073 return new Persister(strategy).read(ConfigTO.class, file); 074 } 075 catch (ClassNotFoundException ex) { 076 // Ugly hack to catch common case of non-existing plugin 077 String message = ex.getMessage(); 078 079 if (!message.startsWith("org.syncany.plugins.")) { 080 // Apparently there are other ClassNotFoundExceptions possible. 081 throw new ConfigException("Config file does not exist or is invalid: " + file, ex); 082 } 083 084 message = message.replaceFirst("org.syncany.plugins.", ""); 085 message = message.replaceAll("\\..*", ""); 086 throw new ConfigException("Is the " + message + " plugin installed?"); 087 } 088 catch (Exception ex) { 089 throw new ConfigException("Config file does not exist or is invalid: " + file, ex); 090 } 091 } 092 093 public void save(File file) throws ConfigException { 094 try { 095 Registry registry = new Registry(); 096 Strategy strategy = new RegistryStrategy(registry); 097 registry.bind(SaltedSecretKey.class, new SaltedSecretKeyConverter()); 098 registry.bind(String.class, new EncryptedTransferSettingsConverter(transferSettings.getClass())); 099 100 new Persister(strategy).write(this, file); 101 } 102 catch (Exception e) { 103 throw new ConfigException("Cannot write config to file " + file, e); 104 } 105 } 106 107 public String getMachineName() { 108 return machineName; 109 } 110 111 public void setMachineName(String machineName) { 112 this.machineName = machineName; 113 } 114 115 public String getDisplayName() { 116 return displayName; 117 } 118 119 public void setDisplayName(String displayName) { 120 this.displayName = displayName; 121 } 122 123 public TransferSettings getTransferSettings() { 124 return transferSettings; 125 } 126 127 public void setTransferSettings(TransferSettings transferSettings) { 128 this.transferSettings = transferSettings; 129 } 130 131 public SaltedSecretKey getMasterKey() { 132 return masterKey; 133 } 134 135 public void setMasterKey(SaltedSecretKey masterKey) { 136 this.masterKey = masterKey; 137 } 138 139 public Long getCacheKeepBytes() { 140 return cacheKeepBytes; 141 } 142 143 public void setCacheKeepBytes(Long cacheKeepBytes) { 144 this.cacheKeepBytes = cacheKeepBytes; 145 } 146 147}