Author: vsiveton Date: Fri Dec 10 12:19:07 2010 New Revision: 1044321 URL: http://svn.apache.org/viewvc?rev=1044321&view=rev Log: MDOAP-25: foaf:Organization usage doesn't comply with DoaP/FoaF specs. Submitted by: Tim Fliss Reviewed by: Vincent Siveton
o patch applied with formatting Modified: maven/plugins/trunk/maven-doap-plugin/src/main/java/org/apache/maven/plugin/doap/DoapMojo.java maven/plugins/trunk/maven-doap-plugin/src/main/java/org/apache/maven/plugin/doap/DoapUtil.java maven/plugins/trunk/maven-doap-plugin/src/test/java/org/apache/maven/plugin/doap/DoapMojoTest.java maven/plugins/trunk/maven-doap-plugin/src/test/java/org/apache/maven/plugin/doap/stubs/AsfDoapProjectStub.java maven/plugins/trunk/maven-doap-plugin/src/test/java/org/apache/maven/plugin/doap/stubs/DoapProjectStub.java maven/plugins/trunk/maven-doap-plugin/src/test/resources/unit/doap-configuration/doap-configuration-plugin-config.xml Modified: maven/plugins/trunk/maven-doap-plugin/src/main/java/org/apache/maven/plugin/doap/DoapMojo.java URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-doap-plugin/src/main/java/org/apache/maven/plugin/doap/DoapMojo.java?rev=1044321&r1=1044320&r2=1044321&view=diff ============================================================================== --- maven/plugins/trunk/maven-doap-plugin/src/main/java/org/apache/maven/plugin/doap/DoapMojo.java (original) +++ maven/plugins/trunk/maven-doap-plugin/src/main/java/org/apache/maven/plugin/doap/DoapMojo.java Fri Dec 10 12:19:07 2010 @@ -33,6 +33,8 @@ import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Locale; +import java.util.Map; +import java.util.Set; import java.util.TimeZone; import org.apache.maven.artifact.Artifact; @@ -68,11 +70,10 @@ import org.codehaus.plexus.util.xml.XMLW import org.codehaus.plexus.util.xml.XmlWriterUtil; /** - * Generate a <a href="http://usefulinc.com/ns/doap">Description of a Project (DOAP)</a> - * file from the main information found in a POM. - * <br/> - * <b>Note</b>: The generated file is tailored for use by projects at - * <a href="http://projects.apache.org/doap.html">Apache</a>. + * Generate a <a href="http://usefulinc.com/ns/doap">Description of a Project (DOAP)</a> file from the main information + * found in a POM. <br/> + * <b>Note</b>: The generated file is tailored for use by projects at <a + * href="http://projects.apache.org/doap.html">Apache</a>. * * @author Jason van Zyl * @author <a href="mailto:vincent.sive...@gmail.com">Vincent Siveton</a> @@ -154,7 +155,7 @@ public class DoapMojo * The name of the DOAP file that will be generated. * * @parameter expression="${doapFile}" - * default-value="${project.reporting.outputDirectory}/doap_${project.artifactId}.rdf" + * default-value="${project.reporting.outputDirectory}/doap_${project.artifactId}.rdf" * @required */ private File doapFile; @@ -188,7 +189,7 @@ public class DoapMojo * * @parameter expression="${category}" * @deprecated Since 1.0. Instead of, configure <code>category</code> property in <code>doapOptions</code> - * parameter. + * parameter. */ private String category; @@ -197,22 +198,22 @@ public class DoapMojo * * @parameter expression="${language}" * @deprecated Since 1.0. Instead of, configure <code>programmingLanguage</code> property in - * <code>doapOptions</code> parameter. + * <code>doapOptions</code> parameter. */ private String language; /** - * Specific DOAP parameters, i.e. options that POM doesn't have any notions. - * <br/> + * Specific DOAP parameters, i.e. options that POM doesn't have any notions. <br/> * Example: + * * <pre> * <doapOptions> * <programmingLanguage>java</programmingLanguage> * </doapOptions> * </pre> + * * <br/> - * See <a href="./apidocs/org/apache/maven/plugin/doap/options/DoapOptions.html">Javadoc</a> - * <br/> + * See <a href="./apidocs/org/apache/maven/plugin/doap/options/DoapOptions.html">Javadoc</a> <br/> * * @parameter expression="${doapOptions}" * @since 1.0 @@ -222,9 +223,9 @@ public class DoapMojo /** * Specific ASF extensions parameters, i.e. options that POM doesn't have any notions but required by ASF DOAP - * requirements. - * <br/> + * requirements. <br/> * Example: + * * <pre> * <asfExtOptions> * <included>true</included> @@ -233,16 +234,15 @@ public class DoapMojo * ... * </asfExtOptions> * </pre> + * * <b>Note</b>: By default, <code>asfExtOptions/included</code> is set to <code>true</code> to include the ASF - * extensions. - * <br/> - * See <a href="./apidocs/org/apache/maven/plugin/doap/options/ASFExtOptions.html">Javadoc</a> - * <br/> + * extensions. <br/> + * See <a href="./apidocs/org/apache/maven/plugin/doap/options/ASFExtOptions.html">Javadoc</a> <br/> * * @parameter expression="${asfExtOptions}" * @since 1.0 * @see <a href="http://svn.apache.org/repos/asf/infrastructure/site-tools/trunk/projects/asfext"> - * http://svn.apache.org/repos/asf/infrastructure/site-tools/trunk/projects/asfext</a> + * http://svn.apache.org/repos/asf/infrastructure/site-tools/trunk/projects/asfext</a> * @see <a href="http://projects.apache.org/docs/pmc.html">http://projects.apache.org/docs/pmc.html</a> * @see <a href="http://projects.apache.org/docs/standards.html">http://projects.apache.org/docs/standards.html</a> */ @@ -250,12 +250,9 @@ public class DoapMojo /** * The value for the <code>xml:lang</code> attribute used by the <code><rdf:RDF/><code>, - * <code><description/></code> and <code><shortdesc/></code> elements. - * <br/> - * POM doesn't have any notions about language. - * <br/> - * See <a href="http://www.w3.org/TR/REC-xml/#sec-lang-tag">http://www.w3.org/TR/REC-xml/#sec-lang-tag</a> - * <br/> + * <code><description/></code> and <code><shortdesc/></code> elements. <br/> + * POM doesn't have any notions about language. <br/> + * See <a href="http://www.w3.org/TR/REC-xml/#sec-lang-tag">http://www.w3.org/TR/REC-xml/#sec-lang-tag</a> <br/> * * @parameter expression="${lang}" default-value="en" * @required @@ -264,8 +261,8 @@ public class DoapMojo private String lang; /** - * The <code>about</code> URI-reference which should be displayed in the DOAP file. - * Example: + * The <code>about</code> URI-reference which should be displayed in the DOAP file. Example: + * * <pre> * <rdf:RDF> * <Project rdf:about="http://maven.apache.org/"> @@ -273,9 +270,9 @@ public class DoapMojo * </Project> * </rdf:RDF> * </pre> + * * See <a href="http://www.w3.org/TR/1999/REC-rdf-syntax-19990222/#aboutAttr"> - * http://www.w3.org/TR/1999/REC-rdf-syntax-19990222/#aboutAttr</a> - * <br/> + * http://www.w3.org/TR/1999/REC-rdf-syntax-19990222/#aboutAttr</a> <br/> * * @parameter expression="${about}" default-value="${project.url}" * @since 1.0 @@ -414,6 +411,9 @@ public class DoapMojo } writer.endElement(); // Project + + writeOrganizations( writer ); + writer.endElement(); // rdf:RDF try @@ -537,10 +537,8 @@ public class DoapMojo if ( StringUtils.isNotEmpty( doapOptions.getOldHomepage() ) ) { XmlWriterUtil.writeLineBreak( writer ); - XmlWriterUtil.writeCommentText( - writer, - "URL of a project's past homepage, associated with exactly one project.", - 2 ); + XmlWriterUtil.writeCommentText( writer, + "URL of a project's past homepage, associated with exactly one project.", 2 ); DoapUtil.writeRdfResourceElement( writer, "old-homepage", doapOptions.getOldHomepage() ); } } @@ -550,7 +548,7 @@ public class DoapMojo * * @param writer not null * @see <a href="http://usefulinc.com/ns/doap#programming-language"> - * http://usefulinc.com/ns/doap#programming-language</a> + * http://usefulinc.com/ns/doap#programming-language</a> */ private void writeProgrammingLanguage( XMLWriter writer ) { @@ -566,8 +564,7 @@ public class DoapMojo { if ( asfExtOptions.isIncluded() && !ASFExtOptions.isProgrammingLanguageSupportedByASF( language ) ) { - getLog().warn( - "The programming language '" + language + "' is not supported by ASF. " + getLog().warn( "The programming language '" + language + "' is not supported by ASF. " + "Refer you to http://projects.apache.org/languages.html" ); } @@ -582,8 +579,7 @@ public class DoapMojo if ( asfExtOptions.isIncluded() && !ASFExtOptions.isProgrammingLanguageSupportedByASF( languages[i].trim() ) ) { - getLog().warn( - "The programming language '" + languages[i].trim() + "' is not supported by ASF. " + getLog().warn( "The programming language '" + languages[i].trim() + "' is not supported by ASF. " + "Refer you to http://projects.apache.org/languages.html" ); } @@ -605,7 +601,7 @@ public class DoapMojo return; } - //TODO: how to lookup category, map it, or just declare it. + // TODO: how to lookup category, map it, or just declare it. XmlWriterUtil.writeLineBreak( writer ); XmlWriterUtil.writeCommentText( writer, "A category of project.", 2 ); @@ -613,15 +609,13 @@ public class DoapMojo { if ( asfExtOptions.isIncluded() && !ASFExtOptions.isCategorySupportedByASF( category ) ) { - getLog().warn( - "The given category '" + category + "' is not supported by ASF. " + getLog().warn( "The given category '" + category + "' is not supported by ASF. " + "Refer you to http://projects.apache.org/categories.html" ); } if ( asfExtOptions.isIncluded() ) { - DoapUtil - .writeRdfResourceElement( writer, "category", "http://projects.apache.org/category/" + category ); + DoapUtil.writeRdfResourceElement( writer, "category", "http://projects.apache.org/category/" + category ); } else { @@ -636,8 +630,7 @@ public class DoapMojo { if ( asfExtOptions.isIncluded() && !ASFExtOptions.isCategorySupportedByASF( categories[i] ) ) { - getLog().warn( - "The given category '" + categories[i] + "' is not supported by ASF. " + getLog().warn( "The given category '" + categories[i] + "' is not supported by ASF. " + "Refer you to http://projects.apache.org/categories.html" ); } @@ -764,8 +757,8 @@ public class DoapMojo XmlWriterUtil.writeLineBreak( writer ); XmlWriterUtil.writeCommentText( writer, "The URI of the license the software is distributed under.", 2 ); - //TODO: how to map to usefulinc site, or if this is necessary, the OSI page might - // be more appropriate. + // TODO: how to map to usefulinc site, or if this is necessary, the OSI page might + // be more appropriate. for ( Iterator it = project.getLicenses().iterator(); it.hasNext(); ) { License license = (License) it.next(); @@ -864,8 +857,9 @@ public class DoapMojo private void writeReleases( XMLWriter writer ) throws MojoExecutionException { - Artifact artifact = artifactFactory.createArtifact( project.getGroupId(), project.getArtifactId(), project - .getVersion(), null, project.getPackaging() ); + Artifact artifact = + artifactFactory.createArtifact( project.getGroupId(), project.getArtifactId(), project.getVersion(), null, + project.getPackaging() ); RepositoryMetadata metadata = new ArtifactRepositoryMetadata( artifact ); for ( Iterator it = remoteRepositories.iterator(); it.hasNext(); ) @@ -941,8 +935,9 @@ public class DoapMojo { ArtifactRepository repo = (ArtifactRepository) it2.next(); - Artifact artifactRelease = artifactFactory.createArtifact( project.getGroupId(), project - .getArtifactId(), version, null, project.getPackaging() ); + Artifact artifactRelease = + artifactFactory.createArtifact( project.getGroupId(), project.getArtifactId(), version, null, + project.getPackaging() ); if ( artifactRelease == null ) { @@ -980,9 +975,8 @@ public class DoapMojo } catch ( ParseException e ) { - getLog().error( - "Unable to parse date '" - + metadata.getMetadata().getVersioning().getLastUpdated() + "'" ); + getLog().error( "Unable to parse date '" + metadata.getMetadata().getVersioning().getLastUpdated() + + "'" ); continue; } @@ -1037,6 +1031,7 @@ public class DoapMojo /** * Write a DOAP repository, for instance: + * * <pre> * <repository> * <SVNRepository> @@ -1078,10 +1073,9 @@ public class DoapMojo else { /* - * Supported DOAP repositories actually unsupported by SCM: - * BitKeeper (http://usefulinc.com/ns/doap#BKRepository) - * Arch (http://usefulinc.com/ns/doap#ArchRepository) - * Other SCM repos are unsupported by DOAP. + * Supported DOAP repositories actually unsupported by SCM: BitKeeper + * (http://usefulinc.com/ns/doap#BKRepository) Arch (http://usefulinc.com/ns/doap#ArchRepository) Other SCM + * repos are unsupported by DOAP. */ writer.startElement( "Repository" ); @@ -1124,7 +1118,7 @@ public class DoapMojo XmlWriterUtil.writeCommentText( writer, "Contributed persons", 2 ); } - List maintainers = DoapUtil.getDevelopersOrContributorsWithMaintainerRole( i18n, developersOrContributors ); + List maintainers = DoapUtil.getDevelopersOrContributorsWithMaintainerRole( i18n, developersOrContributors ); List developers = DoapUtil.getDevelopersOrContributorsWithDeveloperRole( i18n, developersOrContributors ); List documenters = DoapUtil.getDevelopersOrContributorsWithDocumenterRole( i18n, developersOrContributors ); List translators = DoapUtil.getDevelopersOrContributorsWithTranslatorRole( i18n, developersOrContributors ); @@ -1171,6 +1165,7 @@ public class DoapMojo /** * Write a DOAP maintainer or developer or documenter or translator or tester or helper, for instance: + * * <pre> * <maintainer> * <foaf:Person> @@ -1273,7 +1268,9 @@ public class DoapMojo String name; String email; String organization; + String organizationUrl; String homepage; + String nodeId = null; if ( Developer.class.isAssignableFrom( developerOrContributor.getClass() ) ) { @@ -1281,6 +1278,7 @@ public class DoapMojo name = d.getName(); email = d.getEmail(); organization = d.getOrganization(); + organizationUrl = d.getOrganizationUrl(); homepage = d.getUrl(); } else @@ -1289,6 +1287,7 @@ public class DoapMojo name = c.getName(); email = c.getEmail(); organization = c.getOrganization(); + organizationUrl = c.getOrganizationUrl(); homepage = c.getUrl(); } @@ -1298,8 +1297,19 @@ public class DoapMojo return; } + if ( !StringUtils.isEmpty( organization ) || !StringUtils.isEmpty( organizationUrl ) ) + { + DoapUtil.Organization doapOrganization = DoapUtil.addOrganization( organization, organizationUrl ); + nodeId = DoapUtil.getNodeId(); + doapOrganization.addMember( nodeId ); + } + writer.startElement( doapType ); writer.startElement( "foaf:Person" ); + if ( StringUtils.isNotEmpty( nodeId ) ) + { + writer.addAttribute( "rdf:nodeID", nodeId ); + } writer.startElement( "foaf:name" ); writer.writeText( name ); writer.endElement(); // foaf:name @@ -1307,9 +1317,9 @@ public class DoapMojo { DoapUtil.writeRdfResourceElement( writer, "foaf:mbox", "mailto:" + email ); } - if ( StringUtils.isNotEmpty( organization ) ) + if ( StringUtils.isNotEmpty( organization ) || StringUtils.isNotEmpty( organizationUrl ) ) { - DoapUtil.writeRdfResourceElement( writer, "foaf:Organization", organization ); + DoapUtil.addOrganization( organization, organizationUrl ); } if ( StringUtils.isNotEmpty( homepage ) ) { @@ -1358,7 +1368,7 @@ public class DoapMojo * * @param writer not null * @see <a href="http://svn.apache.org/repos/asf/infrastructure/site-tools/trunk/projects/asfext"> - * http://svn.apache.org/repos/asf/infrastructure/site-tools/trunk/projects/asfext</a> + * http://svn.apache.org/repos/asf/infrastructure/site-tools/trunk/projects/asfext</a> * @see <a href="http://projects.apache.org/docs/pmc.html">http://projects.apache.org/docs/pmc.html</a> */ private void writeASFext( XMLWriter writer ) @@ -1375,8 +1385,7 @@ public class DoapMojo { if ( StringUtils.isEmpty( project.getUrl() ) ) { - getLog().warn( - "No project url discovered! According http://projects.apache.org/docs/pmc.html, " + getLog().warn( "No project url discovered! According http://projects.apache.org/docs/pmc.html, " + "asfext:pmc is required" ); } else @@ -1394,8 +1403,7 @@ public class DoapMojo { if ( StringUtils.isEmpty( project.getName() ) ) { - getLog().warn( - "No project name discovered! According http://projects.apache.org/docs/pmc.html, " + getLog().warn( "No project name discovered! According http://projects.apache.org/docs/pmc.html, " + "asfext:name is required" ); } else @@ -1415,8 +1423,7 @@ public class DoapMojo // asfext:charter if ( StringUtils.isEmpty( asfExtOptions.getCharter() ) ) { - getLog().warn( - "No charter specified! According http://projects.apache.org/docs/pmc.html, " + getLog().warn( "No charter specified! According http://projects.apache.org/docs/pmc.html, " + "charter is required" ); } else @@ -1446,8 +1453,7 @@ public class DoapMojo } else { - getLog().warn( - "No chair man discovered! According http://projects.apache.org/docs/pmc.html, " + getLog().warn( "No chair man discovered! According http://projects.apache.org/docs/pmc.html, " + "asfext:chair is required" ); } } @@ -1472,7 +1478,7 @@ public class DoapMojo * * @param writer not null * @see <a href="http://svn.apache.org/repos/asf/infrastructure/site-tools/trunk/projects/asfext"> - * http://svn.apache.org/repos/asf/infrastructure/site-tools/trunk/projects/asfext</a> + * http://svn.apache.org/repos/asf/infrastructure/site-tools/trunk/projects/asfext</a> * @see <a href="http://projects.apache.org/docs/standards.html">http://projects.apache.org/docs/standards.html</a> */ private void writeASFImplements( XMLWriter writer ) @@ -1491,8 +1497,7 @@ public class DoapMojo if ( StringUtils.isEmpty( standard.getTitle() ) ) { - getLog().warn( - "No title specified! According http://projects.apache.org/docs/standards.html, " + getLog().warn( "No title specified! According http://projects.apache.org/docs/standards.html, " + "asfext:title is required" ); } else @@ -1504,8 +1509,7 @@ public class DoapMojo if ( StringUtils.isEmpty( standard.getBody() ) ) { - getLog().warn( - "No body specified! According http://projects.apache.org/docs/standards.html, " + getLog().warn( "No body specified! According http://projects.apache.org/docs/standards.html, " + "asfext:body is required" ); } else @@ -1517,8 +1521,7 @@ public class DoapMojo if ( StringUtils.isEmpty( standard.getId() ) ) { - getLog().warn( - "No id specified! According http://projects.apache.org/docs/standards.html, " + getLog().warn( "No id specified! According http://projects.apache.org/docs/standards.html, " + "asfext:id is required" ); } else @@ -1540,14 +1543,54 @@ public class DoapMojo } } + /** + * Write a Foaf Organization, for instance: + * + * <pre> + * <<foaf:Organization> + * <foaf:name>YoyoDyne</foaf:name> + * <foaf:homepage rdf:resource="http://yoyodyne.example.org"/> + * <foaf:member rdf:nodeID="benny_profane"> + * </foaf:Organization> + * </pre> + * + * @param writer not null + * @param developersOrContributors list of <code>{...@link Developer}/{...@link Contributor}</code> + * @param doapType not null + * @see #writeDeveloperOrContributor(XMLWriter, Object, String) + */ + private void writeOrganizations( XMLWriter writer ) + { + Set organizations = DoapUtil.getOrganizations(); + + for ( Iterator it = organizations.iterator(); it.hasNext(); ) + { + DoapUtil.Organization organization = (DoapUtil.Organization) ( (Map.Entry) it.next() ).getValue(); + writer.startElement( "foaf:Organization" ); + if ( !StringUtils.isEmpty( organization.getName() ) ) + { + DoapUtil.writeElement( writer, "foaf:name", organization.getName() ); + } + if ( !StringUtils.isEmpty( organization.getUrl() ) ) + { + DoapUtil.writeRdfResourceElement( writer, "foaf:homepage", organization.getUrl() ); + } + List members = organization.getMembers(); + for ( Iterator memberIterator = members.iterator(); memberIterator.hasNext(); ) + { + DoapUtil.writeRdfNodeIdElement( writer, "foaf:member", (String) memberIterator.next() ); + } + writer.endElement(); // foaf:Organization + } + } + // ---------------------------------------------------------------------- // Static methods // ---------------------------------------------------------------------- /** - * Compose a URL from two parts: a base URL and a file path. This method - * makes sure that there will not be two slash '/' characters after each - * other. + * Compose a URL from two parts: a base URL and a file path. This method makes sure that there will not be two slash + * '/' characters after each other. * * @param base The base URL * @param path The file Modified: maven/plugins/trunk/maven-doap-plugin/src/main/java/org/apache/maven/plugin/doap/DoapUtil.java URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-doap-plugin/src/main/java/org/apache/maven/plugin/doap/DoapUtil.java?rev=1044321&r1=1044320&r2=1044321&view=diff ============================================================================== --- maven/plugins/trunk/maven-doap-plugin/src/main/java/org/apache/maven/plugin/doap/DoapUtil.java (original) +++ maven/plugins/trunk/maven-doap-plugin/src/main/java/org/apache/maven/plugin/doap/DoapUtil.java Fri Dec 10 12:19:07 2010 @@ -28,9 +28,11 @@ import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.Iterator; +import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Set; import java.util.Properties; import org.apache.maven.model.Contributor; @@ -61,6 +63,12 @@ public class DoapUtil /** RDF resource attribute */ protected static final String RDF_RESOURCE = "rdf:resource"; + /** RDF nodeID attribute */ + protected static final String RDF_NODE_ID = "rdf:nodeID"; + + /** DoaP Organizations stored by name */ + private static Map organizations = new HashMap(); + /** * Write comments in the DOAP file header * @@ -162,6 +170,28 @@ public class DoapUtil } /** + * @param writer not null + * @param name not null + * @param value could be null. In this case, the element is not written. + * @throws IllegalArgumentException if name is null or empty + */ + public static void writeRdfNodeIdElement( XMLWriter writer, String name, String value ) + throws IllegalArgumentException + { + if ( StringUtils.isEmpty( name ) ) + { + throw new IllegalArgumentException( "name should be defined" ); + } + + if ( value != null ) + { + writer.startElement( name ); + writer.addAttribute( RDF_NODE_ID, value ); + writer.endElement(); + } + } + + /** * @param i18n the internationalization component * @param developersOrContributors list of <code>{...@link Developer}/{...@link Contributor}</code> * @return a none null list of developers or contributors which have a <code>developer</code> DOAP role. @@ -232,6 +262,103 @@ public class DoapUtil } /** + * Utility class for keeping track of DOAP organizations in the DoaP mojo. + * + * @author <a href="mailto:t.fl...@gmail.com">Tim Fliss</a> + * @version $Id$ + * @since 1.1 + */ + public static class Organization + { + private String name; + + private String url; + + private List members = new LinkedList(); + + public Organization( String name, String url ) + { + this.name = name; + this.url = url; + } + + public void setName( String name ) + { + this.name = name; + } + + public String getName() + { + return name; + } + + public void setUrl( String url ) + { + this.url = url; + } + + public String getUrl() + { + return url; + } + + public void addMember( String nodeId ) + { + members.add( nodeId ); + } + + public List getMembers() + { + return members; + } + }; + + /** + * put an organization from the pom file in the organization list. + * + * @param name from the pom file (e.g. Yoyodyne) + * @param url from the pom file (e.g. http://yoyodyne.example.org/about) + * @return the existing organization if a duplicate, or a new one. + */ + public static Organization addOrganization( String name, String url ) + { + Organization organization = (Organization) organizations.get( name ); + + if ( organization == null ) + { + organization = new DoapUtil.Organization( name, url ); + } + + organizations.put( name, organization ); + return organization; + } + + // unique RDF blank node index scoped internal to the DOAP file + private static int nodeNumber = 1; + + /** + * get a unique (within the DoaP file) RDF blank node ID + * + * @return the nodeID + * @see <a href="http://www.w3.org/TR/rdf-syntax-grammar/#section-Syntax-blank-nodes"> + * http://www.w3.org/TR/rdf-syntax-grammar/#section-Syntax-blank-nodes</a> + */ + public static String getNodeId() + { + return "b" + nodeNumber++; + } + + /** + * get the set of Organizations that people are members of + * + * @return Map.EntrySet of DoapUtil.Organization + */ + public static Set getOrganizations() + { + return organizations.entrySet(); + } + + /** * Validate the given DOAP file. * * @param doapFile not null and should exists. @@ -275,18 +402,16 @@ public class DoapUtil // ---------------------------------------------------------------------- /** - * Filter the developers/contributors roles by the keys from {...@link I18N#getBundle()}. - * <br/> + * Filter the developers/contributors roles by the keys from {...@link I18N#getBundle()}. <br/> * I18N roles supported in DOAP, i.e. <code>maintainer</code>, <code>developer</code>, <code>documenter</code>, - * <code>translator</code>, <code>tester</code>, <code>helper</code>. - * <br/> + * <code>translator</code>, <code>tester</code>, <code>helper</code>. <br/> * <b>Note:</b> Actually, only English keys are used. * * @param i18n i18n component * @param developersOrContributors list of <code>{...@link Developer}/{...@link Contributor}</code> * @return a none null map with <code>maintainers</code>, <code>developers</code>, <code>documenters</code>, - * <code>translators</code>, <code>testers</code>, <code>helpers</code>, <code>unknowns</code> as keys and list of - * <code>{...@link Developer}/{...@link Contributor}</code> as value. + * <code>translators</code>, <code>testers</code>, <code>helpers</code>, <code>unknowns</code> as keys and + * list of <code>{...@link Developer}/{...@link Contributor}</code> as value. */ private static Map filterDevelopersOrContributorsByDoapRoles( I18N i18n, List developersOrContributors ) { Modified: maven/plugins/trunk/maven-doap-plugin/src/test/java/org/apache/maven/plugin/doap/DoapMojoTest.java URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-doap-plugin/src/test/java/org/apache/maven/plugin/doap/DoapMojoTest.java?rev=1044321&r1=1044320&r2=1044321&view=diff ============================================================================== --- maven/plugins/trunk/maven-doap-plugin/src/test/java/org/apache/maven/plugin/doap/DoapMojoTest.java (original) +++ maven/plugins/trunk/maven-doap-plugin/src/test/java/org/apache/maven/plugin/doap/DoapMojoTest.java Fri Dec 10 12:19:07 2010 @@ -65,8 +65,7 @@ public class DoapMojoTest throws Exception { File pluginXmlFile = - new File( getBasedir(), - "src/test/resources/unit/doap-configuration/doap-configuration-plugin-config.xml" ); + new File( getBasedir(), "src/test/resources/unit/doap-configuration/doap-configuration-plugin-config.xml" ); DoapMojo mojo = (DoapMojo) lookupMojo( "generate", pluginXmlFile ); assertNotNull( "Mojo found.", mojo ); @@ -101,6 +100,14 @@ public class DoapMojoTest // ASF ext assertFalse( readed.indexOf( "<asfext:pmc rdf:resource=\"" + mavenProject.getUrl() + "\"/>" ) != -1 ); assertFalse( readed.indexOf( "<asfext:name>" + mavenProject.getName() + "</name>" ) != -1 ); + + // Developers and Organizations + assertTrue( readed.indexOf( "<maintainer>" ) != -1 ); + assertTrue( readed.indexOf( "<foaf:Person rdf:nodeID=\"b1\">" ) != -1 ); + assertTrue( readed.indexOf( "<foaf:name>Jane Doe</foaf:name>" ) != -1 ); + assertTrue( readed.indexOf( "<foaf:Organization>" ) != -1 ); + assertTrue( readed.indexOf( "<foaf:homepage rdf:resource=\"http://www.example.org\"/>" ) != -1 ); + assertTrue( readed.indexOf( "<foaf:member rdf:nodeID=\"b1\"/>" ) != -1 ); } /** @@ -126,8 +133,7 @@ public class DoapMojoTest mojo.execute(); - File doapFile = - new File( getBasedir(), "target/test/unit/asf-doap-configuration/asf-doap-configuration.rdf" ); + File doapFile = new File( getBasedir(), "target/test/unit/asf-doap-configuration/asf-doap-configuration.rdf" ); assertTrue( "Doap File was not generated!", doapFile.exists() ); String readed = readFile( doapFile ); @@ -137,8 +143,7 @@ public class DoapMojoTest // Pure DOAP assertTrue( readed.indexOf( "<rdf:RDF xml:lang=\"en\" xmlns=\"http://usefulinc.com/ns/doap#\" " + "xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" " - + "xmlns:foaf=\"http://xmlns.com/foaf/0.1/\" " - + "xmlns:asfext=\"http://projects.apache.org/ns/asfext#\">" ) != -1 ); + + "xmlns:foaf=\"http://xmlns.com/foaf/0.1/\" " + "xmlns:asfext=\"http://projects.apache.org/ns/asfext#\">" ) != -1 ); if ( StringUtils.isNotEmpty( mavenProject.getUrl() ) ) { assertTrue( readed.indexOf( "<Project rdf:about=\"" + mavenProject.getUrl() + "\">" ) != -1 ); @@ -184,8 +189,7 @@ public class DoapMojoTest private static List getRemoteRepositories() { ArtifactRepository repository = - new DefaultArtifactRepository( "central", "http://repo1.maven.org/maven2", - new DefaultRepositoryLayout() ); + new DefaultArtifactRepository( "central", "http://repo1.maven.org/maven2", new DefaultRepositoryLayout() ); return Collections.singletonList( repository ); } } Modified: maven/plugins/trunk/maven-doap-plugin/src/test/java/org/apache/maven/plugin/doap/stubs/AsfDoapProjectStub.java URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-doap-plugin/src/test/java/org/apache/maven/plugin/doap/stubs/AsfDoapProjectStub.java?rev=1044321&r1=1044320&r2=1044321&view=diff ============================================================================== --- maven/plugins/trunk/maven-doap-plugin/src/test/java/org/apache/maven/plugin/doap/stubs/AsfDoapProjectStub.java (original) +++ maven/plugins/trunk/maven-doap-plugin/src/test/java/org/apache/maven/plugin/doap/stubs/AsfDoapProjectStub.java Fri Dec 10 12:19:07 2010 @@ -20,6 +20,7 @@ package org.apache.maven.plugin.doap.stu */ import java.io.File; +import java.util.List; import org.apache.maven.model.Model; import org.apache.maven.model.io.xpp3.MavenXpp3Reader; @@ -60,6 +61,7 @@ public class AsfDoapProjectStub setDescription( model.getDescription() ); setUrl( model.getUrl() ); setPackaging( model.getPackaging() ); + setDevelopers( model.getDevelopers() ); } /** {...@inheritdoc} */ @@ -67,4 +69,10 @@ public class AsfDoapProjectStub { return new File( super.getBasedir() + "/src/test/resources/unit/asf-doap-configuration/" ); } + + /** {...@inheritdoc} */ + public List getDevelopers() + { + return model.getDevelopers(); + } } Modified: maven/plugins/trunk/maven-doap-plugin/src/test/java/org/apache/maven/plugin/doap/stubs/DoapProjectStub.java URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-doap-plugin/src/test/java/org/apache/maven/plugin/doap/stubs/DoapProjectStub.java?rev=1044321&r1=1044320&r2=1044321&view=diff ============================================================================== --- maven/plugins/trunk/maven-doap-plugin/src/test/java/org/apache/maven/plugin/doap/stubs/DoapProjectStub.java (original) +++ maven/plugins/trunk/maven-doap-plugin/src/test/java/org/apache/maven/plugin/doap/stubs/DoapProjectStub.java Fri Dec 10 12:19:07 2010 @@ -20,6 +20,7 @@ package org.apache.maven.plugin.doap.stu */ import java.io.File; +import java.util.List; import org.apache.maven.model.Model; import org.apache.maven.model.io.xpp3.MavenXpp3Reader; @@ -60,6 +61,7 @@ public class DoapProjectStub setDescription( model.getDescription() ); setUrl( model.getUrl() ); setPackaging( model.getPackaging() ); + setDevelopers( model.getDevelopers() ); } /** {...@inheritdoc} */ @@ -67,4 +69,10 @@ public class DoapProjectStub { return new File( super.getBasedir() + "/src/test/resources/unit/doap-configuration/" ); } + + /** {...@inheritdoc} */ + public List getDevelopers() + { + return model.getDevelopers(); + } } Modified: maven/plugins/trunk/maven-doap-plugin/src/test/resources/unit/doap-configuration/doap-configuration-plugin-config.xml URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-doap-plugin/src/test/resources/unit/doap-configuration/doap-configuration-plugin-config.xml?rev=1044321&r1=1044320&r2=1044321&view=diff ============================================================================== --- maven/plugins/trunk/maven-doap-plugin/src/test/resources/unit/doap-configuration/doap-configuration-plugin-config.xml (original) +++ maven/plugins/trunk/maven-doap-plugin/src/test/resources/unit/doap-configuration/doap-configuration-plugin-config.xml Fri Dec 10 12:19:07 2010 @@ -47,6 +47,20 @@ under the License. <url>http://jira.codehaus.org/browse/MDOAPTEST</url> </issueManagement> + <developers> + <developer> + <id>jdoe</id> + <name>Jane Doe</name> + <email>j...@example.org</email> + <organization>Example Organization</organization> + <organizationUrl>http://www.example.org</organizationUrl> + <roles> + <role>PMC Member</role> + </roles> + <timezone>-8</timezone> + </developer> + </developers> + <build> <plugins> <plugin>