com.callidusrobotics.droptables.model.ReportGenerator.java Source code

Java tutorial

Introduction

Here is the source code for com.callidusrobotics.droptables.model.ReportGenerator.java

Source

/**
 * Copyright (C) 2015 Rusty Gerard
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.callidusrobotics.droptables.model;

import groovy.lang.Binding;
import groovy.lang.GroovyRuntimeException;
import groovy.lang.GroovyShell;
import groovy.lang.Script;
import groovy.text.SimpleTemplateEngine;
import groovy.text.Template;
import groovy.util.GroovyScriptEngine;

import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.Date;
import java.util.Map;
import java.util.Map.Entry;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.Validate;
import org.bson.types.ObjectId;
import org.codehaus.groovy.control.CompilationFailedException;
import org.hibernate.validator.constraints.NotEmpty;
import org.mongodb.morphia.annotations.Entity;
import org.mongodb.morphia.annotations.Id;
import org.mongodb.morphia.annotations.PrePersist;
import org.mongodb.morphia.annotations.Property;

import com.fasterxml.jackson.annotation.JsonProperty;

/**
 * POJO to store Groovy scripts, templates, and default variable bindings for
 * ad-hoc report generation.
 *
 * @author Rusty Gerard
 * @since 0.0.1
 */
@Entity("droptables.reports")
public class ReportGenerator {
    /**
     * Enumerated type of supported scripting languages.
     *
     * @author Rusty Gerard
     * @since 0.0.1
     */
    public enum Language {
        GROOVY
    }

    @Id
    ObjectId id;

    @Property("dateCreated")
    Date created;

    @Property("dateModified")
    Date modified;

    @NotEmpty
    @Property("name")
    String name;

    @NotNull
    @Property("description")
    String description;

    @NotEmpty
    @Property("author")
    String author;

    @Valid
    @NotNull
    @Property("language")
    Language language;

    @NotEmpty
    @Property("template")
    String template;

    @NotEmpty
    @Property("script")
    String script;

    @Valid
    @NotNull
    @Property("defaultParameters")
    Map<String, String> binding = Collections.emptyMap();

    @PrePersist
    void prePersist() {
        // FIXME: These dates should use Mongo's currentDate
        // Maybe we could register ReportDao as an @EntityListeners ?
        if (created == null) {
            created = modified = new Date();
        } else {
            modified = new Date();
        }
    }

    public ObjectId getId() {
        return id;
    }

    @JsonProperty("dateCreated")
    public Date getCreated() {
        if (created == null) {
            return null;
        }

        return new Date(created.getTime());
    }

    @JsonProperty("dateCreated")
    public void setCreated(Date created) {
        if (created != null) {
            this.created = new Date(created.getTime());
        }
    }

    @JsonProperty("dateModified")
    public Date getModified() {
        if (modified == null) {
            return null;
        }

        return new Date(modified.getTime());
    }

    @JsonProperty("dateModified")
    public void setModified(Date modified) {
        if (modified != null) {
            this.modified = new Date(modified.getTime());
        }
    }

    @JsonProperty("name")
    public String getName() {
        return name;
    }

    @JsonProperty("name")
    public void setName(String name) {
        this.name = name;
    }

    @JsonProperty("description")
    public String getDescription() {
        return description;
    }

    @JsonProperty("description")
    public void setDescription(String description) {
        this.description = description;
    }

    @JsonProperty("author")
    public String getAuthor() {
        return author;
    }

    @JsonProperty("author")
    public void setAuthor(String author) {
        this.author = author;
    }

    @JsonProperty("language")
    public Language getLanguage() {
        return language;
    }

    @JsonProperty("language")
    public void setLanguage(Language language) {
        Validate.notNull(language);
        this.language = language;
    }

    @JsonProperty("template")
    public String getTemplate() {
        return template;
    }

    @JsonProperty("template")
    public void setTemplate(String template) throws GroovyRuntimeException, ClassNotFoundException, IOException {
        new SimpleTemplateEngine().createTemplate(template);

        this.template = template;
    }

    public Template parseTemplate() throws CompilationFailedException, ClassNotFoundException, IOException {
        return new SimpleTemplateEngine().createTemplate(template);
    }

    @JsonProperty("script")
    public String getScript() {
        return script;
    }

    @JsonProperty("script")
    public void setScript(String script) throws CompilationFailedException {
        new GroovyShell().parse(script);

        this.script = script;
    }

    /**
     * Converts the String into a Script object.
     *
     * @return The Script object, never null
     * @throws CompilationFailedException
     */
    public Script parseScript() throws CompilationFailedException {
        return new GroovyShell().parse(script);
    }

    /**
     * Writes the String data to a file for use by a {@link GroovyScriptEngine}.
     *
     * @param cacheDir
     *          The directory to create the file in.
     * @return The name of the file that was written to.
     * @throws IOException
     */
    public String writeScript(String cacheDir) throws IOException {
        if (id == null) {
            throw new IOException("Unable to persist script: ID not set.");
        }

        String filename = id + ".groovy";
        FileUtils.writeStringToFile(new File(cacheDir, filename), script);

        return filename;
    }

    @JsonProperty("defaultParameters")
    public Map<String, String> getBinding() {
        return Collections.unmodifiableMap(binding);
    }

    @JsonProperty("defaultParameters")
    @SuppressWarnings("unchecked")
    public void setBinding(Map<String, String> binding) throws InstantiationException, IllegalAccessException {
        this.binding = binding.getClass().newInstance();
        this.binding.putAll(binding);
    }

    /**
     * Converts the Map of default parameters into a Binding object.
     *
     * @return The Binding, never null
     */
    public Binding parseBinding() {
        Binding result = new Binding();
        for (Entry<String, String> entry : binding.entrySet()) {
            result.setVariable(entry.getKey(), entry.getValue());
        }

        return result;
    }
}