org.esa.cci.sst.tools.BasicTool.java Source code

Java tutorial

Introduction

Here is the source code for org.esa.cci.sst.tools.BasicTool.java

Source

/*
 * Copyright (C) 2011 Brockmann Consult GmbH (info@brockmann-consult.de)
 *
 * 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 3 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, see http://www.gnu.org/licenses/
 */

package org.esa.cci.sst.tools;

import org.apache.commons.cli.*;
import org.esa.beam.framework.gpf.GPF;
import org.esa.cci.sst.log.SstLogging;
import org.esa.cci.sst.orm.PersistenceManager;
import org.esa.cci.sst.orm.Storage;
import org.esa.cci.sst.tool.Configuration;
import org.esa.cci.sst.tool.ToolException;
import org.esa.cci.sst.util.TimeUtil;

import javax.media.jai.JAI;
import javax.persistence.Query;
import java.io.*;
import java.text.MessageFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Properties;
import java.util.TimeZone;
import java.util.logging.Formatter;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;

/**
 * The base class for all MMS command line tools.
 *
 * @author Martin Boettcher
 * @author Norman Fomferra
 * @author Ralf Quast
 */
public abstract class BasicTool {

    private Storage toolStorage;

    public static final String CONFIG_FILE_OPTION_NAME = "c";
    public static final String DEFAULT_CONFIGURATION_FILE_NAME = "mms-config.properties";

    private final String name;
    private final String version;
    private final Configuration config;
    private final Options options;

    protected final Logger logger;
    private ErrorHandler errorHandler;

    private boolean initialised;
    private PersistenceManager persistenceManager;

    static {
        TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
        Locale.setDefault(Locale.ENGLISH);

        System.setProperty("EPSG-HSQL.directory", System.getProperty("user.home", ".") + File.separator + "tmp");
        System.setProperty("beam.imageManager.enableSourceTileCaching", "true");

        JAI.enableDefaultTileCache();
        JAI.getDefaultInstance().getTileCache().setMemoryCapacity(1024 * 1024 * 1024);

        GPF.getDefaultInstance().getOperatorSpiRegistry().loadOperatorSpis();

    }

    protected BasicTool(String name, String version) {
        this.name = name;
        this.version = version;

        options = createCommandLineOptions();

        config = new Configuration();
        config.add(System.getProperties(), "mms.");

        logger = SstLogging.getLogger();
    }

    public final String getName() {
        return name;
    }

    public final ErrorHandler getErrorHandler() {
        if (errorHandler == null) {
            synchronized (this) {
                if (errorHandler == null) {
                    errorHandler = new ErrorHandler() {
                        @Override
                        public void terminate(ToolException e) {
                            final Logger localLogger = SstLogging.getLogger();
                            localLogger.log(Level.SEVERE, e.getMessage(), e);
                            if (e.getCause() != null) {
                                if (localLogger.isLoggable(Level.FINEST)) {
                                    for (final StackTraceElement element : e.getCause().getStackTrace()) {
                                        localLogger.log(Level.FINEST, element.toString());
                                    }
                                }
                                e.getCause().printStackTrace(System.err);
                            }
                            System.exit(e.getExitCode());
                        }

                        @Override
                        public void warn(Throwable t, String message) {
                            final Logger localLogger = SstLogging.getLogger();
                            localLogger.log(Level.WARNING, message, t);
                            if (localLogger.isLoggable(Level.FINEST)) {
                                for (final StackTraceElement element : t.getStackTrace()) {
                                    localLogger.log(Level.FINEST, element.toString());
                                }
                            }
                        }
                    };
                }
            }
        }
        return errorHandler;
    }

    public Configuration getConfig() {
        return config;
    }

    private void setDebug(boolean debug) {
        if (debug) {
            SstLogging.setLevelDebug();
        }
    }

    private void setSilent(boolean silent) {
        if (silent) {
            SstLogging.setLevelSilent();
        }
    }

    private Options getOptions() {
        return options;
    }

    public final PersistenceManager getPersistenceManager() {
        return persistenceManager;
    }

    public final boolean setCommandLineArgs(String[] args) {
        final CommandLineParser parser = new PosixParser();
        try {
            final CommandLine commandLine = parser.parse(getOptions(), args);
            setSilent(commandLine.hasOption("silent"));
            setDebug(commandLine.hasOption("debug"));
            if (commandLine.hasOption("version")) {
                printVersion();
                return false;
            }
            if (commandLine.hasOption("help")) {
                printHelp();
                return false;
            }
            final String configurationFilePath = commandLine.getOptionValue(CONFIG_FILE_OPTION_NAME);
            if (configurationFilePath != null) {
                final File configurationFile = new File(configurationFilePath);
                addConfigurationProperties(configurationFile);
                config.put(Configuration.KEY_MMS_CONFIGURATION, configurationFile.getPath());
            }
            final Properties optionProperties = commandLine.getOptionProperties("D");
            config.add(optionProperties);

            final Properties privateProperties = new Properties();
            privateProperties.load(BasicTool.class.getResourceAsStream("PRIVATE.properties"));
            config.add(privateProperties);
        } catch (ParseException e) {
            throw new ToolException(e.getMessage(), e, ToolException.COMMAND_LINE_ARGUMENTS_PARSE_ERROR);
        } catch (IOException e) {
            throw new ToolException(e.getMessage(), e, ToolException.TOOL_ERROR);
        }

        return true;
    }

    public Storage getStorage() {
        return toolStorage;
    }

    public void initialize() {
        if (initialised) {
            return;
        }
        SstLogging.getLogger().info("connecting to database " + config.getStringValue("openjpa.ConnectionURL"));
        try {
            persistenceManager = PersistenceManager.create(Constants.PERSISTENCE_UNIT_NAME,
                    Constants.PERSISTENCE_RETRY_COUNT, config.getAsProperties());
        } catch (Exception e) {
            throw new ToolException("Unable to establish database connection.", e, ToolException.TOOL_DB_ERROR);
        }
        if (config.getBooleanValue("mms.db.useindex", false)) {
            try {
                persistenceManager.transaction();
                final Query setSeqScanOff = persistenceManager.createNativeQuery("set enable_seqscan to off");
                setSeqScanOff.executeUpdate();
                persistenceManager.commit();
            } catch (Exception e) {
                SstLogging.getLogger().warning("failed setting seqscan to off: " + e.getMessage());
            }
        }
        toolStorage = persistenceManager.getStorage();

        initialised = true;
    }

    protected String getCommandLineSyntax() {
        return getName();
    }

    protected void printHelp() {
        new HelpFormatter().printHelp(getCommandLineSyntax(), "Valid options are", getOptions(), "", true);
    }

    private void addConfigurationProperties(File configurationFile) {
        FileReader reader = null;
        try {
            reader = new FileReader(configurationFile);
            config.load(reader);
        } catch (FileNotFoundException e) {
            throw new ToolException(MessageFormat.format("File not found: {0}", configurationFile), e,
                    ToolException.CONFIGURATION_FILE_NOT_FOUND_ERROR);
        } catch (IOException e) {
            throw new ToolException(MessageFormat.format("Failed to read from {0}.", configurationFile), e,
                    ToolException.CONFIGURATION_FILE_IO_ERROR);
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    // ignore
                }
            }
        }
    }

    private void printVersion() {
        System.out.println(MessageFormat.format("Version {0}", version));
    }

    private static Options createCommandLineOptions() {
        final Option helpOpt = new Option("help", "print this message");
        final Option versionOpt = new Option("version", "print the version information and exit");
        final Option verboseOpt = new Option("verbose", "be extra verbose");
        final Option debugOpt = new Option("debug", "print debugging information");

        final Option confFileOpt = new Option(CONFIG_FILE_OPTION_NAME, "alternative configuration file");
        confFileOpt.setArgs(1);
        confFileOpt.setArgName("file");
        confFileOpt.setType(File.class);

        final Option propertyOpt = new Option("D", "use value for given property");
        propertyOpt.setValueSeparator('=');
        propertyOpt.setArgName("property=value");
        propertyOpt.setArgs(2);

        Options options = new Options();
        options.addOption(helpOpt);
        options.addOption(versionOpt);
        options.addOption(verboseOpt);
        options.addOption(debugOpt);
        options.addOption(confFileOpt);
        options.addOption(propertyOpt);

        return options;
    }
}