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

Java tutorial

Introduction

Here is the source code for org.codehaus.mojo.mrm.impl.maven.ArtifactStoreFileSystem.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.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.GregorianCalendar;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.TimeZone;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;
import org.codehaus.mojo.mrm.api.BaseFileSystem;
import org.codehaus.mojo.mrm.api.DefaultDirectoryEntry;
import org.codehaus.mojo.mrm.api.DirectoryEntry;
import org.codehaus.mojo.mrm.api.Entry;
import org.codehaus.mojo.mrm.api.maven.Artifact;
import org.codehaus.mojo.mrm.api.maven.ArtifactNotFoundException;
import org.codehaus.mojo.mrm.api.maven.ArtifactStore;
import org.codehaus.mojo.mrm.api.maven.MetadataNotFoundException;

/**
 * A {@link org.codehaus.mojo.mrm.api.FileSystem} that delegates to a {@link ArtifactStore}.
 *
 * @see FileSystemArtifactStore for the oposite.
 * @since 1.0
 */
public class ArtifactStoreFileSystem extends BaseFileSystem {

    /**
     * Regex to match the groupId portion of a path.
     *
     * @since 1.0
     */
    private static final String GROUP_ID_PATH_REGEX = "/((?:[^/]+/)+)";

    /**
     * Regex to match the artifactId portion of a path.
     *
     * @since 1.0
     */
    private static final String ARTIFACT_ID_PATH_REGEX = "([^/]+)/";

    /**
     * Regex to match the version portion of a path.
     *
     * @since 1.0
     */
    private static final String VERSION_REGEX = "([^/]+)/";

    /**
     * Regex to match the version portion of a path if the version is a <code>-SNAPSHOT</code>.
     *
     * @since 1.0
     */
    private static final String SNAPSHOT_VERSION_REGEX = "([^/]+)-SNAPSHOT/";

    /**
     * Regex to match a metadata path.
     *
     * @since 1.0
     */
    /*package*/ static final Pattern METADATA = Pattern.compile(GROUP_ID_PATH_REGEX + "(maven-metadata\\.xml)");

    /**
     * Regex to match a release artifact path.
     *
     * @since 1.0
     */
    /*package*/ static final Pattern ARTIFACT = Pattern
            .compile(GROUP_ID_PATH_REGEX + ARTIFACT_ID_PATH_REGEX + VERSION_REGEX + "(\\2-\\3(-[^.]+)?\\.([^/]*))");

    /**
     * Regex to match a snapshot artifact path.
     *
     * @since 1.0
     */
    /*package*/ static final Pattern SNAPSHOT_ARTIFACT = Pattern
            .compile(GROUP_ID_PATH_REGEX + ARTIFACT_ID_PATH_REGEX + SNAPSHOT_VERSION_REGEX
                    + "(\\2-(?:\\3-(?:SNAPSHOT|\\d{8}\\.\\d{6}-\\d+))(-[^.]+)?\\.([^/]*))");

    /**
     * The backing {@link ArtifactStore}.
     *
     * @since 1.0
     */
    private final ArtifactStore store;

    /**
     * Creates a {@link org.codehaus.mojo.mrm.api.FileSystem} backed by an {@link ArtifactStore}.
     *
     * @param store the backing artifact store.
     * @since 1.0
     */
    public ArtifactStoreFileSystem(ArtifactStore store) {
        this.store = store;
    }

    /**
     * {@inheritDoc}
     */
    public Entry[] listEntries(DirectoryEntry directory) {
        if (getRoot().equals(directory)) {
            Set<String> rootGroupIds = new TreeSet<String>(store.getGroupIds(""));
            Entry[] result = new Entry[rootGroupIds.size()];
            int index = 0;
            for (String name : rootGroupIds) {
                result[index++] = new DefaultDirectoryEntry(this, getRoot(), name);
            }
            return result;
        }
        List<Entry> result = new ArrayList<Entry>();
        Set<String> names = new HashSet<String>();
        String path = directory.toPath().substring(1); // skip initial '/'

        try {
            store.getMetadataLastModified(path);
            MetadataFileEntry entry = new MetadataFileEntry(this, directory, path, store);
            if (!names.contains(entry.getName())) {
                result.add(entry);
                names.add(entry.getName());
            }
        } catch (MetadataNotFoundException e) {
            // ignore
        } catch (IOException e) {
            // ignore
        }

        String groupId = path.replace('/', '.');

        // get all the groupId's that start with this groupId
        String groupIdPrefix = groupId + ".";
        Set<String> groupIds = new TreeSet<String>(store.getGroupIds(groupId));
        for (String name : groupIds) {
            if (!names.contains(name)) {
                result.add(new DefaultDirectoryEntry(this, directory, name));
                names.add(name);
            }
        }

        // get all the artifactIds that belong to this groupId
        for (String name : store.getArtifactIds(groupId)) {
            if (!names.contains(name)) {
                result.add(new DefaultDirectoryEntry(this, directory, name));
                names.add(name);
            }
        }

        DirectoryEntry parent = directory.getParent();
        if (parent != null && !getRoot().equals(parent)) {
            // get all the versions that belong to the groupId/artifactId path
            groupId = parent.toPath().substring(1).replace('/', '.');
            String artifactId = directory.getName();
            for (String name : store.getVersions(groupId, artifactId)) {
                if (!names.contains(name)) {
                    result.add(new DefaultDirectoryEntry(this, directory, name));
                    names.add(name);
                }
            }
            DirectoryEntry grandParent = parent.getParent();
            if (grandParent != null && !getRoot().equals(grandParent)) {
                // get all the versions that belong to the groupId/artifactId path
                groupId = grandParent.toPath().substring(1).replace('/', '.');
                artifactId = parent.getName();
                String version = directory.getName();
                for (Artifact a : store.getArtifacts(groupId, artifactId, version)) {
                    ArtifactFileEntry entry = new ArtifactFileEntry(this, directory, a, store);
                    if (!names.contains(entry.getName())) {
                        result.add(entry);
                        names.add(entry.getName());
                    }
                }
            }
        }

        // sort
        Collections.sort(result, new Comparator<Entry>() {
            public int compare(Entry o1, Entry o2) {
                return (o1).getName().compareTo((o2).getName());
            }
        });
        return result.toArray(new Entry[result.size()]);
    }

    /**
     * {@inheritDoc}
     */
    protected Entry get(DirectoryEntry parent, String name) {

        String path = parent.toPath() + "/" + name;

        if ("favicon.ico".equals(name)) {
            return null;
        }
        if (METADATA.matcher(path).matches()) {
            MetadataFileEntry entry = new MetadataFileEntry(this, parent, parent.toPath(), store);
            try {
                entry.getLastModified();
                return entry;
            } catch (IOException e) {
                return null;
            }
        } else {
            Matcher snapshotArtifact = SNAPSHOT_ARTIFACT.matcher(path);
            if (snapshotArtifact.matches()) {
                String groupId = StringUtils.stripEnd(snapshotArtifact.group(1), "/").replace('/', '.');
                String artifactId = snapshotArtifact.group(2);
                String version = snapshotArtifact.group(3) + "-SNAPSHOT";
                Pattern 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+)))(?:-([^.]+))?\\.([^/]*)");
                Matcher matcher = rule.matcher(name);
                if (!matcher.matches()) {
                    String classifier = snapshotArtifact.group(5);
                    String type = snapshotArtifact.group(6);
                    if (classifier != null) {
                        classifier = classifier.substring(1);
                    }
                    if (StringUtils.isEmpty(classifier)) {
                        classifier = null;
                    }
                    return new ArtifactFileEntry(this, parent,
                            new Artifact(groupId, artifactId, version, classifier, type), store);
                }
                if (matcher.group(1).equals("SNAPSHOT")) {
                    Artifact artifact = new Artifact(groupId, artifactId, version, matcher.group(9),
                            matcher.group(10));
                    try {
                        store.get(artifact);
                        return new ArtifactFileEntry(this, parent, artifact, store);
                    } catch (IOException e) {
                        return null;
                    } catch (ArtifactNotFoundException e) {
                        return null;
                    }
                }
                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));

                    Artifact artifact = new Artifact(groupId, artifactId, version, matcher.group(9),
                            matcher.group(10), timestamp, buildNumber);
                    try {
                        store.get(artifact);
                        return new ArtifactFileEntry(this, parent, artifact, store);
                    } catch (IOException e) {
                        return null;
                    } catch (ArtifactNotFoundException e) {
                        return null;
                    }
                } catch (NullPointerException e) {
                    return new DefaultDirectoryEntry(this, parent, name);
                }
            } else {
                Matcher matcher = ARTIFACT.matcher(path);
                if (matcher.matches()) {
                    String groupId = StringUtils.stripEnd(matcher.group(1), "/").replace('/', '.');
                    String artifactId = matcher.group(2);
                    String version = matcher.group(3);
                    String classifier = matcher.group(5);
                    String type = matcher.group(6);
                    if (classifier != null) {
                        classifier = classifier.substring(1);
                    }
                    if (StringUtils.isEmpty(classifier)) {
                        classifier = null;
                    }

                    Artifact artifact = new Artifact(groupId, artifactId, version, classifier, type);
                    try {
                        store.get(artifact);
                        return new ArtifactFileEntry(this, parent, artifact, store);
                    } catch (ArtifactNotFoundException e) {
                        return null;
                    } catch (IOException e) {
                        return null;
                    }
                } else {
                    return new DefaultDirectoryEntry(this, parent, name);
                }
            }
        }
    }

    /**
     * {@inheritDoc}
     */
    public long getLastModified(DirectoryEntry entry) throws IOException {
        return System.currentTimeMillis();
    }

}