import org.apache.archiva.model.ArtifactReference;
import org.apache.archiva.model.VersionedReference;
+import org.apache.archiva.repository.content.ItemSelector;
/**
* @return the relative path to the artifact.
*/
String toPath( ArtifactReference reference );
+
+
+ /**
+ * Return the path, that represents the item specified by the selector.
+ * @param selector the selector with the artifact coordinates
+ * @return the path to the content item
+ */
+ String toPath( ItemSelector selector );
}
* under the License.
*/
-import org.apache.archiva.repository.UnsupportedRepositoryTypeException;
import org.apache.archiva.repository.storage.StorageAsset;
-import java.util.Map;
-
/**
*
* Represents a artifact of a repository. This object contains unique coordinates of the
--- /dev/null
+package org.apache.archiva.repository.content;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Map;
+
+/**
+ * The item selector is used to specify coordinates for retrieving ContentItem elements.
+ */
+public interface ItemSelector
+{
+
+ String getProjectId();
+
+ String getNamespace();
+
+ String getVersion( );
+
+ String getArtifactVersion();
+
+ String getArtifactId( );
+
+ String getType();
+
+ String getClassifier();
+
+ String getAttribute( String key );
+
+ Map<String, String> getAttributes( );
+
+ default boolean hasNamespace() {
+ return !StringUtils.isEmpty( getNamespace( ) );
+ }
+
+ default boolean hasProjectId() {
+ return !StringUtils.isEmpty( getProjectId( ) );
+ }
+
+ default boolean hasVersion() {
+ return !StringUtils.isEmpty(getVersion());
+ }
+
+ default boolean hasArtifactId() {
+ return !StringUtils.isEmpty( getArtifactId( ) );
+ }
+
+ default boolean hasArtifactVersion() {
+ return !StringUtils.isEmpty( getArtifactVersion( ) );
+ }
+
+ default boolean hasType() {
+ return !StringUtils.isEmpty( getType( ) );
+ }
+
+ default boolean hasClassifier() {
+ return !StringUtils.isEmpty( getClassifier( ) );
+ }
+
+ boolean hasAttributes();
+}
* under the License.
*/
-import org.apache.archiva.repository.ManagedRepositoryContent;
+import org.apache.archiva.repository.RepositoryContent;
import org.apache.archiva.repository.storage.StorageAsset;
/**
* The repository this project is part of.
* @return the repository content
*/
- ManagedRepositoryContent getRepository();
+ RepositoryContent getRepository();
/**
* Returns the asset that corresponds to this project.
--- /dev/null
+package org.apache.archiva.repository.content.base;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.archiva.repository.content.ItemSelector;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Item selector for querying artifacts and other content items.
+ */
+public class ArchivaItemSelector implements ItemSelector
+{
+
+ private String projectId = null;
+ private String version = null;
+ private String artifactVersion = null;
+ private String artifactId = null;
+ private String namespace = "";
+ private String type = null;
+ private String classifier = null;
+ private Map<String,String> attributes;
+
+
+ private ArchivaItemSelector() {
+
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder
+ {
+ private final ArchivaItemSelector selector = new ArchivaItemSelector( );
+
+ public Builder withNamespace( String namespace )
+ {
+ selector.namespace = namespace;
+ return this;
+ }
+
+
+ public Builder withProjectId( String projectId )
+ {
+ selector.projectId = projectId;
+ return this;
+ }
+
+
+ public Builder withVersion( String version )
+ {
+ selector.version = version;
+ return this;
+ }
+
+
+ public Builder withArtifactVersion( String artifactVersion )
+ {
+ selector.artifactVersion = artifactVersion;
+ return this;
+ }
+
+
+ public Builder withArtifactId( String artifactId )
+ {
+ selector.artifactId = artifactId;
+ return this;
+ }
+
+
+ public Builder withType( String type )
+ {
+ selector.type = type;
+ return this;
+ }
+
+
+ public Builder withClassifier( String classifier )
+ {
+ selector.classifier = classifier;
+ return this;
+ }
+
+
+ public Builder withAttribute( String key, String value )
+ {
+ selector.setAttribute( key, value );
+ return this;
+ }
+
+ public ArchivaItemSelector build() {
+ return selector;
+ }
+ }
+
+ private void setAttribute(String key, String value) {
+ if (this.attributes == null) {
+ this.attributes = new HashMap<>( );
+ }
+ this.attributes.put( key, value );
+ }
+
+ @Override
+ public String getProjectId( )
+ {
+ return projectId;
+ }
+
+ @Override
+ public String getNamespace( )
+ {
+ return namespace;
+ }
+
+ @Override
+ public String getVersion( )
+ {
+ return version;
+ }
+
+ @Override
+ public String getArtifactVersion( )
+ {
+ return artifactVersion;
+ }
+
+ @Override
+ public String getArtifactId( )
+ {
+ return artifactId;
+ }
+
+ @Override
+ public String getType( )
+ {
+ return type;
+ }
+
+ @Override
+ public String getClassifier( )
+ {
+ return classifier;
+ }
+
+ @Override
+ public String getAttribute( String key )
+ {
+ if ( this.attributes == null || !this.attributes.containsKey( key ) )
+ {
+
+ return "";
+ }
+ else
+ {
+ return this.attributes.get( key );
+ }
+ }
+
+ @Override
+ public Map<String, String> getAttributes( )
+ {
+ if (this.attributes==null) {
+ return Collections.emptyMap( );
+ } else {
+ return Collections.unmodifiableMap( this.attributes );
+ }
+ }
+
+ @Override
+ public boolean hasAttributes( )
+ {
+ return attributes!=null && attributes.size()>0;
+ }
+}
* under the License.
*/
+import org.apache.archiva.repository.ManagedRepository;
import org.apache.archiva.repository.ManagedRepositoryContent;
+import org.apache.archiva.repository.RepositoryContent;
import org.apache.archiva.repository.content.Project;
import org.apache.archiva.repository.storage.StorageAsset;
import org.apache.commons.lang3.StringUtils;
{
private String namespace;
private String id;
- private ManagedRepositoryContent repositoryContent;
+ private RepositoryContent repositoryContent;
private StorageAsset asset;
// Setting all setters to private. Builder is the way to go.
}
@Override
- public ManagedRepositoryContent getRepository( )
+ public RepositoryContent getRepository( )
{
return this.repositoryContent;
}
}
- public OptBuilder withRepository( ManagedRepositoryContent repository ) {
+ public OptBuilder withRepository( RepositoryContent repository ) {
project.repositoryContent = repository;
return this;
}
project.namespace = "";
}
if (project.asset == null) {
- project.asset = project.getRepository( ).getRepository( ).getAsset( "" );
+ if (project.getRepository() instanceof ManagedRepositoryContent) {
+ project.asset = (( ManagedRepositoryContent)project.getRepository( )).getRepository( ).getAsset( "" );
+ }
+
}
return project;
}
public ArchivaVersion build() {
if (this.version.asset == null) {
- this.version.project.getRepository( ).getRepository().getAsset( "" );
+ this.version.project.getAsset( );
}
return this.version;
}
--- /dev/null
+package org.apache.archiva.repository.content.base;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class ArchivaItemSelectorTest
+{
+
+ @Test
+ void getProjectId( )
+ {
+
+ ArchivaItemSelector selector = ArchivaItemSelector.builder( ).withProjectId( "test-project-123" ).build( );
+ assertEquals( "test-project-123", selector.getProjectId( ) );
+ assertTrue( selector.hasProjectId( ) );
+ assertFalse( selector.hasVersion( ) );
+ assertFalse( selector.hasArtifactId( ) );
+ assertFalse( selector.hasArtifactVersion( ) );
+ assertFalse( selector.hasType( ) );
+ assertFalse( selector.hasClassifier( ) );
+ assertFalse( selector.hasAttributes( ) );
+ }
+
+ @Test
+ void getNamespace( )
+ {
+ ArchivaItemSelector selector = ArchivaItemSelector.builder( ).withNamespace( "abc.de.fg" ).build();
+ assertEquals( "abc.de.fg", selector.getNamespace( ) );
+ assertFalse( selector.hasProjectId( ) );
+ assertFalse( selector.hasVersion( ) );
+ assertFalse( selector.hasArtifactId( ) );
+ assertFalse( selector.hasArtifactVersion( ) );
+ assertFalse( selector.hasType( ) );
+ assertFalse( selector.hasClassifier( ) );
+ assertFalse( selector.hasAttributes( ) );
+ }
+
+ @Test
+ void getVersion( )
+ {
+ ArchivaItemSelector selector = ArchivaItemSelector.builder( ).withVersion( "1.15.20.3" ).build();
+ assertEquals( "1.15.20.3", selector.getVersion( ) );
+ assertFalse( selector.hasProjectId( ) );
+ assertTrue( selector.hasVersion( ) );
+ assertFalse( selector.hasArtifactId( ) );
+ assertFalse( selector.hasArtifactVersion( ) );
+ assertFalse( selector.hasType( ) );
+ assertFalse( selector.hasClassifier( ) );
+ assertFalse( selector.hasAttributes( ) );
+ }
+
+ @Test
+ void getArtifactVersion( )
+ {
+ ArchivaItemSelector selector = ArchivaItemSelector.builder( ).withArtifactVersion( "5.13.2.4" ).build();
+ assertEquals( "5.13.2.4", selector.getArtifactVersion() );
+ assertFalse( selector.hasProjectId( ) );
+ assertFalse( selector.hasVersion( ) );
+ assertFalse( selector.hasArtifactId( ) );
+ assertTrue( selector.hasArtifactVersion( ) );
+ assertFalse( selector.hasType( ) );
+ assertFalse( selector.hasClassifier( ) );
+ assertFalse( selector.hasAttributes( ) );
+ }
+
+ @Test
+ void getArtifactId( )
+ {
+ ArchivaItemSelector selector = ArchivaItemSelector.builder( ).withArtifactId( "xml-tools" ).build();
+ assertEquals( "xml-tools", selector.getArtifactId() );
+ assertFalse( selector.hasProjectId( ) );
+ assertFalse( selector.hasVersion( ) );
+ assertTrue( selector.hasArtifactId( ) );
+ assertFalse( selector.hasArtifactVersion( ) );
+ assertFalse( selector.hasType( ) );
+ assertFalse( selector.hasClassifier( ) );
+ assertFalse( selector.hasAttributes( ) );
+
+ }
+
+ @Test
+ void getType( )
+ {
+ ArchivaItemSelector selector = ArchivaItemSelector.builder( ).withType( "javadoc" ).build();
+ assertEquals( "javadoc", selector.getType() );
+ assertFalse( selector.hasProjectId( ) );
+ assertFalse( selector.hasVersion( ) );
+ assertFalse( selector.hasArtifactId( ) );
+ assertFalse( selector.hasArtifactVersion( ) );
+ assertTrue( selector.hasType( ) );
+ assertFalse( selector.hasClassifier( ) );
+ assertFalse( selector.hasAttributes( ) );
+ }
+
+ @Test
+ void getClassifier( )
+ {
+ ArchivaItemSelector selector = ArchivaItemSelector.builder( ).withClassifier( "source" ).build();
+ assertEquals( "source", selector.getClassifier() );
+ assertFalse( selector.hasProjectId( ) );
+ assertFalse( selector.hasVersion( ) );
+ assertFalse( selector.hasArtifactId( ) );
+ assertFalse( selector.hasArtifactVersion( ) );
+ assertFalse( selector.hasType( ) );
+ assertTrue( selector.hasClassifier( ) );
+ assertFalse( selector.hasAttributes( ) );
+ }
+
+ @Test
+ void getAttribute( )
+ {
+ ArchivaItemSelector selector = ArchivaItemSelector.builder( ).withAttribute( "test1","value1" ).
+ withAttribute( "test2", "value2" ).build();
+ assertEquals( "value1", selector.getAttribute("test1") );
+ assertEquals( "value2", selector.getAttribute("test2") );
+ assertFalse( selector.hasProjectId( ) );
+ assertFalse( selector.hasVersion( ) );
+ assertFalse( selector.hasArtifactId( ) );
+ assertFalse( selector.hasArtifactVersion( ) );
+ assertFalse( selector.hasType( ) );
+ assertFalse( selector.hasClassifier( ) );
+ assertTrue( selector.hasAttributes( ) );
+ }
+
+}
\ No newline at end of file
import org.apache.archiva.repository.LayoutException;
import org.apache.archiva.repository.ManagedRepository;
import org.apache.archiva.repository.ManagedRepositoryContent;
+import org.apache.archiva.repository.content.ItemSelector;
import org.apache.archiva.repository.storage.StorageAsset;
import org.springframework.stereotype.Service;
return null;
}
+ @Override
+ public String toPath( ItemSelector selector )
+ {
+ return null;
+ }
+
@Override
public String toPath( ArchivaArtifact reference )
{
import org.apache.archiva.repository.LayoutException;
import org.apache.archiva.repository.RemoteRepository;
import org.apache.archiva.repository.RemoteRepositoryContent;
+import org.apache.archiva.repository.content.ItemSelector;
import org.springframework.stereotype.Service;
/**
return null;
}
+ @Override
+ public String toPath( ItemSelector selector )
+ {
+ return null;
+ }
+
@Override
public RepositoryURL toURL( ArtifactReference reference )
{
import org.apache.archiva.model.ProjectReference;
import org.apache.archiva.model.VersionedReference;
import org.apache.archiva.repository.*;
+import org.apache.archiva.repository.content.ItemSelector;
import org.apache.archiva.repository.storage.FilesystemStorage;
import org.apache.archiva.repository.storage.StorageAsset;
import org.apache.commons.lang3.StringUtils;
return null;
}
+ @Override
+ public String toPath( ItemSelector selector )
+ {
+ return null;
+ }
+
@Override
public String toPath( ArchivaArtifact reference )
{
import org.apache.archiva.model.ProjectReference;
import org.apache.archiva.model.VersionedReference;
import org.apache.archiva.repository.*;
+import org.apache.archiva.repository.content.ItemSelector;
import org.apache.archiva.repository.storage.FilesystemStorage;
import org.apache.archiva.repository.storage.RepositoryStorage;
import org.apache.archiva.repository.storage.StorageAsset;
return null;
}
+ @Override
+ public String toPath( ItemSelector selector )
+ {
+ return null;
+ }
+
@Override
public String toPath( ArchivaArtifact reference )
{
import org.apache.archiva.repository.LayoutException;
import org.apache.archiva.repository.RemoteRepository;
import org.apache.archiva.repository.RemoteRepositoryContent;
+import org.apache.archiva.repository.content.ItemSelector;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
StringUtils.isNotEmpty(reference.getClassifier()) ? "-"+reference.getClassifier() : "")+"."+reference.getType();
}
+ @Override
+ public String toPath( ItemSelector selector )
+ {
+ String baseVersion;
+ if (!selector.hasVersion() && VersionUtil.isSnapshot(selector.getArtifactVersion())) {
+ baseVersion=VersionUtil.getBaseVersion(selector.getArtifactVersion());
+ } else {
+ baseVersion=selector.getVersion();
+ }
+ return selector.getNamespace().replaceAll("\\.", "/")+"/"+selector.getArtifactId()+"/"+baseVersion+"/"
+ +selector.getArtifactId()+"-"+selector.getVersion()+(
+ StringUtils.isNotEmpty(selector.getClassifier()) ? "-"+selector.getClassifier() : "")+"."+selector.getType();
+ }
+
@Override
public RepositoryURL toURL( ArtifactReference reference )
{
import org.apache.archiva.metadata.model.maven2.MavenArtifactFacet;
import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator;
import org.apache.archiva.repository.storage.StorageAsset;
+import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
private void appendNamespaceAndProject( StringBuilder path, String namespace, String projectId )
{
appendNamespace( path, namespace );
- path.append( projectId ).append( PATH_SEPARATOR );
+ if (StringUtils.isNotEmpty( projectId ))
+ {
+ path.append( projectId ).append( PATH_SEPARATOR );
+ }
}
private void appendNamespace( StringBuilder path, String namespace )
{
- path.append( formatAsDirectory( namespace ) ).append( PATH_SEPARATOR );
+ if ( StringUtils.isNotEmpty( namespace ) ) {
+ path.append( formatAsDirectory( namespace ) ).append( PATH_SEPARATOR );
+ }
}
@Override
import org.apache.archiva.model.VersionedReference;
import org.apache.archiva.repository.LayoutException;
import org.apache.archiva.repository.RepositoryContent;
+import org.apache.archiva.repository.content.ItemSelector;
import org.apache.archiva.repository.content.PathParser;
+import org.apache.archiva.repository.content.Version;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
return path.toString( );
}
+ @Override
+ public String toPath ( ItemSelector selector ) {
+ if (selector==null) {
+ throw new IllegalArgumentException( "ItemSelector must not be null." );
+ }
+ String projectId;
+ // Initialize the project id if not set
+ if (selector.hasProjectId()) {
+ projectId = selector.getProjectId( );
+ } else if (selector.hasArtifactId()) {
+ // projectId same as artifact id, if set
+ projectId = selector.getArtifactId( );
+ } else {
+ // we arrive here, if projectId && artifactId not set
+ return pathTranslator.toPath( selector.getNamespace(), "");
+ }
+ if ( !selector.hasArtifactId( )) {
+ return pathTranslator.toPath( selector.getNamespace( ), projectId );
+ }
+ // this part only, if projectId && artifactId is set
+ String artifactVersion = "";
+ String version = "";
+ if (selector.hasVersion() && selector.hasArtifactVersion() ) {
+ artifactVersion = selector.getArtifactVersion();
+ version = VersionUtil.getBaseVersion( selector.getVersion( ) );
+ } else if (!selector.hasVersion() && selector.hasArtifactVersion()) {
+ // we try to retrieve the base version, if artifact version is only set
+ version = VersionUtil.getBaseVersion( selector.getArtifactVersion( ) );
+ artifactVersion = selector.getArtifactVersion( );
+ } else if (selector.hasVersion() && !selector.hasArtifactVersion()) {
+ artifactVersion = selector.getVersion();
+ version = VersionUtil.getBaseVersion( selector.getVersion( ) );
+ }
+
+ return pathTranslator.toPath( selector.getNamespace(), projectId, version,
+ constructId( selector.getArtifactId(), artifactVersion, selector.getClassifier(), selector.getType() ) );
+
+ }
+
public String toMetadataPath( ProjectReference reference )
{
final StringBuilder path = new StringBuilder();
import org.apache.archiva.repository.LayoutException;
import org.apache.archiva.repository.ManagedRepository;
import org.apache.archiva.repository.ManagedRepositoryContent;
+import org.apache.archiva.repository.content.ItemSelector;
import org.apache.archiva.repository.storage.StorageAsset;
import org.apache.commons.lang3.StringUtils;
}
}
+
// The variant with runtime exception for stream usage
private ArtifactReference toArtifactRef(String path) {
try {
import org.apache.archiva.model.ArtifactReference;
import org.apache.archiva.repository.AbstractRepositoryLayerTestCase;
import org.apache.archiva.repository.LayoutException;
+import org.apache.archiva.repository.content.ItemSelector;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;
}
}
+ public void testToPathOnNullItemSelector()
+
+ {
+ try
+ {
+ ItemSelector selector = null;
+ toPath( selector );
+ fail( "Should have failed due to null artifact reference." );
+ }
+ catch ( IllegalArgumentException e )
+ {
+ /* expected path */
+ }
+ }
+
private void assertArtifactReference( ArtifactReference actualReference, String groupId, String artifactId,
String version, String classifier, String type )
{
throws LayoutException;
protected abstract String toPath( ArtifactReference reference );
+
+
+ protected abstract String toPath( ItemSelector selector );
}
import org.apache.archiva.model.VersionedReference;
import org.apache.archiva.repository.EditableManagedRepository;
import org.apache.archiva.repository.LayoutException;
+import org.apache.archiva.repository.content.ItemSelector;
import org.apache.archiva.repository.content.maven2.ManagedDefaultRepositoryContent;
import org.apache.archiva.repository.maven2.MavenManagedRepository;
import org.apache.commons.io.FileUtils;
return repoContent.toPath( reference );
}
+ @Override
+ protected String toPath( ItemSelector selector ) {
+ return repoContent.toPath( selector );
+ }
+
private Path setupRepoCopy( String source, String target) throws IOException
{
Path defaultRepo = getRepositoryPath( source );
import org.apache.archiva.repository.LayoutException;
import org.apache.archiva.repository.RemoteRepository;
import org.apache.archiva.repository.RemoteRepositoryContent;
+import org.apache.archiva.repository.content.ItemSelector;
import org.apache.archiva.repository.content.maven2.RemoteDefaultRepositoryContent;
import org.junit.Before;
{
return repoContent.toPath( reference );
}
+
+ @Override
+ protected String toPath( ItemSelector selector ) {
+ return repoContent.toPath( selector );
+ }
}