* Implemented ArtifactDAO

* Fixed Query / Constraints when using dates (and other parameterized objects)



git-svn-id: https://svn.apache.org/repos/asf/maven/archiva/branches@526879 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Joakim Erdfelt 2007-04-09 19:12:10 +00:00
parent ae49b08e31
commit 7b322e2d20
11 changed files with 462 additions and 94 deletions

View File

@ -20,7 +20,6 @@
*/
import org.apache.maven.archiva.model.ArchivaArtifact;
import org.apache.maven.archiva.model.ArchivaArtifactModel;
import java.util.List;

View File

@ -39,4 +39,31 @@ public interface Constraint
* @return the sort direction name. ("ASC" or "DESC") (only valid if {@link #getSortColumn()} is specified.)
*/
public String getSortDirection();
/**
* Get the declared imports used for this query. (optional)
*
* NOTE: This is DAO implementation specific.
*
* @return the imports. (can be null)
*/
public String[] getDeclaredImports();
/**
* Get the declared parameters used for this query. (optional)
*
* NOTE: This is DAO implementation specific.
*
* @return the parameters. (can be null)
*/
public String[] getDeclaredParameters();
/**
* Get the parameters used for this query. (required if using {@link #getDeclaredParameters()} )
*
* NOTE: This is DAO implementation specific.
*
* @return the parameters. (can be null)
*/
public Object[] getParameters();
}

View File

@ -22,23 +22,36 @@
import org.apache.maven.archiva.database.Constraint;
/**
* UnprocessedArtifactsConstraint
* AbstractConstraint
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class UnprocessedArtifactsConstraint
public abstract class AbstractConstraint
implements Constraint
{
protected String[] declImports;
protected String[] declParams;
protected Object[] params;
public String getFetchLimits()
{
return null;
}
public String getSortColumn()
public String[] getDeclaredImports()
{
return "groupId";
return declImports;
}
public String[] getDeclaredParameters()
{
return declParams;
}
public Object[] getParameters()
{
return params;
}
public String getSortDirection()
@ -46,9 +59,7 @@ public String getSortDirection()
return Constraint.ASCENDING;
}
public String getWhereCondition()
{
return "whenProcessed == null";
}
public abstract String getSortColumn();
public abstract String getWhereCondition();
}

View File

@ -9,6 +9,7 @@
* @version $Id$
*/
public class ArchivaRepositoryByUrlConstraint
extends AbstractConstraint
implements Constraint
{
private String whereCondition;
@ -23,18 +24,8 @@ public String getWhereCondition()
return whereCondition;
}
public String getFetchLimits()
{
return null;
}
public String getSortColumn()
{
return "url";
}
public String getSortDirection()
{
return Constraint.ASCENDING;
}
}

View File

@ -0,0 +1,72 @@
package org.apache.maven.archiva.database.constraints;
/*
* 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.Constraint;
import java.util.Date;
/**
* ArtifactsProcessedConstraint
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class ArtifactsProcessedConstraint
extends AbstractConstraint
implements Constraint
{
private String whereClause;
public ArtifactsProcessedConstraint( boolean isProcessed )
{
if ( isProcessed )
{
whereClause = "whenProcessed != null";
}
else
{
whereClause = "whenProcessed == null";
}
}
/**
* A Constraint showing artifacts processed since date provided.
* @param since
*/
public ArtifactsProcessedConstraint( Date since )
{
whereClause = "whenProcessed > since";
declImports = new String[] { "import java.util.Date" };
declParams = new String[] { "Date since" };
params = new Object[] { since };
}
public String getSortColumn()
{
return "groupId";
}
public String getWhereCondition()
{
return whereClause;
}
}

View File

@ -182,6 +182,8 @@ public List getAllObjects( Class clazz, Constraint constraint )
Query query = pm.newQuery( extent );
List result = null;
if ( constraint != null )
{
if ( constraint.getSortColumn() != null )
@ -205,9 +207,65 @@ public List getAllObjects( Class clazz, Constraint constraint )
{
query.setFilter( constraint.getWhereCondition() );
}
if ( constraint.getDeclaredImports() != null )
{
for ( int i = 0; i < constraint.getDeclaredImports().length; i++ )
{
String qimport = constraint.getDeclaredImports()[i];
query.declareImports( qimport );
}
}
List result = (List) query.execute();
if ( constraint.getDeclaredParameters() != null )
{
if ( constraint.getParameters() == null )
{
throw new JDOException( "Unable to use query, there are declared parameters, "
+ "but no parameter objects to use." );
}
if ( constraint.getParameters().length != constraint.getDeclaredParameters().length )
{
throw new JDOException( "Unable to use query, there are <"
+ constraint.getDeclaredParameters().length + "> declared parameters, yet there are <"
+ constraint.getParameters().length + "> parameter objects to use. This should be equal." );
}
for ( int i = 0; i < constraint.getDeclaredParameters().length; i++ )
{
String declaredParam = constraint.getDeclaredParameters()[i];
query.declareParameters( declaredParam );
}
switch ( constraint.getParameters().length )
{
case 1:
result = (List) query.execute( constraint.getParameters()[0] );
break;
case 2:
result = (List) query
.execute( constraint.getParameters()[0], constraint.getParameters()[1] );
break;
case 3:
result = (List) query
.execute( constraint.getParameters()[0], constraint.getParameters()[1], constraint
.getParameters()[2] );
break;
default:
throw new JDOException( "Unable to use more than 3 parameters." );
}
}
else
{
// Process unparameterized query.
result = (List) query.execute();
}
}
else
{
result = (List) query.execute();
}
result = (List) pm.detachCopyAll( result );
@ -221,63 +279,12 @@ public List getAllObjects( Class clazz, Constraint constraint )
}
}
// public List getUserAssignmentsForRoles( Class clazz, String ordering, Collection roleNames )
// {
// PersistenceManager pm = getPersistenceManager();
// Transaction tx = pm.currentTransaction();
//
// try
// {
// tx.begin();
//
// Extent extent = pm.getExtent( clazz, true );
//
// Query query = pm.newQuery( extent );
//
// if ( ordering != null )
// {
// query.setOrdering( ordering );
// }
//
// query.declareImports( "import java.lang.String" );
//
// StringBuffer filter = new StringBuffer();
//
// Iterator i = roleNames.iterator();
//
// if ( roleNames.size() > 0 )
// {
// filter.append( "this.roleNames.contains(\"" ).append( i.next() ).append( "\")" );
//
// while ( i.hasNext() )
// {
// filter.append( " || this.roleNames.contains(\"" ).append( i.next() ).append( "\")" );
// }
//
// query.setFilter( filter.toString() );
// }
//
// List result = (List) query.execute();
//
// result = (List) pm.detachCopyAll( result );
//
// tx.commit();
//
// return result;
// }
// finally
// {
// rollbackIfActive( tx );
// }
// }
public Object getObjectById( Class clazz, Object id, String fetchGroup )
throws ObjectNotFoundException, ArchivaDatabaseException
{
if ( id == null )
{
throw new ObjectNotFoundException( "Unable to get object '" + clazz.getName()
+ "' from jdo using null id." );
throw new ObjectNotFoundException( "Unable to get object '" + clazz.getName() + "' from jdo using null id." );
}
PersistenceManager pm = getPersistenceManager();

View File

@ -24,7 +24,11 @@
import org.apache.maven.archiva.database.Constraint;
import org.apache.maven.archiva.database.ObjectNotFoundException;
import org.apache.maven.archiva.model.ArchivaArtifact;
import org.apache.maven.archiva.model.ArchivaArtifactModel;
import org.apache.maven.archiva.model.jpox.ArchivaArtifactModelKey;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
@ -39,13 +43,14 @@ public class JdoArtifactDAO
implements ArtifactDAO
{
/**
* @plexus.requirement role-hint="default"
* @plexus.requirement role-hint="archiva"
*/
private JdoAccess jdo;
/* .\ Archiva Artifact \. _____________________________________________________________ */
public ArchivaArtifact createArtifact( String groupId, String artifactId, String version, String classifier, String type )
public ArchivaArtifact createArtifact( String groupId, String artifactId, String version, String classifier,
String type )
{
ArchivaArtifact artifact;
@ -61,32 +66,57 @@ public ArchivaArtifact createArtifact( String groupId, String artifactId, String
return artifact;
}
public ArchivaArtifact getArtifact( String groupId, String artifactId, String version, String classifier, String type )
public ArchivaArtifact getArtifact( String groupId, String artifactId, String version, String classifier,
String type )
throws ObjectNotFoundException, ArchivaDatabaseException
{
ArchivaArtifactModelKey key = new ArchivaArtifactModelKey();
key.groupId = groupId;
key.artifactId = artifactId;
key.version = version;
key.classifier = classifier;
key.type = type;
return null;
ArchivaArtifactModel model = (ArchivaArtifactModel) jdo.getObjectById( ArchivaArtifactModel.class, key, null );
return new ArchivaArtifact( model );
}
public List queryArtifacts( Constraint constraint )
throws ObjectNotFoundException, ArchivaDatabaseException
{
// TODO Auto-generated method stub
return null;
List results = jdo.getAllObjects( ArchivaArtifactModel.class, constraint );
if ( ( results == null ) || results.isEmpty() )
{
return results;
}
List ret = new ArrayList();
Iterator it = results.iterator();
while ( it.hasNext() )
{
ArchivaArtifactModel model = (ArchivaArtifactModel) it.next();
ret.add( new ArchivaArtifact( model ) );
}
return ret;
}
public ArchivaArtifact saveArtifact( ArchivaArtifact artifact )
throws ArchivaDatabaseException
{
// TODO Auto-generated method stub
ArchivaArtifactModel model = (ArchivaArtifactModel) jdo.saveObject( artifact.getModel() );
if ( model == null )
{
return null;
}
return new ArchivaArtifact( model );
}
public void deleteArtifact( ArchivaArtifact artifact )
throws ArchivaDatabaseException
{
// TODO Auto-generated method stub
jdo.removeObject( artifact.getModel() );
}
}

View File

@ -39,7 +39,7 @@ public class JdoProjectModelDAO
implements ProjectModelDAO
{
/**
* @plexus.requirement role-hint="default"
* @plexus.requirement role-hint="archiva"
*/
private JdoAccess jdo;

View File

@ -30,6 +30,15 @@
*/
public interface DatabaseUpdater
{
/**
* Execute the {@link #updateAllUnprocessed()} and {@link #updateAllProcessed()}
* tasks in one go.
*
* @throws ArchivaDatabaseException
*/
public void update()
throws ArchivaDatabaseException;
/**
* Update all unprocessed content.
*
@ -45,4 +54,26 @@ public void updateAllUnprocessed()
*/
public void updateUnprocessed( ArchivaArtifact artifact )
throws ArchivaDatabaseException;
/**
* Update all previously processed content.
*
* This is done to allow archiva to remove content from the database that
* may have been removed from the filesystem too.
*
* @throws ArchivaDatabaseException if there was a fatal error with the database.
*/
public void updateAllProcessed()
throws ArchivaDatabaseException;
/**
* Update specific processed content.
*
* Example: This is done to allow a specific artifact to be removed from the
* database if it no longer exists on the filesystem.
*
* @throws ArchivaDatabaseException if there was a fatal error with the database.
*/
public void updateProcessed( ArchivaArtifact artifact )
throws ArchivaDatabaseException;
}

View File

@ -25,7 +25,7 @@
import org.apache.maven.archiva.consumers.ConsumerException;
import org.apache.maven.archiva.database.ArchivaDAO;
import org.apache.maven.archiva.database.ArchivaDatabaseException;
import org.apache.maven.archiva.database.constraints.UnprocessedArtifactsConstraint;
import org.apache.maven.archiva.database.constraints.ArtifactsProcessedConstraint;
import org.apache.maven.archiva.model.ArchivaArtifact;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
@ -35,6 +35,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@ -63,7 +64,7 @@ public class JdoDatabaseUpdater
/**
* The collection of available consumers.
* @plexus.requirement role=""
* @plexus.requirement role="org.apache.maven.archiva.consumers.ArchivaArtifactConsumer"
*/
private Map availableConsumers;
@ -82,10 +83,17 @@ public class JdoDatabaseUpdater
*/
private List propertyNameTriggers = new ArrayList();
public void update()
throws ArchivaDatabaseException
{
updateAllUnprocessed();
updateAllProcessed();
}
public void updateAllUnprocessed()
throws ArchivaDatabaseException
{
List unprocessedArtifacts = dao.getArtifactDAO().queryArtifacts( new UnprocessedArtifactsConstraint() );
List unprocessedArtifacts = dao.getArtifactDAO().queryArtifacts( new ArtifactsProcessedConstraint( false ) );
beginConsumerLifecycle( this.activeUnprocessedConsumers );
@ -109,6 +117,33 @@ public void updateAllUnprocessed()
}
}
public void updateAllProcessed()
throws ArchivaDatabaseException
{
List processedArtifacts = dao.getArtifactDAO().queryArtifacts( new ArtifactsProcessedConstraint( true ) );
beginConsumerLifecycle( this.activeProcessedConsumers );
try
{
// Process each consumer.
Iterator it = processedArtifacts.iterator();
while ( it.hasNext() )
{
ArchivaArtifact artifact = (ArchivaArtifact) it.next();
if ( !artifact.getModel().isProcessed() )
{
updateProcessed( artifact );
}
}
}
finally
{
consumerConsumerLifecycle( this.activeProcessedConsumers );
}
}
private void consumerConsumerLifecycle( List consumers )
{
Iterator it = consumers.iterator();
@ -142,7 +177,28 @@ public void updateUnprocessed( ArchivaArtifact artifact )
}
catch ( ConsumerException e )
{
getLogger().warn( "Unable to process artifact: " + artifact );
getLogger().warn( "Unable to consume (unprocessed) artifact: " + artifact );
}
}
artifact.getModel().setWhenProcessed( new Date() );
dao.getArtifactDAO().saveArtifact( artifact );
}
public void updateProcessed( ArchivaArtifact artifact )
throws ArchivaDatabaseException
{
Iterator it = this.activeProcessedConsumers.iterator();
while ( it.hasNext() )
{
ArchivaArtifactConsumer consumer = (ArchivaArtifactConsumer) it.next();
try
{
consumer.processArchivaArtifact( artifact );
}
catch ( ConsumerException e )
{
getLogger().warn( "Unable to consume (processed) artifact: " + artifact );
}
}
}

View File

@ -0,0 +1,144 @@
package org.apache.maven.archiva.database.constraints;
/*
* 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.AbstractArchivaDatabaseTestCase;
import org.apache.maven.archiva.database.ArtifactDAO;
import org.apache.maven.archiva.model.ArchivaArtifact;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
/**
* ArtifactsProcessedConstraintTest
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class ArtifactsProcessedConstraintTest
extends AbstractArchivaDatabaseTestCase
{
public ArchivaArtifact createArtifact( String groupId, String artifactId, String version, String whenProcessed )
throws Exception
{
ArchivaArtifact artifact = dao.getArtifactDAO().createArtifact( groupId, artifactId, version, "", "jar" );
assertNotNull( "Artifact should not be null.", artifact );
Date dateWhenProcessed = null;
if ( whenProcessed != null )
{
dateWhenProcessed = toDate( whenProcessed );
}
artifact.getModel().setWhenProcessed( dateWhenProcessed );
// Satisfy table / column requirements.
artifact.getModel().setLastModified( new Date() );
return artifact;
}
private Date toDate( String txt )
throws Exception
{
SimpleDateFormat sdf = new SimpleDateFormat( "yyyy/MM/dd HH:mm:ss" );
return sdf.parse( txt );
}
public void assertResults( String type, List results, String expectedArtifacts[] )
{
assertNotNull( "Results[" + type + "] should not be null.", results );
assertEquals( "Results[" + type + "].size", expectedArtifacts.length, results.size() );
for ( int i = 0; i < expectedArtifacts.length; i++ )
{
String artifactId = expectedArtifacts[i];
int found = 0;
Iterator it = results.iterator();
while ( it.hasNext() )
{
ArchivaArtifact artifact = (ArchivaArtifact) it.next();
if ( artifactId.equals( artifact.getArtifactId() ) )
{
found++;
}
}
if ( found <= 0 )
{
fail( "Results[" + type + "] - Did not find expected artifact ID [" + artifactId + "]" );
}
if ( found > 1 )
{
fail( "Results[" + type + "] - Expected to find 1 copy of artifact ID [" + artifactId
+ "], yet found <" + found + "> instead." );
}
}
}
protected void setUp()
throws Exception
{
super.setUp();
ArtifactDAO adao = dao.getArtifactDAO();
assertNotNull( "Artifact DAO should not be null.", adao );
adao.saveArtifact( createArtifact( "org.apache.maven.archiva", "archiva-common", "1.0-SNAPSHOT", null ) );
adao.saveArtifact( createArtifact( "org.apache.maven.archiva", "archiva-utils", "1.0-SNAPSHOT",
"2006/08/22 19:01:00" ) );
adao.saveArtifact( createArtifact( "org.apache.maven.archiva", "archiva-old", "0.1", "2004/02/15 9:01:00" ) );
adao.saveArtifact( createArtifact( "org.apache.maven.archiva", "archiva-database", "1.0-SNAPSHOT", null ) );
}
public void testNotProcessed()
throws Exception
{
List results = dao.getArtifactDAO().queryArtifacts( new ArtifactsProcessedConstraint( false ) );
assertResults( "not-processed", results, new String[] { "archiva-common", "archiva-database" } );
}
public void testProcessed()
throws Exception
{
List results = dao.getArtifactDAO().queryArtifacts( new ArtifactsProcessedConstraint( true ) );
assertResults( "processed", results, new String[] { "archiva-utils", "archiva-old" } );
}
public void testSinceRecent()
throws Exception
{
Date since = toDate( "2006/01/01 12:00:00" );
List results = dao.getArtifactDAO().queryArtifacts( new ArtifactsProcessedConstraint( since ) );
assertResults( "processed", results, new String[] { "archiva-utils" } );
}
public void testSinceOld()
throws Exception
{
Date since = toDate( "2001/01/01 12:00:00" );
List results = dao.getArtifactDAO().queryArtifacts( new ArtifactsProcessedConstraint( since ) );
assertResults( "processed", results, new String[] { "archiva-utils", "archiva-old" } );
}
}