Author: pottlinger
Date: Wed Aug  6 21:16:30 2014
New Revision: 1616351

URL: http://svn.apache.org/r1616351
Log:
Reducing warnings and updating dependencies

-Updated plugins and dependencies (including SCM/SSH) in whisker's parent pom 
after upgrading to new parent pom apache:14
-Fixing javadoc that prevented a build with JDK8.
-Using annotation-based maven plugin configuration, updated maven dependencies 
for that.
-LHF: Removed SuppressWarnings by removing empty if statements.


Modified:
    
creadur/whisker/trunk/apache-whisker-app/src/main/java/org/apache/creadur/whisker/app/Whisker.java
    
creadur/whisker/trunk/apache-whisker-app/src/main/java/org/apache/creadur/whisker/app/analysis/LicenseAnalyst.java
    
creadur/whisker/trunk/apache-whisker-app/src/main/java/org/apache/creadur/whisker/app/analysis/ResourceSourceAuditor.java
    
creadur/whisker/trunk/apache-whisker-app/src/main/java/org/apache/creadur/whisker/app/load/StreamableResourceFactory.java
    
creadur/whisker/trunk/apache-whisker-cli/src/main/java/org/apache/creadur/whisker/cli/Main.java
    
creadur/whisker/trunk/apache-whisker-model/src/main/java/org/apache/creadur/whisker/model/NoticeCollator.java
    
creadur/whisker/trunk/apache-whisker-model/src/main/java/org/apache/creadur/whisker/model/Resource.java
    
creadur/whisker/trunk/apache-whisker-model/src/main/java/org/apache/creadur/whisker/model/ResourceNamesCollator.java
    creadur/whisker/trunk/apache-whisker-plugin4maven/pom.xml
    
creadur/whisker/trunk/apache-whisker-plugin4maven/src/main/java/org/apache/creadur/whisker/plugin/maven/GenerateMojo.java
    
creadur/whisker/trunk/apache-whisker-velocity/src/main/java/org/apache/creadur/whisker/out/velocity/RenderingHelper.java
    
creadur/whisker/trunk/apache-whisker-xml/src/main/java/org/apache/creadur/whisker/fromxml/JDomBuilder.java
    
creadur/whisker/trunk/apache-whisker-xml/src/main/java/org/apache/creadur/whisker/fromxml/MissingIDException.java
    creadur/whisker/trunk/pom.xml

Modified: 
creadur/whisker/trunk/apache-whisker-app/src/main/java/org/apache/creadur/whisker/app/Whisker.java
URL: 
http://svn.apache.org/viewvc/creadur/whisker/trunk/apache-whisker-app/src/main/java/org/apache/creadur/whisker/app/Whisker.java?rev=1616351&r1=1616350&r2=1616351&view=diff
==============================================================================
--- 
creadur/whisker/trunk/apache-whisker-app/src/main/java/org/apache/creadur/whisker/app/Whisker.java
 (original)
+++ 
creadur/whisker/trunk/apache-whisker-app/src/main/java/org/apache/creadur/whisker/app/Whisker.java
 Wed Aug  6 21:16:30 2014
@@ -69,7 +69,7 @@ public class Whisker {
     }
 
     /**
-     * Gets the factory that builds product {@link Writer}s.
+     * Gets the factory that builds product {@link java.io.Writer}s.
      * @return factory
      */
     public final ResultWriterFactory getWriterFactory() {
@@ -77,7 +77,7 @@ public class Whisker {
     }
 
     /**
-     * Sets the factory that builds product {@link Writer}s.
+     * Sets the factory that builds product {@link java.io.Writer}s.
      * @param writerFactory not null
      * @return this, not null
      */

Modified: 
creadur/whisker/trunk/apache-whisker-app/src/main/java/org/apache/creadur/whisker/app/analysis/LicenseAnalyst.java
URL: 
http://svn.apache.org/viewvc/creadur/whisker/trunk/apache-whisker-app/src/main/java/org/apache/creadur/whisker/app/analysis/LicenseAnalyst.java?rev=1616351&r1=1616350&r2=1616351&view=diff
==============================================================================
--- 
creadur/whisker/trunk/apache-whisker-app/src/main/java/org/apache/creadur/whisker/app/analysis/LicenseAnalyst.java
 (original)
+++ 
creadur/whisker/trunk/apache-whisker-app/src/main/java/org/apache/creadur/whisker/app/analysis/LicenseAnalyst.java
 Wed Aug  6 21:16:30 2014
@@ -209,14 +209,11 @@ public class LicenseAnalyst {
      * @param directory not null
      * @param collator not null
      */
-    @SuppressWarnings("PMD.EmptyIfStmt")
     private void analyseExtraLicenses(final Directory directory,
             final ResourceNamesCollator collator) {
         final Collection<String> actualResources = directory.getContents();
         for (final String resourceLicense: collator.getNames()) {
-            if (actualResources.contains(resourceLicense)) {
-                // Fine
-            } else {
+            if (!actualResources.contains(resourceLicense)) {
                 getExtraLicenses().add(
                         new ResourceDescription(
                                 directory.getName(),
@@ -230,14 +227,11 @@ public class LicenseAnalyst {
      * @param directory not null
      * @param collator not null
      */
-    @SuppressWarnings("PMD.EmptyIfStmt")
     private void analyseMissingLicenses(final Directory directory,
             final ResourceNamesCollator collator) {
         final Collection<String> licensedResources = collator.getNames();
         for (final String actualResource: directory.getContents()) {
-            if (licensedResources.contains(actualResource)) {
-                // Fine
-            } else {
+            if (!licensedResources.contains(actualResource)) {
                 getMissingLicenses().add(
                         new ResourceDescription(
                                 directory.getName(),

Modified: 
creadur/whisker/trunk/apache-whisker-app/src/main/java/org/apache/creadur/whisker/app/analysis/ResourceSourceAuditor.java
URL: 
http://svn.apache.org/viewvc/creadur/whisker/trunk/apache-whisker-app/src/main/java/org/apache/creadur/whisker/app/analysis/ResourceSourceAuditor.java?rev=1616351&r1=1616350&r2=1616351&view=diff
==============================================================================
--- 
creadur/whisker/trunk/apache-whisker-app/src/main/java/org/apache/creadur/whisker/app/analysis/ResourceSourceAuditor.java
 (original)
+++ 
creadur/whisker/trunk/apache-whisker-app/src/main/java/org/apache/creadur/whisker/app/analysis/ResourceSourceAuditor.java
 Wed Aug  6 21:16:30 2014
@@ -104,7 +104,6 @@ public final class ResourceSourceAuditor
      * @see Visitor#visit(Resource)
      */
     @Override
-    @SuppressWarnings("PMD.EmptyIfStmt")
     public void visit(final Resource resource) {
         if (lastLicense == null) {
             throw new IllegalArgumentException(
@@ -120,8 +119,6 @@ public final class ResourceSourceAuditor
             } else {
                 resourcesMissingSource.add(pair);
             }
-        } else {
-            // Source not required
         }
     }
 

Modified: 
creadur/whisker/trunk/apache-whisker-app/src/main/java/org/apache/creadur/whisker/app/load/StreamableResourceFactory.java
URL: 
http://svn.apache.org/viewvc/creadur/whisker/trunk/apache-whisker-app/src/main/java/org/apache/creadur/whisker/app/load/StreamableResourceFactory.java?rev=1616351&r1=1616350&r2=1616351&view=diff
==============================================================================
--- 
creadur/whisker/trunk/apache-whisker-app/src/main/java/org/apache/creadur/whisker/app/load/StreamableResourceFactory.java
 (original)
+++ 
creadur/whisker/trunk/apache-whisker-app/src/main/java/org/apache/creadur/whisker/app/load/StreamableResourceFactory.java
 Wed Aug  6 21:16:30 2014
@@ -65,7 +65,7 @@ public final class StreamableResourceFac
      * builds an instance that streams, on demand,
      * from the classpath. Otherwise, builds an
      * instances that streams from the file system.
-     * @param resourceName
+     * @param resourceName source stream name.
      * @return not null
      */
     public StreamableResource streamFromResource(final String resourceName) {

Modified: 
creadur/whisker/trunk/apache-whisker-cli/src/main/java/org/apache/creadur/whisker/cli/Main.java
URL: 
http://svn.apache.org/viewvc/creadur/whisker/trunk/apache-whisker-cli/src/main/java/org/apache/creadur/whisker/cli/Main.java?rev=1616351&r1=1616350&r2=1616351&view=diff
==============================================================================
--- 
creadur/whisker/trunk/apache-whisker-cli/src/main/java/org/apache/creadur/whisker/cli/Main.java
 (original)
+++ 
creadur/whisker/trunk/apache-whisker-cli/src/main/java/org/apache/creadur/whisker/cli/Main.java
 Wed Aug  6 21:16:30 2014
@@ -70,7 +70,7 @@ public final class Main {
     /**
      * Bootstraps application.
      * @param args not null
-     * @throws Exception when application unexpectedly fails
+     * @throws Exception when application fails unexpectedly
      */
     public static void main(final String[] args) throws Exception {
         System.exit(new Main(app()).run(args));
@@ -196,7 +196,7 @@ public final class Main {
      * @param args not null
      * @return true when command line contains option for help,
      * false otherwise
-     * @throws ParseException
+     * @throws ParseException in case options could not be read properly.
      */
     public boolean printHelp(String[] args) throws ParseException {
         final CommandLineOption help = CommandLineOption.PRINT_HELP;

Modified: 
creadur/whisker/trunk/apache-whisker-model/src/main/java/org/apache/creadur/whisker/model/NoticeCollator.java
URL: 
http://svn.apache.org/viewvc/creadur/whisker/trunk/apache-whisker-model/src/main/java/org/apache/creadur/whisker/model/NoticeCollator.java?rev=1616351&r1=1616350&r2=1616351&view=diff
==============================================================================
--- 
creadur/whisker/trunk/apache-whisker-model/src/main/java/org/apache/creadur/whisker/model/NoticeCollator.java
 (original)
+++ 
creadur/whisker/trunk/apache-whisker-model/src/main/java/org/apache/creadur/whisker/model/NoticeCollator.java
 Wed Aug  6 21:16:30 2014
@@ -70,8 +70,8 @@ public class NoticeCollator extends Visi
     }
 
     /**
-     * @param notices
-     * @return
+     * @param notices map of notice-id and notices.
+     * @return list of notices.
      */
     public Set<String> notices(final Map<String, String> notices) {
         final Set<String> results = new HashSet<String>();

Modified: 
creadur/whisker/trunk/apache-whisker-model/src/main/java/org/apache/creadur/whisker/model/Resource.java
URL: 
http://svn.apache.org/viewvc/creadur/whisker/trunk/apache-whisker-model/src/main/java/org/apache/creadur/whisker/model/Resource.java?rev=1616351&r1=1616350&r2=1616351&view=diff
==============================================================================
--- 
creadur/whisker/trunk/apache-whisker-model/src/main/java/org/apache/creadur/whisker/model/Resource.java
 (original)
+++ 
creadur/whisker/trunk/apache-whisker-model/src/main/java/org/apache/creadur/whisker/model/Resource.java
 Wed Aug  6 21:16:30 2014
@@ -120,10 +120,10 @@ public class Resource implements Compara
     }
 
     /**
-     * Based on name.
+     * Comparison happens based on name.
      * @see java.lang.Comparable#compareTo(java.lang.Object)
-     * @param other
-     * @return comparison based on name
+     * @param other resource to compare to.
+     * @return result of comparison based on name
      */
     public int compareTo(final Resource other) {
         return getName().compareTo(other.getName());

Modified: 
creadur/whisker/trunk/apache-whisker-model/src/main/java/org/apache/creadur/whisker/model/ResourceNamesCollator.java
URL: 
http://svn.apache.org/viewvc/creadur/whisker/trunk/apache-whisker-model/src/main/java/org/apache/creadur/whisker/model/ResourceNamesCollator.java?rev=1616351&r1=1616350&r2=1616351&view=diff
==============================================================================
--- 
creadur/whisker/trunk/apache-whisker-model/src/main/java/org/apache/creadur/whisker/model/ResourceNamesCollator.java
 (original)
+++ 
creadur/whisker/trunk/apache-whisker-model/src/main/java/org/apache/creadur/whisker/model/ResourceNamesCollator.java
 Wed Aug  6 21:16:30 2014
@@ -75,12 +75,9 @@ public class ResourceNamesCollator exten
      * @param resource not null
      */
     @Override
-    @SuppressWarnings("PMD.EmptyIfStmt")
     public void visit(final Resource resource) {
-        if (this.resources.add(new ImmutablePair<WithinDirectory, Resource>(
+        if (!this.resources.add(new ImmutablePair<WithinDirectory, Resource>(
                 this.lastDirectory, resource))) {
-            // Fine
-        } else {
             // Already added
             if (this.lastDirectory == null) {
                 // Issue with logic which will result in a null pointer later
@@ -89,6 +86,6 @@ public class ResourceNamesCollator exten
             }
             this.duplicates.add(new ImmutablePair<WithinDirectory, Resource>(
                     this.lastDirectory, resource));
-        }
+      }
     }
 }

Modified: creadur/whisker/trunk/apache-whisker-plugin4maven/pom.xml
URL: 
http://svn.apache.org/viewvc/creadur/whisker/trunk/apache-whisker-plugin4maven/pom.xml?rev=1616351&r1=1616350&r2=1616351&view=diff
==============================================================================
--- creadur/whisker/trunk/apache-whisker-plugin4maven/pom.xml (original)
+++ creadur/whisker/trunk/apache-whisker-plugin4maven/pom.xml Wed Aug  6 
21:16:30 2014
@@ -33,9 +33,14 @@
     <dependency>
       <groupId>org.apache.maven</groupId>
       <artifactId>maven-plugin-api</artifactId>
-      <version>2.0</version>
+      <version>3.2.2</version>
+    </dependency>
+    <dependency>
+         <groupId>org.apache.maven.plugin-tools</groupId>
+         <artifactId>maven-plugin-annotations</artifactId>
+         <!-- keep in sync with maven-plugin-plugin version derived from 
parent -->
+         <version>3.2</version>
     </dependency>
-
     <dependency>
       <groupId>org.apache.commons</groupId>
       <artifactId>commons-lang3</artifactId>
@@ -87,10 +92,8 @@
       <groupId>commons-collections</groupId>
       <artifactId>commons-collections</artifactId>
     </dependency>
-
   </dependencies>
 
-
   <build>
     <plugins>
       <plugin>
@@ -136,17 +139,17 @@
               <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-project-info-reports-plugin</artifactId>
-                <version>2.4</version>
+                <version>2.7</version>
               </plugin>
               <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-surefire-report-plugin</artifactId>
-                <version>2.12</version>
+                <version>2.17</version>
               </plugin>
               <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-jxr-plugin</artifactId>
-                <version>2.3</version>
+                <version>2.4</version>
                 <configuration>
                   <linkJavadoc>true</linkJavadoc>
                 </configuration>
@@ -154,12 +157,12 @@
               <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-plugin-plugin</artifactId>
-                <version>3.0</version>
+                <version>3.2</version>
               </plugin>
               <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-javadoc-plugin</artifactId>
-                <version>2.8.1</version>
+                <version>2.9.1</version>
               </plugin>
             </reportPlugins>
           </configuration>

Modified: 
creadur/whisker/trunk/apache-whisker-plugin4maven/src/main/java/org/apache/creadur/whisker/plugin/maven/GenerateMojo.java
URL: 
http://svn.apache.org/viewvc/creadur/whisker/trunk/apache-whisker-plugin4maven/src/main/java/org/apache/creadur/whisker/plugin/maven/GenerateMojo.java?rev=1616351&r1=1616350&r2=1616351&view=diff
==============================================================================
--- 
creadur/whisker/trunk/apache-whisker-plugin4maven/src/main/java/org/apache/creadur/whisker/plugin/maven/GenerateMojo.java
 (original)
+++ 
creadur/whisker/trunk/apache-whisker-plugin4maven/src/main/java/org/apache/creadur/whisker/plugin/maven/GenerateMojo.java
 Wed Aug  6 21:16:30 2014
@@ -20,42 +20,39 @@ package org.apache.creadur.whisker.plugi
 
 import java.io.File;
 
-import org.apache.maven.plugin.AbstractMojo;
-import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.creadur.whisker.app.Act;
 import org.apache.creadur.whisker.app.Whisker;
 import org.apache.creadur.whisker.app.load.StreamableResourceFactory;
 import org.apache.creadur.whisker.app.out.WriteResultsIntoDirectoryFactory;
 import org.apache.creadur.whisker.out.velocity.VelocityEngine;
-
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugins.annotations.*;
 
 /**
  * Generates licensing related materials such as LICENSE and NOTICE documents
- * for assembled applications.
- * @goal generate
+ * for assembled applications. The plugin is not bound to a specific lifecycle 
phase.
  */
+@Mojo(name = "generate")
 public class GenerateMojo extends AbstractMojo {
 
     /**
      * Destination for generated materials
-     *
-     * @parameter default-value="${project.build.directory}"
      */
+       @Parameter(defaultValue = "${project.build.directory}")
     private File outputDirectory;
 
     /**
      * The licensing materials will be encoding thus.
-     * @parameter property="outputEncoding" 
default-value="${project.build.sourceEncoding}"
      */
+       @Parameter(property = "outputEncoding", defaultValue = 
"${project.build.sourceEncoding}")
     private String outputEncoding;
 
     /**
      * This file contains a description of the licensing qualities of
      * the expected contents of the assembled application.
-     *
-     * @required
-     * @parameter property="apacheWhiskerDescriptor"
      */
+       @Parameter(property = "apacheWhiskerDescriptor", required = true)
     private File descriptor;
 
     /**

Modified: 
creadur/whisker/trunk/apache-whisker-velocity/src/main/java/org/apache/creadur/whisker/out/velocity/RenderingHelper.java
URL: 
http://svn.apache.org/viewvc/creadur/whisker/trunk/apache-whisker-velocity/src/main/java/org/apache/creadur/whisker/out/velocity/RenderingHelper.java?rev=1616351&r1=1616350&r2=1616351&view=diff
==============================================================================
--- 
creadur/whisker/trunk/apache-whisker-velocity/src/main/java/org/apache/creadur/whisker/out/velocity/RenderingHelper.java
 (original)
+++ 
creadur/whisker/trunk/apache-whisker-velocity/src/main/java/org/apache/creadur/whisker/out/velocity/RenderingHelper.java
 Wed Aug  6 21:16:30 2014
@@ -41,8 +41,9 @@ public class RenderingHelper {
     private final Configuration configuration;
 
     /**
-     * Constructs a helper for the given work.
+     * Constructs a helper for the given work and configuration.
      * @param work not null
+     * @param configuration not null
      */
     public RenderingHelper(final Descriptor work, final Configuration 
configuration) {
         super();

Modified: 
creadur/whisker/trunk/apache-whisker-xml/src/main/java/org/apache/creadur/whisker/fromxml/JDomBuilder.java
URL: 
http://svn.apache.org/viewvc/creadur/whisker/trunk/apache-whisker-xml/src/main/java/org/apache/creadur/whisker/fromxml/JDomBuilder.java?rev=1616351&r1=1616350&r2=1616351&view=diff
==============================================================================
--- 
creadur/whisker/trunk/apache-whisker-xml/src/main/java/org/apache/creadur/whisker/fromxml/JDomBuilder.java
 (original)
+++ 
creadur/whisker/trunk/apache-whisker-xml/src/main/java/org/apache/creadur/whisker/fromxml/JDomBuilder.java
 Wed Aug  6 21:16:30 2014
@@ -48,457 +48,575 @@ import org.jdom.input.SAXBuilder;
  * Builds a model from xml using JDOM.
  */
 public class JDomBuilder {
-    
-    private static final String COPYRIGHT_NOTICE_NAME = "copyright-notice";
-    /**
+
+       private static final String COPYRIGHT_NOTICE_NAME = "copyright-notice";
+       /**
      * 
      */
-    private static final String LICENSE_ELEMENT_NAME = "license";
-    /**
+       private static final String LICENSE_ELEMENT_NAME = "license";
+       /**
      * 
      */
-    private static final String PRIMARY_LICENSE_NAME = "primary-license";
-    /** Names the element representing an organisation */
-    private static final String ORGANISATION_ELEMENT_NAME = "organisation";
-    /** Names the element representing a resource */
-    private static final String RESOURCE_ELEMENT_NAME = "resource";
-
-    /**
-     * Builds a resource.
-     * @param element not null
-     * @return built resource, not null
-     * @throws UnexpectedElementException when element is not named 'resource'
-     */
-    public Resource resource(Element element) throws 
UnexpectedElementException {
-        if (RESOURCE_ELEMENT_NAME.equals(element.getName())) {
-            return new 
Resource(StringUtils.trim(element.getAttributeValue("name")), 
-                    StringUtils.trim(element.getAttributeValue("notice")),
-                    StringUtils.trim(element.getAttributeValue("source")));
-        } else {
-            throw unexpectedElementException(element, RESOURCE_ELEMENT_NAME);
-        }
-    }
-
-    /**
-     * Builds a suitable exception when the element name is unexpected.
-     * @param element, not null
-     * @param expectedElement, not null
-     * @return a suitable exception, not null
-     */
-    private UnexpectedElementException unexpectedElementException(Element 
element,
-            final String expectedElement) {
-        return new UnexpectedElementException(expectedElement, 
element.getName());
-    }
-
-    /**
-     * Builds an organisation model from xml.
-     * @param element, not null
-     * @return {@link Organisation} not null
-     * @throws UnexpectedElementException when element is not named 
'organisation'
-     */
-    public Organisation organisation(Element element) throws 
UnexpectedElementException {
-        if (ORGANISATION_ELEMENT_NAME.equals(element.getName())) {
-            return new Organisation(
-                    element.getAttributeValue("id"), 
-                    element.getAttributeValue("name"), 
-                    element.getAttributeValue("url"));
-        } else {
-            throw unexpectedElementException(element, 
ORGANISATION_ELEMENT_NAME);
-        }
-    }
-
-    /**
-     * @param element
-     * @return
-     */
-    @SuppressWarnings("unchecked")
-    public Collection<Resource> collectResources(Element element) {
-        final Collection<Resource> resources = new TreeSet<Resource>();
-        for (Element resourceElement: (List<Element>) 
element.getChildren("resource")) {
-            resources.add(new JDomBuilder().resource(resourceElement));
-        }
-        return Collections.unmodifiableCollection(resources);
-    }
-
-    /**
-     * Finds the organisation linked by ID from the given element.
-     * @param element modelled ByOrganisation, not null
-     * @param organisationsById organisations identified, not null
-     * @throws MissingIDException when the linked organisation is not found in 
the given map
-     */
-    public Organisation organisation(final Element element,
-            final Map<String, Organisation> organisationsById) throws 
MissingIDException {
-        final String id = element.getAttributeValue("id");
-        if (organisationsById.containsKey(id)) {
-            return organisationsById.get(id);
-        } else {
-            throw new MissingIDException(ORGANISATION_ELEMENT_NAME, 
element.getName(), id);
-        }
-    }
-    
-    /**
-     * Builds a by-organisation model from xml.
-     * @param element not null
-     * @param organisation not null
-     * @return not null
-     */
-    public ByOrganisation byOrganisation(final Element element, final 
Organisation organisation) {
-        return new ByOrganisation(organisation, collectResources(element));
-    }
-
-    /**
-     * Builds a by-organisation model from xml.
-     * @param byOrganisation not null
-     * @param organisationsById not null 
-     * @return not null
-     * @throws MissingIDException when the linked organisation is not found in 
the given map
-     */
-    public ByOrganisation byOrganisation(final Element byOrganisation, 
-            final Map<String, Organisation> organisationsById) throws 
MissingIDException  {
-        return byOrganisation(byOrganisation, organisation(byOrganisation, 
organisationsById));
-    }
-
-    /**
-     * Collects by-organisation children.
-     * @param parent not null
-     * @param map not null
-     * @return unmodifiable set sort by natural order, not null
-     */
-    @SuppressWarnings("unchecked")
-    public SortedSet<ByOrganisation> collectByOrganisations(final Element 
parent, 
-            final Map<String, Organisation> map) {
-        final SortedSet<ByOrganisation> results = new 
TreeSet<ByOrganisation>();
-        if (parent != null) {
-            for (final Element byOrgElement: (List<Element>) 
parent.getChildren("by-organisation")) {
-                results.add(byOrganisation(byOrgElement, map));
-            }
-        }
-        return Collections.unmodifiableSortedSet(results);
-    }
-
-    /**
-     * Builds a license model from xml.
-     * @param element not null
-     * @return not null
-     */
-    public License license(Element element) {
-        final Element text = element.getChild("text");
-        return new 
License("yes".equalsIgnoreCase(element.getAttributeValue("requires-source")), 
-                text == null ? "" : text.getText(), 
-                expectedParameters(element), 
-                element.getAttributeValue("id"), 
-                element.getAttributeValue("url"),
-                element.getAttributeValue("name"));
-    }
-    
-    @SuppressWarnings("unchecked")
-    private Collection<String> expectedParameters(final Element element) {
-        final Collection<String> results = new HashSet<String>();
-        final Element templateElement = element.getChild("template");
-        if (templateElement != null) {
-            for (Element parameterNameElement: (List<Element>) 
templateElement.getChildren("parameter-name")) {
-                results.add(parameterNameElement.getTextTrim());
-            }
-        }
-        return results;
-    }
-
-    /**
-     * Finds the license with an id matching that referenced by the element.
-     * @param element not null
-     * @param licenses not null
-     * @return not null
-     * @throws MissingIDException when referenced license isn't found in the 
collection
-     */
-    public License license(final Element element, final Map<String, License> 
licenses) throws MissingIDException {
-        final String id = element.getAttributeValue("id");
-        if (licenses.containsKey(id)) {
-            return licenses.get(id);
-        } else {
-            throw new MissingIDException(LICENSE_ELEMENT_NAME, 
element.getName(), id);
-        }
-    }
-
-    /**
-     * Builds a with-license model from xml.
-     * @param element not null
-     * @param licenses not null
-     * @param organisations not null
-     * @return
-     * @throws MissingIDException when referenced license isn't found in the 
collection
-     */
-    public WithLicense withLicense(Element element,
-            Map<String, License> licenses,
-            Map<String, Organisation> organisations) throws MissingIDException 
 {
-        return new WithLicense(license(element, licenses), 
copyrightNotice(element), 
-                parameters(element), collectByOrganisations(element, 
organisations));
-    }
-    
-    /**
-     * Extracts copyright notice content from with-license.
-     * @param element not null
-     * @return not null
-     */
-    private String copyrightNotice(final Element element) {
-        final String result;
-        final Element copyrightNoticeElement = 
element.getChild(COPYRIGHT_NOTICE_NAME);
-        if (copyrightNoticeElement == null) {
-            result = null;
-        } else {
-            result = copyrightNoticeElement.getTextTrim();
-        }
-        return result;
-    }
-
-    /**
-     * Builds a list of parameter values by name.
-     * @param element not null
-     * @return parameter values indexed by value, not null
-     * @throws DuplicateElementException when two parameters shared the same 
name
-     */
-    @SuppressWarnings("unchecked")
-    public Map<String, String> parameters(Element element) throws 
DuplicateElementException {
-        final Map<String, String> results = new HashMap<String, String>();
-        final Element licenseParametersElement = 
element.getChild("license-parameters");
-        if (licenseParametersElement != null) {
-            for (Element parameterElement: (List<Element>) 
licenseParametersElement.getChildren("parameter")) {
-                final String name = 
parameterElement.getChild("name").getTextTrim();
-                if (results.containsKey(name)) {
-                    throw new DuplicateElementException("Duplicate parameter 
'" + name + "'");
-                }
-                results.put(name, 
-                        parameterElement.getChild("value").getTextTrim());
-            }   
-        }
-        return results;
-    }
-
-    /**
-     * Collects child with-licenses.
-     * @param licenses not null
-     * @param organisations not null
-     * @param parent not null
-     * @return not null, possibly empty
-     */
-    @SuppressWarnings("unchecked")
-    public Collection<WithLicense> withLicenses(Map<String, License> licenses,
-            Map<String, Organisation> organisations, Element parent) {
-        final List<WithLicense> results = new ArrayList<WithLicense>();
-        for (Element withLicenseElement: (List<Element>) 
parent.getChildren("with-license")) {
-            results.add(new JDomBuilder().withLicense(withLicenseElement, 
licenses, organisations));
-        }
-        Collections.sort(results);
-        return results;
-    }
-
-    /**
-     * Collects child organisations of public domain.
-     * @param organisations not null
-     * @param parent not null
-     * @return not null, possibly null
-     */
-    public Collection<ByOrganisation> publicDomain(
-            final Map<String, Organisation> organisations, final Element 
parent) {
-        return new 
JDomBuilder().collectByOrganisations(parent.getChild("public-domain"), 
organisations);
-    }
-
-    /**
-     * Builds a within directory model from XML.
-     * @param element not null
-     * @param licenses not null
-     * @param organisations not null
-     * @return not null
-     */
-    public WithinDirectory withinDirectory(Element element,
-            Map<String, License> licenses,
-            Map<String, Organisation> organisations) {
-        return new WithinDirectory(element.getAttributeValue("dir"), 
-                withLicenses(licenses, organisations, element), 
publicDomain(organisations, element));
-    }
-
-    /**
-     * Collects organisation definitions within document.
-     * @param document, not null
-     * @return organisations indexed by id, not null possibly empty
-     */
-    public Map<String, Organisation> mapOrganisations(Document document) {
-        final Map<String, Organisation> organisationsById = new 
HashMap<String, Organisation>();
-        
-        final Element childOrganisations = 
document.getRootElement().getChild("organisations");
-        if (childOrganisations != null) {
-            @SuppressWarnings("unchecked")
-            final List<Element> organisations = (List<Element>) 
childOrganisations.getChildren("organisation");
-            for (final Element element: organisations) {
-                new 
JDomBuilder().organisation(element).storeIn(organisationsById);
-            }
-        }
-        return Collections.unmodifiableMap(organisationsById);
-    }
-
-    /**
-     * Collects license definitions within document.
-     * @param document, not null
-     * @return licenses, indexed by id, not null, possibly empty
-     */
-    public Map<String, License> mapLicenses(Document document) {
-        final Map<String, License> results = new HashMap<String, License>();
-        final Element licensesChild = 
document.getRootElement().getChild("licenses");
-        if (licensesChild != null) {
-            @SuppressWarnings("unchecked")
-            final List<Element> children = (List<Element>) 
licensesChild.getChildren();
-            for (final Element element: children) {
-                new JDomBuilder().license(element).storeIn(results);
-            }
-        }
-        return Collections.unmodifiableMap(results);
-
-    }
-
-    /**
-     * Finds the primary license for the given document from the given 
licenses.
-     * @param document not null
-     * @param licenses not null
-     * @return not null
-     */
-    public License primaryLicense(Document document,
-            Map<String, License> licenses) {
-        final String idAttributeValue = 
getPrimaryLicenseElement(document).getAttributeValue("id");
-        final License results = licenses.get(idAttributeValue);
-        if (results == null) {
-            throw new MissingIDException(LICENSE_ELEMENT_NAME, 
PRIMARY_LICENSE_NAME, idAttributeValue);
-        }
-        return results;
-    }
-
-    /**
-     * Gets the element representing the primary license.
-     * @param document not null
-     * @return not null
-     */
-    private Element getPrimaryLicenseElement(final Document document) {
-        return document.getRootElement().getChild(PRIMARY_LICENSE_NAME);
-    }
-
-    /**
-     * Gets the additional primary copyright notice 
-     * from the document.
-     * @param document not null
-     * @return optional primary copyright notice, possibly null
-     */
-    public String primaryCopyrightNotice(final Document document) {
-        final String result;
-        final Element copyrightElement = 
-                
getPrimaryLicenseElement(document).getChild(COPYRIGHT_NOTICE_NAME);
-        if (copyrightElement == null) {
-            result = null;
-        } else {
-            result = copyrightElement.getTextTrim();
-        }
-        return result;
-    }
-
-    
-    /**
-     * Collects notices in the given documents.
-     * @param document, not null
-     * @return notices indexed by id, immutable, not null, possibly empty
-     */
-    public Map<String, String> mapNotices(Document document) {
-        final Map<String, String> results = new HashMap<String, String>();
-        final Element noticesElement = 
document.getRootElement().getChild("notices");
-        if (noticesElement != null){
-            @SuppressWarnings("unchecked")
-            final List<Element> children = (List<Element>) 
noticesElement.getChildren();
-            for (final Element element: children) {
-                results.put(element.getAttributeValue("id"), 
element.getTextTrim());
-            }
-        }
-        return Collections.unmodifiableMap(results);
-
-    }
-
-    /**
-     * Retrieves the text of the primary notice.
-     * @param document, not null
-     * @return the text of the primary notice, 
-     * or null when there is no primary notice
-     */
-    public String primaryNotice(Document document) {
-        final String result;
-        final Element primaryNoticeElement = 
document.getRootElement().getChild("primary-notice");
-        if (primaryNoticeElement == null) {
-            result = null;
-        } else {
-            result = primaryNoticeElement.getText()
-                .replace("${year}", 
Integer.toString(Calendar.getInstance().get(Calendar.YEAR)));
-        }
-        return result;
-    }
-
-    /**
-     * Retrieves the ID of the primary organisation.
-     * @param document, not null
-     * @return the id of the primary organisation when set,
-     * otherwise null
-     */
-    public String primaryOrganisationId(final Document document) {
-        final String result;
-        final Element primaryOrganisationElement = 
document.getRootElement().getChild("primary-organisation");
-        if (primaryOrganisationElement == null) {
-            result = null;
-        } else {
-            result = primaryOrganisationElement.getAttributeValue("id");
-        }
-        return result;
-    }    
-
-    private WithinDirectory directory(final Element element, final Map<String, 
License> licenses,
-            final Map<String, Organisation> organisations) {
-        return new JDomBuilder().withinDirectory(element, licenses, 
organisations);
-    }
-
-    /**
-     * Collects contents of the document.
-     * @param document not null
-     * @return not null, possibly empty
-     * @throws DuplicateElementException when dir names are not unique
-     */
-    @SuppressWarnings("PMD.EmptyIfStmt")
-    public Collection<WithinDirectory> collectContents(final Document 
document, final Map<String, License> licenses,
-            final Map<String, Organisation> organisations) throws 
DuplicateElementException {
-        final Collection<WithinDirectory> results = new 
TreeSet<WithinDirectory>();
-        @SuppressWarnings("unchecked")
-        final List<Element> children = 
document.getRootElement().getChildren("within");
-        for (Element element: children) {
-            if (results.add(directory(element, licenses, organisations))) {
-                // fine
-            } else {
-                throw new DuplicateElementException("Duplicate parameter '" + 
element.getAttribute("dir").getValue() + "'");
-            }
-        }
-        return results;
-    }
-    
-    /**
-     * Builds work from the given document.
-     * @param document not null
-     * @return not null
-     */
-    public Descriptor build(final Document document) {
-        final Map<String, Organisation> organisations = 
mapOrganisations(document);
-        final Map<String, License> licenses = mapLicenses(document);
-        final Map<String, String> notices = mapNotices(document);
-        final License primaryLicense = primaryLicense(document, licenses);
-        final String primaryCopyrightNotice = primaryCopyrightNotice(document);
-        final String primaryNotice = primaryNotice(document);
-        final String primaryOrganisationId = primaryOrganisationId(document);
-        final Collection<WithinDirectory> contents = collectContents(document, 
licenses, organisations); 
-        return new Descriptor(primaryLicense, primaryCopyrightNotice,
-                primaryOrganisationId, primaryNotice, 
-                licenses, notices, organisations, contents);
-    }
-    
-    public Descriptor build(final InputStream xmlStream) throws JDOMException, 
IOException {
-        return build(new SAXBuilder().build(xmlStream));
-    }
+       private static final String PRIMARY_LICENSE_NAME = "primary-license";
+       /** Names the element representing an organisation */
+       private static final String ORGANISATION_ELEMENT_NAME = "organisation";
+       /** Names the element representing a resource */
+       private static final String RESOURCE_ELEMENT_NAME = "resource";
+
+       /**
+        * Builds a resource.
+        * 
+        * @param element
+        *            not null
+        * @return built resource, not null
+        * @throws UnexpectedElementException
+        *             when element is not named 'resource'
+        */
+       public Resource resource(Element element) throws 
UnexpectedElementException {
+               if (RESOURCE_ELEMENT_NAME.equals(element.getName())) {
+                       return new Resource(StringUtils.trim(element
+                                       .getAttributeValue("name")), 
StringUtils.trim(element
+                                       .getAttributeValue("notice")), 
StringUtils.trim(element
+                                       .getAttributeValue("source")));
+               } else {
+                       throw unexpectedElementException(element, 
RESOURCE_ELEMENT_NAME);
+               }
+       }
+
+       /**
+        * Builds a suitable exception when the element name is unexpected.
+        * 
+        * @param element
+        *            , not null
+        * @param expectedElement
+        *            , not null
+        * @return a suitable exception, not null
+        */
+       private UnexpectedElementException unexpectedElementException(
+                       Element element, final String expectedElement) {
+               return new UnexpectedElementException(expectedElement,
+                               element.getName());
+       }
+
+       /**
+        * Builds an organisation model from xml.
+        * 
+        * @param element
+        *            , not null
+        * @return {@link Organisation} not null
+        * @throws UnexpectedElementException
+        *             when element is not named 'organisation'
+        */
+       public Organisation organisation(Element element)
+                       throws UnexpectedElementException {
+               if (ORGANISATION_ELEMENT_NAME.equals(element.getName())) {
+                       return new Organisation(element.getAttributeValue("id"),
+                                       element.getAttributeValue("name"),
+                                       element.getAttributeValue("url"));
+               } else {
+                       throw unexpectedElementException(element, 
ORGANISATION_ELEMENT_NAME);
+               }
+       }
+
+       /**
+        * @param element
+        *            JDOM element to collect.
+        * @return collected resources.
+        */
+       @SuppressWarnings("unchecked")
+       public Collection<Resource> collectResources(Element element) {
+               final Collection<Resource> resources = new TreeSet<Resource>();
+               for (Element resourceElement : (List<Element>) element
+                               .getChildren("resource")) {
+                       resources.add(new 
JDomBuilder().resource(resourceElement));
+               }
+               return Collections.unmodifiableCollection(resources);
+       }
+
+       /**
+        * @return Finds the organisation linked by ID from the given element.
+        * @param element
+        *            modelled ByOrganisation, not null
+        * @param organisationsById
+        *            organisations identified, not null
+        * @throws MissingIDException
+        *             when the linked organisation is not found in the given 
map
+        */
+       public Organisation organisation(final Element element,
+                       final Map<String, Organisation> organisationsById)
+                       throws MissingIDException {
+               final String id = element.getAttributeValue("id");
+               if (organisationsById.containsKey(id)) {
+                       return organisationsById.get(id);
+               } else {
+                       throw new MissingIDException(ORGANISATION_ELEMENT_NAME,
+                                       element.getName(), id);
+               }
+       }
+
+       /**
+        * Builds a by-organisation model from xml.
+        * 
+        * @param element
+        *            not null
+        * @param organisation
+        *            not null
+        * @return not null
+        */
+       public ByOrganisation byOrganisation(final Element element,
+                       final Organisation organisation) {
+               return new ByOrganisation(organisation, 
collectResources(element));
+       }
+
+       /**
+        * Builds a by-organisation model from xml.
+        * 
+        * @param byOrganisation
+        *            not null
+        * @param organisationsById
+        *            not null
+        * @return not null
+        * @throws MissingIDException
+        *             when the linked organisation is not found in the given 
map
+        */
+       public ByOrganisation byOrganisation(final Element byOrganisation,
+                       final Map<String, Organisation> organisationsById)
+                       throws MissingIDException {
+               return byOrganisation(byOrganisation,
+                               organisation(byOrganisation, 
organisationsById));
+       }
+
+       /**
+        * Collects by-organisation children.
+        * 
+        * @param parent
+        *            not null
+        * @param map
+        *            not null
+        * @return unmodifiable set sort by natural order, not null
+        */
+       @SuppressWarnings("unchecked")
+       public SortedSet<ByOrganisation> collectByOrganisations(
+                       final Element parent, final Map<String, Organisation> 
map) {
+               final SortedSet<ByOrganisation> results = new 
TreeSet<ByOrganisation>();
+               if (parent != null) {
+                       for (final Element byOrgElement : (List<Element>) parent
+                                       .getChildren("by-organisation")) {
+                               results.add(byOrganisation(byOrgElement, map));
+                       }
+               }
+               return Collections.unmodifiableSortedSet(results);
+       }
+
+       /**
+        * Builds a license model from xml.
+        * 
+        * @param element
+        *            not null
+        * @return not null
+        */
+       public License license(Element element) {
+               final Element text = element.getChild("text");
+               return new License("yes".equalsIgnoreCase(element
+                               .getAttributeValue("requires-source")), text == 
null ? ""
+                               : text.getText(), expectedParameters(element),
+                               element.getAttributeValue("id"),
+                               element.getAttributeValue("url"),
+                               element.getAttributeValue("name"));
+       }
+
+       @SuppressWarnings("unchecked")
+       private Collection<String> expectedParameters(final Element element) {
+               final Collection<String> results = new HashSet<String>();
+               final Element templateElement = element.getChild("template");
+               if (templateElement != null) {
+                       for (Element parameterNameElement : (List<Element>) 
templateElement
+                                       .getChildren("parameter-name")) {
+                               results.add(parameterNameElement.getTextTrim());
+                       }
+               }
+               return results;
+       }
+
+       /**
+        * Finds the license with an id matching that referenced by the element.
+        * 
+        * @param element
+        *            not null
+        * @param licenses
+        *            not null
+        * @return not null
+        * @throws MissingIDException
+        *             when referenced license isn't found in the collection
+        */
+       public License license(final Element element,
+                       final Map<String, License> licenses) throws 
MissingIDException {
+               final String id = element.getAttributeValue("id");
+               if (licenses.containsKey(id)) {
+                       return licenses.get(id);
+               } else {
+                       throw new MissingIDException(LICENSE_ELEMENT_NAME,
+                                       element.getName(), id);
+               }
+       }
+
+       /**
+        * @return Builds a with-license model from xml.
+        * @param element
+        *            not null
+        * @param licenses
+        *            not null
+        * @param organisations
+        *            not null
+        * 
+        * @throws MissingIDException
+        *             when referenced license isn't found in the collection
+        */
+       public WithLicense withLicense(Element element,
+                       Map<String, License> licenses,
+                       Map<String, Organisation> organisations) throws 
MissingIDException {
+               return new WithLicense(license(element, licenses),
+                               copyrightNotice(element), parameters(element),
+                               collectByOrganisations(element, organisations));
+       }
+
+       /**
+        * Extracts copyright notice content from with-license.
+        * 
+        * @param element
+        *            not null
+        * @return not null
+        */
+       private String copyrightNotice(final Element element) {
+               final String result;
+               final Element copyrightNoticeElement = element
+                               .getChild(COPYRIGHT_NOTICE_NAME);
+               if (copyrightNoticeElement == null) {
+                       result = null;
+               } else {
+                       result = copyrightNoticeElement.getTextTrim();
+               }
+               return result;
+       }
+
+       /**
+        * Builds a list of parameter values by name.
+        * 
+        * @param element
+        *            not null
+        * @return parameter values indexed by value, not null
+        * @throws DuplicateElementException
+        *             when two parameters shared the same name
+        */
+       @SuppressWarnings("unchecked")
+       public Map<String, String> parameters(Element element)
+                       throws DuplicateElementException {
+               final Map<String, String> results = new HashMap<String, 
String>();
+               final Element licenseParametersElement = element
+                               .getChild("license-parameters");
+               if (licenseParametersElement != null) {
+                       for (Element parameterElement : (List<Element>) 
licenseParametersElement
+                                       .getChildren("parameter")) {
+                               final String name = 
parameterElement.getChild("name")
+                                               .getTextTrim();
+                               if (results.containsKey(name)) {
+                                       throw new 
DuplicateElementException("Duplicate parameter '"
+                                                       + name + "'");
+                               }
+                               results.put(name, 
parameterElement.getChild("value")
+                                               .getTextTrim());
+                       }
+               }
+               return results;
+       }
+
+       /**
+        * Collects child with-licenses.
+        * 
+        * @param licenses
+        *            not null
+        * @param organisations
+        *            not null
+        * @param parent
+        *            not null
+        * @return not null, possibly empty
+        */
+       @SuppressWarnings("unchecked")
+       public Collection<WithLicense> withLicenses(Map<String, License> 
licenses,
+                       Map<String, Organisation> organisations, Element 
parent) {
+               final List<WithLicense> results = new ArrayList<WithLicense>();
+               for (Element withLicenseElement : (List<Element>) parent
+                               .getChildren("with-license")) {
+                       results.add(new 
JDomBuilder().withLicense(withLicenseElement,
+                                       licenses, organisations));
+               }
+               Collections.sort(results);
+               return results;
+       }
+
+       /**
+        * Collects child organisations of public domain.
+        * 
+        * @param organisations
+        *            not null
+        * @param parent
+        *            not null
+        * @return not null, possibly null
+        */
+       public Collection<ByOrganisation> publicDomain(
+                       final Map<String, Organisation> organisations, final 
Element parent) {
+               return new JDomBuilder().collectByOrganisations(
+                               parent.getChild("public-domain"), 
organisations);
+       }
+
+       /**
+        * Builds a within directory model from XML.
+        * 
+        * @param element
+        *            not null
+        * @param licenses
+        *            not null
+        * @param organisations
+        *            not null
+        * @return not null
+        */
+       public WithinDirectory withinDirectory(Element element,
+                       Map<String, License> licenses,
+                       Map<String, Organisation> organisations) {
+               return new WithinDirectory(element.getAttributeValue("dir"),
+                               withLicenses(licenses, organisations, element), 
publicDomain(
+                                               organisations, element));
+       }
+
+       /**
+        * Collects organisation definitions within document.
+        * 
+        * @param document
+        *            , not null
+        * @return organisations indexed by id, not null possibly empty
+        */
+       public Map<String, Organisation> mapOrganisations(Document document) {
+               final Map<String, Organisation> organisationsById = new 
HashMap<String, Organisation>();
+
+               final Element childOrganisations = 
document.getRootElement().getChild(
+                               "organisations");
+               if (childOrganisations != null) {
+                       @SuppressWarnings("unchecked")
+                       final List<Element> organisations = (List<Element>) 
childOrganisations
+                                       .getChildren("organisation");
+                       for (final Element element : organisations) {
+                               new JDomBuilder().organisation(element).storeIn(
+                                               organisationsById);
+                       }
+               }
+               return Collections.unmodifiableMap(organisationsById);
+       }
+
+       /**
+        * Collects license definitions within document.
+        * 
+        * @param document
+        *            , not null
+        * @return licenses, indexed by id, not null, possibly empty
+        */
+       public Map<String, License> mapLicenses(Document document) {
+               final Map<String, License> results = new HashMap<String, 
License>();
+               final Element licensesChild = 
document.getRootElement().getChild(
+                               "licenses");
+               if (licensesChild != null) {
+                       @SuppressWarnings("unchecked")
+                       final List<Element> children = (List<Element>) 
licensesChild
+                                       .getChildren();
+                       for (final Element element : children) {
+                               new 
JDomBuilder().license(element).storeIn(results);
+                       }
+               }
+               return Collections.unmodifiableMap(results);
+
+       }
+
+       /**
+        * Finds the primary license for the given document from the given 
licenses.
+        * 
+        * @param document
+        *            not null
+        * @param licenses
+        *            not null
+        * @return not null
+        */
+       public License primaryLicense(Document document,
+                       Map<String, License> licenses) {
+               final String idAttributeValue = 
getPrimaryLicenseElement(document)
+                               .getAttributeValue("id");
+               final License results = licenses.get(idAttributeValue);
+               if (results == null) {
+                       throw new MissingIDException(LICENSE_ELEMENT_NAME,
+                                       PRIMARY_LICENSE_NAME, idAttributeValue);
+               }
+               return results;
+       }
+
+       /**
+        * Gets the element representing the primary license.
+        * 
+        * @param document
+        *            not null
+        * @return not null
+        */
+       private Element getPrimaryLicenseElement(final Document document) {
+               return document.getRootElement().getChild(PRIMARY_LICENSE_NAME);
+       }
+
+       /**
+        * Gets the additional primary copyright notice from the document.
+        * 
+        * @param document
+        *            not null
+        * @return optional primary copyright notice, possibly null
+        */
+       public String primaryCopyrightNotice(final Document document) {
+               final String result;
+               final Element copyrightElement = 
getPrimaryLicenseElement(document)
+                               .getChild(COPYRIGHT_NOTICE_NAME);
+               if (copyrightElement == null) {
+                       result = null;
+               } else {
+                       result = copyrightElement.getTextTrim();
+               }
+               return result;
+       }
+
+       /**
+        * Collects notices in the given documents.
+        * 
+        * @param document
+        *            , not null
+        * @return notices indexed by id, immutable, not null, possibly empty
+        */
+       public Map<String, String> mapNotices(Document document) {
+               final Map<String, String> results = new HashMap<String, 
String>();
+               final Element noticesElement = 
document.getRootElement().getChild(
+                               "notices");
+               if (noticesElement != null) {
+                       @SuppressWarnings("unchecked")
+                       final List<Element> children = (List<Element>) 
noticesElement
+                                       .getChildren();
+                       for (final Element element : children) {
+                               results.put(element.getAttributeValue("id"),
+                                               element.getTextTrim());
+                       }
+               }
+               return Collections.unmodifiableMap(results);
+
+       }
+
+       /**
+        * Retrieves the text of the primary notice.
+        * 
+        * @param document
+        *            , not null
+        * @return the text of the primary notice, or null when there is no 
primary
+        *         notice
+        */
+       public String primaryNotice(Document document) {
+               final String result;
+               final Element primaryNoticeElement = document.getRootElement()
+                               .getChild("primary-notice");
+               if (primaryNoticeElement == null) {
+                       result = null;
+               } else {
+                       result = primaryNoticeElement.getText()
+                                       .replace(
+                                                       "${year}",
+                                                       
Integer.toString(Calendar.getInstance().get(
+                                                                       
Calendar.YEAR)));
+               }
+               return result;
+       }
+
+       /**
+        * Retrieves the ID of the primary organisation.
+        * 
+        * @param document
+        *            , not null
+        * @return the id of the primary organisation when set, otherwise null
+        */
+       public String primaryOrganisationId(final Document document) {
+               final String result;
+               final Element primaryOrganisationElement = 
document.getRootElement()
+                               .getChild("primary-organisation");
+               if (primaryOrganisationElement == null) {
+                       result = null;
+               } else {
+                       result = 
primaryOrganisationElement.getAttributeValue("id");
+               }
+               return result;
+       }
+
+       private WithinDirectory directory(final Element element,
+                       final Map<String, License> licenses,
+                       final Map<String, Organisation> organisations) {
+               return new JDomBuilder().withinDirectory(element, licenses,
+                               organisations);
+       }
+
+       /**
+        * Collects contents of the document.
+        * 
+        * @param document
+        *            not null
+        * @param licenses
+        *            not null
+        * @param organisations
+        *            not null
+        * @return not null, possibly empty
+        * @throws DuplicateElementException
+        *             when directory names are not unique
+        */
+       public Collection<WithinDirectory> collectContents(final Document 
document,
+                       final Map<String, License> licenses,
+                       final Map<String, Organisation> organisations)
+                       throws DuplicateElementException {
+               final Collection<WithinDirectory> results = new 
TreeSet<WithinDirectory>();
+               @SuppressWarnings("unchecked")
+               final List<Element> children = 
document.getRootElement().getChildren(
+                               "within");
+               for (Element element : children) {
+                       boolean addedSuccessfully = 
results.add(directory(element,
+                                       licenses, organisations));
+
+                       if (!addedSuccessfully) {
+                               throw new DuplicateElementException("Duplicate 
parameter '"
+                                               + 
element.getAttribute("dir").getValue() + "'");
+                       }
+               }
+               return results;
+       }
+
+       /**
+        * Builds work from the given document.
+        * 
+        * @param document
+        *            not null
+        * @return not null
+        */
+       public Descriptor build(final Document document) {
+               final Map<String, Organisation> organisations = 
mapOrganisations(document);
+               final Map<String, License> licenses = mapLicenses(document);
+               final Map<String, String> notices = mapNotices(document);
+               final License primaryLicense = primaryLicense(document, 
licenses);
+               final String primaryCopyrightNotice = 
primaryCopyrightNotice(document);
+               final String primaryNotice = primaryNotice(document);
+               final String primaryOrganisationId = 
primaryOrganisationId(document);
+               final Collection<WithinDirectory> contents = 
collectContents(document,
+                               licenses, organisations);
+               return new Descriptor(primaryLicense, primaryCopyrightNotice,
+                               primaryOrganisationId, primaryNotice, licenses, 
notices,
+                               organisations, contents);
+       }
+
+       public Descriptor build(final InputStream xmlStream) throws 
JDOMException,
+                       IOException {
+               return build(new SAXBuilder().build(xmlStream));
+       }
 }

Modified: 
creadur/whisker/trunk/apache-whisker-xml/src/main/java/org/apache/creadur/whisker/fromxml/MissingIDException.java
URL: 
http://svn.apache.org/viewvc/creadur/whisker/trunk/apache-whisker-xml/src/main/java/org/apache/creadur/whisker/fromxml/MissingIDException.java?rev=1616351&r1=1616350&r2=1616351&view=diff
==============================================================================
--- 
creadur/whisker/trunk/apache-whisker-xml/src/main/java/org/apache/creadur/whisker/fromxml/MissingIDException.java
 (original)
+++ 
creadur/whisker/trunk/apache-whisker-xml/src/main/java/org/apache/creadur/whisker/fromxml/MissingIDException.java
 Wed Aug  6 21:16:30 2014
@@ -30,8 +30,8 @@ public class MissingIDException extends 
     
     /**
      * Constructs an instance.
-     * @param organisationElementName not null
-     * @param name not null
+     * @param linkedElement not null
+     * @param linkingElement not null
      * @param id not null
      */
     public MissingIDException(final String linkedElement, final String 
linkingElement,

Modified: creadur/whisker/trunk/pom.xml
URL: 
http://svn.apache.org/viewvc/creadur/whisker/trunk/pom.xml?rev=1616351&r1=1616350&r2=1616351&view=diff
==============================================================================
--- creadur/whisker/trunk/pom.xml (original)
+++ creadur/whisker/trunk/pom.xml Wed Aug  6 21:16:30 2014
@@ -29,7 +29,7 @@
   <parent>
     <groupId>org.apache</groupId>
     <artifactId>apache</artifactId>
-    <version>13</version>
+    <version>14</version>
   </parent>
 
   <dependencyManagement>
@@ -49,7 +49,7 @@
       <dependency>
         <groupId>org.apache.commons</groupId>
         <artifactId>commons-lang3</artifactId>
-        <version>3.0</version>
+        <version>3.3.2</version>
       </dependency>
 
       <dependency>
@@ -61,7 +61,7 @@
       <dependency>
           <groupId>commons-io</groupId>
           <artifactId>commons-io</artifactId>
-          <version>2.1</version>
+          <version>2.4</version>
       </dependency>
 
       <dependency>
@@ -85,7 +85,7 @@
       <dependency>
         <groupId>org.jmock</groupId>
         <artifactId>jmock-junit3</artifactId>
-        <version>2.5.1</version>
+        <version>2.6.0</version>
         <scope>test</scope>
       </dependency>
 
@@ -106,7 +106,7 @@
   <properties>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     <target.jdk>1.5</target.jdk>
-    <junit.version>3.8.1</junit.version>
+    <junit.version>3.8.2</junit.version>
     <!--
     Publication to the website is a two phase operation:
 
@@ -132,6 +132,7 @@
 
   <!-- ================================ Build information -->
   <build>
+  <defaultGoal>clean install</defaultGoal>
     <pluginManagement>
       <plugins>
         <plugin>
@@ -145,7 +146,7 @@
         <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-site-plugin</artifactId>
-               <version>3.1</version>
+               <version>3.4</version>
                <configuration>
                  
<outputEncoding>${project.build.sourceEncoding}</outputEncoding>
                  <inputEncoding>${project.build.sourceEncoding}</inputEncoding>
@@ -156,17 +157,17 @@
                    <plugin>
                      <groupId>org.apache.maven.plugins</groupId>
                      <artifactId>maven-checkstyle-plugin</artifactId>
-                     <version>2.9.1</version>
+                     <version>2.12.1</version>
                    </plugin>
                    <plugin>
                      <groupId>org.apache.maven.plugins</groupId>
                      <artifactId>maven-javadoc-plugin</artifactId>
-                     <version>2.9</version>
+                     <version>2.9.1</version>
                    </plugin>
                    <plugin>
                      <groupId>org.apache.maven.plugins</groupId>
                      <artifactId>maven-jxr-plugin</artifactId>
-                     <version>2.3</version>
+                     <version>2.4</version>
                      <configuration>
                        <aggregate>true</aggregate>
                        <linkJavadoc>true</linkJavadoc>
@@ -175,11 +176,11 @@
                    <plugin>
                      <groupId>org.apache.maven.plugins</groupId>
                      <artifactId>maven-surefire-report-plugin</artifactId>
-                     <version>2.12</version>
+                     <version>2.17</version>
                    </plugin>
                    <plugin>
                      <artifactId>maven-pmd-plugin</artifactId>
-                     <version>2.7.1</version>
+                     <version>3.1</version>
                      <configuration>
                        <linkXRef>true</linkXRef>
                        <sourceEncoding>utf-8</sourceEncoding>
@@ -195,7 +196,7 @@
                    <plugin>
                      <groupId>org.apache.maven.plugins</groupId>
                      <artifactId>maven-changes-plugin</artifactId>
-                     <version>2.7.1</version>
+                     <version>2.10</version>
                      <reportSets>
                        <reportSet>
                          <reports>
@@ -208,13 +209,13 @@
                    <plugin>
                      <groupId>org.codehaus.mojo</groupId>
                      <artifactId>jdepend-maven-plugin</artifactId>
-                     <version>2.0-beta-2</version>
+                     <version>2.0</version>
                    </plugin>
                    <!-- cobertura plugin -->
                    <plugin>
                      <groupId>org.codehaus.mojo</groupId>
                      <artifactId>cobertura-maven-plugin</artifactId>
-                     <version>2.5.1</version>
+                     <version>2.6</version>
                    </plugin>
                    <!-- catch code tags -->
                    <plugin>
@@ -239,12 +240,12 @@
                    <plugin>
                      <groupId>org.codehaus.mojo</groupId>
                      <artifactId>findbugs-maven-plugin</artifactId>
-                     <version>2.5</version>
+                     <version>3.0.0</version>
                    </plugin>
                    <plugin>
                      <groupId>org.apache.maven.plugins</groupId>
                      <artifactId>maven-project-info-reports-plugin</artifactId>
-                     <version>2.4</version>
+                     <version>2.7</version>
                    </plugin>
 
                  </reportPlugins>
@@ -266,7 +267,7 @@
           <plugin>
             <groupId>org.apache.maven.plugins</groupId>
             <artifactId>maven-scm-publish-plugin</artifactId>
-            <version>1.0-beta-2</version>
+            <version>1.1</version>
             <extensions>true</extensions>
             <configuration>
               <!-- svn location for publication -->
@@ -281,7 +282,7 @@
       <extension>
         <groupId>org.apache.maven.wagon</groupId>
          <artifactId>wagon-ssh</artifactId>
-         <version>1.0-beta-7</version>
+         <version>2.6</version>
       </extension>
     </extensions>
   </build>
@@ -315,6 +316,16 @@
     <system>JIRA</system>
     <url>https://issues.apache.org/jira/browse/WHISKER</url>
   </issueManagement>
+  
+       <!-- TODO
+       <ciManagement>
+               <system>Jenkins</system>
+               <url>http://ci.apache.org/builders/whisker_trunk</url>
+               Jenkins builds are at:
+               https://builds.apache.org/job/Creadur-Whisker/ - check Java5 
compliance and run all tests
+               https://builds.apache.org/job/Creadur-Whisker-Site/ - generate 
mvn site
+       </ciManagement>
+        -->
 
   <mailingLists>
     <mailingList>


Reply via email to