001/*
002 * (C) Copyright 2010-2015 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Nuxeo - initial API and implementation
018 */
019package org.nuxeo.connect.client.vindoz;
020
021import java.io.File;
022import java.io.IOException;
023import java.util.ArrayList;
024import java.util.List;
025
026import org.apache.commons.lang3.SystemUtils;
027import org.apache.commons.logging.Log;
028import org.apache.commons.logging.LogFactory;
029
030import org.nuxeo.common.Environment;
031import org.nuxeo.common.utils.FileUtils;
032import org.nuxeo.connect.update.Package;
033import org.nuxeo.connect.update.PackageType;
034import org.nuxeo.runtime.api.Framework;
035
036/**
037 * Helper class used to manage packages installation issue under windows systems.
038 * <p>
039 * Because the Windows OS locks all the jar files loaded by the JVM, we can not do proper installation. So installation
040 * is delayed until next restart where installation is done before Nuxeo starts (and loads the jars).
041 *
042 * @author Tiry (tdelprat@nuxeo.com)
043 */
044public class InstallAfterRestart {
045
046    public static final String FILE_NAME = "installAfterRestart.log";
047
048    public static final String FAKE_VIDOZ = "org.nuxeo.fake.vindoz";
049
050    protected static final List<String> pkgNameOrIds = new ArrayList<>();
051
052    protected static final List<String> uninstallpkgNameOrIds = new ArrayList<>();
053
054    protected static final Log log = LogFactory.getLog(InstallAfterRestart.class);
055
056    protected static boolean isNeededByOs() {
057        return Framework.isBooleanPropertyTrue(FAKE_VIDOZ) || SystemUtils.IS_OS_WINDOWS;
058    }
059
060    /**
061     * Returns true if a restart should be triggered after install
062     */
063    public static boolean isNeededForPackage(Package pkg) {
064        if (!Framework.isDevModeSet()) {
065            return true;
066        }
067        boolean isNotStudioOrWindows = PackageType.STUDIO != pkg.getType() && isNeededByOs();
068        boolean isHotFix = PackageType.HOT_FIX == pkg.getType();
069        boolean isAddonAndNoHotReload = PackageType.ADDON == pkg.getType() && !pkg.supportsHotReload();
070        return isNotStudioOrWindows || isHotFix || isAddonAndNoHotReload;
071    }
072
073    protected static boolean isDevMode() {
074        return Framework.isDevModeSet();
075    }
076
077    /**
078     * @deprecated Since 7.4. Use {@link SystemUtils#IS_OS_WINDOWS}
079     */
080    @Deprecated
081    protected static boolean isVindozBox() {
082        return SystemUtils.IS_OS_WINDOWS;
083    }
084
085    public static void addPackageForInstallation(String pkgNameOrId) {
086        if (!pkgNameOrIds.contains(pkgNameOrId)) {
087            pkgNameOrIds.add(pkgNameOrId);
088            savePkgList();
089        }
090    }
091
092    public static void addPackageForUnInstallation(String pkgNameOrId) {
093        if (!pkgNameOrIds.contains(pkgNameOrId) && !(uninstallpkgNameOrIds.contains(pkgNameOrId))) {
094            pkgNameOrIds.add(pkgNameOrId);
095            uninstallpkgNameOrIds.add(pkgNameOrId);
096            savePkgList();
097        }
098    }
099
100    public static boolean isMarkedForInstallAfterRestart(String pkgNameOrId) {
101        return pkgNameOrIds.contains(pkgNameOrId);
102    }
103
104    protected static void savePkgList() {
105        String path = Framework.getProperty(Environment.NUXEO_DATA_DIR);
106        File installFile = new File(path, FILE_NAME);
107        List<String> cmds = new ArrayList<>();
108        for (String pkgNameOrId : pkgNameOrIds) {
109            String cmd = pkgNameOrId;
110            if (uninstallpkgNameOrIds.contains(pkgNameOrId)) {
111                cmd = "uninstall " + pkgNameOrId;
112            }
113            cmds.add(cmd);
114        }
115
116        try {
117            FileUtils.writeLines(installFile, cmds);
118        } catch (IOException e) {
119            log.error("Unable to same listing of packages to install on restart", e);
120        }
121    }
122
123    /**
124     * @since 5.6
125     */
126    public static boolean isMarkedForUninstallAfterRestart(String pkgName) {
127        return uninstallpkgNameOrIds.contains(pkgName);
128    }
129
130}