org.orbisgis.framework.Main.java Source code

Java tutorial

Introduction

Here is the source code for org.orbisgis.framework.Main.java

Source

/**
 * OrbisGIS is a java GIS application dedicated to research in GIScience.
 * OrbisGIS is developed by the GIS group of the DECIDE team of the 
 * Lab-STICC CNRS laboratory, see <http://www.lab-sticc.fr/>.
 *
 * The GIS group of the DECIDE team is located at :
 *
 * Laboratoire Lab-STICC  CNRS UMR 6285
 * Equipe DECIDE
 * UNIVERSIT DE BRETAGNE-SUD
 * Institut Universitaire de Technologie de Vannes
 * 8, Rue Montaigne - BP 561 56017 Vannes Cedex
 * 
 * OrbisGIS is distributed under GPL 3 license.
 *
 * Copyright (C) 2007-2014 CNRS (IRSTV FR CNRS 2488)
 * Copyright (C) 2015-2016 CNRS (Lab-STICC UMR CNRS 6285)
 *
 * This file is part of OrbisGIS.
 *
 * OrbisGIS 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 3 of the License, or (at your option) any later
 * version.
 *
 * OrbisGIS 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
 * OrbisGIS. If not, see <http://www.gnu.org/licenses/>.
 *
 * For more information, please consult: <http://www.orbisgis.org/>
 * or contact directly:
 * info_at_ orbisgis.org
 */
package org.orbisgis.framework;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.channels.OverlappingFileLockException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Stack;
import javax.swing.JOptionPane;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.felix.framework.Logger;
import org.apache.felix.main.AutoProcessor;
import org.osgi.framework.Constants;
import org.osgi.framework.FrameworkEvent;
import org.osgi.framework.Version;
import org.osgi.framework.launch.Framework;
import org.xnap.commons.i18n.I18n;
import org.xnap.commons.i18n.I18nFactory;

/**
 * Entry point of User Interface.
 */
final class Main {
    private static final I18n I18N = I18nFactory.getI18n(Main.class);
    private static boolean debugMode = false;
    /** if true Remove configurations file and cache */
    private static boolean noFailMode = false;
    private static final int BUNDLE_STABILITY_TIMEOUT = 3000;
    private static final int SAFE_MODE_COUNTDOWN_DELETE = 5000;
    private static final Logger LOGGER = new Logger();
    private static Version version;
    private static final String OBR_REPOSITORY_URL = "obr.repository.url";
    private static final String OBR_REPOSITORY_SNAPSHOT_URL = "obr.repository.snapshot.url";

    //Minimum supported java version
    public static final char MIN_JAVA_VERSION = '7';

    protected static Framework m_fwk = null;

    /**
     * Utility class
     */
    private Main() {

    }

    private static void parseCommandLine(String[] args) {
        //Read parameters
        Stack<String> sargs = new Stack<String>();
        for (String arg : args) {
            sargs.insertElementAt(arg, 0);
        }
        while (!sargs.empty()) {
            String argument = sargs.pop();
            if (argument.contentEquals("--debug")) {
                debugMode = true;
            } else if (argument.contentEquals("--nofailmode")) {
                noFailMode = true;
            }
        }
    }

    /**
     * Entry point of User Interface
     */
    public static void main(String[] args) {
        // Deactivate JOOQ Ascii Art printing
        Properties properties = System.getProperties();
        properties.setProperty("org.jooq.no-logo", "True");
        // debug try { Thread.sleep(5000); } catch (Exception ex) {}
        long deploymentTime = 0;
        BundleTools bundleTools = new BundleTools(LOGGER);
        parseCommandLine(args);
        //Check if the java version is greater than 1.6+
        if (!isVersion(MIN_JAVA_VERSION)) {
            JOptionPane.showMessageDialog(null, I18N.tr("OrbisGIS needs at least a java 1.7+"));
        } else {
            // Fetch application version
            version = new Version(1, 0, 0);
            try (InputStream fs = Main.class.getResourceAsStream("version.txt")) {
                String versionTxt = IOUtils.readLines(fs).get(0);
                version = new Version(versionTxt.replace("-", "."));
            } catch (IOException ex) {
                LOGGER.log(Logger.LOG_ERROR, ex.getLocalizedMessage(), ex);
            }
            // Create CoreWorkspace instance
            CoreWorkspaceImpl coreWorkspace = new CoreWorkspaceImpl(version.getMajor(), version.getMinor(),
                    version.getMicro(), version.getQualifier(), LOGGER);
            // Create Lock file if not exists
            File lockFile = new File(coreWorkspace.getApplicationFolder(), "instance.lock");
            if (!lockFile.exists()) {
                try {
                    new File(coreWorkspace.getApplicationFolder()).mkdirs();
                    if (!lockFile.createNewFile()) {
                        LOGGER.log(Logger.LOG_ERROR, "Cannot create lock file !\n" + lockFile.getAbsolutePath());
                        return;
                    }
                } catch (IOException ex) {
                    LOGGER.log(Logger.LOG_ERROR,
                            "Application cache folder is not accessible !\n" + lockFile.getAbsolutePath(), ex);
                    return;
                }
            }
            try (FileOutputStream fileOutputStream = new FileOutputStream(lockFile);
                    FileLock lock = fileOutputStream.getChannel().tryLock()) {
                if (lock == null) {
                    LOGGER.log(Logger.LOG_ERROR,
                            "Only a single instance of OrbisGIS can be run, please close other instance");
                    return;
                }
                // Fetch cache folder
                File felixBundleCache = new File(coreWorkspace.getPluginCache());
                // If safe mode delete cache
                if (noFailMode && felixBundleCache.isDirectory()) {
                    System.err.println(
                            "Safe mode engaged, clear the following folder in 5 seconds..\n" + felixBundleCache);
                    try {
                        Thread.sleep(SAFE_MODE_COUNTDOWN_DELETE);
                        FileUtils.deleteDirectory(felixBundleCache);
                    } catch (InterruptedException ex) {
                        return;
                    } catch (IOException ex) {
                        LOGGER.log(Logger.LOG_ERROR, ex.getLocalizedMessage(), ex);
                    }
                }
                // Delete snapshot fragments bundles
                long beginDeleteFragments = System.currentTimeMillis();
                bundleTools.deleteFragmentInCache(felixBundleCache);
                deploymentTime += System.currentTimeMillis() - beginDeleteFragments;
                LOGGER.log(Logger.LOG_INFO,
                        I18N.tr("Waiting for bundle stability, deployment of built-in bundles done in" + " {0} s",
                                deploymentTime / 1000.0));
                // Start main of felix framework
                try {
                    String[] felixArgs = new String[] { "-b", BundleTools.BUNDLE_DIRECTORY,
                            felixBundleCache.getAbsolutePath() };
                    LOGGER.log(Logger.LOG_INFO, "Start Apache Felix:\n" + Arrays.toString(felixArgs));
                    startFelix(BundleTools.BUNDLE_DIRECTORY, felixBundleCache.getAbsolutePath());
                } catch (Exception ex) {
                    LOGGER.log(Logger.LOG_ERROR, ex.getLocalizedMessage(), ex);
                }
            } catch (OverlappingFileLockException ex) {
                LOGGER.log(Logger.LOG_ERROR,
                        "Only a single instance of OrbisGIS can be run, please close other instance");
            } catch (IOException ex) {
                LOGGER.log(Logger.LOG_ERROR,
                        "Application cache folder is not accessible !\n" + lockFile.getAbsolutePath(), ex);
            }
        }
    }

    public static void startFelix(String bundleDir, String cacheDir) {
        // Load system properties.
        org.apache.felix.main.Main.loadSystemProperties();

        // Read configuration properties.
        Map<String, String> configProps = org.apache.felix.main.Main.loadConfigProperties();
        // If no configuration properties were found, then create
        // an empty properties object.
        if (configProps == null) {
            System.err.println("No " + org.apache.felix.main.Main.CONFIG_PROPERTIES_FILE_VALUE + " found.");
            configProps = new HashMap<>();
        }

        //If OrbisGIS is in a SNAPSHOT version, uses the release and snapshot orb.
        //Else only uses the release one.
        if (configProps.containsKey(OBR_REPOSITORY_URL) && configProps.containsKey(OBR_REPOSITORY_SNAPSHOT_URL)) {
            if (version.getQualifier().equals("SNAPSHOT")) {
                configProps.remove(OBR_REPOSITORY_URL);
                configProps.put(OBR_REPOSITORY_URL, configProps.get(OBR_REPOSITORY_SNAPSHOT_URL));
            }
            configProps.remove(OBR_REPOSITORY_SNAPSHOT_URL);
        }

        // Copy framework properties from the system properties.
        org.apache.felix.main.Main.copySystemProperties(configProps);

        // If there is a passed in bundle auto-deploy directory, then
        // that overwrites anything in the config file.
        if (bundleDir != null) {
            configProps.put(AutoProcessor.AUTO_DEPLOY_DIR_PROPERY, bundleDir);
        }

        // If there is a passed in bundle cache directory, then
        // that overwrites anything in the config file.
        if (cacheDir != null) {
            configProps.put(Constants.FRAMEWORK_STORAGE, cacheDir);
        }

        // If enabled, register a shutdown hook to make sure the framework is
        // cleanly shutdown when the VM exits.
        String enableHook = configProps.get(org.apache.felix.main.Main.SHUTDOWN_HOOK_PROP);
        if ((enableHook == null) || !enableHook.equalsIgnoreCase("false")) {
            Runtime.getRuntime().addShutdownHook(new Thread("Felix Shutdown Hook") {
                public void run() {
                    try {
                        if (m_fwk != null) {
                            m_fwk.stop();
                            m_fwk.waitForStop(0);
                        }
                    } catch (Exception ex) {
                        System.err.println("Error stopping framework: " + ex);
                    }
                }
            });
        }

        try {
            // Create an instance of the framework.
            PluginHost pluginHost = new PluginHost(new File(configProps.get(Constants.FRAMEWORK_STORAGE)), LOGGER);
            pluginHost.init(configProps);
            m_fwk = pluginHost.getFramework();
            // Use the system bundle context to process the auto-deploy
            // and auto-install/auto-start properties.
            AutoProcessor.process(configProps, m_fwk.getBundleContext());
            FrameworkEvent event;
            do {
                // Start the framework.
                m_fwk.start();
                // Wait for framework to stop to exit the VM.
                event = m_fwk.waitForStop(0);
            }
            // If the framework was updated, then restart it.
            while (event.getType() == FrameworkEvent.STOPPED_UPDATE);
            // Otherwise, exit.
            System.exit(0);
        } catch (Exception ex) {
            LOGGER.log(Logger.LOG_ERROR, "Could not create framework: ", ex);
            ex.printStackTrace();
            System.exit(0);
        }
    }

    /**
     * Utility method to check if the java machine is supported.
     *
     * @param minJavaVersion
     * @return
     */
    private static boolean isVersion(char minJavaVersion) {
        String version = System.getProperty("java.version");
        char minor = version.charAt(2);
        if (minor >= minJavaVersion) {
            return true;
        }
        return false;
    }
}