CatalogueImportService.java

/*
 * Copyright © 2024-2025 The CTAN Team and individual authors
 *
 * This file is distributed under the 3-clause BSD license.
 * See file LICENSE for details.
 */
package org.ctan.site.services.catalogue;

import java.io.File;
import java.io.IOException;

import org.ctan.site.CtanConfiguration.CatalogueConfig;
import org.ctan.site.services.search.base.IndexingService;
import org.ctan.site.services.search.base.IndexingSession;
import org.ctan.site.services.util.NullCheck;
import org.ctan.site.stores.AuthorStore;
import org.ctan.site.stores.LicenseStore;
import org.ctan.site.stores.PkgStore;
import org.ctan.site.stores.TopicStore;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import lombok.NonNull;

/**
 * This abstract base class provides the fundamentals for the catalogue imports
 * from ML files.
 *
 * @author <a href="mailto:gene@ctan.org">Gerd Neugebauer</a>
 */
public class CatalogueImportService {

    /**
     * The field <code>file</code> contains the file pointing to the entries
     * directory.
     */
    private File entries;

    /**
     * The field <code>authorService</code> contains the author service.
     */
    private AuthorsImportService authorService;

    /**
     * The field <code>topicService</code> contains the topic service.
     */
    private TopicsImportService topicService;

    /**
     * The field <code>pkgService</code> contains the package service.
     */
    private PkgsImportService pkgService;

    /**
     * The field <code>indexingService</code> contains the indexing service.
     */
    private IndexingService indexingService;

    /**
     * This is the constructor for <code>CatalogueImportService</code>.
     *
     * @param config the configuration
     * @param authorStore the author store
     * @param topicStore the topic store
     * @param pkgStore the package store
     * @param licenseStore the license store
     * @param indexingService the indexing service
     */
    @SuppressFBWarnings(value = {"CT_CONSTRUCTOR_THROW", "EI_EXPOSE_REP2"})
    public CatalogueImportService(@NonNull CatalogueConfig config,
        @NonNull AuthorStore authorStore,
        @NonNull TopicStore topicStore,
        @NonNull PkgStore pkgStore,
        @NonNull LicenseStore licenseStore,
        @NonNull IndexingService indexingService) {

        this.indexingService = indexingService;
        var entriesCfg = config.getEntries();
        NullCheck.isNotNullObject(entriesCfg, "config.entries");
        entries = new File(entriesCfg);
        if (!entries.isDirectory()) {
            throw new IllegalArgumentException("entries is not a directory");
        }
        authorService = new AuthorsImportService(entries, authorStore);
        topicService = new TopicsImportService(entries, topicStore);
        pkgService = new PkgsImportService(entries,
            pkgStore, authorStore, topicStore, licenseStore);
    }

    /**
     * The method <code>update</code> provides means to read the Catalogue from
     * XML files into the database.
     *
     * @throws IOException in case of an I/O error
     */
    public void update() throws IOException {

        try (IndexingSession session = indexingService.indexingSession()) {
            var authorsToBeDropped = authorService.updateEntriesAuthors();
            var topicsToBeDropped = topicService.updateExisting();
            var pkgsToBeDropped = pkgService.updateExisting();
            pkgService.drop(pkgsToBeDropped);
            topicService.drop(topicsToBeDropped);
            authorService.drop(authorsToBeDropped);
        }
    }
}