pt.webdetails.cdf.dd.AbstractDashboard.java Source code

Java tutorial

Introduction

Here is the source code for pt.webdetails.cdf.dd.AbstractDashboard.java

Source

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */
package pt.webdetails.cdf.dd;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.text.MessageFormat;
import java.util.Date;
import java.util.regex.Matcher;
import net.sf.json.JSONObject;
import org.apache.commons.jxpath.JXPathContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.pentaho.platform.api.engine.IParameterProvider;
import org.pentaho.platform.api.engine.IPentahoSession;
import pt.webdetails.cdf.dd.render.DependenciesManager;
import pt.webdetails.cdf.dd.render.RenderComponents;
import pt.webdetails.cdf.dd.render.RenderLayout;
import pt.webdetails.cdf.dd.render.StringFilter;
import pt.webdetails.cdf.dd.structure.WcdfDescriptor;
import pt.webdetails.cdf.dd.structure.XmlStructure;
import pt.webdetails.cdf.dd.util.JsonUtils;
import pt.webdetails.cpf.repository.RepositoryAccess;

// Imports for the cache
import org.pentaho.platform.engine.core.system.PentahoSessionHolder;

/**
 *
 * @author pdpi
 */
public abstract class AbstractDashboard implements Serializable, Dashboard {
    /* CONSTANTS */

    private static final long serialVersionUID = 1L;
    // Dashboard rendering
    private static final String DASHBOARD_HEADER_TAG = "\\@HEADER\\@";
    private static final String DASHBOARD_CONTENT_TAG = "\\@CONTENT\\@";
    private static final String DASHBOARD_FOOTER_TAG = "\\@FOOTER\\@";
    private static final String RESOURCE_FOOTER = "resources/patch-footer.html";
    private static final String COMPONENT_PREFIX = "render_";
    private static Log logger = LogFactory.getLog(Dashboard.class);
    /* FIELDS */
    protected boolean absolute, debug;
    protected String template, header, layout, components, footer, absRoot, scheme;
    protected String templateFile, dashboardLocation;
    protected Date loaded;
    private WcdfDescriptor wcdf;
    protected final String alias;

    public AbstractDashboard(IParameterProvider pathParams, IParameterProvider requestParams)
            throws FileNotFoundException {
        absRoot = requestParams.hasParameter("root") ? requestParams.getParameter("root").toString() : "";
        absolute = (!absRoot.equals(""))
                || requestParams.hasParameter("absolute") && requestParams.getParameter("absolute").equals("true");
        debug = requestParams.hasParameter("debug") && requestParams.getParameter("debug").equals("true");
        boolean inferScheme = requestParams.hasParameter("inferScheme")
                ? requestParams.getParameter("inferScheme").equals("true")
                : true;
        scheme = inferScheme ? DashboardDesignerContentGenerator.getScheme(pathParams) : "";
        alias = "";
        construct(DashboardDesignerContentGenerator.getWcdfRelativePath(requestParams));
    }

    public AbstractDashboard(WcdfDescriptor wcdf, boolean absolute, String absRoot, boolean debug, String scheme)
            throws FileNotFoundException {
        this(wcdf, absolute, absRoot, debug, scheme, "");
    }

    public AbstractDashboard(WcdfDescriptor wcdf, boolean absolute, String absRoot, boolean debug, String scheme,
            String alias) throws FileNotFoundException {
        this.absolute = absolute;
        this.absRoot = absRoot;
        this.debug = debug;
        this.scheme = scheme;
        this.wcdf = wcdf;
        this.alias = alias;
        construct();
    }

    public AbstractDashboard(String wcdfPath, boolean absolute, String absRoot, boolean debug, String scheme)
            throws FileNotFoundException {
        this.alias = "";
        this.absolute = absolute;
        this.absRoot = absRoot;
        this.debug = debug;
        this.scheme = scheme;
        construct(wcdfPath);
    }

    protected WcdfDescriptor fetchWcdf(String wcdfPath) throws IOException {
        WcdfDescriptor wcdf = null;
        try {
            IPentahoSession userSession = PentahoSessionHolder.getSession();
            XmlStructure structure = new XmlStructure(userSession);
            if (wcdfPath != null && wcdfPath.endsWith(".wcdf")) {
                wcdf = structure.loadWcdfDescriptor(wcdfPath);
            } else {//we may just be receiving a .cde file (preview)
                wcdf = new WcdfDescriptor();
                wcdf.setStyle(CdfStyles.DEFAULTSTYLE);
            }
        } finally {
        }
        ;

        return wcdf;
    }

    private void construct(String wcdfPath) throws FileNotFoundException {
        try {
            wcdf = fetchWcdf(wcdfPath);
            construct();
        } catch (IOException e) {
            logger.error(e);
        }
    }

    protected void renderContent() throws Exception {
        IPentahoSession userSession = PentahoSessionHolder.getSession();
        RepositoryAccess solutionRepository = RepositoryAccess.getRepository(userSession);
        final JXPathContext doc = openDashboardAsJXPathContext(solutionRepository, dashboardLocation, wcdf);

        final RenderLayout layoutRenderer = new RenderLayout();
        final RenderComponents componentsRenderer = new RenderComponents();
        this.layout = replaceTokens(layoutRenderer.render(doc, alias), absolute, absRoot);
        this.components = replaceTokens(componentsRenderer.render(doc, alias), absolute, absRoot);
        this.header = replaceTokens(renderHeaders(getContent()), absolute, absRoot);
    }

    private void construct() throws FileNotFoundException {

        this.dashboardLocation = wcdf.getStructurePath();
        try {

            this.footer = ResourceManager.getInstance().getResourceAsString(RESOURCE_FOOTER);
            this.templateFile = CdfStyles.getInstance().getResourceLocation(wcdf.getStyle());

            renderContent();
            try {//attempt to read template file
                this.template = replaceTokens(ResourceManager.getInstance().getResourceAsString(this.templateFile),
                        absolute, absRoot);
            } catch (IOException e) {
                //couldn't open template file, attempt to use default
                logger.error(MessageFormat.format("Couldn''t open template file {0}.", this.templateFile), e);
                String templateFile = CdfStyles.getInstance().getResourceLocation(CdfStyles.DEFAULTSTYLE);
                this.template = replaceTokens(ResourceManager.getInstance().getResourceAsString(templateFile),
                        absolute, absRoot);
            }
            this.loaded = new Date();
        } catch (FileNotFoundException e) {
            logger.error(e);
            throw e;
        } catch (Exception e) {
            logger.error(e);
            this.templateFile = null;
        }
    }

    public static JXPathContext openDashboardAsJXPathContext(RepositoryAccess solutionRepository,
            String dashboardLocation, WcdfDescriptor wcdf) throws IOException, FileNotFoundException {
        final JSONObject json = (JSONObject) JsonUtils
                .readJsonFromInputStream(solutionRepository.getResourceInputStream(dashboardLocation));

        if (wcdf != null) {
            json.put("settings", wcdf.toJSON());
        }
        final JXPathContext doc = JXPathContext.newContext(json);
        return doc;
    }

    //TODO: needed? remove
    public String render() {
        return render(null);
    }

    //TODO: remove
    public String render(IParameterProvider params) {
        return render(params, DashboardDesignerContentGenerator.getCdfContext(params));
    }

    public String render(IParameterProvider params, String dashboardContext) {
        logger.debug("[Timing] Starting render proper: " + (new SimpleDateFormat("H:m:s.S")).format(new Date()));
        String quotedFooter = Matcher.quoteReplacement(this.footer),
                quotedHeader = Matcher.quoteReplacement(this.header + dashboardContext),
                quotedContent = Matcher.quoteReplacement(getContent());
        logger.debug("[Timing] Replacing tokens: " + (new SimpleDateFormat("H:m:s.S")).format(new Date()));

        String result = this.template.replaceAll(DASHBOARD_HEADER_TAG, quotedHeader) // Replace the Header
                .replaceAll(DASHBOARD_FOOTER_TAG, quotedFooter) // And the Footer
                .replaceAll(DASHBOARD_CONTENT_TAG, quotedContent); // And even the content!
        logger.debug("[Timing] Finished render proper: " + (new SimpleDateFormat("H:m:s.S")).format(new Date()));
        return result;
    }

    protected String replaceTokens(String content, boolean absolute, String absRoot) {
        final String DASHBOARD_PATH_REGEXP = "\\$\\{dashboardPath\\}",
                ABS_DIR_RES_TAG_REGEXP = "\\$\\{res:(/.+/)\\}", ABS_IMG_TAG_REGEXP = "\\$\\{img:(/.+)\\}",
                ABS_RES_TAG_REGEXP = "\\$\\{res:(/.+)\\}", REL_DIR_RES_TAG_REGEXP = "\\$\\{res:(.+/)\\}",
                REL_IMG_TAG_REGEXP = "\\$\\{img:(.+)\\}", REL_RES_TAG_REGEXP = "\\$\\{res:(.+)\\}";

        final long timestamp = new Date().getTime();
        String root = absolute
                ? (scheme.equals("") ? "" : scheme + "://") + absRoot
                        + DashboardDesignerContentGenerator.SERVER_URL_VALUE
                : "";
        String path = dashboardLocation.replaceAll("(.+/).*", "$1");
        String fixedContent = content // Start with the same content
                .replaceAll(DASHBOARD_PATH_REGEXP, path.replaceAll("(^/.*/$)", "$1")) // replace the dashboard path token
                .replaceAll(ABS_IMG_TAG_REGEXP, root + "res$1" + "?v=" + timestamp)// build the image links, with a timestamp for caching purposes
                .replaceAll(REL_IMG_TAG_REGEXP, root + "res" + path + "$1" + "?v=" + timestamp)// build the image links, with a timestamp for caching purposes
                .replaceAll(ABS_DIR_RES_TAG_REGEXP, root + "res$1")// Directories don't need the caching timestamp
                .replaceAll(REL_DIR_RES_TAG_REGEXP, root + "res" + path + "$1")// Directories don't need the caching timestamp
                .replaceAll(ABS_RES_TAG_REGEXP, root + "res$1" + "?v=" + timestamp)// build the image links, with a timestamp for caching purposes
                .replaceAll(REL_RES_TAG_REGEXP, root + "res" + path + "$1" + "?v=" + timestamp);// build the image links, with a timestamp for caching purposes

        return fixedContent;
    }

    protected String renderHeaders() {
        return renderHeaders("");
    }

    protected String renderHeaders(String contents) {
        String dependencies, styles, cdfDependencies;
        final String title = "<title>" + getWcdf().getTitle() + "</title>";
        // Acquire CDF headers
        try {
            cdfDependencies = DashboardDesignerContentGenerator.getCdfIncludes(contents, getType(), debug, absRoot,
                    scheme);
        } catch (Exception e) {
            logger.error("Failed to get cdf includes");
            cdfDependencies = "";
        }
        // Acquire CDE-specific headers
        if (absolute) {
            final String adornedRoot = (scheme.equals("") ? "" : (scheme + "://")) + absRoot;
            StringFilter css = new StringFilter() {
                public String filter(String input) {
                    //input = input.replaceAll("\\?", "&");
                    return "\t\t<link href='" + adornedRoot + DashboardDesignerContentGenerator.SERVER_URL_VALUE
                            + "getCssResource/" + input + "' rel='stylesheet' type='text/css' />\n";
                }
            };
            StringFilter js = new StringFilter() {
                public String filter(String input) {
                    //input = input.replaceAll("\\?", "&");
                    return "\t\t<script language=\"javascript\" type=\"text/javascript\" src=\"" + adornedRoot
                            + DashboardDesignerContentGenerator.SERVER_URL_VALUE + "getJsResource/" + input
                            + "\"></script>\n";
                }
            };
            if (debug) {
                dependencies = DependenciesManager.getInstance().getEngine(DependenciesManager.Engines.CDF)
                        .getDependencies(js);
                styles = DependenciesManager.getInstance().getEngine(DependenciesManager.Engines.CDF_CSS)
                        .getDependencies(css);
            } else {
                dependencies = DependenciesManager.getInstance().getEngine(DependenciesManager.Engines.CDF)
                        .getPackagedDependencies(js);
                styles = DependenciesManager.getInstance().getEngine(DependenciesManager.Engines.CDF_CSS)
                        .getPackagedDependencies(css);
            }
        } else {
            if (debug) {
                dependencies = DependenciesManager.getInstance().getEngine(DependenciesManager.Engines.CDF)
                        .getDependencies();
                styles = DependenciesManager.getInstance().getEngine(DependenciesManager.Engines.CDF_CSS)
                        .getDependencies();
            } else {
                dependencies = DependenciesManager.getInstance().getEngine(DependenciesManager.Engines.CDF)
                        .getPackagedDependencies();
                styles = DependenciesManager.getInstance().getEngine(DependenciesManager.Engines.CDF_CSS)
                        .getPackagedDependencies();
            }
        }

        String raw = DependenciesManager.getInstance().getEngine(DependenciesManager.Engines.CDF_RAW)
                .getDependencies();
        return title + cdfDependencies + raw + dependencies + styles;
    }

    public String getContent() {
        String epilogue = "<script language=\"javascript\" type=\"text/javascript\">\n" + "Dashboards.init();\n"
                + "</script>";
        return getLayout() + getComponents() + epilogue;
    }

    public String getFooter() {
        return footer;
    }

    public String getHeader() {
        return header;
    }

    public Date getLoaded() {
        return loaded;
    }

    public String getTemplate() {
        return templateFile;
    }

    /**
     * @return the wcdf
     */
    protected WcdfDescriptor getWcdf() {
        return wcdf;
    }

    /**
     * @param wcdf the wcdf to set
     */
    protected void setWcdf(WcdfDescriptor wcdf) {
        this.wcdf = wcdf;
    }

    public String getLayout() {
        return replaceAlias(this.layout, this.alias);
    }

    public String getComponents() {
        return replaceAlias(this.components, this.alias);
    }

    String replaceAlias(String content, String alias) {
        if (content == null) {
            logger.warn("replaceAlias: null content.");
            return content;
        }

        final String SHORT_H_TAG = "\\$\\{h:(.+?)\\}", SHORT_C_TAG = "\\$\\{c:(.+?)\\}",
                SHORT_P_TAG = "\\$\\{p:(.+?)\\}", LONG_H_TAG = "\\$\\{htmlObject:(.+?)\\}",
                LONG_C_TAG = "\\$\\{component:(.+?)\\}", LONG_P_TAG = "\\$\\{parameter:(.+?)\\}";
        alias = alias != null && alias.length() > 0 ? alias + "_" : "";

        String modified = content.replaceAll(SHORT_H_TAG, alias + "$1")
                .replaceAll(SHORT_C_TAG, COMPONENT_PREFIX + alias + "$1").replaceAll(SHORT_P_TAG, alias + "$1")
                .replaceAll(LONG_H_TAG, alias + "$1").replaceAll(LONG_C_TAG, COMPONENT_PREFIX + alias + "$1")
                .replaceAll(LONG_P_TAG, alias + "$1");
        return modified;
    }
}