[MRM-410] Dependency Tree is not shown in artifact details screen.

* Refactored project resolution into ProjectModelResolverFactory component.
* All resolution access points now use this factory.
* Created ResolverFactoryInit as plexus component load-on-start, to hookup database to resolver stack.
* Created archiva:dependency-tree taglib



git-svn-id: https://svn.apache.org/repos/asf/maven/archiva/trunk@548008 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Joakim Erdfelt 2007-06-17 04:50:05 +00:00
parent 743213aaf3
commit e7664898d6
29 changed files with 1227 additions and 405 deletions

View File

@ -21,39 +21,30 @@ package org.apache.maven.archiva.consumers.database;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.archiva.configuration.ArchivaConfiguration;
import org.apache.maven.archiva.configuration.ConfigurationNames;
import org.apache.maven.archiva.configuration.RepositoryConfiguration;
import org.apache.maven.archiva.consumers.AbstractMonitoredConsumer;
import org.apache.maven.archiva.consumers.ConsumerException;
import org.apache.maven.archiva.consumers.DatabaseUnprocessedArtifactConsumer;
import org.apache.maven.archiva.consumers.database.project.WrappedDatabaseProjectModelResolver;
import org.apache.maven.archiva.database.ArchivaDAO;
import org.apache.maven.archiva.database.ArchivaDatabaseException;
import org.apache.maven.archiva.database.ObjectNotFoundException;
import org.apache.maven.archiva.model.ArchivaArtifact;
import org.apache.maven.archiva.model.ArchivaProjectModel;
import org.apache.maven.archiva.model.RepositoryURL;
import org.apache.maven.archiva.model.RepositoryProblem;
import org.apache.maven.archiva.model.RepositoryURL;
import org.apache.maven.archiva.reporting.artifact.CorruptArtifactReport;
import org.apache.maven.archiva.repository.layout.BidirectionalRepositoryLayout;
import org.apache.maven.archiva.repository.layout.BidirectionalRepositoryLayoutFactory;
import org.apache.maven.archiva.repository.layout.LayoutException;
import org.apache.maven.archiva.repository.layout.FilenameParts;
import org.apache.maven.archiva.repository.layout.LayoutException;
import org.apache.maven.archiva.repository.layout.RepositoryLayoutUtils;
import org.apache.maven.archiva.repository.project.ProjectModelException;
import org.apache.maven.archiva.repository.project.ProjectModelFilter;
import org.apache.maven.archiva.repository.project.ProjectModelReader;
import org.apache.maven.archiva.repository.project.ProjectModelResolver;
import org.apache.maven.archiva.repository.project.filters.EffectiveProjectModelFilter;
import org.apache.maven.archiva.repository.project.resolvers.RepositoryProjectModelResolverFactory;
import org.apache.maven.archiva.reporting.artifact.CorruptArtifactReport;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
import org.codehaus.plexus.registry.Registry;
import org.codehaus.plexus.registry.RegistryListener;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
@ -68,7 +59,7 @@ import java.util.List;
*/
public class ProjectModelToDatabaseConsumer
extends AbstractMonitoredConsumer
implements DatabaseUnprocessedArtifactConsumer, RegistryListener, Initializable
implements DatabaseUnprocessedArtifactConsumer
{
/**
* @plexus.configuration default-value="update-db-project"
@ -111,21 +102,12 @@ public class ProjectModelToDatabaseConsumer
private ProjectModelFilter expressionModelFilter;
/**
* @plexus.requirement
*/
private RepositoryProjectModelResolverFactory resolverFactory;
/**
* @plexus.requirement role="org.apache.maven.archiva.repository.project.ProjectModelFilter"
* role-hint="effective"
* @plexus.requirement
* role="org.apache.maven.archiva.repository.project.ProjectModelFilter"
* role-hint="effective"
*/
private EffectiveProjectModelFilter effectiveModelFilter;
/**
* @plexus.requirement role-hint="database"
*/
private ProjectModelResolver databaseResolver;
private List includes;
public ProjectModelToDatabaseConsumer()
@ -185,14 +167,13 @@ public class ProjectModelToDatabaseConsumer
// Resolve the project model
model = effectiveModelFilter.filter( model );
if( isValidModel( model, artifact ) )
if ( isValidModel( model, artifact ) )
{
dao.getProjectModelDAO().saveProjectModel( model );
}
else
{
getLogger().warn( "Invalid or corrupt pom. Project model " + model
+ " was not added in the database." );
getLogger().warn( "Invalid or corrupt pom. Project model " + model + " was not added in the database." );
}
dao.getProjectModelDAO().saveProjectModel( model );
@ -200,7 +181,7 @@ public class ProjectModelToDatabaseConsumer
catch ( ProjectModelException e )
{
getLogger().warn( "Unable to read project model " + artifactFile + " : " + e.getMessage(), e );
addProblem( artifact, "Unable to read project model " + artifactFile + " : " + e.getMessage() );
}
catch ( ArchivaDatabaseException e )
@ -273,50 +254,10 @@ public class ProjectModelToDatabaseConsumer
public boolean isPermanent()
{
// Tells the configuration that this consumer cannot be disabled.
return true;
}
public void beforeConfigurationChange( Registry registry, String propertyName, Object propertyValue )
{
/* nothing to do here */
}
public void afterConfigurationChange( Registry registry, String propertyName, Object propertyValue )
{
if ( ConfigurationNames.isRepositories( propertyName ) )
{
update();
}
}
public void initialize()
throws InitializationException
{
update();
archivaConfiguration.addChangeListener( this );
}
private void update()
{
synchronized ( effectiveModelFilter )
{
effectiveModelFilter.getProjectModelResolverStack().clearResolvers();
// Add the database resolver first!
effectiveModelFilter.getProjectModelResolverStack().addProjectModelResolver( databaseResolver );
List ret = this.resolverFactory.getAllResolvers();
Iterator it = ret.iterator();
while ( it.hasNext() )
{
ProjectModelResolver resolver = (ProjectModelResolver) it.next();
// TODO: Use listener to perform database saving of found models, instead of wrapped resolver.
ProjectModelResolver wrapped = new WrappedDatabaseProjectModelResolver( dao, resolver );
effectiveModelFilter.getProjectModelResolverStack().addProjectModelResolver( wrapped );
}
}
}
private String toPath( ArchivaArtifact artifact )
{
try
@ -341,34 +282,39 @@ public class ProjectModelToDatabaseConsumer
FilenameParts parts = RepositoryLayoutUtils.splitFilename( artifactFile.getName(), null );
if ( !parts.artifactId.equalsIgnoreCase( model.getArtifactId() ) )
{
getLogger().warn( "Project Model " + model + " artifactId: " + model.getArtifactId() +
" does not match the pom file's artifactId: " + parts.artifactId );
getLogger().warn(
"Project Model " + model + " artifactId: " + model.getArtifactId()
+ " does not match the pom file's artifactId: " + parts.artifactId );
addProblem( artifact, "Project Model " + model + " artifactId: " + model.getArtifactId() +
" does not match the pom file's artifactId: " + parts.artifactId );
addProblem( artifact, "Project Model " + model + " artifactId: " + model.getArtifactId()
+ " does not match the pom file's artifactId: " + parts.artifactId );
return false;
}
if ( !parts.version.equalsIgnoreCase( model.getVersion() ) )
{
getLogger().warn( "Project Model " + model + " artifactId: " + model.getArtifactId() +
" does not match the pom file's artifactId: " + parts.artifactId );
getLogger().warn(
"Project Model " + model + " artifactId: " + model.getArtifactId()
+ " does not match the pom file's artifactId: " + parts.artifactId );
addProblem( artifact, "Project Model " + model + " version: " + model.getVersion() +
" does not match the pom file's version: " + parts.version );
addProblem( artifact, "Project Model " + model + " version: " + model.getVersion()
+ " does not match the pom file's version: " + parts.version );
return false;
}
//check if the file name matches the values indicated in the pom
if( !artifactFile.getName().equalsIgnoreCase( model.getArtifactId() + "-" + model.getVersion() + "-" + parts.classifier) )
if ( !artifactFile.getName().equalsIgnoreCase(
model.getArtifactId() + "-" + model.getVersion() + "-"
+ parts.classifier ) )
{
getLogger().warn( "Artifact " + artifact + " does not match the artifactId and/or version " +
"specified in the project model " + model );
getLogger().warn(
"Artifact " + artifact + " does not match the artifactId and/or version "
+ "specified in the project model " + model );
addProblem( artifact, "Artifact " + artifact + " does not match the artifactId and/or version " +
"specified in the project model " + model );
addProblem( artifact, "Artifact " + artifact + " does not match the artifactId and/or version "
+ "specified in the project model " + model );
return false;
}

View File

@ -1,95 +0,0 @@
package org.apache.maven.archiva.consumers.database.project;
import org.apache.maven.archiva.database.ArchivaDAO;
import org.apache.maven.archiva.database.ArchivaDatabaseException;
import org.apache.maven.archiva.database.ObjectNotFoundException;
import org.apache.maven.archiva.model.ArchivaProjectModel;
import org.apache.maven.archiva.model.VersionedReference;
import org.apache.maven.archiva.repository.project.ProjectModelException;
import org.apache.maven.archiva.repository.project.ProjectModelResolver;
/**
* Wrapped {@link ProjectModelResolver} to allow for insertion of resolved project models on discovery.
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class WrappedDatabaseProjectModelResolver
implements ProjectModelResolver
{
private ArchivaDAO dao;
private ProjectModelResolver resolver;
public WrappedDatabaseProjectModelResolver( ArchivaDAO dao, ProjectModelResolver resolver )
{
this.dao = dao;
this.resolver = resolver;
}
public ArchivaProjectModel resolveProjectModel( VersionedReference reference )
throws ProjectModelException
{
ArchivaProjectModel model = resolver.resolveProjectModel( reference );
model.setOrigin( "filesystem" );
if ( model == null )
{
return model;
}
// Test if it exists.
if ( existsInDatabase( model ) )
{
removeFromDatabase( model );
}
saveInDatabase( model );
return model;
}
private void saveInDatabase( ArchivaProjectModel model ) throws ProjectModelException
{
try
{
dao.getProjectModelDAO().saveProjectModel( model );
}
catch ( ArchivaDatabaseException e )
{
throw new ProjectModelException( "Unable to save model to database: " + e.getMessage(), e );
}
}
private void removeFromDatabase( ArchivaProjectModel model ) throws ProjectModelException
{
try
{
dao.getProjectModelDAO().deleteProjectModel( model );
}
catch ( ArchivaDatabaseException e )
{
throw new ProjectModelException( "Unable to remove existing model from database: " + e.getMessage(), e );
}
}
private boolean existsInDatabase( ArchivaProjectModel model ) throws ProjectModelException
{
try
{
ArchivaProjectModel dbmodel = dao.getProjectModelDAO().getProjectModel( model.getGroupId(),
model.getArtifactId(),
model.getVersion() );
return ( dbmodel != null );
}
catch ( ObjectNotFoundException e )
{
return false;
}
catch ( ArchivaDatabaseException e )
{
throw new ProjectModelException( "Unable to check for existing model from database: " + e.getMessage(), e );
}
}
}

View File

@ -1445,7 +1445,8 @@
<name>otherArchives</name>
<version>1.0.0+</version>
<description>The email address to subscribe to this mailing list.</description>
<association>
<association stash.part="true"
jpox.join="false">
<type>String</type>
<multiplicity>*</multiplicity>
</association>

View File

@ -1,4 +1,4 @@
package org.apache.maven.archiva.repository.project.resolvers;
package org.apache.maven.archiva.repository.project;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@ -31,8 +31,9 @@ import org.apache.maven.archiva.repository.RepositoryException;
import org.apache.maven.archiva.repository.layout.BidirectionalRepositoryLayout;
import org.apache.maven.archiva.repository.layout.BidirectionalRepositoryLayoutFactory;
import org.apache.maven.archiva.repository.layout.LayoutException;
import org.apache.maven.archiva.repository.project.ProjectModelReader;
import org.apache.maven.archiva.repository.project.ProjectModelResolver;
import org.apache.maven.archiva.repository.project.resolvers.NopProjectResolver;
import org.apache.maven.archiva.repository.project.resolvers.ProjectModelResolverStack;
import org.apache.maven.archiva.repository.project.resolvers.RepositoryProjectResolver;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
@ -40,11 +41,8 @@ import org.codehaus.plexus.registry.Registry;
import org.codehaus.plexus.registry.RegistryListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* Factory for ProjectModelResolver objects
@ -52,9 +50,9 @@ import java.util.Map;
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*
* @plexus.component role="org.apache.maven.archiva.repository.project.resolvers.RepositoryProjectModelResolverFactory"
* @plexus.component role="org.apache.maven.archiva.repository.project.ProjectModelResolverFactory"
*/
public class RepositoryProjectModelResolverFactory
public class ProjectModelResolverFactory
extends AbstractLogEnabled
implements RegistryListener, Initializable
{
@ -78,86 +76,7 @@ public class RepositoryProjectModelResolverFactory
*/
private ProjectModelReader project300Reader;
/**
* Get the {@link ProjectModelResolver} for the specific archiva repository.
*
* @param repo the repository to base resolver on.
* @return return the resolver for the archiva repository provided.
* @throws RepositoryException if unable to create a resolver for the provided {@link ArchivaRepository}
*/
public ProjectModelResolver getResolver( ArchivaRepository repo )
throws RepositoryException
{
if ( resolverMap.containsKey( repo.getId() ) )
{
return (ProjectModelResolver) this.resolverMap.get( repo.getId() );
}
ProjectModelResolver resolver = toResolver( repo );
resolverMap.put( repo.getId(), resolver );
return resolver;
}
/**
* Get the {@link ProjectModelResolver} for the specific archiva repository based on repository id.
*
* @param repoid the repository id to get the resolver for.
* @return the {@link ProjectModelResolver} if found, or null if repository is not found.
*/
public ProjectModelResolver getResolver( String repoid )
{
return (ProjectModelResolver) this.resolverMap.get( repoid );
}
/**
* Get the {@link List} of {@link ProjectModelResolver} for
* the {@link List} of {@link ArchivaRepository} objects provided.
*
* @param repositoryList the {@link List} of {@link ArchivaRepository} objects to
* get {@link ProjectModelResolver} for.
* @return the {@link List} of {@link ProjectModelResolver} objects.
* @throws RepositoryException if unable to convert any of the provided {@link ArchivaRepository} objects into
* a {@link ProjectModelResolver} object.
*/
public List getResolverList( List repositoryList )
throws RepositoryException
{
List ret = new ArrayList();
if ( CollectionUtils.isEmpty( repositoryList ) )
{
return ret;
}
Iterator it = repositoryList.iterator();
while ( it.hasNext() )
{
ArchivaRepository repo = (ArchivaRepository) it.next();
ret.add( getResolver( repo ) );
}
return ret;
}
/**
* Get the entire {@link List} of {@link ProjectModelResolver} that the factory is tracking.
*
* @return the entire list of {@link ProjectModelResolver} that is being tracked.
*/
public List getAllResolvers()
{
List ret = new ArrayList();
ret.addAll( this.resolverMap.values() );
return ret;
}
public void beforeConfigurationChange( Registry registry, String propertyName, Object propertyValue )
{
/* do nothing */
}
private ProjectModelResolverStack currentResolverStack = new ProjectModelResolverStack();
public void afterConfigurationChange( Registry registry, String propertyName, Object propertyValue )
{
@ -167,33 +86,21 @@ public class RepositoryProjectModelResolverFactory
}
}
private Map resolverMap = new HashMap();
private void update()
public void beforeConfigurationChange( Registry registry, String propertyName, Object propertyValue )
{
synchronized ( resolverMap )
{
resolverMap.clear();
/* do nothing */
}
List configRepos = archivaConfiguration.getConfiguration().getRepositories();
Collection configLocalRepos = CollectionUtils.select( configRepos, LocalRepositoryPredicate.getInstance() );
public ProjectModelResolverStack getCurrentResolverStack()
{
return currentResolverStack;
}
Iterator it = configLocalRepos.iterator();
while ( it.hasNext() )
{
RepositoryConfiguration repoconfig = (RepositoryConfiguration) it.next();
ArchivaRepository repo = ArchivaConfigurationAdaptor.toArchivaRepository( repoconfig );
try
{
RepositoryProjectResolver resolver = toResolver( repo );
resolverMap.put( repo.getId(), resolver );
}
catch ( RepositoryException e )
{
getLogger().warn( e.getMessage(), e );
}
}
}
public void initialize()
throws InitializationException
{
update();
archivaConfiguration.addChangeListener( this );
}
private RepositoryProjectResolver toResolver( ArchivaRepository repo )
@ -225,10 +132,36 @@ public class RepositoryProjectModelResolverFactory
}
}
public void initialize()
throws InitializationException
private void update()
{
update();
archivaConfiguration.addChangeListener( this );
synchronized ( currentResolverStack )
{
this.currentResolverStack.clearResolvers();
List configLocalRepos = new ArrayList();
CollectionUtils.select( archivaConfiguration.getConfiguration().getRepositories(), LocalRepositoryPredicate
.getInstance(), configLocalRepos );
Iterator it = configLocalRepos.iterator();
while ( it.hasNext() )
{
RepositoryConfiguration repoconfig = (RepositoryConfiguration) it.next();
ArchivaRepository repo = ArchivaConfigurationAdaptor.toArchivaRepository( repoconfig );
try
{
RepositoryProjectResolver resolver = toResolver( repo );
// Add filesystem based resolver.
this.currentResolverStack.addProjectModelResolver( resolver );
}
catch ( RepositoryException e )
{
getLogger().warn( e.getMessage(), e );
}
}
// Add no-op resolver.
this.currentResolverStack.addProjectModelResolver( NopProjectResolver.getInstance() );
}
}
}

View File

@ -27,20 +27,32 @@ import org.apache.maven.archiva.model.ArchivaProjectModel;
import org.apache.maven.archiva.model.ArtifactReference;
import org.apache.maven.archiva.model.VersionedReference;
import org.apache.maven.archiva.repository.project.ProjectModelException;
import org.apache.maven.archiva.repository.project.ProjectModelResolverFactory;
import org.apache.maven.archiva.repository.project.filters.EffectiveProjectModelFilter;
import org.apache.maven.archiva.repository.project.resolvers.ProjectModelResolverStack;
/**
* ProjectModelBasedGraphBuilder
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*
* @plexus.component
* role="org.apache.maven.archiva.dependency.graph.DependencyGraphBuilder"
* role-hint="project-model"
*/
public class ProjectModelBasedGraphBuilder
implements DependencyGraphBuilder
{
private ProjectModelResolverStack modelResolver;
/**
* @plexus.requirement
*/
private ProjectModelResolverFactory resolverFactory;
/**
* @plexus.requirement
* role="org.apache.maven.archiva.repository.project.ProjectModelFilter"
* role-hint="effective"
*/
private EffectiveProjectModelFilter effectiveFilter = new EffectiveProjectModelFilter();
public DependencyGraph createGraph( VersionedReference versionedProjectReference )
@ -57,7 +69,7 @@ public class ProjectModelBasedGraphBuilder
VersionedReference versionedProjectReference )
{
ArchivaProjectModel model = resolveModel( fromNode.getArtifact() );
DependencyGraphUtils.addNodeFromModel( model, graph, fromNode );
}
@ -69,7 +81,7 @@ public class ProjectModelBasedGraphBuilder
projectRef.setArtifactId( reference.getArtifactId() );
projectRef.setVersion( reference.getVersion() );
ArchivaProjectModel model = modelResolver.findProject( projectRef );
ArchivaProjectModel model = resolverFactory.getCurrentResolverStack().findProject( projectRef );
if ( model == null )
{
@ -78,8 +90,6 @@ public class ProjectModelBasedGraphBuilder
try
{
effectiveFilter.setProjectModelResolverStack( modelResolver );
ArchivaProjectModel processedModel = effectiveFilter.filter( model );
return processedModel;
@ -103,14 +113,4 @@ public class ProjectModelBasedGraphBuilder
model.setPackaging( reference.getType() );
return model;
}
public ProjectModelResolverStack getModelResolver()
{
return modelResolver;
}
public void setModelResolver( ProjectModelResolverStack modelResolver )
{
this.modelResolver = modelResolver;
}
}

View File

@ -28,7 +28,7 @@ import org.apache.maven.archiva.model.VersionedReference;
import org.apache.maven.archiva.repository.project.ProjectModelException;
import org.apache.maven.archiva.repository.project.ProjectModelFilter;
import org.apache.maven.archiva.repository.project.ProjectModelMerge;
import org.apache.maven.archiva.repository.project.resolvers.ProjectModelResolverStack;
import org.apache.maven.archiva.repository.project.ProjectModelResolverFactory;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.logging.console.ConsoleLogger;
@ -52,22 +52,10 @@ public class EffectiveProjectModelFilter
{
private ProjectModelFilter expressionFilter = new ProjectModelExpressionFilter();
private ProjectModelResolverStack projectModelResolverStack;
public EffectiveProjectModelFilter()
{
projectModelResolverStack = new ProjectModelResolverStack();
}
public void setProjectModelResolverStack( ProjectModelResolverStack resolverStack )
{
this.projectModelResolverStack = resolverStack;
}
public ProjectModelResolverStack getProjectModelResolverStack()
{
return this.projectModelResolverStack;
}
/**
* @plexus.requirement
*/
private ProjectModelResolverFactory resolverFactory;
/**
* Take the provided {@link ArchivaProjectModel} and build the effective {@link ArchivaProjectModel}.
@ -89,7 +77,7 @@ public class EffectiveProjectModelFilter
return null;
}
if ( this.projectModelResolverStack.isEmpty() )
if ( resolverFactory.getCurrentResolverStack().isEmpty() )
{
throw new IllegalStateException( "Unable to build effective pom with no project model resolvers defined." );
}
@ -171,7 +159,7 @@ public class EffectiveProjectModelFilter
getLogger().debug( "Has parent: " + parentRef );
// Find parent using resolvers.
ArchivaProjectModel parentProject = this.projectModelResolverStack.findProject( parentRef );
ArchivaProjectModel parentProject = this.resolverFactory.getCurrentResolverStack().findProject( parentRef );
if ( parentProject != null )
{

View File

@ -0,0 +1,41 @@
package org.apache.maven.archiva.repository.project.resolvers;
/*
* 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 org.apache.maven.archiva.model.ArchivaProjectModel;
import org.apache.maven.archiva.model.VersionedReference;
import org.apache.maven.archiva.repository.project.ProjectModelException;
import org.apache.maven.archiva.repository.project.ProjectModelResolver;
/**
* FalseProjectResolver will never resolver a model.
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class FalseProjectResolver
implements ProjectModelResolver
{
public ArchivaProjectModel resolveProjectModel( VersionedReference reference )
throws ProjectModelException
{
throw new ProjectModelException( "Cannot resolve model in FalseProjectResolver." );
}
}

View File

@ -0,0 +1,32 @@
package org.apache.maven.archiva.repository.project.resolvers;
/*
* 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.
*/
/**
* Tag for RepositoryProjectResolver's to indicate that it is basing
* it's resolution from the Filesystem.
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public interface FilesystemBasedResolver
{
}

View File

@ -0,0 +1,59 @@
package org.apache.maven.archiva.repository.project.resolvers;
/*
* 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 org.apache.maven.archiva.model.ArchivaProjectModel;
import org.apache.maven.archiva.model.VersionedReference;
import org.apache.maven.archiva.repository.project.ProjectModelException;
import org.apache.maven.archiva.repository.project.ProjectModelResolver;
/**
* A No-op Project Resolver, perform no lookup, just returns the requested
* information in the form of a simple ArchviaProjectModel.
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class NopProjectResolver
implements ProjectModelResolver
{
private static NopProjectResolver INSTANCE = new NopProjectResolver();
public static NopProjectResolver getInstance()
{
return INSTANCE;
}
public ArchivaProjectModel resolveProjectModel( VersionedReference reference )
throws ProjectModelException
{
ArchivaProjectModel model = new ArchivaProjectModel();
model.setGroupId( reference.getGroupId() );
model.setArtifactId( reference.getArtifactId() );
model.setVersion( reference.getVersion() );
model.setPackaging( "pom" );
model.setOrigin( "nop" );
return model;
}
}

View File

@ -35,6 +35,8 @@ import java.util.List;
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*
* @plexus.component role="org.apache.maven.archiva.repository.project.resolvers.ProjectModelResolverStack"
*/
public class ProjectModelResolverStack
{
@ -113,11 +115,26 @@ public class ProjectModelResolverStack
return null;
}
public boolean hasResolver( ProjectModelResolver resolver )
{
return this.resolvers.contains( resolver );
}
public boolean isEmpty()
{
return this.resolvers.isEmpty();
}
public void prependProjectModelResolver( ProjectModelResolver resolver )
{
if ( resolver == null )
{
return;
}
this.resolvers.add( 0, resolver );
}
public void removeListener( ProjectModelResolutionListener listener )
{
if ( listener == null )

View File

@ -37,7 +37,7 @@ import java.io.File;
* @version $Id$
*/
public class RepositoryProjectResolver
implements ProjectModelResolver
implements ProjectModelResolver, FilesystemBasedResolver
{
private ArchivaRepository repository;
@ -45,7 +45,8 @@ public class RepositoryProjectResolver
private BidirectionalRepositoryLayout layout;
public RepositoryProjectResolver( ArchivaRepository repository, ProjectModelReader reader, BidirectionalRepositoryLayout layout )
public RepositoryProjectResolver( ArchivaRepository repository, ProjectModelReader reader,
BidirectionalRepositoryLayout layout )
{
this.repository = repository;
this.reader = reader;

View File

@ -29,6 +29,7 @@ import org.apache.maven.archiva.repository.project.ProjectModelException;
import org.apache.maven.archiva.repository.project.ProjectModelFilter;
import org.apache.maven.archiva.repository.project.ProjectModelReader;
import org.apache.maven.archiva.repository.project.ProjectModelResolver;
import org.apache.maven.archiva.repository.project.ProjectModelResolverFactory;
import org.apache.maven.archiva.repository.project.readers.ProjectModel400Reader;
import org.apache.maven.archiva.repository.project.resolvers.RepositoryProjectResolver;
import org.codehaus.plexus.PlexusTestCase;
@ -83,10 +84,9 @@ public class EffectiveProjectModelFilterTest
public void testBuildEffectiveProject()
throws Exception
{
initTestResolverFactory();
EffectiveProjectModelFilter filter = lookupEffective();
filter.getProjectModelResolverStack().addProjectModelResolver( createDefaultRepositoryResolver() );
ArchivaProjectModel startModel = createArchivaProjectModel( DEFAULT_REPOSITORY
+ "/org/apache/maven/archiva/archiva-model/1.0-SNAPSHOT/archiva-model-1.0-SNAPSHOT.pom" );
@ -98,6 +98,17 @@ public class EffectiveProjectModelFilterTest
assertModel( expectedModel, effectiveModel );
}
private ProjectModelResolverFactory initTestResolverFactory()
throws Exception
{
ProjectModelResolverFactory resolverFactory = (ProjectModelResolverFactory) lookup( ProjectModelResolverFactory.class );
resolverFactory.getCurrentResolverStack().clearResolvers();
resolverFactory.getCurrentResolverStack().addProjectModelResolver( createDefaultRepositoryResolver() );
return resolverFactory;
}
private void assertModel( ArchivaProjectModel expectedModel, ArchivaProjectModel effectiveModel )
{
assertEquals( "Equivalent Models", expectedModel, effectiveModel );

View File

@ -28,6 +28,10 @@
<artifactId>archiva-database</artifactId>
<name>Archiva Database</name>
<dependencies>
<dependency>
<groupId>org.apache.maven.archiva</groupId>
<artifactId>archiva-repository-layer</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven.archiva</groupId>
<artifactId>archiva-consumer-api</artifactId>
@ -102,11 +106,6 @@
<artifactId>plexus-registry-commons</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.maven.archiva</groupId>
<artifactId>archiva-repository-layer</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>hsqldb</groupId>
<artifactId>hsqldb</artifactId>

View File

@ -1,4 +1,4 @@
package org.apache.maven.archiva.consumers.database.project;
package org.apache.maven.archiva.database.project;
/*
* Licensed to the Apache Software Foundation (ASF) under one

View File

@ -0,0 +1,153 @@
package org.apache.maven.archiva.database.project;
/*
* 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 org.apache.maven.archiva.database.ArchivaDAO;
import org.apache.maven.archiva.database.ArchivaDatabaseException;
import org.apache.maven.archiva.database.ObjectNotFoundException;
import org.apache.maven.archiva.model.ArchivaProjectModel;
import org.apache.maven.archiva.model.VersionedReference;
import org.apache.maven.archiva.repository.project.ProjectModelException;
import org.apache.maven.archiva.repository.project.ProjectModelResolver;
import org.apache.maven.archiva.repository.project.resolvers.FilesystemBasedResolver;
import org.apache.maven.archiva.repository.project.resolvers.ProjectModelResolutionListener;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import java.util.List;
/**
* Just in Time save of project models to the database, implemented as a listener
* on {@link ProjectModelResolver} objects that implement {@link FilesystemBasedResolver}.
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*
* @plexus.component
* role="org.apache.maven.archiva.repository.project.resolvers.ProjectModelResolutionListener"
* role-hint="model-to-db"
*/
public class ProjectModelToDatabaseListener
extends AbstractLogEnabled
implements ProjectModelResolutionListener
{
/**
* @plexus.requirement role-hint="jdo"
*/
private ArchivaDAO dao;
private void saveInDatabase( ArchivaProjectModel model )
throws ProjectModelException
{
try
{
dao.getProjectModelDAO().saveProjectModel( model );
}
catch ( ArchivaDatabaseException e )
{
throw new ProjectModelException( "Unable to save model to database: " + e.getMessage(), e );
}
}
private void removeFromDatabase( ArchivaProjectModel model )
throws ProjectModelException
{
try
{
dao.getProjectModelDAO().deleteProjectModel( model );
}
catch ( ArchivaDatabaseException e )
{
throw new ProjectModelException( "Unable to remove existing model from database: " + e.getMessage(), e );
}
}
private boolean existsInDatabase( ArchivaProjectModel model )
throws ProjectModelException
{
try
{
ArchivaProjectModel dbmodel = dao.getProjectModelDAO().getProjectModel( model.getGroupId(),
model.getArtifactId(),
model.getVersion() );
return ( dbmodel != null );
}
catch ( ObjectNotFoundException e )
{
return false;
}
catch ( ArchivaDatabaseException e )
{
throw new ProjectModelException( "Unable to check for existing model from database: " + e.getMessage(), e );
}
}
public void resolutionAttempting( VersionedReference projectRef, ProjectModelResolver resolver )
{
/* do nothing */
}
public void resolutionError( VersionedReference projectRef, ProjectModelResolver resolver, Exception cause )
{
/* do nothing */
}
public void resolutionMiss( VersionedReference projectRef, ProjectModelResolver resolver )
{
/* do nothing */
}
public void resolutionNotFound( VersionedReference projectRef, List resolverList )
{
/* do nothing */
}
public void resolutionStart( VersionedReference projectRef, List resolverList )
{
/* do nothing */
}
public void resolutionSuccess( VersionedReference projectRef, ProjectModelResolver resolver,
ArchivaProjectModel model )
{
if ( !( resolver instanceof FilesystemBasedResolver ) )
{
// Nothing to do. skip it.
return;
}
model.setOrigin( "filesystem" );
try
{
// Test if it exists.
if ( existsInDatabase( model ) )
{
removeFromDatabase( model );
}
saveInDatabase( model );
}
catch ( ProjectModelException e )
{
getLogger().warn( e.getMessage(), e );
}
}
}

View File

@ -28,7 +28,6 @@ import org.apache.maven.archiva.database.browsing.RepositoryBrowsing;
import org.apache.maven.archiva.model.ArchivaProjectModel;
import org.codehaus.plexus.xwork.action.PlexusActionSupport;
import java.util.Collections;
import java.util.List;
/**
@ -42,7 +41,7 @@ public class ShowArtifactAction
implements Validateable
{
/* .\ Not Exposed \._____________________________________________ */
/**
* @plexus.requirement role-hint="default"
*/
@ -67,11 +66,6 @@ public class ShowArtifactAction
* The list of artifacts that depend on this versioned project.
*/
private List dependees;
/**
* The list of dependencies in tree format
*/
private List dependencyTree;
/**
* The reports associated with this versioned project.
@ -80,7 +74,7 @@ public class ShowArtifactAction
private List mailingLists;
private List dependencies;
private List dependencies;
/**
* Show the versioned project information tab.
@ -96,11 +90,10 @@ public class ShowArtifactAction
}
catch ( ObjectNotFoundException oe )
{
addActionError( "Unable to find project model for [" + groupId + ":" + artifactId
+ ":" + version + "]." );
addActionError( "Unable to find project model for [" + groupId + ":" + artifactId + ":" + version + "]." );
return ERROR;
}
}
return SUCCESS;
}
@ -109,12 +102,12 @@ public class ShowArtifactAction
* Show the artifact information tab.
*/
public String dependencies()
throws ObjectNotFoundException, ArchivaDatabaseException
throws ObjectNotFoundException, ArchivaDatabaseException
{
this.model = repoBrowsing.selectVersion( groupId, artifactId, version );
this.dependencies = model.getDependencies();
return SUCCESS;
}
@ -122,23 +115,23 @@ public class ShowArtifactAction
* Show the mailing lists information tab.
*/
public String mailingLists()
throws ObjectNotFoundException, ArchivaDatabaseException
throws ObjectNotFoundException, ArchivaDatabaseException
{
this.model = repoBrowsing.selectVersion( groupId, artifactId, version );
this.mailingLists = model.getMailingLists();
return SUCCESS;
}
/**
* Show the reports tab.
*/
public String reports()
throws ObjectNotFoundException, ArchivaDatabaseException
throws ObjectNotFoundException, ArchivaDatabaseException
{
System.out.println("#### In reports.");
System.out.println( "#### In reports." );
// TODO: hook up reports on project - this.reports = artifactsDatabase.findArtifactResults( groupId, artifactId, version );
System.out.println("#### Found " + reports.size() + " reports.");
System.out.println( "#### Found " + reports.size() + " reports." );
return SUCCESS;
}
@ -147,7 +140,7 @@ public class ShowArtifactAction
* Show the dependees (other artifacts that depend on this project) tab.
*/
public String dependees()
throws ObjectNotFoundException, ArchivaDatabaseException
throws ObjectNotFoundException, ArchivaDatabaseException
{
this.model = repoBrowsing.selectVersion( groupId, artifactId, version );
@ -160,12 +153,10 @@ public class ShowArtifactAction
* Show the dependencies of this versioned project tab.
*/
public String dependencyTree()
throws ObjectNotFoundException, ArchivaDatabaseException
throws ObjectNotFoundException, ArchivaDatabaseException
{
this.model = repoBrowsing.selectVersion( groupId, artifactId, version );
this.dependencyTree = Collections.EMPTY_LIST;
return SUCCESS;
}
@ -237,14 +228,8 @@ public class ShowArtifactAction
return dependencies;
}
public List getDependees()
{
return dependees;
}
public List getDependencyTree()
{
return dependencyTree;
}
}

View File

@ -20,7 +20,10 @@ package org.apache.maven.archiva.web.startup;
*/
import org.apache.commons.lang.StringUtils;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -30,8 +33,14 @@ import java.util.regex.Pattern;
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*
* @plexus.component
* role="org.apache.maven.archiva.web.startup.Banner"
* role-hint="default"
*/
public class Banner
extends AbstractLogEnabled
implements Initializable
{
public static String encode( String raw )
{
@ -222,4 +231,10 @@ public class Banner
String banner = getBanner( version );
logger.info( StringUtils.repeat( "_", 25 ) + "\n" + banner );
}
public void initialize()
throws InitializationException
{
Banner.display( getLogger(), ArchivaVersion.determineVersion( this.getClass().getClassLoader() ) );
}
}

View File

@ -44,8 +44,9 @@ import java.util.List;
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*
* @plexus.component role="org.apache.maven.archiva.web.startup.ConfigurationSynchronization"
* role-hint="default"
* @plexus.component
* role="org.apache.maven.archiva.web.startup.ConfigurationSynchronization"
* role-hint="default"
*/
public class ConfigurationSynchronization
extends AbstractLogEnabled
@ -59,8 +60,8 @@ public class ConfigurationSynchronization
/**
* @plexus.requirement role-hint="default"
*/
RoleManager roleManager;
private RoleManager roleManager;
/**
* @plexus.requirement
*/
@ -109,40 +110,40 @@ public class ConfigurationSynchronization
ArchivaRepository drepo = ArchivaConfigurationAdaptor.toArchivaRepository( repoConfig );
drepo.getModel().setCreationSource( "configuration" );
dao.getRepositoryDAO().saveRepository( drepo );
}
}
}
catch ( ArchivaDatabaseException e )
{
// Log error.
getLogger().error( "Unable to add configured repositories to the database: " + e.getMessage(), e );
}
// manage roles for repositories
try
try
{
if ( !roleManager.templatedRoleExists( "archiva-repository-observer", repoConfig.getId() ) )
{
roleManager.createTemplatedRole( "archiva-repository-observer", repoConfig.getId() );
}
if ( !roleManager.templatedRoleExists( "archiva-repository-manager", repoConfig.getId() ) );
}
if ( !roleManager.templatedRoleExists( "archiva-repository-manager", repoConfig.getId() ) )
;
{
roleManager.createTemplatedRole( "archiva-repository-manager", repoConfig.getId() );
}
}
}
catch ( RoleManagerException e )
{
// Log error.
getLogger().error( "Unable to create roles for configured repositories: " + e.getMessage(), e );
}
}
}
public void initialize()
throws InitializationException
{
Banner.display( getLogger(), ArchivaVersion.determineVersion( this.getClass().getClassLoader() ) );
synchConfiguration();
archivaConfiguration.addChangeListener( this );
}

View File

@ -0,0 +1,72 @@
package org.apache.maven.archiva.web.startup;
/*
* 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 org.apache.maven.archiva.database.project.ProjectModelToDatabaseListener;
import org.apache.maven.archiva.repository.project.ProjectModelResolver;
import org.apache.maven.archiva.repository.project.ProjectModelResolverFactory;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
/**
* ResolverFactoryInit - Initialize the Resolver Factory, and hook it up to
* the database.
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*
* @plexus.component
* role="org.apache.maven.archiva.web.startup.ResolverFactoryInit"
* role-hint="default"
*/
public class ResolverFactoryInit
extends AbstractLogEnabled
implements Initializable
{
/**
* @plexus.requirement role-hint="database"
*/
private ProjectModelResolver databaseResolver;
/**
* @plexus.requirement
* role="org.apache.maven.archiva.repository.project.resolvers.ProjectModelResolutionListener"
* role-hint="model-to-db"
*/
private ProjectModelToDatabaseListener modelToDbListener;
/**
* The resolver factorying being initialized.
*
* @plexus.requirement
*/
private ProjectModelResolverFactory resolverFactory;
public void initialize()
throws InitializationException
{
if ( !resolverFactory.getCurrentResolverStack().hasResolver( databaseResolver ) )
{
resolverFactory.getCurrentResolverStack().prependProjectModelResolver( databaseResolver );
}
resolverFactory.getCurrentResolverStack().addListener( modelToDbListener );
}
}

View File

@ -0,0 +1,242 @@
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 org.apache.commons.lang.StringUtils;
import org.apache.maven.archiva.dependency.DependencyGraphFactory;
import org.apache.maven.archiva.dependency.graph.DependencyGraph;
import org.apache.maven.archiva.dependency.graph.DependencyGraphBuilder;
import org.apache.maven.archiva.dependency.graph.DependencyGraphEdge;
import org.apache.maven.archiva.dependency.graph.DependencyGraphNode;
import org.apache.maven.archiva.dependency.graph.GraphTaskException;
import org.apache.maven.archiva.dependency.graph.walk.BaseVisitor;
import org.apache.maven.archiva.dependency.graph.walk.DependencyGraphWalker;
import org.apache.maven.archiva.dependency.graph.walk.WalkDepthFirstSearch;
import org.apache.maven.archiva.model.ArtifactReference;
import org.apache.maven.archiva.model.DependencyScope;
import org.apache.maven.archiva.model.VersionedReference;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
/**
* DependencyTree
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*
* @plexus.component role="org.apache.maven.archiva.web.tags.DependencyTree"
*/
public class DependencyTree
extends AbstractLogEnabled
implements Initializable
{
/**
* @plexus.requirement
* role="org.apache.maven.archiva.dependency.graph.DependencyGraphBuilder"
* role-hint="project-model"
*/
private DependencyGraphBuilder graphBuilder;
private DependencyGraphFactory graphFactory = new DependencyGraphFactory();
public class TreeEntry
{
private String pre = "";
private String post = "";
private ArtifactReference artifact;
public void setArtifact( ArtifactReference artifact )
{
this.artifact = artifact;
}
public ArtifactReference getArtifact()
{
return artifact;
}
public String getPost()
{
return post;
}
public void setPost( String post )
{
this.post = post;
}
public String getPre()
{
return pre;
}
public void setPre( String pre )
{
this.pre = pre;
}
public void appendPre( String string )
{
this.pre += string;
}
public void appendPost( String string )
{
this.post += string;
}
}
public List gatherTreeList( String groupId, String artifactId, String version, String nodevar,
PageContext pageContext )
throws JspException
{
if ( StringUtils.isBlank( groupId ) )
{
String emsg = "Error generating dependency tree: groupId is blank.";
getLogger().error( emsg );
throw new JspException( emsg );
}
DependencyGraph graph = fetchGraph( groupId, artifactId, version );
if ( graph == null )
{
throw new JspException( "Graph is null." );
}
TreeListVisitor treeListVisitor = new TreeListVisitor();
DependencyGraphWalker walker = new WalkDepthFirstSearch();
walker.visit( graph, treeListVisitor );
return treeListVisitor.getList();
}
class TreeListVisitor
extends BaseVisitor
{
private List list;
private int walkDepth;
private int outputDepth;
private Stack entryStack = new Stack();
private TreeEntry currentEntry;
public TreeListVisitor()
{
this.list = new ArrayList();
}
public List getList()
{
return this.list;
}
public void discoverGraph( DependencyGraph graph )
{
super.discoverGraph( graph );
this.list.clear();
this.entryStack.clear();
walkDepth = 0;
outputDepth = -1;
}
public void discoverNode( DependencyGraphNode node )
{
super.discoverNode( node );
currentEntry = new TreeEntry();
while ( walkDepth > outputDepth )
{
currentEntry.appendPre( "<ul>" );
outputDepth++;
}
currentEntry.appendPre( "<li>" );
currentEntry.setArtifact( node.getArtifact() );
currentEntry.appendPost( "</li>" );
this.list.add( currentEntry );
this.entryStack.push( currentEntry );
}
public void finishNode( DependencyGraphNode node )
{
super.finishNode( node );
while ( walkDepth < outputDepth )
{
currentEntry.appendPost( "</ul>" );
outputDepth--;
}
this.entryStack.pop();
}
public void discoverEdge( DependencyGraphEdge edge )
{
super.discoverEdge( edge );
walkDepth++;
}
public void finishEdge( DependencyGraphEdge edge )
{
super.finishEdge( edge );
walkDepth--;
}
}
private DependencyGraph fetchGraph( String groupId, String artifactId, String version )
{
// TODO Cache the results to disk, in XML format, in the same place as the artifact is located.
VersionedReference projectRef = new VersionedReference();
projectRef.setGroupId( groupId );
projectRef.setArtifactId( artifactId );
projectRef.setVersion( version );
try
{
return graphFactory.getGraph( projectRef );
}
catch ( GraphTaskException e )
{
getLogger().warn( "Unable to get Graph: " + e.getMessage(), e );
return null;
}
}
public void initialize()
throws InitializationException
{
this.graphFactory.setGraphBuilder( graphBuilder );
this.graphFactory.setDesiredScope( DependencyScope.TEST );
}
}

View File

@ -0,0 +1,205 @@
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 org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.archiva.web.tags.DependencyTree.TreeEntry;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.IterationTag;
import javax.servlet.jsp.tagext.TagSupport;
import javax.servlet.jsp.tagext.TryCatchFinally;
/**
* DependencyTreeTag - just here to output the dependency tree to the browser.
* It was easier to do it this way, vs accessing the dependency graph via a JSP.
*
* <pre>
* <archiva:dependency-tree groupId="org.apache.maven.archiva"
* artifactId="archiva-common"
* version="1.0"
* nodevar="node">
* <b>${node.groupId}</b>:<b>${node.artifactId}</b>:<b>${node.version}</b> (${node.scope})
* </archiva:dependency-tree>
* </pre>
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class DependencyTreeTag
extends TagSupport
implements IterationTag, TryCatchFinally
{
private String groupId;
private String artifactId;
private String version;
private String nodevar;
private Iterator treeIterator;
private List tree;
private TreeEntry currentTreeEntry;
public int doAfterBody()
throws JspException
{
if ( currentTreeEntry != null )
{
out( currentTreeEntry.getPost() );
}
if ( treeIterator.hasNext() )
{
currentTreeEntry = (TreeEntry) treeIterator.next();
out( currentTreeEntry.getPre() );
exposeVariables();
return EVAL_BODY_AGAIN;
}
out( "\n</div><!-- end of dependency-graph -->" );
return SKIP_BODY;
}
public void doCatch( Throwable t )
throws Throwable
{
throw t;
}
public void doFinally()
{
unExposeVariables();
}
public int doStartTag()
throws JspException
{
DependencyTree deptree;
try
{
deptree = (DependencyTree) PlexusTagUtil.lookup( pageContext, DependencyTree.class.getName() );
}
catch ( ComponentLookupException e )
{
throw new JspException( "Unable to lookup DependencyTree: " + e.getMessage(), e );
}
if ( deptree == null )
{
throw new JspException( "Unable to process dependency tree. Component not found." );
}
if ( StringUtils.isBlank( nodevar ) )
{
nodevar = "node";
}
this.tree = deptree.gatherTreeList( groupId, artifactId, version, nodevar, pageContext );
if ( CollectionUtils.isEmpty( this.tree ) )
{
return SKIP_BODY;
}
treeIterator = tree.iterator();
out( "<div class=\"dependency-graph\">" );
currentTreeEntry = (TreeEntry) treeIterator.next();
out( currentTreeEntry.getPre() );
exposeVariables();
return EVAL_BODY_INCLUDE;
}
public void release()
{
groupId = "";
artifactId = "";
version = "";
nodevar = "";
tree = null;
treeIterator = null;
super.release();
}
public void setArtifactId( String artifactId )
{
this.artifactId = artifactId;
}
public void setGroupId( String groupId )
{
this.groupId = groupId;
}
public void setNodevar( String nodevar )
{
this.nodevar = nodevar;
}
public void setVersion( String version )
{
this.version = version;
}
private void exposeVariables()
throws JspException
{
if ( currentTreeEntry == null )
{
pageContext.removeAttribute( nodevar, PageContext.PAGE_SCOPE );
}
else
{
pageContext.setAttribute( nodevar, currentTreeEntry.getArtifact() );
}
}
private void out( String msg )
throws JspException
{
try
{
pageContext.getOut().append( msg );
}
catch ( IOException e )
{
throw new JspException( "Unable to output to jsp page context." );
}
}
private void unExposeVariables()
{
pageContext.removeAttribute( nodevar, PageContext.PAGE_SCOPE );
}
}

View File

@ -20,10 +20,22 @@
<plexus>
<load-on-start>
<component>
<role>org.apache.maven.archiva.web.startup.Banner</role>
<role-hint>default</role-hint>
</component>
<component>
<role>org.apache.maven.archiva.web.startup.ConfigurationSynchronization</role>
<role-hint>default</role-hint>
</component>
<component>
<role>org.apache.maven.archiva.web.startup.ResolverFactoryInit</role>
<role-hint>default</role-hint>
</component>
<component>
<role>org.apache.maven.archiva.web.startup.Banner</role>
<role-hint>default</role-hint>
</component>
<component>
<role>org.apache.maven.archiva.scheduled.ArchivaTaskScheduler</role>
<role-hint>default</role-hint>

View File

@ -95,5 +95,45 @@
</tag>
<tag>
<name>dependency-tree</name>
<tag-class>org.apache.maven.archiva.web.tags.DependencyTreeTag</tag-class>
<body-content>JSP</body-content>
<description><![CDATA[Render a dependency tree for the provided project.]]></description>
<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>
<attribute>
<name>nodevar</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<description><![CDATA[The variable name for the node.]]></description>
</attribute>
</tag>
</taglib>

View File

@ -213,7 +213,7 @@
</action>
<action name="showArtifactDependencyTree" class="showArtifactAction" method="dependencyTree">
<result>/WEB-INF/jsp/showArtifact.jsp</result>
<result>/WEB-INF/jsp/artifact/dependencyTree.jsp</result>
</action>
</package>

View File

@ -27,4 +27,8 @@
<decorator name="default" page="default.jsp">
<pattern>/*</pattern>
</decorator>
<decorator name="artifactDetails" page="artifactDecorator.jsp">
<pattern>/*/dependencyTree</pattern>
</decorator>
</decorators>

View File

@ -21,7 +21,7 @@
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib prefix="redback" uri="http://plexus.codehaus.org/redback/taglib-1.0" %>
<%@ taglib prefix="archiva" uri="http://maven.apache.org/archiva"%>
<%@ taglib prefix="archiva" uri="http://maven.apache.org/archiva" %>
<html>
<head>

View File

@ -0,0 +1,27 @@
<%--
~ 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.
--%>
<%@ taglib prefix="page" uri="http://www.opensymphony.com/sitemesh/page" %>
<%@ taglib prefix="my" tagdir="/WEB-INF/tags" %>
<%@ taglib prefix="archiva" uri="http://maven.apache.org/archiva" %>
<archiva:dependency-tree groupId="${groupId}" artifactId="${artifactId}" version="${version}">
<my:showArtifactLink groupId="${node.groupId}" artifactId="${node.artifactId}"
version="${node.version}"/>
</archiva:dependency-tree>

View File

@ -0,0 +1,149 @@
<%--
~ 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.
--%>
<%@ taglib prefix="decorator" uri="http://www.opensymphony.com/sitemesh/decorator" %>
<%@ taglib prefix="page" uri="http://www.opensymphony.com/sitemesh/page" %>
<%@ taglib prefix="ww" uri="/webwork" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="redback" uri="http://plexus.codehaus.org/redback/taglib-1.0" %>
<%@ taglib prefix="my" tagdir="/WEB-INF/tags" %>
<%@ taglib prefix="archiva" uri="http://maven.apache.org/archiva" %>
<page:applyDecorator name="default">
<html>
<head>
<title>Browse Repository</title>
<ww:head/>
</head>
<body>
<ww:set name="model" value="model"/>
<c:choose>
<c:when test="${model.packaging == 'maven-plugin'}">
<c:url var="imageUrl" value="/images/mavenplugin.gif"/>
<c:set var="packageName">Maven Plugin</c:set>
</c:when>
<c:when test="${model.packaging == 'pom'}">
<c:url var="imageUrl" value="/images/pom.gif"/>
<c:set var="packageName">POM</c:set>
</c:when>
<%-- These types aren't usually set in the POM yet, so we fudge them for the well known ones --%>
<c:when test="${model.packaging == 'maven-archetype' or model.groupId == 'org.apache.maven.archetypes'}">
<c:url var="imageUrl" value="/images/archetype.gif"/>
<c:set var="packageName">Maven Archetype</c:set>
</c:when>
<c:when test="${model.packaging == 'maven-skin' or model.groupId == 'org.apache.maven.skins'}">
<c:url var="imageUrl" value="/images/skin.gif"/>
<c:set var="packageName">Maven Skin</c:set>
</c:when>
<%-- Must be last so that the above get picked up if possible --%>
<c:when test="${model.packaging == 'jar'}">
<c:url var="imageUrl" value="/images/jar.gif"/>
<c:set var="packageName">JAR</c:set>
</c:when>
<c:otherwise>
<c:url var="imageUrl" value="/images/other.gif"/>
<c:set var="packageName"></c:set>
</c:otherwise>
</c:choose>
<img src="${imageUrl}" width="66" height="66" alt="${packageName}" title="${packageName}" style="float: left"/>
<h1>
<c:choose>
<c:when test="${empty(model.name)}">
${model.artifactId}
</c:when>
<c:otherwise>
${model.name}
</c:otherwise>
</c:choose>
</h1>
<div id="contentArea">
<div id="tabs">
<span>
<c:set var="url">
<ww:url action="showArtifact">
<ww:param name="groupId" value="%{groupId}"/>
<ww:param name="artifactId" value="%{artifactId}"/>
<ww:param name="version" value="%{version}"/>
</ww:url>
</c:set>
<my:currentWWUrl url="${url}">Info</my:currentWWUrl>
<c:set var="url">
<ww:url action="showArtifactDependencies">
<ww:param name="groupId" value="%{groupId}"/>
<ww:param name="artifactId" value="%{artifactId}"/>
<ww:param name="version" value="%{version}"/>
</ww:url>
</c:set>
<my:currentWWUrl url="${url}">Dependencies</my:currentWWUrl>
<c:set var="url">
<ww:url action="showArtifactDependencyTree">
<ww:param name="groupId" value="%{groupId}"/>
<ww:param name="artifactId" value="%{artifactId}"/>
<ww:param name="version" value="%{version}"/>
</ww:url>
</c:set>
<my:currentWWUrl url="${url}">Dependency Tree</my:currentWWUrl>
<c:set var="url">
<ww:url action="showArtifactDependees">
<ww:param name="groupId" value="%{groupId}"/>
<ww:param name="artifactId" value="%{artifactId}"/>
<ww:param name="version" value="%{version}"/>
</ww:url>
</c:set>
<my:currentWWUrl url="${url}">Used By</my:currentWWUrl>
<c:set var="url">
<ww:url action="showArtifactMailingLists">
<ww:param name="groupId" value="%{groupId}"/>
<ww:param name="artifactId" value="%{artifactId}"/>
<ww:param name="version" value="%{version}"/>
</ww:url>
</c:set>
<my:currentWWUrl url="${url}">Mailing Lists</my:currentWWUrl>
<%-- POSTPONED to 1.0-alpha-2
<redback:ifAnyAuthorized permissions="archiva-access-reports">
<c:set var="url">
<ww:url action="showArtifactReports">
<ww:param name="groupId" value="%{groupId}"/>
<ww:param name="artifactId" value="%{artifactId}"/>
<ww:param name="version" value="%{version}"/>
</ww:url>
</c:set>
<my:currentWWUrl url="${url}">Reports</my:currentWWUrl>
</redback:ifAnyAuthorized>
--%>
</span>
</div>
<div class="sidebar3">
<archiva:downloadArtifact groupId="${groupId}" artifactId="${artifactId}" version="${Version}" />
</div>
<decorator:body />
</div>
</body>
</html>
</page:applyDecorator>

View File

@ -20,28 +20,12 @@
<%@ taglib prefix="ww" uri="/webwork" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="my" tagdir="/WEB-INF/tags" %>
<%@ taglib prefix="archiva" uri="http://maven.apache.org/archiva" %>
<ul class="dependencyTree">
<c:set var="prevDepth" value="1"/>
<ww:set name="dependencyTree" value="dependencyTree"/>
<c:forEach items="${dependencyTree}" var="node">
<c:choose>
<c:when test="${node.depth < prevDepth}">
</ul>
<li>
</c:when>
<c:when test="${node.depth > prevDepth}">
<ul>
<li>
</c:when>
<c:otherwise>
<li>
</c:otherwise>
</c:choose>
<archiva:dependency-tree groupId="${groupId}" artifactId="${artifactId}" version="${version}" />
<%--
<my:showArtifactLink groupId="${node.artifact.groupId}" artifactId="${node.artifact.artifactId}"
version="${node.artifact.version}"/>
</li>
<c:set var="prevDepth" value="${node.depth}"/>
</c:forEach>
</ul>
--%>