# WatermarkingMojo.java

    package org.thewonderlemming.c4plantuml.mojo;

    import java.io.IOException;
    import java.nio.file.Files;
    import java.nio.file.Path;
    import java.time.LocalDate;
    import java.time.format.DateTimeFormatter;

    import org.apache.maven.plugin.MojoExecutionException;
    import org.apache.maven.plugin.MojoFailureException;
    import org.apache.maven.plugins.annotations.LifecyclePhase;
    import org.apache.maven.plugins.annotations.Mojo;
    import org.apache.maven.plugins.annotations.Parameter;

    /**
     * A MOJO that adds a watermark to the C4 PlantUML files that are contained in the output directory, allowing the
     * generated schemas to hold information on the generation date, the build version and so on.
     *
     * @author thewonderlemming
     *
     */
    @Mojo(name = "watermark", defaultPhase = LifecyclePhase.PROCESS_CLASSES)
    public class WatermarkingMojo extends AbstractParentMojo {

        /**
         * Default copyright name, if none is provided.
         * <p>
         * It is the default value for the {@code copyrightName} property.
         */
        public static final String DEFAULT_COPYRIGHT_NAME = "";

        /**
         * Default format for the date, if an invalid formatting pattern or no pattern is provided.
         * <p>
         * It defaults to {@code DateTimeFormatter.ISO_DATE}.
         */
        public static final DateTimeFormatter DEFAULT_DATE_FORMATTER = DateTimeFormatter.ISO_DATE;

        /**
         * Default diagram name, if none is provided.
         * <p>
         * It is the default value for the {@code watermarkName} property.
         */
        public static final String DEFAULT_WATERMARK_NAME = "changeMe";

        /**
         * Watermark string pattern.
         */
        public static final String WATERMARK_FORMAT_STRING = "FOOTER(\"Version %s - Generated on %s - \u00a9%d %s\", \"%s\")";

        private static final String END_UML_TAG = "@enduml";

        @Parameter(property = "copyrightName", defaultValue = DEFAULT_COPYRIGHT_NAME, alias = "copyrightName")
        private String copyrightName;

        @Parameter(property = "dateFormat", defaultValue = "", alias = "dateFormat")
        private String dateFormat;

        @Parameter(property = "watermarkName", defaultValue = DEFAULT_WATERMARK_NAME, alias = "watermarkName")
        private String watermarkName;

        /**
         * Adds watermark to the C4 PlantUML files contained in the output directory.
         * <p>
         * {@inheritDoc}
         */
        @Override
        protected void doExecute() throws MojoExecutionException, MojoFailureException {

            try {

                processOutputDirectory();

            } catch (final IOException e) {

                final String errMsg = "Cannot process output directory \"" + getOutputDirectory() + "\" for watermaking";
                throw new MojoFailureException(errMsg, e);
            }
        }

        private void addWatermarkToFile(final Path file) throws IOException {

            assert (getCurrentCharset() != null) : "Expected currentCharset to be set";
            assert (file != null && file.toFile().exists()) : "Expected given path to exist";
            assert (file.toFile().isFile()) : "Expected given path to be a file";

            final String content = new String(Files.readAllBytes(file), getCurrentCharset())
                .replace(END_UML_TAG, generateWatermarkString() + "\n" + END_UML_TAG);

            Files.write(file, content.getBytes(getCurrentCharset()));
        }

        private String generateWatermarkString() {

            final LocalDate currentDate = LocalDate.now();
            final String diagramVersion = getProject().getVersion();
            final String diagramName = this.watermarkName.isEmpty()
                ? getProject().getGroupId() + ":" + getProject().getArtifactId()
                : this.watermarkName;

            return String
                .format(WATERMARK_FORMAT_STRING,
                    diagramVersion,
                    currentDate.format(getDateTimeFormatter()),
                    currentDate.getYear(),
                    this.copyrightName != null ? this.copyrightName : "",
                    diagramName);
        }

        private DateTimeFormatter getDateTimeFormatter() {

            try {

                return null != dateFormat
                    ? DateTimeFormatter.ofPattern(this.dateFormat)
                    : DEFAULT_DATE_FORMATTER;

            } catch (final IllegalArgumentException e) {
                return DEFAULT_DATE_FORMATTER;
            }
        }

        private void processOutputDirectory() throws IOException {

            assert (getOutputDirectory() != null) : "Expected outputDirectory to be set";

            processOutputDirectoryFiles(path -> {

                try {

                    addWatermarkToFile(path);

                } catch (final IOException e) {
                    getLog().error("Cannot add watermark to file: " + path, e);
                }
            });
        }
    }