Java tutorial
/* 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.cdfrunjs.dashboard; import java.io.IOException; import java.text.MessageFormat; import java.util.regex.Matcher; import org.apache.commons.jxpath.JXPathContext; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import pt.webdetails.cdf.dd.CdeConstants; import pt.webdetails.cdf.dd.CdeEngine; import pt.webdetails.cdf.dd.model.core.*; import pt.webdetails.cdf.dd.model.core.writer.*; import pt.webdetails.cdf.dd.model.core.writer.js.*; import pt.webdetails.cdf.dd.model.inst.*; import pt.webdetails.cdf.dd.render.DependenciesManager; import pt.webdetails.cdf.dd.render.DependenciesManager.StdPackages; import pt.webdetails.cdf.dd.render.RenderLayout; import pt.webdetails.cdf.dd.render.Renderer; import pt.webdetails.cdf.dd.structure.DashboardWcdfDescriptor; import pt.webdetails.cdf.dd.util.CdeEnvironment; import pt.webdetails.cdf.dd.util.Utils; import pt.webdetails.cpf.Util; import pt.webdetails.cpf.packager.StringFilter; /** * @author dcleao */ public abstract class CdfRunJsDashboardWriter extends JsWriterAbstract implements IThingWriter { private static final Log logger = LogFactory.getLog(CdfRunJsDashboardWriter.class); private static final String EPILOGUE = wrapJsScriptTags("Dashboards.init();"); // ------------ public void write(Object output, IThingWriteContext context, Thing t) throws ThingWriteException { this.write((CdfRunJsDashboardWriteResult.Builder) output, (CdfRunJsDashboardWriteContext) context, (Dashboard) t); } public abstract String getType(); public void write(CdfRunJsDashboardWriteResult.Builder builder, CdfRunJsDashboardWriteContext ctx, Dashboard dash) throws ThingWriteException { assert dash == ctx.getDashboard(); DashboardWcdfDescriptor wcdf = dash.getWcdf(); // ------------ String template; try { template = this.readTemplate(wcdf); } catch (IOException ex) { throw new ThingWriteException("Could not read style template file.", ex); } template = ctx.replaceTokens(template); // ------------ String footer; try { footer = Util.toString( CdeEnvironment.getPluginSystemReader().getFileInputStream(CdeConstants.RESOURCE_FOOTER)); } catch (IOException ex) { throw new ThingWriteException("Could not read footer file.", ex); } // ------------ String layout = ctx.replaceTokensAndAlias(this.writeLayout(ctx, dash)); String components = ctx.replaceTokensAndAlias(this.writeComponents(ctx, dash)); String content = writeContent(layout, components); String header = ctx.replaceTokens(writeHeaders(content, ctx)); // Leave the DASHBOARD_HEADER_TAG to replace additional stuff on render. template = template .replaceAll(CdeConstants.DASHBOARD_HEADER_TAG, Matcher.quoteReplacement(header) + CdeConstants.DASHBOARD_HEADER_TAG) .replaceAll(CdeConstants.DASHBOARD_FOOTER_TAG, Matcher.quoteReplacement(footer)) .replaceAll(CdeConstants.DASHBOARD_CONTENT_TAG, Matcher.quoteReplacement(content)); // Export builder.setTemplate(template).setHeader(header).setLayout(layout).setComponents(components) .setContent(content).setFooter(footer).setLoadedDate(ctx.getDashboard().getSourceDate()); } protected String readTemplate(DashboardWcdfDescriptor wcdf) throws IOException { return readStyleTemplateOrDefault(wcdf.getStyle()); } // ----------------- protected String writeLayout(CdfRunJsDashboardWriteContext context, Dashboard dash) { // TODO: HACK: uses pass-through XPath node... if (dash.getLayoutCount() == 1) { JXPathContext docXP = dash.getLayout("TODO").getLayoutXPContext(); try { return getLayoutRenderer(docXP, context).render(context.getOptions().getAliasPrefix()); } catch (Exception ex) { logger.error("Error rendering layout", ex); } } return ""; } protected Renderer getLayoutRenderer(JXPathContext docXP, CdfRunJsDashboardWriteContext context) { return new RenderLayout(docXP, context); } // ----------------- protected String writeComponents(CdfRunJsDashboardWriteContext context, Dashboard dash) throws ThingWriteException { DashboardWcdfDescriptor wcdf = dash.getWcdf(); StringBuilder out = new StringBuilder(); StringBuilder widgetsOut = new StringBuilder(); // Output WCDF out.append("wcdfSettings = "); out.append(wcdf.toJSON().toString(2)); out.append(';'); out.append(NEWLINE); out.append(NEWLINE); boolean isFirstComp = true; StringBuilder addCompIds = new StringBuilder(); boolean isFirstAddComp = true; IThingWriterFactory factory = context.getFactory(); Iterable<Component> comps = dash.getRegulars(); for (Component comp : comps) { if (StringUtils.isNotEmpty(comp.getName())) { IThingWriter writer; try { writer = factory.getWriter(comp); } catch (UnsupportedThingException ex) { throw new ThingWriteException(ex); } boolean isWidget = comp instanceof WidgetComponent; StringBuilder out2 = isWidget ? widgetsOut : out; if (!isFirstComp) { out2.append(NEWLINE); } // NOTE: Widgets don't really exist at runtime, // only their (leaf-)content does. if (comp instanceof VisualComponent && !(comp instanceof WidgetComponent)) { if (isFirstAddComp) { isFirstAddComp = false; } else { addCompIds.append(", "); } addCompIds.append(context.getId(comp)); } writer.write(out2, context, comp); isFirstComp = false; } } if (!isFirstAddComp) { out.append(NEWLINE); out.append("Dashboards.addComponents(["); out.append(addCompIds); out.append("]);"); out.append(NEWLINE); } out.append(widgetsOut); return out.toString(); } // ----------------- protected String writeHeaders(String contents, CdfRunJsDashboardWriteContext context) { CdfRunJsDashboardWriteOptions options = context.getOptions(); DashboardWcdfDescriptor wcdf = context.getDashboard().getWcdf(); final String title = "<title>" + wcdf.getTitle() + "</title>"; // Get CDF headers String cdfDeps; try { cdfDeps = CdeEngine.getEnv().getCdfIncludes(contents, this.getType(), options.isDebug(), options.isAbsolute(), options.getAbsRoot(), options.getScheme()); } catch (Exception ex) { logger.error("Failed to get cdf includes"); cdfDeps = ""; } // Get CDE headers final String baseUrl = (options.isAbsolute() ? (!StringUtils.isEmpty(options.getAbsRoot()) ? options.getSchemedRoot() + "/" : CdeEngine.getInstance().getEnvironment().getUrlProvider().getWebappContextRoot()) : ""); // + // ; StringFilter cssFilter = new StringFilter() { public String filter(String input) { return String.format("\t\t<link href=\"%s%s\" rel=\"stylesheet\" type=\"text/css\" />\n", baseUrl, baseUrl.endsWith("/") && input.startsWith("/") ? input.replaceFirst("/", "") : input); } public String filter(String input, String baseUrl) { return String.format("\t\t<link href=\"%s%s\" rel=\"stylesheet\" type=\"text/css\" />\n", baseUrl, baseUrl.endsWith("/") && input.startsWith("/") ? input.replaceFirst("/", "") : input); } }; StringFilter jsFilter = new StringFilter() { public String filter(String input) { return String.format( "\t\t<script language=\"javascript\" type=\"text/javascript\" src=\"%s%s\"></script>\n", baseUrl, baseUrl.endsWith("/") && input.startsWith("/") ? input.replaceFirst("/", "") : input); } public String filter(String input, String baseUrl) { return String.format( "\t\t<script language=\"javascript\" type=\"text/javascript\" src=\"%s%s\"></script>\n", baseUrl, baseUrl.endsWith("/") && input.startsWith("/") ? input.replaceFirst("/", "") : input); } }; DependenciesManager depMgr = DependenciesManager.getInstance(); boolean isPackaged = !options.isDebug(); String scriptDeps = depMgr.getPackage(StdPackages.COMPONENT_DEF_SCRIPTS).getDependencies(jsFilter, isPackaged); String styleDeps = depMgr.getPackage(StdPackages.COMPONENT_STYLES).getDependencies(cssFilter, isPackaged); String rawDeps = depMgr.getPackage(StdPackages.COMPONENT_SNIPPETS).getRawDependencies(false); return title + cdfDeps + rawDeps + scriptDeps + styleDeps; } // ----------------- protected static String readStyleTemplateOrDefault(String styleName) throws IOException { if (StringUtils.isNotEmpty(styleName)) { try { return readStyleTemplate(styleName); } catch (IOException ex) { } } // Couldn't open template file, attempt to use default return readStyleTemplate(CdeConstants.DEFAULT_STYLE); } protected static String readStyleTemplate(String styleName) throws IOException { return readTemplateFile( CdeEnvironment.getPluginResourceLocationManager().getStyleResourceLocation(styleName)); } protected static String readTemplateFile(String templateFile) throws IOException { try { if (CdeEnvironment.getPluginRepositoryReader().fileExists(templateFile)) { // template is in solution repository return Util.toString(CdeEnvironment.getPluginRepositoryReader().getFileInputStream(templateFile)); } else if (CdeEnvironment.getPluginSystemReader().fileExists(templateFile)) { // template is in system return Util.toString(CdeEnvironment.getPluginSystemReader().getFileInputStream(templateFile)); } else if (Utils.getAppropriateReadAccess(templateFile).fileExists(templateFile)) { return Util.toString(Utils.getAppropriateReadAccess(templateFile).getFileInputStream(templateFile)); } else { // last chance : template is in user-defined folder return Util.toString(CdeEnvironment.getUserContentAccess().getFileInputStream(templateFile)); } } catch (IOException ex) { logger.error(MessageFormat.format("Couldn't open template file '{0}'.", templateFile), ex); throw ex; } } private String writeContent(String layout, String components) { StringBuilder out = new StringBuilder(); out.append(layout); wrapJsScriptTags(out, components); out.append(EPILOGUE); return out.toString(); } }