[MRM-1362] Add simple 'CRUD' pages for project-level metadata along with a "generic metadata" plugin

o removed project metadata custom tag
o enable delete of generic metadata properties
o added unit tests for adding and deleting properties
o clear facet properties read from file before doing the update so that removed facet properties are not retained when updating project version metadata


git-svn-id: https://svn.apache.org/repos/asf/archiva/trunk@952127 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Maria Odea B. Ching 2010-06-07 07:40:26 +00:00
parent a946c2e933
commit 8891e9fdd2
10 changed files with 253 additions and 494 deletions

View File

@ -24,7 +24,6 @@ import com.opensymphony.xwork2.Validateable;
import org.apache.archiva.metadata.generic.GenericMetadataFacet; import org.apache.archiva.metadata.generic.GenericMetadataFacet;
import org.apache.archiva.metadata.model.ArtifactMetadata; import org.apache.archiva.metadata.model.ArtifactMetadata;
import org.apache.archiva.metadata.model.Dependency; import org.apache.archiva.metadata.model.Dependency;
import org.apache.archiva.metadata.model.License;
import org.apache.archiva.metadata.model.MailingList; import org.apache.archiva.metadata.model.MailingList;
import org.apache.archiva.metadata.model.ProjectVersionMetadata; import org.apache.archiva.metadata.model.ProjectVersionMetadata;
import org.apache.archiva.metadata.model.ProjectVersionReference; import org.apache.archiva.metadata.model.ProjectVersionReference;
@ -57,6 +56,7 @@ import java.util.Map;
* @plexus.component role="com.opensymphony.xwork2.Action" role-hint="showArtifactAction" * @plexus.component role="com.opensymphony.xwork2.Action" role-hint="showArtifactAction"
* instantiation-strategy="per-lookup" * instantiation-strategy="per-lookup"
*/ */
@SuppressWarnings( "serial" )
public class ShowArtifactAction public class ShowArtifactAction
extends AbstractRepositoryBasedAction extends AbstractRepositoryBasedAction
implements Validateable implements Validateable
@ -106,12 +106,8 @@ public class ShowArtifactAction
private boolean dependencyTree = false; private boolean dependencyTree = false;
private ProjectVersionMetadata projectMetadata;
private String deleteItem; private String deleteItem;
private String itemValue;
private Map<String, String> genericMetadata; private Map<String, String> genericMetadata;
private String propertyName; private String propertyName;
@ -335,13 +331,7 @@ public class ShowArtifactAction
genericMetadata.put( propertyName, propertyValue ); genericMetadata.put( propertyName, propertyValue );
GenericMetadataFacet genericMetadataFacet = new GenericMetadataFacet(); updateProjectMetadata( projectMetadata );
genericMetadataFacet.fromProperties( genericMetadata );
// add updated facet
projectMetadata.addFacet( genericMetadataFacet );
metadataRepository.updateProjectVersion( repositoryId, groupId, artifactId, projectMetadata );
projectMetadata = getProjectVersionMetadata(); projectMetadata = getProjectVersionMetadata();
@ -355,94 +345,55 @@ public class ShowArtifactAction
return SUCCESS; return SUCCESS;
} }
public String updateProjectMetadata() public String deleteMetadataEntry()
{ {
metadataRepository.updateProjectVersion( repositoryId, groupId, artifactId, projectMetadata ); ProjectVersionMetadata projectMetadata = getProjectVersionMetadata();
String errorMsg = null;
if ( projectMetadata == null )
{
addActionError( errorMsg != null ? errorMsg : "Artifact not found" );
return ERROR;
}
if ( projectMetadata.getFacet( GenericMetadataFacet.FACET_ID ) != null )
{
genericMetadata = projectMetadata.getFacet( GenericMetadataFacet.FACET_ID ).toProperties();
if ( !StringUtils.isEmpty( deleteItem ) )
{
genericMetadata.remove( deleteItem );
updateProjectMetadata( projectMetadata );
projectMetadata = getProjectVersionMetadata();
genericMetadata = projectMetadata.getFacet( GenericMetadataFacet.FACET_ID ).toProperties();
model = projectMetadata;
addActionMessage( "Property successfully deleted." );
}
deleteItem = "";
}
else
{
addActionError( errorMsg != null ? errorMsg : "No generic metadata facet for this artifact." );
return ERROR;
}
return SUCCESS; return SUCCESS;
} }
public String deleteMetadataEntry() private void updateProjectMetadata( ProjectVersionMetadata projectMetadata )
{ {
projectMetadata = getProjectVersionMetadata(); GenericMetadataFacet genericMetadataFacet = new GenericMetadataFacet();
genericMetadataFacet.fromProperties( genericMetadata );
if ( !StringUtils.isEmpty( deleteItem ) && !StringUtils.isEmpty( itemValue ) ) projectMetadata.addFacet( genericMetadataFacet );
{
if ( "dependency".equals( deleteItem ) )
{
removeDependency();
}
else if ( "mailingList".equals( deleteItem ) )
{
removeMailingList();
}
else if ( "license".equals( deleteItem ) )
{
removeLicense();
}
deleteItem = ""; metadataRepository.updateProjectVersion( repositoryId, groupId, artifactId, projectMetadata );
itemValue = "";
}
return updateProjectMetadata();
}
private void removeDependency()
{
List<Dependency> dependencies = projectMetadata.getDependencies();
List<Dependency> newDependencies = new ArrayList<Dependency>();
if ( dependencies != null )
{
for ( Dependency dependency : dependencies )
{
if ( !StringUtils.equals( itemValue, dependency.getArtifactId() ) )
{
newDependencies.add( dependency );
}
}
}
projectMetadata.setDependencies( newDependencies );
}
private void removeMailingList()
{
List<MailingList> mailingLists = projectMetadata.getMailingLists();
List<MailingList> newMailingLists = new ArrayList<MailingList>();
if ( mailingLists != null )
{
for ( MailingList mailingList : mailingLists )
{
if ( !StringUtils.equals( itemValue, mailingList.getName() ) )
{
newMailingLists.add( mailingList );
}
}
}
projectMetadata.setMailingLists( newMailingLists );
}
private void removeLicense()
{
List<License> licenses = projectMetadata.getLicenses();
List<License> newLicenses = new ArrayList<License>();
if ( licenses != null )
{
for ( License license : licenses )
{
if ( !StringUtils.equals( itemValue, license.getName() ) )
{
newLicenses.add( license );
}
}
}
projectMetadata.setLicenses( newLicenses );
} }
@Override @Override
@ -539,36 +490,16 @@ public class ShowArtifactAction
return artifacts.keySet(); return artifacts.keySet();
} }
public void setRepositoryFactory( RepositoryContentFactory repositoryFactory )
{
this.repositoryFactory = repositoryFactory;
}
public boolean isDependencyTree() public boolean isDependencyTree()
{ {
return dependencyTree; return dependencyTree;
} }
public ProjectVersionMetadata getProjectMetadata()
{
return projectMetadata;
}
public void setProjectMetadata( ProjectVersionMetadata projectMetadata )
{
this.projectMetadata = projectMetadata;
}
public void setDeleteItem( String deleteItem ) public void setDeleteItem( String deleteItem )
{ {
this.deleteItem = deleteItem; this.deleteItem = deleteItem;
} }
public void setItemValue( String itemValue )
{
this.itemValue = itemValue;
}
public Map<String, String> getGenericMetadata() public Map<String, String> getGenericMetadata()
{ {
return genericMetadata; return genericMetadata;
@ -599,6 +530,16 @@ public class ShowArtifactAction
this.propertyValue = propertyValue; this.propertyValue = propertyValue;
} }
public void setRepositoryFactory( RepositoryContentFactory repositoryFactory )
{
this.repositoryFactory = repositoryFactory;
}
public void setMetadataRepository( MetadataRepository metadataRepository )
{
this.metadataRepository = metadataRepository;
}
// TODO: move this into the artifact metadata itself via facets where necessary // TODO: move this into the artifact metadata itself via facets where necessary
public class ArtifactDownloadInfo public class ArtifactDownloadInfo

View File

@ -1,305 +0,0 @@
package org.apache.maven.archiva.web.tags;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import java.io.IOException;
import java.util.List;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
import org.apache.archiva.metadata.model.Dependency;
import org.apache.archiva.metadata.model.License;
import org.apache.archiva.metadata.model.MailingList;
import org.apache.archiva.metadata.model.ProjectVersionMetadata;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* ProjectMetadataTag
*
* Outputs the project metadata attributes, used in the Metadata tab in artifact browse.
*/
@SuppressWarnings( "serial" )
public class ProjectMetadataTag
extends TagSupport
{
private Logger log = LoggerFactory.getLogger( ProjectMetadataTag.class );
private Object object;
private String groupId;
private String artifactId;
private String version;
@Override
public void release()
{
object = null;
super.release();
}
@Override
public int doStartTag()
throws JspException
{
StringBuffer buf = new StringBuffer();
if ( object == null )
{
buf.append( "Error generating project metadata." );
log.error( "Unable to generate project metadata for null object." );
}
else if ( object instanceof ProjectVersionMetadata )
{
ProjectVersionMetadata metadata = (ProjectVersionMetadata) object;
buildProjectMetadata( buf, metadata );
}
else
{
buf.append( "Unable to generate project metadata for object " ).append( object.getClass().getName() );
}
out( buf.toString() );
return EVAL_BODY_INCLUDE;
}
private void out( String msg )
throws JspException
{
try
{
pageContext.getOut().print( msg );
}
catch ( IOException e )
{
throw new JspException( "Unable to output to jsp page context." );
}
}
private void buildProjectMetadata( StringBuffer metadataEntries, ProjectVersionMetadata projectMetadata )
{
startList( metadataEntries );
addListItem( "project.metadata.id=", projectMetadata.getId(), metadataEntries );
addListItem( "project.url=", projectMetadata.getUrl(), metadataEntries );
addListItem( "project.name=", projectMetadata.getName(), metadataEntries );
addListItem( "project.description=", projectMetadata.getDescription(), metadataEntries );
if ( projectMetadata.getOrganization() != null )
{
startListItem( "organization", metadataEntries );
startList( metadataEntries );
addListItem( "organization.name=", projectMetadata.getOrganization().getName(), metadataEntries );
addListItem( "organization.url=", projectMetadata.getOrganization().getUrl(), metadataEntries );
endList( metadataEntries );
endListItem( metadataEntries );
}
if ( projectMetadata.getIssueManagement() != null )
{
startListItem( "issueManagement", metadataEntries );
startList( metadataEntries );
addListItem( "issueManagement.system=", projectMetadata.getIssueManagement().getSystem(), metadataEntries );
addListItem( "issueManagement.url=", projectMetadata.getIssueManagement().getUrl(), metadataEntries );
endList( metadataEntries );
endListItem( metadataEntries );
}
if ( projectMetadata.getScm() != null )
{
startListItem( "scm", metadataEntries );
startList( metadataEntries );
addListItem( "scm.url=", projectMetadata.getScm().getUrl(), metadataEntries );
addListItem( "scm.connection=", projectMetadata.getScm().getConnection(), metadataEntries );
addListItem( "scm.developer.connection=", projectMetadata.getScm().getDeveloperConnection(),
metadataEntries );
endList( metadataEntries );
endListItem( metadataEntries );
}
if ( projectMetadata.getCiManagement() != null )
{
startListItem( "ciManagement", metadataEntries );
startList( metadataEntries );
addListItem( "ciManagement.system=", projectMetadata.getCiManagement().getSystem(), metadataEntries );
addListItem( "ciManagement.url=", projectMetadata.getCiManagement().getUrl(), metadataEntries );
endList( metadataEntries );
endListItem( metadataEntries );
}
if ( projectMetadata.getLicenses() != null && !projectMetadata.getLicenses().isEmpty() )
{
startListItem( "licenses", metadataEntries );
List<License> licenses = projectMetadata.getLicenses();
int ctr = 0;
startList( metadataEntries );
for ( License license : licenses )
{
createDeleteLink( "license", license.getName(), metadataEntries );
startList( metadataEntries );
addListItem( "licenses." + ctr + ".name=", license.getName(), metadataEntries );
addListItem( "licenses." + ctr + ".url=", license.getUrl(), metadataEntries );
endList( metadataEntries );
endListItem( metadataEntries );
ctr++;
}
endList( metadataEntries );
endListItem( metadataEntries );
}
if ( projectMetadata.getMailingLists() != null && !projectMetadata.getMailingLists().isEmpty() )
{
startListItem( "mailingLists", metadataEntries );
List<MailingList> lists = projectMetadata.getMailingLists();
List<String> otherArchives;
int ctr = 0;
int archiveCtr = 0;
startList( metadataEntries );
for ( MailingList list : lists )
{
createDeleteLink( "mailingList", list.getName(), metadataEntries );
startList( metadataEntries );
addListItem( "mailingLists." + ctr + ".name=", list.getName(), metadataEntries );
addListItem( "mailingLists." + ctr + ".archive.url=", list.getMainArchiveUrl(), metadataEntries );
addListItem( "mailingLists." + ctr + ".post=", list.getPostAddress(), metadataEntries );
addListItem( "mailingLists." + ctr + ".subscribe=", list.getSubscribeAddress(), metadataEntries );
addListItem( "mailingLists." + ctr + ".unsubscribe=", list.getUnsubscribeAddress(), metadataEntries );
startListItem( "mailingLists." + ctr + ".otherArchives", metadataEntries );
if ( list.getOtherArchives() != null && list.getOtherArchives().size() > 0 )
{
archiveCtr = 0;
otherArchives = list.getOtherArchives();
startList( metadataEntries );
for ( String archive : otherArchives )
{
addListItem( "mailingLists." + ctr + ".otherArchives." + archiveCtr + "=", archive,
metadataEntries );
metadataEntries.append( archive );
archiveCtr++;
}
endList( metadataEntries );
}
endListItem( metadataEntries );
endList( metadataEntries );
endListItem( metadataEntries );
ctr++;
}
endList( metadataEntries );
endListItem( metadataEntries );
}
if ( projectMetadata.getDependencies() != null && !projectMetadata.getDependencies().isEmpty() )
{
startListItem( "dependencies", metadataEntries );
List<Dependency> dependencies = projectMetadata.getDependencies();
int ctr = 0;
startList( metadataEntries );
for ( Dependency dependency : dependencies )
{
createDeleteLink( "dependency", dependency.getArtifactId(), metadataEntries );
startList( metadataEntries );
addListItem( "dependency." + ctr + ".group.id=", dependency.getGroupId(), metadataEntries );
addListItem( "dependency." + ctr + ".artifact.id=", dependency.getArtifactId(), metadataEntries );
addListItem( "dependency." + ctr + ".version=", dependency.getVersion(), metadataEntries );
addListItem( "dependency." + ctr + ".classifier=", dependency.getClassifier(), metadataEntries );
addListItem( "dependency." + ctr + ".type=", dependency.getType(), metadataEntries );
addListItem( "dependency." + ctr + ".scope=", dependency.getScope(), metadataEntries );
addListItem( "dependency." + ctr + ".system.path=", dependency.getSystemPath(), metadataEntries );
endList( metadataEntries );
endListItem( metadataEntries );
ctr++;
}
endList( metadataEntries );
endListItem( metadataEntries );
}
endList( metadataEntries );
}
private void startList( StringBuffer metadataEntries )
{
metadataEntries.append( "\n<ul>" );
}
private void endList( StringBuffer metadataEntries )
{
metadataEntries.append( "\n</ul>" );
}
private void addListItem( String label, String value, StringBuffer metadataEntries )
{
String newValue = StringUtils.isEmpty( value ) ? "" : value;
metadataEntries.append( "\n<li>" ).append( label ).append( newValue ).append( "</li>" );
}
private void startListItem( String value, StringBuffer metadataEntries )
{
metadataEntries.append( "\n<li>" ).append( value );
}
private void endListItem( StringBuffer metadataEntries )
{
metadataEntries.append( "\n</li>" );
}
private void createDeleteLink( String name, String value, StringBuffer metadataEntries )
{
metadataEntries.append( "\n<li>" ).append( value )
.append( "\n<a href=\"showProjectMetadata!deleteMetadataEntry.action?" )
.append( "groupId=" ).append( groupId )
.append( "&artifactId=" ).append( artifactId )
.append( "&version=" ).append( version )
.append( "&deleteItem=" ).append( name )
.append( "&itemValue=").append( value ).append( "\" >" )
.append( "<img src=\"images/icons/delete.gif\"/>" ).append( "</a>" );
}
public void setObject( Object object )
{
this.object = object;
}
public void setGroupId( String groupId )
{
this.groupId = groupId;
}
public void setArtifactId( String artifactId )
{
this.artifactId = artifactId;
}
public void setVersion( String version )
{
this.version = version;
}
}

View File

@ -228,10 +228,8 @@
</action> </action>
<action name="deleteMetadataEntry" class="showArtifactAction" method="deleteMetadataEntry"> <action name="deleteMetadataEntry" class="showArtifactAction" method="deleteMetadataEntry">
<result name="success" type="redirect-action"> <result name="input">/WEB-INF/jsp/showArtifact.jsp</result>
<param name="actionName">showProjectMetadata</param> <result name="success">/WEB-INF/jsp/showArtifact.jsp</result>
<param name="namespace">/</param>
</result>
</action> </action>
</package> </package>

View File

@ -61,25 +61,20 @@
<c:if test="${!empty genericMetadata}"> <c:if test="${!empty genericMetadata}">
<ul> <ul>
<c:forEach var="prop" items="${genericMetadata}"> <c:forEach var="prop" items="${genericMetadata}">
<li>${prop.key}=${prop.value}</li> <c:url var="deletePropertyUrl" value="showProjectMetadata!deleteMetadataEntry.action">
<c:param name="groupId" value="${groupId}"/>
<c:param name="artifactId" value="${artifactId}"/>
<c:param name="version" value="${version}"/>
<c:param name="deleteItem" value="${prop.key}"/>
</c:url>
<li>${prop.key}=${prop.value}
<a href="${deletePropertyUrl}">
<img src="<c:url value="/images/icons/delete.gif" />" alt="Delete" width="12" length="12"/>
</a>
</li>
</c:forEach> </c:forEach>
</ul> </ul>
</c:if> </c:if>
</div> </div>
<p>
<s:if test="hasActionMessages()">
<div id="messages">
<s:actionmessage/>
</div>
</s:if>
<s:if test="hasActionErrors()">
<div id="messages">
<s:actionerror/>
</div>
</s:if>
</p>
<%-- <archiva:project-metadata object="${projectMetadata}" groupId="${groupId}" artifactId="${artifactId}" version="${version}" /> --%>
</div> </div>

View File

@ -249,6 +249,11 @@
<s:actionmessage /> <s:actionmessage />
</div> </div>
</s:if> </s:if>
<s:if test="hasActionErrors()">
<div id="messages">
<s:actionerror/>
</div>
</s:if>
</div> </div>
</div> </div>
</body> </body>

View File

@ -110,45 +110,4 @@
</tag> </tag>
<tag>
<name>project-metadata</name>
<tag-class>org.apache.maven.archiva.web.tags.ProjectMetadataTag</tag-class>
<body-content>empty</body-content>
<description><![CDATA[Render the project metadata tree from the provided ProjectMetadataVersion object]]></description>
<attribute>
<name>object</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<description><![CDATA[The Object to Render]]></description>
</attribute>
<attribute>
<name>groupId</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<description><![CDATA[The groupId]]></description>
</attribute>
<attribute>
<name>artifactId</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<description><![CDATA[The artifactId]]></description>
</attribute>
<attribute>
<name>version</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<description><![CDATA[The version]]></description>
</attribute>
</tag>
</taglib> </taglib>

View File

@ -27,9 +27,14 @@ import org.apache.archiva.metadata.model.Dependency;
import org.apache.archiva.metadata.model.MailingList; import org.apache.archiva.metadata.model.MailingList;
import org.apache.archiva.metadata.model.ProjectVersionMetadata; import org.apache.archiva.metadata.model.ProjectVersionMetadata;
import org.apache.archiva.metadata.model.ProjectVersionReference; import org.apache.archiva.metadata.model.ProjectVersionReference;
import org.apache.archiva.metadata.repository.MetadataRepository;
import org.apache.archiva.metadata.repository.file.FileMetadataRepository;
import org.apache.archiva.metadata.repository.memory.TestMetadataResolver; import org.apache.archiva.metadata.repository.memory.TestMetadataResolver;
import org.apache.archiva.metadata.repository.storage.maven2.MavenArtifactFacet; import org.apache.archiva.metadata.repository.storage.maven2.MavenArtifactFacet;
import org.apache.maven.archiva.common.utils.VersionUtil; import org.apache.maven.archiva.common.utils.VersionUtil;
import org.apache.maven.archiva.configuration.ArchivaConfiguration;
import org.apache.maven.archiva.configuration.Configuration;
import org.apache.maven.archiva.configuration.DefaultArchivaConfiguration;
import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration; import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
import org.apache.maven.archiva.repository.ManagedRepositoryContent; import org.apache.maven.archiva.repository.ManagedRepositoryContent;
import org.apache.maven.archiva.repository.RepositoryContentFactory; import org.apache.maven.archiva.repository.RepositoryContentFactory;
@ -396,6 +401,61 @@ public class ShowArtifactActionTest
assertTrue( action.getArtifacts().isEmpty() ); assertTrue( action.getArtifacts().isEmpty() );
} }
public void testAddAndDeleteMetadataProperty()
{
ProjectVersionMetadata versionMetadata = createProjectModel( TEST_VERSION );
metadataResolver.setProjectVersion( TEST_REPO, TEST_GROUP_ID, TEST_ARTIFACT_ID, versionMetadata );
setActionParameters();
action.setPropertyName( "foo" );
action.setPropertyValue( "bar" );
action.setRepositoryId( TEST_REPO );
String result = action.addMetadataProperty();
assertActionSuccess( action, result );
assertActionParameters( action );
Map<String, String> genericMetadata = action.getGenericMetadata();
assertNotNull( genericMetadata.get( TEST_GENERIC_METADATA_PROPERTY_NAME ) );
assertEquals( genericMetadata.get( TEST_GENERIC_METADATA_PROPERTY_NAME ), TEST_GENERIC_METADATA_PROPERTY_VALUE );
assertNotNull( genericMetadata.get( "foo" ) );
assertEquals( "bar", genericMetadata.get( "foo" ) );
assertEquals( TEST_REPO, action.getRepositoryId() );
assertNotNull( action.getModel() );
assertNull( action.getDependees() );
assertNull( action.getDependencies() );
assertNull( action.getMailingLists() );
assertTrue( action.getArtifacts().isEmpty() );
// test delete property
setActionParameters();
action.setDeleteItem( "foo" );
result = action.deleteMetadataEntry();
assertEquals( Action.SUCCESS, result );
assertActionParameters( action );
assertTrue( !action.getActionMessages().isEmpty() );
assertTrue( action.getActionMessages().contains( "Property successfully deleted." ) );
genericMetadata = action.getGenericMetadata();
assertNotNull( genericMetadata.get( TEST_GENERIC_METADATA_PROPERTY_NAME ) );
assertEquals( genericMetadata.get( TEST_GENERIC_METADATA_PROPERTY_NAME ), TEST_GENERIC_METADATA_PROPERTY_VALUE );
assertNull( genericMetadata.get( "foo" ) );
assertEquals( TEST_REPO, action.getRepositoryId() );
assertNotNull( action.getModel() );
assertNull( action.getDependees() );
assertNull( action.getDependencies() );
assertNull( action.getMailingLists() );
assertTrue( action.getArtifacts().isEmpty() );
}
private void assertArtifacts( List<ArtifactMetadata> expectedArtifacts, private void assertArtifacts( List<ArtifactMetadata> expectedArtifacts,
Map<String, List<ShowArtifactAction.ArtifactDownloadInfo>> artifactMap ) Map<String, List<ShowArtifactAction.ArtifactDownloadInfo>> artifactMap )
{ {
@ -575,10 +635,25 @@ public class ShowArtifactActionTest
ManagedRepositoryConfiguration config = new ManagedRepositoryConfiguration(); ManagedRepositoryConfiguration config = new ManagedRepositoryConfiguration();
config.setId( TEST_REPO ); config.setId( TEST_REPO );
config.setLocation( getTestFile( "target/test-repo" ).getAbsolutePath() ); config.setLocation( getTestFile( "target/test-repo" ).getAbsolutePath() );
ManagedRepositoryContent content = new ManagedDefaultRepositoryContent(); ManagedRepositoryContent content = new ManagedDefaultRepositoryContent();
content.setRepository( config ); content.setRepository( config );
factory.getManagedRepositoryContent( TEST_REPO ); factory.getManagedRepositoryContent( TEST_REPO );
FileMetadataRepository metadataRepo = ( FileMetadataRepository ) lookup( MetadataRepository.class );
MockControl archivaConfigControl = MockControl.createControl( ArchivaConfiguration.class );
ArchivaConfiguration archivaConfig = (ArchivaConfiguration) archivaConfigControl.getMock();
Configuration configuration = new Configuration();
configuration.addManagedRepository( config );
metadataRepo.setConfiguration( archivaConfig );
archivaConfig.getConfiguration();
action.setMetadataRepository( metadataRepo );
archivaConfigControl.setDefaultReturnValue( configuration );
control.setDefaultReturnValue( content ); control.setDefaultReturnValue( content );
control.replay(); control.replay();
archivaConfigControl.replay();
} }
} }

View File

@ -165,6 +165,40 @@ public abstract class AbstractMetadataRepositoryTest
assertEquals( Collections.<String>emptyList(), new ArrayList<String>( metadata.getFacetIds() ) ); assertEquals( Collections.<String>emptyList(), new ArrayList<String>( metadata.getFacetIds() ) );
} }
public void testUpdateProjectVersionMetadataWithExistingFacetsFacetPropertyWasRemoved()
throws MetadataResolutionException
{
ProjectVersionMetadata metadata = new ProjectVersionMetadata();
metadata.setId( TEST_PROJECT_VERSION );
Map<String, String> additionalProps = new HashMap<String,String>();
additionalProps.put( "deleteKey", "deleteValue" );
MetadataFacet facet = new TestMetadataFacet( TEST_FACET_ID, "baz", additionalProps );
metadata.addFacet( facet );
repository.updateProjectVersion( TEST_REPO_ID, TEST_NAMESPACE, TEST_PROJECT, metadata );
metadata = repository.getProjectVersion( TEST_REPO_ID, TEST_NAMESPACE, TEST_PROJECT, TEST_PROJECT_VERSION );
assertEquals( Collections.singleton( TEST_FACET_ID ), metadata.getFacetIds() );
TestMetadataFacet testFacet = (TestMetadataFacet) metadata.getFacet( TEST_FACET_ID );
Map<String, String> facetProperties = testFacet.toProperties();
assertEquals( "deleteValue", facetProperties.get( "deleteKey" ) );
facetProperties.remove( "deleteKey" );
TestMetadataFacet newTestFacet = new TestMetadataFacet( TEST_FACET_ID, testFacet.getValue(), facetProperties );
metadata.addFacet( newTestFacet );
repository.updateProjectVersion( TEST_REPO_ID, TEST_NAMESPACE, TEST_PROJECT, metadata );
metadata = repository.getProjectVersion( TEST_REPO_ID, TEST_NAMESPACE, TEST_PROJECT, TEST_PROJECT_VERSION );
assertEquals( Collections.singleton( TEST_FACET_ID ), metadata.getFacetIds() );
testFacet = (TestMetadataFacet) metadata.getFacet( TEST_FACET_ID );
assertFalse( testFacet.toProperties().containsKey( "deleteKey" ) );
}
public void testUpdateArtifactMetadataWithExistingFacets() public void testUpdateArtifactMetadataWithExistingFacets()
{ {
ArtifactMetadata metadata = createArtifact(); ArtifactMetadata metadata = createArtifact();
@ -614,6 +648,10 @@ public abstract class AbstractMetadataRepositoryTest
{ {
private String testFacetId; private String testFacetId;
private Map<String, String> additionalProps;
private String value;
private TestMetadataFacet( String value ) private TestMetadataFacet( String value )
{ {
this.value = value; this.value = value;
@ -626,7 +664,11 @@ public abstract class AbstractMetadataRepositoryTest
testFacetId = facetId; testFacetId = facetId;
} }
private String value; private TestMetadataFacet( String facetId, String value, Map<String, String> additionalProps )
{
this( facetId, value );
this.additionalProps = additionalProps;
}
public String getFacetId() public String getFacetId()
{ {
@ -642,7 +684,21 @@ public abstract class AbstractMetadataRepositoryTest
{ {
if ( value != null ) if ( value != null )
{ {
return Collections.singletonMap( "foo", value ); if( additionalProps == null )
{
return Collections.singletonMap( "foo", value );
}
else
{
Map<String, String> props = new HashMap<String, String>();
props.put( "foo", value );
for( String key : additionalProps.keySet() )
{
props.put( key, additionalProps.get( key ) );
}
return props;
}
} }
else else
{ {
@ -657,6 +713,18 @@ public abstract class AbstractMetadataRepositoryTest
{ {
this.value = value; this.value = value;
} }
properties.remove( "foo" );
if( additionalProps == null )
{
additionalProps = new HashMap<String, String>();
}
for( String key: properties.keySet() )
{
additionalProps.put( key, properties.get( key ) );
}
} }
public String getValue() public String getValue()

View File

@ -19,7 +19,6 @@ package org.apache.archiva.metadata.generic;
* under the License. * under the License.
*/ */
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.TreeMap; import java.util.TreeMap;

View File

@ -140,6 +140,9 @@ public class FileMetadataRepository
{ {
properties.remove( name ); properties.remove( name );
} }
// clear the facet contents so old properties are no longer written
clearMetadataFacetProperties( versionMetadata, properties );
} }
properties.setProperty( "id", versionMetadata.getId() ); properties.setProperty( "id", versionMetadata.getId() );
setProperty( properties, "name", versionMetadata.getName() ); setProperty( properties, "name", versionMetadata.getName() );
@ -225,6 +228,27 @@ public class FileMetadataRepository
} }
} }
private void clearMetadataFacetProperties( ProjectVersionMetadata versionMetadata, Properties properties )
{
List<Object> propsToRemove = new ArrayList<Object>();
for ( MetadataFacet facet : versionMetadata.getFacetList() )
{
for ( Object key : properties.keySet() )
{
String keyString = ( String ) key;
if( keyString.startsWith( facet.getFacetId() + ":" ) )
{
propsToRemove.add( key );
}
}
}
for( Object key : propsToRemove )
{
properties.remove( key );
}
}
public void updateProjectReference( String repoId, String namespace, String projectId, String projectVersion, public void updateProjectReference( String repoId, String namespace, String projectId, String projectVersion,
ProjectVersionReference reference ) ProjectVersionReference reference )
{ {