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

io.quarkiverse.roq.frontmatter.deployment.publish.RoqFrontMatterPublishProcessor Maven / Gradle / Ivy

There is a newer version: 1.1.1
Show newest version
package io.quarkiverse.roq.frontmatter.deployment.publish;

import static io.quarkiverse.roq.frontmatter.deployment.TemplateLink.DEFAULT_PAGINATE_LINK_TEMPLATE;
import static io.quarkiverse.roq.frontmatter.deployment.data.RoqFrontMatterDataProcessor.PAGINATE_KEY;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

import org.jboss.logging.Logger;

import io.quarkiverse.roq.frontmatter.deployment.Paginate;
import io.quarkiverse.roq.frontmatter.deployment.RoqFrontMatterRootUrlBuildItem;
import io.quarkiverse.roq.frontmatter.deployment.TemplateLink;
import io.quarkiverse.roq.frontmatter.deployment.data.RoqFrontMatterDocumentTemplateBuildItem;
import io.quarkiverse.roq.frontmatter.deployment.data.RoqFrontMatterPaginateTemplateBuildItem;
import io.quarkiverse.roq.frontmatter.runtime.config.RoqSiteConfig;
import io.quarkiverse.roq.frontmatter.runtime.model.PageInfo;
import io.quarkiverse.roq.frontmatter.runtime.model.Paginator;
import io.quarkiverse.roq.frontmatter.runtime.model.RootUrl;
import io.quarkiverse.roq.frontmatter.runtime.model.RoqUrl;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.runtime.configuration.ConfigurationException;
import io.vertx.core.json.JsonObject;

class RoqFrontMatterPublishProcessor {

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

    @BuildStep
    public void publishCollections(
            List documentTemplates,
            BuildProducer publishDocuments) {
        for (RoqFrontMatterDocumentTemplateBuildItem documentTemplate : documentTemplates) {
            publishDocuments.produce(new RoqFrontMatterPublishDocumentPageBuildItem(documentTemplate.url(),
                    documentTemplate.raw().info(), documentTemplate.collection(), documentTemplate.data()));
        }
    }

    @BuildStep
    public void paginatePublish(RoqSiteConfig config,
            RoqFrontMatterRootUrlBuildItem rootUrlItem,
            BuildProducer pagesProducer,
            List paginationList,
            List documents,
            List derivedCollections) {
        if (paginationList.isEmpty() || rootUrlItem == null) {
            return;
        }
        final RootUrl rootUrl = rootUrlItem.rootUrl();
        final Map sizeByCollection = new HashMap<>();

        for (RoqFrontMatterPublishDocumentPageBuildItem document : documents) {
            sizeByCollection.computeIfAbsent(document.collection().id(), k -> new AtomicInteger()).incrementAndGet();
        }

        for (RoqFrontMatterPublishDerivedCollectionBuildItem derivedCollection : derivedCollections) {
            sizeByCollection.computeIfAbsent(derivedCollection.collection(), k -> new AtomicInteger())
                    .addAndGet(derivedCollection.documentIds().size());
        }

        for (RoqFrontMatterPaginateTemplateBuildItem pagination : paginationList) {
            final JsonObject data = pagination.data();
            Paginate paginate = readPaginate(pagination.info().id(), data, pagination.defaultPaginatedCollection());
            AtomicInteger collectionSize = sizeByCollection.get(paginate.collection());
            if (collectionSize == null) {
                throw new ConfigurationException(
                        "Paginate collection not found '" + paginate.collection() + "' in " + pagination.info().id());
            }
            final int total = collectionSize.get();
            if (paginate.size() <= 0) {
                throw new ConfigurationException("Page size must be greater than zero.");
            }
            int countPages = (total + paginate.size() - 1) / paginate.size();

            List paginatedPages = new ArrayList<>();
            final String linkTemplate = paginate.link() != null ? paginate.link() : DEFAULT_PAGINATE_LINK_TEMPLATE;
            for (int i = 1; i <= countPages; i++) {
                final RoqUrl paginatedUrl;
                if (i == 1) {
                    paginatedUrl = pagination.url();
                } else {
                    final String link = TemplateLink.paginateLink(config.rootPath(), linkTemplate,
                            new TemplateLink.PaginateLinkData(pagination.info(),
                                    paginate.collection(), Integer.toString(i), data));
                    paginatedUrl = rootUrl.resolve(link);
                }
                PageInfo info = pagination.info();
                if (i > 1) {
                    info = info.changeId(paginatedUrl.path());
                }
                paginatedPages.add(new PageToPublish(paginatedUrl, info, data));
            }

            for (int i = 1; i <= countPages; i++) {
                Integer prev = i > 1 ? i - 1 : null;
                Integer next = i <= countPages - 1 ? i + 1 : null;
                PageToPublish currentPage = paginatedPages.get(i - 1);
                PageToPublish previousPage;
                PageToPublish nextPage;
                RoqUrl previousUrl = null;
                RoqUrl nextUrl = null;
                if (prev != null) {
                    previousPage = paginatedPages.get(prev - 1);
                    previousUrl = previousPage.url();
                }
                if (next != null) {
                    nextPage = paginatedPages.get(next - 1);
                    nextUrl = nextPage.url();
                }
                Paginator paginator = new Paginator(paginate.collection(), total, paginate.size(), countPages, i, prev,
                        previousUrl, next, nextUrl);
                pagesProducer.produce(new RoqFrontMatterPublishPageBuildItem(currentPage.url(), currentPage.info(),
                        currentPage.data(), paginator));
            }
        }

    }

    private static Paginate readPaginate(String name, JsonObject data, String defaultCollection) {
        final Object value = data.getValue(PAGINATE_KEY);
        if (value instanceof JsonObject paginate) {
            final String collection = paginate.getString("collection", defaultCollection);
            if (collection == null) {
                throw new ConfigurationException("Invalid pagination configuration in " + name);
            }
            return new Paginate(paginate.getInteger("size", 5), paginate.getString("link", DEFAULT_PAGINATE_LINK_TEMPLATE),
                    collection);
        }
        if (value instanceof String collection) {
            return new Paginate(5, DEFAULT_PAGINATE_LINK_TEMPLATE, collection);
        }
        if (value instanceof Boolean paginate && paginate) {
            if (defaultCollection == null) {
                throw new ConfigurationException("Invalid pagination configuration in " + name);
            }
            return new Paginate(5, DEFAULT_PAGINATE_LINK_TEMPLATE, defaultCollection);
        }
        throw new ConfigurationException("Invalid pagination configuration in " + name);
    }

    private record PageToPublish(RoqUrl url, PageInfo info, JsonObject data) {
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy