org.codehaus.mojo.mrm.impl.maven.DiskArtifactStore.java Source code

Java tutorial

Introduction

Here is the source code for org.codehaus.mojo.mrm.impl.maven.DiskArtifactStore.java

Source

/*
 * Copyright 2011 Stephen Connolly
 *
 * Licensed 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.codehaus.mojo.mrm.impl.maven;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Calendar;
import java.util.Collections;
import java.util.GregorianCalendar;
import java.util.HashSet;
import java.util.Set;
import java.util.Stack;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.artifact.repository.metadata.Metadata;
import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader;
import org.codehaus.mojo.mrm.api.maven.Artifact;
import org.codehaus.mojo.mrm.api.maven.ArtifactNotFoundException;
import org.codehaus.mojo.mrm.api.maven.BaseArtifactStore;
import org.codehaus.mojo.mrm.api.maven.MetadataNotFoundException;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;

/**
 * An artifact store backed by a directory on the local disk.
 *
 * @since 1.0
 */
public class DiskArtifactStore extends BaseArtifactStore {
    /**
     * The root of the artifact store.
     *
     * @since 1.0
     */
    private final File root;

    /**
     * Creates a new artifact store hosted at the supplied root directory.
     *
     * @param root the root directory of the artifact store.
     * @since 1.0
     */
    public DiskArtifactStore(File root) {
        this.root = root;
    }

    /**
     * {@inheritDoc}
     */
    public Set<String> getGroupIds(String parentGroupId) {
        File parentDir = StringUtils.isEmpty(parentGroupId) ? root
                : new File(root, parentGroupId.replace('.', '/'));
        if (!parentDir.isDirectory()) {
            return Collections.emptySet();
        }
        File[] groupDirs = parentDir.listFiles();
        Set<String> result = new HashSet<String>();
        for (int i = 0; i < groupDirs.length; i++) {
            if (groupDirs[i].isDirectory()) {
                result.add(groupDirs[i].getName());
            }
        }
        return result;
    }

    /**
     * {@inheritDoc}
     */
    public Set<String> getArtifactIds(String groupId) {
        File groupDir = new File(root, groupId.replace('.', '/'));
        if (!groupDir.isDirectory()) {
            return Collections.emptySet();
        }
        Set<String> result = new HashSet<String>();
        File[] artifactDirs = groupDir.listFiles();
        for (int i = 0; i < artifactDirs.length; i++) {
            if (!artifactDirs[i].isDirectory()) {
                continue;
            }
            final String artifactId = artifactDirs[i].getName();
            result.add(artifactId);
        }
        return result;
    }

    /**
     * {@inheritDoc}
     */
    public Set<String> getVersions(String groupId, String artifactId) {
        File groupDir = new File(root, groupId.replace('.', '/'));
        File artifactDir = new File(groupDir, artifactId);
        if (!artifactDir.isDirectory()) {
            return Collections.emptySet();
        }
        File[] dirs = artifactDir.listFiles();
        Set<String> result = new HashSet<String>();
        for (int i = 0; i < dirs.length; i++) {
            if (!dirs[i].isDirectory()) {
                continue;
            }
            result.add(dirs[i].getName());
        }
        return result;
    }

    /**
     * {@inheritDoc}
     */
    public Set<Artifact> getArtifacts(final String groupId, final String artifactId, final String version) {
        File groupDir = new File(root, groupId.replace('.', '/'));
        File artifactDir = new File(groupDir, artifactId);
        File versionDir = new File(artifactDir, version);
        if (!versionDir.isDirectory()) {
            return Collections.emptySet();
        }
        final Pattern rule;

        abstract class ArtifactFactory {
            abstract Artifact get(File file);
        }

        final ArtifactFactory factory;
        if (version.endsWith("-SNAPSHOT")) {
            rule = Pattern.compile("\\Q" + artifactId + "\\E-(?:\\Q" + StringUtils.removeEnd(version, "-SNAPSHOT")
                    + "\\E-(SNAPSHOT|(\\d{4})(\\d{2})(\\d{2})\\.(\\d{2})(\\d{2})(\\d{2})-(\\d+)))(?:-([^.]+))?\\.([^/]*)");
            factory = new ArtifactFactory() {
                public Artifact get(File file) {
                    Matcher matcher = rule.matcher(file.getName());
                    if (!matcher.matches()) {
                        return null;
                    }
                    if (matcher.group(1).equals("SNAPSHOT")) {
                        return new Artifact(groupId, artifactId, version, matcher.group(9), matcher.group(10));
                    }
                    try {
                        Calendar cal = new GregorianCalendar();
                        cal.setTimeZone(TimeZone.getTimeZone("GMT"));
                        cal.set(Calendar.YEAR, Integer.parseInt(matcher.group(2)));
                        cal.set(Calendar.MONTH, Integer.parseInt(matcher.group(3)) - 1);
                        cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(matcher.group(4)));
                        cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(matcher.group(5)));
                        cal.set(Calendar.MINUTE, Integer.parseInt(matcher.group(6)));
                        cal.set(Calendar.SECOND, Integer.parseInt(matcher.group(7)));
                        long timestamp = cal.getTimeInMillis();
                        int buildNumber = Integer.parseInt(matcher.group(8));
                        return new Artifact(groupId, artifactId, version, matcher.group(9), matcher.group(10),
                                timestamp, buildNumber);
                    } catch (NullPointerException e) {
                        return null;
                    }
                }
            };
        } else {
            rule = Pattern.compile("\\Q" + artifactId + "\\E-\\Q" + version + "\\E(?:-([^.]+))?\\.(.+)");
            factory = new ArtifactFactory() {
                public Artifact get(File file) {
                    Matcher matcher = rule.matcher(file.getName());
                    if (!matcher.matches()) {
                        return null;
                    }
                    return new Artifact(groupId, artifactId, version, matcher.group(1), matcher.group(2));
                }
            };
        }
        File[] files = versionDir.listFiles();
        Set<Artifact> result = new HashSet<Artifact>(files.length);
        for (int i = 0; i < files.length; i++) {
            if (!files[i].isFile() || !rule.matcher(files[i].getName()).matches()) {
                continue;
            }
            Artifact artifact = factory.get(files[i]);
            if (artifact != null) {
                result.add(artifact);
            }
        }
        return result;
    }

    /**
     * {@inheritDoc}
     */
    public long getLastModified(Artifact artifact) throws IOException, ArtifactNotFoundException {
        File groupDir = new File(root, artifact.getGroupId().replace('.', '/'));
        File artifactDir = new File(groupDir, artifact.getArtifactId());
        File versionDir = new File(artifactDir, artifact.getVersion());
        File file = new File(versionDir, artifact.getName());
        if (!file.isFile()) {
            throw new ArtifactNotFoundException(artifact);
        }
        return file.lastModified();
    }

    /**
     * {@inheritDoc}
     */
    public long getSize(Artifact artifact) throws IOException, ArtifactNotFoundException {
        File groupDir = new File(root, artifact.getGroupId().replace('.', '/'));
        File artifactDir = new File(groupDir, artifact.getArtifactId());
        File versionDir = new File(artifactDir, artifact.getVersion());
        File file = new File(versionDir, artifact.getName());
        if (!file.isFile()) {
            throw new ArtifactNotFoundException(artifact);
        }
        return file.length();
    }

    /**
     * {@inheritDoc}
     */
    public InputStream get(Artifact artifact) throws IOException, ArtifactNotFoundException {
        File groupDir = new File(root, artifact.getGroupId().replace('.', '/'));
        File artifactDir = new File(groupDir, artifact.getArtifactId());
        File versionDir = new File(artifactDir, artifact.getVersion());
        File file = new File(versionDir, artifact.getName());
        if (!file.isFile()) {
            throw new ArtifactNotFoundException(artifact);
        }
        return new FileInputStream(file);
    }

    /**
     * {@inheritDoc}
     */
    public void set(Artifact artifact, InputStream content) throws IOException {
        throw new UnsupportedOperationException("Read-only store");
    }

    /**
     * {@inheritDoc}
     */
    public Metadata getMetadata(String path) throws IOException, MetadataNotFoundException {
        File file = root;
        String[] parts = StringUtils.strip(path, "/").split("/");
        for (int i = 0; i < parts.length; i++) {
            file = new File(file, parts[i]);
        }
        file = new File(file, "maven-metadata.xml");
        if (!file.isFile()) {
            throw new MetadataNotFoundException(path);
        }
        MetadataXpp3Reader reader = new MetadataXpp3Reader();
        InputStream inputStream = null;
        try {
            inputStream = new FileInputStream(file);
            return reader.read(inputStream);
        } catch (XmlPullParserException e) {
            IOException ioe = new IOException(e.getMessage());
            ioe.initCause(e);
            throw ioe;
        } finally {
            IOUtils.closeQuietly(inputStream);
        }
    }

    /**
     * {@inheritDoc}
     */
    public long getMetadataLastModified(String path) throws IOException, MetadataNotFoundException {
        File file = root;
        String[] parts = StringUtils.strip(path, "/").split("/");
        Stack<File> stack = new Stack<File>();
        for (int i = 0; i < parts.length; i++) {
            if ("..".equals(parts[i])) {
                if (!stack.isEmpty()) {
                    file = (File) stack.pop();
                } else {
                    file = root;
                }
            } else if (!".".equals(parts[i])) {
                file = new File(file, parts[i]);
                stack.push(file);
            }
        }
        file = new File(file, "maven-metadata.xml");
        if (!file.isFile()) {
            throw new MetadataNotFoundException(path);
        }
        return file.lastModified();
    }

}