* under the License.
*/
-import org.apache.archiva.repository.storage.StorageAsset;
-
/**
- *
* Represents a artifact of a repository. This object contains unique coordinates of the
* artifact. A artifact has exactly one file representation in the repository.
* The artifact instance does not tell, if the file exists or is readable. It just
* keeps the coordinates and some meta information of the artifact.
- *
+ * <p>
* Artifact implementations should be immutable. The implementation must not always represent the current state of the
* corresponding storage asset (file). It is just a view of the attributes for a given point in time.
- *
+ * <p>
* Implementations must provide proper hash and equals methods.
*
- *
* @author Martin Stockhammer <martin_s@apache.org>
*/
public interface Artifact extends ContentItem
{
- /**
- * The namespace is the location of the artifact.
- * E.g. for maven artifacts it is the groupId.
- * The namespace may be empty. Which means that is the base or root namespace.
- *
- * @return the namespace of the artifact. Never returns <code>null</code>.
- */
- String getNamespace();
/**
* The artifact identifier. The ID is unique in a given namespace of a given repository.
* But there may exist artifacts with the same ID but different types, classifiers or extensions.
- *
+ * <p>
* Never returns <code>null</code> or a empty string.
*
* @return the identifier of the artifact. Never returns <code>null</code> or empty string
*/
- String getId();
+ String getId( );
/**
* The version string of the artifact. The version string is exactly the version that is attached
* @return the artifact version string
* @see #getVersion()
*/
- String getArtifactVersion();
+ String getArtifactVersion( );
/**
* Returns the attached version this artifact is part of.
+ *
* @return the version object
*/
- Version getVersion();
+ Version getVersion( );
/**
* Returns the type of the artifact. The type is some hint about the usage of the artifact.
*
* @return the type of the artifact. Returns never <code>null</code>, but may be empty string
*/
- String getType();
+ String getType( );
/**
* A classifier that distinguishes artifacts.
*
* @return the classifier of the artifact. Returns never <code>null</code>, but may be empty string
*/
- String getClassifier();
+ String getClassifier( );
/**
* Short cut for the file name. Should always return the same value as the artifact name.
+ *
* @return the name of the file
*/
- default String getFileName() {
+ default String getFileName( )
+ {
return getAsset( ).getName( );
}
*
* @return the file name extension
*/
- default String getExtension() {
- final String name = getAsset().getName();
+ default String getExtension( )
+ {
+ final String name = getAsset( ).getName( );
final int idx = name.lastIndexOf( '.' );
- if (idx>=0) {
+ if ( idx >= 0 )
+ {
return name.substring( idx );
- } else {
+ }
+ else
+ {
return "";
}
}
*
* @return the file name remainder
*/
- String getRemainder();
+ String getRemainder( );
/**
* Should return the mime type of the artifact.
*
* @return the mime type of the artifact.
*/
- String getContentType();
-
- /**
- * Returns the storage representation of the artifact. The asset must not exist.
- *
- * @return the asset this artifact corresponds to.
- */
- StorageAsset getAsset();
+ String getContentType( );
}
* under the License.
*/
+import org.apache.archiva.repository.ManagedRepositoryContent;
import org.apache.archiva.repository.UnsupportedConversionException;
+import org.apache.archiva.repository.storage.StorageAsset;
import java.util.Map;
{
/**
* Returns the repository type specific implementation
+ *
* @param clazz the specific implementation class
- * @param <T> the class or interface
+ * @param <T> the class or interface
* @return the specific project implementation
*/
<T extends Project> T adapt( Class<T> clazz ) throws UnsupportedConversionException;
/**
* Returns <code>true</code>, if this project supports the given adaptor class.
+ *
* @param clazz the class to convert this project to
- * @param <T> the type
+ * @param <T> the type
* @return <code>true/code>, if the implementation is supported, otherwise false
*/
<T extends Project> boolean supports( Class<T> clazz );
/**
* Additional attributes
+ *
* @return the additional attributes
*/
Map<String, String> getAttributes( );
*
* @param key the attribute key
* @return the value, if the key exists, otherwise <code>null</code>
- *
*/
String getAttribute( String key );
+
+ /**
+ * Returns the storage representation of the artifact. The asset must not exist.
+ *
+ * @return the asset this artifact corresponds to.
+ */
+ StorageAsset getAsset( );
+
+
+ /**
+ * The repository this project is part of.
+ *
+ * @return the repository content
+ */
+ ManagedRepositoryContent getRepository( );
+
}
--- /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.
+ */
+
+package org.apache.archiva.repository.content;
+
+/**
+ * This exception is thrown, if the artifact, version or group item with the selected coordinates
+ * cannot be found.
+ *
+ * @author Martin Stockhammer <martin_s@apache.org>
+ * @since 3.0
+ */
+public class ItemNotFoundException extends Exception
+{
+ public ItemNotFoundException( )
+ {
+ }
+
+ public ItemNotFoundException( String message )
+ {
+ super( message );
+ }
+
+ public ItemNotFoundException( String message, Throwable cause )
+ {
+ super( message, cause );
+ }
+
+ public ItemNotFoundException( Throwable cause )
+ {
+ super( cause );
+ }
+
+ public ItemNotFoundException( String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace )
+ {
+ super( message, cause, enableSuppression, writableStackTrace );
+ }
+}
public interface ItemSelector
{
- String getProjectId();
+ String getProjectId( );
- String getNamespace();
+ String getNamespace( );
String getVersion( );
- String getArtifactVersion();
+ String getArtifactVersion( );
String getArtifactId( );
- String getType();
+ String getType( );
- String getClassifier();
+ String getClassifier( );
String getAttribute( String key );
+ String getExtension( String extension );
+
Map<String, String> getAttributes( );
- default boolean hasNamespace() {
+ default boolean hasNamespace( )
+ {
return !StringUtils.isEmpty( getNamespace( ) );
}
- default boolean hasProjectId() {
+ default boolean hasProjectId( )
+ {
return !StringUtils.isEmpty( getProjectId( ) );
}
- default boolean hasVersion() {
- return !StringUtils.isEmpty(getVersion());
+ default boolean hasVersion( )
+ {
+ return !StringUtils.isEmpty( getVersion( ) );
}
- default boolean hasArtifactId() {
+ default boolean hasArtifactId( )
+ {
return !StringUtils.isEmpty( getArtifactId( ) );
}
- default boolean hasArtifactVersion() {
+ default boolean hasArtifactVersion( )
+ {
return !StringUtils.isEmpty( getArtifactVersion( ) );
}
- default boolean hasType() {
+ default boolean hasType( )
+ {
return !StringUtils.isEmpty( getType( ) );
}
- default boolean hasClassifier() {
+ default boolean hasClassifier( )
+ {
return !StringUtils.isEmpty( getClassifier( ) );
}
- boolean hasAttributes();
+ boolean hasAttributes( );
+
+ boolean hasExtension( );
}
--- /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.
+ */
+
+package org.apache.archiva.repository.content;
+
+import java.util.List;
+
+/**
+ * The namespace represents some kind of hierarchical coordinate where artifacts are stored.
+ * The syntax of the namespace (e.g. the separator like '.' or '/') is dependent on the repository type.
+ *
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public interface Namespace extends ContentItem
+{
+ String getNamespace( );
+
+ List<String> getNamespacePath( );
+
+}
/**
* PathParser interface.
- *
- *
*/
public interface PathParser
{
/**
* Return a item selector for the given path.
+ *
* @param path the path relative to the repository
* @return a item selector instance
* @throws LayoutException if the path does not reference a valid item
*/
- ItemSelector toItemSelector(String path) throws LayoutException;
+ ItemSelector toItemSelector( String path ) throws LayoutException;
}
* under the License.
*/
-import org.apache.archiva.repository.RepositoryContent;
-import org.apache.archiva.repository.storage.StorageAsset;
-
/**
- *
* The project is the container for several versions each with different artifacts.
*
* <pre>
* |
* +--> version 2 ----> artifact 3
* </pre>
- *
+ * <p>
* Implementations must provide proper hash and equals methods.
*
* @author Martin Stockhammer <martin_s@apache.org>
/**
* The namespace of the project
+ *
* @return the namespace
*/
- String getNamespace();
+ Namespace getNamespace( );
/**
* The id of the project
+ *
* @return the project id
*/
- String getId();
+ String getId( );
- /**
- * The repository this project is part of.
- * @return the repository content
- */
- RepositoryContent getRepository();
-
- /**
- * Returns the asset that corresponds to this project.
- * It depends of the implementation, if the asset provides additional information about the
- * project or not.
- *
- * @return the repository asset that represents this project
- */
- StorageAsset getAsset();
}
* under the License.
*/
-import org.apache.archiva.repository.UnsupportedRepositoryTypeException;
-import org.apache.archiva.repository.storage.StorageAsset;
-
-import java.util.Map;
+import java.util.List;
/**
- *
* Each artifact is attached to exactly one version.
- *
+ * <p>
* Implementations must provide proper hash and equals methods.
*
* @author Martin Stockhammer <martin_s@apache.org>
*
* @return the version string
*/
- String getVersion();
+ String getVersion( );
/**
- * Returns the local representation of the version. For maven this is a directory.
- * It is implementation dependent, what exactly this asset points to.
+ * Returns the version segments. E.g. for 1.3.4 it will return ["1","3"."4"]
*
- * @return the local storage representation of the version
+ * @return
*/
- StorageAsset getAsset();
+ List<String> getVersionSegments( );
/**
- * Each version is attached to a project.
- * @return the attached project
+ * Returns the project this version is attached to.
+ *
+ * @return the project instance. Will never return <code>null</code>
*/
- Project getProject();
-
+ Project getProject( );
}
import org.apache.archiva.repository.content.Artifact;
import org.apache.archiva.repository.content.Version;
+import org.apache.archiva.repository.content.base.builder.ArtifactOptBuilder;
+import org.apache.archiva.repository.content.base.builder.ArtifactVersionBuilder;
+import org.apache.archiva.repository.content.base.builder.ArtifactWithIdBuilder;
+import org.apache.archiva.repository.content.base.builder.WithVersionObjectBuilder;
import org.apache.archiva.repository.storage.StorageAsset;
import org.apache.commons.lang3.StringUtils;
/**
- *
- * Base implementation of artifact. A builder is used to create instances.
+ * Base implementation of artifact.
+ * <p>
+ * You have to use the builder method {@link #withAsset(StorageAsset)} to create a instance.
+ * The build() method can be called after the required attributes are set.
+ * <p>
+ * Artifact are equal if the following coordinates match:
+ * <ul>
+ * <li>repository</li>
+ * <li>asset</li>
+ * <li>version</li>
+ * <li>artifactId</li>
+ * <li>artifactVersion</li>
+ * <li>type</li>
+ * <li>classifier</li>
+ * </ul>
*
* @author Martin Stockhammer <martin_s@apache.org>
*/
public class ArchivaArtifact extends ArchivaContentItem implements Artifact
{
- private String namespace;
private String id;
private String artifactVersion;
private Version version;
private String classifier;
private String remainder;
private String contentType;
- private StorageAsset asset;
- private ArchivaArtifact() {
+ private ArchivaArtifact( )
+ {
}
- @Override
- public String getNamespace( )
- {
- return namespace;
- }
@Override
public String getId( )
return contentType;
}
- @Override
- public StorageAsset getAsset( )
+
+ /**
+ * Returns the builder for creating a new artifact instance. You have to fill the
+ * required attributes before the build() method is available.
+ *
+ * @param asset the storage asset representing the artifact
+ * @return a builder for creating new artifact instance
+ */
+ public static WithVersionObjectBuilder withAsset( StorageAsset asset )
{
- return asset;
+ return new Builder( ).withAsset( asset );
}
- public static ArtifactVersionBuilder withId(String id) {
- return new Builder( ).withId( id );
- }
+ @Override
+ public boolean equals( Object o )
+ {
+ if ( this == o ) return true;
+ if ( o == null || getClass( ) != o.getClass( ) ) return false;
+ if ( !super.equals( o ) ) return false;
- public interface ArtifactVersionBuilder {
- VersionBuilder withArtifactVersion( String version );
- }
- public interface VersionBuilder {
- AssetBuilder withVersion( Version version );
- }
- public interface AssetBuilder {
- Builder withAsset( StorageAsset asset );
+ ArchivaArtifact that = (ArchivaArtifact) o;
+
+ if ( !id.equals( that.id ) ) return false;
+ if ( !artifactVersion.equals( that.artifactVersion ) ) return false;
+ if ( !version.equals( that.version ) ) return false;
+ if ( !type.equals( that.type ) ) return false;
+ return classifier.equals( that.classifier );
}
+ @Override
+ public int hashCode( )
+ {
+ int result = super.hashCode( );
+ result = 31 * result + id.hashCode( );
+ result = 31 * result + artifactVersion.hashCode( );
+ result = 31 * result + version.hashCode( );
+ result = 31 * result + type.hashCode( );
+ result = 31 * result + classifier.hashCode( );
+ return result;
+ }
- public static class Builder implements ArtifactVersionBuilder, VersionBuilder,
- AssetBuilder
+ private static class Builder
+ extends ContentItemBuilder<ArchivaArtifact, ArtifactOptBuilder, WithVersionObjectBuilder>
+ implements ArtifactVersionBuilder, WithVersionObjectBuilder, ArtifactWithIdBuilder, ArtifactOptBuilder
{
- ArchivaArtifact artifact = new ArchivaArtifact( );
- public ArtifactVersionBuilder withId(String id) {
- artifact.id = id;
- return this;
+ Builder( )
+ {
+ super( new ArchivaArtifact( ) );
}
+ @Override
+ protected ArtifactOptBuilder getOptBuilder( )
+ {
+ return this;
+ }
@Override
- public VersionBuilder withArtifactVersion( String version )
+ protected WithVersionObjectBuilder getNextBuilder( )
{
- if ( StringUtils.isEmpty( version ) ) {
- throw new IllegalArgumentException( "version may not be null or empty" );
- }
- artifact.artifactVersion = version;
return this;
}
@Override
- public AssetBuilder withVersion( Version version )
+ public ArtifactWithIdBuilder withVersion( Version version )
{
- if (version==null) {
+ if ( version == null )
+ {
throw new IllegalArgumentException( "version may not be null" );
}
- artifact.version = version;
+ item.version = version;
+ super.setRepository( version.getRepository( ) );
return this;
}
- public Builder withAsset(StorageAsset asset) {
- if (asset==null) {
- throw new IllegalArgumentException( "Asset may not be null" );
+ @Override
+ public ArtifactOptBuilder withId( String id )
+ {
+ if ( StringUtils.isEmpty( id ) )
+ {
+ throw new IllegalArgumentException( "Artifact id may not be null or empty" );
}
- artifact.asset = asset;
+ item.id = id;
return this;
}
- public Builder withNamespace(String namespace) {
- artifact.namespace = namespace;
+
+ @Override
+ public ArtifactOptBuilder withArtifactVersion( String version )
+ {
+ if ( version == null )
+ {
+ throw new IllegalArgumentException( "version may not be null" );
+ }
+ item.artifactVersion = version;
return this;
}
- public Builder withType(String type) {
- artifact.type = type;
+ @Override
+ public ArtifactOptBuilder withType( String type )
+ {
+ item.type = type;
return this;
}
- public Builder withClassifier(String classifier) {
- artifact.classifier = classifier;
+ @Override
+ public ArtifactOptBuilder withClassifier( String classifier )
+ {
+ item.classifier = classifier;
return this;
}
- public Builder withRemainder(String remainder) {
- artifact.remainder = remainder;
+ @Override
+ public ArtifactOptBuilder withRemainder( String remainder )
+ {
+ item.remainder = remainder;
return this;
}
- public Builder withContentType(String contentType) {
- artifact.contentType = contentType;
+ @Override
+ public ArtifactOptBuilder withContentType( String contentType )
+ {
+ item.contentType = contentType;
return this;
}
- public ArchivaArtifact build() {
- if (artifact.namespace==null) {
- artifact.namespace = "";
+ @Override
+ public ArchivaArtifact build( )
+ {
+ super.build( );
+ if ( item.artifactVersion == null )
+ {
+ item.artifactVersion = "";
+ }
+ if ( item.classifier == null )
+ {
+ item.classifier = "";
}
- if (artifact.classifier==null) {
- artifact.classifier = "";
+ if ( item.type == null )
+ {
+ item.type = "";
}
- if (artifact.type == null) {
- artifact.type = "";
+ if ( item.contentType == null )
+ {
+ item.contentType = "";
}
- if (artifact.contentType==null) {
- artifact.contentType = "";
+ if ( item.remainder == null )
+ {
+ item.remainder = "";
}
- return artifact;
+ return item;
}
}
}
* under the License.
*/
+import org.apache.archiva.repository.ManagedRepositoryContent;
import org.apache.archiva.repository.content.ContentItem;
import org.apache.archiva.repository.content.Project;
+import org.apache.archiva.repository.content.base.builder.OptBuilder;
+import org.apache.archiva.repository.content.base.builder.WithAssetBuilder;
+import org.apache.archiva.repository.content.base.builder.WithRepositoryBuilder;
+import org.apache.archiva.repository.storage.StorageAsset;
import org.apache.commons.lang3.StringUtils;
import java.util.Collections;
/**
* Abstract implementation of ContentItem interface.
- *
+ * <p>
* The attribute map is created, when the first values are put to the map.
- *
*/
public abstract class ArchivaContentItem implements ContentItem
{
private Map<String, String> attributes;
+ private ManagedRepositoryContent repository;
+ private StorageAsset asset;
@Override
- public <T extends Project> T adapt( Class<T> clazz ) {
- return (T)this;
+ public <T extends Project> T adapt( Class<T> clazz )
+ {
+ return (T) this;
}
@Override
- public <T extends Project> boolean supports( Class<T> clazz ) {
- return clazz != null && clazz.isAssignableFrom( this.getClass() );
+ public <T extends Project> boolean supports( Class<T> clazz )
+ {
+ return clazz != null && clazz.isAssignableFrom( this.getClass( ) );
}
@Override
public Map<String, String> getAttributes( )
{
- if (this.attributes==null) {
+ if ( this.attributes == null )
+ {
return Collections.emptyMap( );
- } else
+ }
+ else
{
return Collections.unmodifiableMap( this.attributes );
}
/**
* Adds a attribute value. The key must not be <code>null</code>.
*
- * @param key the attribute key
+ * @param key the attribute key
* @param value the attribute value
* @throws IllegalArgumentException if the key is <code>null</code> or empty
*/
- public void putAttribute(String key, String value) throws IllegalArgumentException {
- if (this.attributes==null) {
+ public void putAttribute( String key, String value ) throws IllegalArgumentException
+ {
+ if ( this.attributes == null )
+ {
this.attributes = new HashMap<>( );
}
- if ( StringUtils.isEmpty( key ) ) {
+ if ( StringUtils.isEmpty( key ) )
+ {
throw new IllegalArgumentException( "Key value must not be empty or null" );
}
this.attributes.put( key, value );
@Override
public String getAttribute( String key )
{
- if (this.attributes==null) {
+ if ( this.attributes == null )
+ {
return null;
- } else
+ }
+ else
{
return this.attributes.get( key );
}
}
+
+ @Override
+ public ManagedRepositoryContent getRepository( )
+ {
+ return repository;
+ }
+
+ @Override
+ public StorageAsset getAsset( )
+ {
+ return asset;
+ }
+
+ @Override
+ public boolean equals( Object o )
+ {
+ if ( this == o ) return true;
+ if ( o == null || getClass( ) != o.getClass( ) ) return false;
+
+ ArchivaContentItem that = (ArchivaContentItem) o;
+
+ if ( !repository.equals( that.repository ) ) return false;
+ return asset.equals( that.asset );
+ }
+
+ @Override
+ public int hashCode( )
+ {
+ int result = repository.hashCode( );
+ result = 31 * result + asset.hashCode( );
+ return result;
+ }
+
+
+ /// Builder section
+
+ /*
+ * Builder implementation for each content item.
+ * Should be extended by the subclasses.
+ */
+
+
+ /**
+ * Builder for content item. Must be extended by subclasses.
+ * The builder uses chained interfaces for building the required attributes. That means you have to set
+ * some certain attributes, before you can build the content item instance via the {@link #build()} method.
+ * <p>
+ * Subclasses should extend from this class and provide the interface/class for the destination item,
+ * a interface for the optional attributes and a interface that is returned after the last required attribute is
+ * set.
+ * <p>
+ * The interface for optional attributes should inherit from {@link OptBuilder}
+ *
+ * @param <I> the item class that should be built
+ * @param <O> the class/interface for the optional attributes
+ * @param <N> the class/interface for the next (required) attribute after the base attributes are set
+ */
+ protected abstract static class ContentItemBuilder<I extends ArchivaContentItem, O extends OptBuilder<I, O>, N>
+ implements WithRepositoryBuilder, WithAssetBuilder<N>,
+ OptBuilder<I, O>
+ {
+
+ protected I item;
+
+ protected ContentItemBuilder( I item )
+ {
+ this.item = item;
+ }
+
+ protected abstract O getOptBuilder( );
+
+ protected abstract N getNextBuilder( );
+
+ public WithAssetBuilder<N> withRepository( ManagedRepositoryContent repository )
+ {
+ if ( repository == null )
+ {
+ throw new IllegalArgumentException( "Repository may not be null" );
+ }
+ ( (ArchivaContentItem) item ).repository = repository;
+ return this;
+ }
+
+ public N withAsset( StorageAsset asset )
+ {
+ if ( asset == null )
+ {
+ throw new IllegalArgumentException( "Asset may not be null" );
+ }
+ ( (ArchivaContentItem) item ).asset = asset;
+ return getNextBuilder( );
+ }
+
+ public O withAttribute( String key, String value )
+ {
+ if ( StringUtils.isEmpty( key ) )
+ {
+ throw new IllegalArgumentException( "Attribute key may not be null" );
+ }
+ item.putAttribute( key, value );
+ return getOptBuilder( );
+ }
+
+ protected void setRepository( ManagedRepositoryContent repository )
+ {
+ ( (ArchivaContentItem) item ).repository = repository;
+ }
+
+ public I build( )
+ {
+ return item;
+ }
+
+ }
}
*/
import org.apache.archiva.repository.content.ItemSelector;
+import org.apache.commons.lang3.StringUtils;
import java.util.Collections;
import java.util.HashMap;
private String namespace = "";
private String type = null;
private String classifier = null;
- private Map<String,String> attributes;
+ private String extension = null;
+ private Map<String, String> attributes;
- private ArchivaItemSelector() {
+ private ArchivaItemSelector( )
+ {
}
- public static Builder builder() {
- return new Builder();
+ public static Builder builder( )
+ {
+ return new Builder( );
}
public static class Builder
return this;
}
- public ArchivaItemSelector build() {
+ public Builder withExtension( String extension )
+ {
+ selector.extension = extension;
+ return this;
+ }
+
+ public ArchivaItemSelector build( )
+ {
return selector;
}
}
- private void setAttribute(String key, String value) {
- if (this.attributes == null) {
+ private void setAttribute( String key, String value )
+ {
+ if ( this.attributes == null )
+ {
this.attributes = new HashMap<>( );
}
this.attributes.put( key, value );
}
}
+ @Override
+ public String getExtension( String extension )
+ {
+ return null;
+ }
+
@Override
public Map<String, String> getAttributes( )
{
- if (this.attributes==null) {
+ if ( this.attributes == null )
+ {
return Collections.emptyMap( );
- } else {
+ }
+ else
+ {
return Collections.unmodifiableMap( this.attributes );
}
}
@Override
public boolean hasAttributes( )
{
- return attributes!=null && attributes.size()>0;
+ return attributes != null && attributes.size( ) > 0;
+ }
+
+ @Override
+ public boolean hasExtension( )
+ {
+ return StringUtils.isNotEmpty( extension );
}
}
--- /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.
+ */
+
+package org.apache.archiva.repository.content.base;
+
+import org.apache.archiva.repository.ManagedRepositoryContent;
+import org.apache.archiva.repository.content.Namespace;
+import org.apache.archiva.repository.content.base.builder.NamespaceOptBuilder;
+import org.apache.archiva.repository.content.base.builder.WithAssetBuilder;
+import org.apache.archiva.repository.content.base.builder.WithNamespaceBuilder;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.regex.PatternSyntaxException;
+
+/**
+ * Namespace representation.
+ * Two namespace instances are equal, if the namespace string and the base attributes, like repository and
+ * asset are equal. The separator expression does not influence equality.
+ *
+ * @author Martin Stockhammer <martin_s@apache.org>
+ * @since 3.0
+ */
+public class ArchivaNamespace extends ArchivaContentItem implements Namespace
+{
+ private String namespace;
+ private List<String> namespacePath;
+ private String separatorExpression = "\\.";
+
+ private ArchivaNamespace( )
+ {
+
+ }
+
+ @Override
+ public String getNamespace( )
+ {
+ return namespace;
+ }
+
+ @Override
+ public List<String> getNamespacePath( )
+ {
+ return this.namespacePath;
+ }
+
+ public static WithAssetBuilder<WithNamespaceBuilder> withRepository( ManagedRepositoryContent repository )
+ {
+ return new Builder( ).withRepository( repository );
+ }
+
+
+ @Override
+ public boolean equals( Object o )
+ {
+ if ( this == o ) return true;
+ if ( o == null || getClass( ) != o.getClass( ) ) return false;
+ if ( !super.equals( o ) ) return false;
+
+ ArchivaNamespace that = (ArchivaNamespace) o;
+
+ return namespace.equals( that.namespace );
+ }
+
+ @Override
+ public int hashCode( )
+ {
+ int result = super.hashCode( );
+ result = 31 * result + namespace.hashCode( );
+ return result;
+ }
+
+ private static class Builder extends ContentItemBuilder<ArchivaNamespace, NamespaceOptBuilder, WithNamespaceBuilder>
+ implements WithNamespaceBuilder, NamespaceOptBuilder
+ {
+
+ private Builder( )
+ {
+ super( new ArchivaNamespace( ) );
+ }
+
+ @Override
+ protected NamespaceOptBuilder getOptBuilder( )
+ {
+ return this;
+ }
+
+ @Override
+ protected WithNamespaceBuilder getNextBuilder( )
+ {
+ return this;
+ }
+
+ @Override
+ public NamespaceOptBuilder withNamespace( String namespace )
+ {
+ if ( namespace == null )
+ {
+ throw new IllegalArgumentException( "Namespace may not be null" );
+ }
+ this.item.namespace = namespace;
+ setNamespacePath( namespace );
+ return this;
+ }
+
+ private void setNamespacePath( String namespace )
+ {
+ if ( StringUtils.isEmpty( namespace ) )
+ {
+ this.item.namespacePath = Collections.emptyList( );
+ }
+ else
+ {
+ this.item.namespacePath = Arrays.asList( namespace.split( this.item.separatorExpression ) );
+ }
+ }
+
+ @Override
+ public NamespaceOptBuilder withSeparatorExpression( String expression )
+ {
+ if ( StringUtils.isEmpty( expression ) )
+ {
+ throw new IllegalArgumentException( "Separator expression may not be null or empty" );
+ }
+ this.item.separatorExpression = expression;
+ try
+ {
+ setNamespacePath( this.item.namespace );
+ }
+ catch ( PatternSyntaxException e )
+ {
+ throw new IllegalArgumentException( "Bad pattern syntax separator expression " + expression + ": " + e.getMessage( ), e );
+ }
+ return this;
+ }
+
+ @Override
+ public ArchivaNamespace build( )
+ {
+ super.build( );
+ return this.item;
+ }
+ }
+
+
+}
* 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.Namespace;
import org.apache.archiva.repository.content.Project;
+import org.apache.archiva.repository.content.base.builder.ProjectOptBuilder;
+import org.apache.archiva.repository.content.base.builder.ProjectWithIdBuilder;
+import org.apache.archiva.repository.content.base.builder.WithNamespaceObjectBuilder;
import org.apache.archiva.repository.storage.StorageAsset;
import org.apache.commons.lang3.StringUtils;
/**
* Immutable class, that represents a project.
+ * <p>
+ * The namespace and id are required attributes for each instance.
+ * <p>
+ * Two project instances are equal if the id, and the namespace are equal and if the base attributes
+ * repository and asset match.
+ *
+ * @author Martin Stockhammer <martin_s@apache.org>
+ * @since 3.0
*/
public class ArchivaProject extends ArchivaContentItem implements Project
{
- private String namespace;
+ private Namespace namespace;
private String id;
- private RepositoryContent repositoryContent;
- private StorageAsset asset;
// Setting all setters to private. Builder is the way to go.
- private ArchivaProject() {
+ private ArchivaProject( )
+ {
}
/**
- * Creates the builder that allows to create a new instance.
- * @param id the project id, must not be <code>null</code>
+ * Creates the builder for creating new archiva project instances.
+ * You have to set all required attributes before you can call the build() method.
+ *
+ * @param storageAsset the asset
* @return a builder instance
*/
- public static Builder withId( String id) {
- return new Builder( ).withId( id );
+ public static WithNamespaceObjectBuilder withAsset( StorageAsset storageAsset )
+ {
+ return new Builder( ).withAsset( storageAsset );
}
-
@Override
- public String getNamespace( )
+ public Namespace getNamespace( )
{
return this.namespace;
}
return this.id;
}
+
@Override
- public RepositoryContent getRepository( )
+ public boolean equals( Object o )
{
- return this.repositoryContent;
+ if ( this == o ) return true;
+ if ( o == null || getClass( ) != o.getClass( ) ) return false;
+ if ( !super.equals( o ) ) return false;
+
+ ArchivaProject that = (ArchivaProject) o;
+
+ if ( !namespace.equals( that.namespace ) ) return false;
+ return id.equals( that.id );
}
@Override
- public StorageAsset getAsset( )
+ public int hashCode( )
{
- return asset;
+ int result = super.hashCode( );
+ result = 31 * result + namespace.hashCode( );
+ result = 31 * result + id.hashCode( );
+ return result;
}
-
/*
- * Builder interface chaining is used to restrict mandatory attributes
- * This interface is for the optional arguments.
+ * Builder class
*/
- public interface OptBuilder {
-
- OptBuilder withAsset( StorageAsset asset );
-
- OptBuilder withNamespace( String namespace);
-
- OptBuilder withAttribute( String key, String value );
-
- }
- /*
- * Builder classes for instantiation
- */
- public static final class Builder implements OptBuilder
+ public static final class Builder
+ extends ContentItemBuilder<ArchivaProject, ProjectOptBuilder, WithNamespaceObjectBuilder>
+ implements ProjectOptBuilder, ProjectWithIdBuilder, WithNamespaceObjectBuilder
{
- final private ArchivaProject project = new ArchivaProject();
-
private Builder( )
{
-
- }
-
- private Builder withId(String id) {
- if ( StringUtils.isEmpty( id ) ) {
- throw new IllegalArgumentException( "Null or empty value not allowed for id" );
- }
- project.id = id;
- return this;
+ super( new ArchivaProject( ) );
}
- public OptBuilder withRepository( RepositoryContent repository ) {
- project.repositoryContent = repository;
+ @Override
+ protected ProjectOptBuilder getOptBuilder( )
+ {
return this;
}
@Override
- public OptBuilder withAsset( StorageAsset asset )
+ protected WithNamespaceObjectBuilder getNextBuilder( )
{
- project.asset = asset;
return this;
}
- public OptBuilder withNamespace( String namespace) {
- if (namespace==null) {
- throw new IllegalArgumentException( "Null value not allowed for namespace" );
+ @Override
+ public ProjectOptBuilder withId( String id )
+ {
+ if ( StringUtils.isEmpty( id ) )
+ {
+ throw new IllegalArgumentException( "Null or empty value not allowed for id" );
}
- project.namespace = namespace;
+ item.id = id;
return this;
}
- public OptBuilder withAttribute( String key, String value) {
- project.putAttribute( key, value );
+ @Override
+ public ProjectWithIdBuilder withNamespace( Namespace namespace )
+ {
+ if ( namespace == null )
+ {
+ throw new IllegalArgumentException( "Null value not allowed for namespace" );
+ }
+ item.namespace = namespace;
+ super.setRepository( namespace.getRepository( ) );
return this;
}
- ArchivaProject build() {
- if (project.namespace==null) {
- project.namespace = "";
- }
- if (project.asset == null) {
- if (project.getRepository() instanceof ManagedRepositoryContent) {
- project.asset = (( ManagedRepositoryContent)project.getRepository( )).getRepository( ).getAsset( "" );
- }
-
+ @Override
+ public ArchivaProject build( )
+ {
+ super.build( );
+ if ( item.namespace == null )
+ {
+ throw new IllegalArgumentException( "Namespace may not be null" );
}
- return project;
+ return item;
}
}
-
}
import org.apache.archiva.repository.content.Project;
import org.apache.archiva.repository.content.Version;
+import org.apache.archiva.repository.content.base.builder.VersionOptBuilder;
+import org.apache.archiva.repository.content.base.builder.WithProjectBuilder;
+import org.apache.archiva.repository.content.base.builder.WithVersionBuilder;
import org.apache.archiva.repository.storage.StorageAsset;
import org.apache.commons.lang3.StringUtils;
+import java.util.Arrays;
+import java.util.List;
+import java.util.regex.PatternSyntaxException;
+
+/**
+ * Immutable version instance.
+ * <p>
+ * You have to use the builder method to create instances of this version object.
+ * <p>
+ * The project and the version string are required attributes of this instance additional to the base
+ * attributes repository and asset.
+ * <p>
+ * Two instances are equal, if the project and the version match in addition to the base attributes repository and asset.
+ */
public class ArchivaVersion extends ArchivaContentItem implements Version
{
private String version;
- private StorageAsset asset;
private Project project;
+ private String separatorExpression = "\\.";
+ private List<String> versionSegments;
- private ArchivaVersion() {
+ private ArchivaVersion( )
+ {
}
- public static ProjectBuilder withVersion(String version) {
- return new Builder( ).withVersion( version );
+ /**
+ * Creates a new builder for creating new version instances. You have to provide the required
+ * attributes before the build() method can be called.
+ *
+ * @param storageAsset the storage asset
+ * @return the builder for creating new version instances
+ */
+ public static WithProjectBuilder withAsset( StorageAsset storageAsset )
+ {
+ return new Builder( ).withAsset( storageAsset );
}
@Override
- public String getVersion( )
+ public List<String> getVersionSegments( )
{
- return version;
+ return versionSegments;
}
@Override
- public StorageAsset getAsset( )
+ public String getVersion( )
{
- return asset;
+ return version;
}
@Override
return project;
}
- public interface ProjectBuilder {
- Builder withProject( Project project );
+
+ @Override
+ public boolean equals( Object o )
+ {
+ if ( this == o ) return true;
+ if ( o == null || getClass( ) != o.getClass( ) ) return false;
+ if ( !super.equals( o ) ) return false;
+
+ ArchivaVersion that = (ArchivaVersion) o;
+
+ if ( !version.equals( that.version ) ) return false;
+ return project.equals( that.project );
}
- public static final class Builder implements ProjectBuilder {
+ @Override
+ public int hashCode( )
+ {
+ int result = super.hashCode( );
+ result = 31 * result + version.hashCode( );
+ result = 31 * result + project.hashCode( );
+ return result;
+ }
- private ArchivaVersion version = new ArchivaVersion();
+ private static final class Builder extends ContentItemBuilder<ArchivaVersion, VersionOptBuilder, WithProjectBuilder>
+ implements WithProjectBuilder, WithVersionBuilder, VersionOptBuilder
+ {
- ProjectBuilder withVersion( String version )
+ Builder( )
{
- if ( StringUtils.isEmpty( version ) ) {
- throw new IllegalArgumentException( "Version parameter must not be empty or null." );
- }
- this.version.version = version;
- return this;
+ super( new ArchivaVersion( ) );
}
+ @Override
+ protected WithProjectBuilder getNextBuilder( )
+ {
+ return this;
+ }
@Override
- public Builder withProject( Project project )
+ protected VersionOptBuilder getOptBuilder( )
{
- this.version.project = project;
return this;
}
- public Builder withAsset( StorageAsset asset )
+ @Override
+ public VersionOptBuilder withVersion( String version )
{
- this.version.asset = asset;
+ if ( StringUtils.isEmpty( version ) )
+ {
+ throw new IllegalArgumentException( "Version parameter must not be empty or null." );
+ }
+ item.version = version;
+ updateVersionSegments( );
return this;
}
- public Builder withAttribute(String key, String value) {
- this.version.putAttribute( key, value );
+
+ private void updateVersionSegments( )
+ {
+ item.versionSegments = Arrays.asList( item.version.split( item.separatorExpression ) );
+ }
+
+ @Override
+ public WithVersionBuilder withProject( Project project )
+ {
+ if ( project == null )
+ {
+ throw new IllegalArgumentException( "Project may not be null" );
+ }
+ item.project = project;
+ super.setRepository( project.getRepository( ) );
return this;
}
- public ArchivaVersion build() {
- if (this.version.asset == null) {
- this.version.project.getAsset( );
+ public ArchivaVersion build( )
+ {
+ super.build( );
+ return item;
+ }
+
+ @Override
+ public VersionOptBuilder withSeparatorExpression( String expression )
+ {
+ if ( StringUtils.isEmpty( expression ) )
+ {
+ throw new IllegalArgumentException( "Separator expression may not be null or empty" );
+ }
+ this.item.separatorExpression = expression;
+ try
+ {
+ updateVersionSegments( );
}
- return this.version;
+ catch ( PatternSyntaxException e )
+ {
+ throw new IllegalArgumentException( "Bad separator expression " + expression + ": " + e.getMessage( ), e );
+ }
+ return this;
}
}
/**
* Maven 1.x request type to classifier mapping for translating to a Maven 2.x storage
- *
+ * <p>
* TODO reuse mappings for other repositories
*
* @since 1.1
* Utility class that gives information about the physical location of artifacts.
*/
@Service( "ArtifactUtil#default" )
-public class ArtifactUtil {
+public class ArtifactUtil
+{
@Inject
RepositoryContentFactory repositoryContentFactory;
* Returns the physical location of a given artifact in the repository. There is no check for the
* existence of the returned file.
*
- * @param repository The repository, where the artifact is stored.
+ * @param repository The repository, where the artifact is stored.
* @param artifactReference The artifact reference.
* @return The absolute path to the artifact.
* @throws RepositoryException
*/
- public Path getArtifactPath(ManagedRepository repository, ArtifactReference artifactReference) throws RepositoryException {
- final ManagedRepositoryContent content = repositoryContentFactory.getManagedRepositoryContent(repository);
+ public Path getArtifactPath( ManagedRepository repository, ArtifactReference artifactReference ) throws RepositoryException
+ {
+ final ManagedRepositoryContent content = repositoryContentFactory.getManagedRepositoryContent( repository );
final String artifactPath = content.toPath( artifactReference );
- return Paths.get(repository.getLocation()).resolve(artifactPath);
+ return Paths.get( repository.getLocation( ) ).resolve( artifactPath );
}
/**
* Returns the physical location of a given artifact in the repository. There is no check for the
* existence of the returned file.
*
- * @param repository The repository, where the artifact is stored.
+ * @param repository The repository, where the artifact is stored.
* @param artifactReference The artifact reference.
* @return The asset representation of the artifact.
* @throws RepositoryException
*/
- public StorageAsset getArtifactAsset(ManagedRepository repository, ArtifactReference artifactReference) throws RepositoryException {
- final ManagedRepositoryContent content = repositoryContentFactory.getManagedRepositoryContent(repository);
+ public StorageAsset getArtifactAsset( ManagedRepository repository, ArtifactReference artifactReference ) throws RepositoryException
+ {
+ final ManagedRepositoryContent content = repositoryContentFactory.getManagedRepositoryContent( repository );
final String artifactPath = content.toPath( artifactReference );
- return repository.getAsset(artifactPath);
+ return repository.getAsset( artifactPath );
}
}
--- /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.
+ */
+
+package org.apache.archiva.repository.content.base.builder;
+
+import org.apache.archiva.repository.content.base.ArchivaArtifact;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public interface ArtifactOptBuilder
+ extends OptBuilder<ArchivaArtifact, ArtifactOptBuilder>
+{
+
+ ArtifactOptBuilder withArtifactVersion( String version );
+
+ ArtifactOptBuilder withType( String type );
+
+ ArtifactOptBuilder withClassifier( String classifier );
+
+ ArtifactOptBuilder withRemainder( String remainder );
+
+ ArtifactOptBuilder withContentType( String contentType );
+
+ ArchivaArtifact build( );
+}
--- /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.
+ */
+
+package org.apache.archiva.repository.content.base.builder;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public interface ArtifactVersionBuilder
+{
+ ArtifactOptBuilder withArtifactVersion( String version );
+}
--- /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.
+ */
+
+package org.apache.archiva.repository.content.base.builder;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public interface ArtifactWithIdBuilder
+{
+ ArtifactOptBuilder withId( String id );
+}
--- /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.
+ */
+
+package org.apache.archiva.repository.content.base.builder;
+
+import org.apache.archiva.repository.content.base.ArchivaNamespace;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public interface NamespaceOptBuilder
+ extends OptBuilder<ArchivaNamespace, NamespaceOptBuilder>
+{
+
+ NamespaceOptBuilder withSeparatorExpression( String expression );
+
+ ArchivaNamespace build( );
+
+}
--- /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.
+ */
+
+package org.apache.archiva.repository.content.base.builder;
+
+import org.apache.archiva.repository.content.ContentItem;
+
+/**
+ * Optional attributes. Subclasses should inherit from this interface for their own optional
+ * interface
+ *
+ * @param <O> the target builder interface for the optional attributes
+ */
+public interface OptBuilder<I extends ContentItem, O extends OptBuilder>
+{
+ O withAttribute( String key, String value );
+
+ I build( );
+}
--- /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.
+ */
+
+package org.apache.archiva.repository.content.base.builder;
+
+import org.apache.archiva.repository.content.base.ArchivaProject;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */ /*
+ * Builder interface chaining is used to restrict mandatory attributes
+ * This interface is for the optional arguments.
+ */
+public interface ProjectOptBuilder
+ extends OptBuilder<ArchivaProject, ProjectOptBuilder>
+{
+
+ ProjectOptBuilder withId( String id );
+
+ ArchivaProject build( );
+
+}
--- /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.
+ */
+
+package org.apache.archiva.repository.content.base.builder;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public interface ProjectWithIdBuilder
+{
+ ProjectOptBuilder withId( String id );
+}
--- /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.
+ */
+
+package org.apache.archiva.repository.content.base.builder;
+
+import org.apache.archiva.repository.content.base.ArchivaVersion;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public interface VersionOptBuilder
+ extends OptBuilder<ArchivaVersion, VersionOptBuilder>
+{
+
+ VersionOptBuilder withSeparatorExpression( String expression );
+
+}
--- /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.
+ */
+
+package org.apache.archiva.repository.content.base.builder;
+
+import org.apache.archiva.repository.storage.StorageAsset;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public interface WithAssetBuilder<N>
+{
+ N withAsset( StorageAsset asset );
+}
--- /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.
+ */
+
+package org.apache.archiva.repository.content.base.builder;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public interface WithNamespaceBuilder
+{
+ NamespaceOptBuilder withNamespace( String expression );
+}
--- /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.
+ */
+
+package org.apache.archiva.repository.content.base.builder;
+
+import org.apache.archiva.repository.content.Namespace;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public interface WithNamespaceObjectBuilder
+{
+ ProjectWithIdBuilder withNamespace( Namespace namespace );
+}
--- /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.
+ */
+
+package org.apache.archiva.repository.content.base.builder;
+
+import org.apache.archiva.repository.content.Project;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public interface WithProjectBuilder
+{
+ WithVersionBuilder withProject( Project project );
+}
--- /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.
+ */
+
+package org.apache.archiva.repository.content.base.builder;
+
+import org.apache.archiva.repository.ManagedRepositoryContent;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public interface WithRepositoryBuilder<N>
+{
+ WithAssetBuilder<N> withRepository( ManagedRepositoryContent repository );
+}
--- /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.
+ */
+
+package org.apache.archiva.repository.content.base.builder;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public interface WithVersionBuilder
+{
+ VersionOptBuilder withVersion( String version );
+}
--- /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.
+ */
+
+package org.apache.archiva.repository.content.base.builder;
+
+import org.apache.archiva.repository.content.Version;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public interface WithVersionObjectBuilder
+{
+ ArtifactWithIdBuilder withVersion( Version version );
+}
--- /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.
+ */
+
+package org.apache.archiva.repository.content.base;
+
+import org.apache.archiva.repository.content.base.builder.OptBuilder;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+class ArchivaArtifactTest extends ContentItemTest
+{
+
+ ArchivaProject project;
+ ArchivaVersion version;
+
+ @BeforeEach
+ void init() {
+ ArchivaNamespace namespace = ArchivaNamespace.withRepository( repository ).withAsset( asset ).withNamespace( "abc.def" ).build();
+ project = ArchivaProject.withAsset( asset ).withNamespace( namespace ).withId( "proj001" ).build( );
+ version = ArchivaVersion.withAsset( asset ).withProject( project ).withVersion( "2.33.1" ).build();
+ }
+
+
+ @Override
+ public OptBuilder getBuilder( )
+ {
+ return ArchivaArtifact.withAsset( asset ).withVersion( version ).withId( "testartifact" );
+ }
+
+
+ @Test
+ void idOnly() {
+ ArchivaArtifact item = ArchivaArtifact.withAsset( asset ).withVersion( version ).withId( "testartifact" ).build( );
+
+ assertNotNull( item );
+ assertNotNull( item.getRepository( ) );
+ assertEquals(repository, item.getRepository());
+ assertNotNull( item.getAsset( ) );
+ assertEquals( asset, item.getAsset( ) );
+ assertNotNull( item.getVersion( ) );
+ assertEquals( version, item.getVersion( ) );
+ assertNotNull( item.getArtifactVersion( ) );
+ assertEquals( "", item.getArtifactVersion( ) );
+ assertNotNull( item.getType( ) );
+ assertEquals( "", item.getType( ) );
+ assertNotNull( item.getClassifier( ) );
+ assertEquals( "", item.getClassifier( ) );
+ assertNotNull( item.getRemainder( ) );
+ assertEquals( "", item.getRemainder( ) );
+ assertNotNull( item.getContentType( ) );
+ assertEquals( "", item.getContentType( ) );
+ assertNotNull( item.getId( ) );
+ assertEquals( "testartifact", item.getId( ) );
+
+ }
+
+
+ @Test
+ void withArtifactVersion() {
+ ArchivaArtifact item = ArchivaArtifact.withAsset( asset ).withVersion( version ).withId( "testartifact" )
+ .withArtifactVersion( "1.0.10494949" )
+ .build( );
+ assertNotNull( item );
+ assertNotNull( item.getRepository( ) );
+ assertEquals(repository, item.getRepository());
+ assertNotNull( item.getAsset( ) );
+ assertEquals( asset, item.getAsset( ) );
+ assertNotNull( item.getVersion( ) );
+ assertEquals( version, item.getVersion( ) );
+ assertNotNull( item.getType( ) );
+ assertEquals( "", item.getType( ) );
+ assertNotNull( item.getClassifier( ) );
+ assertEquals( "", item.getClassifier( ) );
+ assertNotNull( item.getRemainder( ) );
+ assertEquals( "", item.getRemainder( ) );
+ assertNotNull( item.getContentType( ) );
+ assertEquals( "", item.getContentType( ) );
+ assertEquals( "testartifact", item.getId( ) );
+ assertNotNull( item.getArtifactVersion( ) );
+ assertEquals( "1.0.10494949", item.getArtifactVersion( ) );
+ }
+
+ @Test
+ void withType() {
+ ArchivaArtifact item = ArchivaArtifact.withAsset( asset ).withVersion( version ).withId( "testartifact" )
+ .withType( "javadoc" )
+ .build( );
+ assertNotNull( item );
+ assertNotNull( item.getRepository( ) );
+ assertEquals(repository, item.getRepository());
+ assertNotNull( item.getAsset( ) );
+ assertEquals( asset, item.getAsset( ) );
+ assertNotNull( item.getVersion( ) );
+ assertEquals( version, item.getVersion( ) );
+ assertNotNull( item.getType( ) );
+ assertEquals( "javadoc", item.getType( ) );
+ assertNotNull( item.getClassifier( ) );
+ assertEquals( "", item.getClassifier( ) );
+ assertNotNull( item.getRemainder( ) );
+ assertEquals( "", item.getRemainder( ) );
+ assertNotNull( item.getContentType( ) );
+ assertEquals( "", item.getContentType( ) );
+ assertEquals( "testartifact", item.getId( ) );
+ assertNotNull( item.getArtifactVersion( ) );
+ assertEquals( "", item.getArtifactVersion( ) );
+ }
+
+ @Test
+ void withClassifier() {
+ ArchivaArtifact item = ArchivaArtifact.withAsset( asset ).withVersion( version ).withId( "testartifact" )
+ .withClassifier( "source" )
+ .build( );
+ assertNotNull( item );
+ assertNotNull( item.getRepository( ) );
+ assertEquals(repository, item.getRepository());
+ assertNotNull( item.getAsset( ) );
+ assertEquals( asset, item.getAsset( ) );
+ assertNotNull( item.getVersion( ) );
+ assertEquals( version, item.getVersion( ) );
+ assertNotNull( item.getType( ) );
+ assertEquals( "", item.getType( ) );
+ assertNotNull( item.getClassifier( ) );
+ assertEquals( "source", item.getClassifier( ) );
+ assertNotNull( item.getRemainder( ) );
+ assertEquals( "", item.getRemainder( ) );
+ assertNotNull( item.getContentType( ) );
+ assertEquals( "", item.getContentType( ) );
+ assertEquals( "testartifact", item.getId( ) );
+ assertNotNull( item.getArtifactVersion( ) );
+ assertEquals( "", item.getArtifactVersion( ) );
+ }
+
+ @Test
+ void withRemainder() {
+ ArchivaArtifact item = ArchivaArtifact.withAsset( asset ).withVersion( version ).withId( "testartifact" )
+ .withRemainder( "jar.md5" )
+ .build( );
+ assertNotNull( item );
+ assertNotNull( item.getRepository( ) );
+ assertEquals(repository, item.getRepository());
+ assertNotNull( item.getAsset( ) );
+ assertEquals( asset, item.getAsset( ) );
+ assertNotNull( item.getVersion( ) );
+ assertEquals( version, item.getVersion( ) );
+ assertNotNull( item.getType( ) );
+ assertEquals( "", item.getType( ) );
+ assertNotNull( item.getClassifier( ) );
+ assertEquals( "", item.getClassifier( ) );
+ assertNotNull( item.getRemainder( ) );
+ assertEquals( "jar.md5", item.getRemainder( ) );
+ assertNotNull( item.getContentType( ) );
+ assertEquals( "", item.getContentType( ) );
+ assertEquals( "testartifact", item.getId( ) );
+ assertNotNull( item.getArtifactVersion( ) );
+ assertEquals( "", item.getArtifactVersion( ) );
+ }
+
+ @Test
+ void withContentType() {
+ ArchivaArtifact item = ArchivaArtifact.withAsset( asset ).withVersion( version ).withId( "testartifact" )
+ .withContentType( "text/xml" )
+ .build( );
+ assertNotNull( item );
+ assertNotNull( item.getRepository( ) );
+ assertEquals(repository, item.getRepository());
+ assertNotNull( item.getAsset( ) );
+ assertEquals( asset, item.getAsset( ) );
+ assertNotNull( item.getVersion( ) );
+ assertEquals( version, item.getVersion( ) );
+ assertNotNull( item.getType( ) );
+ assertEquals( "", item.getType( ) );
+ assertNotNull( item.getClassifier( ) );
+ assertEquals( "", item.getClassifier( ) );
+ assertNotNull( item.getRemainder( ) );
+ assertEquals( "", item.getRemainder( ) );
+ assertNotNull( item.getContentType( ) );
+ assertEquals( "text/xml", item.getContentType( ) );
+ assertEquals( "testartifact", item.getId( ) );
+ assertNotNull( item.getArtifactVersion( ) );
+ assertEquals( "", item.getArtifactVersion( ) );
+ }
+
+ @Test
+ void withAllAttributes() {
+ ArchivaArtifact item = ArchivaArtifact.withAsset( asset ).withVersion( version ).withId( "testartifact" )
+ .withArtifactVersion( "3.0.484848" )
+ .withType( "jar" )
+ .withClassifier( "private" )
+ .withRemainder( "jar.sha1" )
+ .withContentType( "text/html" )
+ .build( );
+
+ assertNotNull( item );
+ assertNotNull( item.getRepository( ) );
+ assertEquals(repository, item.getRepository());
+ assertNotNull( item.getAsset( ) );
+ assertEquals( asset, item.getAsset( ) );
+ assertNotNull( item.getVersion( ) );
+ assertEquals( version, item.getVersion( ) );
+ assertNotNull( item.getType( ) );
+ assertEquals( "jar", item.getType( ) );
+ assertNotNull( item.getClassifier( ) );
+ assertEquals( "private", item.getClassifier( ) );
+ assertNotNull( item.getRemainder( ) );
+ assertEquals( "jar.sha1", item.getRemainder( ) );
+ assertNotNull( item.getContentType( ) );
+ assertEquals( "text/html", item.getContentType( ) );
+ assertEquals( "testartifact", item.getId( ) );
+ assertNotNull( item.getArtifactVersion( ) );
+ assertEquals( "3.0.484848", item.getArtifactVersion( ) );
+ }
+
+
+ @Test
+ void equality() {
+ ArchivaArtifact item1 = ArchivaArtifact.withAsset( asset ).withVersion( version ).withId( "testartifact" )
+ .withArtifactVersion( "3.0.484848" )
+ .withType( "jar" )
+ .withClassifier( "private" )
+ .withRemainder( "jar.sha1" )
+ .withContentType( "text/html" )
+ .build( );
+
+ ArchivaArtifact item2 = ArchivaArtifact.withAsset( asset ).withVersion( version ).withId( "testartifact" )
+ .withArtifactVersion( "3.0.484849" )
+ .withType( "jar" )
+ .withClassifier( "private" )
+ .withRemainder( "jar.sha1" )
+ .withContentType( "text/html" )
+ .build( );
+
+ ArchivaArtifact item3 = ArchivaArtifact.withAsset( asset ).withVersion( version ).withId( "testartifact" )
+ .withArtifactVersion( "3.0.484848" )
+ .withType( "jar" )
+ .withClassifier( "private" )
+ .withRemainder( "jar.sha1" )
+ .withContentType( "text/html" )
+ .build( );
+
+ ArchivaArtifact item4 = ArchivaArtifact.withAsset( asset ).withVersion( version ).withId( "testartifact" )
+ .withArtifactVersion( "3.0.484848" )
+ .withType( "sourcejar" )
+ .withClassifier( "private" )
+ .withRemainder( "jar.sha1" )
+ .withContentType( "text/html" )
+ .build( );
+
+ ArchivaArtifact item5 = ArchivaArtifact.withAsset( asset ).withVersion( version ).withId( "testartifact" )
+ .withArtifactVersion( "3.0.484848" )
+ .withType( "jar" )
+ .withClassifier( "public" )
+ .withRemainder( "jar.sha1" )
+ .withContentType( "text/html" )
+ .build( );
+
+ ArchivaArtifact item6 = ArchivaArtifact.withAsset( asset ).withVersion( version ).withId( "testartifact" )
+ .withArtifactVersion( "3.0.484848" )
+ .withType( "jar" )
+ .withClassifier( "private" )
+ .withRemainder( "jar.md5" )
+ .withContentType( "text/html" )
+ .build( );
+
+ ArchivaArtifact item7 = ArchivaArtifact.withAsset( asset ).withVersion( version ).withId( "testartifact" )
+ .withArtifactVersion( "3.0.484848" )
+ .withType( "jar" )
+ .withClassifier( "private" )
+ .withRemainder( "jar.sha1" )
+ .withContentType( "text/xml" )
+ .build( );
+
+ ArchivaArtifact item8 = ArchivaArtifact.withAsset( asset ).withVersion( version ).withId( "testartifact2" )
+ .withArtifactVersion( "3.0.484848" )
+ .withType( "jar" )
+ .withClassifier( "private" )
+ .withRemainder( "jar.sha1" )
+ .withContentType( "text/html" )
+ .build( );
+
+ ArchivaArtifact item9 = ArchivaArtifact.withAsset( asset ).withVersion( version ).withId( "testartifact2" )
+ .build( );
+
+ ArchivaArtifact item10 = ArchivaArtifact.withAsset( asset ).withVersion( version ).withId( "testartifact2" )
+ .build( );
+
+
+ assertNotEquals( item1, item2 );
+ assertEquals( item1, item3 );
+ assertNotEquals( item1, item4 );
+ assertNotEquals( item1, item5 );
+ // remainder and content type are ignored
+ assertEquals( item1, item6 );
+ assertEquals( item1, item7 );
+
+ assertNotEquals( item1, item8 );
+ assertEquals( item9, item10 );
+
+ }
+
+}
\ No newline at end of file
--- /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.
+ */
+
+package org.apache.archiva.repository.content.base;
+
+import org.apache.archiva.repository.content.base.builder.NamespaceOptBuilder;
+import org.apache.archiva.repository.content.base.builder.OptBuilder;
+import org.apache.archiva.repository.content.base.builder.WithNamespaceBuilder;
+import org.apache.archiva.repository.mock.ManagedRepositoryContentMock;
+import org.junit.jupiter.api.Test;
+
+import java.io.IOException;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ *
+ *
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+class ArchivaNamespaceTest extends ContentItemTest
+{
+
+
+ @Test
+ void nullNamespaceThrowsIllegalArgumentException() {
+ WithNamespaceBuilder builder = ArchivaNamespace.withRepository( repository ).withAsset( asset );
+ assertThrows( IllegalArgumentException.class, ( ) -> builder.withNamespace( null ) );
+ }
+
+ @Test
+ public void namespaceOnly() throws IOException
+ {
+ assertNotNull( this.repository );
+ ArchivaNamespace result = ArchivaNamespace.withRepository( repository )
+ .withAsset( this.asset ).withNamespace( "test.1d.d" ).build( );
+
+ assertNotNull( result );
+ assertEquals( this.repository, result.getRepository( ) );
+ assertEquals( this.asset, result.getAsset( ) );
+ assertEquals( "test.1d.d", result.getNamespace( ) );
+ assertNotNull( result.getAttributes( ) );
+ assertEquals( 0, result.getAttributes( ).size( ) );
+ assertArrayEquals( new String[]{ "test", "1d", "d" }, result.getNamespacePath().toArray() );
+ }
+
+ @Test
+ public void namespaceWithEmptyPart() throws IOException
+ {
+ assertNotNull( this.repository );
+ ArchivaNamespace result = ArchivaNamespace.withRepository( repository )
+ .withAsset( this.asset ).withNamespace( "test.1d..d." ).build( );
+
+ assertNotNull( result );
+ assertEquals( this.repository, result.getRepository( ) );
+ assertEquals( this.asset, result.getAsset( ) );
+ assertEquals( "test.1d..d.", result.getNamespace( ) );
+ assertNotNull( result.getAttributes( ) );
+ assertEquals( 0, result.getAttributes( ).size( ) );
+ assertArrayEquals( new String[]{ "test", "1d", "","d" }, result.getNamespacePath().toArray() );
+ }
+
+ @Test
+ public void withSeparatorExpression() throws IOException
+ {
+ assertNotNull( this.repository );
+ ArchivaNamespace result = ArchivaNamespace.withRepository( repository )
+ .withAsset( this.asset ).withNamespace( "test.1d.d/abc/def" )
+ .withSeparatorExpression( "/" )
+ .build( );
+
+ assertNotNull( result );
+ assertEquals( this.repository, result.getRepository( ) );
+ assertEquals( this.asset, result.getAsset( ) );
+ assertEquals( "test.1d.d/abc/def", result.getNamespace( ) );
+ assertNotNull( result.getAttributes( ) );
+ assertEquals( 0, result.getAttributes( ).size( ) );
+ assertArrayEquals( new String[]{ "test.1d.d", "abc", "def" }, result.getNamespacePath().toArray() );
+ }
+
+ @Test
+ void badSeparatorExpression() {
+ NamespaceOptBuilder builder = ArchivaNamespace.withRepository( repository ).withAsset( asset ).withNamespace( "abc.de/abc" );
+ assertThrows( IllegalArgumentException.class, ( ) -> builder.withSeparatorExpression( null ) );
+ assertThrows( IllegalArgumentException.class, ( ) -> builder.withSeparatorExpression( "(" ) );
+ }
+
+
+ @Test
+ void equalityTests() {
+ ArchivaNamespace ns1 = ArchivaNamespace.withRepository( repository ).withAsset( asset ).withNamespace( "abc.de/abc" ).build();
+ ArchivaNamespace ns2 = ArchivaNamespace.withRepository( repository ).withAsset( asset ).withNamespace( "abc.de/abc" ).build();
+ ArchivaNamespace ns3 = ArchivaNamespace.withRepository( repository ).withAsset( asset ).withNamespace( "abc.de/abcd" ).build();
+ ArchivaNamespace ns4 = ArchivaNamespace.withRepository( repository ).withAsset( asset ).withNamespace( "abc.de/abc" ).
+ withSeparatorExpression( "/" ).build();
+ ArchivaNamespace ns5 = ArchivaNamespace.withRepository( new ManagedRepositoryContentMock() ).withAsset( asset ).withNamespace( "abc.de/abc" ).build();
+
+ assertFalse( ns1 == ns2 );
+ assertEquals( ns1, ns2 );
+ assertNotEquals( ns1, ns3 );
+ assertEquals( ns1, ns4 );
+ assertNotEquals( ns1, ns5 );
+
+ }
+
+
+ @Override
+ public OptBuilder getBuilder( )
+ {
+ return ArchivaNamespace.withRepository( repository ).withAsset( asset ).withNamespace( "abc.def" );
+ }
+}
\ No newline at end of file
--- /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.
+ */
+
+package org.apache.archiva.repository.content.base;
+
+import org.apache.archiva.repository.content.Namespace;
+import org.apache.archiva.repository.content.base.builder.OptBuilder;
+import org.apache.archiva.repository.content.base.builder.ProjectWithIdBuilder;
+import org.apache.archiva.repository.content.base.builder.WithNamespaceObjectBuilder;
+import org.apache.archiva.repository.mock.ManagedRepositoryContentMock;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+class ArchivaProjectTest extends ContentItemTest
+{
+
+ Namespace namespace;
+
+ @BeforeEach
+ void init() {
+ namespace = ArchivaNamespace.withRepository( repository ).withAsset( asset ).withNamespace( "test.namespace.123" ).build();
+ }
+
+ @Override
+ public OptBuilder getBuilder( )
+ {
+ return ArchivaProject.withAsset( asset ).withNamespace( namespace ).withId( "abcde" );
+ }
+
+ @Test
+ void withNamespaceAndId() {
+ ArchivaProject item = ArchivaProject.withAsset( asset ).withNamespace( namespace )
+ .withId( "abcdefg" ).build( );
+
+ assertNotNull( item );
+ assertEquals( "abcdefg", item.getId( ) );
+ assertNotNull( item.getNamespace( ) );
+ assertEquals( namespace, item.getNamespace( ) );
+ assertNotNull( item.getRepository( ) );
+ assertEquals( repository, item.getRepository( ) );
+ assertNotNull( item.getAsset( ) );
+ assertEquals( asset, item.getAsset( ) );
+
+ }
+
+ @Test
+ void illegalNamespace() {
+ WithNamespaceObjectBuilder builder = ArchivaProject.withAsset( asset );
+
+ assertThrows( IllegalArgumentException.class, ( ) -> builder.withNamespace( null ) );
+ }
+
+ @Test
+ void illegalId() {
+ ProjectWithIdBuilder builder = ArchivaProject.withAsset( asset ).withNamespace( namespace );
+ assertThrows( IllegalArgumentException.class, ( ) -> builder.withId( null ) );
+ assertThrows( IllegalArgumentException.class, ( ) -> builder.withId( "" ) );
+ }
+
+ @Test
+ void equalityTests() {
+ ArchivaProject item1 = ArchivaProject.withAsset( asset ).withNamespace( namespace )
+ .withId( "abcdefgtest1" ).build( );
+ ArchivaProject item2 = ArchivaProject.withAsset( asset ).withNamespace( namespace )
+ .withId( "abcdefgtest2" ).build( );
+ ArchivaProject item3 = ArchivaProject.withAsset( asset ).withNamespace( namespace )
+ .withId( "abcdefgtest1" ).build( );
+ ArchivaNamespace ns2 = ArchivaNamespace.withRepository( repository ).withAsset( asset ).withNamespace( "test.namespace.123" ).build( );
+ ArchivaProject item4 = ArchivaProject.withAsset( asset ).withNamespace( ns2 )
+ .withId( "abcdefgtest1" ).build( );
+ ArchivaNamespace ns3 = ArchivaNamespace.withRepository( repository ).withAsset( asset ).withNamespace( "test.namespace.1234" ).build( );
+ ArchivaProject item5 = ArchivaProject.withAsset( asset ).withNamespace( ns3 )
+ .withId( "abcdefgtest1" ).build( );
+
+ assertNotEquals( item1, item2 );
+ assertEquals( item1, item3 );
+ assertEquals( item1, item4 );
+ assertNotEquals( item1, item5 );
+
+ }
+
+
+
+}
\ No newline at end of file
--- /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.
+ */
+
+package org.apache.archiva.repository.content.base;
+
+import org.apache.archiva.repository.content.base.builder.OptBuilder;
+import org.apache.archiva.repository.content.base.builder.WithVersionBuilder;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+class ArchivaVersionTest extends ContentItemTest
+{
+
+ ArchivaProject project;
+
+ @BeforeEach
+ void init() {
+ ArchivaNamespace namespace = ArchivaNamespace.withRepository( repository ).withAsset( asset ).withNamespace( "abc.def" ).build();
+ project = ArchivaProject.withAsset( asset ).withNamespace( namespace ).withId( "proj001" ).build( );
+ }
+
+ @Override
+ public OptBuilder getBuilder( )
+ {
+ return ArchivaVersion.withAsset( asset ).withProject( project ).withVersion( "1.5.8" );
+ }
+
+ @Test
+ void versionOnly() {
+ ArchivaVersion item = ArchivaVersion.withAsset( asset ).withProject( project ).withVersion( "3.4.5" ).build();
+ assertNotNull( item );
+ assertNotNull( item.getRepository( ) );
+ assertEquals( repository, item.getRepository( ) );
+ assertNotNull( item.getAsset( ) );
+ assertEquals( asset, item.getAsset( ) );
+ assertNotNull( item.getProject( ) );
+ assertEquals( project, item.getProject( ) );
+ assertNotNull( item.getVersion( ) );
+ assertEquals( "3.4.5", item.getVersion( ) );
+ assertNotNull( item.getVersionSegments( ) );
+ assertArrayEquals( new String[]{"3", "4", "5"}, item.getVersionSegments( ).toArray( ) );
+ }
+
+ @Test
+ void versionSegments() {
+ ArchivaVersion item = ArchivaVersion.withAsset( asset ).withProject( project ).withVersion( "3.455.5" ).build();
+ assertNotNull( item );
+ assertNotNull( item.getVersionSegments( ) );
+ assertArrayEquals( new String[]{"3", "455", "5"}, item.getVersionSegments( ).toArray( ) );
+
+ ArchivaVersion item2 = ArchivaVersion.withAsset( asset ).withProject( project ).withVersion( "xd43.455.5" ).build();
+ assertNotNull( item2 );
+ assertNotNull( item2.getVersionSegments( ) );
+ assertArrayEquals( new String[]{"xd43", "455", "5"}, item2.getVersionSegments( ).toArray( ) );
+ }
+
+ @Test
+ void illegalVersion() {
+ WithVersionBuilder builder = ArchivaVersion.withAsset( asset ).withProject( project );
+ assertThrows( IllegalArgumentException.class, ( ) -> builder.withVersion( null ) );
+ assertThrows( IllegalArgumentException.class, ( ) -> builder.withVersion( "" ) );
+ }
+
+}
\ No newline at end of file
--- /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.
+ */
+
+package org.apache.archiva.repository.content.base;
+
+import org.apache.archiva.common.filelock.DefaultFileLockManager;
+import org.apache.archiva.repository.content.ContentItem;
+import org.apache.archiva.repository.content.base.builder.OptBuilder;
+import org.apache.archiva.repository.mock.ManagedRepositoryContentMock;
+import org.apache.archiva.repository.storage.FilesystemStorage;
+import org.apache.archiva.repository.storage.StorageAsset;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.io.IOException;
+import java.nio.file.Paths;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public abstract class ContentItemTest
+{
+ protected ManagedRepositoryContentMock repository;
+ protected FilesystemStorage storage;
+ protected StorageAsset asset;
+
+ @BeforeEach
+ public void setup() throws IOException
+ {
+ this.repository = new ManagedRepositoryContentMock( );
+
+ this.storage = new FilesystemStorage( Paths.get( "target" ), new DefaultFileLockManager( ) );
+
+ this.asset = storage.getAsset( "" );
+
+ }
+
+ public abstract OptBuilder getBuilder();
+
+ @Test
+ void testWithAttribute() {
+ ContentItem test = getBuilder( ).withAttribute( "testkey1", "testvalue1" ).withAttribute( "testkey2", "testvalue2" ).build( );
+
+ assertNotNull( test.getAttributes( ) );
+ assertEquals( 2, test.getAttributes( ).size( ) );
+ assertEquals( "testvalue1", test.getAttribute( "testkey1" ) );
+ assertEquals( "testvalue2", test.getAttribute( "testkey2" ) );
+ assertNull( test.getAttribute( "key123" ) );
+
+ }
+
+}