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

org.linkeddatafragments.views.HtmlTriplePatternFragmentWriterImpl Maven / Gradle / Ivy

package org.linkeddatafragments.views;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
import org.apache.jena.rdf.model.RDFNode;
import org.apache.jena.rdf.model.Statement;
import org.apache.jena.rdf.model.StmtIterator;
import org.linkeddatafragments.datasource.IDataSource;
import org.linkeddatafragments.datasource.index.IndexDataSource;
import org.linkeddatafragments.fragments.ILinkedDataFragment;
import org.linkeddatafragments.fragments.tpf.ITriplePatternFragment;
import org.linkeddatafragments.fragments.tpf.ITriplePatternFragmentRequest;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

//TODO: Refactor to a composable & flexible architecture using DataSource types, fragments types and request types

/**
 * Serializes an {@link ILinkedDataFragment} to the HTML format
 *
 * @author Miel Vander Sande
 */
public class HtmlTriplePatternFragmentWriterImpl extends TriplePatternFragmentWriterBase implements ILinkedDataFragmentWriter {
    private final Configuration cfg;

    private final Template indexTemplate;
    private final Template datasourceTemplate;
    private final Template notfoundTemplate;
    private final Template errorTemplate;

    private final String HYDRA = "http://www.w3.org/ns/hydra/core#";

    /**
     *
     * @param prefixes
     * @param datasources
     * @throws IOException
     */
    public HtmlTriplePatternFragmentWriterImpl(Map prefixes, HashMap datasources) throws IOException {
        super(prefixes, datasources);

        cfg = new Configuration(Configuration.VERSION_2_3_22);
        cfg.setClassForTemplateLoading(getClass(), "/views");
        cfg.setDefaultEncoding("UTF-8");
        cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);

        indexTemplate = cfg.getTemplate("index.ftl.html");
        datasourceTemplate = cfg.getTemplate("datasource.ftl.html");
        notfoundTemplate = cfg.getTemplate("notfound.ftl.html");
        errorTemplate = cfg.getTemplate("error.ftl.html");
    }

    /**
     *
     * @param outputStream
     * @param datasource
     * @param fragment
     * @param tpfRequest
     * @throws IOException
     * @throws TemplateException
     */
    @Override
    public void writeFragment(ServletOutputStream outputStream, IDataSource datasource, ITriplePatternFragment fragment, ITriplePatternFragmentRequest tpfRequest) throws IOException, TemplateException{
        Map data = new HashMap();

        // base.ftl.html
        data.put("assetsPath", "assets/");
        data.put("header", datasource.getTitle());
        data.put("date", new Date());

        // fragment.ftl.html
        data.put("datasourceUrl", tpfRequest.getDatasetURL());
        data.put("datasource", datasource);

        // Parse controls to template variables
        StmtIterator controls = fragment.getControls();
        while (controls.hasNext()) {
            Statement control = controls.next();

            String predicate = control.getPredicate().getURI();
            RDFNode object = control.getObject();
            if (!object.isAnon()) {
                String value = object.isURIResource() ? object.asResource().getURI() : object.asLiteral().getLexicalForm();
                data.put(predicate.replaceFirst(HYDRA, ""), value);
            }
        }

        // Add metadata
        data.put("totalEstimate", fragment.getTotalSize());
        data.put("itemsPerPage", fragment.getMaxPageSize());

        // Add triples and datasources
        List triples = fragment.getTriples().toList();
        data.put("triples", triples);
        data.put("datasources", getDatasources());

        // Calculate start and end triple number
        Long start = ((tpfRequest.getPageNumber() - 1) * fragment.getMaxPageSize()) + 1;
        data.put("start", start);
        data.put("end", (start - 1) + (triples.size() < fragment.getMaxPageSize() ? triples.size() : fragment.getMaxPageSize()));

        // Compose query object
        Map query = new HashMap();
        query.put("subject", !tpfRequest.getSubject().isVariable() ? tpfRequest.getSubject().asConstantTerm() : "");
        query.put("predicate", !tpfRequest.getPredicate().isVariable() ? tpfRequest.getPredicate().asConstantTerm() : "");
        query.put("object", !tpfRequest.getObject().isVariable() ? tpfRequest.getObject().asConstantTerm() : "");
        data.put("query", query);

        // Get the template (uses cache internally)
        Template temp = datasource instanceof IndexDataSource ? indexTemplate : datasourceTemplate;

        // Merge data-model with template
        temp.process(data, new OutputStreamWriter(outputStream));
    }

    @Override
    public void writeNotFound(ServletOutputStream outputStream, HttpServletRequest request) throws Exception {
        Map data = new HashMap();
        data.put("assetsPath", "assets/");
        data.put("datasources", getDatasources());
        data.put("date", new Date());
        data.put("url", request.getRequestURL().toString());

        notfoundTemplate.process(data, new OutputStreamWriter(outputStream));
    }

    @Override
    public void writeError(ServletOutputStream outputStream, Exception ex)  throws Exception {
        Map data = new HashMap();
        data.put("assetsPath", "assets/");
        data.put("date", new Date());
        data.put("error", ex);

        errorTemplate.process(data, new OutputStreamWriter(outputStream));
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy