View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.release.plugin.velocity;
18  
19  import java.io.Writer;
20  
21  import org.apache.commons.lang3.StringUtils;
22  import org.apache.velocity.Template;
23  import org.apache.velocity.VelocityContext;
24  import org.apache.velocity.app.VelocityEngine;
25  import org.apache.velocity.runtime.RuntimeConstants;
26  import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
27  
28  /**
29   * This class' purpose is to generate the <code>README.html</code> that moves along with the
30   * release for the sake of downloading the release from the distribution area.
31   *
32   * @since 1.3
33   */
34  public final class ReadmeHtmlVelocityDelegate {
35  
36      /**
37       * A builder class for instantiation of the {@link ReadmeHtmlVelocityDelegate}.
38       */
39      public static final class ReadmeHtmlVelocityDelegateBuilder {
40  
41          /** The maven artifactId to use in the <code>README.vm</code> template. */
42          private String artifactId;
43  
44          /** The maven version to use in the <code>README.vm</code> template. */
45          private String version;
46  
47          /** The site url to use in the <code>README.vm</code> template. */
48          private String siteUrl;
49  
50          /**
51           * Private constructor for using the builder through the {@link ReadmeHtmlVelocityDelegate#builder()}
52           * method.
53           */
54          private ReadmeHtmlVelocityDelegateBuilder() {
55          }
56  
57          /**
58           * Builds up the {@link ReadmeHtmlVelocityDelegate} from the previously set parameters.
59           *
60           * @return a new {@link ReadmeHtmlVelocityDelegate}.
61           */
62          public ReadmeHtmlVelocityDelegate build() {
63              return new ReadmeHtmlVelocityDelegate(this.artifactId, this.version, this.siteUrl);
64          }
65  
66          /**
67           * Adds the artifactId to the {@link ReadmeHtmlVelocityDelegate}.
68           *
69           * @param artifactId the {@link String} representing the maven artifactId.
70           * @return the builder to continue building.
71           */
72          public ReadmeHtmlVelocityDelegateBuilder withArtifactId(final String artifactId) {
73              this.artifactId = artifactId;
74              return this;
75          }
76  
77          /**
78           * Adds the siteUrl to the {@link ReadmeHtmlVelocityDelegate}.
79           *
80           * @param siteUrl the site url to be used in the <code>README.html</code>
81           * @return the builder to continue building.
82           */
83          public ReadmeHtmlVelocityDelegateBuilder withSiteUrl(final String siteUrl) {
84              this.siteUrl = siteUrl;
85              return this;
86          }
87  
88          /**
89           * Adds the version to the {@link ReadmeHtmlVelocityDelegate}.
90           *
91           * @param version the maven version.
92           * @return the builder to continue building.
93           */
94          public ReadmeHtmlVelocityDelegateBuilder withVersion(final String version) {
95              this.version = version;
96              return this;
97          }
98      }
99  
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 }