/* * Copyright (C) 2015-2017 PÂRIS Quentin * * 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 2 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package org.phoenicis.containers.wine; import jdk.nashorn.api.scripting.ScriptObjectMirror; import org.phoenicis.containers.dto.WinePrefixContainerDTO; import org.phoenicis.containers.wine.parameters.RegistryParameter; import org.phoenicis.library.LibraryManager; import org.phoenicis.library.ShortcutManager; import org.phoenicis.library.dto.ShortcutCategoryDTO; import org.phoenicis.scripts.interpreter.InteractiveScriptSession; import org.phoenicis.scripts.interpreter.ScriptInterpreter; import org.phoenicis.tools.files.FileUtilities; import org.phoenicis.tools.system.OperatingSystemFetcher; import org.phoenicis.tools.system.terminal.TerminalOpener; import org.phoenicis.win32.registry.RegistryWriter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Consumer; public class WinePrefixContainerController { private static final Logger LOGGER = LoggerFactory.getLogger(WinePrefixContainerController.class); private final ScriptInterpreter scriptInterpreter; private final TerminalOpener terminalOpener; private final String wineEnginesPath; private final OperatingSystemFetcher operatingSystemFetcher; private final RegistryWriter registryWriter; private final LibraryManager libraryManager; private final ShortcutManager shortcutManager; private final FileUtilities fileUtilities; public WinePrefixContainerController(ScriptInterpreter scriptInterpreter, TerminalOpener terminalOpener, String wineEnginesPath, OperatingSystemFetcher operatingSystemFetcher, RegistryWriter registryWriter, LibraryManager libraryManager, ShortcutManager shortcutManager, FileUtilities fileUtilities) { this.scriptInterpreter = scriptInterpreter; this.terminalOpener = terminalOpener; this.wineEnginesPath = wineEnginesPath; this.operatingSystemFetcher = operatingSystemFetcher; this.registryWriter = registryWriter; this.libraryManager = libraryManager; this.shortcutManager = shortcutManager; this.fileUtilities = fileUtilities; } public void repairPrefix(WinePrefixContainerDTO winePrefix, Runnable doneCallback, Consumer<Exception> errorCallback) { // FIXME final InteractiveScriptSession interactiveScriptSession = scriptInterpreter.createInteractiveSession(); interactiveScriptSession.eval("include([\"Functions\", \"Engines\", \"Wine\"]);", ignored -> interactiveScriptSession.eval("new Wine()", output -> { final ScriptObjectMirror wine = (ScriptObjectMirror) output; wine.callMember("prefix", winePrefix.getName()); wine.callMember("run", "wineboot"); wine.callMember("wait"); doneCallback.run(); }, errorCallback), errorCallback); } public void killProcesses(WinePrefixContainerDTO winePrefix, Runnable doneCallback, Consumer<Exception> errorCallback) { final InteractiveScriptSession interactiveScriptSession = scriptInterpreter.createInteractiveSession(); interactiveScriptSession.eval("include([\"Functions\", \"Engines\", \"Wine\"]);", ignored -> interactiveScriptSession.eval("new Wine()", output -> { final ScriptObjectMirror wine = (ScriptObjectMirror) output; wine.callMember("prefix", winePrefix.getName()); wine.callMember("kill"); doneCallback.run(); }, errorCallback), errorCallback); } public void changeSetting(WinePrefixContainerDTO winePrefix, RegistryParameter setting, Runnable doneCallback, Consumer<Exception> errorCallback) { final InteractiveScriptSession interactiveScriptSession = scriptInterpreter.createInteractiveSession(); final String registryPatch = registryWriter.generateRegFileContent(setting.toRegistryPatch()); LOGGER.info("Updating registry for prefix: " + winePrefix.getPath()); LOGGER.info(registryPatch); interactiveScriptSession.eval("include([\"Functions\", \"Engines\", \"Wine\"]);", ignored -> interactiveScriptSession.eval("new Wine()", output -> { final ScriptObjectMirror wine = (ScriptObjectMirror) output; wine.callMember("prefix", winePrefix.getName()); final ScriptObjectMirror regedit = (ScriptObjectMirror) wine.callMember("regedit"); regedit.callMember("patch", registryPatch); wine.callMember("wait"); doneCallback.run(); }, errorCallback), errorCallback); } public void runInPrefix(WinePrefixContainerDTO winePrefix, String command, Runnable doneCallback, Consumer<Exception> errorCallback) { final InteractiveScriptSession interactiveScriptSession = scriptInterpreter.createInteractiveSession(); interactiveScriptSession.eval("include([\"Functions\", \"Engines\", \"Wine\"]);", ignored -> interactiveScriptSession.eval("new Wine()", output -> { final ScriptObjectMirror wine = (ScriptObjectMirror) output; wine.callMember("prefix", winePrefix.getName()); wine.callMember("run", command); wine.callMember("wait"); doneCallback.run(); }, errorCallback), errorCallback); } public void deletePrefix(WinePrefixContainerDTO winePrefix, Consumer<Exception> errorCallback) { try { fileUtilities.remove(new File(winePrefix.getPath())); } catch (IOException e) { LOGGER.error("Cannot delete Wine prefix (" + winePrefix.getPath() + ")! Exception: " + e.toString()); errorCallback.accept(e); } List<ShortcutCategoryDTO> categories = libraryManager.fetchShortcuts(); categories.stream().flatMap(shortcutCategoryDTO -> shortcutCategoryDTO.getShortcuts().stream()) .forEach(shortcutDTO -> { final InteractiveScriptSession interactiveScriptSession = scriptInterpreter .createInteractiveSession(); interactiveScriptSession.eval("include([\"Functions\", \"Shortcuts\", \"Reader\"]);", ignored -> interactiveScriptSession.eval("new ShortcutReader()", output -> { final ScriptObjectMirror shortcutReader = (ScriptObjectMirror) output; shortcutReader.callMember("of", shortcutDTO); final String container = (String) shortcutReader.callMember("container"); if (container.equals(winePrefix.getName())) { shortcutManager.deleteShortcut(shortcutDTO); } }, errorCallback), errorCallback); }); } public void openTerminalInPrefix(WinePrefixContainerDTO winePrefixContainerDTO) { final Map<String, String> environment = new HashMap<>(); environment.put("WINEPREFIX", winePrefixContainerDTO.getPath()); environment.put("PATH", fetchWineVersionPath(winePrefixContainerDTO) + "/bin/" + ":$PATH"); terminalOpener.openTerminal(winePrefixContainerDTO.getPath(), environment); } private String fetchWineVersionPath(WinePrefixContainerDTO winePrefixContainerDTO) { return wineEnginesPath + "/" + winePrefixContainerDTO.getDistribution() + "-" + operatingSystemFetcher.fetchCurrentOperationSystem().getWinePackage() + "-" + winePrefixContainerDTO.getArchitecture() + "/" + winePrefixContainerDTO.getVersion(); } }