/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright (c) 2015 ForgeRock AS. All Rights Reserved * * The contents of this file are subject to the terms * of the Common Development and Distribution License * (the License). You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * http://forgerock.org/license/CDDLv1.0.html * See the License for the specific language governing * permission and limitations under the License. * * When distributing Covered Code, include this CDDL * Header Notice in each file and include the License file * at http://forgerock.org/license/CDDLv1.0.html * If applicable, add the following below the CDDL Header, * with the fields enclosed by brackets [] replaced by * your own identifying information: * "Portions Copyrighted [year] [name of copyright owner]" */ package org.forgerock.openidm.tools.scriptedbundler; import com.github.jknack.handlebars.Handlebars; import com.github.jknack.handlebars.Helper; import com.github.jknack.handlebars.Options; import com.github.jknack.handlebars.Template; import com.github.jknack.handlebars.helper.StringHelpers; import org.apache.commons.io.FileUtils; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * Generates the source files from templates using a JSON configuration for the substitution variables. Templates are * in Handlebars format. The filepaths are also processed as Handlebars templates. */ public class SourceGenerator { private final static SourceGenerator stub = new SourceGenerator(); private static final List<SourceTemplate> templates = new ArrayList<SourceTemplate>(); static { templates.addAll(Arrays.asList( new SourceTemplate("ScriptedConfiguration.template", "{{packageName}}Configuration.groovy", "./src/main/groovy/org/forgerock/openicf/connectors/{{lower packageName}}/"), new SourceTemplate("Messages.template", "Messages.properties", "./src/main/resources/org/forgerock/openicf/connectors/{{lower packageName}}/"), new SourceTemplate("pom.template", "pom.xml", "./"), new SourceTemplate("AuthenticateScript.groovy.template", "AuthenticateScript.groovy", "./src/main/resources/script/{{lower packageName}}/"), new SourceTemplate("TestScript.groovy.template", "TestScript.groovy", "./src/main/resources/script/{{lower packageName}}/"), new SourceTemplate("CreateScript.groovy.template", "CreateScript.groovy", "./src/main/resources/script/{{lower packageName}}/"), new SourceTemplate("DeleteScript.groovy.template", "DeleteScript.groovy", "./src/main/resources/script/{{lower packageName}}/"), new SourceTemplate("UpdateScript.groovy.template", "UpdateScript.groovy", "./src/main/resources/script/{{lower packageName}}/"), new SourceTemplate("SchemaScript.groovy.template", "SchemaScript.groovy", "./src/main/resources/script/{{lower packageName}}/"), new SourceTemplate("SearchScript.groovy.template", "SearchScript.groovy", "./src/main/resources/script/{{lower packageName}}/"), new SourceTemplate("SyncScript.groovy.template", "SyncScript.groovy", "./src/main/resources/script/{{lower packageName}}/"), new SourceTemplate("provisioner.openicf.json.template", "provisioner.openicf-{{lower packageName}}.json", "./src/main/resources/conf/"))); } /** * Generates all of the source files from Handlebars templates. Variables are substituted with * values found in the {@link CustomConfiguration} object. * * @param config * @throws IOException */ public static void generateSources(CustomConfiguration config) throws IOException { // Add in the appropriate Connector template templates.add(new SourceTemplate(config.getBaseConnectorType().getConnectorTemplate(), "{{packageName}}Connector.java", "./src/main/java/org/forgerock/openicf/connectors/{{lower packageName}}/")); Handlebars hb = new Handlebars(); StringHelpers.register(hb); hb.registerHelper("t", new Helper<String>() { @Override public CharSequence apply(String context, Options options) throws IOException { return "{{t \"" + context + "\"}}"; } }); for (SourceTemplate template : templates) { try { Template hbtemplate = hb.compileInline(template.getOutputName()); String outputFilename = hbtemplate.apply(config); hbtemplate = hb.compileInline(template.getOutputPath()); String outputPath = hbtemplate.apply(config); BufferedReader reader = new BufferedReader(new InputStreamReader( stub.getClass().getResourceAsStream("/" + template.getInputName()))); StringBuilder out = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { out.append(line).append("\n"); } hbtemplate = hb.compileInline(out.toString()); String contents = hbtemplate.apply(config); FileUtils.write(new File(outputPath + outputFilename), contents); } catch (Exception e) { throw new IOException("Failed to read contents of " + template.getInputName(), e); } } SourceTemplate uiTemplate = new SourceTemplate(config.getBaseConnectorType().getUITemplate(), "org.forgerock.openicf.connectors.{{lower packageName}}.{{packageName}}Connector_1.4.html", "./src/main/resources/ui/"); try { Template hbtemplate = hb.compileInline(uiTemplate.getOutputName()); String outputFilename = hbtemplate.apply(config); hbtemplate = hb.compileInline(uiTemplate.getOutputPath()); String outputPath = hbtemplate.apply(config); // Process our initial templated section of the output UI template BufferedReader reader = new BufferedReader(new InputStreamReader( stub.getClass().getResourceAsStream("/UI_base.template"))); StringBuilder out = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { out.append(line).append("\n"); } hbtemplate = hb.compileInline(out.toString()); String contents = hbtemplate.apply(config); // Append non-processed content reader = new BufferedReader(new InputStreamReader( stub.getClass().getResourceAsStream("/" + uiTemplate.getInputName()))); out = new StringBuilder(); while ((line = reader.readLine()) != null) { out.append(line).append("\n"); } contents += out.toString(); FileUtils.write(new File(outputPath + outputFilename), contents); } catch (IOException e) { throw new IOException("Failed to read contents of " + uiTemplate.getInputName(), e); } } }