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.operations.init; 019 020import java.io.File; 021import java.io.IOException; 022import java.lang.reflect.Constructor; 023import java.lang.reflect.InvocationTargetException; 024import java.nio.file.Files; 025import java.nio.file.Paths; 026import java.util.logging.Logger; 027 028import org.syncany.config.Config; 029import org.syncany.config.LocalEventBus; 030import org.syncany.config.to.ConfigTO; 031import org.syncany.operations.Operation; 032import org.syncany.operations.daemon.messages.ShowMessageExternalEvent; 033import org.syncany.plugins.Plugins; 034import org.syncany.plugins.UserInteractionListener; 035import org.syncany.plugins.transfer.StorageException; 036import org.syncany.plugins.transfer.TransferManager; 037import org.syncany.plugins.transfer.TransferManagerFactory.TransferManagerBuilder; 038import org.syncany.plugins.transfer.TransferPlugin; 039import org.syncany.plugins.transfer.TransferSettings; 040import org.syncany.plugins.transfer.features.ReadAfterWriteConsistent; 041import org.syncany.util.EnvironmentUtil; 042 043/** 044 * The abstract init operation implements common functions of the {@link InitOperation} 045 * and the {@link ConnectOperation}. Its sole purpose is to avoid duplicate code in these 046 * similar operations. 047 * 048 * @author Philipp C. Heckel (philipp.heckel@gmail.com) 049 */ 050public abstract class AbstractInitOperation extends Operation { 051 protected static final Logger logger = Logger.getLogger(AbstractInitOperation.class.getSimpleName()); 052 053 protected UserInteractionListener listener; 054 protected LocalEventBus eventBus; 055 056 public AbstractInitOperation(Config config, UserInteractionListener listener) { 057 super(config); 058 059 this.listener = listener; 060 this.eventBus = LocalEventBus.getInstance(); 061 } 062 063 protected File createAppDirs(File localDir) throws IOException { 064 if (localDir == null) { 065 throw new RuntimeException("Unable to create app dir, local dir is null."); 066 } 067 068 File appDir = new File(localDir, Config.DIR_APPLICATION); 069 File logDir = new File(appDir, Config.DIR_LOG); 070 File cacheDir = new File(appDir, Config.DIR_CACHE); 071 File databaseDir = new File(appDir, Config.DIR_DATABASE); 072 File stateDir = new File(appDir, Config.DIR_STATE); 073 074 appDir.mkdir(); 075 logDir.mkdir(); 076 cacheDir.mkdir(); 077 databaseDir.mkdir(); 078 stateDir.mkdir(); 079 080 if (EnvironmentUtil.isWindows()) { 081 Files.setAttribute(Paths.get(appDir.getAbsolutePath()), "dos:hidden", true); 082 } 083 084 return appDir; 085 } 086 087 protected void deleteAppDirs(File localDir) throws IOException { 088 File appDir = new File(localDir, Config.DIR_APPLICATION); 089 File logDir = new File(appDir, Config.DIR_LOG); 090 File cacheDir = new File(appDir, Config.DIR_CACHE); 091 File databaseDir = new File(appDir, Config.DIR_DATABASE); 092 093 for (File log : logDir.listFiles()) { 094 log.delete(); 095 } 096 097 for (File cache : cacheDir.listFiles()) { 098 cache.delete(); 099 } 100 101 for (File db : databaseDir.listFiles()) { 102 db.delete(); 103 } 104 105 for (File file : appDir.listFiles()) { 106 file.delete(); 107 } 108 109 logDir.delete(); 110 cacheDir.delete(); 111 databaseDir.delete(); 112 appDir.delete(); 113 } 114 115 protected void fireNotifyCreateMaster() { 116 eventBus.post(new ShowMessageExternalEvent("Creating master key from password (this might take a while) ...")); 117 } 118 119 protected TransferManager createTransferManagerFromNullConfig(ConfigTO configTo) throws IllegalAccessException, 120 InvocationTargetException, InstantiationException, NoSuchMethodException, StorageException { 121 122 // Init plugin and transfer manager 123 TransferPlugin plugin = Plugins.get(configTo.getTransferSettings().getType(), TransferPlugin.class); 124 125 TransferSettings transferSettings = configTo.getTransferSettings(); 126 transferSettings.setUserInteractionListener(listener); 127 TransferManager transferManager = plugin.createTransferManager(transferSettings, config); 128 129 // constructor is not visible and config seems to be null at this point, hence we cannot use the build method here 130 Constructor<TransferManagerBuilder> tmbConstructor = TransferManagerBuilder.class.getDeclaredConstructor(Config.class, TransferManager.class); 131 tmbConstructor.setAccessible(true); 132 133 return tmbConstructor.newInstance(config, transferManager) 134 .withFeature(ReadAfterWriteConsistent.class) 135 .asDefault(); 136 } 137}