Package org.apache.marmotta.maven.plugins.repochecker

Source Code of org.apache.marmotta.maven.plugins.repochecker.RepositoryCheckerMojo

/**
* 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.marmotta.maven.plugins.repochecker;

import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.PoolingClientConnectionManager;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;
import org.apache.maven.shared.dependency.graph.DependencyGraphBuilder;
import org.apache.maven.shared.dependency.graph.DependencyGraphBuilderException;
import org.apache.maven.shared.dependency.graph.DependencyNode;
import org.codehaus.plexus.util.StringUtils;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;

@Mojo(name = "matrix", requiresDependencyResolution = ResolutionScope.TEST, threadSafe = true)
public class RepositoryCheckerMojo extends AbstractMojo {

  private static final String META_XML = "maven-metadata.xml";

  public enum Result {
    FOUND, NOT_FOUND, IGNORED, ERROR
  }

  /**
   * The Maven project.
   */
  @Component
  private MavenProject project;

  /**
   * The dependency tree builder to use.
   */
  @Component(hint = "default")
  private DependencyGraphBuilder dependencyGraphBuilder;

  @Parameter(property = "repositories")
  private String[] repositories;

  @Parameter(property = "checkSnapshots", defaultValue = "true")
  private boolean checkSnapshots;

  @Parameter(property = "depth", defaultValue = "1")
  private int depth;

  @Parameter(property = "breakOnMissing", defaultValue = "false")
  private boolean breakOnMissing;

  @Parameter(property = "silent", defaultValue = "false")
  private boolean silent;

  private final ResponseHandler<Boolean> fileExistsHandler;

  public RepositoryCheckerMojo() {
    fileExistsHandler = new ResponseHandler<Boolean>() {
      public Boolean handleResponse(HttpResponse response)
          throws ClientProtocolException, IOException {
        return response.getStatusLine().getStatusCode() < 300;
      }
    };
  }

  public void execute() throws MojoExecutionException, MojoFailureException {
    ClientConnectionManager manager = new PoolingClientConnectionManager();
    final DefaultHttpClient client = new DefaultHttpClient(manager);

    final MatrixPrinter printer;
    if (silent) {
      printer = new SilentMatrixPrinter();
    } else
      printer = new LogMatrixPrinter(getLog(), 1);

    try {
      final Log log = getLog();
      final List<ArtifactRepository> reps;
      if (repositories != null && repositories.length > 0) {
        @SuppressWarnings("unchecked")
        final LinkedList<ArtifactRepository> _tmp = new LinkedList<ArtifactRepository>(
            project.getRemoteArtifactRepositories());
        reps = new LinkedList<ArtifactRepository>();

        for (String rid : repositories) {
          ArtifactRepository r = null;
          for (ArtifactRepository ar : _tmp) {
            if (rid.equals(ar.getId())) {
              r = ar;
              break;
            }
          }
          if (r != null)
            reps.add(r);
          else
            log.warn("Could not find artifact repository '" + rid
                + "'");
        }

        if (reps.size() == 0) {
          log.warn("No artifact repositories provided, skipping.");
          return;
        }
      } else {
        @SuppressWarnings("unchecked")
        final LinkedList<ArtifactRepository> _tmp = new LinkedList<ArtifactRepository>(
            project.getRemoteArtifactRepositories());
        reps = _tmp;
      }

      printer.printHeader(reps);

      final DependencyNode rootNode = dependencyGraphBuilder
          .buildDependencyGraph(project, null);
      Set<Artifact> missingArtifacts = checkDepNode(rootNode, reps, 0, client, printer);

      printer.printFooter(reps);
     
      if (missingArtifacts.size() > 0) {
        log.warn("unresolved dependencies:");
        for (Artifact missing : missingArtifacts) {
          log.warn("  " + missing.getId());
        }
      }
    } catch (DependencyGraphBuilderException e) {
      throw new MojoExecutionException(
          "Cannot build project dependency graph", e);
    } finally {
      client.getConnectionManager().shutdown();
    }
  }

  private Set<Artifact> checkDepNode(final DependencyNode rootNode,
      final List<ArtifactRepository> repositories, final int level,
      DefaultHttpClient client, MatrixPrinter printer)
      throws MojoFailureException {
    if (!(level < depth))
      return Collections.emptySet();

    HashSet<Artifact> missingArts = new HashSet<Artifact>();
    for (DependencyNode dep : rootNode.getChildren()) {
      Artifact artifact = dep.getArtifact();

      if (!checkSnapshots && artifact.isSnapshot()) {
        printer.printResult(artifact, level, Collections.nCopies(repositories.size(), Result.IGNORED));
      } else {
        final LinkedList<Result> results = new LinkedList<RepositoryCheckerMojo.Result>();
        for (ArtifactRepository repo : repositories) {
          Result result = lookupArtifact(artifact, repo, client);
          results.add(result);
        }

        if (!results.contains(Result.FOUND)) {
          missingArts.add(artifact);
          if (breakOnMissing) {
            throw new MojoFailureException(
                String.format(
                    "did not find artifact %s in any of the available repositories",
                    artifact.getId()));
          }
        }

        printer.printResult(artifact, level, results);
        missingArts.addAll(checkDepNode(dep, repositories, level + 1, client, printer));
      }
    }
   
    return missingArts;
  }

  private Result lookupArtifact(Artifact artifact, ArtifactRepository rep,
      DefaultHttpClient client) {

    if (artifact.isSnapshot() && !rep.getSnapshots().isEnabled()) {
      return Result.NOT_FOUND;
    }
    if (artifact.isRelease() && !rep.getReleases().isEnabled()) {
      return Result.NOT_FOUND;
    }

    try {
      final String baseUrl = rep.getUrl().replaceAll("/$", "") + "/";

      if (client.execute(new HttpHead(baseUrl + buildRelUrl(artifact)),
          fileExistsHandler)) {
        return Result.FOUND;
      }
      if (artifact.isSnapshot()) {
        // now check for a timestamp version
        final String fName = client.execute(new HttpGet(baseUrl
            + buildArtifactDir(artifact) + META_XML),
            createTimestampHandler(artifact));
        if (fName != null
            && client.execute(new HttpHead(baseUrl
                + buildArtifactDir(artifact) + fName),
                fileExistsHandler)) {
          return Result.FOUND;
        } else {
          return Result.NOT_FOUND;
        }
      } else {
        return Result.NOT_FOUND;
      }
    } catch (IOException e) {
      return Result.ERROR;
    }
  }

  private ResponseHandler<String> createTimestampHandler(
      final Artifact artifact) {
    return new ResponseHandler<String>() {

      public String handleResponse(HttpResponse response)
          throws ClientProtocolException, IOException {
        if (response.getStatusLine().getStatusCode() >= 300) {
          return null;
        }
        if (response.getEntity() == null)
          return null;
        InputStream content = response.getEntity().getContent();
        if (content == null)
          return null;

        try {
          Document doc = new SAXBuilder().build(content);

          Element meta = doc.getRootElement();
          if (!"metadata".equals(meta.getName()))
            throw new IOException();
          Element vers = meta.getChild("versioning");
          if (vers == null)
            throw new IOException();
          Element sVers = vers.getChild("snapshotVersions");
          if (sVers == null)
            throw new IOException();

          for (Element sv : sVers.getChildren("snapshotVersion")) {
            // if there is a classifier, check if it's the right one
            if (artifact.hasClassifier()) {
              if (!artifact.getClassifier().equals(
                  sv.getChildText("classifier"))) {
                continue;
              }
            }
            if (!artifact.getType().equals(
                sv.getChildText("extension"))) {
              continue;
            }

            // If we reach this, then it's the right snapshotVersion
            StringBuilder sb = new StringBuilder(
                artifact.getArtifactId());
            sb.append("-").append(sv.getChildText("value"));
            if (artifact.hasClassifier())
              sb.append("-")
                  .append(sv.getChildText("classifier"));
            sb.append(".").append(sv.getChildText("extension"));

            return sb.toString();
          }
          return null;
        } catch (JDOMException e) {
          throw new IOException(e);
        }
      }
    };
  }

  private String buildRelUrl(Artifact artifact) {
    StringBuilder sb = new StringBuilder(buildArtifactDir(artifact));
    sb.append(buildArtifactFileName(artifact));
    return sb.toString();
  }

  private String buildArtifactFileName(Artifact artifact) {
    StringBuilder sb = new StringBuilder();

    sb.append(artifact.getArtifactId());
    sb.append("-").append(artifact.getVersion());

    if (!StringUtils.isBlank(artifact.getClassifier()))
      sb.append("-").append(artifact.getClassifier());

    sb.append(".").append(artifact.getType());

    return sb.toString();
  }

  private String buildArtifactDir(Artifact artifact) {
    StringBuilder sb = new StringBuilder(artifact.getGroupId().replaceAll(
        "\\.", "/"));

    sb.append("/").append(artifact.getArtifactId());
    sb.append("/").append(artifact.getVersion());
    sb.append("/");

    return sb.toString();
  }

}
TOP

Related Classes of org.apache.marmotta.maven.plugins.repochecker.RepositoryCheckerMojo

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.