All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.metaeffekt.artifact.resolver.maven.index.lucene.MavenLuceneIndexer Maven / Gradle / Ivy

package org.metaeffekt.artifact.resolver.maven.index.lucene;

import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.metaeffekt.artifact.resolver.generic.index.lucene.AbstractLuceneIndex;

import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.Map;

/**
 * Maven Lucene Indexer. Produces dedicated index to support the queries on MavenLuceneIndex.
 */
@Slf4j
public class MavenLuceneIndexer extends AbstractLuceneIndex {

    private static final int INDEX_WRITER_MAX_RAM_BUFFER_SIZE_MB = 128;

    private static final String DEDUPLICATE = "DEDUPLICATE";

    private final IndexWriter writer;

    public MavenLuceneIndexer(@NonNull File directoryPath, @NonNull Analyzer analyzer) throws IOException {
        super(directoryPath, analyzer);
        final IndexWriterConfig conf = new IndexWriterConfig(getAnalyzer());
        conf.setCommitOnClose(true);
        conf.setRAMBufferSizeMB(INDEX_WRITER_MAX_RAM_BUFFER_SIZE_MB);
        conf.setUseCompoundFile(false);

        this.writer = new IndexWriter(getDirectory(), conf);
    }

    public void addEntry(@NonNull Map> keyValueMap) throws IOException {
        final Document document = new Document();

        if (keyValueMap.containsKey(DEDUPLICATE)) {
            log.error("Can't support key named [DEDUPLICATE]: key reserved by this class.");
            throw new IllegalArgumentException("Can't support key named [DEDUPLICATE]: key reserved by this class.");
        }

        for (Map.Entry> entry : keyValueMap.entrySet()) {
            if (!StringUtils.equals(entry.getKey(), "u")) {
                // removing this abort means non-"u" field will be parsed as a "u" field by below code
                if (log.isTraceEnabled()) {
                    log.trace("Skip unsupported key unequals 'u': [{}]", entry.getKey());
                }

                continue;
            }

            for (String value : entry.getValue()) {
                final String[] split = value.split("\\|");

                final String groupId = split[0];
                final String artifactId = split[1];
                final String version = split[2];
                final String classifier = split[3];
                final String extensionOrPackaging = split[4];

                document.add(new TextField("g", groupId, Field.Store.YES));
                document.add(new TextField("a", artifactId, Field.Store.YES));
                document.add(new TextField("v", version, Field.Store.YES));
                document.add(new TextField("c", classifier, Field.Store.YES));
                document.add(new TextField("p", extensionOrPackaging, Field.Store.YES));

                // guess extension
                String suffix = extensionOrPackaging;
                if (extensionOrPackaging.equalsIgnoreCase("module")) {
                    suffix = "jar";
                }

                // guess default filename
                final String filename = artifactId + "-" + version + ("NA".equalsIgnoreCase(classifier) ? "" : "-" + classifier) + "." + suffix;
                document.add(new TextField("df", filename, Field.Store.YES));

                // guess extended filename
                final String extendedFilename = groupId + "." + artifactId + "-" + version + ("NA".equalsIgnoreCase(classifier) ? "" : "-" + classifier) + "." + suffix;
                document.add(new TextField("ef", extendedFilename, Field.Store.YES));
            }
        }

        this.writer.addDocument(document);
    }

    public void clear() throws IOException {
        writer.deleteAll();
        writer.forceMergeDeletes(false);
        writer.commit();
    }

    /**
     * Simple passthrough method to commit changes to storage.
     *
     * @throws IOException throws on write failure
     */
    public void commit() throws IOException {
        writer.commit();
    }

    /**
     * Closes underlying index interfaces.
     */
    @Override
    public void close() throws Exception {
        writer.close();
        super.close();
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy