Introduction

Provides Maven reports on smartics-properties.

The following report types are provided:

  1. HTML report for integration into a Maven site
  2. XML report as project metadata in /META-INF/smartics-properties

This plugin provides also tools to a deal with properties. Currently only one such tool is available:

  1. Properties Export - generate a Java properties file with default values. For details on how to use this feature please refer to Creating Default Java Properties Files.

In the next two sections we show to examples, one with a simple property and one with an enumeration property.

Examples: Property Set

Property Set

This is an example of a property set that is used in the next sections. Please refer to the project test-module-agile for further details.

/**
 * Announcement Properties
 */
@PropertySet("announce")
public interface AnnouncementProperties
{
  /**
   * The file system directory where announcements are stored.
   *
   * @return the file system directory where announcements are stored.
   */
  @NotNull
  String directory();

  /**
   * The lookup interval for checking {@link #directory() directory} for new
   * announcements. The value is expected in milliseconds. A value of zero
   * indicates, that no automatic lookup is used.
   *
   * @return the lookup interval for checking {@link #directory() directory} for
   *         new announcements.
   */
  @PropertyExpression("300000" /* = 5 * 60 * 1000 ms = 5 min */)
  @Min(value = 0)
  @PropertyLifecycle(access = AccessType.READ_WRITE,
      updateInterval = 30 * UpdateInterval.ONE_SECOND)
  int lookupIntervalMs();

  /**
   * Returns the property key for the property {@link #lookupIntervalMs()}.
   *
   * @return the property key for the property {@link #lookupIntervalMs()}.
   */
  PropertyKey getLookupIntervalMsPropertyKey();
}

For detailed information about how to use smartics-properties please refer to the Introduction and the Tutorials.

HTML Report

The report makes property information available on a web site. The report looks like this:

Screenshot collage of smartics-properties.

The upper left shows the index of all property sets. You may either jump to a property set report (e.g. 'announce') or directly to one of its individual properties. Below the index you see a property set report (announce in this case). There is a tabular report about all the properties in the set with a link to the report of each property. An example for such a property report is on the right.

Please refer to Add a Properties Report to the Site for more information on this topic.

XML Report

Generates XML reports for smartics-properties. The reports are per default written to /META-INF/smartics-properties in the projectdoc format for properties. The information is read by the runtime if smartics-properties are used and is responsible to make compile-time information available (i.e. Javadoc comments).

A sample structure looks like this:

Screenshot of a sample META-INF folder with reports.

The following example shows a report on a property:

<?xml version="1.0" encoding="UTF-8"?>
<property
  xmlns="http://www.smartics.de/schema/projectdoc/doctype/property/1"
  name="announce.lookupIntervalMs">
  <identification>
    <space>property:de.smartics.sandbox.mail.AnnouncementProperties</space>
    <title>announce.lookupIntervalMs</title>
  </identification>
  <propertySet>announce</propertySet>
  <name>announce.lookupIntervalMs</name>
  <type>int</type>
  <specification>The lookup interval for checking {@link #directory() directory} for new&#xD;
    announcements. The value is expected in milliseconds. A value of zero&#xD;
    indicates, that no automatic lookup is used.</specification>
  <defaultValue>300000</defaultValue>
  <valueConstraints>
    <constraint>
      <type>de.smartics.properties.spi.core.constraint.jsr303.GenericPropertyConstraint</type>
      <description>Min(value=0)</description>
    </constraint>
  </valueConstraints>
  <implementation>
    <type>de.smartics.sandbox.mail.AnnouncementProperties</type>
    <field>lookupIntervalMs</field>
    <lineNumber>54</lineNumber>
  </implementation>
</property>

Please refer to Generating Properties Metadata for more information on this topic.

Examples: Property Set with Enumeration Values

Property Set

This is an example of a property set with enumeration values. Please refer to the project test-module-agile for further details.

/**
 * The example features an artificial enumeration of properties of a user story.
 * <p>
 * Just a paragraph to test.
 * </p>
 */
@PropertySet("agile")
public interface UserStoryProperties
{
  /**
   * The name of a user story.
   *
   * @return the property value.
   */
  String name();

  /**
   * The descriptor of the name property.
   *
   * @return descriptor of the name property.
   */
  PropertyDescriptor namePropertyDescriptor();

  /**
   * The story point stating the estimated work to implement the story.
   *
   * @return the property value.
   */
  @PropertyKeyName("story-points")
  @PropertyExpression("8")
  // CHECKSTYLE:OFF
  @PropertyIntValueRange({ 0, 1, 2, 3, 5, 8, 13, 21, 50, 100 })
  // CHECKSTYLE:ON
  int storyPoint();

  /**
   * The descriptor of the story point property.
   *
   * @return descriptor of the story point property.
   */
  PropertyDescriptor storyPointPropertyDescriptor();

  /**
   * The business priority of the user story.
   *
   * @return the property value.
   */
  @PropertyKeyName("business-priority")
  @PropertyExpression("required")
  Priority businessPriority();

  /**
   * The descriptor of the business priority property.
   *
   * @return descriptor of the business priority property.
   */
  PropertyDescriptor businessPriorityPropertyDescriptor();
}

And here is the code of the enumeration:

/**
 * The valid priority values for user stories.
 * <p>
 * Only {@link #REQUIRED required}, {@link #VERY_IMPORTANT very important} are
 * items that are necessary to be implemented.
 * </p>
 */
public enum Priority
{
  // ****************************** Enumeration *******************************

  /**
   * The story is required for the final product.
   * <p>
   * This and {@link #VERY_IMPORTANT} are items necessary to be implemented.
   * </p>
   */
  REQUIRED("required", 1),

  /**
   * The story is very important for the final product.
   * <p>
   * This and {@link #REQUIRED} are items necessary to be implemented.
   * </p>
   */
  VERY_IMPORTANT("very-important", 2),

  /**
   * The story is a nice-to-have for the final product, but not relevant for the
   * release.
   */
  NICE_TO_HAVE("nice-to-have", 3),

  /**
   * The story would add to the user experience of the user, but is not relevant
   * for the release.
   */
  POLISHING("polishing", 4),

  /**
   * The story is not necessary to be part of the release, but may be included
   * if resources are available. If the product backlog contains only
   * dispensable stores, the development is likely to come to an end.
   * <p>
   * The priority is available to keep stories in the product backlog for
   * further references.
   * </p>
   */
  DISPENSABLE("dispensable", 5);

  // ********************************* Fields *********************************

  // --- constants ------------------------------------------------------------

  // --- members --------------------------------------------------------------

  /**
   * The identifier of the priority. This value is used for resource lookups.
   */
  private final String id;

  /**
   * The value of the priority.
   */
  private final int priorityValue;

  // ****************************** Constructors ******************************

  /**
   * Default constructor.
   *
   * @param id the identifier of the priority.
   * @param priorityValue the value of the priority.
   */
  private Priority(final String id, final int priorityValue)
  {
    this.id = id;
    this.priorityValue = priorityValue;
  }

  // ********************************* Methods ********************************

  // --- init -----------------------------------------------------------------

  // --- get&set --------------------------------------------------------------

  /**
   * Returns the identifier of the priority. This value is used for resource
   * lookups.
   *
   * @return the identifier of the priority.
   */
  public String getId()
  {
    return id;
  }

  /**
   * Returns the value of the priority.
   *
   * @return the value of the priority.
   */
  public int getPriorityValue()
  {
    return priorityValue;
  }

  // --- business -------------------------------------------------------------

  /**
   * Returns the priority values as a list.
   *
   * @return the priority values as a list.
   */
  public List<Priority> getValues()
  {
    return Arrays.asList(values());
  }

  /**
   * Parses the string representation of a priority instance.
   *
   * @return the priority instance read from the string.
   * @throws IllegalArgumentException if {@code valueAsString} is not a valid
   *           string representation of a priority value.
   */
  public Priority fromString(final String valueAsString)
    throws IllegalArgumentException
  {
    for (Priority priority : values())
    {
      if (valueAsString.equals(priority.id))
      {
        return priority;
      }
    }

    final String message =
        "The value '" + valueAsString
            + "' is not a valid value for priority. Valid values are: "
            + toString(Locale.ENGLISH);
    throw new IllegalArgumentException(message);
  }

  // --- object basics --------------------------------------------------------

  /**
   * Returns the string representation of the instance for the given locale.
   *
   * @param locale the locale for which the string representation is requested.
   * @return the string representation of this instance.
   */
  public String toString(final Locale locale)
  {
    final StringBuilder buffer = new StringBuilder(64);
    for (Priority priority : values())
    {
      buffer.append(priority.id).append(", ");
    }

    final int length = buffer.length();
    if (length > 0)
    {
      buffer.setLength(length - 2);
    }

    return buffer.toString();
  }

  /**
   * {@inheritDoc}
   *
   * @see java.lang.Enum#toString()
   */
  @Override
  public String toString()
  {
    return id;
  }
}

HTML Report

The report makes property information available on a web site. The report looks like this:

Screenshot collage of smartics-properties.

XML Report

The following example shows a report on a property:

<?xml version="1.0" encoding="UTF-8"?>
<property
  xmlns="http://www.smartics.de/schema/projectdoc/doctype/property/1"
  name="agile.businessPriority">
  <identification>
    <space>property:de.smartics.sandbox.agile.UserStoryProperties</space>
    <title>agile.businessPriority</title>
  </identification>
  <propertySet>agile</propertySet>
  <name>agile.business-priority</name>
  <type>de.smartics.sandbox.agile.Priority</type>
  <specification>The business priority of the user story.</specification>
  <defaultValue>required</defaultValue>
  <valueRange>
    <summary>The valid priority values for user stories.&#xD;
      &lt;p&gt;&#xD;
      Only {@link #REQUIRED required}, {@link #VERY_IMPORTANT very important} are&#xD;
      items that are necessary to be implemented.&#xD;
      &lt;/p&gt;</summary>
    <element>
      <value>required</value>
      <description>The story is required for the final product.&#xD;
        &lt;p&gt;&#xD;
        This and {@link #VERY_IMPORTANT} are items necessary to be implemented.&#xD;
        &lt;/p&gt;</description>
    </element>
    <element>
      <value>very-important</value>
      <description>The story is very important for the final product.&#xD;
        &lt;p&gt;&#xD;
        This and {@link #REQUIRED} are items necessary to be implemented.&#xD;
        &lt;/p&gt;</description>
    </element>
    <element>
      <value>nice-to-have</value>
      <description>The story is a nice-to-have for the final product, but not relevant for the&#xD;
        release.
      </description>
    </element>
    <element>
      <value>polishing</value>
      <description>The story would add to the user experience of the user, but is not relevant&#xD;
        for the release.
      </description>
    </element>
    <element>
      <value>dispensable</value>
      <description>The story is not necessary to be part of the release, but may be included&#xD;
        if resources are available. If the product backlog contains only&#xD;
        dispensable stores, the development is likely to come to an end.&#xD;
        &lt;p&gt;&#xD;
        The priority is available to keep stories in the product backlog for&#xD;
        further references.&#xD;
        &lt;/p&gt;</description>
    </element>
  </valueRange>
  <valueConstraints>
    <constraint>
      <type>de.smartics.properties.spi.core.constraints.PropertyRangeConstraint</type>
      <description>Select one of the following values: required, very-important, nice-to-have, polishing, dispensable
      </description>
    </constraint>
  </valueConstraints>
  <implementation>
    <type>de.smartics.sandbox.agile.UserStoryProperties</type>
    <field>businessPriority</field>
    <lineNumber>73</lineNumber>
  </implementation>
</property>

Please refer to Generating Properties Metadata for more information on this topic.