package ch.sbb.maven.plugins.iib.mojos; import static org.twdata.maven.mojoexecutor.MojoExecutor.artifactId; import static org.twdata.maven.mojoexecutor.MojoExecutor.configuration; import static org.twdata.maven.mojoexecutor.MojoExecutor.element; import static org.twdata.maven.mojoexecutor.MojoExecutor.executeMojo; import static org.twdata.maven.mojoexecutor.MojoExecutor.executionEnvironment; import static org.twdata.maven.mojoexecutor.MojoExecutor.goal; import static org.twdata.maven.mojoexecutor.MojoExecutor.groupId; import static org.twdata.maven.mojoexecutor.MojoExecutor.name; import static org.twdata.maven.mojoexecutor.MojoExecutor.plugin; import static org.twdata.maven.mojoexecutor.MojoExecutor.version; import java.io.File; import java.io.IOException; import java.util.List; import org.apache.commons.io.FilenameUtils; import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.BuildPluginManager; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Component; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.project.MavenProject; import org.codehaus.plexus.util.FileUtils; import ch.sbb.maven.plugins.iib.utils.ApplyBarOverride; import ch.sbb.maven.plugins.iib.utils.ConfigurableProperties; import ch.sbb.maven.plugins.iib.utils.ReadBar; /** * Validates override .properties files and (optionally) applies them to the default .bar file. */ @Mojo(name = "apply-bar-overrides", defaultPhase = LifecyclePhase.PROCESS_CLASSES) public class ApplyBarOverridesMojo extends AbstractMojo { /** * Projects containing files to include in the BAR file in the workspace. Required for a new workspace. */ @Parameter(property = "iib.applicationName") protected String applicationName; /** * Whether the applybaroverride command should be executed or not */ @Parameter(property = "iib.applybaroverrides", defaultValue = "true", required = true) protected Boolean applyBarOverrides; /** * Whether the applybaroverride command should be executed or not */ @Parameter(property = "iib.applyBarOverrideRecursively", defaultValue = "true", required = true) protected Boolean applyBarOverrideRecursively; /** * The basename of the trace file to use when applybaroverriding bar files */ @Parameter(property = "iib.applyBarOverrideTraceFile", defaultValue = "${project.build.directory}/applybaroverridetrace.txt", required = true) protected File applyBarOverrideTraceFile; /** * The name of the BAR (compressed file format) archive file where the result is stored. * */ @Parameter(property = "iib.barName", defaultValue = "${project.build.directory}/iib/${project.artifactId}-${project.version}.bar", required = true) protected File barName; /** * The name of the default properties file to be generated from the bar file. * */ @Parameter(property = "iib.defaultPropertiesFile", defaultValue = "${project.build.directory}/iib/default.properties", required = true) protected File defaultPropertiesFile; /** * Whether or not to fail the build if properties are found to be invalid. */ @Parameter(property = "iib.failOnInvalidProperties", defaultValue = "true", required = true) protected Boolean failOnInvalidProperties; /** * Appends the _ (underscore) character and the value of VersionString to the names of the compiled versions of the message flows (.cmf) files added to the BAR file, before the file extension. */ @Parameter(property = "iib.versionString", defaultValue = "${project.version}") protected String versionString; /** * The Maven Project Object */ @Parameter(property = "project", required = true, readonly = true) protected MavenProject project; /** * The Maven Session Object */ @Parameter(property = "session", required = true, readonly = true) protected MavenSession session; /** * The Maven PluginManager Object */ @Component protected BuildPluginManager buildPluginManager; public void execute() throws MojoFailureException { copyAndFilterResources(); getLog().info("Reading bar file: " + barName); ConfigurableProperties overridableProperties; try { overridableProperties = getOverridableProperties(); } catch (IOException e) { throw new MojoFailureException("Error extracting configurable properties from bar file: " + barName.getAbsolutePath(), e); } writeToFile(overridableProperties, defaultPropertiesFile); validatePropertiesFiles(overridableProperties); if (applyBarOverrides) { executeApplyBarOverrides(); } } private void copyAndFilterResources() throws MojoFailureException { getLog().debug("Project Build Resources: " + project.getBuild().getResources().toString()); try { // copy the main resources executeMojo(plugin(groupId("org.apache.maven.plugins"), artifactId("maven-resources-plugin"), version("2.6")), goal("copy-resources"), configuration(element(name("outputDirectory"), "${project.build.directory}/iib"), element(name("resources"), element(name("resource"), // TODO hard-coding this isn't great form // see also ValidateConfigurablePropertiesMojo.java element(name("directory"), "src/main/resources"), element(name("filtering"), "true")))), executionEnvironment(project, session, buildPluginManager)); // copy the test resources executeMojo(plugin(groupId("org.apache.maven.plugins"), artifactId("maven-resources-plugin"), version("2.6")), goal("copy-resources"), configuration(element(name("outputDirectory"), "${project.build.directory}/iib-test"), element(name("resources"), element(name("resource"), // TODO hard-coding this isn't great form // see also ValidateConfigurablePropertiesMojo.java element(name("directory"), "src/test/resources"), element(name("filtering"), "true")))), executionEnvironment(project, session, buildPluginManager)); } catch (MojoExecutionException e) { // TODO handle exception throw new MojoFailureException("Error while copying and filtering resources", e); } } private void executeApplyBarOverrides() throws MojoFailureException { for (File propFile : getTargetPropertiesFiles()) { String targetBarFilename = (new File(propFile.getParent(), FilenameUtils.getBaseName(propFile.getName()).concat(".bar"))).getAbsolutePath(); try { ApplyBarOverride.applyBarOverride(barName.getAbsolutePath(), propFile.getAbsolutePath(), targetBarFilename); } catch (IOException e) { // TODO handle exception throw new MojoFailureException("Error applying properties file " + propFile.getAbsolutePath(), e); } } } /** * @param propFile the name of the apply bar override property file * @return the value to be passed to the (-v) Trace parameter on the command line */ protected String getTraceFileParameter(File propFile) { String filename = FilenameUtils.getBaseName(applyBarOverrideTraceFile.getAbsolutePath()) + "-" + FilenameUtils.getBaseName(propFile.getName()) + ".txt"; String directory = applyBarOverrideTraceFile.getParent(); return new File(directory, filename).getAbsolutePath(); } private void validatePropertiesFiles(ConfigurableProperties overrideableProperties) throws MojoFailureException { boolean invalidPropertiesFound = false; List<File> propFiles = null; propFiles = getTargetPropertiesFiles(); getLog().info("Validating properties files"); for (File file : propFiles) { getLog().info(" " + file.getAbsolutePath()); try { ConfigurableProperties definedProps = new ConfigurableProperties(); definedProps.load(defaultPropertiesFile); // check if all the defined properties are valid if (!overrideableProperties.keySet().containsAll(definedProps.keySet())) { getLog().error("Invalid properties found in " + file.getAbsolutePath()); invalidPropertiesFound = true; // list the invalid properties in this file for (Object definedProp : definedProps.keySet()) { if (!overrideableProperties.containsKey(ConfigurableProperties.getPropName((String) definedProp))) { getLog().error(" " + definedProp); } } } } catch (IOException e) { throw new MojoFailureException("Error loading properties file: " + file.getAbsolutePath(), e); } } if (failOnInvalidProperties && invalidPropertiesFound) { throw new MojoFailureException("Invalid properties were found"); } } private void writeToFile(ConfigurableProperties configurableProperties, File file) throws MojoFailureException { getLog().info("Writing overridable properties to: " + defaultPropertiesFile.getAbsolutePath()); try { configurableProperties.save(defaultPropertiesFile); } catch (IOException e) { throw new MojoFailureException("Error writing properties file: " + file.getAbsolutePath(), e); } } /** * @return a sorted list of properties that can be overriden for a given bar file * @throws IOException */ protected ConfigurableProperties getOverridableProperties() throws IOException { return ReadBar.getOverridableProperties(barName.getAbsolutePath()); } @SuppressWarnings("unchecked") private List<File> getTargetPropertiesFiles() throws MojoFailureException { List<File> propFiles = null; File targetIibDirectory = new File(project.getBuild().getDirectory(), "iib"); try { // TODO hard-coding this isn't great form // see also PrepareIibBarPackagingMojo.java propFiles = FileUtils.getFiles(targetIibDirectory, "*.properties", "default.properties"); File targetIibTestDir = new File(project.getBuild().getDirectory(), "iib-test"); if (targetIibTestDir.canRead()) { propFiles.addAll(FileUtils.getFiles(targetIibTestDir, "*.properties", "")); } } catch (IOException e) { // TODO handle exception throw new MojoFailureException("Error searching for properties files under " + targetIibDirectory, e); } return propFiles; } }