org.codice.ddf.spatial.geocoding.index.IndexInitializer.java Source code

Java tutorial

Introduction

Here is the source code for org.codice.ddf.spatial.geocoding.index.IndexInitializer.java

Source

/**
 * Copyright (c) Codice Foundation
 *
 * <p>This is free software: you can redistribute it and/or modify it under the terms of the GNU
 * Lesser General Public License as published by the Free Software Foundation, either version 3 of
 * the License, or any later version.
 *
 * <p>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 Lesser General Public License for more details. A copy of the GNU Lesser General Public
 * License is distributed along with this program and can be found at
 * <http://www.gnu.org/licenses/lgpl.html>.
 */
package org.codice.ddf.spatial.geocoding.index;

import ddf.security.service.SecurityServiceException;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.nio.file.Paths;
import java.util.concurrent.ExecutorService;
import org.apache.commons.io.FileUtils;
import org.codice.ddf.security.common.Security;
import org.codice.ddf.spatial.geocoding.GeoEntryExtractionException;
import org.codice.ddf.spatial.geocoding.GeoEntryExtractor;
import org.codice.ddf.spatial.geocoding.GeoEntryIndexer;
import org.codice.ddf.spatial.geocoding.GeoEntryIndexingException;
import org.codice.ddf.spatial.geocoding.GeoNamesRemoteDownloadException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class IndexInitializer {

    private static final Logger LOGGER = LoggerFactory.getLogger(IndexInitializer.class);

    private static final String PROCESSED = ".processed";

    private String defaultGeoNamesDataPath;

    private GeoEntryExtractor extractor;

    private GeoEntryIndexer indexer;

    private ExecutorService executor;

    private final Security security;

    public IndexInitializer() {
        security = Security.getInstance();
    }

    public void init() {
        File defaultGeoNamesDataFile = Paths.get(defaultGeoNamesDataPath).toFile();
        if (!defaultGeoNamesDataFile.exists()) {
            LOGGER.warn(
                    "Could not locate default GeoNames data file at {}. Check that your distribution is not corrupted.",
                    defaultGeoNamesDataPath);
            return;
        }
        submitUpdateIndexToExecutorService(defaultGeoNamesDataFile);
        executor.shutdown();
    }

    private void submitUpdateIndexToExecutorService(File defaultGeoNamesDataFile) {
        executor.submit(() -> {
            LOGGER.info("Indexing default GeoNames data at {}.", defaultGeoNamesDataPath);
            security.runAsAdmin(() -> {
                try {
                    security.runWithSubjectOrElevate(() -> updateIndex(defaultGeoNamesDataFile));
                } catch (SecurityServiceException | InvocationTargetException e) {
                    LOGGER.debug("Unable to update Gazetteer index.", e);
                }
                return null;
            });
        });
    }

    private Object updateIndex(File defaultGeoNamesDataFile) {
        final String defaultGeonamesDataPath = defaultGeoNamesDataFile.getAbsolutePath();

        if (resourceProcessed(defaultGeonamesDataPath)) {
            LOGGER.trace("{} has already been processed", defaultGeonamesDataPath);
        } else {
            try {
                indexer.updateIndex(defaultGeoNamesDataFile.getAbsolutePath(), extractor, true, progress -> {
                    if (progress >= 100) {
                        LOGGER.info("Default GeoNames data indexed successfully");
                    }
                });
                fileProcessingComplete(defaultGeonamesDataPath);
            } catch (GeoEntryIndexingException | GeoEntryExtractionException | GeoNamesRemoteDownloadException e) {
                LOGGER.debug("Could not update index.", e);
            }
        }

        return null;
    }

    public void destroy() {
        executor.shutdownNow();
    }

    public void setDefaultGeoNamesDataPath(String defaultGeonamesDataPath) {
        this.defaultGeoNamesDataPath = defaultGeonamesDataPath;
    }

    public void setExtractor(GeoEntryExtractor extractor) {
        this.extractor = extractor;
    }

    public void setIndexer(GeoEntryIndexer indexer) {
        this.indexer = indexer;
    }

    public void setExecutor(ExecutorService executor) {
        this.executor = executor;
    }

    private static boolean resourceProcessed(String resource) {
        String processedIndicator = resource + PROCESSED;
        File processedFile = new File(processedIndicator);
        return processedFile.exists();
    }

    private static void fileProcessingComplete(String resource) {
        String processedIndicator = resource + PROCESSED;
        File processedFile = new File(processedIndicator);
        try {
            FileUtils.touch(processedFile);
        } catch (IOException e) {
            LOGGER.debug("Unable to create {} to indicate {} processed", processedIndicator, resource, e);
        }
    }
}