org.apache.archiva.repository.content.maven2.ManagedDefaultRepositoryContent.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.archiva.repository.content.maven2.ManagedDefaultRepositoryContent.java

Source

package org.apache.archiva.repository.content.maven2;

/*
 * 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.admin.model.beans.ManagedRepository;
import org.apache.archiva.common.utils.PathUtil;
import org.apache.archiva.configuration.FileTypes;
import org.apache.archiva.metadata.repository.storage.maven2.DefaultArtifactMappingProvider;
import org.apache.archiva.model.ArchivaArtifact;
import org.apache.archiva.model.ArtifactReference;
import org.apache.archiva.model.ProjectReference;
import org.apache.archiva.model.VersionedReference;
import org.apache.archiva.repository.ContentNotFoundException;
import org.apache.archiva.repository.ManagedRepositoryContent;
import org.apache.archiva.repository.RepositoryException;
import org.apache.archiva.repository.layout.LayoutException;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import javax.inject.Inject;
import javax.inject.Named;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

/**
 * ManagedDefaultRepositoryContent
 */
@Service("managedRepositoryContent#default")
@Scope("prototype")
public class ManagedDefaultRepositoryContent extends AbstractDefaultRepositoryContent
        implements ManagedRepositoryContent {
    @Inject
    @Named("fileTypes")
    private FileTypes filetypes;

    private ManagedRepository repository;

    public ManagedDefaultRepositoryContent() {
        // default to use if there are none supplied as components
        this.artifactMappingProviders = Collections.singletonList(new DefaultArtifactMappingProvider());
    }

    @Override
    public void deleteVersion(VersionedReference reference) {
        String path = toMetadataPath(reference);
        File projectPath = new File(getRepoRoot(), path);

        File projectDir = projectPath.getParentFile();
        if (projectDir.exists() && projectDir.isDirectory()) {
            FileUtils.deleteQuietly(projectDir);
        }
    }

    @Override
    public void deleteProject(String namespace, String projectId)
            throws RepositoryException, ContentNotFoundException {
        ArtifactReference artifactReference = new ArtifactReference();
        artifactReference.setGroupId(namespace);
        artifactReference.setArtifactId(projectId);
        String path = toPath(artifactReference);
        File directory = new File(getRepoRoot(), path);
        if (!directory.exists()) {
            throw new ContentNotFoundException("cannot found project " + namespace + ":" + projectId);
        }
        if (directory.isDirectory()) {
            try {
                FileUtils.deleteDirectory(directory);
            } catch (IOException e) {
                throw new RepositoryException(e.getMessage(), e);
            }
        } else {
            log.warn("project {}:{} is not a directory", namespace, projectId);
        }

    }

    @Override
    public void deleteArtifact(ArtifactReference artifactReference) {
        String path = toPath(artifactReference);
        File filePath = new File(getRepoRoot(), path);

        if (filePath.exists()) {
            FileUtils.deleteQuietly(filePath);
        }

        File filePathmd5 = new File(getRepoRoot(), path + ".md5");

        if (filePathmd5.exists()) {
            FileUtils.deleteQuietly(filePathmd5);
        }

        File filePathsha1 = new File(getRepoRoot(), path + ".sha1");

        if (filePathsha1.exists()) {
            FileUtils.deleteQuietly(filePathsha1);
        }
    }

    @Override
    public void deleteGroupId(String groupId) throws ContentNotFoundException {

        String path = StringUtils.replaceChars(groupId, '.', '/');

        File directory = new File(getRepoRoot(), path);

        if (directory.exists()) {
            try {
                FileUtils.deleteDirectory(directory);
            } catch (IOException e) {
                log.warn("skip error deleting directory {}:", directory.getPath(), e);
            }
        }
    }

    @Override
    public String getId() {
        return repository.getId();
    }

    @Override
    public Set<ArtifactReference> getRelatedArtifacts(ArtifactReference reference) throws ContentNotFoundException {
        File artifactFile = toFile(reference);
        File repoDir = artifactFile.getParentFile();

        if (!repoDir.exists()) {
            throw new ContentNotFoundException(
                    "Unable to get related artifacts using a non-existant directory: " + repoDir.getAbsolutePath());
        }

        if (!repoDir.isDirectory()) {
            throw new ContentNotFoundException(
                    "Unable to get related artifacts using a non-directory: " + repoDir.getAbsolutePath());
        }

        Set<ArtifactReference> foundArtifacts = new HashSet<>();

        // First gather up the versions found as artifacts in the managed repository.
        File repoFiles[] = repoDir.listFiles();
        for (File repoFile : repoFiles) {
            if (repoFile.isDirectory()) {
                // Skip it. it's a directory.
                continue;
            }
            String relativePath = PathUtil.getRelative(repository.getLocation(), repoFile);
            if (filetypes.matchesArtifactPattern(relativePath)) {
                try {
                    ArtifactReference artifact = toArtifactReference(relativePath);

                    // Test for related, groupId / artifactId / version must match.
                    if (artifact.getGroupId().equals(reference.getGroupId())
                            && artifact.getArtifactId().equals(reference.getArtifactId())
                            && artifact.getVersion().equals(reference.getVersion())) {
                        foundArtifacts.add(artifact);
                    }
                } catch (LayoutException e) {
                    log.debug("Not processing file that is not an artifact: {}", e.getMessage());
                }
            }
        }

        return foundArtifacts;
    }

    @Override
    public String getRepoRoot() {
        return repository.getLocation();
    }

    @Override
    public ManagedRepository getRepository() {
        return repository;
    }

    /**
     * Gather the Available Versions (on disk) for a specific Project Reference, based on filesystem
     * information.
     *
     * @return the Set of available versions, based on the project reference.
     * @throws org.apache.archiva.repository.layout.LayoutException
     * @throws org.apache.archiva.repository.layout.LayoutException
     */
    @Override
    public Set<String> getVersions(ProjectReference reference) throws ContentNotFoundException, LayoutException {
        String path = toMetadataPath(reference);

        int idx = path.lastIndexOf('/');
        if (idx > 0) {
            path = path.substring(0, idx);
        }

        File repoDir = new File(repository.getLocation(), path);

        if (!repoDir.exists()) {
            throw new ContentNotFoundException(
                    "Unable to get Versions on a non-existant directory: " + repoDir.getAbsolutePath());
        }

        if (!repoDir.isDirectory()) {
            throw new ContentNotFoundException(
                    "Unable to get Versions on a non-directory: " + repoDir.getAbsolutePath());
        }

        Set<String> foundVersions = new HashSet<>();
        VersionedReference versionRef = new VersionedReference();
        versionRef.setGroupId(reference.getGroupId());
        versionRef.setArtifactId(reference.getArtifactId());

        File repoFiles[] = repoDir.listFiles();
        for (File repoFile : repoFiles) {
            if (!repoFile.isDirectory()) {
                // Skip it. not a directory.
                continue;
            }
            // Test if dir has an artifact, which proves to us that it is a valid version directory.
            String version = repoFile.getName();
            versionRef.setVersion(version);
            if (hasArtifact(versionRef)) {
                // Found an artifact, must be a valid version.
                foundVersions.add(version);
            }
        }

        return foundVersions;
    }

    @Override
    public Set<String> getVersions(VersionedReference reference) throws ContentNotFoundException {
        String path = toMetadataPath(reference);

        int idx = path.lastIndexOf('/');
        if (idx > 0) {
            path = path.substring(0, idx);
        }

        File repoDir = new File(repository.getLocation(), path);

        if (!repoDir.exists()) {
            throw new ContentNotFoundException(
                    "Unable to get versions on a non-existant directory: " + repoDir.getAbsolutePath());
        }

        if (!repoDir.isDirectory()) {
            throw new ContentNotFoundException(
                    "Unable to get versions on a non-directory: " + repoDir.getAbsolutePath());
        }

        Set<String> foundVersions = new HashSet<>();

        // First gather up the versions found as artifacts in the managed repository.
        File repoFiles[] = repoDir.listFiles();
        for (File repoFile : repoFiles) {
            if (repoFile.isDirectory()) {
                // Skip it. it's a directory.
                continue;
            }
            String relativePath = PathUtil.getRelative(repository.getLocation(), repoFile);
            if (filetypes.matchesDefaultExclusions(relativePath)) {
                // Skip it, it's metadata or similar
                continue;
            }
            if (filetypes.matchesArtifactPattern(relativePath)) {
                try {
                    ArtifactReference artifact = toArtifactReference(relativePath);

                    foundVersions.add(artifact.getVersion());
                } catch (LayoutException e) {
                    log.debug("Not processing file that is not an artifact: {}", e.getMessage());
                }
            }
        }

        return foundVersions;
    }

    @Override
    public boolean hasContent(ArtifactReference reference) {
        File artifactFile = toFile(reference);
        return artifactFile.exists() && artifactFile.isFile();
    }

    @Override
    public boolean hasContent(ProjectReference reference) {
        try {
            Set<String> versions = getVersions(reference);
            return !versions.isEmpty();
        } catch (ContentNotFoundException | LayoutException e) {
            return false;
        }
    }

    @Override
    public boolean hasContent(VersionedReference reference) {
        try {
            return (getFirstArtifact(reference) != null);
        } catch (IOException | LayoutException e) {
            return false;
        }
    }

    @Override
    public void setRepository(ManagedRepository repository) {
        this.repository = repository;
    }

    /**
     * Convert a path to an artifact reference.
     *
     * @param path the path to convert. (relative or full location path)
     * @throws org.apache.archiva.repository.layout.LayoutException if the path cannot be converted to an artifact reference.
     */
    @Override
    public ArtifactReference toArtifactReference(String path) throws LayoutException {
        if ((path != null) && path.startsWith(repository.getLocation()) && repository.getLocation().length() > 0) {
            return super.toArtifactReference(path.substring(repository.getLocation().length() + 1));
        }

        return super.toArtifactReference(path);
    }

    @Override
    public File toFile(ArtifactReference reference) {
        return new File(repository.getLocation(), toPath(reference));
    }

    @Override
    public File toFile(ArchivaArtifact reference) {
        return new File(repository.getLocation(), toPath(reference));
    }

    /**
     * Get the first Artifact found in the provided VersionedReference location.
     *
     * @param reference the reference to the versioned reference to search within
     * @return the ArtifactReference to the first artifact located within the versioned reference. or null if
     *         no artifact was found within the versioned reference.
     * @throws java.io.IOException     if the versioned reference is invalid (example: doesn't exist, or isn't a directory)
     * @throws org.apache.archiva.repository.layout.LayoutException
     */
    private ArtifactReference getFirstArtifact(VersionedReference reference) throws LayoutException, IOException {
        String path = toMetadataPath(reference);

        int idx = path.lastIndexOf('/');
        if (idx > 0) {
            path = path.substring(0, idx);
        }

        File repoDir = new File(repository.getLocation(), path);

        if (!repoDir.exists()) {
            throw new IOException("Unable to gather the list of snapshot versions on a non-existant directory: "
                    + repoDir.getAbsolutePath());
        }

        if (!repoDir.isDirectory()) {
            throw new IOException("Unable to gather the list of snapshot versions on a non-directory: "
                    + repoDir.getAbsolutePath());
        }

        File repoFiles[] = repoDir.listFiles();
        for (File repoFile : repoFiles) {
            if (repoFile.isDirectory()) {
                // Skip it. it's a directory.
                continue;
            }
            String relativePath = PathUtil.getRelative(repository.getLocation(), repoFile);
            if (filetypes.matchesArtifactPattern(relativePath)) {
                ArtifactReference artifact = toArtifactReference(relativePath);

                return artifact;
            }
        }

        // No artifact was found.
        return null;
    }

    private boolean hasArtifact(VersionedReference reference) throws LayoutException {
        try {
            return (getFirstArtifact(reference) != null);
        } catch (IOException e) {
            return false;
        }
    }

    public void setFiletypes(FileTypes filetypes) {
        this.filetypes = filetypes;
    }
}