Package pt.webdetails.cdf.dd.model.inst.writer.cggrunjs

Source Code of pt.webdetails.cdf.dd.model.inst.writer.cggrunjs.CggRunJsGenericComponentWriter

/* 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.model.inst.writer.cggrunjs;
import java.io.ByteArrayInputStream;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import pt.webdetails.cdf.dd.CdeEngine;
import pt.webdetails.cdf.dd.model.core.Thing;
import pt.webdetails.cdf.dd.model.core.UnsupportedThingException;
import pt.webdetails.cdf.dd.model.core.writer.IThingWriteContext;
import pt.webdetails.cdf.dd.model.core.writer.IThingWriter;
import pt.webdetails.cdf.dd.model.core.writer.IThingWriterFactory;
import pt.webdetails.cdf.dd.model.core.writer.ThingWriteException;
import pt.webdetails.cdf.dd.model.core.writer.js.JsWriterAbstract;
import pt.webdetails.cdf.dd.model.inst.Dashboard;
import pt.webdetails.cdf.dd.model.inst.DataSourceComponent;
import pt.webdetails.cdf.dd.model.inst.GenericComponent;
import pt.webdetails.cdf.dd.model.inst.writer.cdfrunjs.CdfRunJsThingWriterFactory;
import pt.webdetails.cdf.dd.model.inst.writer.cdfrunjs.dashboard.CdfRunJsDashboardWriteContext;
import pt.webdetails.cdf.dd.model.inst.writer.cdfrunjs.dashboard.CdfRunJsDashboardWriteOptions;
import pt.webdetails.cdf.dd.util.Utils;
import pt.webdetails.cpf.repository.api.IUserContentAccess;
import pt.webdetails.cpf.utils.CharsetHelper;
import pt.webdetails.cdf.dd.model.meta.ComponentType;
import pt.webdetails.cdf.dd.model.meta.Resource;

/**
* @author dcleao
*/
public class CggRunJsGenericComponentWriter extends JsWriterAbstract implements IThingWriter
{
  private static final Log    _logger = LogFactory.getLog(CggRunJsGenericComponentWriter.class);
  private static final String CGG_EXTENSION = ".js";

  public void write(Object output, IThingWriteContext context, Thing t) throws ThingWriteException
  {
    this.write((IUserContentAccess) output, (CggRunJsDashboardWriteContext)context, (GenericComponent)t);
  }

  public void write(IUserContentAccess access, CggRunJsDashboardWriteContext context, GenericComponent comp) throws ThingWriteException
  {
    String dashboardFilePath = context.getDashboard().getSourcePath();
    String dashboardFileDir  = FilenameUtils.getFullPath(dashboardFilePath);
    String dashboardFileName = FilenameUtils.getName(dashboardFilePath);

    StringBuilder out = new StringBuilder();

    out.append("lib('cdf-env.js');")
       .append(NEWLINE)
       .append(NEWLINE);

    this.renderChart(out, context, comp, dashboardFileDir);
    out.append(NEWLINE);

    this.renderDatasource(out, context, comp);
    out.append(NEWLINE)
       .append(NEWLINE);

    String chartName = comp.getName();
    String compVarName = "render_" + chartName;

    out.append("cgg.render(").append(compVarName).append(");")
       .append(NEWLINE);

    String chartScript = out.toString();

    writeFile(access, chartScript, dashboardFileDir, chartName, dashboardFileName);
    // Legacy support requires to keep generating dashboard unqualified scripts as well
    writeFile(access, chartScript, dashboardFileDir, chartName,  null);
  }

   private void writeFile(
       IUserContentAccess access,
           String chartScript,
           String dashboardFileDir,
           String chartName,
           String dashboadFilName)
  {
    try
    {
      String prefix   = dashboadFilName == null ? "" : dashboadFilName.substring(0, dashboadFilName.lastIndexOf('.')) + '_';
      String fileName = prefix + chartName + CGG_EXTENSION;

      byte[] content = chartScript.getBytes(CharsetHelper.getEncoding());

      if(!access.saveFile(Utils.joinPath(dashboardFileDir, fileName), new ByteArrayInputStream(content))) {
        _logger.error("Failed to write CGG script file for chart '" + chartName + "'.");
      }
    } catch(Exception ex) {
      _logger.error("Failed to write script file for '" + chartName + "': " + ex.getCause().getMessage());
    }
  }

  private void renderChart(
          StringBuilder out,
          CggRunJsDashboardWriteContext context,
          GenericComponent comp,
          String dashDir) throws ThingWriteException
  {
    ComponentType compType = comp.getMeta();

    for(Resource resource : compType.getResources())
    {
      Resource.Type resType = resource.getType();
      switch(resType)
      {
        case RAW:
          out.append(NEWLINE);
          out.append(resource.getSource());
          out.append(NEWLINE);
          break;

        case SCRIPT:
          out.append(NEWLINE);
          out.append("load('");
          out.append(makeDashRelative(resource.getSource(), dashDir));
          out.append("');");
          out.append(NEWLINE);
          break;
      }
    }

    // Implementation
    String srcImpl = compType.getImplementationPath();
    if(StringUtils.isNotEmpty(srcImpl))
    {
      out.append(NEWLINE);
      out.append("load('");
      out.append(makeDashRelative(srcImpl, dashDir));
      out.append("');");
      out.append(NEWLINE);
    }

    // ---------------
    // TODO: HACK: Delegate writing the component definition to the corresponding CdfRunJs writer
    // Should this be done differently?
    IThingWriterFactory writerFactory = new CdfRunJsThingWriterFactory();
    IThingWriter compWriter;
    try
    {
      compWriter = writerFactory.getWriter(comp);
    }
    catch(UnsupportedThingException ex)
    {
      throw new ThingWriteException("Error while obtaining a writer for rendering the generic component.", ex);
    }

    // Options are kind of irrelevant in this context,
    // as we're only rendering one component, not a dashboard (and not a widget component).
    CdfRunJsDashboardWriteOptions options = new CdfRunJsDashboardWriteOptions(false, false, "", "");

    // Idem
    CdfRunJsDashboardWriteContext writeContext =
        CdeEngine.getInstance().getEnvironment().getCdfRunJsDashboardWriteContext(
            writerFactory,
            /*indent*/"",
            /*bypassCacheRead*/true,
            context.getDashboard(),
            options);

    compWriter.write(out, writeContext, comp);
  }

  // Both are solution dir relative.
  private static String makeDashRelative(String path, String dashDir)
  {
    // resource -> system/pentaho-cdf-dd/resources/custom/components/InteractiveCosmos/interactiveCosmos.js
    // dashDir  -> cde/ <dashboard-is-here>
    // resource must be found relative to dashDir:
    // -> ../system/pentaho-cdf-dd/...
    // Find how many times to go back
    // Remove leading and trailing /
    dashDir = dashDir.replaceAll("^[/\\\\]*(.*?)[/\\\\]*$", "$1");

    if(!dashDir.isEmpty())
    {
      int count = dashDir.split("[/\\\\]").length;
      for(int i = 0 ; i < count ; i++)
      {
        path = "../" + path;
      }
    }

    return path;
  }
  private void renderDatasource(StringBuilder out, CggRunJsDashboardWriteContext context, GenericComponent comp) throws ThingWriteException
  {
    Dashboard dash = context.getDashboard();
    String dataSourceName = comp.tryGetPropertyValue("dataSource", null);
    if(StringUtils.isNotEmpty(dataSourceName))
    {
      DataSourceComponent dsComp = dash.getDataSource(dataSourceName);

      IThingWriterFactory factory = context.getFactory();
      IThingWriter dsWriter;
      try
      {
        dsWriter = factory.getWriter(dsComp);
      }
      catch (UnsupportedThingException ex)
      {
        throw new ThingWriteException(ex);
      }

      CggRunJsComponentWriteContext compContext = new CggRunJsComponentWriteContext(factory, dash, comp);
      dsWriter.write(out, compContext, dsComp);
    }
  }
}
TOP

Related Classes of pt.webdetails.cdf.dd.model.inst.writer.cggrunjs.CggRunJsGenericComponentWriter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.