View Javadoc

1   /*
2    * Copyright 2006-2012 smartics, Kronseder & Reiner GmbH
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package de.smartics.maven.plugin.buildmetadata.common;
17  
18  import java.util.ArrayList;
19  import java.util.Arrays;
20  import java.util.Collections;
21  import java.util.HashSet;
22  import java.util.List;
23  import java.util.Map;
24  import java.util.Properties;
25  import java.util.Set;
26  
27  import org.codehaus.plexus.util.StringUtils;
28  
29  /**
30   * Constants used in this package.
31   *
32   * @author <a href="mailto:robert.reiner@smartics.de">Robert Reiner</a>
33   * @version $Revision: 8936 $
34   */
35  public final class Constant
36  {
37    // ********************************* Fields *********************************
38  
39    // --- constants ------------------------------------------------------------
40  
41    // ... sections .............................................................
42  
43    /**
44     * The name of the SCM section.
45     * <p>
46     * The value of this constant is {@value}.
47     * </p>
48     */
49    public static final String SECTION_BUILD_SCM = "build.scm";
50  
51    /**
52     * The name of the artifact section.
53     * <p>
54     * The value of this constant is {@value}.
55     * </p>
56     */
57    public static final String SECTION_ARTIFACT = "build.artifact";
58  
59    /**
60     * The name of the build date section.
61     * <p>
62     * The value of this constant is {@value}.
63     * </p>
64     */
65    public static final String SECTION_BUILD_DATE = "build.timeAndDate";
66  
67    /**
68     * The name of the runtime build section.
69     * <p>
70     * The value of this constant is {@value}.
71     * </p>
72     */
73    public static final String SECTION_BUILD_RUNTIME = "build.runtime";
74  
75    /**
76     * The name of the Java build section.
77     * <p>
78     * The value of this constant is {@value}.
79     * </p>
80     */
81    public static final String SECTION_BUILD_JAVA = "build.java";
82  
83    /**
84     * The name of the Maven build section.
85     * <p>
86     * The value of this constant is {@value}.
87     * </p>
88     */
89    public static final String SECTION_BUILD_MAVEN = "build.maven";
90  
91    /**
92     * The name of the miscellaneous build section.
93     * <p>
94     * The value of this constant is {@value}.
95     * </p>
96     */
97    public static final String SECTION_BUILD_MISC = "build.misc";
98  
99    /**
100    * The name of the project section.
101    * <p>
102    * The value of this constant is {@value}.
103    * </p>
104    */
105   public static final String SECTION_PROJECT = "project";
106 
107   // ... build property names .................................................
108 
109   /**
110    * The name of the project property that stores the URL to the SCM server.
111    * <p>
112    * The value of this constant is {@value}.
113    * </p>
114    */
115   public static final String PROP_NAME_SCM_URL = "build.scmRevision.url";
116 
117   /**
118    * The name of the project property that stores the revision number provided
119    * by the SCM.
120    * <p>
121    * The value of this constant is {@value}.
122    * </p>
123    */
124   public static final String PROP_NAME_SCM_REVISION_ID = "build.scmRevision.id";
125 
126   /**
127    * The name of the project property that stores the date the revision number
128    * was set.
129    * <p>
130    * The value of this constant is {@value}.
131    * </p>
132    */
133   public static final String PROP_NAME_SCM_REVISION_DATE =
134       "build.scmRevision.date";
135 
136   /**
137    * The name of the project property that stores the information if the local
138    * sources are modified.
139    * <p>
140    * The value of this constant is {@value}.
141    * </p>
142    */
143   public static final String PROP_NAME_SCM_LOCALLY_MODIFIED =
144       "build.scmLocallyModified";
145 
146   /**
147    * The name of the project property that stores the files that are locally
148    * modified.
149    * <p>
150    * The value of this constant is {@value}.
151    * </p>
152    */
153   public static final String PROP_NAME_SCM_LOCALLY_MODIFIED_FILES =
154       "build.scmLocallyModified.files";
155 
156   /**
157    * The name of the project property that stores the formatted build date.
158    * <p>
159    * The value of this constant is {@value}.
160    * </p>
161    */
162   public static final String PROP_NAME_BUILD_DATE = "build.date";
163 
164   /**
165    * The name of the project property that stores the build timestamp.
166    * <p>
167    * The value of this constant is {@value}.
168    * </p>
169    */
170   public static final String PROP_NAME_BUILD_TIMESTAMP =
171       "build.timestamp.millis";
172 
173   /**
174    * The name of the project property that stores the pattern of the build date.
175    * This way it is easy for the reading client to parse the build date.
176    * <p>
177    * The value of this constant is {@value}.
178    * </p>
179    */
180   public static final String PROP_NAME_BUILD_DATE_PATTERN =
181       "build.date.pattern";
182 
183   /**
184    * The name of the project property that stores the group ID as read from the
185    * POM.
186    * <p>
187    * The value of this constant is {@value}.
188    * </p>
189    */
190   public static final String PROP_NAME_GROUP_ID = "build.groupId";
191 
192   /**
193    * The name of the project property that stores the artifact ID as read from
194    * the POM.
195    * <p>
196    * The value of this constant is {@value}.
197    * </p>
198    */
199   public static final String PROP_NAME_ARTIFACT_ID = "build.artifactId";
200 
201   /**
202    * The name of the project property that stores the version as read from the
203    * POM.
204    * <p>
205    * The value of this constant is {@value}.
206    * </p>
207    */
208   public static final String PROP_NAME_VERSION = "build.version";
209 
210   /**
211    * The name of the project property that stores the full version that may
212    * include the version, the build date, the build number and the revision
213    * number.
214    * <p>
215    * The value of this constant is {@value}.
216    * </p>
217    */
218   public static final String PROP_NAME_FULL_VERSION = "build.version.full";
219 
220   /**
221    * The name of the project property that stores the build year.
222    * <p>
223    * The value of this constant is {@value}.
224    * </p>
225    */
226   public static final String PROP_NAME_BUILD_YEAR = "build.year";
227 
228   /**
229    * The name of the project property that stores the duration of the build in
230    * milliseconds. The duration is taken at the end of the build when the last
231    * plugin is run. The plugin cannot guarantee that there is no work done
232    * afterwards. The install and deploy phase are not measured since the plugin
233    * is running in the verify phase.
234    * <p>
235    * The value of this constant is {@value}.
236    * </p>
237    */
238   public static final String PROP_NAME_BUILD_DURATION = "build.duration";
239 
240   /**
241    * The name of the project property that stores the copyright year. The
242    * copyright year is either the inception year (if inception and build year
243    * are the same) or the period starting with the inception year and ending
244    * with the build year.
245    * <p>
246    * The value of this constant is {@value}.
247    * </p>
248    */
249   public static final String PROP_NAME_COPYRIGHT_YEAR = "build.copyright.year";
250 
251   /**
252    * The default pattern for the (locale independent) build date.
253    * <p>
254    * The value of this constant is {@value}.
255    * </p>
256    */
257   public static final String DEFAULT_DATE_PATTERN = "dd.MM.yyyy";
258 
259   /**
260    * The name of the project property that stores the build user. This is the
261    * person or system that run the build. It is either a configured value or the
262    * value of the system property <code>user.name</code>.
263    * <p>
264    * The value of this constant is {@value}.
265    * </p>
266    */
267   public static final String PROP_NAME_BUILD_USER = "build.user";
268 
269   /**
270    * The name of the property that stores the name of the host the build has
271    * been run on.
272    * <p>
273    * The value of this constant is {@value}.
274    * </p>
275    */
276   public static final String PROP_NAME_HOSTNAME = "build.host.name";
277 
278   /**
279    * The name of the property that stores the name of the operating system the
280    * build has been run on.
281    * <p>
282    * The value of this constant is {@value}.
283    * </p>
284    */
285   public static final String PROP_NAME_OS_NAME = "build.os.name";
286 
287   /**
288    * The name of the property that stores the architecture of the operating
289    * system the build has been run on.
290    * <p>
291    * The value of this constant is {@value}.
292    * </p>
293    */
294   public static final String PROP_NAME_OS_ARCH = "build.os.arch";
295 
296   /**
297    * The name of the property that stores the version of the operating system
298    * the build has been run on.
299    * <p>
300    * The value of this constant is {@value}.
301    * </p>
302    */
303   public static final String PROP_NAME_OS_VERSION = "build.os.version";
304 
305   /**
306    * The name of the property that stores the name of Java runtime being
307    * executed for the build.
308    * <p>
309    * The value of this constant is {@value}.
310    * </p>
311    */
312   public static final String PROP_NAME_JAVA_RUNTIME_NAME =
313       "build.java.runtime.name";
314 
315   /**
316    * The name of the property that stores the version of Java runtime being
317    * executed for the build.
318    * <p>
319    * The value of this constant is {@value}.
320    * </p>
321    */
322   public static final String PROP_NAME_JAVA_RUNTIME_VERSION =
323       "build.java.runtime.version";
324 
325   /**
326    * The name of the property that stores the name of the vendor of Java being
327    * executed for the build.
328    * <p>
329    * The value of this constant is {@value}.
330    * </p>
331    */
332   public static final String PROP_NAME_JAVA_VENDOR = "build.java.vendor";
333 
334   /**
335    * The name of the property that stores the name of the Java VM being executed
336    * for the build.
337    * <p>
338    * The value of this constant is {@value}.
339    * </p>
340    */
341   public static final String PROP_NAME_JAVA_VM = "build.java.vm";
342 
343   /**
344    * The name of the property that stores the name of the Java compiler being
345    * executed for the build.
346    * <p>
347    * The value of this constant is {@value}.
348    * </p>
349    */
350   public static final String PROP_NAME_JAVA_COMPILER = "build.java.compiler";
351 
352   /**
353    * The name of the property that stores the version of Maven being executed
354    * for the build.
355    * <p>
356    * The value of this constant is {@value}.
357    * </p>
358    */
359   public static final String PROP_NAME_MAVEN_VERSION = "build.maven.version";
360 
361   /**
362    * The name of the property that stores the goals given on the command line
363    * for the build.
364    * <p>
365    * The value of this constant is {@value}.
366    * </p>
367    */
368   public static final String PROP_NAME_MAVEN_GOALS =
369       "build.maven.execution.goals";
370 
371   /**
372    * The name of the property that stores the command line to start the build.
373    * <p>
374    * The value of this constant is {@value}.
375    * </p>
376    */
377   public static final String PROP_NAME_MAVEN_CMDLINE =
378       "build.maven.execution.cmdline";
379 
380   /**
381    * The name of the property that stores the Maven opts set in the environment.
382    * <p>
383    * The value of this constant is {@value}.
384    * </p>
385    */
386   public static final String PROP_NAME_MAVEN_OPTS =
387       "build.maven.execution.opts";
388 
389   /**
390    * The name of the property that stores the Java opts set in the environment.
391    * <p>
392    * The value of this constant is {@value}.
393    * </p>
394    */
395   public static final String PROP_NAME_JAVA_OPTS =
396       "build.maven.execution.java.opts";
397 
398   /**
399    * The name of the property that flags if the artifact is build within the
400    * project that is the execution root.
401    * <p>
402    * The value of this constant is {@value}.
403    * </p>
404    */
405   public static final String PROP_NAME_MAVEN_IS_EXECUTION_ROOT =
406       "build.maven.execution.isRoot";
407 
408   /**
409    * The name of the property that contains the name of the execution project.
410    * <p>
411    * The value of this constant is {@value}.
412    * </p>
413    */
414   public static final String PROP_NAME_MAVEN_EXECUTION_PROJECT =
415       "build.maven.execution.project";
416 
417   /**
418    * The name of the property that contains the name of the filters being
419    * registered for the build.
420    * <p>
421    * The value of this constant is {@value}.
422    * </p>
423    */
424   public static final String PROP_NAME_MAVEN_FILTERS =
425       "build.maven.execution.filters";
426 
427   /**
428    * The prefix used to provide execution properties to the build properties
429    * file.
430    * <p>
431    * The value of this constant is {@value}.
432    * </p>
433    */
434   public static final String MAVEN_EXECUTION_PROPERTIES_PREFIX =
435       "execution.property";
436 
437   /**
438    * The name of the property that contains names of active profiles during the
439    * build.
440    * <p>
441    * The value of this constant is {@value}.
442    * </p>
443    */
444   public static final String PROP_NAME_MAVEN_ACTIVE_PROFILES =
445       "build.maven.execution.profiles.active";
446 
447   /**
448    * The prefix used to provide active profile information of the build.
449    * <p>
450    * The value of this constant is {@value}.
451    * </p>
452    */
453   public static final String MAVEN_ACTIVE_PROFILE_PREFIX =
454       "build.maven.execution.profile.active";
455 
456   /**
457    * The name of the property that stores URL of the project homepage.
458    * <p>
459    * The value of this constant is {@value}.
460    * </p>
461    */
462   public static final String PROP_NAME_PROJECT_HOMEPAGE =
463       "project.page.home.url";
464 
465   /**
466    * The name of the property that stores URL to a page useful for operations
467    * teams.
468    * <p>
469    * The value of this constant is {@value}.
470    * </p>
471    */
472   public static final String PROP_NAME_PROJECT_OPS = "project.page.ops.url";
473 
474   /**
475    * The name of the property that stores a value to categorize the project.
476    * <p>
477    * The value of this constant is {@value}.
478    * </p>
479    */
480   public static final String PROP_NAME_PROJECT_CATEGORY = "project.category";
481 
482   /**
483    * The name of the property that stores a value to further categorize the
484    * project.
485    * <p>
486    * The value of this constant is {@value}.
487    * </p>
488    */
489   public static final String PROP_NAME_PROJECT_SUBCATEGORY =
490       "project.subcategory";
491 
492   /**
493    * The name of the property that stores a comma separated list of tags to
494    * categorize the project.
495    * <p>
496    * The value of this constant is {@value}.
497    * </p>
498    */
499   public static final String PROP_NAME_PROJECT_TAGS = "project.tags";
500 
501   /**
502    * List of properties, organized in sections, relevant to the build report.
503    * The order of properties in this list determines the order of the properties
504    * listed in the report.
505    */
506   public static final List<Section> REPORT_PROPERTIES;
507 
508   /**
509    * The set of standard keys known to be rendered in sections. This list allows
510    * to render properties within a separate section that have not yet been
511    * rendered.
512    */
513   public static final Set<String> STANDARD_PROPERTIES;
514 
515   // --- members --------------------------------------------------------------
516 
517   // ****************************** Initializer *******************************
518 
519   static
520   {
521     final List<Section> sections = new ArrayList<Section>();
522     final Section scm =
523         new Section(SECTION_BUILD_SCM, PROP_NAME_SCM_REVISION_ID,
524             PROP_NAME_SCM_REVISION_DATE, PROP_NAME_SCM_URL,
525             PROP_NAME_SCM_LOCALLY_MODIFIED_FILES);
526     sections.add(scm);
527 
528     final Section artifact =
529         new Section(SECTION_ARTIFACT, PROP_NAME_GROUP_ID,
530             PROP_NAME_ARTIFACT_ID, PROP_NAME_VERSION, PROP_NAME_FULL_VERSION);
531     sections.add(artifact);
532 
533     final Section dateAndVersion =
534         new Section(SECTION_BUILD_DATE, PROP_NAME_BUILD_DATE,
535             PROP_NAME_BUILD_TIMESTAMP, PROP_NAME_BUILD_YEAR,
536             PROP_NAME_COPYRIGHT_YEAR, DEFAULT_DATE_PATTERN);
537     sections.add(dateAndVersion);
538 
539     final Section buildRuntime =
540         new Section(SECTION_BUILD_RUNTIME, PROP_NAME_HOSTNAME,
541             PROP_NAME_OS_NAME, PROP_NAME_OS_ARCH, PROP_NAME_OS_VERSION,
542             PROP_NAME_BUILD_USER);
543     sections.add(buildRuntime);
544 
545     final Section buildJava =
546         new Section(SECTION_BUILD_JAVA, PROP_NAME_JAVA_VENDOR,
547             PROP_NAME_JAVA_RUNTIME_NAME, PROP_NAME_JAVA_RUNTIME_VERSION,
548             PROP_NAME_JAVA_VM, PROP_NAME_JAVA_COMPILER, PROP_NAME_JAVA_OPTS);
549     sections.add(buildJava);
550 
551     final Section buildMaven =
552         new Section(SECTION_BUILD_MAVEN, PROP_NAME_MAVEN_VERSION,
553             PROP_NAME_MAVEN_CMDLINE, PROP_NAME_MAVEN_GOALS,
554             PROP_NAME_MAVEN_OPTS, PROP_NAME_MAVEN_EXECUTION_PROJECT,
555             PROP_NAME_MAVEN_ACTIVE_PROFILES);
556     sections.add(buildMaven);
557 
558     final Section project =
559         new Section(SECTION_PROJECT, PROP_NAME_PROJECT_HOMEPAGE,
560             PROP_NAME_PROJECT_OPS, PROP_NAME_PROJECT_CATEGORY,
561             PROP_NAME_PROJECT_SUBCATEGORY, PROP_NAME_PROJECT_TAGS);
562     sections.add(project);
563 
564     final Set<String> properties =
565         new HashSet<String>(Arrays.asList(new String[]
566         { PROP_NAME_SCM_REVISION_ID, PROP_NAME_SCM_REVISION_DATE,
567          PROP_NAME_SCM_URL, PROP_NAME_SCM_LOCALLY_MODIFIED_FILES,
568          PROP_NAME_BUILD_DATE, PROP_NAME_BUILD_TIMESTAMP, PROP_NAME_BUILD_YEAR,
569          PROP_NAME_COPYRIGHT_YEAR, DEFAULT_DATE_PATTERN, PROP_NAME_GROUP_ID,
570          PROP_NAME_ARTIFACT_ID, PROP_NAME_VERSION, PROP_NAME_FULL_VERSION,
571          PROP_NAME_HOSTNAME, PROP_NAME_OS_NAME, PROP_NAME_OS_ARCH,
572          PROP_NAME_OS_VERSION, PROP_NAME_BUILD_USER, PROP_NAME_JAVA_VENDOR,
573          PROP_NAME_JAVA_RUNTIME_NAME, PROP_NAME_JAVA_RUNTIME_VERSION,
574          PROP_NAME_JAVA_VM, PROP_NAME_JAVA_COMPILER, PROP_NAME_JAVA_OPTS,
575          PROP_NAME_MAVEN_VERSION, PROP_NAME_MAVEN_CMDLINE,
576          PROP_NAME_MAVEN_GOALS, PROP_NAME_MAVEN_OPTS,
577          PROP_NAME_MAVEN_EXECUTION_PROJECT, PROP_NAME_MAVEN_ACTIVE_PROFILES,
578          PROP_NAME_PROJECT_HOMEPAGE, PROP_NAME_PROJECT_OPS }));
579 
580     STANDARD_PROPERTIES = Collections.unmodifiableSet(properties);
581     REPORT_PROPERTIES = Collections.unmodifiableList(sections);
582   }
583 
584   // ****************************** Constructors ******************************
585 
586   /**
587    * Constant pattern.
588    */
589   private Constant()
590   {
591   }
592 
593   // ****************************** Inner Classes *****************************
594 
595   /**
596    * The section allows to group build meta data properties.
597    */
598   public static final class Section
599   {
600     /**
601      * The resource key to access the title of the section.
602      */
603     private final String titleKey;
604 
605     /**
606      * The build meta data properties to be displayed in this section.
607      */
608     private final List<String> properties;
609 
610     /**
611      * Default constructor.
612      *
613      * @param titleKey the resource key to access the title of the section.
614      * @param properties the build meta data properties to be displayed in this
615      *          section.
616      */
617     private Section(final String titleKey, final String... properties)
618     {
619       this.titleKey = titleKey;
620       this.properties = Arrays.asList(properties);
621     }
622 
623     /**
624      * Returns the resource key to access the title of the section.
625      *
626      * @return the resource key to access the title of the section.
627      */
628     public String getTitleKey()
629     {
630       return titleKey;
631     }
632 
633     /**
634      * Returns the build meta data properties to be displayed in this section.
635      *
636      * @return the build meta data properties to be displayed in this section.
637      */
638     public List<String> getProperties()
639     {
640       return properties;
641     }
642   }
643 
644   // ********************************* Methods ********************************
645 
646   // --- init -----------------------------------------------------------------
647 
648   // --- get&set --------------------------------------------------------------
649 
650   // --- business -------------------------------------------------------------
651 
652   /**
653    * Checks if the given property is rejected from being displayed in the misc
654    * section of a report.
655    *
656    * @param name the name of the property to check.
657    * @return <code>true</code> if the property is to be rendered in a misc
658    *         section, <code>false</code> otherwise.
659    */
660   public static boolean isIntendedForMiscSection(final String name)
661   {
662     return !name.startsWith(MAVEN_ACTIVE_PROFILE_PREFIX);
663   }
664 
665   /**
666    * Calculates the non standard properties relevant for the misc section.
667    *
668    * @param buildMetaDataProperties the build meta data.
669    * @param userProperties the list of a system properties or environment
670    *          variables to be selected by the user to include into the build
671    *          meta data properties.
672    * @return the non standard properties.
673    */
674   public static Properties calcNonStandardProperties(
675       final Properties buildMetaDataProperties,
676       final List<Property> userProperties)
677   {
678     final SortedProperties nonStandardProperties = new SortedProperties();
679     final Set<String> selectedProperties =
680         createSelectedPropertiesExcludeMiscSection(userProperties);
681 
682     for (final Map.Entry<Object, Object> entry : buildMetaDataProperties
683         .entrySet())
684     {
685       final String key = String.valueOf(entry.getKey());
686       if (!Constant.STANDARD_PROPERTIES.contains(key)
687           && !selectedProperties.contains(key))
688       {
689         nonStandardProperties.put(key, entry.getValue());
690       }
691     }
692     return nonStandardProperties;
693   }
694 
695   private static Set<String> createSelectedPropertiesExcludeMiscSection(
696       final List<Property> userProperties)
697   {
698     final Set<String> selectedProperties = new HashSet<String>();
699 
700     if (userProperties != null)
701     {
702       for (final Property property : userProperties)
703       {
704         if (isNotTargetedForMiscSection(property.getSection()))
705         {
706           selectedProperties.add(property.getName());
707         }
708       }
709     }
710     return selectedProperties;
711   }
712 
713   private static boolean isNotTargetedForMiscSection(final String section)
714   {
715     return SECTION_BUILD_SCM.equals(section)
716            || SECTION_BUILD_DATE.equals(section)
717            || SECTION_BUILD_RUNTIME.equals(section)
718            || SECTION_BUILD_JAVA.equals(section)
719            || SECTION_BUILD_MAVEN.equals(section);
720   }
721 
722   /**
723    * Prettifies a multi value string that contains brackets. It simply removes
724    * the brackets.
725    *
726    * @param string the string to prettify.
727    * @return the prettified string.
728    */
729   public static String prettify(final String string)
730   {
731     final String trimmed = string.trim();
732     final int end = trimmed.length() - 1;
733     if (trimmed.charAt(0) == '[' && trimmed.charAt(end) == ']')
734     {
735       return trimmed.substring(1, end);
736     }
737     return trimmed;
738   }
739 
740   /**
741    * Prettifies a value string that contains brackets. It simply removes the
742    * brackets.
743    *
744    * @param value the object whose string representation is to be prettified.
745    * @return the prettified string.
746    */
747   public static String prettifyFilesValue(final Object value)
748   {
749     if (value == null)
750     {
751       return null;
752     }
753 
754     String string = String.valueOf(value);
755     if (StringUtils.isNotBlank(string))
756     {
757       string = string.replace(']', ' ');
758       string = string.replace('[', ',');
759       if (string.indexOf(0) == ',')
760       {
761         return string.substring(1);
762       }
763     }
764 
765     return string;
766   }
767 
768   // --- object basics --------------------------------------------------------
769 }