    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one or more
    003 * contributor license agreements.  See the NOTICE file distributed with
    004 * this work for additional information regarding copyright ownership.
    005 * The ASF licenses this file to You under the Apache License, Version 2.0
    006 * (the "License"); you may not use this file except in compliance with
    007 * the License.  You may obtain a copy of the License at
    008 *
    009 *      https://www.apache.org/licenses/LICENSE-2.0
    010 *
    011 * Unless required by applicable law or agreed to in writing, software
    012 * distributed under the License is distributed on an "AS IS" BASIS,
    013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014 * See the License for the specific language governing permissions and
    015 * limitations under the License.
    016 */
    017package org.apache.commons.release.plugin.velocity;
    018
    019import java.io.Writer;
    020
    021import org.apache.commons.lang3.StringUtils;
    022import org.apache.velocity.Template;
    023import org.apache.velocity.VelocityContext;
    024import org.apache.velocity.app.VelocityEngine;
    025import org.apache.velocity.runtime.RuntimeConstants;
    026import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
    027
    028/**
    029 * This class' purpose is to generate the <code>README.html</code> that moves along with the
    030 * release for the sake of downloading the release from the distribution area.
    031 *
    032 * @since 1.3
    033 */
    034public final class ReadmeHtmlVelocityDelegate {
    035
    036    /**
    037     * A builder class for instantiation of the {@link ReadmeHtmlVelocityDelegate}.
    038     */
    039    public static final class ReadmeHtmlVelocityDelegateBuilder {
    040
    041        /** The maven artifactId to use in the <code>README.vm</code> template. */
    042        private String artifactId;
    043
    044        /** The maven version to use in the <code>README.vm</code> template. */
    045        private String version;
    046
    047        /** The site url to use in the <code>README.vm</code> template. */
    048        private String siteUrl;
    049
    050        /**
    051         * Private constructor for using the builder through the {@link ReadmeHtmlVelocityDelegate#builder()}
    052         * method.
    053         */
    054        private ReadmeHtmlVelocityDelegateBuilder() {
    055        }
    056
    057        /**
    058         * Builds up the {@link ReadmeHtmlVelocityDelegate} from the previously set parameters.
    059         *
    060         * @return a new {@link ReadmeHtmlVelocityDelegate}.
    061         */
    062        public ReadmeHtmlVelocityDelegate build() {
    063            return new ReadmeHtmlVelocityDelegate(this.artifactId, this.version, this.siteUrl);
    064        }
    065
    066        /**
    067         * Adds the artifactId to the {@link ReadmeHtmlVelocityDelegate}.
    068         *
    069         * @param artifactId the {@link String} representing the maven artifactId.
    070         * @return the builder to continue building.
    071         */
    072        public ReadmeHtmlVelocityDelegateBuilder withArtifactId(final String artifactId) {
    073            this.artifactId = artifactId;
    074            return this;
    075        }
    076
    077        /**
    078         * Adds the siteUrl to the {@link ReadmeHtmlVelocityDelegate}.
    079         *
    080         * @param siteUrl the site url to be used in the <code>README.html</code>
    081         * @return the builder to continue building.
    082         */
    083        public ReadmeHtmlVelocityDelegateBuilder withSiteUrl(final String siteUrl) {
    084            this.siteUrl = siteUrl;
    085            return this;
    086        }
    087
    088        /**
    089         * Adds the version to the {@link ReadmeHtmlVelocityDelegate}.
    090         *
    091         * @param version the maven version.
    092         * @return the builder to continue building.
    093         */
    094        public ReadmeHtmlVelocityDelegateBuilder withVersion(final String version) {
    095            this.version = version;
    096            return this;
    097        }
    098    }
    099
    100    /** The location of the velocity template for this class. */
    101    private static final String TEMPLATE = "resources/org/apache/commons/release/plugin"
    102                                         + "/velocity/README.vm";
    103
    104    /**
    105     * Gets the {@link ReadmeHtmlVelocityDelegateBuilder} for constructing the {@link ReadmeHtmlVelocityDelegate}.
    106     *
    107     * @return the {@link ReadmeHtmlVelocityDelegateBuilder}.
    108     */
    109    public static ReadmeHtmlVelocityDelegateBuilder builder() {
    110        return new ReadmeHtmlVelocityDelegateBuilder();
    111    }
    112
    113    /** This is supposed to represent the maven artifactId. */
    114    private final String artifactId;
    115
    116    /** This is supposed to represent the maven version of the release. */
    117    private final String version;
    118
    119    /** The url of the site that gets set into the <code>README.html</code>. */
    120    private final String siteUrl;
    121
    122    /**
    123     * The private constructor to be used by the {@link ReadmeHtmlVelocityDelegateBuilder}.
    124     *
    125     * @param artifactId sets the {@link ReadmeHtmlVelocityDelegate#artifactId}.
    126     * @param version sets the {@link ReadmeHtmlVelocityDelegate#version}.
    127     * @param siteUrl sets the {@link ReadmeHtmlVelocityDelegate#siteUrl}.
    128     */
    129    private ReadmeHtmlVelocityDelegate(final String artifactId, final String version, final String siteUrl) {
    130        this.artifactId = artifactId;
    131        this.version = version;
    132        this.siteUrl = siteUrl;
    133    }
    134
    135    /**
    136     * Renders the <code>README.vm</code> velocity template with the variables constructed with the
    137     * {@link ReadmeHtmlVelocityDelegateBuilder}.
    138     *
    139     * @param writer is the {@link Writer} to which we wish to render the <code>README.vm</code> template.
    140     * @return a reference to the {@link Writer} passed in.
    141     */
    142    public Writer render(final Writer writer) {
    143        final VelocityEngine ve = new VelocityEngine();
    144        ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
    145        ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
    146        ve.init();
    147        final Template template = ve.getTemplate(TEMPLATE);
    148        final String[] splitArtifactId = artifactId.split("-");
    149        final String wordCommons = "commons";
    150        String artifactShortName = "";
    151        if (splitArtifactId.length > 1) {
    152            artifactShortName = splitArtifactId[1];
    153        } else if (splitArtifactId.length == 1) {
    154            artifactShortName = splitArtifactId[0];
    155        }
    156        // ".+\\d$" matches a non-empty string that terminates in a digit {0-9}.
    157        if (artifactShortName.matches(".+\\d$")) {
    158            artifactShortName = artifactShortName.substring(0, artifactShortName.length() - 1);
    159        }
    160        final String artifactIdWithFirstLetterscapitalized =
    161                StringUtils.capitalize(wordCommons)
    162                        + "-"
    163                        + artifactShortName.toUpperCase();
    164        final VelocityContext context = new VelocityContext();
    165        context.internalPut("artifactIdWithFirstLetterscapitalized", artifactIdWithFirstLetterscapitalized);
    166        context.internalPut("artifactShortName", artifactShortName.toUpperCase());
    167        context.internalPut("artifactId", artifactId);
    168        context.internalPut("version", version);
    169        context.internalPut("siteUrl", siteUrl);
    170        template.merge(context, writer);
    171        return writer;
    172    }
    173}