org.codice.solr.factory.impl.EmbeddedSolrFiles.java Source code

Java tutorial

Introduction

Here is the source code for org.codice.solr.factory.impl.EmbeddedSolrFiles.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.solr.factory.impl;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.io.Closeables;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Objects;
import javax.annotation.Nullable;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.Validate;
import org.apache.solr.core.SolrConfig;
import org.apache.solr.schema.IndexSchema;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 * @deprecated Removing support for embedded and standalone Solr in the future.
 *     <p>Maintain embedded Solr configuration and schema files.
 *     <p><i>Note:</i> The corresponding {@link SolrConfig} and {@link IndexSchema} will be
 *     constructed the first time they are retrieved.
 */
@Deprecated
class EmbeddedSolrFiles {
    private static final Logger LOGGER = LoggerFactory.getLogger(EmbeddedSolrFiles.class);

    private final String coreName;
    private final String configName;
    private final File configFile;
    private final String schemaName;
    private final File schemaFile;
    private final ConfigurationFileProxy configProxy;
    private volatile SolrConfig solrConfig = null;
    private volatile IndexSchema schemaIndex = null;
    private volatile String dataDirPath = null;

    @VisibleForTesting // required by Spock to spy on an existing object
    EmbeddedSolrFiles() {
        this.coreName = null;
        this.configName = null;
        this.configFile = null;
        this.schemaName = null;
        this.schemaFile = null;
        this.configProxy = null;
    }

    /**
     * Constructor.
     *
     * @param coreName name of the Solr core
     * @param configXml name of the Solr configuration file
     * @param schemaXmls file names of the Solr core schemas to attempt to load (will start with the
     *     first and fallback to the others in order if unavailable)
     * @param configProxy {@link ConfigurationFileProxy} instance to use
     * @throws IllegalArgumentException if <code>coreName</code>, <code>configXml</code>, <code>
     *     schemaXmls</code>, or <code>configProxy</code> is <code>null</code> or if unable to find
     *     any files
     */
    public EmbeddedSolrFiles(String coreName, String configXml, String[] schemaXmls,
            ConfigurationFileProxy configProxy) {
        Validate.notNull(coreName, "invalid null Solr core name");
        Validate.notNull(configXml, "invalid null Solr config file");
        Validate.notNull(schemaXmls, "invalid null Solr schema files");
        Validate.notEmpty(schemaXmls, "missing Solr schema files");
        Validate.noNullElements(schemaXmls, "invalid null Solr schema file");
        Validate.notNull(configProxy, "invalid null Solr config proxy");
        this.coreName = coreName;
        this.configName = configXml;
        this.configProxy = configProxy;
        this.configFile = FileUtils.toFile(configProxy.getResource(configXml, coreName));
        Validate.notNull(configFile, "Unable to find Solr configuration file: " + configXml);
        File solrSchemaFile = null;
        String schemaXml = null;

        for (final String s : schemaXmls) {
            schemaXml = s;
            solrSchemaFile = FileUtils.toFile(configProxy.getResource(schemaXml, coreName));
            if (solrSchemaFile != null) {
                break;
            }
        }
        Validate.notNull(solrSchemaFile, "Unable to find Solr schema file(s): " + Arrays.toString(schemaXmls));
        this.schemaFile = solrSchemaFile;
        this.schemaName = schemaXml;
    }

    /**
     * Gets the schema file.
     *
     * @return the corresponding schema file
     */
    public File getSchemaFile() {
        return schemaFile;
    }

    /**
     * Gets the configuration file.
     *
     * @return the corresponding config file
     */
    public File getConfigFile() {
        return configFile;
    }

    /**
     * Gets the home directory where the configuration resides.
     *
     * @return the home directory where the configuration resides
     */
    public File getConfigHome() {
        return configFile.getParentFile();
    }

    /**
     * Creates or retrieves the schema index corresponding to this set of Solr files.
     *
     * @return a corresponding index for the schema
     * @throws IllegalArgumentException if unable to load or parse the corresponding schema or config
     */
    public IndexSchema getSchemaIndex() {
        if (schemaIndex == null) {
            final SolrConfig cfg = getConfig(); // make sure it is initialized
            InputStream is = null;

            LOGGER.debug("Loading and creating index for {} schema using file [{} ({})]", coreName, schemaName,
                    schemaFile);
            try {
                is = FileUtils.openInputStream(schemaFile);
                this.schemaIndex = newIndexSchema(cfg, schemaName, new InputSource(is));
            } catch (IOException e) {
                LOGGER.debug("failed to open {} Solr schema file [{} ({})]", coreName, schemaName, schemaFile, e);
                throw new IllegalArgumentException("Unable to open Solr schema file: " + schemaName, e);
            } catch (RuntimeException e) { // thrown as is by IndexSchema()
                LOGGER.debug("failed to parse {} Solr schema file [{} ({})]", coreName, schemaName, schemaFile, e);
                throw new IllegalArgumentException("Unable to parse Solr schema file: " + schemaName, e);
            } finally {
                Closeables.closeQuietly(is);
            }
        }
        return schemaIndex;
    }

    /**
     * Creates or retrieves the Solr config for this set of Solr files.
     *
     * @return a corresponding Solr config
     * @throws IllegalArgumentException if unable to load or parse the corresponding config
     */
    public SolrConfig getConfig() {
        if (solrConfig == null) {
            InputStream is = null;

            LOGGER.debug("Loading and creating Solr config for {} using file [{} ({})]", coreName, configName,
                    configFile);
            try {
                is = FileUtils.openInputStream(configFile);
            } catch (IOException e) {
                LOGGER.debug("failed to open {} Solr config file [{} ({})]", coreName, configName, configFile, e);
                throw new IllegalArgumentException("Unable to open Solr configuration file: " + configName, e);
            }
            try {
                this.solrConfig = newConfig(getConfigHome().getParentFile().toPath(), configName,
                        new InputSource(is));
            } catch (ParserConfigurationException | IOException | SAXException e) {

                LOGGER.debug("failed to parse {} Solr config file [{} ({})]", coreName, configName, configFile, e);
                throw new IllegalArgumentException("Unable to parse Solr configuration file: " + configName, e);
            } finally {
                Closeables.closeQuietly(is);
            }
        }
        return solrConfig;
    }

    /**
     * Retrieves the path to the data directory used for the Solr embedded files.
     *
     * @return the corresponding path to the data directory if any
     */
    @Nullable
    public String getDataDirPath() {
        if (dataDirPath == null) {
            final File dataDir = configProxy.getDataDirectory();

            if (dataDir != null) {
                dataDirPath = Paths.get(dataDir.getAbsolutePath(), coreName, "data").toString();
                LOGGER.debug("Solr({}): Using data directory [{}]", coreName, dataDirPath);
            }
        }
        return dataDirPath;
    }

    @Override
    public int hashCode() {
        return Objects.hash(coreName, configFile, schemaFile);
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == this) {
            return true;
        } else if (obj instanceof EmbeddedSolrFiles) {
            final EmbeddedSolrFiles f = (EmbeddedSolrFiles) obj;

            return coreName.equals(f.coreName) && configFile.equals(f.configFile)
                    && schemaFile.equals(f.schemaFile);
        }
        return false;
    }

    @Override
    public String toString() {
        return coreName + ',' + configName + ',' + schemaName;
    }

    @VisibleForTesting
    IndexSchema newIndexSchema(SolrConfig cfg, String name, InputSource source) {
        return new IndexSchema(cfg, name, source);
    }

    @VisibleForTesting
    SolrConfig newConfig(Path instanceDir, String name, InputSource is)
            throws ParserConfigurationException, IOException, SAXException {
        return new SolrConfig(instanceDir, name, is);
    }
}