--- /dev/null
+package org.apache.archiva.repository;
+
+/*
+ * 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.Artifact;
+import org.apache.archiva.repository.content.ContentItem;
+import org.apache.archiva.repository.content.Namespace;
+import org.apache.archiva.repository.content.Project;
+import org.apache.archiva.repository.content.Version;
+
+/**
+ *
+ * Deletion status of a given item.
+ *
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public class ItemDeleteStatus
+{
+ public static final int OK = 0;
+ public static final int DELETION_FAILED = 1;
+ public static final int ITEM_NOT_FOUND = 2;
+ public static final int UNKNOWN = 128;
+
+ private ContentItem item;
+ private int status;
+ private Throwable exception;
+
+ public ItemDeleteStatus(ContentItem item) {
+ this.item = item;
+ this.status = OK;
+ }
+
+ public ItemDeleteStatus(ContentItem item, int status) {
+ this.item = item;
+ this.status = status;
+ }
+
+ public ItemDeleteStatus(ContentItem item, int status, Throwable e) {
+ this.item = item;
+ this.status = status;
+ this.exception = e;
+ }
+
+ public ContentItem getItem( )
+ {
+ return item;
+ }
+
+ public int getStatus( )
+ {
+ return status;
+ }
+
+ public Throwable getException( )
+ {
+ return exception;
+ }
+
+ public Class<? extends ContentItem> getItemType() {
+ if (item instanceof Namespace ) {
+ return Namespace.class;
+ } else if (item instanceof Project ) {
+ return Project.class;
+ } else if (item instanceof Version ) {
+ return Version.class;
+ } else if (item instanceof Artifact ) {
+ return Artifact.class;
+ } else {
+ return ContentItem.class;
+ }
+ }
+
+
+ public <U extends ContentItem> U adapt(Class<U> clazz) throws IllegalArgumentException {
+ if (clazz.isAssignableFrom( item.getClass() )) {
+ return (U) item;
+ } else {
+ throw new IllegalArgumentException( "Cannot convert instance of " + item.getClass( ) + " to " + clazz );
+ }
+ }
+
+
+
+
+}
import org.apache.archiva.repository.storage.StorageAsset;
import java.nio.file.Path;
+import java.util.BitSet;
import java.util.List;
import java.util.Set;
+import java.util.function.Consumer;
import java.util.stream.Stream;
/**
/// ***************** New generation interface **********************
+ /**
+ * Delete all items that match the given selector. The type and number of deleted items
+ * depend on the specific selector:
+ * <ul>
+ * <li>namespace: the complete namespace is deleted (recursively if the recurse flag is set)</li>
+ * <li>project: the complete project and all contained versions are deleted</li>
+ * <li>version: the version inside the project is deleted (project is required)</li>
+ * <li>artifactId: all artifacts that match the id (project and version are required)</li>
+ * <li>artifactVersion: all artifacts that match the version (project and version are required)</li>
+ * <li></li>
+ * </ul>
+ *
+ * @param selector the item selector that selects the artifacts to delete
+ * @param consumer a consumer of the items that will be called after deletion
+ * @returns the list of items that are deleted
+ * @throws ContentAccessException if the deletion was not possible or only partly successful, because the access
+ * to the artifacts failed
+ * @throws IllegalArgumentException if the selector does not specify valid artifacts to delete
+ */
+ void deleteAllItems( ItemSelector selector, Consumer<ItemDeleteStatus> consumer) throws ContentAccessException, IllegalArgumentException;
+
/**
* Removes the specified content item and if the item is a container or directory,
* all content stored under the given item.
* <li>artifactId or projectId</li>
* </ul>
* If the coordinates do not provide enough information for selecting a artifact, a {@link IllegalArgumentException} will be thrown
- * It depends on the repository type, what exactly is deleted for a given set of coordinates. Some repository type
+ * It depends on the repository type, what exactly is returned for a given set of coordinates. Some repository type
* may have different required and optional coordinates. For further information please check the documentation for the
* type specific implementations.
*
- * The following coordinates are optional and may further specify the artifact to delete.
+ * The following coordinates are optional and may further specify the artifact to return.
* <ul>
* <li>classifier</li>
* <li>type</li>
*/
Stream<? extends Artifact> newArtifactStream( ItemSelector selector) throws ContentAccessException;
+ /**
+ * Returns a stream of items that match the given selector. It may return a stream of mixed types,
+ * like namespaces, projects, versions and artifacts. It will not select a specific type.
+ * The selector can specify the '*' pattern for all fields.
+ * The returned elements will be provided by depth first.
+ *
+ * @param selector the item selector that specifies the items
+ * @return the stream of content items
+ * @throws ContentAccessException if the access to the underlying storage failed
+ * @throws IllegalArgumentException if a illegal coordinate combination was provided
+ */
+ Stream<? extends ContentItem> newItemStream(ItemSelector selector, boolean parallel) throws ContentAccessException, IllegalArgumentException;
+
/**
* Return the projects that are part of the given namespace.
*
* @author Martin Stockhammer <martin_s@apache.org>
*/
-public interface Artifact extends ContentItem
+public interface Artifact extends DataItem
{
/**
*
* @return the identifier of the artifact. Never returns <code>null</code> or empty string
*/
+ @Override
String getId( );
/**
*/
String getClassifier( );
+ /**
+ * This may be different from extension and gives the remainder that is used to build the file path from
+ * the artifact coordinates (namespace, id, version, classifier, type)
+ *
+ * @return the file name remainder
+ */
+ String getRemainder( );
+
+ /**
+ * Returns the type of the artifact
+ * @return
+ */
+ @Override
+ ArtifactType getDataType();
+
+ /**
+ * Returns a unique key
+ * @return
+ */
+ String toKey();
+
+
/**
* Short cut for the file name. Should always return the same value as the artifact name.
*
* @return the name of the file
*/
+ @Override
default String getFileName( )
{
return getAsset( ).getName( );
*
* @return the file name extension
*/
+ @Override
default String getExtension( )
{
final String name = getAsset( ).getName( );
}
}
- /**
- * This may be different from extension and gives the remainder that is used to build the file path from
- * the artifact coordinates (namespace, id, version, classifier, type)
- *
- * @return the file name remainder
- */
- String getRemainder( );
-
- /**
- * Should return the mime type of the artifact.
- *
- * @return the mime type of the artifact.
- */
- String getContentType( );
-
- /**
- * Returns the type of the artifact
- * @return
- */
- ArtifactType getArtifactType();
-
- /**
- * Returns a unique key
- * @return
- */
- String toKey();
-
-
-
+ default ContentItem getParent( )
+ {
+ return getVersion();
+ }
}
*
* @author Martin Stockhammer <martin_s@apache.org>
*/
-public interface ArtifactType
+public interface ArtifactType extends DataItemType
{
String name();
}
--- /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.
+ */
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public enum BaseDataItemTypes implements DataItemType
+{
+ METADATA,UNKNOWN
+}
--- /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.
+ */
+
+/**
+ *
+ * A data item is a item that is not a real artifact because it does not have
+ * a version, but is normally file based.
+ *
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public interface DataItem extends ContentItem
+{
+
+ /**
+ * Returns the parent of the data item
+ * @return the parent item, which is either a Version, Project or Namespace
+ */
+ ContentItem getParent( );
+
+ /**
+ * Returns the identifier of the data item.
+ * @return the identifier string
+ */
+ String getId( );
+
+ /**
+ * Returns the extension of the file. This method should always return the extension string after the last
+ * '.'-character.
+ *
+ * @return the file name extension
+ */
+ default String getExtension( )
+ {
+ final String name = getAsset( ).getName( );
+ final int idx = name.lastIndexOf( '.' )+1;
+ if ( idx > 0 )
+ {
+ return name.substring( idx );
+ }
+ else
+ {
+ return "";
+ }
+ }
+
+ /**
+ * Should return the mime type of the artifact.
+ *
+ * @return the mime type of the artifact.
+ */
+ String getContentType( );
+
+
+ /**
+ * 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( )
+ {
+ return getAsset( ).getName( );
+ }
+
+ /**
+ * Returns the
+ * @return the type of the item
+ */
+ DataItemType getDataType();
+
+}
--- /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.
+ */
+
+/**
+ * The data item type
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public interface DataItemType
+{
+ String name();
+}
import org.apache.archiva.repository.content.Artifact;
import org.apache.archiva.repository.content.ArtifactType;
import org.apache.archiva.repository.content.BaseArtifactTypes;
+import org.apache.archiva.repository.content.ContentItem;
+import org.apache.archiva.repository.content.DataItem;
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;
}
-
@Override
public String getId( )
{
}
@Override
- public ArtifactType getArtifactType( )
+ public ArtifactType getDataType( )
{
return artifactType;
}
--- /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.BaseArtifactTypes;
+import org.apache.archiva.repository.content.BaseDataItemTypes;
+import org.apache.archiva.repository.content.ContentItem;
+import org.apache.archiva.repository.content.DataItem;
+import org.apache.archiva.repository.content.DataItemType;
+import org.apache.archiva.repository.content.base.builder.DataItemOptBuilder;
+import org.apache.archiva.repository.content.base.builder.DataItemWithIdBuilder;
+import org.apache.archiva.repository.storage.StorageAsset;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * 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>
+ * Artifacts 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>
+ * <li>artifactType</li>
+ * </ul>
+ *
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public class ArchivaDataItem extends ArchivaContentItem implements DataItem
+{
+ private String id;
+ private ContentItem parent;
+ private String contentType;
+ private DataItemType dataItemType;
+
+ private ArchivaDataItem( )
+ {
+
+ }
+
+ @Override
+ public String getId( )
+ {
+ return id;
+ }
+
+ @Override
+ public ContentItem getParent( )
+ {
+ return parent;
+ }
+
+ @Override
+ public String getContentType( )
+ {
+ return contentType;
+ }
+
+ @Override
+ public DataItemType getDataType( )
+ {
+ return dataItemType;
+ }
+
+
+ /**
+ * 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 DataItemWithIdBuilder withAsset( StorageAsset asset )
+ {
+ return new Builder( ).withAsset( asset );
+ }
+
+
+ @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;
+
+ ArchivaDataItem that = (ArchivaDataItem) o;
+
+ if ( !id.equals( that.id ) ) return false;
+ if ( !parent.equals( that.parent ) ) return false;
+ return dataItemType.equals(that.dataItemType );
+ }
+
+ @Override
+ public int hashCode( )
+ {
+ int result = super.hashCode( );
+ result = 31 * result + id.hashCode( );
+ result = 31 * result + parent.hashCode( );
+ result = 31 * result + dataItemType.hashCode( );
+ return result;
+ }
+
+ @Override
+ public String toString( )
+ {
+ final StringBuilder sb = new StringBuilder( "ArchivaArtifact{" );
+ sb.append( "id='" ).append( id ).append( '\'' );
+ sb.append( ", parent=" ).append( parent );
+ sb.append( ", contentType='" ).append( contentType ).append( '\'' );
+ sb.append( ", artifactType=" ).append( dataItemType );
+ sb.append( '}' );
+ return sb.toString( );
+ }
+
+ public static String defaultString( String value )
+ {
+ if ( value == null )
+ {
+ return "";
+ }
+
+ return value.trim();
+ }
+
+ private static class Builder
+ extends ContentItemBuilder<ArchivaDataItem, DataItemOptBuilder, DataItemWithIdBuilder >
+ implements DataItemOptBuilder,DataItemWithIdBuilder
+ {
+
+ Builder( )
+ {
+ super( new ArchivaDataItem( ) );
+ }
+
+ @Override
+ protected DataItemOptBuilder getOptBuilder( )
+ {
+ return this;
+ }
+
+ @Override
+ protected DataItemWithIdBuilder getNextBuilder( )
+ {
+ return this;
+ }
+
+ @Override
+ public DataItemOptBuilder withParent( ContentItem parent )
+ {
+ if ( parent == null )
+ {
+ throw new IllegalArgumentException( "version may not be null" );
+ }
+ item.parent = parent;
+ super.setRepository( parent.getRepository( ) );
+ return this;
+ }
+
+ @Override
+ public DataItemOptBuilder withId( String id )
+ {
+ if ( StringUtils.isEmpty( id ) )
+ {
+ throw new IllegalArgumentException( "Artifact id may not be null or empty" );
+ }
+ item.id = id;
+ return this;
+ }
+
+
+ @Override
+ public DataItemOptBuilder withContentType( String contentType )
+ {
+ item.contentType = contentType;
+ return this;
+ }
+
+ @Override
+ public DataItemOptBuilder withDataType( DataItemType type )
+ {
+ item.dataItemType = type;
+ return this;
+ }
+
+ @Override
+ public ArchivaDataItem build( )
+ {
+ super.build( );
+ if ( item.contentType == null )
+ {
+ item.contentType = "";
+ }
+ if (item.dataItemType ==null) {
+ item.dataItemType = BaseDataItemTypes.UNKNOWN;
+ }
+
+ return item;
+ }
+ }
+}
--- /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.ArtifactType;
+import org.apache.archiva.repository.content.ContentItem;
+import org.apache.archiva.repository.content.DataItem;
+import org.apache.archiva.repository.content.DataItemType;
+import org.apache.archiva.repository.content.base.ArchivaArtifact;
+import org.apache.archiva.repository.content.base.ArchivaDataItem;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public interface DataItemOptBuilder
+ extends OptBuilder<ArchivaDataItem, DataItemOptBuilder>
+{
+
+ DataItemOptBuilder withParent( ContentItem parent );
+
+ DataItemOptBuilder withContentType( String contentType );
+
+ DataItemOptBuilder withDataType( DataItemType type );
+
+ ArchivaDataItem 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 DataItemWithIdBuilder
+{
+ DataItemOptBuilder withId( String id );
+}
import org.apache.archiva.model.VersionedReference;
import org.apache.archiva.repository.ContentAccessException;
import org.apache.archiva.repository.ContentNotFoundException;
+import org.apache.archiva.repository.ItemDeleteStatus;
import org.apache.archiva.repository.LayoutException;
import org.apache.archiva.repository.ManagedRepository;
import org.apache.archiva.repository.ManagedRepositoryContent;
import java.nio.file.Path;
import java.util.List;
+import java.util.function.Consumer;
import java.util.stream.Stream;
/**
return null;
}
+ @Override
+ public void deleteAllItems( ItemSelector selector, Consumer<ItemDeleteStatus> consumer ) throws ContentAccessException, IllegalArgumentException
+ {
+
+ }
+
@Override
public void deleteItem( ContentItem item ) throws ItemNotFoundException, ContentAccessException
{
return null;
}
+ @Override
+ public Stream<? extends ContentItem> newItemStream( ItemSelector selector, boolean parallel ) throws ContentAccessException, IllegalArgumentException
+ {
+ return null;
+ }
+
@Override
public List<? extends Project> getProjects( Namespace namespace ) throws ContentAccessException
{
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;
return null;
}
+ @Override
+ public void deleteAllItems( ItemSelector selector, Consumer<ItemDeleteStatus> consumer ) throws ContentAccessException, IllegalArgumentException
+ {
+
+ }
+
@Override
public void deleteItem( ContentItem item ) throws ItemNotFoundException, ContentAccessException
{
return null;
}
+ @Override
+ public Stream<? extends ContentItem> newItemStream( ItemSelector selector, boolean parallel ) throws ContentAccessException, IllegalArgumentException
+ {
+ return null;
+ }
+
@Override
public List<? extends Project> getProjects( Namespace namespace ) throws ContentAccessException
{