001/*
002 * (C) Copyright 2010-2015 Nuxeo SA (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl-2.1.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Nuxeo - initial API and implementation
016 */
017package org.nuxeo.connect.client.vindoz;
018
019import java.io.File;
020import java.io.IOException;
021import java.util.ArrayList;
022import java.util.List;
023
024import org.apache.commons.lang3.SystemUtils;
025import org.apache.commons.logging.Log;
026import org.apache.commons.logging.LogFactory;
027
028import org.nuxeo.common.Environment;
029import org.nuxeo.common.utils.FileUtils;
030import org.nuxeo.connect.update.Package;
031import org.nuxeo.connect.update.PackageType;
032import org.nuxeo.runtime.api.Framework;
033
034/**
035 * Helper class used to manage packages installation issue under windows systems.
036 * <p>
037 * Because the Windows OS locks all the jar files loaded by the JVM, we can not do proper installation. So installation
038 * is delayed until next restart where installation is done before Nuxeo starts (and loads the jars).
039 *
040 * @author Tiry (tdelprat@nuxeo.com)
041 */
042public class InstallAfterRestart {
043
044    public static final String FILE_NAME = "installAfterRestart.log";
045
046    public static final String FAKE_VIDOZ = "org.nuxeo.fake.vindoz";
047
048    protected static final List<String> pkgNameOrIds = new ArrayList<>();
049
050    protected static final List<String> uninstallpkgNameOrIds = new ArrayList<>();
051
052    protected static final Log log = LogFactory.getLog(InstallAfterRestart.class);
053
054    protected static boolean isNeededByOs() {
055        return Framework.isBooleanPropertyTrue(FAKE_VIDOZ) || SystemUtils.IS_OS_WINDOWS;
056    }
057
058    /**
059     * Returns true if a restart should be triggered after install
060     */
061    public static boolean isNeededForPackage(Package pkg) {
062        if (!Framework.isDevModeSet()) {
063            return true;
064        }
065        boolean isNotStudioOrWindows = PackageType.STUDIO != pkg.getType() && isNeededByOs();
066        boolean isHotFix = PackageType.HOT_FIX == pkg.getType();
067        boolean isAddonAndNoHotReload = PackageType.ADDON == pkg.getType() && !pkg.supportsHotReload();
068        return isNotStudioOrWindows || isHotFix || isAddonAndNoHotReload;
069    }
070
071    protected static boolean isDevMode() {
072        return Framework.isDevModeSet();
073    }
074
075    /**
076     * @deprecated Since 7.4. Use {@link SystemUtils#IS_OS_WINDOWS}
077     */
078    @Deprecated
079    protected static boolean isVindozBox() {
080        return SystemUtils.IS_OS_WINDOWS;
081    }
082
083    public static void addPackageForInstallation(String pkgNameOrId) {
084        if (!pkgNameOrIds.contains(pkgNameOrId)) {
085            pkgNameOrIds.add(pkgNameOrId);
086            savePkgList();
087        }
088    }
089
090    public static void addPackageForUnInstallation(String pkgNameOrId) {
091        if (!pkgNameOrIds.contains(pkgNameOrId) && !(uninstallpkgNameOrIds.contains(pkgNameOrId))) {
092            pkgNameOrIds.add(pkgNameOrId);
093            uninstallpkgNameOrIds.add(pkgNameOrId);
094            savePkgList();
095        }
096    }
097
098    public static boolean isMarkedForInstallAfterRestart(String pkgNameOrId) {
099        return pkgNameOrIds.contains(pkgNameOrId);
100    }
101
102    protected static void savePkgList() {
103        String path = Framework.getProperty(Environment.NUXEO_DATA_DIR);
104        File installFile = new File(path, FILE_NAME);
105        List<String> cmds = new ArrayList<>();
106        for (String pkgNameOrId : pkgNameOrIds) {
107            String cmd = pkgNameOrId;
108            if (uninstallpkgNameOrIds.contains(pkgNameOrId)) {
109                cmd = "uninstall " + pkgNameOrId;
110            }
111            cmds.add(cmd);
112        }
113
114        try {
115            FileUtils.writeLines(installFile, cmds);
116        } catch (IOException e) {
117            log.error("Unable to same listing of packages to install on restart", e);
118        }
119    }
120
121    /**
122     * @since 5.6
123     */
124    public static boolean isMarkedForUninstallAfterRestart(String pkgName) {
125        return uninstallpkgNameOrIds.contains(pkgName);
126    }
127
128}