| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.jackrabbit.filevault.maven.packaging; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.util.Arrays; |
| import java.util.HashSet; |
| import java.util.LinkedList; |
| import java.util.List; |
| import java.util.Set; |
| import java.util.stream.Collectors; |
| |
| import org.apache.jackrabbit.vault.fs.io.DocViewFormat; |
| import org.apache.maven.plugin.AbstractMojo; |
| import org.apache.maven.plugin.MojoExecutionException; |
| import org.apache.maven.plugin.MojoFailureException; |
| import org.apache.maven.plugin.logging.Log; |
| 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.codehaus.plexus.util.Scanner; |
| import org.jetbrains.annotations.NotNull; |
| import org.sonatype.plexus.build.incremental.BuildContext; |
| |
| /** |
| * Maven goal which either checks only the formatting of the Docview XML files to comply with the |
| * formatting rules from FileVault or also reformats those files. |
| */ |
| @Mojo( |
| name = "format-xml", |
| defaultPhase = LifecyclePhase.PROCESS_SOURCES, |
| threadSafe = true |
| ) |
| public class FormatDocviewXmlMojo extends AbstractMojo { |
| |
| /** |
| * The directory that contains the jcr_root of the content. Multiple directories can be specified as a comma separated list, |
| * which will act as a search path and cause the plugin to look for the first existing directory. |
| */ |
| @Parameter( |
| property = "vault.jcrRootSourceDirectory", |
| required = true, |
| defaultValue = |
| "${project.basedir}/jcr_root," + |
| "${project.basedir}/src/main/jcr_root," + |
| "${project.basedir}/src/main/content/jcr_root," + |
| "${project.basedir}/src/content/jcr_root," + |
| "${project.build.outputDirectory}" |
| ) |
| private File[] jcrRootSourceDirectory; |
| |
| /** |
| * Include patterns for files to include. If not set defaults to [**\/*.xml]. |
| * <p> |
| * Note: includes have precedences over excludes. |
| * Each pattern can either be an <a href="https://ant.apache.org/manual/dirtasks.html#patterns">Ant-like pattern</a> or |
| * a regular expression if it is starting with {@code %regex[} and ending with {@code ]}. |
| */ |
| @Parameter |
| protected Set<String> includes = new HashSet<>(); |
| |
| /** |
| * Exclude patterns for files to exclude. If not set defaults to []. |
| * <p> |
| * Note: includes have precedences over excludes. |
| * Each pattern can either be an <a href="https://ant.apache.org/manual/dirtasks.html#patterns">Ant-like pattern</a> or |
| * a regular expression if it is starting with {@code %regex[} and ending with {@code ]}. |
| */ |
| @Parameter |
| protected Set<String> excludes = new HashSet<>(); |
| |
| /** |
| * If set to {@code true} then fails the build if it encounters XML files which don't follow the |
| * formatting rules for XML Docview files. |
| * If set to {@code false} will reformat all XML Docview files. |
| */ |
| @Parameter(defaultValue = "false") |
| private boolean validateOnly; |
| |
| /** |
| * If set to {@code true} will also run on incremental builds (i.e. within Eclipse with m2e). |
| * Otherwise this goal is skipped in incremental builds and only runs on full builds. |
| */ |
| @Parameter(defaultValue = "false") |
| private boolean enableForIncrementalBuild; |
| |
| @Component |
| protected BuildContext buildContext; |
| |
| private static final String MSG_MALFORMED_FILE = "Malformed according to DocView format"; |
| private static final String MSG_COUNTERMEASURE = "Use either your IDE with JCR-VLT integration to sync files with the repository or use vlt-cli to apply the docview format " + |
| "(http://jackrabbit.apache.org/filevault/usage.html)."; |
| |
| public void execute() throws MojoExecutionException, MojoFailureException { |
| if (buildContext.isIncremental() && !enableForIncrementalBuild) { |
| getLog().info("Skip executing mojo 'format-xml' for incremental builds as parameter 'enableForIncrementalBuilds' is set to 'false'"); |
| } else { |
| File jcrSourceDirectory = AbstractSourceAndMetadataPackageMojo.getFirstExistingDirectory(jcrRootSourceDirectory); |
| if (jcrSourceDirectory != null) { |
| executeInternal(jcrSourceDirectory); |
| } else { |
| if (getLog().isDebugEnabled()) { |
| getLog().debug("None of the configured jcrRootSourceDirectory directories exists, skipping: " + |
| Arrays.stream(jcrRootSourceDirectory).map(File::toString).collect(Collectors.joining(", "))); |
| } |
| } |
| } |
| } |
| |
| protected void executeInternal(@NotNull File sourceDirectory) |
| throws MojoExecutionException, MojoFailureException { |
| |
| if (includes.isEmpty()) { |
| includes.add("**/*.xml"); |
| } |
| |
| Log log = getLog(); |
| List<File> malformedFiles = new LinkedList<>(); |
| DocViewFormat docViewFormat = new DocViewFormat(); |
| Scanner directoryScanner = buildContext.newScanner(sourceDirectory); |
| directoryScanner.setIncludes(includes.toArray(new String[includes.size()])); |
| directoryScanner.setExcludes(excludes.toArray(new String[excludes.size()])); |
| directoryScanner.scan(); |
| |
| for (String subpath : directoryScanner.getIncludedFiles()) { |
| File toCheck = new File(sourceDirectory, subpath); |
| try { |
| if (docViewFormat.format(toCheck, validateOnly)) { |
| if (validateOnly) { |
| // collect all malformed files to emit one failure at the end |
| malformedFiles.add(toCheck); |
| // emit violations for m2e (https://www.eclipse.org/m2e/documentation/m2e-making-maven-plugins-compat.html) |
| buildContext.addMessage(toCheck, 0, 0, MSG_MALFORMED_FILE + ". " + MSG_COUNTERMEASURE, BuildContext.SEVERITY_ERROR, null); |
| log.error(MSG_MALFORMED_FILE + ":" + toCheck); |
| } else { |
| log.info("Reformatted file '" + toCheck + "'."); |
| } |
| } else { |
| buildContext.removeMessages(toCheck); |
| } |
| } catch (IOException ex) { |
| throw new MojoExecutionException("Failed to read " + toCheck, ex); |
| } |
| } |
| |
| if (!malformedFiles.isEmpty()) { |
| String message = "Found " + malformedFiles.size() + " files being malformed according to DocView format: Please check error message emitted above." + |
| "\n\n" + MSG_COUNTERMEASURE; |
| throw new MojoFailureException(message); |
| } |
| } |
| } |