</execution>
</executions>
</plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-enforcer-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>enforce-beanshell</id>
+ <goals>
+ <goal>enforce</goal>
+ </goals>
+ <configuration>
+ <rules>
+ <evaluateBeanshell>
+ <message>Site descriptor needs to be updated for the current release version</message>
+ <condition>
+ <![CDATA[
+ javax.xml.xpath.XPath xpath = javax.xml.xpath.XPathFactory.newInstance().newXPath();
+ org.xml.sax.InputSource is = new org.xml.sax.InputSource( new java.io.FileInputStream( "${basedir}/src/site/site.xml" ) );
+ xpath.evaluate( "//project/body/breadcrumbs/item[@name='${project.version}']/@href", is ).equals( "/docs/${project.version}" )
+ ]]>
+ </condition>
+ </evaluateBeanshell>
+ <evaluateBeanshell>
+ <message>Release notes need to be updated for the current release version</message>
+ <condition>
+ <![CDATA[
+ org.codehaus.plexus.util.FileUtils.fileRead( "${basedir}/src/site/apt/release-notes.apt" ).indexOf( "Release Notes for Archiva ${project.version}" ) >= 0
+ ]]>
+ </condition>
+ </evaluateBeanshell>
+ </rules>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
</plugins>
</build>
</profile>
</profiles>
-
</project>
-----
- Release Notes for Archiva 1.1.1
+ Release Notes for Archiva 1.2-SNAPSHOT
-----
-Release Notes for Archiva 1.1.1
+Release Notes for Archiva 1.2-SNAPSHOT
- The Apache Archiva team would like to announce the release of Archiva 1.1.1.
-
- Archiva 1.1.1 is {{{http://archiva.apache.org/download.html} available for download from the web site}}.
+ The Apache Archiva team would like to announce the release of Archiva 1.2. Archiva is {{{http://archiva.apache.org/download.html}
+ available for download from the web site}}.
Archiva is an application for managing one or more remote repositories, including administration, artifact handling, browsing and searching.
* the archiva-user mailing list: {{http://archiva.apache.org/mail-lists.html}}
-* New in Archiva 1.1
+* New in Archiva 1.2
-** Artifact Uploads
+~~TODO
- To simplify adding artifacts to a repository, an upload form has been put in place that allows you to put an artifact and POM into
- the repository without the need for the Maven <<<deploy-file>>> command.
+* Release Notes
-** RSS
+ The Archiva 1.2 feature set can be seen in the {{{tour/index.html} feature tour}}.
- RSS is now available for getting a feed of new artifacts being added to a given repository. Two types of feeds are generated by Archiva:
- new artifacts in a repository and new versions of a specific artifact. Details are available in {{{userguide/rss.html}Rss Feeds}}.
+* Changes in Archiva 1.2
-** Virtual Repositories
+~~TODO
- Virtual repositories or repository groups allows downloading from a group of repositories via one url. For more details of this feature,
- see {{{userguide/virtual-repositories.html}Virtual Repositories}}.
+* Changes in Archiva 1.1.3
-** Timeouts
+** Bug
- Connections to remote repositories can now have a configurable timeout value
+ * [MRM-967] - Security Issue: If repository observer role is enabled for the 'guest' user, an invalid user is able to deploy to that repository
-** New Runtime Bundle
+ * [MRM-397] - background of the Archiva logo is not transparent in repositories page
- The application is now distributed using Jetty 6.1 and it's documented configuration, rather than the previous
- Plexus application server bundle. It continues to use the Java Service Wrapper (v3.2.3) for application monitoring,
- though the configuration has been improved, particularly with regard to separating the application configuration from the installation.
+ * [MRM-580] - does not give error message when one defines an illegal directory for a managed repository
-** Using Spring
+ * [MRM-954] - Footer doesn't stretch across repositoryGroups page
- Archiva now uses the Spring Framework as it's underlying container instead of Plexus. This results in a boost in performance and
- stability for the web application in particular.
+* Changes in Archiva 1.1.2
-** Using Apache Jackrabbit WebDAV Servlet
+** Bug
- Archiva now uses Apache Jackrabbit's WebDAV servlet for serving repository content instead of plexus-webdav. The change results in reduced
- codebase complexity, increased standards compliance, better webdav client support and a small peformance boost.
+ * [MRM-765] - should not be possible to create a proxy connector if there are no remote repositories
-* Release Notes
+ * [MRM-807] - Deployed dll won't be indexed
+
+ * [MRM-834] - Wrong repository url when archiva is used behind Apache with mof_proxy
+
+ * [MRM-841] - Introducing a new scannable artifact file type requires restart in order for some consumers to work
+
+ * [MRM-880] - Archiva does not start up on Solaris 64-Bit
+
+ * [MRM-881] - Failing to startup due to invalid bean definition
+
+ * [MRM-893] - Illegal browse operation allow
+
+ * [MRM-902] - If path has leading slash when being checked againts whitelists and blacklists causes matching failure
+
+ * [MRM-903] - Repository scanning should not stop when encounters error
+
+ * [MRM-905] - EL Expression failed with empty/not functions
+
+ * [MRM-911] - Archiva checks user's credentials before guest's rights on the repository
+
+ * [MRM-912] - rss urls seem to use fixed webcontext "archiva" instead of actual webcontext
+
+ * [MRM-915] - NPE with rss links
+
+ * [MRM-926] - NPE with search page
+
+ * [MRM-932] - Error 500 when clicking the Next or Previous icon of the results of a search, if user is trying to search for java classes, packages or methods.
+
+ * [MRM-934] - For bytecode search, only 1 version of the artifact is returned even if there are more than 1 version of that artifact which matched the search
+
+ * [MRM-943] - results search option should only be available on results page
+
+** Improvement
+
+ * [MRM-839] - change RSS URLs
+
+ * [MRM-848] - Pre-configured repositories initially appear to be empty
+
+ * [MRM-874] - POM snippet for plugins should be <plugin> not <dependency>
- The Archiva 1.1 feature set can be seen in the {{{tour/index.html} feature tour}}.
+ The full list of changes can be found {{{http://jira.codehaus.org/secure/ReleaseNote.jspa?version=14491&styleName=Text&projectId=10980} in JIRA}}.
* Changes in Archiva 1.1.1
<project>
<body>
<breadcrumbs>
- <item name="1.1.1" href="/docs/1.1.1" />
+ <item name="1.2-SNAPSHOT" href="/docs/1.2-SNAPSHOT" />
</breadcrumbs>
<menu name="Introduction">
</plugin>
</plugins>
</build>
- <pluginRepositories>
- <pluginRepository>
- <id>codehaus.snapshots</id>
- <url>http://snapshots.repository.codehaus.org/</url>
- </pluginRepository>
- </pluginRepositories>
</project>
}
else
{
- return version.endsWith( SNAPSHOT );
+ return isGenericSnapshot(version);
}
}
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.ArchivaModelCloner;
import org.apache.maven.archiva.model.ArchivaProjectModel;
import org.apache.maven.archiva.model.Keys;
import org.apache.maven.archiva.model.RepositoryProblem;
import org.apache.maven.archiva.repository.RepositoryException;
import org.apache.maven.archiva.repository.content.ManagedLegacyRepositoryContent;
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.filters.EffectiveProjectModelFilter;
import org.apache.maven.archiva.repository.project.readers.ProjectModel300Reader;
*/
private RepositoryContentFactory repositoryFactory;
- /**
- * @plexus.requirement role-hint="expression"
- */
- private ProjectModelFilter expressionModelFilter;
-
/**
* @plexus.requirement role="org.apache.maven.archiva.repository.project.ProjectModelFilter"
* role-hint="effective"
{
model = reader.read( artifactFile );
- model.setOrigin( "filesystem" );
-
// The version should be updated to the artifact/filename version if it is a unique snapshot
if ( VersionUtil.isUniqueSnapshot( artifact.getVersion() ) )
{
model.setVersion( artifact.getVersion() );
}
- // Filter the model
- model = expressionModelFilter.filter( model );
-
- // Resolve the project model
+ // Resolve the project model (build effective model, resolve expressions)
model = effectiveModelFilter.filter( model );
if ( isValidModel( model, repo, artifact ) )
{
log.debug( "Adding project model to database - " + Keys.toKey( model ) );
+
+ // Clone model, since DAO while detachingCopy resets its contents
+ // This changes contents of the cache in EffectiveProjectModelFilter
+ model = ArchivaModelCloner.clone( model );
dao.getProjectModelDAO().saveProjectModel( model );
}
else
}
}
}
-
}
--- /dev/null
+package org.apache.maven.archiva.consumers.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.
+ */
+
+import java.io.File;
+import java.util.Iterator;
+
+import org.apache.maven.archiva.configuration.ArchivaConfiguration;
+import org.apache.maven.archiva.configuration.Configuration;
+import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
+import org.apache.maven.archiva.consumers.ConsumerException;
+import org.apache.maven.archiva.consumers.DatabaseUnprocessedArtifactConsumer;
+import org.apache.maven.archiva.database.ArchivaDatabaseException;
+import org.apache.maven.archiva.database.ObjectNotFoundException;
+import org.apache.maven.archiva.database.ProjectModelDAO;
+import org.apache.maven.archiva.model.ArchivaArtifact;
+import org.apache.maven.archiva.model.ArchivaArtifactModel;
+import org.apache.maven.archiva.model.ArchivaProjectModel;
+import org.apache.maven.archiva.model.Dependency;
+import org.apache.maven.archiva.model.Keys;
+import org.codehaus.plexus.spring.PlexusInSpringTestCase;
+
+/**
+ * Test for ProjectModelToDatabaseConsumerTest
+ *
+ * @author <a href="mailto:michal.stochmialek@eurobank.pl">Michal Stochmialek</a>
+ */
+public class ProjectModelToDatabaseConsumerTest
+ extends PlexusInSpringTestCase
+{
+ private ProjectModelToDatabaseConsumer consumer;
+
+ private ProjectModelDAO modelDao;
+
+ public void setUp()
+ throws Exception
+ {
+ super.setUp();
+
+ ArchivaConfiguration archivaConfig = (ArchivaConfiguration) lookup( ArchivaConfiguration.class );
+
+ Configuration configuration = archivaConfig.getConfiguration();
+ ManagedRepositoryConfiguration repo = configuration.findManagedRepositoryById( "internal" );
+ repo.setLocation( new File( getBasedir(), "src/test/resources/test-repo" ).toString() );
+
+ consumer =
+ (ProjectModelToDatabaseConsumer) lookup( DatabaseUnprocessedArtifactConsumer.class, "update-db-project" );
+ modelDao = (ProjectModelDAO) lookup( ProjectModelDAO.class, "jdo" );
+ }
+
+ public void testProcess()
+ throws Exception
+ {
+ ArchivaProjectModel model = processAndGetModel( "test-project", "test-project-endpoint-pom", "2.4.4" );
+ assertNotNull( model.getParentProject() );
+ assertEquals( "test-project:test-project:2.4.4", Keys.toKey( model.getParentProject() ) );
+
+ assertFalse( model.getDependencyManagement().isEmpty() );
+
+ model = processAndGetModel( "test-project", "test-project-endpoint-ejb", "2.4.4" );
+ assertNotNull( model.getParentProject() );
+ assertEquals( "test-project:test-project-endpoint-pom:2.4.4", Keys.toKey( model.getParentProject() ) );
+ assertTrue( hasDependency( model, "test-project:test-project-api:2.4.4" ) );
+ assertTrue( hasDependency( model, "commons-id:commons-id:0.1-dev" ) );
+
+ model = processAndGetModel( "test-project", "test-project", "2.4.4" );
+ assertFalse( model.getDependencyManagement().isEmpty() );
+ }
+
+ private boolean hasDependency( ArchivaProjectModel model, String key )
+ {
+ for ( Iterator i = model.getDependencies().iterator(); i.hasNext(); )
+ {
+ Dependency dependency = (Dependency) i.next();
+ if ( key.equals( Keys.toKey( dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion() ) ) )
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private ArchivaProjectModel processAndGetModel( String group, String artifactId, String version )
+ throws ConsumerException, ObjectNotFoundException, ArchivaDatabaseException
+ {
+ ArchivaArtifact artifact = createArtifact( group, artifactId, version, "pom" );
+ consumer.processArchivaArtifact( artifact );
+
+ ArchivaProjectModel model = modelDao.getProjectModel( group, artifactId, version );
+ assertEquals( group, model.getGroupId() );
+ assertEquals( artifactId, model.getArtifactId() );
+ assertEquals( version, model.getVersion() );
+ return model;
+ }
+
+ protected ArchivaArtifact createArtifact( String group, String artifactId, String version, String type )
+ {
+ ArchivaArtifactModel model = new ArchivaArtifactModel();
+ model.setGroupId( group );
+ model.setArtifactId( artifactId );
+ model.setVersion( version );
+ model.setType( type );
+ model.setRepositoryId( "internal" );
+
+ return new ArchivaArtifact( model );
+ }
+
+}
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ ~ 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.
+-->
+
+<component-set>
+ <components>
+ <!-- JdoAccess -->
+ <component>
+ <role>org.apache.maven.archiva.database.jdo.JdoAccess</role>
+ <role-hint>archiva</role-hint>
+ <implementation>org.apache.maven.archiva.database.jdo.JdoAccess</implementation>
+ <requirements>
+ <requirement>
+ <role>org.codehaus.plexus.jdo.JdoFactory</role>
+ <role-hint>archiva</role-hint>
+ </requirement>
+ </requirements>
+ </component>
+
+ <!-- JDO Factory -->
+ <component>
+ <role>org.codehaus.plexus.jdo.JdoFactory</role>
+ <role-hint>archiva</role-hint>
+ <implementation>org.codehaus.plexus.jdo.DefaultConfigurableJdoFactory</implementation>
+
+ <configuration>
+ <!-- Database Configuration -->
+ <driverName>org.hsqldb.jdbcDriver</driverName>
+ <url>jdbc:hsqldb:mem:TESTDB</url>
+ <userName>sa</userName>
+ <password></password>
+
+ <!-- JPOX and JDO configuration -->
+ <persistenceManagerFactoryClass>org.jpox.PersistenceManagerFactoryImpl</persistenceManagerFactoryClass>
+ <otherProperties>
+ <property>
+ <name>javax.jdo.PersistenceManagerFactoryClass</name>
+ <value>org.jpox.PersistenceManagerFactoryImpl</value>
+ </property>
+ <property>
+ <name>org.jpox.autoCreateSchema</name>
+ <value>true</value>
+ </property>
+ </otherProperties>
+ </configuration>
+ </component>
+
+ <component>
+ <role>org.codehaus.plexus.cache.Cache</role>
+ <role-hint>effective-project-cache</role-hint>
+ <implementation>org.codehaus.plexus.cache.ehcache.EhcacheCache</implementation>
+ <description>Effective Project Cache</description>
+ <configuration>
+ <disk-expiry-thread-interval-seconds>600</disk-expiry-thread-interval-seconds>
+ <disk-persistent>true</disk-persistent>
+ <disk-store-path>${java.io.tmpdir}/archiva/effectiveproject</disk-store-path>
+ <eternal>true</eternal>
+ <max-elements-in-memory>1000</max-elements-in-memory>
+ <memory-eviction-policy>LRU</memory-eviction-policy>
+ <name>effective-project-cache</name>
+ <overflow-to-disk>false</overflow-to-disk>
+ <!-- TODO: Adjust the time to live to be more sane (ie: huge 4+ hours) -->
+ <!-- 45 minutes = 2700 seconds -->
+ <time-to-idle-seconds>2700</time-to-idle-seconds>
+ <!-- 30 minutes = 1800 seconds -->
+ <time-to-live-seconds>1800</time-to-live-seconds>
+ </configuration>
+ </component>
+ </components>
+</component-set>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>test-project</groupId>
+ <artifactId>test-project</artifactId>
+ <version>2.4.4</version>
+ </parent>
+ <groupId>test-project</groupId>
+ <artifactId>test-project-api</artifactId>
+ <name>Test Project API</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>javax.activation</groupId>
+ <artifactId>activation</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>stax</groupId>
+ <artifactId>stax-api</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-source-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>test-project</groupId>
+ <artifactId>test-project-broker-pom</artifactId>
+ <version>2.4.4</version>
+ </parent>
+ <artifactId>test-project-broker-ejb</artifactId>
+ <name>Test Project Broker EJB</name>
+ <packaging>ejb</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>test-project</groupId>
+ <artifactId>test-project-common</artifactId>
+ <type>test-jar</type>
+ <version>${pom.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>test-project</groupId>
+ <artifactId>test-project-common</artifactId>
+ <version>${pom.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>test-project</groupId>
+ <artifactId>test-project-api</artifactId>
+ <version>${pom.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-httpclient</groupId>
+ <artifactId>commons-httpclient</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-id</groupId>
+ <artifactId>commons-id</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-discovery</groupId>
+ <artifactId>commons-discovery</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-mock</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.jms</groupId>
+ <artifactId>jms</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.activation</groupId>
+ <artifactId>activation</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.mail</groupId>
+ <artifactId>mail</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.management</groupId>
+ <artifactId>jmxri</artifactId>
+ </dependency>
+ </dependencies>
+
+</project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>test-project</groupId>
+ <artifactId>test-project</artifactId>
+ <version>2.4.4</version>
+ </parent>
+ <artifactId>test-project-broker-pom</artifactId>
+ <name>Test Project Broker POM</name>
+ <packaging>pom</packaging>
+
+ <modules>
+ <module>broker-ejb</module>
+ </modules>
+</project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>test-project</groupId>
+ <artifactId>test-project</artifactId>
+ <version>2.4.4</version>
+ </parent>
+ <groupId>test-project</groupId>
+ <artifactId>test-project-common</artifactId>
+ <name>Test Project Commons</name>
+ <dependencies>
+ <dependency>
+ <groupId>test-project</groupId>
+ <artifactId>test-project-api</artifactId>
+ <version>${pom.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-id</groupId>
+ <artifactId>commons-id</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-discovery</groupId>
+ <artifactId>commons-discovery</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-collections</groupId>
+ <artifactId>commons-collections</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-httpclient</groupId>
+ <artifactId>commons-httpclient</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>stax</groupId>
+ <artifactId>stax-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.woodstox</groupId>
+ <artifactId>wstx-asl</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.castor</groupId>
+ <artifactId>castor</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>xerces</groupId>
+ <artifactId>xerces</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.activation</groupId>
+ <artifactId>activation</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.jms</groupId>
+ <artifactId>jms</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.ejb</groupId>
+ <artifactId>ejb</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.mail</groupId>
+ <artifactId>mail</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.management</groupId>
+ <artifactId>jmxri</artifactId>
+ </dependency>
+ </dependencies>
+
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-source-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>test-jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>test-project</groupId>
+ <artifactId>test-project-endpoint-pom</artifactId>
+ <version>2.4.4</version>
+ </parent>
+ <groupId>test-project</groupId>
+ <artifactId>test-project-endpoint-ejb</artifactId>
+ <name>Test Project Endpoint EJB</name>
+ <packaging>ejb</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>test-project</groupId>
+ <artifactId>test-project-common</artifactId>
+ <version>${pom.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>test-project</groupId>
+ <artifactId>test-project-api</artifactId>
+ <version>${pom.version}</version>
+ </dependency>
+ <dependency>
+ <!-- for tests only -->
+ <groupId>test-project</groupId>
+ <artifactId>test-project-common</artifactId>
+ <version>${pom.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>commons-id</groupId>
+ <artifactId>commons-id</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-discovery</groupId>
+ <artifactId>commons-discovery</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.jms</groupId>
+ <artifactId>jms</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.activation</groupId>
+ <artifactId>activation</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.mail</groupId>
+ <artifactId>mail</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>xml-apis</groupId>
+ <artifactId>xml-apis</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.management</groupId>
+ <artifactId>jmxri</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ </dependency>
+ </dependencies>
+
+</project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>test-project</groupId>
+ <artifactId>test-project</artifactId>
+ <version>2.4.4</version>
+ </parent>
+ <artifactId>test-project-endpoint-pom</artifactId>
+ <name>Test Project Endpoint POM</name>
+ <packaging>pom</packaging>
+
+ <modules>
+ <module>endpoint-ejb</module>
+ </modules>
+</project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>test-project</groupId>
+ <artifactId>test-project</artifactId>
+ <name>Test Project</name>
+ <version>2.4.4</version>
+ <packaging>pom</packaging>
+
+ <organization>
+ <name>Company</name>
+ <url>http://www.company.com/</url>
+ </organization>
+ <inceptionYear>2002</inceptionYear>
+
+ <modules>
+ <module>api</module>
+ <module>common</module>
+ <module>broker</module>
+ <module>endpoint</module>
+ </modules>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <dependencyManagement>
+ <dependencies>
+ <!-- common version strategy -->
+ <dependency>
+ <groupId>javax.activation</groupId>
+ <artifactId>activation</artifactId>
+ <version>1.0.2</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.jms</groupId>
+ <artifactId>jms</artifactId>
+ <version>1.0.2</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.ejb</groupId>
+ <artifactId>ejb</artifactId>
+ <version>2.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ <version>2.4</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.mail</groupId>
+ <artifactId>mail</artifactId>
+ <version>1.4</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>xml-apis</groupId>
+ <artifactId>xml-apis</artifactId>
+ <version>2.0.2</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ <version>1.0.4</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <version>2.1</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-collections</groupId>
+ <artifactId>commons-collections</artifactId>
+ <version>3.2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring</artifactId>
+ <version>2.0.7</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-mock</artifactId>
+ <version>2.0.7</version>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-jdbc</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-web</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <version>1.2.8</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-discovery</groupId>
+ <artifactId>commons-discovery</artifactId>
+ <version>0.2</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-id</groupId>
+ <artifactId>commons-id</artifactId>
+ <version>0.1-dev</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.castor</groupId>
+ <artifactId>castor</artifactId>
+ <version>1.0.5-xml</version>
+ </dependency>
+ <dependency>
+ <groupId>xerces</groupId>
+ <artifactId>xerces</artifactId>
+ <version>2.4.0</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-httpclient</groupId>
+ <artifactId>commons-httpclient</artifactId>
+ <version>3.1</version>
+ </dependency>
+ <dependency>
+ <groupId>stax</groupId>
+ <artifactId>stax-api</artifactId>
+ <version>1.0.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.woodstox</groupId>
+ <artifactId>wstx-asl</artifactId>
+ <version>3.2.1</version>
+ </dependency>
+ <dependency>
+ <groupId>com.thoughtworks.xstream</groupId>
+ <artifactId>xstream</artifactId>
+ <version>1.2.2</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.management</groupId>
+ <artifactId>jmxri</artifactId>
+ <version>1.2.1</version>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+</project>
StringBuffer key = new StringBuffer();
key.append( defaultString( reference.getGroupId() ) ).append( ":" );
- key.append( defaultString( reference.getArtifactId() ) ).append( ":" );
+ key.append( defaultString( reference.getArtifactId() ) );
return key.toString();
}
key.append( defaultString( reference.getGroupId() ) ).append( ":" );
key.append( defaultString( reference.getArtifactId() ) ).append( ":" );
- key.append( defaultString( reference.getVersion() ) ).append( ":" );
+ key.append( defaultString( reference.getVersion() ) );
return key.toString();
}
The number of new files discovered.
</description>
</field>
+ <field>
+ <name>totalProjectCount</name>
+ <version>1.0.0+</version>
+ <identifier>false</identifier>
+ <required>true</required>
+ <type>long</type>
+ <description>
+ The total number of unique projects in the repository.
+ </description>
+ </field>
+ <field>
+ <name>totalGroupCount</name>
+ <version>1.0.0+</version>
+ <identifier>false</identifier>
+ <required>true</required>
+ <type>long</type>
+ <description>
+ The total number of unique groups in the repository.
+ </description>
+ </field>
+ <field>
+ <name>totalArtifactCount</name>
+ <version>1.0.0+</version>
+ <identifier>false</identifier>
+ <required>true</required>
+ <type>long</type>
+ <description>
+ The total number of artifacts in the repository.
+ </description>
+ </field>
+ <field>
+ <name>totalSize</name>
+ <version>1.0.0+</version>
+ <identifier>false</identifier>
+ <required>true</required>
+ <type>long</type>
+ <description>
+ The total size in bytes of the repository.
+ </description>
+ </field>
</fields>
<codeSegments>
<codeSegment>
// check it starts with the same version up to the snapshot part
int leadingLength = expected.length() - 9;
- if ( version.startsWith( expected.substring( 0, leadingLength ) ) && version.length() > leadingLength )
+ if ( leadingLength > 0 && version.startsWith( expected.substring( 0, leadingLength ) ) &&
+ version.length() > leadingLength )
{
// If we expect a non-generic snapshot - look for the timestamp
Matcher m = SNAPSHOT_PATTERN.matcher( version.substring( leadingLength + 1 ) );
ArchivaProjectModel merged = new ArchivaProjectModel();
// Unmerged.
+ merged.setParentProject(mainProject.getParentProject());
merged.setArtifactId( mainProject.getArtifactId() );
merged.setPackaging( StringUtils.defaultIfEmpty( mainProject.getPackaging(), "jar" ) );
merged.setRelocation( mainProject.getRelocation() );
}
Properties merged = new Properties();
+ merged.putAll(mainProperties);
Enumeration keys = parentProperties.propertyNames();
while ( keys.hasMoreElements() )
// Clone submitted project (so that we don't mess with it)
effectiveProject = ArchivaModelCloner.clone( project );
- // Setup Expression Evaluation pieces.
- effectiveProject = expressionFilter.filter( effectiveProject );
-
DEBUG( "Starting build of effective with: " + effectiveProject );
// Merge in all the parent poms.
effectiveProject = mergeParent( effectiveProject );
+ // Setup Expression Evaluation pieces.
+ effectiveProject = expressionFilter.filter( effectiveProject );
+
// Resolve dependency versions from dependency management.
applyDependencyManagement( effectiveProject );
+ // groupId or version could be updated by parent or expressions
+ projectKey = toProjectKey( effectiveProject );
+
// Do not add project into cache if it contains no groupId and
// version information
- if ( project.getGroupId() != null && project.getVersion() != null )
+ if ( effectiveProject.getGroupId() != null && effectiveProject.getVersion() != null )
{
synchronized ( effectiveProjectCache )
{
if ( parentProject != null )
{
// Merge the pom with the parent pom.
- parentProject = expressionFilter.filter( parentProject );
parentProject = mergeParent( parentProject );
+ parentProject = expressionFilter.filter( parentProject );
// Cache the pre-merged parent.
synchronized ( effectiveProjectCache )
try
{
// Setup some common properties.
+ VersionedReference parent = model.getParentProject();
+ if ( parent != null )
+ {
+ String parentGroupId = StringUtils.defaultString( evaluator.expand( parent.getGroupId() ) );
+ String parentArtifactId = StringUtils.defaultString( evaluator.expand( parent.getArtifactId() ) );
+ String parentVersion = StringUtils.defaultString( evaluator.expand( parent.getVersion() ) );
+
+ props.setProperty( "parent.groupId", parentGroupId );
+ props.setProperty( "parent.artifactId", parentArtifactId );
+ props.setProperty( "parent.version", parentVersion );
+ }
+
String groupId = StringUtils.defaultString( evaluator.expand( model.getGroupId() ) );
String artifactId = StringUtils.defaultString( evaluator.expand( model.getArtifactId() ) );
String version = StringUtils.defaultString( evaluator.expand( model.getVersion() ) );
String name = StringUtils.defaultString( evaluator.expand( model.getName() ) );
+
/* Archiva doesn't need to handle a full expression language with object tree walking
* as the requirements within Archiva are much smaller, a quick replacement of the
* important fields (groupId, artifactId, version, name) are handled specifically.
model.setProperties( getProperties( xml.getElement( "//project/properties" ) ) );
model.setDependencies( getDependencies( xml ) );
+ model.setOrigin("filesystem");
+
/* Following are not valid for <pomVersion>3</pomVersion> / Maven 1 pom files.
*
* model.setDependencyManagement()
model.setBuildExtensions( getBuildExtensions( xml ) );
model.setRelocation( getRelocation( xml ) );
+
+ model.setOrigin("filesystem");
return model;
}
<artifactId>archiva-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.maven.archiva</groupId>
+ <artifactId>archiva-test-A</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.archiva</groupId>
+ <artifactId>archiva-test-B</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-utils</artifactId>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- ====================================================================== -->
+<!-- -->
+<!-- Generated by Maven Help Plugin on 9/17/08 5:36 PM -->
+<!-- See: http://maven.apache.org/plugins/maven-help-plugin/ -->
+<!-- -->
+<!-- ====================================================================== -->
+
+<!-- ====================================================================== -->
+<!-- -->
+<!-- Effective POM for project -->
+<!-- 'test-project:test-project-endpoint-ejb:ejb:2.4.4' -->
+<!-- -->
+<!-- ====================================================================== -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <artifactId>test-project-endpoint-pom</artifactId>
+ <groupId>test-project</groupId>
+ <version>2.4.4</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>test-project</groupId>
+ <artifactId>test-project-endpoint-ejb</artifactId>
+ <packaging>ejb</packaging>
+ <name>Test Project Endpoint EJB</name>
+ <version>2.4.4</version>
+ <inceptionYear>2002</inceptionYear>
+ <organization>
+ <name>Company</name>
+ <url>http://www.company.com/</url>
+ </organization>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>test-project</groupId>
+ <artifactId>test-project-common</artifactId>
+ <version>2.4.4</version>
+ </dependency>
+ <dependency>
+ <groupId>test-project</groupId>
+ <artifactId>test-project-api</artifactId>
+ <version>2.4.4</version>
+ </dependency>
+ <dependency>
+ <groupId>test-project</groupId>
+ <artifactId>test-project-common</artifactId>
+ <version>2.4.4</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>commons-id</groupId>
+ <artifactId>commons-id</artifactId>
+ <version>0.1-dev</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-discovery</groupId>
+ <artifactId>commons-discovery</artifactId>
+ <version>0.2</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ <version>1.0.4</version>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <version>1.2.8</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.jms</groupId>
+ <artifactId>jms</artifactId>
+ <version>1.0.2</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.activation</groupId>
+ <artifactId>activation</artifactId>
+ <version>1.0.2</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.mail</groupId>
+ <artifactId>mail</artifactId>
+ <version>1.4</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>xml-apis</groupId>
+ <artifactId>xml-apis</artifactId>
+ <version>2.0.2</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.management</groupId>
+ <artifactId>jmxri</artifactId>
+ <version>1.2.1</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ <version>2.4</version>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>javax.activation</groupId>
+ <artifactId>activation</artifactId>
+ <version>1.0.2</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.jms</groupId>
+ <artifactId>jms</artifactId>
+ <version>1.0.2</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.ejb</groupId>
+ <artifactId>ejb</artifactId>
+ <version>2.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ <version>2.4</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.mail</groupId>
+ <artifactId>mail</artifactId>
+ <version>1.4</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>xml-apis</groupId>
+ <artifactId>xml-apis</artifactId>
+ <version>2.0.2</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ <version>1.0.4</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <version>2.1</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-collections</groupId>
+ <artifactId>commons-collections</artifactId>
+ <version>3.2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring</artifactId>
+ <version>2.0.7</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-mock</artifactId>
+ <version>2.0.7</version>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <artifactId>spring-jdbc</artifactId>
+ <groupId>org.springframework</groupId>
+ </exclusion>
+ <exclusion>
+ <artifactId>spring-web</artifactId>
+ <groupId>org.springframework</groupId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <version>1.2.8</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-discovery</groupId>
+ <artifactId>commons-discovery</artifactId>
+ <version>0.2</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-id</groupId>
+ <artifactId>commons-id</artifactId>
+ <version>0.1-dev</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.castor</groupId>
+ <artifactId>castor</artifactId>
+ <version>1.0.5-xml</version>
+ </dependency>
+ <dependency>
+ <groupId>xerces</groupId>
+ <artifactId>xerces</artifactId>
+ <version>2.4.0</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-httpclient</groupId>
+ <artifactId>commons-httpclient</artifactId>
+ <version>3.1</version>
+ </dependency>
+ <dependency>
+ <groupId>stax</groupId>
+ <artifactId>stax-api</artifactId>
+ <version>1.0.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.woodstox</groupId>
+ <artifactId>wstx-asl</artifactId>
+ <version>3.2.1</version>
+ </dependency>
+ <dependency>
+ <groupId>com.thoughtworks.xstream</groupId>
+ <artifactId>xstream</artifactId>
+ <version>1.2.2</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.management</groupId>
+ <artifactId>jmxri</artifactId>
+ <version>1.2.1</version>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+</project>
\ No newline at end of file
assertLayout( path, groupId, artifactId, version, classifier, type );
}
+ /**
+ * A timestamped versioned artifact but without release version part. Like on axiom trunk.
+ */
+ public void testBadSnapshotWithoutReleasePart()
+ {
+ assertBadPath( "org/apache/ws/commons/axiom/axiom/SNAPSHOT/axiom-20070912.093446-2.pom",
+ "snapshot version without release part");
+ }
+
/**
* A timestamped versioned artifact, should reside in a SNAPSHOT baseversion directory.
* @throws LayoutException
assertNull( parser.expect( "2.0-SNAPSHOT" ) );
}
+ public void testExpectWrongSnapshot2()
+ {
+ // tests parsing axiom snapshots without exceptions
+ FilenameParser parser = new FilenameParser( "axiom-20080221.062205-9.pom" );
+
+ assertEquals( "axiom", parser.nextNonVersion() );
+ assertNull( parser.expect( "SNAPSHOT" ) );
+ }
+
public void testClassifier()
{
FilenameParser parser = new FilenameParser( "artifact-id-1.0-20070219.171202-34-test-sources.jar" );
public void testBuildEffectiveProject()
throws Exception
{
+ assertEffectiveProject(
+ "/org/apache/maven/archiva/archiva-model/1.0-SNAPSHOT/archiva-model-1.0-SNAPSHOT.pom",
+ "/archiva-model-effective.pom");
+ assertEffectiveProject(
+ "/test-project/test-project-endpoint-ejb/2.4.4/test-project-endpoint-ejb-2.4.4.pom",
+ "/test-project-model-effective.pom");
+ }
+
+ private void assertEffectiveProject(String pomFile, String effectivePomFile) throws Exception,
+ ProjectModelException {
initTestResolverFactory();
EffectiveProjectModelFilter filter = lookupEffective();
- ArchivaProjectModel startModel = createArchivaProjectModel( DEFAULT_REPOSITORY
- + "/org/apache/maven/archiva/archiva-model/1.0-SNAPSHOT/archiva-model-1.0-SNAPSHOT.pom" );
+ ArchivaProjectModel startModel = createArchivaProjectModel( DEFAULT_REPOSITORY + pomFile );
ArchivaProjectModel effectiveModel = filter.filter( startModel );
- ArchivaProjectModel expectedModel = createArchivaProjectModel( "src/test/expected-poms/"
- + "/archiva-model-effective.pom" );
+ ArchivaProjectModel expectedModel = createArchivaProjectModel( "src/test/expected-poms/" + effectivePomFile);
assertModel( expectedModel, effectiveModel );
}
+
/**
* [MRM-510] In Repository Browse, the first unique snapshot version clicked is getting persisted in the
* request resulting to 'version does not match' error
while ( it.hasNext() )
{
Dependency dep = it.next();
- String key = Dependency.toVersionlessKey( dep );
+ String key = Dependency.toKey( dep );
map.put( key, dep );
}
return map;
assertEquals( "Parent Version", "1.0-SNAPSHOT", parentRef.getVersion() );
assertNotNull( "Dependencies", project.getDependencies() );
- assertEquals( "Dependencies.size", 6, project.getDependencies().size() );
+ assertEquals( "Dependencies.size", 8, project.getDependencies().size() );
}
}
<groupId>org.apache.maven.archiva</groupId>
<artifactId>archiva-common</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.maven.archiva</groupId>
+ <artifactId>archiva-test-A</artifactId>
+ <version>${pom.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.archiva</groupId>
+ <artifactId>archiva-test-B</artifactId>
+ <version>${parent.version}</version>
+ </dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-utils</artifactId>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>test-project</groupId>
+ <artifactId>test-project</artifactId>
+ <version>2.4.4</version>
+ </parent>
+ <groupId>test-project</groupId>
+ <artifactId>test-project-api</artifactId>
+ <name>Test Project API</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>javax.activation</groupId>
+ <artifactId>activation</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>stax</groupId>
+ <artifactId>stax-api</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-source-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>test-project</groupId>
+ <artifactId>test-project-broker-pom</artifactId>
+ <version>2.4.4</version>
+ </parent>
+ <artifactId>test-project-broker-ejb</artifactId>
+ <name>Test Project Broker EJB</name>
+ <packaging>ejb</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>test-project</groupId>
+ <artifactId>test-project-common</artifactId>
+ <type>test-jar</type>
+ <version>${pom.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>test-project</groupId>
+ <artifactId>test-project-common</artifactId>
+ <version>${pom.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>test-project</groupId>
+ <artifactId>test-project-api</artifactId>
+ <version>${pom.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-httpclient</groupId>
+ <artifactId>commons-httpclient</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-id</groupId>
+ <artifactId>commons-id</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-discovery</groupId>
+ <artifactId>commons-discovery</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-mock</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.jms</groupId>
+ <artifactId>jms</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.activation</groupId>
+ <artifactId>activation</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.mail</groupId>
+ <artifactId>mail</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.management</groupId>
+ <artifactId>jmxri</artifactId>
+ </dependency>
+ </dependencies>
+
+</project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>test-project</groupId>
+ <artifactId>test-project</artifactId>
+ <version>2.4.4</version>
+ </parent>
+ <artifactId>test-project-broker-pom</artifactId>
+ <name>Test Project Broker POM</name>
+ <packaging>pom</packaging>
+
+ <modules>
+ <module>broker-ejb</module>
+ </modules>
+</project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>test-project</groupId>
+ <artifactId>test-project</artifactId>
+ <version>2.4.4</version>
+ </parent>
+ <groupId>test-project</groupId>
+ <artifactId>test-project-common</artifactId>
+ <name>Test Project Commons</name>
+ <dependencies>
+ <dependency>
+ <groupId>test-project</groupId>
+ <artifactId>test-project-api</artifactId>
+ <version>${pom.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-id</groupId>
+ <artifactId>commons-id</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-discovery</groupId>
+ <artifactId>commons-discovery</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-collections</groupId>
+ <artifactId>commons-collections</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-httpclient</groupId>
+ <artifactId>commons-httpclient</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>stax</groupId>
+ <artifactId>stax-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.woodstox</groupId>
+ <artifactId>wstx-asl</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.castor</groupId>
+ <artifactId>castor</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>xerces</groupId>
+ <artifactId>xerces</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.activation</groupId>
+ <artifactId>activation</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.jms</groupId>
+ <artifactId>jms</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.ejb</groupId>
+ <artifactId>ejb</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.mail</groupId>
+ <artifactId>mail</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.management</groupId>
+ <artifactId>jmxri</artifactId>
+ </dependency>
+ </dependencies>
+
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-source-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>test-jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>test-project</groupId>
+ <artifactId>test-project-endpoint-pom</artifactId>
+ <version>2.4.4</version>
+ </parent>
+ <groupId>test-project</groupId>
+ <artifactId>test-project-endpoint-ejb</artifactId>
+ <name>Test Project Endpoint EJB</name>
+ <packaging>ejb</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>test-project</groupId>
+ <artifactId>test-project-common</artifactId>
+ <version>${pom.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>test-project</groupId>
+ <artifactId>test-project-api</artifactId>
+ <version>${pom.version}</version>
+ </dependency>
+ <dependency>
+ <!-- for tests only -->
+ <groupId>test-project</groupId>
+ <artifactId>test-project-common</artifactId>
+ <version>${pom.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>commons-id</groupId>
+ <artifactId>commons-id</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-discovery</groupId>
+ <artifactId>commons-discovery</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.jms</groupId>
+ <artifactId>jms</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.activation</groupId>
+ <artifactId>activation</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.mail</groupId>
+ <artifactId>mail</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>xml-apis</groupId>
+ <artifactId>xml-apis</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.management</groupId>
+ <artifactId>jmxri</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ </dependency>
+ </dependencies>
+
+</project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>test-project</groupId>
+ <artifactId>test-project</artifactId>
+ <version>2.4.4</version>
+ </parent>
+ <artifactId>test-project-endpoint-pom</artifactId>
+ <name>Test Project Endpoint POM</name>
+ <packaging>pom</packaging>
+
+ <modules>
+ <module>endpoint-ejb</module>
+ </modules>
+</project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>test-project</groupId>
+ <artifactId>test-project</artifactId>
+ <name>Test Project</name>
+ <version>2.4.4</version>
+ <packaging>pom</packaging>
+
+ <organization>
+ <name>Company</name>
+ <url>http://www.company.com/</url>
+ </organization>
+ <inceptionYear>2002</inceptionYear>
+
+ <modules>
+ <module>api</module>
+ <module>common</module>
+ <module>broker</module>
+ <module>endpoint</module>
+ </modules>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <dependencyManagement>
+ <dependencies>
+ <!-- common version strategy -->
+ <dependency>
+ <groupId>javax.activation</groupId>
+ <artifactId>activation</artifactId>
+ <version>1.0.2</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.jms</groupId>
+ <artifactId>jms</artifactId>
+ <version>1.0.2</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.ejb</groupId>
+ <artifactId>ejb</artifactId>
+ <version>2.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ <version>2.4</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.mail</groupId>
+ <artifactId>mail</artifactId>
+ <version>1.4</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>xml-apis</groupId>
+ <artifactId>xml-apis</artifactId>
+ <version>2.0.2</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ <version>1.0.4</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <version>2.1</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-collections</groupId>
+ <artifactId>commons-collections</artifactId>
+ <version>3.2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring</artifactId>
+ <version>2.0.7</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-mock</artifactId>
+ <version>2.0.7</version>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-jdbc</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-web</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <version>1.2.8</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-discovery</groupId>
+ <artifactId>commons-discovery</artifactId>
+ <version>0.2</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-id</groupId>
+ <artifactId>commons-id</artifactId>
+ <version>0.1-dev</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.castor</groupId>
+ <artifactId>castor</artifactId>
+ <version>1.0.5-xml</version>
+ </dependency>
+ <dependency>
+ <groupId>xerces</groupId>
+ <artifactId>xerces</artifactId>
+ <version>2.4.0</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-httpclient</groupId>
+ <artifactId>commons-httpclient</artifactId>
+ <version>3.1</version>
+ </dependency>
+ <dependency>
+ <groupId>stax</groupId>
+ <artifactId>stax-api</artifactId>
+ <version>1.0.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.woodstox</groupId>
+ <artifactId>wstx-asl</artifactId>
+ <version>3.2.1</version>
+ </dependency>
+ <dependency>
+ <groupId>com.thoughtworks.xstream</groupId>
+ <artifactId>xstream</artifactId>
+ <version>1.2.2</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.management</groupId>
+ <artifactId>jmxri</artifactId>
+ <version>1.2.1</version>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+</project>
protected Object[] params;
protected int[] range;
+
+ protected String sortDirection = Constraint.ASCENDING;
public String getFilter()
{
public String getSortDirection()
{
- return Constraint.ASCENDING;
+ return sortDirection;
}
public String[] getVariables()
params = new Object[] { repoId };
}
- public ArtifactsByRepositoryConstraint( String repoId, Date targetWhenGathered, String sortColumn )
+ public ArtifactsByRepositoryConstraint( String repoId, Date targetWhenGathered, String sortColumn, boolean isBefore )
{
+ String condition = isBefore ? "<=" : ">=";
+
declImports = new String[] { "import java.util.Date" };
- whereClause = "this.repositoryId == repoId && this.whenGathered >= targetWhenGathered";
+ whereClause = "this.repositoryId == repoId && this.whenGathered " + condition + " targetWhenGathered";
declParams = new String[] { "String repoId", "Date targetWhenGathered" };
params = new Object[] { repoId, targetWhenGathered };
this.sortColumn = sortColumn;
}
+
+ public ArtifactsByRepositoryConstraint( String repoId, String type, Date before, String sortColumn )
+ {
+ declImports = new String[] { "import java.util.Date" };
+ whereClause =
+ "this.repositoryId == repoId && this.type == type && this.whenGathered <= before";
+ declParams = new String[] { "String repoId", "String type", "Date before" };
+ params = new Object[] { repoId, type, before };
+ this.sortColumn = sortColumn;
+ }
public String getSortColumn()
{
package org.apache.maven.archiva.database.constraints;
+import java.util.Date;
+
+import org.apache.maven.archiva.database.Constraint;
+
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
declParams = new String[] { "String repoId" };
params = new Object[] { repoId };
}
+
+ public RepositoryContentStatisticsByRepositoryConstraint( String repoId, Date startDate, Date endDate )
+ {
+ declImports = new String[] { "import java.util.Date" };
+ whereClause = "repositoryId == repoId && whenGathered >= startDate && whenGathered <= endDate";
+ declParams = new String[] { "String repoId", "Date startDate", "Date endDate" };
+ params = new Object[] { repoId, startDate, endDate };
+
+ sortDirection = Constraint.DESCENDING;
+ }
public String getSortColumn()
{
implements Constraint
{
private StringBuffer sql = new StringBuffer();
-
+
+ private Class resultClass;
+
/**
* Obtain a set of unique ArtifactIds for the specified groupId.
*
*/
public UniqueArtifactIdConstraint( List<String> selectedRepositoryIds, String groupId )
{
- appendSelect( sql );
+ appendSelect( sql, false );
sql.append( " WHERE " );
SqlBuilder.appendWhereSelectedRepositories( sql, "repositoryId", selectedRepositoryIds );
sql.append( " && " );
*/
public UniqueArtifactIdConstraint( String groupId )
{
- appendSelect( sql );
+ appendSelect( sql, false );
sql.append( " WHERE " );
appendWhereSelectedGroupId( sql );
appendGroupBy( sql );
super.params = new Object[] { groupId };
}
+
+ /**
+ * Obtain a set of unique artifactIds with respect to their groups from the specified repository.
+ *
+ * @param repoId
+ * @param isUnique
+ */
+ public UniqueArtifactIdConstraint( String repoId, boolean isUnique )
+ {
+ appendSelect( sql, isUnique );
+ sql.append( " WHERE repositoryId == \"" + repoId + "\"" );
+
+ resultClass = Object[].class;
+ }
@SuppressWarnings("unchecked")
public Class getResultClass()
{
+ if( resultClass != null )
+ {
+ return resultClass;
+ }
+
return String.class;
}
buf.append( " GROUP BY artifactId ORDER BY artifactId ASCENDING" );
}
- private void appendSelect( StringBuffer buf )
+ private void appendSelect( StringBuffer buf, boolean isUnique )
{
- buf.append( "SELECT artifactId FROM " ).append( ArchivaArtifactModel.class.getName() );
+ if( isUnique )
+ {
+ buf.append( "SELECT DISTINCT groupId, artifactId FROM " ).append( ArchivaArtifactModel.class.getName() );
+ }
+ else
+ {
+ buf.append( "SELECT artifactId FROM " ).append( ArchivaArtifactModel.class.getName() );
+ }
}
private void appendWhereSelectedGroupId( StringBuffer buf )
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.ArchivaModelCloner;
import org.apache.maven.archiva.model.ArchivaProjectModel;
import org.apache.maven.archiva.model.VersionedReference;
import org.apache.maven.archiva.repository.project.ProjectModelException;
return;
}
- model.setOrigin( "filesystem" );
+ // Clone model, since DAO while detachingCopy resets contents of the model
+ // this changes behaviour of EffectiveProjectModelFilter
+ model = ArchivaModelCloner.clone( model );
try
{
public class ArtifactsByRepositoryConstraintTest
extends AbstractArchivaDatabaseTestCase
{
- private ArtifactDAO artifactDao;
+ private ArtifactDAO artifactDao;
public void setUp()
throws Exception
{
- super.setUp();
+ super.setUp();
ArchivaDAO dao = (ArchivaDAO) lookup( ArchivaDAO.ROLE, "jdo" );
artifactDao = dao.getArtifactDAO();
}
- private ArchivaArtifact createArtifact( String groupId, String artifactId, String version )
+ private ArchivaArtifact createArtifact( String groupId, String artifactId, String version, String type )
{
- ArchivaArtifact artifact = artifactDao.createArtifact( groupId, artifactId, version, null, "jar" );
+ ArchivaArtifact artifact = artifactDao.createArtifact( groupId, artifactId, version, null, type );
artifact.getModel().setLastModified( new Date() );
artifact.getModel().setRepositoryId( "test-repo" );
Date whenGathered = Calendar.getInstance().getTime();
whenGathered.setTime( 123456789 );
- ArchivaArtifact artifact = createArtifact( "org.apache.archiva", "artifact-one", "1.0" );
+ ArchivaArtifact artifact = createArtifact( "org.apache.archiva", "artifact-one", "1.0", "jar" );
artifact.getModel().setWhenGathered( whenGathered );
artifactDao.saveArtifact( artifact );
- artifact = createArtifact( "org.apache.archiva", "artifact-one", "1.0.1" );
+ artifact = createArtifact( "org.apache.archiva", "artifact-one", "1.0.1", "jar" );
artifact.getModel().setWhenGathered( whenGathered );
artifactDao.saveArtifact( artifact );
- artifact = createArtifact( "org.apache.archiva", "artifact-two", "1.0.2" );
+ artifact = createArtifact( "org.apache.archiva", "artifact-two", "1.0.2", "jar" );
artifact.getModel().setWhenGathered( whenGathered );
artifactDao.saveArtifact( artifact );
- artifact = createArtifact( "org.apache.archiva", "artifact-one", "2.0" );
+ artifact = createArtifact( "org.apache.archiva", "artifact-one", "2.0", "jar" );
artifact.getModel().setRepositoryId( "different-repo" );
artifact.getModel().setWhenGathered( whenGathered );
artifactDao.saveArtifact( artifact );
{
Date whenGathered = Calendar.getInstance().getTime();
- ArchivaArtifact artifact = createArtifact( "org.apache.archiva", "artifact-one", "1.0" );
+ ArchivaArtifact artifact = createArtifact( "org.apache.archiva", "artifact-one", "1.0", "jar" );
artifact.getModel().setWhenGathered( whenGathered );
artifactDao.saveArtifact( artifact );
- artifact = createArtifact( "org.apache.archiva", "artifact-one", "1.0.1" );
+ artifact = createArtifact( "org.apache.archiva", "artifact-one", "1.0.1", "jar" );
artifact.getModel().setWhenGathered( whenGathered );
artifactDao.saveArtifact( artifact );
- artifact = createArtifact( "org.apache.archiva", "artifact-one", "1.0.2" );
+ artifact = createArtifact( "org.apache.archiva", "artifact-one", "1.0.2", "jar" );
artifact.getModel().setWhenGathered( whenGathered );
artifactDao.saveArtifact( artifact );
- artifact = createArtifact( "org.apache.archiva", "artifact-one", "2.0" );
+ artifact = createArtifact( "org.apache.archiva", "artifact-one", "2.0", "jar" );
artifact.getModel().setRepositoryId( "different-repo" );
artifact.getModel().setWhenGathered( whenGathered );
artifactDao.saveArtifact( artifact );
Date olderWhenGathered = Calendar.getInstance().getTime();
olderWhenGathered.setTime( 123456789 );
- artifact = createArtifact( "org.apache.archiva", "artifact-two", "1.1-SNAPSHOT" );
+ artifact = createArtifact( "org.apache.archiva", "artifact-two", "1.1-SNAPSHOT", "jar" );
artifact.getModel().setWhenGathered( olderWhenGathered );
artifactDao.saveArtifact( artifact );
- artifact = createArtifact( "org.apache.archiva", "artifact-three", "2.0-beta-1" );
+ artifact = createArtifact( "org.apache.archiva", "artifact-three", "2.0-beta-1", "jar" );
artifact.getModel().setWhenGathered( whenGathered );
artifactDao.saveArtifact( artifact );
assertConstraint( "Artifacts By Repository and When Gathered", 4,
- new ArtifactsByRepositoryConstraint( "test-repo", whenGathered, "repositoryId" ) );
+ new ArtifactsByRepositoryConstraint( "test-repo", whenGathered, "repositoryId", false ) );
}
+
+ public void testQueryArtifactsInRepoByType()
+ throws Exception
+ {
+ Calendar cal = Calendar.getInstance();
+ cal.set( 2008, 9, 1 );
+ Date whenGathered = cal.getTime();
+
+ ArchivaArtifact artifact = createArtifact( "org.apache.archiva", "artifact-one", "1.0", "jar" );
+ artifact.getModel().setWhenGathered( whenGathered );
+ artifactDao.saveArtifact( artifact );
+
+ artifact = createArtifact( "org.apache.archiva", "artifact-one", "1.0.1", "jar" );
+ artifact.getModel().setWhenGathered( whenGathered );
+ artifactDao.saveArtifact( artifact );
+
+ artifact = createArtifact( "org.apache.archiva", "artifact-one", "1.0.2", "jar" );
+ artifact.getModel().setWhenGathered( whenGathered );
+ artifactDao.saveArtifact( artifact );
+
+ artifact = createArtifact( "org.apache.archiva", "artifact-two", "1.1-SNAPSHOT", "war" );
+ artifact.getModel().setWhenGathered( whenGathered );
+ artifactDao.saveArtifact( artifact );
+
+ artifact = createArtifact( "org.apache.archiva", "artifact-three", "2.0-beta-1", "war" );
+ artifact.getModel().setWhenGathered( whenGathered );
+ artifactDao.saveArtifact( artifact );
+ Calendar cal2 = Calendar.getInstance();
+ cal2.set( 2008, 12, 12 );
+ Date diffWhenGathered = cal2.getTime();
+
+ artifact = createArtifact( "org.apache.archiva", "artifact-one", "2.0", "jar" );
+ artifact.getModel().setWhenGathered( diffWhenGathered );
+ artifactDao.saveArtifact( artifact );
+
+ cal2 = Calendar.getInstance();
+ cal2.set( 2008, 10, 30 );
+ Date before = cal2.getTime();
+
+ assertConstraint( "Artifacts of Type 'jar' By Repository and When Gathered", 3,
+ new ArtifactsByRepositoryConstraint( "test-repo", "jar", before, "whenGathered" ) );
+ assertConstraint( "Artifacts of Type 'war' By Repository and When Gathered", 2,
+ new ArtifactsByRepositoryConstraint( "test-repo", "war", before, "whenGathered" ) );
+ }
+
private void assertConstraint( String msg, int count, ArtifactsByRepositoryConstraint constraint )
throws Exception
{
* @version
*/
public class RepositoryContentStatisticsByRepositoryConstraintTest
- extends AbstractArchivaDatabaseTestCase
+ extends AbstractArchivaDatabaseTestCase
{
private RepositoryContentStatistics createStats( String repoId, String timestamp, long duration, long totalfiles,
long newfiles )
assertEquals( "internal", ( (RepositoryContentStatistics) results.get( 2 ) ).getRepositoryId() );
assertEquals( "internal", ( (RepositoryContentStatistics) results.get( 3 ) ).getRepositoryId() );
}
+
+ public void testStatsWithDateRange()
+ throws Exception
+ {
+ Constraint constraint =
+ new RepositoryContentStatisticsByRepositoryConstraint( "internal", toDate( "2007/10/18 8:00:00" ),
+ toDate( "2007/10/20 8:00:00" ) );
+ List results = dao.getRepositoryContentStatisticsDAO().queryRepositoryContentStatistics( constraint );
+ assertNotNull( "Stats: results (not null)", results );
+ assertEquals( "Stats: results.size", 3, results.size() );
+
+ assertEquals( "internal", ( (RepositoryContentStatistics) results.get( 0 ) ).getRepositoryId() );
+ assertEquals( toDate( "2007/10/20 8:00:00" ),
+ ( (RepositoryContentStatistics) results.get( 0 ) ).getWhenGathered() );
+
+ assertEquals( "internal", ( (RepositoryContentStatistics) results.get( 1 ) ).getRepositoryId() );
+ assertEquals( toDate( "2007/10/19 8:00:00" ),
+ ( (RepositoryContentStatistics) results.get( 1 ) ).getWhenGathered() );
+
+ assertEquals( "internal", ( (RepositoryContentStatistics) results.get( 2 ) ).getRepositoryId() );
+ assertEquals( toDate( "2007/10/18 8:00:00" ),
+ ( (RepositoryContentStatistics) results.get( 2 ) ).getWhenGathered() );
+ }
}
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.ArchivaDatabaseException;
import org.apache.maven.archiva.database.ArtifactDAO;
import org.apache.maven.archiva.database.SimpleConstraint;
import org.apache.maven.archiva.model.ArchivaArtifact;
public void testConstraint()
throws Exception
{
- ArchivaArtifact artifact;
+ setUpArtifacts();
- // Setup artifacts in fresh DB.
+ 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" ) );
+ }
+
+ public void testConstraintDisregardGroupId()
+ throws Exception
+ {
+ setUpArtifacts();
+
+ assertConstraintWithMultipleResultTypes( new String[] { "commons-lang", "test-one", "test-two", "test-two", "test-bar", "modellong" },
+ new UniqueArtifactIdConstraint( "testable_repo", true ) );
+ }
+
+ private void setUpArtifacts()
+ throws ArchivaDatabaseException
+ {
+ ArchivaArtifact artifact;
+
+ // Setup artifacts in fresh DB.
artifact = createArtifact( "commons-lang", "commons-lang", "2.0" );
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 assertConstraintWithMultipleResultTypes( String[] artifactIds, SimpleConstraint constraint )
+ throws Exception
+ {
+ String prefix = "Unique Artifact IDs: ";
+
+ List<Object[]> results = dao.query( constraint );
+ assertNotNull( prefix + "Not Null", results );
+ assertEquals( prefix + "Results.size", artifactIds.length, results.size() );
+
+ List<String> expectedArtifactIds = Arrays.asList( artifactIds );
+
+ Iterator<Object[]> it = results.iterator();
+ while ( it.hasNext() )
+ {
+ Object[] actualArtifactIds = (Object[]) it.next();
+ String actualArtifactId = ( String ) actualArtifactIds[1];
+ assertTrue( prefix + "artifactId result should not be blank.", StringUtils.isNotBlank( actualArtifactId ) );
+ assertTrue( prefix + " artifactId result <" + actualArtifactId + "> exists in expected artifactIds.",
+ expectedArtifactIds.contains( actualArtifactId ) );
+ }
+ }
+
private void assertConstraint( String[] artifactIds, SimpleConstraint constraint )
{
String prefix = "Unique Artifact IDs: ";
- List results = dao.query( constraint );
+ List<String> results = dao.query( constraint );
assertNotNull( prefix + "Not Null", results );
assertEquals( prefix + "Results.size", artifactIds.length, results.size() );
- List expectedArtifactIds = Arrays.asList( artifactIds );
+ List<String> expectedArtifactIds = Arrays.asList( artifactIds );
- Iterator it = results.iterator();
+ Iterator<String> it = results.iterator();
while ( it.hasNext() )
{
String actualArtifactId = (String) it.next();
assertConstraint( new String[] { "org.codehaus.modello", "org.codehaus.mojo", "org.apache.archiva" },
new UniqueGroupIdConstraint( observableRepositories ) );
- }
-
+ }
+
private void assertConstraint( String[] expectedGroupIds, SimpleConstraint constraint )
throws Exception
{
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-spring</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
</build>
--- /dev/null
+package org.apache.maven.archiva.reporting;
+
+/*
+ * 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.
+ */
+
+/**
+ * ArchivaReportException
+ *
+ * @author <a href="mailto:oching@apache.org">Maria Odea Ching</a>
+ * @version $Id: ArchivaReportException.java
+ */
+public class ArchivaReportException
+ extends Exception
+{
+ public ArchivaReportException( String message, Throwable cause )
+ {
+ super( message, cause );
+ }
+
+ public ArchivaReportException( String message )
+ {
+ super( message );
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.reporting;
+
+import java.util.Date;
+
+/*
+ * 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.
+ */
+
+/**
+ * RepositoryStatistics
+ *
+ * @author <a href="mailto:oching@apache.org">Maria Odea Ching</a>
+ */
+public class RepositoryStatistics
+{
+ private String repositoryId;
+
+ private long fileCount = 0;
+
+ private long totalSize = 0;
+
+ private long projectCount = 0;
+
+ private long groupCount = 0;
+
+ private long artifactCount = 0;
+
+ private long pluginCount = 0;
+
+ private long archetypeCount = 0;
+
+ private long jarCount = 0;
+
+ private long warCount = 0;
+
+ private long earCount = 0;
+
+ private long dllCount = 0;
+
+ private long exeCount = 0;
+
+ private long pomCount = 0;
+
+ private long deploymentCount = 0;
+
+ private long downloadCount = 0;
+
+ private Date dateOfScan;
+
+ public String getRepositoryId()
+ {
+ return repositoryId;
+ }
+
+ public void setRepositoryId( String repositoryId )
+ {
+ this.repositoryId = repositoryId;
+ }
+
+ public long getFileCount()
+ {
+ return fileCount;
+ }
+
+ public void setFileCount( long fileCount )
+ {
+ this.fileCount = fileCount;
+ }
+
+ public long getTotalSize()
+ {
+ return totalSize;
+ }
+
+ public void setTotalSize( long totalSize )
+ {
+ this.totalSize = totalSize;
+ }
+
+ public long getProjectCount()
+ {
+ return projectCount;
+ }
+
+ public void setProjectCount( long projectCount )
+ {
+ this.projectCount = projectCount;
+ }
+
+ public long getGroupCount()
+ {
+ return groupCount;
+ }
+
+ public void setGroupCount( long groupCount )
+ {
+ this.groupCount = groupCount;
+ }
+
+ public long getArtifactCount()
+ {
+ return artifactCount;
+ }
+
+ public void setArtifactCount( long artifactCount )
+ {
+ this.artifactCount = artifactCount;
+ }
+
+ public long getPluginCount()
+ {
+ return pluginCount;
+ }
+
+ public void setPluginCount( long pluginCount )
+ {
+ this.pluginCount = pluginCount;
+ }
+
+ public long getArchetypeCount()
+ {
+ return archetypeCount;
+ }
+
+ public void setArchetypeCount( long archetypeCount )
+ {
+ this.archetypeCount = archetypeCount;
+ }
+
+ public long getJarCount()
+ {
+ return jarCount;
+ }
+
+ public void setJarCount( long jarCount )
+ {
+ this.jarCount = jarCount;
+ }
+
+ public long getWarCount()
+ {
+ return warCount;
+ }
+
+ public void setWarCount( long warCount )
+ {
+ this.warCount = warCount;
+ }
+
+ public long getEarCount()
+ {
+ return earCount;
+ }
+
+ public void setEarCount( long earCount )
+ {
+ this.earCount = earCount;
+ }
+
+ public long getDllCount()
+ {
+ return dllCount;
+ }
+
+ public void setDllCount( long dllCount )
+ {
+ this.dllCount = dllCount;
+ }
+
+ public long getExeCount()
+ {
+ return exeCount;
+ }
+
+ public void setExeCount( long exeCount )
+ {
+ this.exeCount = exeCount;
+ }
+
+ public long getPomCount()
+ {
+ return pomCount;
+ }
+
+ public void setPomCount( long pomCount )
+ {
+ this.pomCount = pomCount;
+ }
+
+ public long getDeploymentCount()
+ {
+ return deploymentCount;
+ }
+
+ public void setDeploymentCount( long deploymentCount )
+ {
+ this.deploymentCount = deploymentCount;
+ }
+
+ public long getDownloadCount()
+ {
+ return downloadCount;
+ }
+
+ public void setDownloadCount( long downloadCount )
+ {
+ this.downloadCount = downloadCount;
+ }
+
+ public Date getDateOfScan()
+ {
+ return dateOfScan;
+ }
+
+ public void setDateOfScan( Date dateOfScan )
+ {
+ this.dateOfScan = dateOfScan;
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.reporting;
+
+/*
+ * 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.Date;
+import java.util.List;
+
+import org.apache.maven.archiva.model.RepositoryContentStatistics;
+
+/**
+ * RepositoryStatisticsReportGenerator
+ *
+ * @author <a href="mailto:oching@apache.org">Maria Odea Ching</a>
+ * @version $Id: RepositoryStatisticsReportGenerator.java
+ */
+public interface RepositoryStatisticsReportGenerator
+{
+ public static final String JAR_TYPE = "jar";
+
+ public static final String WAR_TYPE = "war";
+
+ public static final String POM_TYPE = "pom";
+
+ public static final String MAVEN_PLUGIN = "maven-plugin";
+
+ public static final String ARCHETYPE = "archetype";
+
+ public List<RepositoryStatistics> generateReport( List<RepositoryContentStatistics> repoContentStats, String repository, Date startDate, Date endDate, DataLimits limits )
+ throws ArchivaReportException;
+
+ public List<RepositoryStatistics> generateReport( List<RepositoryContentStatistics> repoContentStats, String repository, Date startDate, Date endDate )
+ throws ArchivaReportException;
+}
--- /dev/null
+package org.apache.maven.archiva.reporting;
+
+/*
+ * 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.Date;
+import java.util.List;
+
+import org.apache.maven.archiva.database.ArchivaDAO;
+import org.apache.maven.archiva.database.ArchivaDatabaseException;
+import org.apache.maven.archiva.database.ArtifactDAO;
+import org.apache.maven.archiva.database.constraints.ArtifactsByRepositoryConstraint;
+import org.apache.maven.archiva.model.RepositoryContentStatistics;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * SimpleRepositoryStatisticsReportGenerator
+ *
+ * @author <a href="mailto:oching@apache.org">Maria Odea Ching</a>
+ * @version $Id: SimpleRepositoryStatisticsReportGenerator.java
+ *
+ * @plexus.component role="org.apache.maven.archiva.reporting.RepositoryStatisticsReportGenerator" role-hint="simple"
+ */
+public class SimpleRepositoryStatisticsReportGenerator
+ implements RepositoryStatisticsReportGenerator
+{
+ private Logger log = LoggerFactory.getLogger( SimpleRepositoryStatisticsReportGenerator.class );
+
+ /**
+ * @plexus.requirement role-hint="jdo"
+ */
+ private ArchivaDAO dao;
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.apache.maven.archiva.reporting.RepositoryStatisticsReportGenerator#generateReport(java.util.List
+ * repoContentStats, java.util.String repository, java.util.Date startDate, java.util.Date endDate,
+ * org.apache.maven.archiva.reporting.DataLimits limits )
+ */
+ public List<RepositoryStatistics> generateReport( List<RepositoryContentStatistics> repoContentStats,
+ String repository, Date startDate, Date endDate, DataLimits limits )
+ throws ArchivaReportException
+ {
+ if( limits.getCurrentPage() > limits.getCountOfPages() )
+ {
+ throw new ArchivaReportException( "The requested page exceeds the total number of pages." );
+ }
+
+ int start = ( limits.getPerPageCount() * limits.getCurrentPage() ) - limits.getPerPageCount();
+ int end = ( start + limits.getPerPageCount() ) - 1;
+
+ if( end > repoContentStats.size() )
+ {
+ end = repoContentStats.size() - 1;
+ }
+
+ return constructRepositoryStatistics( repoContentStats, repository, endDate, start, end );
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.apache.maven.archiva.reporting.RepositoryStatisticsReportGenerator#generateReport(java.util.List
+ * repoContentStats, java.util.String repository, java.util.Date startDate, java.util.Date endDate)
+ */
+ public List<RepositoryStatistics> generateReport( List<RepositoryContentStatistics> repoContentStats, String repository, Date startDate, Date endDate )
+ throws ArchivaReportException
+ {
+ return constructRepositoryStatistics( repoContentStats, repository, endDate, 0, repoContentStats.size() - 1 );
+ }
+
+ private List<RepositoryStatistics> constructRepositoryStatistics(
+ List<RepositoryContentStatistics> repoContentStats,
+ String repository, Date endDate,
+ int start, int end )
+ {
+ ArtifactDAO artifactDao = dao.getArtifactDAO();
+
+ List<RepositoryStatistics> repoStatisticsList = new ArrayList<RepositoryStatistics>();
+ for( int i = start; i <= end; i++ )
+ {
+ RepositoryContentStatistics repoContentStat = (RepositoryContentStatistics) repoContentStats.get( i );
+ RepositoryStatistics repoStatistics = new RepositoryStatistics();
+ repoStatistics.setRepositoryId( repository );
+
+ // get only the latest
+ repoStatistics.setArtifactCount( repoContentStat.getTotalArtifactCount() );
+ repoStatistics.setGroupCount( repoContentStat.getTotalGroupCount() );
+ repoStatistics.setProjectCount( repoContentStat.getTotalProjectCount() );
+ repoStatistics.setTotalSize( repoContentStat.getTotalSize() );
+ repoStatistics.setFileCount( repoContentStat.getTotalFileCount() );
+ repoStatistics.setDateOfScan( repoContentStat.getWhenGathered() );
+
+ try
+ {
+ //TODO use the repo content stats whenGathered date instead of endDate for single repo reports
+ List types = artifactDao.queryArtifacts(
+ new ArtifactsByRepositoryConstraint( repository, JAR_TYPE, endDate, "whenGathered" ) );
+ repoStatistics.setJarCount( types.size() );
+
+ types = artifactDao.queryArtifacts(
+ new ArtifactsByRepositoryConstraint( repository, WAR_TYPE, endDate, "whenGathered" ) );
+ repoStatistics.setWarCount( types.size() );
+
+ types = artifactDao.queryArtifacts(
+ new ArtifactsByRepositoryConstraint( repository, MAVEN_PLUGIN, endDate, "whenGathered" ) );
+ repoStatistics.setPluginCount( types.size() );
+
+ // TODO: must need to be able to track archetypes. possible way of identifying an
+ // archetype is by checking if archetype.xml exists in src/main/resources/META-INF/
+
+ }
+ catch( ArchivaDatabaseException e )
+ {
+ log.error( "Error occurred while querying artifacts from the database.", e.getMessage() );
+ }
+
+ repoStatisticsList.add( repoStatistics );
+ }
+
+ return repoStatisticsList;
+ }
+
+ public void setDao( ArchivaDAO dao )
+ {
+ this.dao = dao;
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.reporting;
+
+/*
+ * 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.Calendar;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.maven.archiva.database.ArchivaDAO;
+import org.apache.maven.archiva.database.ArtifactDAO;
+import org.apache.maven.archiva.database.constraints.ArtifactsByRepositoryConstraint;
+import org.apache.maven.archiva.model.ArchivaArtifact;
+import org.apache.maven.archiva.model.RepositoryContentStatistics;
+import org.codehaus.plexus.spring.PlexusInSpringTestCase;
+import org.easymock.MockControl;
+import org.easymock.internal.AlwaysMatcher;
+
+/**
+ * SimpleRepositoryStatisticsReportGeneratorTest
+ *
+ * @author <a href="mailto:oching@apache.org">Maria Odea Ching</a>
+ * @version $Id: SimpleRepositoryStatisticsReportGenerator.java
+ *
+ * @plexus.component role="org.apache.maven.archiva.reporting.RepositoryStatisticsReportGenerator" role-hint="simple"
+ */
+public class SimpleRepositoryStatisticsReportGeneratorTest
+ extends PlexusInSpringTestCase
+{
+ private MockControl daoControl;
+
+ private ArchivaDAO dao;
+
+ private MockControl artifactDaoControl;
+
+ private ArtifactDAO artifactDao;
+
+ private SimpleRepositoryStatisticsReportGenerator generator;
+
+ private static final String REPO = "test-repo";
+
+ public void setUp()
+ throws Exception
+ {
+ super.setUp();
+
+ daoControl = MockControl.createControl( ArchivaDAO.class );
+ dao = ( ArchivaDAO ) daoControl.getMock();
+
+ generator = new SimpleRepositoryStatisticsReportGenerator();
+ generator.setDao( dao );
+
+ artifactDaoControl = MockControl.createControl( ArtifactDAO.class );
+ artifactDaoControl.setDefaultMatcher( new AlwaysMatcher() );
+ artifactDao = ( ArtifactDAO ) artifactDaoControl.getMock();
+ }
+
+ private Date toDate( int year, int month, int date, int hour, int min, int sec )
+ {
+ Calendar cal = Calendar.getInstance();
+ cal.clear();
+ cal.set( year, month, date, hour, min, sec );
+
+ return cal.getTime();
+ }
+
+ private List<ArchivaArtifact> createArtifacts( String type )
+ {
+ List<ArchivaArtifact> artifacts = new ArrayList<ArchivaArtifact>();
+ artifacts.add( createArtifact( REPO, "org.apache.archiva", "repository-statistics-" + type, "1.0", type ) );
+ artifacts.add( createArtifact( REPO, "org.apache.archiva", "repository-statistics-" + type, "1.1", type ) );
+ artifacts.add( createArtifact( REPO, "org.apache.archiva", "repository-statistics-" + type, "1.2", type ) );
+ artifacts.add( createArtifact( REPO, "org.apache.archiva", "repository-statistics-" + type, "2.0", type ) );
+ artifacts.add( createArtifact( REPO, "org.apache.archiva", "repository-statistics-" + type, "3.0", type ) );
+
+ return artifacts;
+ }
+
+ private ArchivaArtifact createArtifact( String repoId, String groupId, String artifactId, String version, String type )
+ {
+ ArchivaArtifact artifact = new ArchivaArtifact( groupId, artifactId, version, null, type );
+ artifact.getModel().setLastModified( new Date() );
+ artifact.getModel().setRepositoryId( repoId );
+
+ return artifact;
+ }
+
+ private RepositoryContentStatistics createRepositoryContentStatistics( Date startDate, String repositoryId )
+ {
+ RepositoryContentStatistics repoContentStats = new RepositoryContentStatistics();
+ repoContentStats.setRepositoryId( repositoryId );
+ repoContentStats.setDuration( 10000 );
+ repoContentStats.setNewFileCount( 100 );
+ repoContentStats.setTotalArtifactCount( 200 );
+ repoContentStats.setTotalFileCount( 250 );
+ repoContentStats.setTotalGroupCount( 100 );
+ repoContentStats.setTotalProjectCount( 180 );
+ repoContentStats.setTotalSize( 200000 );
+ repoContentStats.setWhenGathered( startDate );
+
+ return repoContentStats;
+ }
+
+ private List<RepositoryContentStatistics> createStatisticsHistoryForSingleRepositoryTest( String repoId )
+ {
+ List<RepositoryContentStatistics> repoContentStatsList = new ArrayList<RepositoryContentStatistics>();
+
+ repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 11, 1, 0, 0, 0 ), repoId ) );
+ repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 10, 16, 0, 0, 0 ), repoId ) );
+ repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 10, 1, 0, 0, 0 ), repoId ) );
+ repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 9, 16, 0, 0, 0 ), repoId ) );
+ repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 9, 1, 0, 0, 0 ), repoId ) );
+ repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 8, 16, 0, 0, 0 ), repoId ) );
+ repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 8, 1, 0, 0, 0 ), repoId ) );
+ repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 7, 16, 0, 0, 0 ), repoId ) );
+ repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 7, 1, 0, 0, 0 ), repoId ) );
+ repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 6, 16, 0, 0, 0 ), repoId ) );
+ repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 6, 1, 0, 0, 0 ), repoId ) );
+ repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 5, 16, 0, 0, 0 ), repoId ) );
+ repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 5, 1, 0, 0, 0 ), repoId ) );
+ repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 4, 16, 0, 0, 0 ), repoId ) );
+ repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 4, 1, 0, 0, 0 ), repoId ) );
+ repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 3, 16, 0, 0, 0 ), repoId ) );
+ repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 3, 1, 0, 0, 0 ), repoId ) );
+ repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 2, 16, 0, 0, 0 ), repoId ) );
+ repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 2, 1, 0, 0, 0 ), repoId ) );
+ repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 1, 16, 0, 0, 0 ), repoId ) );
+ repoContentStatsList.add( createRepositoryContentStatistics( toDate( 2008, 1, 1, 0, 0, 0 ), repoId ) );
+
+ return repoContentStatsList;
+ }
+
+ public void testSimpleReportWithPagination()
+ throws Exception
+ {
+ Date startDate = toDate( 2008, 1, 1, 0, 0, 0 );
+ Date endDate = toDate( 2008, 11, 30, 0, 0, 0 );
+
+ DataLimits limits = new DataLimits();
+ limits.setPerPageCount( 5 );
+ limits.setCurrentPage( 1 );
+ limits.setCountOfPages( 5 );
+ limits.setTotalCount( 21 );
+
+ List<ArchivaArtifact> jarArtifacts = createArtifacts( RepositoryStatisticsReportGenerator.JAR_TYPE );
+ List<ArchivaArtifact> warArtifacts = createArtifacts( RepositoryStatisticsReportGenerator.WAR_TYPE );
+ List<ArchivaArtifact> mavenPlugins = createArtifacts( RepositoryStatisticsReportGenerator.MAVEN_PLUGIN );
+
+ List<RepositoryContentStatistics> repoContentStats = createStatisticsHistoryForSingleRepositoryTest( REPO );
+
+ // get first page
+ daoControl.expectAndReturn( dao.getArtifactDAO(), artifactDao );
+
+ artifactDaoControl.expectAndReturn( artifactDao.queryArtifacts(
+ new ArtifactsByRepositoryConstraint( REPO, RepositoryStatisticsReportGenerator.JAR_TYPE, endDate, "whenGathered") ), jarArtifacts, 5 );
+
+ artifactDaoControl.expectAndReturn( artifactDao.queryArtifacts(
+ new ArtifactsByRepositoryConstraint( REPO, RepositoryStatisticsReportGenerator.WAR_TYPE, endDate, "whenGathered") ), warArtifacts, 5 );
+
+ artifactDaoControl.expectAndReturn( artifactDao.queryArtifacts(
+ new ArtifactsByRepositoryConstraint( REPO, RepositoryStatisticsReportGenerator.MAVEN_PLUGIN, endDate, "whenGathered") ), mavenPlugins, 5 );
+
+ daoControl.replay();
+ artifactDaoControl.replay();
+
+ List<RepositoryStatistics> data = generator.generateReport( repoContentStats, REPO, startDate, endDate, limits );
+
+ daoControl.verify();
+ artifactDaoControl.verify();
+
+ assertEquals( 5, data.size() );
+
+ RepositoryStatistics stats = (RepositoryStatistics) data.get( 0 );
+ assertEquals( REPO, stats.getRepositoryId() );
+ assertEquals( 200, stats.getArtifactCount() );
+ assertEquals( 5, stats.getJarCount() );
+ assertEquals( 5, stats.getWarCount() );
+ assertEquals( 5, stats.getPluginCount() );
+ assertEquals( toDate( 2008, 11, 1, 0, 0, 0 ).getTime(), stats.getDateOfScan().getTime() );
+ assertEquals( toDate( 2008, 9, 1, 0, 0, 0 ).getTime(), ( (RepositoryStatistics) data.get( 4 ) ).getDateOfScan().getTime() );
+
+ // get last page
+ limits.setCurrentPage( 5 );
+
+ daoControl.reset();
+ artifactDaoControl.reset();
+
+ artifactDaoControl.setDefaultMatcher( new AlwaysMatcher() );
+
+ daoControl.expectAndReturn( dao.getArtifactDAO(), artifactDao );
+
+ artifactDaoControl.expectAndReturn( artifactDao.queryArtifacts(
+ new ArtifactsByRepositoryConstraint( REPO, RepositoryStatisticsReportGenerator.JAR_TYPE, endDate, "whenGathered") ), jarArtifacts );
+
+ artifactDaoControl.expectAndReturn( artifactDao.queryArtifacts(
+ new ArtifactsByRepositoryConstraint( REPO, RepositoryStatisticsReportGenerator.WAR_TYPE, endDate, "whenGathered") ), warArtifacts );
+
+ artifactDaoControl.expectAndReturn( artifactDao.queryArtifacts(
+ new ArtifactsByRepositoryConstraint( REPO, RepositoryStatisticsReportGenerator.MAVEN_PLUGIN, endDate, "whenGathered") ), mavenPlugins );
+
+ daoControl.replay();
+ artifactDaoControl.replay();
+
+ data = generator.generateReport( repoContentStats, REPO, startDate, endDate, limits );
+
+ daoControl.verify();
+ artifactDaoControl.verify();
+
+ assertEquals( 1, data.size() );
+
+ stats = (RepositoryStatistics) data.get( 0 );
+ assertEquals( REPO, stats.getRepositoryId() );
+ assertEquals( 200, stats.getArtifactCount() );
+ assertEquals( 5, stats.getJarCount() );
+ assertEquals( 5, stats.getWarCount() );
+ assertEquals( 5, stats.getPluginCount() );
+ assertEquals( toDate( 2008, 1, 1, 0, 0, 0 ).getTime(), stats.getDateOfScan().getTime() );
+ }
+
+ public void testSimpleReportWithoutPagination()
+ throws Exception
+ {
+ Date startDate = toDate( 2008, 1, 1, 0, 0, 0 );
+ Date endDate = toDate( 2008, 11, 30, 0, 0, 0 );
+
+ List<ArchivaArtifact> jarArtifacts = createArtifacts( RepositoryStatisticsReportGenerator.JAR_TYPE );
+ List<ArchivaArtifact> warArtifacts = createArtifacts( RepositoryStatisticsReportGenerator.WAR_TYPE );
+ List<ArchivaArtifact> mavenPlugins = createArtifacts( RepositoryStatisticsReportGenerator.MAVEN_PLUGIN );
+
+ List<RepositoryContentStatistics> repoContentStats = createStatisticsHistoryForSingleRepositoryTest( REPO );
+
+ // get first page
+ daoControl.expectAndReturn( dao.getArtifactDAO(), artifactDao );
+
+ artifactDaoControl.expectAndReturn( artifactDao.queryArtifacts(
+ new ArtifactsByRepositoryConstraint( REPO, RepositoryStatisticsReportGenerator.JAR_TYPE, endDate, "whenGathered") ), jarArtifacts, 21 );
+
+ artifactDaoControl.expectAndReturn( artifactDao.queryArtifacts(
+ new ArtifactsByRepositoryConstraint( REPO, RepositoryStatisticsReportGenerator.WAR_TYPE, endDate, "whenGathered") ), warArtifacts, 21 );
+
+ artifactDaoControl.expectAndReturn( artifactDao.queryArtifacts(
+ new ArtifactsByRepositoryConstraint( REPO, RepositoryStatisticsReportGenerator.MAVEN_PLUGIN, endDate, "whenGathered") ), mavenPlugins, 21 );
+
+ daoControl.replay();
+ artifactDaoControl.replay();
+
+ List<RepositoryStatistics> data = generator.generateReport( repoContentStats, REPO, startDate, endDate );
+
+ daoControl.verify();
+ artifactDaoControl.verify();
+
+ assertEquals( 21, data.size() );
+
+ RepositoryStatistics stats = (RepositoryStatistics) data.get( 0 );
+ assertEquals( REPO, stats.getRepositoryId() );
+ assertEquals( 200, stats.getArtifactCount() );
+ assertEquals( 5, stats.getJarCount() );
+ assertEquals( 5, stats.getWarCount() );
+ assertEquals( 5, stats.getPluginCount() );
+ assertEquals( toDate( 2008, 11, 1, 0, 0, 0 ).getTime(), stats.getDateOfScan().getTime() );
+ assertEquals( toDate( 2008, 1, 1, 0, 0, 0 ).getTime(), ( (RepositoryStatistics) data.get( 20 ) ).getDateOfScan().getTime() );
+ }
+
+ public void testSimpleReportNoArtifactCountStatisticsAvailable()
+ throws Exception
+ {
+ Date startDate = toDate( 2008, 1, 1, 0, 0, 0 );
+ Date endDate = toDate( 2008, 11, 30, 0, 0, 0 );
+
+ DataLimits limits = new DataLimits();
+ limits.setPerPageCount( 5 );
+ limits.setCurrentPage( 1 );
+ limits.setCountOfPages( 5 );
+ limits.setTotalCount( 21 );
+
+ List<ArchivaArtifact> jarArtifacts = new ArrayList<ArchivaArtifact>();
+ List<ArchivaArtifact> warArtifacts = new ArrayList<ArchivaArtifact>();
+ List<ArchivaArtifact> mavenPlugins = new ArrayList<ArchivaArtifact>();
+
+ List<RepositoryContentStatistics> repoContentStats = createStatisticsHistoryForSingleRepositoryTest( REPO );
+
+ daoControl.expectAndReturn( dao.getArtifactDAO(), artifactDao );
+
+ artifactDaoControl.expectAndReturn( artifactDao.queryArtifacts(
+ new ArtifactsByRepositoryConstraint( REPO, RepositoryStatisticsReportGenerator.JAR_TYPE, endDate, "whenGathered") ), jarArtifacts, 5 );
+
+ artifactDaoControl.expectAndReturn( artifactDao.queryArtifacts(
+ new ArtifactsByRepositoryConstraint( REPO, RepositoryStatisticsReportGenerator.WAR_TYPE, endDate, "whenGathered") ), warArtifacts, 5 );
+
+ artifactDaoControl.expectAndReturn( artifactDao.queryArtifacts(
+ new ArtifactsByRepositoryConstraint( REPO, RepositoryStatisticsReportGenerator.MAVEN_PLUGIN, endDate, "whenGathered") ), mavenPlugins, 5 );
+
+ daoControl.replay();
+ artifactDaoControl.replay();
+
+ List<RepositoryStatistics> data = generator.generateReport( repoContentStats, REPO, startDate, endDate, limits );
+
+ daoControl.verify();
+ artifactDaoControl.verify();
+
+ assertEquals( 5, data.size() );
+
+ RepositoryStatistics stats = (RepositoryStatistics) data.get( 0 );
+ assertEquals( REPO, stats.getRepositoryId() );
+ assertEquals( 200, stats.getArtifactCount() );
+ assertEquals( 0, stats.getJarCount() );
+ assertEquals( 0, stats.getWarCount() );
+ assertEquals( 0, stats.getPluginCount() );
+ assertEquals( toDate( 2008, 11, 1, 0, 0, 0 ).getTime(), stats.getDateOfScan().getTime() );
+ assertEquals( toDate( 2008, 9, 1, 0, 0, 0 ).getTime(), ( (RepositoryStatistics) data.get( 4 ) ).getDateOfScan().getTime() );
+ // no results found when ArtifactDAO was queried
+ }
+
+ public void testSimpleReportWithPaginationInvalidRequestedPage()
+ throws Exception
+ {
+ Date startDate = toDate( 2008, 1, 1, 0, 0, 0 );
+ Date endDate = toDate( 2008, 11, 30, 0, 0, 0 );
+
+ DataLimits limits = new DataLimits();
+ limits.setPerPageCount( 5 );
+ limits.setCurrentPage( 10 );
+ limits.setCountOfPages( 5 );
+ limits.setTotalCount( 21 );
+
+ List<RepositoryContentStatistics> repoContentStats = createStatisticsHistoryForSingleRepositoryTest( REPO );
+
+ try
+ {
+ List<RepositoryStatistics> data = generator.generateReport( repoContentStats, REPO, startDate, endDate, limits );
+ fail( "An ArchivaReportException should have been thrown." );
+ }
+ catch ( ArchivaReportException a )
+ {
+
+ }
+ // requested page exceeds total number of pages
+ }
+}
*/
import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.archiva.configuration.ArchivaConfiguration;
import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
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.ArtifactsByRepositoryConstraint;
import org.apache.maven.archiva.database.constraints.MostRecentRepositoryScanStatistics;
+import org.apache.maven.archiva.database.constraints.UniqueArtifactIdConstraint;
+import org.apache.maven.archiva.database.constraints.UniqueGroupIdConstraint;
import org.apache.maven.archiva.model.RepositoryContentStatistics;
import org.apache.maven.archiva.repository.RepositoryException;
import org.apache.maven.archiva.repository.scanner.RepositoryScanStatistics;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.io.File;
+import java.util.ArrayList;
import java.util.List;
/**
log.info( "Finished repository task: " + stats.toDump( arepo ) );
- // I hate jpox and modello
- RepositoryContentStatistics dbstats = new RepositoryContentStatistics();
- dbstats.setDuration( stats.getDuration() );
- dbstats.setNewFileCount( stats.getNewFileCount() );
- dbstats.setRepositoryId( stats.getRepositoryId() );
- dbstats.setTotalFileCount( stats.getTotalFileCount() );
- dbstats.setWhenGathered( stats.getWhenGathered() );
+ RepositoryContentStatistics dbstats = constructRepositoryStatistics( arepo, sinceWhen, results, stats );
- dao.getRepositoryContentStatisticsDAO().saveRepositoryContentStatistics( dbstats );
+ dao.getRepositoryContentStatisticsDAO().saveRepositoryContentStatistics( dbstats );
}
catch ( RepositoryException e )
- {
+ {
throw new TaskExecutionException( "Repository error when executing repository job.", e );
- }
+ }
}
+
+ private RepositoryContentStatistics constructRepositoryStatistics( ManagedRepositoryConfiguration arepo,
+ long sinceWhen,
+ List<RepositoryContentStatistics> results,
+ RepositoryScanStatistics stats )
+ {
+ // I hate jpox and modello <-- and so do I
+ RepositoryContentStatistics dbstats = new RepositoryContentStatistics();
+ dbstats.setDuration( stats.getDuration() );
+ dbstats.setNewFileCount( stats.getNewFileCount() );
+ dbstats.setRepositoryId( stats.getRepositoryId() );
+ dbstats.setTotalFileCount( stats.getTotalFileCount() );
+ dbstats.setWhenGathered( stats.getWhenGathered() );
+
+ // total artifact count
+ try
+ {
+ List artifacts = dao.getArtifactDAO().queryArtifacts(
+ new ArtifactsByRepositoryConstraint( arepo.getId(), stats.getWhenGathered(), "groupId", true ) );
+ dbstats.setTotalArtifactCount( artifacts.size() );
+ }
+ catch ( ObjectNotFoundException oe )
+ {
+ log.error( "Object not found in the database : " + oe.getMessage() );
+ }
+ catch ( ArchivaDatabaseException ae )
+ {
+ log.error( "Error occurred while querying artifacts for artifact count : " + ae.getMessage() );
+ }
+
+ // total repo size
+ long size = FileUtils.sizeOfDirectory( new File( arepo.getLocation() ) );
+ dbstats.setTotalSize( size );
+
+ // total unique groups
+ List<String> repos = new ArrayList<String>();
+ repos.add( arepo.getId() );
+
+ List<String> groupIds = dao.query( new UniqueGroupIdConstraint( repos ) );
+ dbstats.setTotalGroupCount( groupIds.size() );
+
+ List<Object[]> artifactIds = dao.query( new UniqueArtifactIdConstraint( arepo.getId(), true ) );
+ dbstats.setTotalProjectCount( artifactIds.size() );
+
+ return dbstats;
+ }
}
Calendar greaterThanThisDate = Calendar.getInstance( DateUtils.UTC_TIME_ZONE );
greaterThanThisDate.add( Calendar.DATE, -( getNumberOfDaysBeforeNow() ) );
- Constraint artifactsByRepo = new ArtifactsByRepositoryConstraint( repoId, greaterThanThisDate.getTime(), "whenGathered" );
+ Constraint artifactsByRepo = new ArtifactsByRepositoryConstraint( repoId, greaterThanThisDate.getTime(), "whenGathered", false );
List<ArchivaArtifact> artifacts = artifactDAO.queryArtifacts( artifactsByRepo );
List<RssFeedEntry> entries = processData( artifacts, true );
return true;
}
- public boolean isAuthorized( String principal, String repoId )
+ public boolean isAuthorized( String principal, String repoId, boolean isWriteRequest )
throws UnauthorizedException
{
try
{
+ String permission = ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS;
+
+ if ( isWriteRequest )
+ {
+ permission = ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD;
+ }
+
User user = securitySystem.getUserManager().findUser( principal );
if ( user.isLocked() )
{
AuthenticationResult authn = new AuthenticationResult( true, principal, null );
SecuritySession securitySession = new DefaultSecuritySession( authn, user );
- return securitySystem.isAuthorized( securitySession, ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS,
- repoId );
+ return securitySystem.isAuthorized( securitySession, permission, repoId );
}
catch ( UserNotFoundException e )
{
return guest;
}
+
+ public void setGuest( String guesT )
+ {
+ guest = guesT;
+ }
}
*/
public interface ServletAuthenticator
{
+ /**
+ * Authentication check for users.
+ *
+ * @param request
+ * @param result
+ * @return
+ * @throws AuthenticationException
+ * @throws AccountLockedException
+ * @throws MustChangePasswordException
+ */
public boolean isAuthenticated( HttpServletRequest request, AuthenticationResult result )
throws AuthenticationException, AccountLockedException, MustChangePasswordException;
+ /**
+ * Authorization check for valid users.
+ *
+ * @param request
+ * @param securitySession
+ * @param repositoryId
+ * @param isWriteRequest
+ * @return
+ * @throws AuthorizationException
+ * @throws UnauthorizedException
+ */
public boolean isAuthorized( HttpServletRequest request, SecuritySession securitySession, String repositoryId,
boolean isWriteRequest ) throws AuthorizationException, UnauthorizedException;
- public boolean isAuthorized( String principal, String repoId )
+ /**
+ * Authorization check specific for user guest, which doesn't go through
+ * HttpBasicAuthentication#getAuthenticationResult( HttpServletRequest request, HttpServletResponse response )
+ * since no credentials are attached to the request.
+ *
+ * See also MRM-911
+ *
+ * @param principal
+ * @param repoId
+ * @param isWriteRequest
+ * @return
+ * @throws UnauthorizedException
+ */
+ public boolean isAuthorized( String principal, String repoId, boolean isWriteRequest )
throws UnauthorizedException;
}
--- /dev/null
+package org.apache.maven.archiva.security;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.maven.archiva.configuration.ArchivaConfiguration;
+import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
+import org.codehaus.plexus.redback.rbac.RBACManager;
+import org.codehaus.plexus.redback.role.RoleManager;
+import org.codehaus.plexus.redback.system.SecuritySystem;
+import org.codehaus.plexus.redback.users.User;
+import org.codehaus.plexus.redback.users.UserManager;
+import org.codehaus.plexus.spring.PlexusInSpringTestCase;
+
+/**
+ * AbstractSecurityTest
+ *
+ * @author <a href="mailto:oching@apache.org">Maria Odea Ching</a>
+ * @version $Id: AbstractSecurityTest
+ */
+public abstract class AbstractSecurityTest
+ extends PlexusInSpringTestCase
+{
+ protected static final String USER_GUEST = "guest";
+
+ protected static final String USER_ADMIN = "admin";
+
+ protected static final String USER_ALPACA = "alpaca";
+
+ protected SecuritySystem securitySystem;
+
+ private RBACManager rbacManager;
+
+ protected RoleManager roleManager;
+
+ private ArchivaConfiguration archivaConfiguration;
+
+ protected UserRepositories userRepos;
+
+ protected void setupRepository( String repoId )
+ throws Exception
+ {
+ // Add repo to configuration.
+ ManagedRepositoryConfiguration repoConfig = new ManagedRepositoryConfiguration();
+ repoConfig.setId( repoId );
+ repoConfig.setName( "Testable repo <" + repoId + ">" );
+ repoConfig.setLocation( getTestPath( "target/test-repo/" + repoId ) );
+ archivaConfiguration.getConfiguration().addManagedRepository( repoConfig );
+
+ // Add repo roles to security.
+ userRepos.createMissingRepositoryRoles( repoId );
+ }
+
+ protected void assignRepositoryObserverRole( String principal, String repoId )
+ throws Exception
+ {
+ roleManager.assignTemplatedRole( ArchivaRoleConstants.TEMPLATE_REPOSITORY_OBSERVER, repoId, principal );
+ }
+
+ protected User createUser( String principal, String fullname )
+ {
+ UserManager userManager = securitySystem.getUserManager();
+
+ User user = userManager.createUser( principal, fullname, principal + "@testable.archiva.apache.org" );
+ securitySystem.getPolicy().setEnabled( false );
+ userManager.addUser( user );
+ securitySystem.getPolicy().setEnabled( true );
+
+ return user;
+ }
+
+ @Override
+ public void setUp()
+ throws Exception
+ {
+ super.setUp();
+
+ File srcConfig = getTestFile( "src/test/resources/repository-archiva.xml" );
+ File destConfig = getTestFile( "target/test-conf/archiva.xml" );
+
+ destConfig.getParentFile().mkdirs();
+ destConfig.delete();
+
+ FileUtils.copyFile( srcConfig, destConfig );
+
+ securitySystem = (SecuritySystem) lookup( SecuritySystem.class, "testable" );
+ rbacManager = (RBACManager) lookup( RBACManager.class, "memory" );
+ roleManager = (RoleManager) lookup( RoleManager.class, "default" );
+ userRepos = (UserRepositories) lookup( UserRepositories.class, "default" );
+ archivaConfiguration = (ArchivaConfiguration) lookup( ArchivaConfiguration.class );
+
+ // Some basic asserts.
+ assertNotNull( securitySystem );
+ assertNotNull( rbacManager );
+ assertNotNull( roleManager );
+ assertNotNull( userRepos );
+ assertNotNull( archivaConfiguration );
+
+ // Setup Admin User.
+ User adminUser = createUser( USER_ADMIN, "Admin User" );
+ roleManager.assignRole( ArchivaRoleConstants.TEMPLATE_SYSTEM_ADMIN, adminUser.getPrincipal().toString() );
+
+ // Setup Guest User.
+ User guestUser = createUser( USER_GUEST, "Guest User" );
+ roleManager.assignRole( ArchivaRoleConstants.TEMPLATE_GUEST, guestUser.getPrincipal().toString() );
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.security;
+
+/*
+ * 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 javax.servlet.http.HttpServletRequest;
+
+import org.codehaus.plexus.redback.authentication.AuthenticationException;
+import org.codehaus.plexus.redback.authentication.AuthenticationResult;
+import org.codehaus.plexus.redback.authorization.UnauthorizedException;
+import org.codehaus.plexus.redback.system.DefaultSecuritySession;
+import org.codehaus.plexus.redback.system.SecuritySession;
+import org.codehaus.plexus.redback.users.User;
+import org.codehaus.plexus.redback.users.UserManager;
+
+import org.easymock.MockControl;
+
+/**
+ * ArchivaServletAuthenticatorTest
+ *
+ * @author <a href="mailto:oching@apache.org">Maria Odea Ching</a>
+ * @version
+ */
+public class ArchivaServletAuthenticatorTest
+ extends AbstractSecurityTest
+{
+ private ServletAuthenticator servletAuth;
+
+ private MockControl httpServletRequestControl;
+
+ private HttpServletRequest request;
+
+ @Override
+ public void setUp()
+ throws Exception
+ {
+ super.setUp();
+
+ servletAuth = ( ServletAuthenticator ) lookup( ServletAuthenticator.class, "default" );
+
+ httpServletRequestControl = MockControl.createControl( HttpServletRequest.class );
+ request = ( HttpServletRequest ) httpServletRequestControl.getMock();
+
+ setupRepository( "corporate" );
+ }
+
+ @Override
+ protected String getPlexusConfigLocation()
+ {
+ return "org/apache/maven/archiva/security/ArchivaServletAuthenticatorTest.xml";
+ }
+
+ protected void assignRepositoryManagerRole( String principal, String repoId )
+ throws Exception
+ {
+ roleManager.assignTemplatedRole( ArchivaRoleConstants.TEMPLATE_REPOSITORY_MANAGER, repoId, principal );
+ }
+
+ public void testIsAuthenticatedUserExists()
+ throws Exception
+ {
+ AuthenticationResult result = new AuthenticationResult( true, "user", null );
+ boolean isAuthenticated = servletAuth.isAuthenticated( request, result );
+
+ assertTrue( isAuthenticated );
+ }
+
+ public void testIsAuthenticatedUserDoesNotExist()
+ throws Exception
+ {
+ AuthenticationResult result = new AuthenticationResult( false, "non-existing-user", null );
+ try
+ {
+ servletAuth.isAuthenticated( request, result );
+ fail( "Authentication exception should have been thrown." );
+ }
+ catch ( AuthenticationException e )
+ {
+ assertEquals( "User Credentials Invalid", e.getMessage() );
+ }
+ }
+
+ public void testIsAuthorizedUserHasWriteAccess()
+ throws Exception
+ {
+ createUser( USER_ALPACA, "Al 'Archiva' Paca" );
+
+ assignRepositoryManagerRole( USER_ALPACA, "corporate" );
+
+ UserManager userManager = securitySystem.getUserManager();
+ User user = userManager.findUser( USER_ALPACA );
+
+ AuthenticationResult result = new AuthenticationResult( true, USER_ALPACA, null );
+
+ SecuritySession session = new DefaultSecuritySession( result, user );
+ boolean isAuthorized = servletAuth.isAuthorized( request, session, "corporate", true );
+
+ assertTrue( isAuthorized );
+ }
+
+ public void testIsAuthorizedUserHasNoWriteAccess()
+ throws Exception
+ {
+ createUser( USER_ALPACA, "Al 'Archiva' Paca" );
+
+ assignRepositoryObserverRole( USER_ALPACA, "corporate" );
+
+ httpServletRequestControl.expectAndReturn( request.getRemoteAddr(), "192.168.111.111" );
+
+ UserManager userManager = securitySystem.getUserManager();
+ User user = userManager.findUser( USER_ALPACA );
+
+ AuthenticationResult result = new AuthenticationResult( true, USER_ALPACA, null );
+
+ SecuritySession session = new DefaultSecuritySession( result, user );
+
+ httpServletRequestControl.replay();
+
+ try
+ {
+ servletAuth.isAuthorized( request, session, "corporate", true );
+ fail( "UnauthorizedException should have been thrown." );
+ }
+ catch ( UnauthorizedException e )
+ {
+ assertEquals( "Access denied for repository corporate", e.getMessage() );
+ }
+
+ httpServletRequestControl.verify();
+ }
+
+
+ public void testIsAuthorizedUserHasReadAccess()
+ throws Exception
+ {
+ createUser( USER_ALPACA, "Al 'Archiva' Paca" );
+
+ assignRepositoryObserverRole( USER_ALPACA, "corporate" );
+
+ UserManager userManager = securitySystem.getUserManager();
+ User user = userManager.findUser( USER_ALPACA );
+
+ AuthenticationResult result = new AuthenticationResult( true, USER_ALPACA, null );
+
+ SecuritySession session = new DefaultSecuritySession( result, user );
+ boolean isAuthorized = servletAuth.isAuthorized( request, session, "corporate", false );
+
+ assertTrue( isAuthorized );
+ }
+
+ public void testIsAuthorizedUserHasNoReadAccess()
+ throws Exception
+ {
+ createUser( USER_ALPACA, "Al 'Archiva' Paca" );
+
+ UserManager userManager = securitySystem.getUserManager();
+ User user = userManager.findUser( USER_ALPACA );
+
+ AuthenticationResult result = new AuthenticationResult( true, USER_ALPACA, null );
+
+ SecuritySession session = new DefaultSecuritySession( result, user );
+ try
+ {
+ servletAuth.isAuthorized( request, session, "corporate", false );
+ fail( "UnauthorizedException should have been thrown." );
+ }
+ catch ( UnauthorizedException e )
+ {
+ assertEquals( "Access denied for repository corporate", e.getMessage() );
+ }
+ }
+
+ public void testIsAuthorizedGuestUserHasWriteAccess()
+ throws Exception
+ {
+ assignRepositoryManagerRole( USER_GUEST, "corporate" );
+ boolean isAuthorized = servletAuth.isAuthorized( USER_GUEST, "corporate", true );
+
+ assertTrue( isAuthorized );
+ }
+
+ public void testIsAuthorizedGuestUserHasNoWriteAccess()
+ throws Exception
+ {
+ assignRepositoryObserverRole( USER_GUEST, "corporate" );
+
+ boolean isAuthorized = servletAuth.isAuthorized( USER_GUEST, "corporate", true );
+ assertFalse( isAuthorized );
+ }
+
+ public void testIsAuthorizedGuestUserHasReadAccess()
+ throws Exception
+ {
+ assignRepositoryObserverRole( USER_GUEST, "corporate" );
+
+ boolean isAuthorized = servletAuth.isAuthorized( USER_GUEST, "corporate", false );
+
+ assertTrue( isAuthorized );
+ }
+
+ public void testIsAuthorizedGuestUserHasNoReadAccess()
+ throws Exception
+ {
+ boolean isAuthorized = servletAuth.isAuthorized( USER_GUEST, "corporate", false );
+
+ assertFalse( isAuthorized );
+ }
+}
* under the License.
*/
-import java.io.File;
import java.util.List;
-import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
-import org.apache.maven.archiva.configuration.ArchivaConfiguration;
-import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
-import org.codehaus.plexus.spring.PlexusInSpringTestCase;
-import org.codehaus.plexus.redback.rbac.RBACManager;
-import org.codehaus.plexus.redback.role.RoleManager;
-import org.codehaus.plexus.redback.system.SecuritySystem;
-import org.codehaus.plexus.redback.users.User;
-import org.codehaus.plexus.redback.users.UserManager;
/**
* DefaultUserRepositoriesTest
* @version $Id$
*/
public class DefaultUserRepositoriesTest
- extends PlexusInSpringTestCase
-{
- private static final String USER_GUEST = "guest";
-
- private static final String USER_ADMIN = "admin";
-
- private static final String USER_ALPACA = "alpaca";
-
- private SecuritySystem securitySystem;
-
- private RBACManager rbacManager;
-
- private RoleManager roleManager;
-
- private ArchivaConfiguration archivaConfiguration;
-
- private UserRepositories userRepos;
-
+ extends AbstractSecurityTest
+{
+ @Override
+ protected String getPlexusConfigLocation()
+ {
+ return "org/apache/maven/archiva/security/DefaultUserRepositoriesTest.xml";
+ }
+
public void testGetObservableRepositoryIds()
throws Exception
{
}
}
- private void setupRepository( String repoId )
- throws Exception
- {
- // Add repo to configuration.
- ManagedRepositoryConfiguration repoConfig = new ManagedRepositoryConfiguration();
- repoConfig.setId( repoId );
- repoConfig.setName( "Testable repo <" + repoId + ">" );
- repoConfig.setLocation( getTestPath( "target/test-repo/" + repoId ) );
- archivaConfiguration.getConfiguration().addManagedRepository( repoConfig );
-
- // Add repo roles to security.
- userRepos.createMissingRepositoryRoles( repoId );
- }
-
private void assignGlobalRepositoryObserverRole( String principal )
throws Exception
{
roleManager.assignRole( ArchivaRoleConstants.TEMPLATE_GLOBAL_REPOSITORY_OBSERVER, principal );
}
-
- private void assignRepositoryObserverRole( String principal, String repoId )
- throws Exception
- {
- roleManager.assignTemplatedRole( ArchivaRoleConstants.TEMPLATE_REPOSITORY_OBSERVER, repoId, principal );
- }
-
- private User createUser( String principal, String fullname )
- {
- UserManager userManager = securitySystem.getUserManager();
-
- User user = userManager.createUser( principal, fullname, principal + "@testable.archiva.apache.org" );
- securitySystem.getPolicy().setEnabled( false );
- userManager.addUser( user );
- securitySystem.getPolicy().setEnabled( true );
-
- return user;
- }
-
- @Override
- protected void setUp()
- throws Exception
- {
- super.setUp();
-
- File srcConfig = getTestFile( "src/test/resources/repository-archiva.xml" );
- File destConfig = getTestFile( "target/test-conf/archiva.xml" );
-
- destConfig.getParentFile().mkdirs();
- destConfig.delete();
-
- FileUtils.copyFile( srcConfig, destConfig );
-
- securitySystem = (SecuritySystem) lookup( SecuritySystem.class, "testable" );
- rbacManager = (RBACManager) lookup( RBACManager.class, "memory" );
- roleManager = (RoleManager) lookup( RoleManager.class, "default" );
- userRepos = (UserRepositories) lookup( UserRepositories.class, "default" );
- archivaConfiguration = (ArchivaConfiguration) lookup( ArchivaConfiguration.class );
-
- // Some basic asserts.
- assertNotNull( securitySystem );
- assertNotNull( rbacManager );
- assertNotNull( roleManager );
- assertNotNull( userRepos );
- assertNotNull( archivaConfiguration );
-
- // Setup Admin User.
- User adminUser = createUser( USER_ADMIN, "Admin User" );
- roleManager.assignRole( ArchivaRoleConstants.TEMPLATE_SYSTEM_ADMIN, adminUser.getPrincipal().toString() );
-
- // Setup Guest User.
- User guestUser = createUser( USER_GUEST, "Guest User" );
- roleManager.assignRole( ArchivaRoleConstants.TEMPLATE_GUEST, guestUser.getPrincipal().toString() );
-
- }
}
--- /dev/null
+<?xml version="1.0" ?>
+<component-set>
+ <components>
+
+ <component>
+ <role>org.apache.maven.archiva.security.ServletAuthenticator</role>
+ <role-hint>default</role-hint>
+ <implementation>org.apache.maven.archiva.security.ArchivaServletAuthenticator</implementation>
+ <description>ArchivaServletAuthenticator</description>
+ <requirements>
+ <requirement>
+ <role>org.codehaus.plexus.redback.system.SecuritySystem</role>
+ <role-hint>testable</role-hint>
+ <field-name>securitySystem</field-name>
+ </requirement>
+ </requirements>
+ </component>
+
+ <component>
+ <role>org.apache.maven.archiva.security.UserRepositories</role>
+ <role-hint>default</role-hint>
+ <implementation>org.apache.maven.archiva.security.DefaultUserRepositories</implementation>
+ <description>DefaultUserRepositories</description>
+ <requirements>
+ <requirement>
+ <role>org.codehaus.plexus.redback.system.SecuritySystem</role>
+ <role-hint>testable</role-hint>
+ <field-name>securitySystem</field-name>
+ </requirement>
+ <requirement>
+ <role>org.codehaus.plexus.redback.rbac.RBACManager</role>
+ <role-hint>memory</role-hint>
+ <field-name>rbacManager</field-name>
+ </requirement>
+ <requirement>
+ <role>org.codehaus.plexus.redback.role.RoleManager</role>
+ <role-hint>default</role-hint>
+ <field-name>roleManager</field-name>
+ </requirement>
+ <requirement>
+ <role>org.apache.maven.archiva.configuration.ArchivaConfiguration</role>
+ <field-name>archivaConfiguration</field-name>
+ </requirement>
+ </requirements>
+ </component>
+
+ <component>
+ <role>org.codehaus.plexus.redback.system.SecuritySystem</role>
+ <role-hint>testable</role-hint>
+ <implementation>org.codehaus.plexus.redback.system.DefaultSecuritySystem</implementation>
+ <description>DefaultSecuritySystem:</description>
+ <requirements>
+ <requirement>
+ <role>org.codehaus.plexus.redback.authentication.AuthenticationManager</role>
+ <field-name>authnManager</field-name>
+ </requirement>
+ <requirement>
+ <role>org.codehaus.plexus.redback.authorization.Authorizer</role>
+ <role-hint>rbac</role-hint>
+ <field-name>authorizer</field-name>
+ </requirement>
+ <requirement>
+ <role>org.codehaus.plexus.redback.users.UserManager</role>
+ <role-hint>memory</role-hint>
+ <field-name>userManager</field-name>
+ </requirement>
+ <requirement>
+ <role>org.codehaus.plexus.redback.keys.KeyManager</role>
+ <role-hint>memory</role-hint>
+ <field-name>keyManager</field-name>
+ </requirement>
+ <requirement>
+ <role>org.codehaus.plexus.redback.policy.UserSecurityPolicy</role>
+ <field-name>policy</field-name>
+ </requirement>
+ </requirements>
+ </component>
+
+ <component>
+ <role>org.codehaus.plexus.redback.authorization.Authorizer</role>
+ <role-hint>rbac</role-hint>
+ <implementation>org.codehaus.plexus.redback.authorization.rbac.RbacAuthorizer</implementation>
+ <description>RbacAuthorizer:</description>
+ <requirements>
+ <requirement>
+ <role>org.codehaus.plexus.redback.rbac.RBACManager</role>
+ <role-hint>memory</role-hint>
+ <field-name>manager</field-name>
+ </requirement>
+ <requirement>
+ <role>org.codehaus.plexus.redback.users.UserManager</role>
+ <role-hint>memory</role-hint>
+ <field-name>userManager</field-name>
+ </requirement>
+ <requirement>
+ <role>org.codehaus.plexus.redback.authorization.rbac.evaluator.PermissionEvaluator</role>
+ <role-hint>default</role-hint>
+ <field-name>evaluator</field-name>
+ </requirement>
+ <requirement>
+ <role>org.codehaus.plexus.redback.configuration.UserConfiguration</role>
+ <role-hint>default</role-hint>
+ <field-name>config</field-name>
+ </requirement>
+ </requirements>
+ </component>
+
+ <component>
+ <role>org.codehaus.plexus.redback.authorization.rbac.evaluator.PermissionEvaluator</role>
+ <role-hint>default</role-hint>
+ <implementation>org.codehaus.plexus.redback.authorization.rbac.evaluator.DefaultPermissionEvaluator</implementation>
+ <requirements>
+ <requirement>
+ <role>org.codehaus.plexus.redback.users.UserManager</role>
+ <role-hint>memory</role-hint>
+ <field-name>userManager</field-name>
+ </requirement>
+ </requirements>
+ </component>
+
+ <component>
+ <role>org.codehaus.plexus.redback.role.RoleManager</role>
+ <role-hint>default</role-hint>
+ <implementation>org.codehaus.plexus.redback.role.DefaultRoleManager</implementation>
+ <description>RoleProfileManager:</description>
+ <requirements>
+ <requirement>
+ <role>org.codehaus.plexus.redback.role.validator.RoleModelValidator</role>
+ <role-hint>default</role-hint>
+ <field-name>modelValidator</field-name>
+ </requirement>
+ <requirement>
+ <role>org.codehaus.plexus.redback.role.processor.RoleModelProcessor</role>
+ <role-hint>default</role-hint>
+ <field-name>modelProcessor</field-name>
+ </requirement>
+ <requirement>
+ <role>org.codehaus.plexus.redback.role.template.RoleTemplateProcessor</role>
+ <role-hint>default</role-hint>
+ <field-name>templateProcessor</field-name>
+ </requirement>
+ <requirement>
+ <role>org.codehaus.plexus.redback.rbac.RBACManager</role>
+ <role-hint>memory</role-hint>
+ <field-name>rbacManager</field-name>
+ </requirement>
+ </requirements>
+ </component>
+
+ <component>
+ <role>org.codehaus.plexus.redback.role.processor.RoleModelProcessor</role>
+ <role-hint>default</role-hint>
+ <implementation>org.codehaus.plexus.redback.role.processor.DefaultRoleModelProcessor</implementation>
+ <description>DefaultRoleModelProcessor: inserts the components of the model that can be populated into the rbac manager</description>
+ <requirements>
+ <requirement>
+ <role>org.codehaus.plexus.redback.rbac.RBACManager</role>
+ <role-hint>memory</role-hint>
+ <field-name>rbacManager</field-name>
+ </requirement>
+ </requirements>
+ </component>
+
+ <component>
+ <role>org.codehaus.plexus.redback.role.template.RoleTemplateProcessor</role>
+ <role-hint>default</role-hint>
+ <implementation>org.codehaus.plexus.redback.role.template.DefaultRoleTemplateProcessor</implementation>
+ <description>DefaultRoleTemplateProcessor: inserts the components of a template into the rbac manager</description>
+ <requirements>
+ <requirement>
+ <role>org.codehaus.plexus.redback.rbac.RBACManager</role>
+ <role-hint>memory</role-hint>
+ <field-name>rbacManager</field-name>
+ </requirement>
+ </requirements>
+ </component>
+
+ <component>
+ <role>org.apache.maven.archiva.configuration.ArchivaConfiguration</role>
+ <implementation>org.apache.maven.archiva.configuration.DefaultArchivaConfiguration</implementation>
+ <requirements>
+ <requirement>
+ <role>org.codehaus.plexus.registry.Registry</role>
+ <role-hint>configured</role-hint>
+ </requirement>
+ </requirements>
+ </component>
+ <component>
+ <role>org.codehaus.plexus.registry.Registry</role>
+ <role-hint>configured</role-hint>
+ <implementation>org.codehaus.plexus.registry.commons.CommonsConfigurationRegistry</implementation>
+ <configuration>
+ <properties>
+ <system/>
+ <xml fileName="${basedir}/target/test-conf/archiva.xml"
+ config-name="org.apache.maven.archiva.base" config-at="org.apache.maven.archiva"/>
+ </properties>
+ </configuration>
+ </component>
+
+ </components>
+</component-set>
* under the License.
*/
-import org.apache.struts2.interceptor.ServletRequestAware;
import com.opensymphony.xwork2.Preparable;
+import org.apache.commons.lang.time.DateFormatUtils;
+import org.apache.commons.lang.time.DateUtils;
+import org.apache.maven.archiva.configuration.ArchivaConfiguration;
import org.apache.maven.archiva.database.ArchivaDAO;
+import org.apache.maven.archiva.database.ArchivaDatabaseException;
import org.apache.maven.archiva.database.Constraint;
+import org.apache.maven.archiva.database.ObjectNotFoundException;
+import org.apache.maven.archiva.database.RepositoryContentStatisticsDAO;
import org.apache.maven.archiva.database.constraints.RangeConstraint;
+import org.apache.maven.archiva.database.constraints.RepositoryContentStatisticsByRepositoryConstraint;
import org.apache.maven.archiva.database.constraints.RepositoryProblemByGroupIdConstraint;
import org.apache.maven.archiva.database.constraints.RepositoryProblemByRepositoryIdConstraint;
import org.apache.maven.archiva.database.constraints.RepositoryProblemConstraint;
import org.apache.maven.archiva.database.constraints.UniqueFieldConstraint;
+import org.apache.maven.archiva.model.RepositoryContentStatistics;
import org.apache.maven.archiva.model.RepositoryProblem;
import org.apache.maven.archiva.model.RepositoryProblemReport;
+import org.apache.maven.archiva.reporting.ArchivaReportException;
+import org.apache.maven.archiva.reporting.DataLimits;
+import org.apache.maven.archiva.reporting.RepositoryStatistics;
+import org.apache.maven.archiva.reporting.RepositoryStatisticsReportGenerator;
import org.apache.maven.archiva.security.ArchivaRoleConstants;
-import org.apache.maven.archiva.web.action.PlexusActionSupport;
import org.codehaus.plexus.redback.rbac.Resource;
-import org.codehaus.plexus.redback.struts2.interceptor.SecureAction;
-import org.codehaus.plexus.redback.struts2.interceptor.SecureActionBundle;
-import org.codehaus.plexus.redback.struts2.interceptor.SecureActionException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletRequest;
+
+import java.text.ParseException;
import java.util.ArrayList;
+import java.util.Calendar;
import java.util.Collection;
+import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
+import org.apache.maven.archiva.web.action.PlexusActionSupport;
+import org.apache.struts2.interceptor.ServletRequestAware;
+import org.codehaus.plexus.redback.struts2.interceptor.SecureAction;
+import org.codehaus.plexus.redback.struts2.interceptor.SecureActionBundle;
+import org.codehaus.plexus.redback.struts2.interceptor.SecureActionException;
/**
* @plexus.component role="com.opensymphony.xwork2.Action" role-hint="generateReport"
extends PlexusActionSupport
implements SecureAction, ServletRequestAware, Preparable
{
+ private Logger log = LoggerFactory.getLogger( GenerateReportAction.class );
+
/**
* @plexus.requirement role-hint="jdo"
*/
protected ArchivaDAO dao;
+
+ /**
+ * @plexus.requirement
+ */
+ private ArchivaConfiguration archivaConfiguration;
protected Constraint constraint;
protected Map<String, List<RepositoryProblemReport>> repositoriesMap =
new TreeMap<String, List<RepositoryProblemReport>>();
-
+
+ // for statistics report
+ /**
+ * @plexus.requirement role-hint="simple"
+ */
+ private RepositoryStatisticsReportGenerator generator;
+
+ private List<String> selectedRepositories = new ArrayList<String>();
+
+ private List<String> availableRepositories;
+
+ private String startDate;
+
+ private String endDate;
+
+ private int reposSize;
+
+ private String selectedRepo;
+
+ private List<RepositoryStatistics> repositoryStatistics = new ArrayList<RepositoryStatistics>();
+
+ private DataLimits limits = new DataLimits();
+
+ private String[] datePatterns = new String[] { "MM/dd/yy", "MM/dd/yyyy", "MMMMM/dd/yyyy", "MMMMM/dd/yy",
+ "dd MMMMM yyyy", "dd/MM/yy", "dd/MM/yyyy", "yyyy/MM/dd" };
+
public void prepare()
{
repositoryIds = new ArrayList<String>();
repositoryIds.add( ALL_REPOSITORIES ); // comes first to be first in the list
repositoryIds.addAll(
dao.query( new UniqueFieldConstraint( RepositoryProblem.class.getName(), "repositoryId" ) ) );
+
+ availableRepositories = new ArrayList<String>();
+
+ // remove selected repositories in the option for the statistics report
+ availableRepositories.addAll( archivaConfiguration.getConfiguration().getManagedRepositoriesAsMap().keySet() );
+ for( String repo : selectedRepositories )
+ {
+ if( availableRepositories.contains( repo ) )
+ {
+ availableRepositories.remove( repo );
+ }
+ }
}
public Collection<String> getRepositoryIds()
return repositoryIds;
}
- @Override
+ /**
+ * Generate the statistics report.
+ *
+ * check whether single repo report or comparison report
+ * 1. if it is a single repository, get all the statistics for the repository on the specified date
+ * - if no date is specified, get only the latest
+ * (total page = 1 --> no pagination since only the most recent stats will be displayed)
+ * - otherwise, get everything within the date range (total pages = repo stats / rows per page)
+ * - required params: repository, startDate, endDate
+ *
+ * 2. if multiple repositories, get the latest statistics on each repository on the specified date
+ * - if no date is specified, use the current date endDate
+ * - required params: repositories, endDate
+ * - total pages = repositories / rows per page
+ *
+ * @return
+ */
+ public String generateStatistics()
+ {
+ if( rowCount < 10 )
+ {
+ addFieldError( "rowCount", "Row count must be larger than 10." );
+ return INPUT;
+ }
+ reposSize = selectedRepositories.size();
+ Date startDateInDateFormat = null;
+ Date endDateInDateFormat = null;
+
+ if( startDate == null || "".equals( startDate ) )
+ {
+ startDateInDateFormat = getDefaultStartDate();
+ }
+ else
+ {
+ try
+ {
+ startDateInDateFormat = DateUtils.parseDate( startDate, datePatterns );
+ }
+ catch ( ParseException e )
+ {
+ addFieldError( "startDate", "Invalid date format.");
+ return INPUT;
+ }
+ }
+
+ if( endDate == null || "".equals( endDate ) )
+ {
+ endDateInDateFormat = getDefaultEndDate();
+ }
+ else
+ {
+ try
+ {
+ endDateInDateFormat = DateUtils.parseDate( endDate, datePatterns );
+ }
+ catch ( ParseException e )
+ {
+ addFieldError( "endDate", "Invalid date format.");
+ return INPUT;
+ }
+ }
+
+ try
+ {
+ RepositoryContentStatisticsDAO repoContentStatsDao = dao.getRepositoryContentStatisticsDAO();
+ if( selectedRepositories.size() > 1 )
+ {
+ limits.setTotalCount( selectedRepositories.size() );
+ limits.setCurrentPage( 1 );
+ limits.setPerPageCount( 1 );
+ limits.setCountOfPages( 1 );
+
+ // multiple repos
+ for( String repo : selectedRepositories )
+ {
+ try
+ {
+ List contentStats = repoContentStatsDao.queryRepositoryContentStatistics(
+ new RepositoryContentStatisticsByRepositoryConstraint( repo, startDateInDateFormat, endDateInDateFormat ) );
+
+ if( contentStats == null || contentStats.isEmpty() )
+ {
+ log.info( "No statistics available for repository '" + repo + "'." );
+ // TODO set repo's stats to 0
+
+ continue;
+ }
+ repositoryStatistics.addAll( generator.generateReport( contentStats, repo, startDateInDateFormat, endDateInDateFormat, limits ) );
+ }
+ catch ( ObjectNotFoundException oe )
+ {
+ log.error( "No statistics available for repository '" + repo + "'." );
+ // TODO set repo's stats to 0
+ }
+ catch ( ArchivaDatabaseException ae )
+ {
+ log.error( "Error encountered while querying statistics of repository '" + repo + "'." );
+ // TODO set repo's stats to 0
+ }
+ }
+ }
+ else if ( selectedRepositories.size() == 1 )
+ {
+ limits.setCurrentPage( getPage() );
+ limits.setPerPageCount( getRowCount() );
+
+ selectedRepo = selectedRepositories.get( 0 );
+ try
+ {
+ List<RepositoryContentStatistics> contentStats = repoContentStatsDao.queryRepositoryContentStatistics(
+ new RepositoryContentStatisticsByRepositoryConstraint( selectedRepo, startDateInDateFormat, endDateInDateFormat ) );
+
+ if( contentStats == null || contentStats.isEmpty() )
+ {
+ addActionError( "No statistics available for repository. Repository might not have been scanned." );
+ return ERROR;
+ }
+
+ limits.setTotalCount( contentStats.size() );
+ int extraPage = ( limits.getTotalCount() % limits.getPerPageCount() ) != 0 ? 1 : 0;
+ int totalPages = ( limits.getTotalCount() / limits.getPerPageCount() ) + extraPage;
+ limits.setCountOfPages( totalPages );
+
+ repositoryStatistics = generator.generateReport( contentStats, selectedRepo, startDateInDateFormat, endDateInDateFormat, limits );
+ }
+ catch ( ObjectNotFoundException oe )
+ {
+ addActionError( oe.getMessage() );
+ return ERROR;
+ }
+ catch ( ArchivaDatabaseException de )
+ {
+ addActionError( de.getMessage() );
+ return ERROR;
+ }
+ }
+ else
+ {
+ addFieldError( "availableRepositories", "Please select a repository (or repositories) from the list." );
+ return INPUT;
+ }
+
+ if( repositoryStatistics.isEmpty() )
+ {
+ return BLANK;
+ }
+
+ if( startDate.equals( getDefaultStartDate() ) )
+ {
+ startDate = null;
+ }
+ else
+ {
+ startDate = DateFormatUtils.format( startDateInDateFormat, "MM/dd/yyyy" );
+ }
+
+ endDate = DateFormatUtils.format( endDateInDateFormat, "MM/dd/yyyy" );
+ }
+ catch ( ArchivaReportException e )
+ {
+ addActionError( "Error encountered while generating report :: " + e.getMessage() );
+ return ERROR;
+ }
+
+ return SUCCESS;
+ }
+
+ private Date getDefaultStartDate()
+ {
+ Calendar cal = Calendar.getInstance();
+ cal.clear();
+ cal.set( 1900, 1, 1, 0, 0, 0 );
+
+ return cal.getTime();
+ }
+
+ private Date getDefaultEndDate()
+ {
+ return Calendar.getInstance().getTime();
+ }
+
public String execute()
throws Exception
- {
+ {
+ if( repositoryId == null )
+ {
+ addFieldError( "repositoryId", "You must provide a repository id.");
+ return INPUT;
+ }
+
+ if( rowCount < 10 )
+ {
+ addFieldError( "rowCount", "Row count must be larger than 10." );
+ return INPUT;
+ }
+
List<RepositoryProblem> problemArtifacts =
dao.getRepositoryProblemDAO().queryRepositoryProblems( configureConstraint() );
return SUCCESS;
}
}
-
+
private static boolean isJasperPresent()
{
if ( jasperPresent == null )
return constraint;
}
+
+ public SecureActionBundle getSecureActionBundle()
+ throws SecureActionException
+ {
+ SecureActionBundle bundle = new SecureActionBundle();
+
+ bundle.setRequiresAuthentication( true );
+ bundle.addRequiredAuthorization( ArchivaRoleConstants.OPERATION_ACCESS_REPORT, Resource.GLOBAL );
+
+ return bundle;
+ }
+
+ private void addToList( RepositoryProblemReport repoProblemReport )
+ {
+ List<RepositoryProblemReport> problemsList = null;
+
+ if ( repositoriesMap.containsKey( repoProblemReport.getRepositoryId() ) )
+ {
+ problemsList = ( List<RepositoryProblemReport> ) repositoriesMap.get( repoProblemReport.getRepositoryId() );
+ }
+ else
+ {
+ problemsList = new ArrayList<RepositoryProblemReport>();
+ repositoriesMap.put( repoProblemReport.getRepositoryId(), problemsList );
+ }
+
+ problemsList.add( repoProblemReport );
+ }
public void setServletRequest( HttpServletRequest request )
{
return repositoriesMap;
}
- public SecureActionBundle getSecureActionBundle()
- throws SecureActionException
+ public List<String> getSelectedRepositories()
{
- SecureActionBundle bundle = new SecureActionBundle();
+ return selectedRepositories;
+ }
- bundle.setRequiresAuthentication( true );
- bundle.addRequiredAuthorization( ArchivaRoleConstants.OPERATION_ACCESS_REPORT, Resource.GLOBAL );
+ public void setSelectedRepositories( List<String> selectedRepositories )
+ {
+ this.selectedRepositories = selectedRepositories;
+ }
- return bundle;
+ public List<String> getAvailableRepositories()
+ {
+ return availableRepositories;
+ }
+
+ public void setAvailableRepositories( List<String> availableRepositories )
+ {
+ this.availableRepositories = availableRepositories;
+ }
+
+ public String getStartDate()
+ {
+ return startDate;
+ }
+
+ public void setStartDate( String startDate )
+ {
+ this.startDate = startDate;
+ }
+
+ public String getEndDate()
+ {
+ return endDate;
+ }
+
+ public void setEndDate( String endDate )
+ {
+ this.endDate = endDate;
+ }
+
+ public List<RepositoryStatistics> getRepositoryStatistics()
+ {
+ return repositoryStatistics;
+ }
+
+ public void setRepositoryStatistics( List<RepositoryStatistics> repositoryStatistics )
+ {
+ this.repositoryStatistics = repositoryStatistics;
}
- private void addToList( RepositoryProblemReport repoProblemReport )
+ public int getReposSize()
+ {
+ return reposSize;
+ }
+
+ public void setReposSize( int reposSize )
+ {
+ this.reposSize = reposSize;
+ }
+
+ public String getSelectedRepo()
+ {
+ return selectedRepo;
+ }
+
+ public void setSelectedRepo( String selectedRepo )
+ {
+ this.selectedRepo = selectedRepo;
+ }
+
+ public DataLimits getLimits()
+ {
+ return limits;
+ }
+
+ public void setLimits( DataLimits limits )
{
- List<RepositoryProblemReport> problemsList = null;
-
- if ( repositoriesMap.containsKey( repoProblemReport.getRepositoryId() ) )
- {
- problemsList = ( List<RepositoryProblemReport> ) repositoriesMap.get( repoProblemReport.getRepositoryId() );
- }
- else
- {
- problemsList = new ArrayList<RepositoryProblemReport>();
- repositoriesMap.put( repoProblemReport.getRepositoryId(), problemsList );
- }
-
- problemsList.add( repoProblemReport );
+ this.limits = limits;
}
}
+++ /dev/null
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
- ~ 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.
- -->
-
-<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
- "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
-
-<validators>
- <field name="rowCount">
- <field-validator type="int">
- <param name="min">10</param>
- <message>Row count must be larger than ${min}.</message>
- </field-validator>
- </field>
- <!--
- <field name="groupId">
- <field-validator type="regex">
- <param name="expression"><![CDATA[([a-zA-Z0-9]+[a-zA-Z0-9.]*)]]></param>
- <message>You must provide a valid group id.</message>
- </field-validator>
- </field>
- -->
- <field name="repositoryId">
- <field-validator type="requiredstring">
- <message>You must provide a repository id.</message>
- </field-validator>
- </field>
-</validators>
</c:forEach>
</div> <%-- admin --%>
-</div> <%-- content area --%>
</c:otherwise>
</c:choose>
+</div> <%-- content area --%>
+
+</body>
+</html>
+
<my:currentWWUrl action="userlist" namespace="/security">User Management</my:currentWWUrl>
</li>
</redback:ifAuthorized>
+ <redback:ifAuthorized permission="archiva-manage-users">
+ <li class="none">
+ <my:currentWWUrl action="roles" namespace="/security">User Roles</my:currentWWUrl>
+ </li>
+ </redback:ifAuthorized>
<redback:ifAuthorized permission="archiva-manage-configuration">
<li class="none">
<my:currentWWUrl action="configureAppearance" namespace="/admin">Appearance</my:currentWWUrl>
<html>
<head>
<title>Reports</title>
- <s:head/>
+ <s:head theme="ajax" />
</head>
<body>
<h1>Reports</h1>
-
+
<div id="contentArea">
- <s:form action="generateReport" namespace="/report" validate="true">
+ <h2>Repository Statistics</h2>
+ <s:form action="generateStatisticsReport" namespace="/report" validate="true">
+
+ <s:optiontransferselect label="Repositories To Be Compared" name="availableRepositories"
+ list="availableRepositories" doubleName="selectedRepositories"
+ doubleList="selectedRepositories" size="8" doubleSize="8"/>
+
+ <s:datetimepicker label="Start Date" name="startDate" id="startDate"/>
+ <s:datetimepicker label="End Date" name="endDate" id="endDate"/>
+ <s:textfield label="Row Count" name="rowCount" />
+
+ <s:submit value="View Statistics"/>
+ </s:form>
+
+ <h2>Repository Health</h2>
+ <s:form namespace="/report" action="generateReport" validate="true">
<s:textfield label="Row Count" name="rowCount" />
<s:textfield label="Group ID" name="groupId"/>
<s:select label="Repository ID" name="repositoryId" list="repositoryIds"/>
+
<s:submit value="Show Report"/>
</s:form>
--- /dev/null
+<%--
+ ~ 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="ww" uri="/webwork" %>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@ taglib prefix="archiva" uri="http://archiva.apache.org" %>
+
+<html>
+<head>
+ <title>Reports</title>
+ <ww:head/>
+</head>
+
+<body>
+<h1>Statistics Report</h1>
+
+<c:url var="imgNextPageUrl" value="/images/icon_next_page.gif"/>
+<c:url var="imgPrevPageUrl" value="/images/icon_prev_page.gif"/>
+<c:url var="imgPrevPageDisabledUrl" value="/images/icon_prev_page_disabled.gif"/>
+<c:url var="imgNextPageDisabledUrl" value="/images/icon_next_page_disabled.gif"/>
+
+<div id="contentArea">
+
+ <%-- TODO: fix problem in date format! --%>
+
+ <%-- Pagination - start --%>
+ <p>
+
+ <%-- Set Prev & Next icons --%>
+ <c:set var="prevPageUrl">
+ <ww:url action="generateStatisticsReport" namespace="/report">
+ <ww:param name="selectedRepositories" value="%{'${selectedRepositories}'}"/>
+ <ww:param name="rowCount" value="%{'${rowCount}'}"/>
+ <ww:param name="startDate" value="%{'${startDate}'}"/>
+ <ww:param name="endDate" value="%{'${endDate}'}"/>
+ <ww:param name="page" value="%{'${page - 1}'}"/>
+ </ww:url>
+ </c:set>
+ <c:set var="nextPageUrl">
+ <ww:url action="generateStatisticsReport" namespace="/report">
+ <ww:param name="selectedRepositories" value="%{'${selectedRepositories}'}"/>
+ <ww:param name="rowCount" value="%{'${rowCount}'}"/>
+ <ww:param name="startDate" value="%{'${startDate}'}"/>
+ <ww:param name="endDate" value="%{'${endDate}'}"/>
+ <ww:param name="page" value="%{'${page + 1}'}"/>
+ </ww:url>
+ </c:set>
+
+ <c:choose>
+ <c:when test="${page == 1}">
+ <img src="${imgPrevPageDisabledUrl}"/>
+ </c:when>
+ <c:otherwise>
+ <a href="${prevPageUrl}">
+ <img src="${imgPrevPageUrl}"/>
+ </a>
+ </c:otherwise>
+ </c:choose>
+
+ <%-- Google-style pagination --%>
+ <c:choose>
+ <c:when test="${limits.countOfPages > 11}">
+ <c:choose>
+ <c:when test="${(page - 5) < 0}">
+ <c:set var="beginVal">0</c:set>
+ <c:set var="endVal">10</c:set>
+ </c:when>
+ <c:when test="${(page + 5) > (limits.countOfPages - 1)}">
+ <c:set var="beginVal">${(limits.countOfPages -1) - 10}</c:set>
+ <c:set var="endVal">${limits.countOfPages - 1}</c:set>
+ </c:when>
+ <c:otherwise>
+ <c:set var="beginVal">${page - 5}</c:set>
+ <c:set var="endVal">${page + 5}</c:set>
+ </c:otherwise>
+ </c:choose>
+ </c:when>
+ <c:otherwise>
+ <c:set var="beginVal">0</c:set>
+ <c:set var="endVal">${limits.countOfPages - 1}</c:set>
+ </c:otherwise>
+ </c:choose>
+
+ <c:forEach var="i" begin="${beginVal}" end="${endVal}">
+ <c:choose>
+ <c:when test="${i != (page - 1)}">
+ <c:set var="specificPageUrl">
+ <ww:url action="generateStatisticsReport" namespace="/report">
+ <ww:param name="selectedRepositories" value="%{'${selectedRepositories}'}"/>
+ <ww:param name="rowCount" value="%{'${rowCount}'}"/>
+ <ww:param name="startDate" value="%{'${startDate}'}"/>
+ <ww:param name="endDate" value="%{'${endDate}'}"/>
+ <ww:param name="page" value="%{'${page + 1}'}"/>
+ </ww:url>
+ </c:set>
+ <a href="${specificPageUrl}">${i + 1}</a>
+ </c:when>
+ <c:otherwise>
+ <b>${i + 1}</b>
+ </c:otherwise>
+ </c:choose>
+ </c:forEach>
+
+ <c:choose>
+ <c:when test="${page == limits.countOfPages}">
+ <img src="${imgNextPageDisabledUrl}"/>
+ </c:when>
+ <c:otherwise>
+ <a href="${nextPageUrl}">
+ <img src="${imgNextPageUrl}"/>
+ </a>
+ </c:otherwise>
+ </c:choose>
+ </p>
+ <%-- Pagination - end --%>
+
+ <c:choose>
+ <c:when test="${reposSize > 1}">
+
+ <h1>Latest Statistics Comparison Report</h1>
+ <table class="infoTable" border="1">
+ <tr>
+ <th>Repository</th>
+ <th>Total File Count</th>
+ <th>Total Size</th>
+ <th>Artifact Count</th>
+ <th>Group Count</th>
+ <th>Project Count</th>
+ <th>Plugins</th>
+ <th>Archetypes</th>
+ <th>Jars</th>
+ <th>Wars</th>
+ <th>Deployments</th>
+ <th>Downloads</th>
+ </tr>
+
+ <c:forEach var="stats" items="${repositoryStatistics}">
+ <tr>
+ <td>${stats.repositoryId}</td>
+ <td align="right">${stats.fileCount}</td>
+ <td align="right">${stats.totalSize}</td>
+ <td align="right">${stats.artifactCount}</td>
+ <td align="right">${stats.groupCount}</td>
+ <td align="right">${stats.projectCount}</td>
+ <td align="right">${stats.pluginCount}</td>
+ <td align="right">${stats.archetypeCount}</td>
+ <td align="right">${stats.jarCount}</td>
+ <td align="right">${stats.warCount}</td>
+ <td align="right">${stats.deploymentCount}</td>
+ <td align="right">${stats.downloadCount}</td>
+ </tr>
+ </c:forEach>
+ </table>
+ </c:when>
+ <c:otherwise>
+
+ <h1>Statistics for Repository '${selectedRepo}'</h1>
+ <table class="infoTable" border="1">
+ <tr>
+ <th>Date of Scan</th>
+ <th>Total File Count</th>
+ <th>Total Size</th>
+ <th>Artifact Count</th>
+ <th>Group Count</th>
+ <th>Project Count</th>
+ <th>Plugins</th>
+ <th>Archetypes</th>
+ <th>Jars</th>
+ <th>Wars</th>
+ <th>Deployments</th>
+ <th>Downloads</th>
+ </tr>
+
+ <c:forEach var="stats" items="${repositoryStatistics}">
+ <tr>
+ <td align="right">${stats.dateOfScan}</td>
+ <td align="right">${stats.fileCount}</td>
+ <td align="right">${stats.totalSize}</td>
+ <td align="right">${stats.artifactCount}</td>
+ <td align="right">${stats.groupCount}</td>
+ <td align="right">${stats.projectCount}</td>
+ <td align="right">${stats.pluginCount}</td>
+ <td align="right">${stats.archetypeCount}</td>
+ <td align="right">${stats.jarCount}</td>
+ <td align="right">${stats.warCount}</td>
+ <td align="right">${stats.deploymentCount}</td>
+ <td align="right">${stats.downloadCount}</td>
+ </tr>
+ </c:forEach>
+ </table>
+
+ </c:otherwise>
+ </c:choose>
+
+</div>
+</body>
+</html>
select {
padding-left: 3px;
- height: 1.4em;
+ height: auto;
+ width: auto;
}
input {
{
checkLocatorIsInstanceOfRepositoryLocator( locator );
ArchivaDavResourceLocator archivaLocator = (ArchivaDavResourceLocator) locator;
-
+
RepositoryGroupConfiguration repoGroupConfig =
archivaConfiguration.getConfiguration().getRepositoryGroupsAsMap().get( archivaLocator.getRepositoryId() );
List<String> repositories = new ArrayList<String>();
boolean isGet = WebdavMethodUtil.isReadMethod( request.getMethod() );
boolean isPut = WebdavMethodUtil.isWriteMethod( request.getMethod() );
-
+
if ( repoGroupConfig != null )
{
if( WebdavMethodUtil.isWriteMethod( request.getMethod() ) )
try
{
- managedRepository = getManagedRepository( repositoryId );
+ managedRepository = getManagedRepository( repositoryId );
}
catch ( DavException de )
{
DavResource resource = null;
if ( !locator.getResourcePath().startsWith( ArchivaDavResource.HIDDEN_PATH_PREFIX ) )
- {
+ {
if ( managedRepository != null )
{
try
{
if( isAuthorized( request, repositoryId ) )
- {
+ {
LogicalResource logicalResource =
new LogicalResource( RepositoryPathUtil.getLogicalResource( locator.getResourcePath() ) );
if ( isPut )
{
- resource = doPut( managedRepository, request, archivaLocator, logicalResource );
+ resource = doPut( managedRepository, request, archivaLocator, logicalResource );
}
}
}
catch ( DavException de )
- {
+ {
e = de;
continue;
}
e = new DavException( HttpServletResponse.SC_NOT_FOUND, "Resource does not exist" );
}
else
- {
+ {
availableResources.add( resource );
String logicalResource = RepositoryPathUtil.getLogicalResource( locator.getResourcePath() );
- resourcesInAbsolutePath.add( managedRepository.getRepoRoot() + logicalResource );
+ resourcesInAbsolutePath.add( managedRepository.getRepoRoot() + logicalResource );
}
}
else
File rootDirectory = new File( managedRepository.getRepoRoot() );
File destDir = new File( rootDirectory, logicalResource.getPath() ).getParentFile();
+
if ( request.getMethod().equals(HTTP_PUT_METHOD) && !destDir.exists() )
{
destDir.mkdirs();
String relPath = PathUtil.getRelative( rootDirectory.getAbsolutePath(), destDir );
triggerAuditEvent( request.getRemoteAddr(), logicalResource.getPath(), relPath, AuditEvent.CREATE_DIR );
}
-
- File resourceFile = new File( managedRepository.getRepoRoot(), logicalResource.getPath() );
-
+
+ File resourceFile = new File( managedRepository.getRepoRoot(), logicalResource.getPath() );
+
return new ArchivaDavResource( resourceFile.getAbsolutePath(), logicalResource.getPath(),
managedRepository.getRepository(), request.getRemoteAddr(),
request.getDavSession(), locator, this, mimeTypes, auditListeners, consumers, archivaXworkUser );
protected boolean isAuthorized( DavServletRequest request, String repositoryId )
throws DavException
- {
+ {
try
- {
+ {
AuthenticationResult result = httpAuth.getAuthenticationResult( request, null );
SecuritySession securitySession = httpAuth.getSecuritySession();
WebdavMethodUtil.isWriteMethod( request.getMethod() ) );
}
catch ( AuthenticationException e )
- {
+ {
+ boolean isPut = WebdavMethodUtil.isWriteMethod( request.getMethod() );
+
// safety check for MRM-911
String guest = archivaXworkUser.getGuest();
try
{
if( servletAuth.isAuthorized( guest,
- ( ( ArchivaDavResourceLocator ) request.getRequestLocator() ).getRepositoryId() ) )
+ ( ( ArchivaDavResourceLocator ) request.getRequestLocator() ).getRepositoryId(), isPut ) )
{
return true;
}
if( allow )
{
+ boolean isPut = WebdavMethodUtil.isWriteMethod( request.getMethod() );
+
for( String repository : repositories )
{
// for prompted authentication
// for the current user logged in
try
{
- if( servletAuth.isAuthorized( activePrincipal, repository ) )
+ if( servletAuth.isAuthorized( activePrincipal, repository, isPut ) )
{
getResource( locator, mergedRepositoryContents, logicalResource, repository );
}
}
else
{
+ boolean isPut = WebdavMethodUtil.isWriteMethod( request.getMethod() );
for( String repository : repositories )
{
try
- {
- if( servletAuth.isAuthorized( activePrincipal, repository ) )
+ {
+ if( servletAuth.isAuthorized( activePrincipal, repository, isPut ) )
{
allow = true;
break;
return true;
}
}
+
+ public void setServletAuth( ServletAuthenticator servletAuth )
+ {
+ this.servletAuth = servletAuth;
+ }
+
+ public void setHttpAuth( HttpAuthenticator httpAuth )
+ {
+ this.httpAuth = httpAuth;
+ }
}
import org.apache.jackrabbit.webdav.DavException;
import org.apache.jackrabbit.webdav.DavServletRequest;
import org.apache.maven.archiva.webdav.util.RepositoryPathUtil;
+import org.apache.maven.archiva.webdav.util.WebdavMethodUtil;
import org.apache.maven.archiva.security.ArchivaXworkUser;
import org.apache.maven.archiva.security.ServletAuthenticator;
import org.codehaus.plexus.redback.authentication.AuthenticationException;
}
catch ( AuthenticationException e )
{
+ boolean isPut = WebdavMethodUtil.isWriteMethod( request.getMethod() );
+
// safety check for MRM-911
String guest = archivaXworkUser.getGuest();
try
{
if( servletAuth.isAuthorized( guest,
- ( ( ArchivaDavResourceLocator ) request.getRequestLocator() ).getRepositoryId() ) )
+ ( ( ArchivaDavResourceLocator ) request.getRequestLocator() ).getRepositoryId(), isPut ) )
{
request.setDavSession(new ArchivaDavSession());
return true;
return true;
}
- public boolean isAuthorized(String arg0, String arg1)
+ public boolean isAuthorized(String arg0, String arg1, boolean isWriteRequest)
throws UnauthorizedException
{
return true;
package org.apache.maven.archiva.webdav;
-/**
- * RepositoryServletSecurityTest
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
*
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.servlet.http.HttpServletResponse;
+
+import net.sf.ehcache.CacheManager;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.jackrabbit.webdav.DavResourceFactory;
+import org.apache.jackrabbit.webdav.DavSessionProvider;
+import org.apache.maven.archiva.configuration.ArchivaConfiguration;
+import org.apache.maven.archiva.configuration.Configuration;
+import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
+import org.apache.maven.archiva.security.ArchivaXworkUser;
+import org.apache.maven.archiva.security.ServletAuthenticator;
+import org.codehaus.plexus.redback.authentication.AuthenticationException;
+import org.codehaus.plexus.redback.authentication.AuthenticationResult;
+import org.codehaus.plexus.redback.authorization.UnauthorizedException;
+import org.codehaus.plexus.redback.system.DefaultSecuritySession;
+import org.codehaus.plexus.redback.system.SecuritySession;
+import org.codehaus.plexus.redback.xwork.filter.authentication.HttpAuthenticator;
+import org.codehaus.plexus.redback.xwork.filter.authentication.basic.HttpBasicAuthentication;
+import org.codehaus.plexus.spring.PlexusInSpringTestCase;
+import org.easymock.MockControl;
+import org.easymock.classextension.MockClassControl;
+import org.easymock.internal.AlwaysMatcher;
+
+import com.meterware.httpunit.GetMethodWebRequest;
+import com.meterware.httpunit.HttpUnitOptions;
+import com.meterware.httpunit.PutMethodWebRequest;
+import com.meterware.httpunit.WebRequest;
+import com.meterware.httpunit.WebResponse;
+import com.meterware.servletunit.InvocationContext;
+import com.meterware.servletunit.ServletRunner;
+import com.meterware.servletunit.ServletUnitClient;
+
+/**
+ * RepositoryServletSecurityTest
+ *
+ * Test the flow of the authentication and authorization checks. This does not necessarily
+ * perform redback security checking.
+ *
* @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
* @version $Id$
*/
public class RepositoryServletSecurityTest
- extends AbstractRepositoryServletTestCase
+ extends PlexusInSpringTestCase
{
- public void testSecuredGet()
+ protected static final String REPOID_INTERNAL = "internal";
+
+ protected ServletUnitClient sc;
+
+ protected File repoRootInternal;
+
+ private ServletRunner sr;
+
+ protected ArchivaConfiguration archivaConfiguration;
+
+ private DavSessionProvider davSessionProvider;
+
+ private MockControl servletAuthControl;
+
+ private ServletAuthenticator servletAuth;
+
+ private MockClassControl httpAuthControl;
+
+ private HttpAuthenticator httpAuth;
+
+ private ArchivaXworkUser archivaXworkUser;
+
+ private RepositoryServlet servlet;
+
+ public void setUp()
+ throws Exception
+ {
+ super.setUp();
+
+ String appserverBase = getTestFile( "target/appserver-base" ).getAbsolutePath();
+ System.setProperty( "appserver.base", appserverBase );
+
+ File testConf = getTestFile( "src/test/resources/repository-archiva.xml" );
+ File testConfDest = new File( appserverBase, "conf/archiva.xml" );
+ FileUtils.copyFile( testConf, testConfDest );
+
+ archivaConfiguration = (ArchivaConfiguration) lookup( ArchivaConfiguration.class );
+ repoRootInternal = new File( appserverBase, "data/repositories/internal" );
+ Configuration config = archivaConfiguration.getConfiguration();
+
+ config.addManagedRepository( createManagedRepository( REPOID_INTERNAL, "Internal Test Repo", repoRootInternal ) );
+ saveConfiguration( archivaConfiguration );
+
+ CacheManager.getInstance().removeCache( "url-failures-cache" );
+
+ HttpUnitOptions.setExceptionsThrownOnErrorStatus( false );
+
+ sr = new ServletRunner( getTestFile( "src/test/resources/WEB-INF/repository-servlet-security-test/web.xml" ) );
+ sr.registerServlet( "/repository/*", RepositoryServlet.class.getName() );
+ sc = sr.newClient();
+
+ servletAuthControl = MockControl.createControl( ServletAuthenticator.class );
+ servletAuthControl.setDefaultMatcher( MockControl.ALWAYS_MATCHER );
+ servletAuth = (ServletAuthenticator) servletAuthControl.getMock();
+
+ httpAuthControl =
+ MockClassControl.createControl( HttpBasicAuthentication.class, HttpBasicAuthentication.class.getMethods() );
+ httpAuthControl.setDefaultMatcher( MockControl.ALWAYS_MATCHER );
+ httpAuth = (HttpAuthenticator) httpAuthControl.getMock();
+
+ archivaXworkUser = new ArchivaXworkUser();
+ archivaXworkUser.setGuest( "guest" );
+
+ davSessionProvider = new ArchivaDavSessionProvider( servletAuth, httpAuth, archivaXworkUser );
+ }
+
+ protected ManagedRepositoryConfiguration createManagedRepository( String id, String name, File location )
{
+ ManagedRepositoryConfiguration repo = new ManagedRepositoryConfiguration();
+ repo.setId( id );
+ repo.setName( name );
+ repo.setLocation( location.getAbsolutePath() );
+ return repo;
+ }
+
+ protected void saveConfiguration()
+ throws Exception
+ {
+ saveConfiguration( archivaConfiguration );
+ }
+
+ protected void saveConfiguration( ArchivaConfiguration archivaConfiguration )
+ throws Exception
+ {
+ archivaConfiguration.save( archivaConfiguration.getConfiguration() );
+ }
+
+ protected void setupCleanRepo( File repoRootDir )
+ throws IOException
+ {
+ FileUtils.deleteDirectory( repoRootDir );
+ if ( !repoRootDir.exists() )
+ {
+ repoRootDir.mkdirs();
+ }
+ }
+
+ @Override
+ protected String getPlexusConfigLocation()
+ {
+ return "org/apache/maven/archiva/webdav/RepositoryServletSecurityTest.xml";
+ }
+
+ @Override
+ protected void tearDown()
+ throws Exception
+ {
+ if ( sc != null )
+ {
+ sc.clearContents();
+ }
+
+ if ( sr != null )
+ {
+ sr.shutDown();
+ }
+
+ if ( repoRootInternal.exists() )
+ {
+ FileUtils.deleteDirectory(repoRootInternal);
+ }
+
+ servlet = null;
+ super.tearDown();
}
-
- public void testSecuredBrowse()
+
+ // test deploy with invalid user, and guest has no write access to repo
+ // 401 must be returned
+ public void testPutWithInvalidUserAndGuestHasNoWriteAccess()
+ throws Exception
{
+ setupCleanRepo( repoRootInternal );
+
+ String putUrl = "http://machine.com/repository/internal/path/to/artifact.jar";
+ InputStream is = getClass().getResourceAsStream( "/artifact.jar" );
+ assertNotNull( "artifact.jar inputstream", is );
+
+ WebRequest request = new PutMethodWebRequest( putUrl, is, "application/octet-stream" );
+ InvocationContext ic = sc.newInvocation( request );
+ servlet = (RepositoryServlet) ic.getServlet();
+ servlet.setDavSessionProvider( davSessionProvider );
+
+ AuthenticationResult result = new AuthenticationResult();
+ httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
+ servletAuthControl.expectAndThrow( servletAuth.isAuthenticated( null, null ),
+ new AuthenticationException( "Authentication error" ) );
+
+ servletAuth.isAuthorized( "guest", "internal", true );
+ servletAuthControl.setMatcher( MockControl.EQUALS_MATCHER );
+ servletAuthControl.setThrowable( new UnauthorizedException( "'guest' has no write access to repository" ) );
+
+ httpAuthControl.replay();
+ servletAuthControl.replay();
+
+ servlet.service( ic.getRequest(), ic.getResponse() );
+
+ httpAuthControl.verify();
+ servletAuthControl.verify();
+
+ //assertEquals(HttpServletResponse.SC_UNAUTHORIZED, response.getResponseCode());
+ }
+
+ // test deploy with invalid user, but guest has write access to repo
+ public void testPutWithInvalidUserAndGuestHasWriteAccess()
+ throws Exception
+ {
+ setupCleanRepo( repoRootInternal );
+
+ String putUrl = "http://machine.com/repository/internal/path/to/artifact.jar";
+ InputStream is = getClass().getResourceAsStream( "/artifact.jar" );
+ assertNotNull( "artifact.jar inputstream", is );
+
+ WebRequest request = new PutMethodWebRequest( putUrl, is, "application/octet-stream" );
+
+ InvocationContext ic = sc.newInvocation( request );
+ servlet = (RepositoryServlet) ic.getServlet();
+ servlet.setDavSessionProvider( davSessionProvider );
+
+ ArchivaDavResourceFactory archivaDavResourceFactory = (ArchivaDavResourceFactory) servlet.getResourceFactory();
+ archivaDavResourceFactory.setHttpAuth( httpAuth );
+ archivaDavResourceFactory.setServletAuth( servletAuth );
+
+ servlet.setResourceFactory( archivaDavResourceFactory );
+
+ AuthenticationResult result = new AuthenticationResult();
+ httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
+ servletAuthControl.expectAndThrow( servletAuth.isAuthenticated( null, null ),
+ new AuthenticationException( "Authentication error" ) );
+
+ servletAuth.isAuthorized( "guest", "internal", true );
+ servletAuthControl.setMatcher( MockControl.EQUALS_MATCHER );
+ servletAuthControl.setReturnValue( true );
+
+ // ArchivaDavResourceFactory#isAuthorized()
+ SecuritySession session = new DefaultSecuritySession();
+ httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
+ httpAuthControl.expectAndReturn( httpAuth.getSecuritySession(), session );
+ servletAuthControl.expectAndThrow( servletAuth.isAuthenticated( null, result ),
+ new AuthenticationException( "Authentication error" ) );
+
+ // check if guest has write access
+ servletAuth.isAuthorized( "guest", "internal", true );
+ servletAuthControl.setMatcher( MockControl.EQUALS_MATCHER );
+ servletAuthControl.setReturnValue( true );
+
+ httpAuthControl.replay();
+ servletAuthControl.replay();
+
+ servlet.service( ic.getRequest(), ic.getResponse() );
+
+ httpAuthControl.verify();
+ servletAuthControl.verify();
+
+ // assertEquals( HttpServletResponse.SC_CREATED, response.getResponseCode() );
+ }
+
+ // test deploy with a valid user with no write access
+ public void testPutWithValidUserWithNoWriteAccess()
+ throws Exception
+ {
+ setupCleanRepo( repoRootInternal );
+
+ String putUrl = "http://machine.com/repository/internal/path/to/artifact.jar";
+ InputStream is = getClass().getResourceAsStream( "/artifact.jar" );
+ assertNotNull( "artifact.jar inputstream", is );
+
+ WebRequest request = new PutMethodWebRequest( putUrl, is, "application/octet-stream" );
+
+ InvocationContext ic = sc.newInvocation( request );
+ servlet = (RepositoryServlet) ic.getServlet();
+ servlet.setDavSessionProvider( davSessionProvider );
+
+ ArchivaDavResourceFactory archivaDavResourceFactory = (ArchivaDavResourceFactory) servlet.getResourceFactory();
+ archivaDavResourceFactory.setHttpAuth( httpAuth );
+ archivaDavResourceFactory.setServletAuth( servletAuth );
+ servlet.setResourceFactory( archivaDavResourceFactory );
+
+ AuthenticationResult result = new AuthenticationResult();
+ httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
+ servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, null ), true );
+
+ // ArchivaDavResourceFactory#isAuthorized()
+ SecuritySession session = new DefaultSecuritySession();
+ httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
+ httpAuthControl.expectAndReturn( httpAuth.getSecuritySession(), session );
+ servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, result ), true );
+ servletAuthControl.expectAndThrow( servletAuth.isAuthorized( null, session, "internal", true ),
+ new UnauthorizedException( "User not authorized" ) );
+
+ httpAuthControl.replay();
+ servletAuthControl.replay();
+
+ servlet.service( ic.getRequest(), ic.getResponse() );
+
+ httpAuthControl.verify();
+ servletAuthControl.verify();
+
+ // assertEquals(HttpServletResponse.SC_UNAUTHORIZED, response.getResponseCode());
+ }
+
+ // test deploy with a valid user with write access
+ public void testPutWithValidUserWithWriteAccess()
+ throws Exception
+ {
+ setupCleanRepo( repoRootInternal );
+ assertTrue( repoRootInternal.exists() );
+
+ String putUrl = "http://machine.com/repository/internal/path/to/artifact.jar";
+ InputStream is = getClass().getResourceAsStream( "/artifact.jar" );
+ assertNotNull( "artifact.jar inputstream", is );
+
+ WebRequest request = new PutMethodWebRequest( putUrl, is, "application/octet-stream" );
+
+ InvocationContext ic = sc.newInvocation( request );
+ servlet = (RepositoryServlet) ic.getServlet();
+ servlet.setDavSessionProvider( davSessionProvider );
+
+ ArchivaDavResourceFactory archivaDavResourceFactory = (ArchivaDavResourceFactory) servlet.getResourceFactory();
+ archivaDavResourceFactory.setHttpAuth( httpAuth );
+ archivaDavResourceFactory.setServletAuth( servletAuth );
+
+ servlet.setResourceFactory( archivaDavResourceFactory );
+
+ AuthenticationResult result = new AuthenticationResult();
+ httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
+ servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, null ), true );
+
+ // ArchivaDavResourceFactory#isAuthorized()
+ SecuritySession session = new DefaultSecuritySession();
+ httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
+ httpAuthControl.expectAndReturn( httpAuth.getSecuritySession(), session );
+ servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, result ), true );
+ servletAuthControl.expectAndReturn( servletAuth.isAuthorized( null, session, "internal", true ), true );
+
+ httpAuthControl.replay();
+ servletAuthControl.replay();
+
+ servlet.service( ic.getRequest(), ic.getResponse() );
+
+ httpAuthControl.verify();
+ servletAuthControl.verify();
+
+ // assertEquals(HttpServletResponse.SC_CREATED, response.getResponseCode());
+ }
+
+ // test get with invalid user, and guest has read access to repo
+ public void testGetWithInvalidUserAndGuestHasReadAccess()
+ throws Exception
+ {
+ String commonsLangJar = "commons-lang/commons-lang/2.1/commons-lang-2.1.jar";
+ String expectedArtifactContents = "dummy-commons-lang-artifact";
+
+ File artifactFile = new File( repoRootInternal, commonsLangJar );
+ artifactFile.getParentFile().mkdirs();
+
+ FileUtils.writeStringToFile( artifactFile, expectedArtifactContents, null );
+
+ WebRequest request = new GetMethodWebRequest( "http://machine.com/repository/internal/" + commonsLangJar );
+ InvocationContext ic = sc.newInvocation( request );
+ servlet = (RepositoryServlet) ic.getServlet();
+ servlet.setDavSessionProvider( davSessionProvider );
+
+ ArchivaDavResourceFactory archivaDavResourceFactory = (ArchivaDavResourceFactory) servlet.getResourceFactory();
+ archivaDavResourceFactory.setHttpAuth( httpAuth );
+ archivaDavResourceFactory.setServletAuth( servletAuth );
+
+ servlet.setResourceFactory( archivaDavResourceFactory );
+
+ AuthenticationResult result = new AuthenticationResult();
+ httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
+ servletAuthControl.expectAndThrow( servletAuth.isAuthenticated( null, null ),
+ new AuthenticationException( "Authentication error" ) );
+ servletAuthControl.expectAndReturn( servletAuth.isAuthorized( "guest", "internal", false ), true );
+
+ // ArchivaDavResourceFactory#isAuthorized()
+ SecuritySession session = new DefaultSecuritySession();
+ httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
+ httpAuthControl.expectAndReturn( httpAuth.getSecuritySession(), session );
+ servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, result ), true );
+ servletAuthControl.expectAndReturn( servletAuth.isAuthorized( null, session, "internal", true ), true );
+
+ httpAuthControl.replay();
+ servletAuthControl.replay();
+
+ WebResponse response = sc.getResponse( request );
+
+ httpAuthControl.verify();
+ servletAuthControl.verify();
+
+ assertEquals( HttpServletResponse.SC_OK, response.getResponseCode() );
+ assertEquals( "Expected file contents", expectedArtifactContents, response.getText() );
+ }
+
+ // test get with invalid user, and guest has no read access to repo
+ public void testGetWithInvalidUserAndGuestHasNoReadAccess()
+ throws Exception
+ {
+ String commonsLangJar = "commons-lang/commons-lang/2.1/commons-lang-2.1.jar";
+ String expectedArtifactContents = "dummy-commons-lang-artifact";
+
+ File artifactFile = new File( repoRootInternal, commonsLangJar );
+ artifactFile.getParentFile().mkdirs();
+
+ FileUtils.writeStringToFile( artifactFile, expectedArtifactContents, null );
+
+ WebRequest request = new GetMethodWebRequest( "http://machine.com/repository/internal/" + commonsLangJar );
+ InvocationContext ic = sc.newInvocation( request );
+ servlet = (RepositoryServlet) ic.getServlet();
+ servlet.setDavSessionProvider( davSessionProvider );
+
+ AuthenticationResult result = new AuthenticationResult();
+ httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
+ servletAuthControl.expectAndThrow( servletAuth.isAuthenticated( null, null ),
+ new AuthenticationException( "Authentication error" ) );
+ servletAuthControl.expectAndReturn( servletAuth.isAuthorized( "guest", "internal", false ), false );
+
+ httpAuthControl.replay();
+ servletAuthControl.replay();
+
+ WebResponse response = sc.getResponse( request );
+
+ httpAuthControl.verify();
+ servletAuthControl.verify();
+
+ assertEquals( HttpServletResponse.SC_UNAUTHORIZED, response.getResponseCode() );
+ }
+
+ // test get with valid user with read access to repo
+ public void testGetWithAValidUserWithReadAccess()
+ throws Exception
+ {
+ String commonsLangJar = "commons-lang/commons-lang/2.1/commons-lang-2.1.jar";
+ String expectedArtifactContents = "dummy-commons-lang-artifact";
+
+ File artifactFile = new File( repoRootInternal, commonsLangJar );
+ artifactFile.getParentFile().mkdirs();
+
+ FileUtils.writeStringToFile( artifactFile, expectedArtifactContents, null );
+
+ WebRequest request = new GetMethodWebRequest( "http://machine.com/repository/internal/" + commonsLangJar );
+ InvocationContext ic = sc.newInvocation( request );
+ servlet = (RepositoryServlet) ic.getServlet();
+ servlet.setDavSessionProvider( davSessionProvider );
+
+ ArchivaDavResourceFactory archivaDavResourceFactory = (ArchivaDavResourceFactory) servlet.getResourceFactory();
+ archivaDavResourceFactory.setHttpAuth( httpAuth );
+ archivaDavResourceFactory.setServletAuth( servletAuth );
+
+ servlet.setResourceFactory( archivaDavResourceFactory );
+
+ AuthenticationResult result = new AuthenticationResult();
+ httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
+ servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, null ), true );
+
+ // ArchivaDavResourceFactory#isAuthorized()
+ SecuritySession session = new DefaultSecuritySession();
+ httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
+ httpAuthControl.expectAndReturn( httpAuth.getSecuritySession(), session );
+ servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, result ), true );
+ servletAuthControl.expectAndReturn( servletAuth.isAuthorized( null, session, "internal", true ), true );
+
+ httpAuthControl.replay();
+ servletAuthControl.replay();
+
+ WebResponse response = sc.getResponse( request );
+
+ httpAuthControl.verify();
+ servletAuthControl.verify();
+
+ assertEquals( HttpServletResponse.SC_OK, response.getResponseCode() );
+ assertEquals( "Expected file contents", expectedArtifactContents, response.getText() );
+ }
+
+ // test get with valid user with no read access to repo
+ public void testGetWithAValidUserWithNoReadAccess()
+ throws Exception
+ {
+ String commonsLangJar = "commons-lang/commons-lang/2.1/commons-lang-2.1.jar";
+ String expectedArtifactContents = "dummy-commons-lang-artifact";
+
+ File artifactFile = new File( repoRootInternal, commonsLangJar );
+ artifactFile.getParentFile().mkdirs();
+
+ FileUtils.writeStringToFile( artifactFile, expectedArtifactContents, null );
+
+ WebRequest request = new GetMethodWebRequest( "http://machine.com/repository/internal/" + commonsLangJar );
+ InvocationContext ic = sc.newInvocation( request );
+ servlet = (RepositoryServlet) ic.getServlet();
+ servlet.setDavSessionProvider( davSessionProvider );
+
+ ArchivaDavResourceFactory archivaDavResourceFactory = (ArchivaDavResourceFactory) servlet.getResourceFactory();
+ archivaDavResourceFactory.setHttpAuth( httpAuth );
+ archivaDavResourceFactory.setServletAuth( servletAuth );
+
+ servlet.setResourceFactory( archivaDavResourceFactory );
+
+ AuthenticationResult result = new AuthenticationResult();
+ httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
+ servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, null ), true );
+
+ // ArchivaDavResourceFactory#isAuthorized()
+ SecuritySession session = new DefaultSecuritySession();
+ httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
+ httpAuthControl.expectAndReturn( httpAuth.getSecuritySession(), session );
+ servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, result ), true );
+ servletAuthControl.expectAndThrow( servletAuth.isAuthorized( null, session, "internal", true ),
+ new UnauthorizedException( "User not authorized to read repository." ) );
+
+ httpAuthControl.replay();
+ servletAuthControl.replay();
+
+ WebResponse response = sc.getResponse( request );
+
+ httpAuthControl.verify();
+ servletAuthControl.verify();
+ assertEquals( HttpServletResponse.SC_UNAUTHORIZED, response.getResponseCode() );
}
}
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ ~ 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.
+ -->
+
+<web-app xmlns="http://java.sun.com/xml/ns/j2ee" version="2.4"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
+
+ <display-name>Apache Archiva</display-name>
+
+ <listener>
+ <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
+ </listener>
+
+ <context-param>
+ <param-name>contextClass</param-name>
+ <param-value>org.codehaus.plexus.spring.PlexusWebApplicationContext</param-value>
+ </context-param>
+
+ <context-param>
+ <param-name>contextConfigLocation</param-name>
+ <param-value>
+ classpath*:/META-INF/plexus/components.xml
+ classpath*:/META-INF/spring-context.xml
+ target/test-classes/org/apache/maven/archiva/webdav/RepositoryServletSecurityTest.xml
+ </param-value>
+ </context-param>
+
+</web-app>
<role-hint>default</role-hint>
<implementation>org.apache.maven.archiva.webdav.DefaultDavServerManager</implementation>
<description>DefaultDavServerManager</description>
- <configuration>
- <provider-hint>proxied</provider-hint>
- </configuration>
+ <requirements>
+ <requirement>
+ <role>org.apache.maven.archiva.webdav.DavServerComponent</role>
+ <role-hint>proxied</role-hint>
+ </requirement>
+ </requirements>
</component>
<component>
<component>
<role>org.apache.maven.archiva.repository.scanner.RepositoryContentConsumers</role>
<role-hint>default</role-hint>
- <implementation>org.apache.maven.archiva.web.repository.StubRepositoryContentConsumers</implementation>
+ <implementation>org.apache.maven.archiva.webdav.StubRepositoryContentConsumers</implementation>
</component>
-
- <!-- TODO: shouldn't need so many components just to use in-memory - is flaky since these are auto-generated -->
+
<component>
<role>org.codehaus.plexus.redback.system.SecuritySystem</role>
<role-hint>default</role-hint>
<implementation>org.codehaus.plexus.redback.system.DefaultSecuritySystem</implementation>
- <requirements>
- <requirement>
- <role>org.codehaus.plexus.redback.authentication.AuthenticationManager</role>
- <field-name>authnManager</field-name>
- </requirement>
- <requirement>
- <role>org.codehaus.plexus.redback.authorization.Authorizer</role>
- <role-hint>rbac</role-hint>
- <field-name>authorizer</field-name>
- </requirement>
- <requirement>
- <role>org.codehaus.plexus.redback.users.UserManager</role>
- <role-hint>memory</role-hint>
- <field-name>userManager</field-name>
- </requirement>
- <requirement>
- <role>org.codehaus.plexus.redback.keys.KeyManager</role>
- <role-hint>memory</role-hint>
- <field-name>keyManager</field-name>
- </requirement>
- <requirement>
- <role>org.codehaus.plexus.redback.policy.UserSecurityPolicy</role>
- <field-name>policy</field-name>
- </requirement>
- </requirements>
</component>
-
- <component>
- <role>org.codehaus.plexus.redback.authentication.Authenticator</role>
- <role-hint>user-manager</role-hint>
- <implementation>org.codehaus.plexus.redback.authentication.users.UserManagerAuthenticator</implementation>
+
+ <component>
+ <role>org.apache.maven.archiva.webdav.ArchivaDavResourceFactory</role>
+ <implementation>org.apache.maven.archiva.webdav.ArchivaDavResourceFactory</implementation>
<requirements>
<requirement>
- <role>org.codehaus.plexus.redback.users.UserManager</role>
- <role-hint>memory</role-hint>
- <field-name>userManager</field-name>
+ <role>org.apache.maven.archiva.configuration.ArchivaConfiguration</role>
+ <field-name>archivaConfiguration</field-name>
</requirement>
<requirement>
- <role>org.codehaus.plexus.redback.policy.UserSecurityPolicy</role>
- <field-name>securityPolicy</field-name>
- </requirement>
- </requirements>
- </component>
-
- <component>
- <role>org.codehaus.plexus.redback.authentication.Authenticator</role>
- <role-hint>keystore</role-hint>
- <implementation>org.codehaus.plexus.redback.authentication.keystore.KeyStoreAuthenticator</implementation>
- <requirements>
- <requirement>
- <role>org.codehaus.plexus.redback.keys.KeyManager</role>
- <role-hint>memory</role-hint>
- <field-name>keystore</field-name>
- </requirement>
- <requirement>
- <role>org.codehaus.plexus.redback.users.UserManager</role>
- <role-hint>memory</role-hint>
- <field-name>userManager</field-name>
- </requirement>
- </requirements>
- </component>
-
- <component>
- <role>org.codehaus.plexus.redback.authorization.rbac.evaluator.PermissionEvaluator</role>
- <role-hint>default</role-hint>
- <implementation>org.codehaus.plexus.redback.authorization.rbac.evaluator.DefaultPermissionEvaluator
- </implementation>
- <requirements>
- <requirement>
- <role>org.codehaus.plexus.redback.users.UserManager</role>
- <role-hint>memory</role-hint>
- <field-name>userManager</field-name>
- </requirement>
- </requirements>
- </component>
-
- <component>
- <role>org.codehaus.plexus.redback.authorization.Authorizer</role>
- <role-hint>rbac</role-hint>
- <implementation>org.codehaus.plexus.redback.authorization.rbac.RbacAuthorizer</implementation>
- <requirements>
+ <role>org.apache.maven.archiva.repository.RepositoryContentFactory</role>
+ <field-name>repositoryFactory</field-name>
+ </requirement>
<requirement>
- <role>org.codehaus.plexus.redback.rbac.RBACManager</role>
- <role-hint>memory</role-hint>
- <field-name>manager</field-name>
+ <role>org.apache.maven.archiva.repository.content.RepositoryRequest</role>
+ <field-name>repositoryRequest</field-name>
</requirement>
<requirement>
- <role>org.codehaus.plexus.redback.users.UserManager</role>
- <role-hint>memory</role-hint>
- <field-name>userManager</field-name>
+ <role>org.apache.maven.archiva.proxy.RepositoryProxyConnectors</role>
+ <field-name>connectors</field-name>
</requirement>
<requirement>
- <role>org.codehaus.plexus.redback.authorization.rbac.evaluator.PermissionEvaluator</role>
- <role-hint>default</role-hint>
- <field-name>evaluator</field-name>
+ <role>org.apache.maven.archiva.repository.metadata.MetadataTools</role>
+ <field-name>metadataTools</field-name>
</requirement>
- </requirements>
- </component>
-
- <component>
- <role>org.codehaus.plexus.redback.role.RoleManager</role>
- <role-hint>default</role-hint>
- <implementation>org.codehaus.plexus.redback.role.DefaultRoleManager</implementation>
- <instantiation-strategy>singleton</instantiation-strategy>
- <requirements>
<requirement>
- <role>org.codehaus.plexus.redback.role.merger.RoleModelMerger</role>
- <role-hint>default</role-hint>
- <field-name>modelMerger</field-name>
+ <role>org.apache.maven.archiva.security.ServletAuthenticator</role>
+ <field-name>servletAuth</field-name>
</requirement>
<requirement>
- <role>org.codehaus.plexus.redback.role.validator.RoleModelValidator</role>
- <role-hint>default</role-hint>
- <field-name>modelValidator</field-name>
+ <role>org.apache.maven.archiva.webdav.util.MimeTypes</role>
+ <field-name>mimeTypes</field-name>
</requirement>
<requirement>
- <role>org.codehaus.plexus.redback.role.processor.RoleModelProcessor</role>
- <role-hint>default</role-hint>
- <field-name>modelProcessor</field-name>
+ <role>org.codehaus.plexus.redback.xwork.filter.authentication.HttpAuthenticator</role>
+ <role-hint>basic</role-hint>
+ <field-name>httpAuth</field-name>
</requirement>
<requirement>
- <role>org.codehaus.plexus.redback.role.template.RoleTemplateProcessor</role>
+ <role>org.apache.maven.archiva.repository.scanner.RepositoryContentConsumers</role>
<role-hint>default</role-hint>
- <field-name>templateProcessor</field-name>
</requirement>
<requirement>
- <role>org.codehaus.plexus.redback.rbac.RBACManager</role>
- <role-hint>memory</role-hint>
- <field-name>rbacManager</field-name>
+ <role>org.codehaus.plexus.digest.ChecksumFile</role>
+ <field-name>checksum</field-name>
</requirement>
<requirement>
- <role>org.codehaus.plexus.PlexusContainer</role>
- <field-name>container</field-name>
+ <role>org.codehaus.plexus.digest.Digester</role>
+ <role-hint>sha1</role-hint>
+ <field-name>digestSha1</field-name>
</requirement>
- </requirements>
- </component>
-
- <component>
- <role>org.codehaus.plexus.redback.role.processor.RoleModelProcessor</role>
- <role-hint>default</role-hint>
- <implementation>org.codehaus.plexus.redback.role.processor.DefaultRoleModelProcessor</implementation>
- <requirements>
<requirement>
- <role>org.codehaus.plexus.redback.rbac.RBACManager</role>
- <role-hint>memory</role-hint>
- <field-name>rbacManager</field-name>
+ <role>org.codehaus.plexus.digest.Digester</role>
+ <role-hint>md5</role-hint>
+ <field-name>digestMd5</field-name>
</requirement>
- </requirements>
- </component>
-
- <component>
- <role>org.codehaus.plexus.redback.role.template.RoleTemplateProcessor</role>
- <role-hint>default</role-hint>
- <implementation>org.codehaus.plexus.redback.role.template.DefaultRoleTemplateProcessor</implementation>
- <requirements>
<requirement>
- <role>org.codehaus.plexus.redback.rbac.RBACManager</role>
- <role-hint>memory</role-hint>
- <field-name>rbacManager</field-name>
- </requirement>
+ <role>org.apache.maven.archiva.security.ArchivaXworkUser</role>
+ <field-name>archivaXworkUser</field-name>
+ </requirement>
</requirements>
</component>
</components>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
- <version>1.0-alpha-3</version>
+ <version>1.0-alpha-4</version>
<executions>
<execution>
<goals>
<version>1.2_Java1.3</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>easymock</groupId>
+ <artifactId>easymockclassextension</artifactId>
+ <version>1.2</version>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl104-over-slf4j</artifactId>