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

org.spincast.website.repositories.TemplateFilesRepository Maven / Gradle / Ivy

There is a newer version: 0.9.28
Show newest version
package org.spincast.website.repositories;

import java.io.InputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.reflections.Reflections;
import org.reflections.scanners.ResourcesScanner;
import org.spincast.core.templating.ITemplatingEngine;
import org.spincast.core.utils.SpincastStatics;
import org.spincast.shaded.org.apache.commons.io.IOUtils;
import org.spincast.shaded.org.apache.commons.lang3.StringUtils;
import org.spincast.website.IAppConfig;
import org.spincast.website.models.INewsEntriesAndTotalNbr;
import org.spincast.website.models.INewsEntry;
import org.spincast.website.models.NewsEntry;

import com.google.common.collect.Lists;
import com.google.inject.Inject;

/**
 * Implementation of the News repository that takes the 
 * news entries from template files.
 */
public class TemplateFilesRepository implements INewsRepository {

    private final IAppConfig appConfig;
    private final ITemplatingEngine templatingEngine;

    private final Object getNewsEntriesLocalLock = new Object();

    private List newsEntries;
    private List newsEntriesAsc;
    private List newsEntriesDesc;
    private Map newsEntriesById;

    /**
     * Constructor
     */
    @Inject
    public TemplateFilesRepository(IAppConfig appConfig,
                                   ITemplatingEngine templatingEngine) {
        this.appConfig = appConfig;
        this.templatingEngine = templatingEngine;
    }

    /**
     * Init
     */
    @Inject
    public void init() {

        //==========================================
        // Load news entries
        //==========================================
        getNewsEntriesLocal();
    }

    protected IAppConfig getAppConfig() {
        return this.appConfig;
    }

    protected ITemplatingEngine getTemplatingEngine() {
        return this.templatingEngine;
    }

    @Override
    public int getNewsEntriesTotalNumber() {
        return getNewsEntriesLocal().size();
    }

    @Override
    public List getNewsEntries(boolean ascOrder) {

        if(ascOrder) {
            if(this.newsEntriesAsc == null) {

                List entries = getNewsEntriesLocal();

                Collections.sort(entries, new Comparator() {

                    @Override
                    public int compare(INewsEntry entry1, INewsEntry entry2) {
                        return entry1.getPublishedDate().compareTo(entry2.getPublishedDate());
                    }
                });

                this.newsEntriesAsc = entries;
            }
            return this.newsEntriesAsc;

        } else {
            if(this.newsEntriesDesc == null) {
                List newsEntriesAsc = getNewsEntries(true);
                this.newsEntriesDesc = Lists.reverse(newsEntriesAsc);
            }
            return this.newsEntriesDesc;
        }
    }

    @Override
    public List getNewsEntries(int startPos, int endPos, boolean ascOrder) {
        return getNewsEntriesAndTotalNbr(startPos, endPos, ascOrder).getNewsEntries();
    }

    @Override
    public INewsEntriesAndTotalNbr getNewsEntriesAndTotalNbr(int startPos, int endPos, boolean ascOrder) {

        if(startPos < 1) {
            startPos = 1;
        }

        if(endPos < 1) {
            endPos = 1;
        }

        if(endPos < startPos) {
            endPos = startPos;
        }

        final List entries = getNewsEntries(ascOrder);

        if(entries.size() == 0 || startPos > entries.size()) {

            return new INewsEntriesAndTotalNbr() {

                @Override
                public List getNewsEntries() {
                    return new ArrayList();
                }

                @Override
                public int getNbrNewsEntriesTotal() {
                    return entries.size();
                }
            };
        }

        if(endPos > entries.size()) {
            endPos = entries.size();
        }

        final int startPosFinal = startPos;
        final int endPosFinal = endPos;
        return new INewsEntriesAndTotalNbr() {

            @Override
            public List getNewsEntries() {
                return Collections.unmodifiableList(entries.subList(startPosFinal - 1, endPosFinal)); // endPos is exclusive here
            }

            @Override
            public int getNbrNewsEntriesTotal() {
                return entries.size();
            }
        };
    }

    @Override
    public INewsEntry getNewsEntry(long newsId) {
        return getNewsEntriesById().get(newsId);
    }

    protected Map getNewsEntriesById() {

        if(this.newsEntriesById == null) {
            this.newsEntriesById = new HashMap();
            List newsEntries = getNewsEntriesLocal();
            for(INewsEntry newsEntry : newsEntries) {
                this.newsEntriesById.put(newsEntry.getId(), newsEntry);
            }
        }

        return this.newsEntriesById;
    }

    protected List getNewsEntriesLocal() {

        if(this.newsEntries == null) {
            synchronized(this.getNewsEntriesLocalLock) {
                if(this.newsEntries == null) {

                    try {
                        List newsEntries = new ArrayList();

                        Set newsRelPaths =
                                new Reflections("news", new ResourcesScanner()).getResources(Pattern.compile(".+\\.html"));

                        for(String newsRelPath : newsRelPaths) {

                            InputStream stream = this.getClass().getClassLoader().getResourceAsStream(newsRelPath);
                            try {
                                StringWriter writer = new StringWriter();
                                IOUtils.copy(stream, writer, "UTF-8");
                                String newsEntryContent = writer.toString();

                                Properties metaProps = getMetaProperties(newsEntryContent);

                                String idStr = metaProps.getProperty("id");
                                long id = Long.parseLong(idStr);
                                String dateStr = metaProps.getProperty("dateUTC");
                                String title = metaProps.getProperty("title");

                                newsEntryContent = cleanContent(newsEntryContent);

                                INewsEntry entry = new NewsEntry(id, dateStr, title, newsEntryContent);
                                newsEntries.add(entry);
                            } finally {
                                IOUtils.closeQuietly(stream);
                            }
                        }
                        this.newsEntries = newsEntries;

                    } catch(Exception ex) {
                        throw SpincastStatics.runtimize(ex);
                    }
                }
            }
        }

        return this.newsEntries;
    }

    protected Properties getMetaProperties(String newsEntryContent) {

        try {
            Matcher matcher = Pattern.compile("(?s)").matcher(newsEntryContent);
            matcher.find();
            String propsStr = StringUtils.strip(matcher.group(1), " \t\r\n");

            Properties props = new Properties();
            props.load(new StringReader(propsStr));

            return props;

        } catch(Exception ex) {
            throw SpincastStatics.runtimize(ex);
        }
    }

    protected String cleanContent(String newsEntryContent) {

        //==========================================
        // Removes the meta informations
        //==========================================
        newsEntryContent = newsEntryContent.replaceAll("(?s)", "");
        newsEntryContent = StringUtils.strip(newsEntryContent, "\r\n");

        //==========================================
        // Replaces some placeholders
        //==========================================
        String appUrlPrefix = getAppConfig().getServerSchemeHostPort();
        newsEntryContent = getTemplatingEngine().evaluate(newsEntryContent, SpincastStatics.params("appUrlPrefix", appUrlPrefix));

        return newsEntryContent;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy