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.io.FileUtils;
027import org.apache.commons.lang3.SystemUtils;
028import org.apache.commons.logging.Log;
029import org.apache.commons.logging.LogFactory;
030import org.nuxeo.common.Environment;
031import org.nuxeo.connect.update.Package;
032import org.nuxeo.connect.update.PackageType;
033import org.nuxeo.runtime.api.Framework;
034
035/**
036 * Helper class used to manage packages installation issue under windows systems.
037 * <p>
038 * Because the Windows OS locks all the jar files loaded by the JVM, we can not do proper installation. So installation
039 * is delayed until next restart where installation is done before Nuxeo starts (and loads the jars).
040 *
041 * @author Tiry (tdelprat@nuxeo.com)
042 */
043public class InstallAfterRestart {
044
045    public static final String FILE_NAME = "installAfterRestart.log";
046
047    public static final String FAKE_VIDOZ = "org.nuxeo.fake.vindoz";
048
049    protected static final List<String> pkgNameOrIds = new ArrayList<>();
050
051    protected static final List<String> uninstallpkgNameOrIds = new ArrayList<>();
052
053    protected static final Log log = LogFactory.getLog(InstallAfterRestart.class);
054
055    protected static boolean isNeededByOs() {
056        return Framework.isBooleanPropertyTrue(FAKE_VIDOZ) || SystemUtils.IS_OS_WINDOWS;
057    }
058
059    /**
060     * Returns true if a restart should be triggered after install
061     */
062    public static boolean isNeededForPackage(Package pkg) {
063        if (!Framework.isDevModeSet()) {
064            return true;
065        }
066        boolean isNotStudioOrWindows = PackageType.STUDIO != pkg.getType() && isNeededByOs();
067        boolean isHotFix = PackageType.HOT_FIX == pkg.getType();
068        boolean isAddonAndNoHotReload = PackageType.ADDON == pkg.getType() && !pkg.supportsHotReload();
069        return isNotStudioOrWindows || isHotFix || isAddonAndNoHotReload;
070    }
071
072    protected static boolean isDevMode() {
073        return Framework.isDevModeSet();
074    }
075
076    /**
077     * @deprecated Since 7.4. Use {@link SystemUtils#IS_OS_WINDOWS}
078     */
079    @Deprecated
080    protected static boolean isVindozBox() {
081        return SystemUtils.IS_OS_WINDOWS;
082    }
083
084    public static void addPackageForInstallation(String pkgNameOrId) {
085        if (!pkgNameOrIds.contains(pkgNameOrId)) {
086            pkgNameOrIds.add(pkgNameOrId);
087            savePkgList();
088        }
089    }
090
091    public static void addPackageForUnInstallation(String pkgNameOrId) {
092        if (!pkgNameOrIds.contains(pkgNameOrId) && !(uninstallpkgNameOrIds.contains(pkgNameOrId))) {
093            pkgNameOrIds.add(pkgNameOrId);
094            uninstallpkgNameOrIds.add(pkgNameOrId);
095            savePkgList();
096        }
097    }
098
099    public static boolean isMarkedForInstallAfterRestart(String pkgNameOrId) {
100        return pkgNameOrIds.contains(pkgNameOrId);
101    }
102
103    protected static void savePkgList() {
104        String path = Framework.getProperty(Environment.NUXEO_DATA_DIR);
105        File installFile = new File(path, FILE_NAME);
106        List<String> cmds = new ArrayList<>();
107        for (String pkgNameOrId : pkgNameOrIds) {
108            String cmd = pkgNameOrId;
109            if (uninstallpkgNameOrIds.contains(pkgNameOrId)) {
110                cmd = "uninstall " + pkgNameOrId;
111            }
112            cmds.add(cmd);
113        }
114
115        try {
116            FileUtils.writeLines(installFile, cmds);
117        } catch (IOException e) {
118            log.error("Unable to same listing of packages to install on restart", e);
119        }
120    }
121
122    /**
123     * @since 5.6
124     */
125    public static boolean isMarkedForUninstallAfterRestart(String pkgName) {
126        return uninstallpkgNameOrIds.contains(pkgName);
127    }
128
129}