* under the License.
*/
+import java.util.List;
+
/**
* ArchivaDAO - The interface for all content within the database.
*
{
public static final String ROLE = ArchivaDAO.class.getName();
+ /**
+ * Perform a simple query against the database.
+ *
+ * @param constraint the constraint to use.
+ * @return the List of results.
+ */
+ List query( SimpleConstraint constraint );
+
ArtifactDAO getArtifactDAO();
ProjectModelDAO getProjectModelDAO();
RepositoryDAO getRepositoryDAO();
-
+
RepositoryProblemDAO getRepositoryProblemDAO();
}
package org.apache.maven.archiva.database;
+/*
+ * 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.
+ */
+
+
/**
- * Constraint
+ * Constraint - a generic object for dealing with database constraints.
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
+ * @see DeclarativeConstraint
+ * @see SimpleConstraint
*/
public interface Constraint
{
* @return the fetch limits on the object. (can be null) (O/RM specific)
*/
public String getFetchLimits();
-
- /**
- * Get the SELECT WHERE (condition) value for the constraint.
- *
- * @return the equivalent of the SELECT WHERE (condition) value for this constraint. (can be null)
- */
- public String getWhereCondition();
-
- /**
- * Get the sort column name.
- *
- * @return the sort column name. (can be null)
- */
- public String getSortColumn();
-
- /**
- * Get the sort direction name.
- *
- * @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();
}
--- /dev/null
+package org.apache.maven.archiva.database;
+
+/*
+ * 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.
+ */
+
+/**
+ * DeclarativeConstraint
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public interface DeclarativeConstraint extends Constraint
+{
+ /**
+ * Get the declared imports used for this query. (optional)
+ *
+ * NOTE: This is DAO implementation specific.
+ *
+ * @return the imports. (can be null)
+ */
+ public abstract String[] getDeclaredImports();
+
+ /**
+ * Get the declared parameters used for this query. (optional)
+ *
+ * NOTE: This is DAO implementation specific.
+ *
+ * @return the parameters. (can be null)
+ */
+ public abstract 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 abstract Object[] getParameters();
+
+ /**
+ * Get the sort direction name.
+ *
+ * @return the sort direction name. ("ASC" or "DESC") (only valid if {@link #getSortColumn()} is specified.)
+ */
+ public abstract String getSortDirection();
+
+ /**
+ * Get the sort column name.
+ *
+ * @return the sort column name. (can be null)
+ */
+ public abstract String getSortColumn();
+
+ /**
+ * Get the SELECT WHERE (condition) value for the constraint.
+ *
+ * @return the equivalent of the SELECT WHERE (condition) value for this constraint. (can be null)
+ */
+ public abstract String getWhereCondition();
+}
\ No newline at end of file
--- /dev/null
+package org.apache.maven.archiva.database;
+
+/*
+ * 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.
+ */
+
+/**
+ * SimpleConstraint
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public interface SimpleConstraint extends Constraint
+{
+ /**
+ * Get the parameters used for this query. (required if using parameterized SQL)
+ *
+ * NOTE: This is DAO implementation specific.
+ *
+ * @return the parameters. (can be null)
+ */
+ public Object[] getParameters();
+
+ /**
+ * Get the SELECT query value for the constraint.
+ *
+ * @return the SELECT value for this constraint. (can be null)
+ */
+ public abstract String getSelectSql();
+
+ /**
+ * For simple Constraints the results class must be specified.
+ *
+ * @return the result class.
+ */
+ public Class getResultClass();
+
+ /**
+ * When working with result classes that are not persistable,
+ * it is advisable to tell the underlying DAO to not do the persistable related efforts.
+ *
+ * @return true if result classes are persistable.
+ */
+ public boolean isResultsPersistable();
+}
\ No newline at end of file
--- /dev/null
+package org.apache.maven.archiva.database.browsing;
+
+/*
+ * 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 java.util.List;
+
+/**
+ * BrowsingResults
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class BrowsingResults
+{
+ private String selectedGroupId;
+
+ private String selectedArtifactId;
+
+ private List groupIds = null;
+
+ private List artifacts = null;
+
+ private List versions = null;
+
+ public BrowsingResults()
+ {
+ /* do nothing, this is the results of the root */
+ }
+
+ public BrowsingResults( String groupId )
+ {
+ this.selectedGroupId = groupId;
+ }
+
+ public BrowsingResults( String groupId, String artifactId )
+ {
+ this.selectedGroupId = groupId;
+ this.selectedArtifactId = artifactId;
+ }
+
+ public List getArtifacts()
+ {
+ return artifacts;
+ }
+
+ public List getGroupIds()
+ {
+ return groupIds;
+ }
+
+ public String getSelectedArtifactId()
+ {
+ return selectedArtifactId;
+ }
+
+ public String getSelectedGroupId()
+ {
+ return selectedGroupId;
+ }
+
+ public List getVersions()
+ {
+ return versions;
+ }
+
+ public boolean hasArtifacts()
+ {
+ return CollectionUtils.isNotEmpty( artifacts );
+ }
+
+ public boolean hasGroupIds()
+ {
+ return CollectionUtils.isNotEmpty( groupIds );
+ }
+
+ public boolean hasVersions()
+ {
+ return CollectionUtils.isNotEmpty( versions );
+ }
+
+ public void setArtifacts( List artifacts )
+ {
+ this.artifacts = artifacts;
+ }
+
+ public void setGroupIds( List groupIds )
+ {
+ this.groupIds = groupIds;
+ }
+
+ public void setVersions( List versions )
+ {
+ this.versions = versions;
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.database.browsing;
+
+/*
+ * 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.database.constraints.UniqueArtifactIdConstraint;
+import org.apache.maven.archiva.database.constraints.UniqueGroupIdConstraint;
+import org.apache.maven.archiva.database.constraints.UniqueVersionConstraint;
+import org.apache.maven.archiva.model.ArchivaProjectModel;
+import org.codehaus.plexus.logging.AbstractLogEnabled;
+
+import java.util.List;
+
+/**
+ * DefaultRepositoryBrowsing
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ *
+ * @plexus.component role="org.apache.maven.archiva.database.browsing.RepositoryBrowsing"
+ * role-hint="default"
+ */
+public class DefaultRepositoryBrowsing
+ extends AbstractLogEnabled
+ implements RepositoryBrowsing
+{
+ /**
+ * @plexus.requirement
+ */
+ private ArchivaDAO dao;
+
+ public BrowsingResults getRoot()
+ {
+ List groups = dao.query( new UniqueGroupIdConstraint() );
+
+ BrowsingResults results = new BrowsingResults();
+
+ results.setGroupIds( GroupIdFilter.filterGroups( groups ) );
+
+ return results;
+ }
+
+ public BrowsingResults selectArtifactId( String groupId, String artifactId )
+ {
+ // List groups = dao.query( new UniqueGroupIdConstraint( groupId ) );
+ // List artifacts = dao.query( new UniqueArtifactIdConstraint( groupId ) );
+ List versions = dao.query( new UniqueVersionConstraint( groupId, artifactId ) );
+
+ BrowsingResults results = new BrowsingResults( groupId, artifactId );
+
+ // results.setGroupIds( groups );
+ // results.setArtifacts( artifacts );
+ results.setArtifacts( versions );
+
+ return results;
+ }
+
+ public BrowsingResults selectGroupId( String groupId )
+ {
+ List groups = dao.query( new UniqueGroupIdConstraint( groupId ) );
+ List artifacts = dao.query( new UniqueArtifactIdConstraint( groupId ) );
+
+ BrowsingResults results = new BrowsingResults( groupId );
+ results.setGroupIds( groups );
+ results.setArtifacts( artifacts );
+
+ return results;
+ }
+
+ public ArchivaProjectModel selectVersion( String groupId, String artifactId, String version )
+ throws ObjectNotFoundException, ArchivaDatabaseException
+ {
+ ArchivaProjectModel model = dao.getProjectModelDAO().getProjectModel( groupId, artifactId, version );
+
+ // TODO: if the model isn't found. load it from disk, insert into DB, and then return it.
+
+ return model;
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.database.browsing;
+
+/*
+ * 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.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.TreeMap;
+
+/**
+ * GroupIdFilter - utility methods for filtering groupIds.
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class GroupIdFilter
+{
+ private static final String GROUP_SEPARATOR = ".";
+
+ /**
+ * <p>
+ * Filter out excessive groupId naming. (to provide a tree-ish view of the list of groupIds).
+ * </p>
+ *
+ * <pre>
+ * // Input List
+ * commons-lang
+ * com.jsch
+ * org.apache.apache
+ * org.apache.maven
+ * org.codehaus.modello
+ * // Filtered List
+ * commons-lang
+ * com.jsch
+ * org
+ * </pre>
+ *
+ * <pre>
+ * // Input List
+ * commons-lang
+ * commons-io
+ * commons-pool
+ * com.jsch
+ * com.jsch.lib
+ * com.jsch.providers
+ * org.apache.apache
+ * org.apache.maven
+ * org.apache.maven.archiva
+ * org.apache.maven.shared
+ * // Filtered List
+ * commons-lang
+ * commons-io
+ * commons-pool
+ * com.jsch
+ * org.apache
+ * </pre>
+ *
+ * @param groups the list of groupIds.
+ * @return
+ */
+ public static List filterGroups( List groups )
+ {
+ GroupTreeNode tree = buildGroupTree( groups );
+ return collateGroups( tree );
+ }
+
+ public static GroupTreeNode buildGroupTree( List groups )
+ {
+ GroupTreeNode rootNode = new GroupTreeNode();
+
+ // build a tree structure
+ for ( Iterator i = groups.iterator(); i.hasNext(); )
+ {
+ String groupId = (String) i.next();
+
+ StringTokenizer tok = new StringTokenizer( groupId, GROUP_SEPARATOR );
+
+ GroupTreeNode node = rootNode;
+
+ while ( tok.hasMoreTokens() )
+ {
+ String part = tok.nextToken();
+
+ if ( !node.getChildren().containsKey( part ) )
+ {
+ GroupTreeNode newNode = new GroupTreeNode( part, node );
+ node.addChild( newNode );
+ node = newNode;
+ }
+ else
+ {
+ node = (GroupTreeNode) node.getChildren().get( part );
+ }
+ }
+ }
+
+ return rootNode;
+ }
+
+ private static List collateGroups( GroupTreeNode rootNode )
+ {
+ List groups = new ArrayList();
+ for ( Iterator i = rootNode.getChildren().values().iterator(); i.hasNext(); )
+ {
+ GroupTreeNode node = (GroupTreeNode) i.next();
+
+ while ( node.getChildren().size() == 1 )
+ {
+ node = (GroupTreeNode) node.getChildren().values().iterator().next();
+ }
+
+ groups.add( node.getFullName() );
+ }
+ return groups;
+ }
+
+ private static class GroupTreeNode
+ {
+ private final String name;
+
+ private final String fullName;
+
+ private final Map children = new TreeMap();
+
+ GroupTreeNode()
+ {
+ name = null;
+ fullName = null;
+ }
+
+ GroupTreeNode( String name, GroupTreeNode parent )
+ {
+ this.name = name;
+ this.fullName = parent.fullName != null ? parent.fullName + GROUP_SEPARATOR + name : name;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public String getFullName()
+ {
+ return fullName;
+ }
+
+ public Map getChildren()
+ {
+ return children;
+ }
+
+ public void addChild( GroupTreeNode newNode )
+ {
+ children.put( newNode.name, newNode );
+ }
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.database.browsing;
+
+/*
+ * 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.ArchivaDatabaseException;
+import org.apache.maven.archiva.database.ObjectNotFoundException;
+import org.apache.maven.archiva.model.ArchivaProjectModel;
+
+/**
+ * RepositoryBrowsing
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public interface RepositoryBrowsing
+{
+ public BrowsingResults getRoot();
+
+ public BrowsingResults selectGroupId( String groupId );
+
+ public BrowsingResults selectArtifactId( String groupId, String artifactId );
+
+ public ArchivaProjectModel selectVersion( String groupId, String artifactId, String version )
+ throws ObjectNotFoundException, ArchivaDatabaseException;
+}
+++ /dev/null
-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;
-
-/**
- * AbstractConstraint
- *
- * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
- * @version $Id$
- */
-public abstract class AbstractConstraint
- implements Constraint
-{
- protected String[] declImports;
- protected String[] declParams;
- protected Object[] params;
-
- public String getFetchLimits()
- {
- return null;
- }
-
- public String[] getDeclaredImports()
- {
- return declImports;
- }
-
- public String[] getDeclaredParameters()
- {
- return declParams;
- }
-
- public Object[] getParameters()
- {
- return params;
- }
-
- public String getSortDirection()
- {
- return Constraint.ASCENDING;
- }
-
- public abstract String getSortColumn();
-
- public abstract String getWhereCondition();
-}
--- /dev/null
+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 org.apache.maven.archiva.database.DeclarativeConstraint;
+
+/**
+ * AbstractDeclarativeConstraint
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public abstract class AbstractDeclarativeConstraint
+ implements DeclarativeConstraint
+{
+ protected String[] declImports;
+
+ protected String[] declParams;
+
+ protected Object[] params;
+
+ public String getFetchLimits()
+ {
+ return null;
+ }
+
+ public String[] getDeclaredImports()
+ {
+ return declImports;
+ }
+
+ public String[] getDeclaredParameters()
+ {
+ return declParams;
+ }
+
+ public Object[] getParameters()
+ {
+ return params;
+ }
+
+ public String getSortDirection()
+ {
+ return Constraint.ASCENDING;
+ }
+}
--- /dev/null
+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.SimpleConstraint;
+
+/**
+ * Simple Constraint abstract for working with nearly-raw SQL strings.
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public abstract class AbstractSimpleConstraint
+ implements SimpleConstraint
+{
+ protected Object[] params;
+
+ public Object[] getParameters()
+ {
+ return params;
+ }
+
+ public String getFetchLimits()
+ {
+ return null;
+ }
+
+ public boolean isResultsPersistable()
+ {
+ return false;
+ }
+}
* @version $Id$
*/
public class ArchivaRepositoryByUrlConstraint
- extends AbstractConstraint
+ extends AbstractDeclarativeConstraint
implements Constraint
{
private String whereCondition;
* @version $Id$
*/
public class ArtifactsBySha1ChecksumConstraint
- extends AbstractConstraint
+ extends AbstractDeclarativeConstraint
implements Constraint
{
private String whereClause;
* @version $Id$
*/
public class ArtifactsProcessedConstraint
- extends AbstractConstraint
+ extends AbstractDeclarativeConstraint
implements Constraint
{
private String whereClause;
* @version $Id$
*/
public class ArtifactsRelatedConstraint
- extends AbstractConstraint
+ extends AbstractDeclarativeConstraint
implements Constraint
{
private String whereClause;
* @version $Id$
*/
public class OlderArtifactsByAgeConstraint
- extends AbstractConstraint
+ extends AbstractDeclarativeConstraint
implements Constraint
{
private String whereClause;
* @version $Id$
*/
public class OlderSnapshotArtifactsByAgeConstraint
- extends AbstractConstraint
+ extends AbstractDeclarativeConstraint
implements Constraint
{
private String whereClause;
* @version $Id$
*/
public class RecentArtifactsByAgeConstraint
- extends AbstractConstraint
+ extends AbstractDeclarativeConstraint
implements Constraint
{
private String whereClause;
* @version $Id$
*/
public class RepositoryProblemByTypeConstraint
- extends AbstractConstraint
+ extends AbstractDeclarativeConstraint
implements Constraint
{
private String whereClause;
--- /dev/null
+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 org.apache.maven.archiva.model.ArchivaArtifactModel;
+
+/**
+ * Obtain a set of unique ArtifactIds for the specified groupId.
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class UniqueArtifactIdConstraint
+ extends AbstractSimpleConstraint
+ implements Constraint
+{
+ private String sql;
+
+ /**
+ * Obtain a set of unique ArtifactIds for the specified groupId.
+ *
+ * @param groupId the groupId to search for artifactIds within.
+ */
+ public UniqueArtifactIdConstraint( String groupId )
+ {
+ sql = "SELECT artifactId FROM " + ArchivaArtifactModel.class.getName()
+ + " WHERE groupId == selectedGroupId PARAMETERS String selectedGroupId"
+ + " GROUP BY artifactId ORDER BY artifactId ASCENDING";
+
+ super.params = new Object[] { groupId };
+ }
+
+ public Class getResultClass()
+ {
+ return String.class;
+ }
+
+ public String getSelectSql()
+ {
+ return sql;
+ }
+}
--- /dev/null
+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 org.apache.maven.archiva.model.ArchivaArtifactModel;
+
+/**
+ * UniqueGroupIdConstraint
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class UniqueGroupIdConstraint
+ extends AbstractSimpleConstraint
+ implements Constraint
+{
+ private String sql;
+
+ public UniqueGroupIdConstraint()
+ {
+ /* this assumes search for no groupId prefix */
+ sql = "SELECT groupId FROM " + ArchivaArtifactModel.class.getName()
+ + " GROUP BY groupId ORDER BY groupId ASCENDING";
+ }
+
+ public UniqueGroupIdConstraint( String groupIdPrefix )
+ {
+ sql = "SELECT groupId FROM " + ArchivaArtifactModel.class.getName()
+ + " WHERE groupId.startsWith(groupIdPrefix) PARAMETERS String groupIdPrefix"
+ + " GROUP BY groupId ORDER BY groupId ASCENDING";
+
+ super.params = new Object[] { groupIdPrefix };
+ }
+
+ public Class getResultClass()
+ {
+ return String.class;
+ }
+
+ public String getSelectSql()
+ {
+ return sql;
+ }
+}
--- /dev/null
+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.commons.lang.StringUtils;
+import org.apache.maven.archiva.database.Constraint;
+import org.apache.maven.archiva.model.ArchivaArtifactModel;
+
+/**
+ * Obtain the list of version's for specific GroupId and ArtifactId.
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class UniqueVersionConstraint
+ extends AbstractSimpleConstraint
+ implements Constraint
+{
+ private String sql;
+
+ /**
+ * Obtain the list of version's for specific GroupId and ArtifactId.
+ *
+ * @param groupId the selected groupId.
+ * @param artifactId the selected artifactId.
+ */
+ public UniqueVersionConstraint( String groupId, String artifactId )
+ {
+ if ( StringUtils.isBlank( groupId ) )
+ {
+ throw new IllegalArgumentException( "A blank groupId is not allowed." );
+ }
+
+ if ( StringUtils.isBlank( artifactId ) )
+ {
+ throw new IllegalArgumentException( "A blank artifactId is not allowed." );
+ }
+
+ sql = "SELECT version FROM " + ArchivaArtifactModel.class.getName()
+ + " WHERE groupId == selectedGroupId && artifactId == selectedArtifactId"
+ + " PARAMETERS String selectedGroupId, String selectedArtifactId"
+ + " GROUP BY version ORDER BY version ASCENDING";
+
+ super.params = new Object[] { groupId, artifactId };
+ }
+
+ public Class getResultClass()
+ {
+ return String.class;
+ }
+
+ public String getSelectSql()
+ {
+ return sql;
+ }
+}
import org.apache.commons.lang.StringUtils;
import org.apache.maven.archiva.database.ArchivaDatabaseException;
import org.apache.maven.archiva.database.Constraint;
+import org.apache.maven.archiva.database.DeclarativeConstraint;
import org.apache.maven.archiva.database.ObjectNotFoundException;
+import org.apache.maven.archiva.database.SimpleConstraint;
+import org.apache.maven.archiva.database.constraints.AbstractSimpleConstraint;
import org.apache.maven.archiva.model.CompoundKey;
import org.codehaus.plexus.jdo.JdoFactory;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
import java.io.PrintStream;
+import java.util.ArrayList;
import java.util.List;
import javax.jdo.Extent;
public List getAllObjects( Class clazz )
{
- return getAllObjects( clazz, null );
+ return queryObjects( clazz, null );
}
- public List getAllObjects( Class clazz, Constraint constraint )
+ public List queryObjects( Class clazz, Constraint constraint )
{
PersistenceManager pm = getPersistenceManager();
Transaction tx = pm.currentTransaction();
{
tx.begin();
- Extent extent = pm.getExtent( clazz, true );
-
- Query query = pm.newQuery( extent );
-
List result = null;
if ( constraint != null )
{
- if ( constraint.getSortColumn() != null )
- {
- String ordering = constraint.getSortColumn();
-
- if ( constraint.getSortDirection() != null )
- {
- ordering += " " + constraint.getSortDirection();
- }
-
- query.setOrdering( ordering );
- }
-
- if ( constraint.getFetchLimits() != null )
- {
- pm.getFetchPlan().addGroup( constraint.getFetchLimits() );
- }
-
- if ( constraint.getWhereCondition() != null )
- {
- query.setFilter( constraint.getWhereCondition() );
- }
-
- if ( constraint.getDeclaredImports() != null )
+ if ( constraint instanceof DeclarativeConstraint )
{
- for ( int i = 0; i < constraint.getDeclaredImports().length; i++ )
- {
- String qimport = constraint.getDeclaredImports()[i];
- query.declareImports( qimport );
- }
+ result = processConstraint( pm, clazz, (DeclarativeConstraint) constraint );
}
-
- if ( constraint.getDeclaredParameters() != null )
+ else if ( constraint instanceof AbstractSimpleConstraint )
{
- 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." );
- }
+ result = processConstraint( pm, (SimpleConstraint) constraint );
}
else
{
- // Process unparameterized query.
- result = (List) query.execute();
+ result = processUnconstrained( pm, clazz );
}
}
else
{
- result = (List) query.execute();
+ result = processUnconstrained( pm, clazz );
}
result = (List) pm.detachCopyAll( result );
}
}
+ public List queryObjects( SimpleConstraint constraint )
+ {
+ PersistenceManager pm = getPersistenceManager();
+ Transaction tx = pm.currentTransaction();
+
+ try
+ {
+ tx.begin();
+
+ List result = processConstraint( pm, constraint );
+
+ // Only detach if results are known to be persistable.
+ if ( constraint.isResultsPersistable() )
+ {
+ result = (List) pm.detachCopyAll( result );
+ }
+ else
+ {
+ List copiedResults = new ArrayList();
+ copiedResults.addAll( result );
+ result = copiedResults;
+ }
+
+ tx.commit();
+
+ return result;
+ }
+ finally
+ {
+ rollbackIfActive( tx );
+ }
+ }
+
+ private List processUnconstrained( PersistenceManager pm, Class clazz )
+ {
+ Extent extent = pm.getExtent( clazz, true );
+ Query query = pm.newQuery( extent );
+ return (List) query.execute();
+ }
+
+ private List processConstraint( PersistenceManager pm, SimpleConstraint constraint )
+ {
+ Query query = pm.newQuery( constraint.getSelectSql() );
+
+ if ( constraint.getResultClass() == null )
+ {
+ throw new IllegalStateException( "Unable to use a SimpleConstraint with a null result class." );
+ }
+
+ query.setResultClass( constraint.getResultClass() );
+
+ if ( constraint.getFetchLimits() != null )
+ {
+ pm.getFetchPlan().addGroup( constraint.getFetchLimits() );
+ }
+
+ if ( constraint.getParameters() != null )
+ {
+ return processParameterizedQuery( query, constraint.getParameters() );
+ }
+
+ return (List) query.execute();
+ }
+
+ private List processConstraint( PersistenceManager pm, Class clazz, DeclarativeConstraint constraint )
+ {
+ Extent extent = pm.getExtent( clazz, true );
+ Query query = pm.newQuery( extent );
+
+ if ( constraint.getSortColumn() != null )
+ {
+ String ordering = constraint.getSortColumn();
+
+ if ( constraint.getSortDirection() != null )
+ {
+ ordering += " " + constraint.getSortDirection();
+ }
+
+ query.setOrdering( ordering );
+ }
+
+ if ( constraint.getFetchLimits() != null )
+ {
+ pm.getFetchPlan().addGroup( constraint.getFetchLimits() );
+ }
+
+ if ( constraint.getWhereCondition() != null )
+ {
+ 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 );
+ }
+ }
+
+ 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 );
+ }
+
+ return processParameterizedQuery( query, constraint.getParameters() );
+ }
+ else
+ {
+ return (List) query.execute();
+ }
+ }
+
+ private List processParameterizedQuery( Query query, Object parameters[] )
+ {
+ switch ( parameters.length )
+ {
+ case 1:
+ return (List) query.execute( parameters[0] );
+ case 2:
+ return (List) query.execute( parameters[0], parameters[1] );
+ case 3:
+ return (List) query.execute( parameters[0], parameters[1], parameters[2] );
+ default:
+ throw new JDOException( "Unable to use more than 3 parameters." );
+ }
+ }
+
public Object getObjectById( Class clazz, Object id, String fetchGroup )
throws ObjectNotFoundException, ArchivaDatabaseException
{
import org.apache.maven.archiva.database.ProjectModelDAO;
import org.apache.maven.archiva.database.RepositoryDAO;
import org.apache.maven.archiva.database.RepositoryProblemDAO;
+import org.apache.maven.archiva.database.SimpleConstraint;
import org.codehaus.plexus.logging.AbstractLogEnabled;
+import java.util.List;
+
/**
* JdoArchivaDAO
*
extends AbstractLogEnabled
implements ArchivaDAO
{
+ /**
+ * @plexus.requirement role-hint="archiva"
+ */
+ private JdoAccess jdo;
+
/**
* @plexus.requirement role-hint="jdo"
*/
* @plexus.requirement role-hint="jdo"
*/
private RepositoryProblemDAO repositoryProblemDAO;
+
+ public List query( SimpleConstraint constraint )
+ {
+ return jdo.queryObjects( constraint );
+ }
public ArtifactDAO getArtifactDAO()
{
public List queryArtifacts( Constraint constraint )
throws ObjectNotFoundException, ArchivaDatabaseException
{
- List results = jdo.getAllObjects( ArchivaArtifactModel.class, constraint );
+ List results = jdo.queryObjects( ArchivaArtifactModel.class, constraint );
if ( ( results == null ) || results.isEmpty() )
{
return results;
public List queryProjectModels( Constraint constraint )
throws ObjectNotFoundException, ArchivaDatabaseException
{
- return jdo.getAllObjects( ArchivaProjectModel.class, constraint );
+ return jdo.queryObjects( ArchivaProjectModel.class, constraint );
}
public ArchivaProjectModel saveProjectModel( ArchivaProjectModel model )
public List queryRepositories( Constraint constraint )
throws ObjectNotFoundException, ArchivaDatabaseException
{
- List results = jdo.getAllObjects( ArchivaRepositoryModel.class, constraint );
+ List results = jdo.queryObjects( ArchivaRepositoryModel.class, constraint );
if ( ( results == null ) || results.isEmpty() )
{
public List queryRepositoryProblems( Constraint constraint )
throws ObjectNotFoundException, ArchivaDatabaseException
{
- return jdo.getAllObjects( RepositoryProblem.class, constraint );
+ return jdo.queryObjects( RepositoryProblem.class, constraint );
}
public RepositoryProblem saveRepositoryProblem( RepositoryProblem problem )
--- /dev/null
+package org.apache.maven.archiva.database.browsing;
+
+/*
+ * 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.ArchivaDAO;
+import org.apache.maven.archiva.database.ArtifactDAO;
+import org.apache.maven.archiva.model.ArchivaArtifact;
+
+import java.util.Date;
+
+/**
+ * RepositoryBrowsingTest
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class RepositoryBrowsingTest
+ extends AbstractArchivaDatabaseTestCase
+{
+ private ArtifactDAO artifactDao;
+
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+
+ ArchivaDAO dao = (ArchivaDAO) lookup( ArchivaDAO.ROLE, "jdo" );
+ artifactDao = dao.getArtifactDAO();
+ }
+
+ public ArchivaArtifact createArtifact( String groupId, String artifactId, String version )
+ {
+ ArchivaArtifact artifact = artifactDao.createArtifact( groupId, artifactId, version, "", "jar" );
+ artifact.getModel().setLastModified( new Date() ); // mandatory field.
+ artifact.getModel().setRepositoryId( "testable_repo" );
+ return artifact;
+ }
+
+ public void saveTestData()
+ throws Exception
+ {
+ ArchivaArtifact artifact;
+
+ // Setup artifacts in fresh DB.
+ artifact = createArtifact( "commons-lang", "commons-lang", "2.0" );
+ artifactDao.saveArtifact( artifact );
+
+ artifact = createArtifact( "commons-lang", "commons-lang", "2.1" );
+ artifactDao.saveArtifact( artifact );
+
+ artifact = createArtifact( "org.apache.maven.test", "test-one", "1.2" );
+ artifactDao.saveArtifact( artifact );
+
+ artifact = createArtifact( "org.apache.maven.test.foo", "test-two", "1.0" );
+ artifactDao.saveArtifact( artifact );
+
+ artifact = createArtifact( "org.apache.maven.shared", "test-two", "2.0" );
+ artifactDao.saveArtifact( artifact );
+
+ artifact = createArtifact( "org.apache.maven.shared", "test-two", "2.1-SNAPSHOT" );
+ artifactDao.saveArtifact( artifact );
+
+ artifact = createArtifact( "org.apache.maven.shared", "test-two", "2.1.1" );
+ artifactDao.saveArtifact( artifact );
+
+ artifact = createArtifact( "org.apache.maven.shared", "test-two", "2.1-alpha-1" );
+ artifactDao.saveArtifact( artifact );
+
+ artifact = createArtifact( "org.apache.maven.shared", "test-bar", "2.1" );
+ artifactDao.saveArtifact( artifact );
+
+ artifact = createArtifact( "org.codehaus.modello", "modellong", "3.0" );
+ artifactDao.saveArtifact( artifact );
+ }
+
+ public RepositoryBrowsing lookupBrowser()
+ throws Exception
+ {
+ RepositoryBrowsing browser = (RepositoryBrowsing) lookup( RepositoryBrowsing.class.getName(), "default" );
+ assertNotNull( "RepositoryBrowsing should not be null.", browser );
+ return browser;
+ }
+
+ public void testSimpleBrowse()
+ throws Exception
+ {
+ saveTestData();
+
+ RepositoryBrowsing browser = lookupBrowser();
+ BrowsingResults results = browser.getRoot();
+ assertNotNull( "Browsing Results should not be null.", results );
+
+ String expectedRootGroupIds[] = new String[] { "commons-lang", "org" };
+
+ assertEquals( "Browsing Results: groupIds on root.", expectedRootGroupIds.length, results.getGroupIds().size() );
+ }
+}
--- /dev/null
+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 junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * IDE Provided Utility Class for all tests.
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class AllTests
+{
+
+ public static Test suite()
+ {
+ TestSuite suite = new TestSuite( "Test for org.apache.maven.archiva.database.constraints" );
+ //$JUnit-BEGIN$
+ suite.addTestSuite( ArtifactsProcessedConstraintTest.class );
+ suite.addTestSuite( ArtifactsBySha1ChecksumConstraintTest.class );
+ suite.addTestSuite( OlderArtifactsByAgeConstraintTest.class );
+ suite.addTestSuite( UniqueGroupIdConstraintTest.class );
+ suite.addTestSuite( OlderSnapshotArtifactsByAgeConstraintTest.class );
+ suite.addTestSuite( RecentArtifactsByAgeConstraintTest.class );
+ //$JUnit-END$
+ return suite;
+ }
+
+}
--- /dev/null
+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.commons.lang.StringUtils;
+import org.apache.maven.archiva.database.AbstractArchivaDatabaseTestCase;
+import org.apache.maven.archiva.database.ArchivaDAO;
+import org.apache.maven.archiva.database.ArtifactDAO;
+import org.apache.maven.archiva.database.SimpleConstraint;
+import org.apache.maven.archiva.model.ArchivaArtifact;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * UniqueArtifactIdConstraintTest
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class UniqueArtifactIdConstraintTest
+ extends AbstractArchivaDatabaseTestCase
+{
+ private ArtifactDAO artifactDao;
+
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+
+ ArchivaDAO dao = (ArchivaDAO) lookup( ArchivaDAO.ROLE, "jdo" );
+ artifactDao = dao.getArtifactDAO();
+ }
+
+ public ArchivaArtifact createArtifact( String groupId, String artifactId, String version )
+ {
+ ArchivaArtifact artifact = artifactDao.createArtifact( groupId, artifactId, version, "", "jar" );
+ artifact.getModel().setLastModified( new Date() ); // mandatory field.
+ artifact.getModel().setRepositoryId( "testable_repo" );
+ return artifact;
+ }
+
+ public void testConstraint()
+ throws Exception
+ {
+ ArchivaArtifact artifact;
+
+ // Setup artifacts in fresh DB.
+ artifact = createArtifact( "commons-lang", "commons-lang", "2.0" );
+ artifactDao.saveArtifact( artifact );
+
+ artifact = createArtifact( "commons-lang", "commons-lang", "2.1" );
+ artifactDao.saveArtifact( artifact );
+
+ artifact = createArtifact( "org.apache.maven.test", "test-one", "1.2" );
+ artifactDao.saveArtifact( artifact );
+
+ artifact = createArtifact( "org.apache.maven.test.foo", "test-two", "1.0" );
+ artifactDao.saveArtifact( artifact );
+
+ artifact = createArtifact( "org.apache.maven.shared", "test-two", "2.0" );
+ artifactDao.saveArtifact( artifact );
+
+ artifact = createArtifact( "org.apache.maven.shared", "test-two", "2.1" );
+ artifactDao.saveArtifact( artifact );
+
+ artifact = createArtifact( "org.apache.maven.shared", "test-bar", "2.1" );
+ artifactDao.saveArtifact( artifact );
+
+ artifact = createArtifact( "org.codehaus.modello", "modellong", "3.0" );
+ artifactDao.saveArtifact( artifact );
+
+ assertConstraint( new String[] {}, new UniqueArtifactIdConstraint( "org.apache" ) );
+ assertConstraint( new String[] { "commons-lang" }, new UniqueArtifactIdConstraint( "commons-lang" ) );
+ assertConstraint( new String[] { "test-one" }, new UniqueArtifactIdConstraint( "org.apache.maven.test" ) );
+ assertConstraint( new String[] { "test-two", "test-bar" },
+ new UniqueArtifactIdConstraint( "org.apache.maven.shared" ) );
+ assertConstraint( new String[] { "modellong" }, new UniqueArtifactIdConstraint( "org.codehaus.modello" ) );
+ }
+
+ private void assertConstraint( String[] artifactIds, SimpleConstraint constraint )
+ {
+ String prefix = "Unique Artifact IDs: ";
+
+ List results = dao.query( constraint );
+ assertNotNull( prefix + "Not Null", results );
+ assertEquals( prefix + "Results.size", artifactIds.length, results.size() );
+
+ List expectedArtifactIds = Arrays.asList( artifactIds );
+
+ Iterator it = results.iterator();
+ while ( it.hasNext() )
+ {
+ String actualArtifactId = (String) it.next();
+ assertTrue( prefix + "artifactId result should not be blank.", StringUtils.isNotBlank( actualArtifactId ) );
+ assertTrue( prefix + " artifactId result <" + actualArtifactId + "> exists in expected artifactIds.",
+ expectedArtifactIds.contains( actualArtifactId ) );
+ }
+ }
+}
--- /dev/null
+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.commons.lang.StringUtils;
+import org.apache.maven.archiva.database.AbstractArchivaDatabaseTestCase;
+import org.apache.maven.archiva.database.ArchivaDAO;
+import org.apache.maven.archiva.database.ArtifactDAO;
+import org.apache.maven.archiva.database.SimpleConstraint;
+import org.apache.maven.archiva.model.ArchivaArtifact;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * UniqueGroupIdConstraintTest
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class UniqueGroupIdConstraintTest
+ extends AbstractArchivaDatabaseTestCase
+{
+ private ArtifactDAO artifactDao;
+
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+
+ ArchivaDAO dao = (ArchivaDAO) lookup( ArchivaDAO.ROLE, "jdo" );
+ artifactDao = dao.getArtifactDAO();
+ }
+
+ public ArchivaArtifact createArtifact( String groupId, String artifactId, String version )
+ {
+ ArchivaArtifact artifact = artifactDao.createArtifact( groupId, artifactId, version, "", "jar" );
+ artifact.getModel().setLastModified( new Date() ); // mandatory field.
+ artifact.getModel().setRepositoryId( "testable_repo" );
+ return artifact;
+ }
+
+ public void testConstraint()
+ throws Exception
+ {
+ ArchivaArtifact artifact;
+
+ // Setup artifacts in fresh DB.
+ artifact = createArtifact( "commons-lang", "commons-lang", "2.0" );
+ artifactDao.saveArtifact( artifact );
+
+ artifact = createArtifact( "commons-lang", "commons-lang", "2.1" );
+ artifactDao.saveArtifact( artifact );
+
+ artifact = createArtifact( "org.apache.maven.test", "test-one", "1.2" );
+ artifactDao.saveArtifact( artifact );
+
+ artifact = createArtifact( "org.apache.maven.test.foo", "test-two", "1.0" );
+ artifactDao.saveArtifact( artifact );
+
+ artifact = createArtifact( "org.apache.maven.shared", "test-two", "2.0" );
+ artifactDao.saveArtifact( artifact );
+
+ artifact = createArtifact( "org.apache.maven.shared", "test-two", "2.1" );
+ artifactDao.saveArtifact( artifact );
+
+ artifact = createArtifact( "org.codehaus.modello", "test-two", "3.0" );
+ artifactDao.saveArtifact( artifact );
+
+ assertConstraint( new String[] {
+ "commons-lang",
+ "org.apache.maven.test",
+ "org.apache.maven.test.foo",
+ "org.apache.maven.shared",
+ "org.codehaus.modello" }, new UniqueGroupIdConstraint() );
+ assertConstraint( new String[] { "commons-lang" }, new UniqueGroupIdConstraint( "commons-lang" ) );
+ assertConstraint( new String[] {
+ "org.apache.maven.test",
+ "org.apache.maven.test.foo",
+ "org.apache.maven.shared" }, new UniqueGroupIdConstraint( "org.apache.maven" ) );
+ assertConstraint( new String[] {
+ "org.apache.maven.test",
+ "org.apache.maven.test.foo",
+ "org.apache.maven.shared" }, new UniqueGroupIdConstraint( "org.apache" ) );
+ assertConstraint( new String[] {
+ "org.apache.maven.test",
+ "org.apache.maven.test.foo",
+ "org.apache.maven.shared",
+ "org.codehaus.modello" }, new UniqueGroupIdConstraint( "org" ) );
+ }
+
+ private void assertConstraint( String[] expectedGroupIds, SimpleConstraint constraint )
+ throws Exception
+ {
+ String prefix = "Unique Group IDs: ";
+
+ List results = dao.query( constraint );
+ assertNotNull( prefix + "Not Null", results );
+ assertEquals( prefix + "Results.size", expectedGroupIds.length, results.size() );
+
+ List groupIdList = Arrays.asList( expectedGroupIds );
+
+ Iterator it = results.iterator();
+ while ( it.hasNext() )
+ {
+ String actualGroupId = (String) it.next();
+ assertTrue( prefix + "groupId result should not be blank.", StringUtils.isNotBlank( actualGroupId ) );
+ assertTrue( prefix + " groupId result <" + actualGroupId + "> exists in expected GroupIds.",
+ groupIdList.contains( actualGroupId ) );
+ }
+ }
+
+}
--- /dev/null
+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.commons.lang.StringUtils;
+import org.apache.maven.archiva.database.AbstractArchivaDatabaseTestCase;
+import org.apache.maven.archiva.database.ArchivaDAO;
+import org.apache.maven.archiva.database.ArtifactDAO;
+import org.apache.maven.archiva.database.SimpleConstraint;
+import org.apache.maven.archiva.model.ArchivaArtifact;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * UniqueVersionConstraintTest
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class UniqueVersionConstraintTest
+ extends AbstractArchivaDatabaseTestCase
+{
+ private ArtifactDAO artifactDao;
+
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+
+ ArchivaDAO dao = (ArchivaDAO) lookup( ArchivaDAO.ROLE, "jdo" );
+ artifactDao = dao.getArtifactDAO();
+ }
+
+ public ArchivaArtifact createArtifact( String groupId, String artifactId, String version )
+ {
+ ArchivaArtifact artifact = artifactDao.createArtifact( groupId, artifactId, version, "", "jar" );
+ artifact.getModel().setLastModified( new Date() ); // mandatory field.
+ artifact.getModel().setRepositoryId( "testable_repo" );
+ return artifact;
+ }
+
+ public void testConstraint()
+ throws Exception
+ {
+ ArchivaArtifact artifact;
+
+ // Setup artifacts in fresh DB.
+ artifact = createArtifact( "commons-lang", "commons-lang", "2.0" );
+ artifactDao.saveArtifact( artifact );
+
+ artifact = createArtifact( "commons-lang", "commons-lang", "2.1" );
+ artifactDao.saveArtifact( artifact );
+
+ artifact = createArtifact( "org.apache.maven.test", "test-one", "1.2" );
+ artifactDao.saveArtifact( artifact );
+
+ artifact = createArtifact( "org.apache.maven.test.foo", "test-two", "1.0" );
+ artifactDao.saveArtifact( artifact );
+
+ artifact = createArtifact( "org.apache.maven.shared", "test-two", "2.0" );
+ artifactDao.saveArtifact( artifact );
+
+ artifact = createArtifact( "org.apache.maven.shared", "test-two", "2.1-SNAPSHOT" );
+ artifactDao.saveArtifact( artifact );
+
+ artifact = createArtifact( "org.apache.maven.shared", "test-two", "2.1.1" );
+ artifactDao.saveArtifact( artifact );
+
+ artifact = createArtifact( "org.apache.maven.shared", "test-two", "2.1-alpha-1" );
+ artifactDao.saveArtifact( artifact );
+
+ artifact = createArtifact( "org.apache.maven.shared", "test-bar", "2.1" );
+ artifactDao.saveArtifact( artifact );
+
+ artifact = createArtifact( "org.codehaus.modello", "modellong", "3.0" );
+ artifactDao.saveArtifact( artifact );
+
+ assertConstraint( new String[] {}, new UniqueVersionConstraint( "org.apache", "invalid" ) );
+ assertConstraint( new String[] {}, new UniqueVersionConstraint( "org.apache.test", "invalid" ) );
+ assertConstraint( new String[] {}, new UniqueVersionConstraint( "invalid", "test-two" ) );
+
+ assertConstraint( new String[] { "2.0", "2.1" }, new UniqueVersionConstraint( "commons-lang", "commons-lang" ) );
+ assertConstraint( new String[] { "1.2" }, new UniqueVersionConstraint( "org.apache.maven.test", "test-one" ) );
+ assertConstraint( new String[] { "2.0", "2.1-SNAPSHOT", "2.1.1", "2.1-alpha-1" },
+ new UniqueVersionConstraint( "org.apache.maven.shared", "test-two" ) );
+ assertConstraint( new String[] { "3.0" }, new UniqueVersionConstraint( "org.codehaus.modello", "modellong" ) );
+ }
+
+ private void assertConstraint( String[] versions, SimpleConstraint constraint )
+ {
+ String prefix = "Unique Versions: ";
+
+ List results = dao.query( constraint );
+ assertNotNull( prefix + "Not Null", results );
+ assertEquals( prefix + "Results.size", versions.length, results.size() );
+
+ List expectedVersions = Arrays.asList( versions );
+
+ Iterator it = results.iterator();
+ while ( it.hasNext() )
+ {
+ String actualVersion = (String) it.next();
+ assertTrue( prefix + "version result should not be blank.", StringUtils.isNotBlank( actualVersion ) );
+ assertTrue( prefix + "version result <" + actualVersion + "> exists in expected versions.",
+ expectedVersions.contains( actualVersion ) );
+ }
+ }
+}
*/
import org.apache.commons.lang.StringUtils;
-import org.apache.maven.archiva.configuration.ArchivaConfiguration;
-import org.apache.maven.archiva.configuration.Configuration;
-import org.apache.maven.archiva.database.ArchivaDAO;
+import org.apache.maven.archiva.database.browsing.BrowsingResults;
+import org.apache.maven.archiva.database.browsing.RepositoryBrowsing;
import org.codehaus.plexus.xwork.action.PlexusActionSupport;
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.StringTokenizer;
-import java.util.TreeMap;
-
/**
* Browse the repository.
*
- * @todo cache should be a proper cache class that is a singleton requirement rather than static variables
+ * @todo cache browsing results.
+ * @todo implement repository selectors (all or specific repository)
+ * @todo implement security around browse (based on repository id at first)
* @plexus.component role="com.opensymphony.xwork.Action" role-hint="browseAction"
*/
public class BrowseAction
extends PlexusActionSupport
{
/**
- * @plexus.requirement
- */
- private ArchivaDAO dao;
-
- /**
- * @plexus.requirement
+ * @plexus.requirement role-hint="default"
*/
- private ArchivaConfiguration archivaConfiguration;
+ private RepositoryBrowsing repoBrowsing;
- private List groups;
+ private BrowsingResults results;
private String groupId;
- private static final String GROUP_SEPARATOR = ".";
-
- private List artifactIds;
-
private String artifactId;
- private List versions;
-
- private static GroupTreeNode rootNode;
-
- private static long groupCacheTime;
-
public String browse()
- throws RepositoryIndexException, IOException
{
- RepositoryArtifactIndex index = getIndex();
-
- if ( !index.exists() )
- {
- addActionError( "The repository is not yet indexed. Please wait, and then try again." );
- return ERROR;
- }
-
- GroupTreeNode rootNode = buildGroupTree( index );
-
- this.groups = collateGroups( rootNode );
-
+ this.results = repoBrowsing.getRoot();
return SUCCESS;
}
public String browseGroup()
- throws RepositoryIndexException, IOException, RepositoryIndexSearchException
{
- RepositoryArtifactIndex index = getIndex();
-
- if ( !index.exists() )
- {
- addActionError( "The repository is not yet indexed. Please wait, and then try again." );
- return ERROR;
- }
-
- GroupTreeNode rootNode = buildGroupTree( index );
-
if ( StringUtils.isEmpty( groupId ) )
{
// TODO: i18n
return ERROR;
}
- StringTokenizer tok = new StringTokenizer( groupId, GROUP_SEPARATOR );
- while ( tok.hasMoreTokens() )
- {
- String part = tok.nextToken();
-
- if ( !rootNode.getChildren().containsKey( part ) )
- {
- // TODO: i18n
- getLogger().debug(
- "Can't find part: " + part + " for groupId " + groupId + " in children " + rootNode.getChildren() );
- addActionError( "The group specified was not found" );
- return ERROR;
- }
- else
- {
- rootNode = (GroupTreeNode) rootNode.getChildren().get( part );
- }
- }
-
- this.groups = collateGroups( rootNode );
-
- this.artifactIds = index.getArtifactIds( groupId );
- Collections.sort( this.artifactIds );
-
+ this.results = repoBrowsing.selectGroupId( groupId );
return SUCCESS;
}
public String browseArtifact()
- throws RepositoryIndexException, IOException, RepositoryIndexSearchException
{
- RepositoryArtifactIndex index = getIndex();
-
if ( StringUtils.isEmpty( groupId ) )
{
// TODO: i18n
return ERROR;
}
- this.versions = index.getVersions( groupId, artifactId );
- Collections.sort( this.versions );
-
- if ( versions.isEmpty() )
- {
- // TODO: i18n
- addActionError( "Could not find any artifacts with the given group and artifact ID" );
- return ERROR;
- }
-
+ this.results = repoBrowsing.selectArtifactId( groupId, artifactId );
return SUCCESS;
}
- private GroupTreeNode buildGroupTree( RepositoryArtifactIndex index )
- throws IOException, RepositoryIndexException
- {
- // TODO: give action message if indexing is in progress
-
- long lastUpdate = index.getLastUpdatedTime();
-
- if ( rootNode == null || lastUpdate > groupCacheTime )
- {
- List groups = index.getAllGroupIds();
-
- getLogger().info( "Loaded " + groups.size() + " groups from index" );
-
- rootNode = new GroupTreeNode();
-
- // build a tree structure
- for ( Iterator i = groups.iterator(); i.hasNext(); )
- {
- String groupId = (String) i.next();
-
- StringTokenizer tok = new StringTokenizer( groupId, GROUP_SEPARATOR );
-
- GroupTreeNode node = rootNode;
-
- while ( tok.hasMoreTokens() )
- {
- String part = tok.nextToken();
-
- if ( !node.getChildren().containsKey( part ) )
- {
- GroupTreeNode newNode = new GroupTreeNode( part, node );
- node.addChild( newNode );
- node = newNode;
- }
- else
- {
- node = (GroupTreeNode) node.getChildren().get( part );
- }
- }
- }
- groupCacheTime = lastUpdate;
- }
- else
- {
- getLogger().debug( "Loaded groups from cache" );
- }
-
- return rootNode;
- }
-
- private List collateGroups( GroupTreeNode rootNode )
- {
- List groups = new ArrayList();
- for ( Iterator i = rootNode.getChildren().values().iterator(); i.hasNext(); )
- {
- GroupTreeNode node = (GroupTreeNode) i.next();
-
- while ( node.getChildren().size() == 1 )
- {
- node = (GroupTreeNode) node.getChildren().values().iterator().next();
- }
-
- groups.add( node.getFullName() );
- }
- return groups;
- }
-
- public List getGroups()
- {
- return groups;
- }
-
- public List getArtifactIds()
- {
- return artifactIds;
- }
-
public String getGroupId()
{
return groupId;
this.artifactId = artifactId;
}
- public List getVersions()
- {
- return versions;
- }
-
- private static class GroupTreeNode
+ public BrowsingResults getResults()
{
- private final String name;
-
- private final String fullName;
-
- private final Map children = new TreeMap();
-
- GroupTreeNode()
- {
- name = null;
- fullName = null;
- }
-
- GroupTreeNode( String name, GroupTreeNode parent )
- {
- this.name = name;
- this.fullName = parent.fullName != null ? parent.fullName + GROUP_SEPARATOR + name : name;
- }
-
- public String getName()
- {
- return name;
- }
-
- public String getFullName()
- {
- return fullName;
- }
-
- public Map getChildren()
- {
- return children;
- }
-
- public void addChild( GroupTreeNode newNode )
- {
- children.put( newNode.name, newNode );
- }
+ return results;
}
}