You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@marmotta.apache.org by ja...@apache.org on 2013/02/26 15:32:17 UTC

[1/3] MARMOTTA-107: renamed packages in maven-plugins MARMOTTA-112: created maven plugin to lookup artifacts in known repositories

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/57f1c085/build/plugins/refpack-maven-plugin/src/main/java/org/apache/marmotta/maven/plugins/refpack/RefPackMojo.java
----------------------------------------------------------------------
diff --git a/build/plugins/refpack-maven-plugin/src/main/java/org/apache/marmotta/maven/plugins/refpack/RefPackMojo.java b/build/plugins/refpack-maven-plugin/src/main/java/org/apache/marmotta/maven/plugins/refpack/RefPackMojo.java
new file mode 100644
index 0000000..3864c27
--- /dev/null
+++ b/build/plugins/refpack-maven-plugin/src/main/java/org/apache/marmotta/maven/plugins/refpack/RefPackMojo.java
@@ -0,0 +1,379 @@
+/**
+ * Copyright (C) 2013 The Apache Software Foundation.
+ *
+ * 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.apache.marmotta.maven.plugins.refpack;
+
+import org.apache.maven.artifact.factory.ArtifactFactory;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.building.ModelBuildingRequest;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.project.DefaultProjectBuildingRequest;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.ProjectBuilder;
+import org.apache.maven.project.ProjectBuildingException;
+import org.apache.maven.project.ProjectBuildingResult;
+import org.jdom2.Element;
+import org.jdom2.output.Format;
+import org.jdom2.output.XMLOutputter;
+import org.sonatype.aether.RepositorySystem;
+import org.sonatype.aether.RepositorySystemSession;
+import org.sonatype.aether.artifact.Artifact;
+import org.sonatype.aether.collection.CollectRequest;
+import org.sonatype.aether.collection.DependencyCollectionException;
+import org.sonatype.aether.graph.Dependency;
+import org.sonatype.aether.graph.DependencyNode;
+import org.sonatype.aether.repository.RemoteRepository;
+import org.sonatype.aether.resolution.DependencyRequest;
+import org.sonatype.aether.resolution.DependencyResolutionException;
+import org.sonatype.aether.resolution.DependencyResult;
+import org.sonatype.aether.util.artifact.DefaultArtifact;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Goal which touches a timestamp file.
+ *
+ * @requiresDependencyResolution compile
+ * @goal generate
+ *
+ * @phase validate
+ */
+public class RefPackMojo extends AbstractMojo {
+    
+    /**
+     * Location of the file.
+     * @parameter expression="${project.build.directory}"
+     * @required
+     */
+    private File outputDirectory;
+
+    /**
+     * @parameter default-value="${project}"
+     * @required
+     * @readonly
+     */
+    private MavenProject project;
+
+    /**
+     * The Group Identifier of the artifacts that should be considered local modules. When walking
+     * the dependency tree, the process will break at each module of this group id and instead add
+     * a dependency to the other module to the refpacks.
+     *
+     * @parameter expression="${refpack.moduleGroupId}" default-value="at.newmedialab.lmf"
+     * @required
+     * @readonly
+     */
+    private String moduleGroupId;
+
+    /**
+     * The entry point to Aether, i.e. the component doing all the work.
+     *
+     * @component
+     */
+    private RepositorySystem repoSystem;
+
+    /**
+     * @parameter default-value="${repositorySystemSession}"
+     * @readonly
+     */
+    private RepositorySystemSession session;
+
+    /**
+     * The project's remote repositories to use for the resolution of project dependencies.
+     *
+     * @parameter default-value="${project.remoteProjectRepositories}"
+     * @readonly
+     */
+    private List<RemoteRepository> projectRepos;
+
+    /**
+     * @component
+     */
+    private ProjectBuilder projectBuilder;
+
+
+    /**
+     * @component
+     */
+    private ArtifactFactory artifactFactory;
+
+    /**
+     * The required modules of the refpack
+     *
+     * @parameter expression="${refpack.requiredModules}"
+     * @readonly
+     */
+    private List<String> requiredModules;
+
+    // we collect here the library dependencies of each module, so we can identify which of the dependencies are already
+    // covered by another module the current module depends on
+    private HashMap<Artifact,Set<Artifact>> moduleLibraries;
+
+    // and here we collect the module dependencies of each module
+    private HashMap<Artifact,Set<Artifact>> moduleDependencies;
+
+    public void execute() throws MojoExecutionException {
+        moduleLibraries = new HashMap<Artifact, Set<Artifact>>();
+        moduleDependencies = new HashMap<Artifact, Set<Artifact>>();
+
+        getLog().info("generating reference packs for group id "+moduleGroupId);
+
+        for(org.apache.maven.artifact.Artifact artifact : (Set<org.apache.maven.artifact.Artifact>)project.getArtifacts()) {
+            if(artifact.getGroupId().equals(moduleGroupId)) {
+
+                DefaultArtifact aetherArtifact = new DefaultArtifact(artifact.getGroupId(),artifact.getArtifactId(), artifact.getType(), artifact.getVersion());
+                Dependency rootDependency = new Dependency(aetherArtifact, "runtime");
+
+                try {
+                    CollectRequest collectRequest = new CollectRequest();
+                    collectRequest.setRoot(rootDependency);
+                    collectRequest.setRepositories(projectRepos);
+
+                    DependencyNode rootNode = repoSystem.collectDependencies( session, collectRequest ).getRoot();
+
+                    DependencyRequest request = new DependencyRequest(rootNode,null);
+                    DependencyResult result = repoSystem.resolveDependencies(session,request);
+
+
+                    getLog().info("Artifact: " + aetherArtifact);
+                    for(DependencyNode child : result.getRoot().getChildren()) {
+                        if(child.getDependency().getArtifact().getGroupId().equals(moduleGroupId)) {
+                            processModule(child);
+                        }
+                    }
+                    processModule(result.getRoot());
+                    /*
+                    deps = aether.resolve(aetherArtifact, JavaScopes.RUNTIME);
+
+                    getLog().info("Artifact: "+aetherArtifact);
+                    for(Artifact dep : deps) {
+                        getLog().info("- dependency "+dep.getFile().getAbsolutePath());
+                    }
+                    */
+                } catch (DependencyResolutionException e) {
+                    getLog().warn("could not resolve dependencies for artifact "+aetherArtifact,e);
+                } catch (DependencyCollectionException e) {
+                    getLog().warn("could not resolve dependencies for artifact "+aetherArtifact,e);
+                }
+            }
+
+        }
+
+    }
+
+    /**
+     * Collect the dependencies to other libraries that are not already collected by modules the current
+     * module depends on.
+     *
+     * @param node
+     * @param currentModule
+     */
+    private void collectLibraryDependencies(DependencyNode node, Artifact currentModule) {
+
+        if(!node.getDependency().getArtifact().getGroupId().equals(moduleGroupId) || !node.getDependency().getArtifact().getArtifactId().startsWith("lmf-")) {
+            // first check if the current artifact is already covered by a module the current module depends on
+            for(Artifact dependentArtifact : moduleDependencies.get(currentModule)) {
+                if(moduleLibraries.containsKey(dependentArtifact) &&
+                        moduleLibraries.get(dependentArtifact).contains(node.getDependency().getArtifact())) {
+                    return;
+                }
+            }
+
+            // collect the current dependency for the module
+            moduleLibraries.get(currentModule).add(node.getDependency().getArtifact());
+
+            for(DependencyNode child : node.getChildren()) {
+                collectLibraryDependencies(child, currentModule);
+            }
+        }
+    }
+
+    /**
+     * Collect the dependencies to other modules inside the same project
+     * @param node
+     * @param currentModule
+     */
+    private void collectModuleDependencies(DependencyNode node, Artifact currentModule) {
+        if(node.getDependency().getArtifact().getGroupId().equals(moduleGroupId) && node.getDependency().getArtifact().getArtifactId().startsWith("lmf-")) {
+            moduleDependencies.get(currentModule).add(node.getDependency().getArtifact());
+        }
+    }
+
+    private void processModule(DependencyNode moduleNode) {
+        CollectRequest collectRequest = new CollectRequest();
+        collectRequest.setRoot(moduleNode.getDependency());
+        collectRequest.setRepositories(projectRepos);
+        try {
+            // collect all the dependency graph for the module, and print it until we reach a dependency to a local module
+            DependencyNode rootNode = repoSystem.collectDependencies( session, collectRequest ).getRoot();
+
+            DependencyRequest request = new DependencyRequest(rootNode,null);
+            DependencyResult result = repoSystem.resolveDependencies(session,request);
+
+            // add entry to module dependencies
+            moduleLibraries.put(moduleNode.getDependency().getArtifact(), new HashSet<Artifact>());
+            moduleDependencies.put(moduleNode.getDependency().getArtifact(), new HashSet<Artifact>());
+
+            getLog().info("processing module "+moduleNode.getDependency().getArtifact().getArtifactId()+":");
+            for(DependencyNode child : result.getRoot().getChildren()) {
+                collectModuleDependencies(child,moduleNode.getDependency().getArtifact());
+            }
+            for(DependencyNode child : result.getRoot().getChildren()) {
+                collectLibraryDependencies(child, moduleNode.getDependency().getArtifact());
+            }
+
+            // information output
+            /*
+            for(Artifact otherModule : moduleDependencies.get(moduleNode.getDependency().getArtifact())) {
+                getLog().info(" - depending on module "+otherModule.getArtifactId());
+            }
+            for(Artifact library : moduleLibraries.get(moduleNode.getDependency().getArtifact())) {
+                getLog().info(" - depending on library "+library);
+            }
+            */
+
+            File destination = new File(outputDirectory,moduleNode.getDependency().getArtifact().getArtifactId()+".xml");
+
+            getLog().info("writing refpack to "+destination.getAbsolutePath());
+
+            // write to output directory
+            writeModuleXML(moduleNode.getDependency().getArtifact(), new FileOutputStream(destination));
+
+        } catch (DependencyCollectionException e) {
+            getLog().error("error while collecting dependencies for module "+moduleNode.getDependency().getArtifact(),e);
+        } catch (DependencyResolutionException e) {
+            getLog().error("error while resolving dependencies for module "+moduleNode.getDependency().getArtifact(),e);
+        } catch (IOException e) {
+            getLog().error("I/O error while writing refpack for module"+moduleNode.getDependency().getArtifact(),e);
+        }
+
+    }
+
+    private void writeModuleXML(Artifact module, OutputStream out) throws IOException {
+        Element installation = new Element("installation");
+        installation.setAttribute("version","1.0");
+
+        Element packs = new Element("packs");
+        installation.addContent(packs);
+
+        Element pack = new Element("pack");
+        packs.addContent(pack);
+
+        // get the model for the artifact, we read name and description from it
+
+        Model pom = getArtifactModel(module);
+
+        // set name of pack from artifact
+        if(pom != null && pom.getName() != null) {
+            pack.setAttribute("name",pom.getName());
+        } else {
+            pack.setAttribute("name",module.getArtifactId());
+        }
+
+        if(pom != null && pom.getDescription() != null) {
+            Element description = new Element("description");
+            description.addContent(pom.getDescription());
+            pack.addContent(description);
+        }
+
+        // add a file entry for the module itself
+        if(!module.getExtension().equals("war")) {
+            Element mainFile = new Element("file");
+            pack.addContent(mainFile);
+            mainFile.setAttribute("src",module.getFile().getAbsolutePath());
+            mainFile.setAttribute("targetdir","$INSTALL_PATH/apache-tomcat-$TOMCAT_VERSION/webapps/LMF/WEB-INF/lib");
+        }
+
+        // add a file entry for each library of the artifact
+        for(Artifact library : moduleLibraries.get(module)) {
+            Element file = new Element("file");
+            pack.addContent(file);
+            file.setAttribute("src",library.getFile().getAbsolutePath());
+            file.setAttribute("targetdir","$INSTALL_PATH/apache-tomcat-$TOMCAT_VERSION/webapps/LMF/WEB-INF/lib");
+        }
+
+        // add a depends name for each module the current one depends on  (in case the project is not the webapp)
+        if(!module.getExtension().equals("war")) {
+            if(requiredModules.contains(module.getArtifactId())) {
+                pack.setAttribute("required","yes");
+            } else {
+                pack.setAttribute("required","no");
+            }
+
+            for(Artifact dependency : moduleDependencies.get(module)) {
+                Element depends = new Element("depends");
+                pack.addContent(depends);
+
+                // get the model for the artifact, we read name and description from it
+                Model pom2 = getArtifactModel(dependency);
+
+                // set name of pack from artifact
+                if(pom2 != null && pom2.getName() != null) {
+                    depends.setAttribute("packname", pom2.getName());
+                } else {
+                    depends.setAttribute("packname",module.getArtifactId());
+                }
+            }
+        } else {
+            pack.setAttribute("required","yes");
+
+            // add webapp directory from installer configuration
+            Element appDir = new Element("fileset");
+            appDir.setAttribute("dir",outputDirectory+"/../webapp/");
+            appDir.setAttribute("targetdir","$INSTALL_PATH/apache-tomcat-$TOMCAT_VERSION/webapps/LMF/");
+            appDir.setAttribute("includes","**");
+
+            pack.addContent(appDir);
+
+            Element logDir = new Element("fileset");
+            logDir.setAttribute("dir",outputDirectory+"/../log/");
+
+            logDir.setAttribute("targetdir","$INSTALL_PATH/apache-tomcat-$TOMCAT_VERSION/logs/");
+            logDir.setAttribute("includes","**");
+
+            pack.addContent(logDir);
+        }
+
+        XMLOutputter writer = new XMLOutputter(Format.getPrettyFormat());
+        writer.output(installation,out);
+
+    }
+
+    private Model getArtifactModel(Artifact artifact) {
+        org.apache.maven.artifact.Artifact mavenArtifact = artifactFactory.createArtifact(artifact.getGroupId(),artifact.getArtifactId(),artifact.getVersion(),"runtime",artifact.getExtension());
+
+        DefaultProjectBuildingRequest req = new DefaultProjectBuildingRequest();
+        req.setRepositorySession(session);
+        req.setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_STRICT);
+
+        try {
+            ProjectBuildingResult res = projectBuilder.build(mavenArtifact, req);
+
+            return res.getProject().getModel();
+        } catch (ProjectBuildingException e) {
+            getLog().warn("error building artifact model for artifact "+artifact,e);
+            return null;
+        }
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/57f1c085/build/plugins/repocheck-maven-plugin/pom.xml
----------------------------------------------------------------------
diff --git a/build/plugins/repocheck-maven-plugin/pom.xml b/build/plugins/repocheck-maven-plugin/pom.xml
new file mode 100644
index 0000000..cf89d94
--- /dev/null
+++ b/build/plugins/repocheck-maven-plugin/pom.xml
@@ -0,0 +1,61 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.marmotta</groupId>
+        <artifactId>plugins-reactor</artifactId>
+        <version>3.0.0-incubating-SNAPSHOT</version>
+        <relativePath>../</relativePath>
+        <!-- <artifactId>maven-plugins</artifactId> <groupId>org.apache.maven.plugins</groupId> 
+            <version>23</version> <relativePath /> -->
+    </parent>
+
+    <artifactId>repocheck-maven-plugin</artifactId>
+    <packaging>maven-plugin</packaging>
+    <name>Repository Plugin</name>
+    <description>Check which repository contains which dependencies </description>
+
+
+
+
+    <dependencies>
+        <dependency>
+            <groupId>org.codehaus.plexus</groupId>
+            <artifactId>plexus-utils</artifactId>
+            <version>3.0.8</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-project</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven.shared</groupId>
+            <artifactId>maven-dependency-tree</artifactId>
+            <version>2.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.jdom</groupId>
+            <artifactId>jdom2</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-logging</groupId>
+            <artifactId>commons-logging</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>            
+            <plugin>
+                <artifactId>maven-plugin-plugin</artifactId>
+                <configuration>
+                    <goalPrefix>repocheck</goalPrefix>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/57f1c085/build/plugins/repocheck-maven-plugin/src/main/java/org/apache/marmotta/maven/plugins/repochecker/LogMatrixPrinter.java
----------------------------------------------------------------------
diff --git a/build/plugins/repocheck-maven-plugin/src/main/java/org/apache/marmotta/maven/plugins/repochecker/LogMatrixPrinter.java b/build/plugins/repocheck-maven-plugin/src/main/java/org/apache/marmotta/maven/plugins/repochecker/LogMatrixPrinter.java
new file mode 100644
index 0000000..cf99dd2
--- /dev/null
+++ b/build/plugins/repocheck-maven-plugin/src/main/java/org/apache/marmotta/maven/plugins/repochecker/LogMatrixPrinter.java
@@ -0,0 +1,70 @@
+package org.apache.marmotta.maven.plugins.repochecker;
+
+import java.util.List;
+
+import org.apache.marmotta.maven.plugins.repochecker.RepositoryCheckerMojo.Result;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.plugin.logging.Log;
+import org.codehaus.plexus.util.StringUtils;
+
+public class LogMatrixPrinter implements MatrixPrinter {
+
+	private char found = '+', notFound = '-', error = 'e', ignored = 'i';
+	private final String sep;
+	private Log log;
+
+	public LogMatrixPrinter(Log logger, int indent) {
+		this.log = logger;
+		sep = StringUtils.repeat(" ", indent);
+	}
+
+	public void printHeader(List<ArtifactRepository> repositories) {
+		log.info("dependencies, and where they are available:");
+
+		final int repCount = repositories.size();
+		for (int i = 0; i < repCount; i++) {
+			final ArtifactRepository rep = repositories.get(i);
+			log.info(String.format("%s%s (%s)",
+					StringUtils.repeat("|" + sep, i), rep.getId(), rep.getUrl()));
+		}
+		log.info(StringUtils.repeat("|" + sep, repCount));
+	}
+
+	public void printResult(Artifact artifact, int level, List<Result> results) {
+
+		StringBuilder sb = new StringBuilder();
+		for (Result result : results) {
+			switch (result) {
+			case FOUND:
+				sb.append(found);
+				break;
+			case NOT_FOUND:
+				sb.append(notFound);
+				break;
+			case IGNORED:
+				sb.append(ignored);
+				break;
+			default:
+				sb.append(error);
+			}
+			sb.append(sep);
+		}
+		sb.append(StringUtils.repeat('|'+sep, level));
+		sb.append(artifact.getId());
+
+		log.info(sb.toString());
+	}
+
+	public void printFooter(List<ArtifactRepository> repositories) {
+		final int repCount = repositories.size();
+
+		log.info(StringUtils.repeat("|" + sep, repCount));
+		for (int i = repCount - 1; i >= 0; i--) {
+			final ArtifactRepository rep = repositories.get(i);
+			log.info(String.format("%s%s (%s)",
+					StringUtils.repeat("|" + sep, i), rep.getId(), rep.getUrl()));
+		}
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/57f1c085/build/plugins/repocheck-maven-plugin/src/main/java/org/apache/marmotta/maven/plugins/repochecker/MatrixPrinter.java
----------------------------------------------------------------------
diff --git a/build/plugins/repocheck-maven-plugin/src/main/java/org/apache/marmotta/maven/plugins/repochecker/MatrixPrinter.java b/build/plugins/repocheck-maven-plugin/src/main/java/org/apache/marmotta/maven/plugins/repochecker/MatrixPrinter.java
new file mode 100644
index 0000000..cf833dd
--- /dev/null
+++ b/build/plugins/repocheck-maven-plugin/src/main/java/org/apache/marmotta/maven/plugins/repochecker/MatrixPrinter.java
@@ -0,0 +1,17 @@
+package org.apache.marmotta.maven.plugins.repochecker;
+
+import java.util.List;
+
+import org.apache.marmotta.maven.plugins.repochecker.RepositoryCheckerMojo.Result;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+
+public interface MatrixPrinter {
+
+	public void printHeader(List<ArtifactRepository> repositories);
+	
+	public void printResult(Artifact artifact, int level, List<Result> results);
+	
+	public void printFooter(List<ArtifactRepository> repositories);
+	
+}

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/57f1c085/build/plugins/repocheck-maven-plugin/src/main/java/org/apache/marmotta/maven/plugins/repochecker/RepositoryCheckerMojo.java
----------------------------------------------------------------------
diff --git a/build/plugins/repocheck-maven-plugin/src/main/java/org/apache/marmotta/maven/plugins/repochecker/RepositoryCheckerMojo.java b/build/plugins/repocheck-maven-plugin/src/main/java/org/apache/marmotta/maven/plugins/repochecker/RepositoryCheckerMojo.java
new file mode 100644
index 0000000..df751a3
--- /dev/null
+++ b/build/plugins/repocheck-maven-plugin/src/main/java/org/apache/marmotta/maven/plugins/repochecker/RepositoryCheckerMojo.java
@@ -0,0 +1,304 @@
+package org.apache.marmotta.maven.plugins.repochecker;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+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);
+			checkDepNode(rootNode, reps, 0, client, printer);
+
+			printer.printFooter(reps);
+		} catch (DependencyGraphBuilderException e) {
+			throw new MojoExecutionException(
+					"Cannot build project dependency graph", e);
+		} finally {
+			client.getConnectionManager().shutdown();
+		}
+	}
+
+	private void checkDepNode(final DependencyNode rootNode,
+			final List<ArtifactRepository> repositories, final int level,
+			DefaultHttpClient client, MatrixPrinter printer)
+			throws MojoFailureException {
+		if (!(level < depth))
+			return;
+
+		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 (breakOnMissing && !results.contains(Result.FOUND))
+					throw new MojoFailureException(
+							String.format(
+									"did not find artifact %s in any of the available repositories",
+									artifact.getId()));
+
+				printer.printResult(artifact, level, results);
+			}
+			checkDepNode(dep, repositories, level + 1, client, printer);
+		}
+	}
+
+	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();
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/57f1c085/build/plugins/repocheck-maven-plugin/src/main/java/org/apache/marmotta/maven/plugins/repochecker/SilentMatrixPrinter.java
----------------------------------------------------------------------
diff --git a/build/plugins/repocheck-maven-plugin/src/main/java/org/apache/marmotta/maven/plugins/repochecker/SilentMatrixPrinter.java b/build/plugins/repocheck-maven-plugin/src/main/java/org/apache/marmotta/maven/plugins/repochecker/SilentMatrixPrinter.java
new file mode 100644
index 0000000..5b55a6e
--- /dev/null
+++ b/build/plugins/repocheck-maven-plugin/src/main/java/org/apache/marmotta/maven/plugins/repochecker/SilentMatrixPrinter.java
@@ -0,0 +1,23 @@
+package org.apache.marmotta.maven.plugins.repochecker;
+
+import java.util.List;
+
+import org.apache.marmotta.maven.plugins.repochecker.RepositoryCheckerMojo.Result;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+
+public class SilentMatrixPrinter implements MatrixPrinter {
+
+	public void printHeader(List<ArtifactRepository> repositories) {
+		// nop;
+	}
+
+	public void printResult(Artifact artifact, int level, List<Result> results) {
+		// nop;
+	}
+
+	public void printFooter(List<ArtifactRepository> repositories) {
+		// nop;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/57f1c085/parent/pom.xml
----------------------------------------------------------------------
diff --git a/parent/pom.xml b/parent/pom.xml
index 7a45f69..681a358 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -1,21 +1,16 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!--
-   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.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+<!-- 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. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 
     <modelVersion>4.0.0</modelVersion>
 
@@ -247,37 +242,37 @@
                                     </action>
                                 </pluginExecution>
                                 <pluginExecution>
-                                	<pluginExecutionFilter>
-                                		<groupId>
-                                			org.apache.felix
-                                		</groupId>
-                                		<artifactId>
-                                			maven-scr-plugin
-                                		</artifactId>
-                                		<versionRange>
-                                			[1.8.0,)
-                                		</versionRange>
-                                		<goals>
-                                			<goal>scr</goal>
-                                		</goals>
-                                	</pluginExecutionFilter>
-                                	<action>
-                                		<ignore></ignore>
-                                	</action>
+                                    <pluginExecutionFilter>
+                                        <groupId>
+                                            org.apache.felix
+                                        </groupId>
+                                        <artifactId>
+                                            maven-scr-plugin
+                                        </artifactId>
+                                        <versionRange>
+                                            [1.8.0,)
+                                        </versionRange>
+                                        <goals>
+                                            <goal>scr</goal>
+                                        </goals>
+                                    </pluginExecutionFilter>
+                                    <action>
+                                        <ignore></ignore>
+                                    </action>
+                                </pluginExecution>
+                                <pluginExecution>
+                                    <pluginExecutionFilter>
+                                        <groupId>org.apache.maven.plugins</groupId>
+                                        <artifactId>maven-remote-resources-plugin</artifactId>
+                                        <versionRange>[1.4,)</versionRange>
+                                        <goals>
+                                            <goal>process</goal>
+                                        </goals>
+                                    </pluginExecutionFilter>
+                                    <action>
+                                        <ignore />
+                                    </action>
                                 </pluginExecution>
-								<pluginExecution>
-									<pluginExecutionFilter>
-										<groupId>org.apache.maven.plugins</groupId>
-										<artifactId>maven-remote-resources-plugin</artifactId>
-										<versionRange>[1.4,)</versionRange>
-										<goals>
-											<goal>process</goal>
-										</goals>
-									</pluginExecutionFilter>
-									<action>
-										<ignore/>
-									</action>
-								</pluginExecution>
                             </pluginExecutions>
                         </lifecycleMappingMetadata>
                     </configuration>
@@ -397,6 +392,39 @@
                     <artifactId>maven-gpg-plugin</artifactId>
                     <version>1.4</version>
                 </plugin>
+                <plugin>
+                    <groupId>org.apache.marmotta</groupId>
+                    <artifactId>repocheck-maven-plugin</artifactId>
+                    <version>${project.version}</version>
+                    <executions>
+                        <execution>
+                            <id>check</id>
+                            <phase>deploy</phase>
+                            <goals>
+                                <goal>matrix</goal>
+                            </goals>
+                            <inherited>true</inherited>
+                            <configuration>
+                                <breakOnMissing>true</breakOnMissing>
+                                <repositories>
+                                    <param>central</param>
+                                    <param>apache.releases</param>
+                                    <param>apache.snapshots</param>
+                                </repositories>
+                            </configuration>
+                        </execution>
+                        <execution>
+                            <id>info</id>
+                            <phase>package</phase>
+                            <goals>
+                                <goal>matrix</goal>
+                            </goals>
+                            <inherited>true</inherited>
+                            <configuration>
+                            </configuration>
+                        </execution>
+                    </executions>
+                </plugin>
             </plugins>
         </pluginManagement>
         <plugins>
@@ -417,17 +445,11 @@
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-javadoc-plugin</artifactId>
                 <executions>
-                    <!--
-                    <execution>
-                        <id>aggregate</id>
-                        <goals>
-                            <goal>aggregate</goal>
-                        </goals>
-                        <phase>site</phase>
-                    </execution>
-                    -->
+                    <!-- <execution> <id>aggregate</id> <goals> <goal>aggregate</goal> 
+                        </goals> <phase>site</phase> </execution> -->
                     <execution>
-                        <!-- configure how the REST API documentation will be produced -->
+                        <!-- configure how the REST API documentation will 
+                            be produced -->
                         <id>restapi</id>
                         <configuration>
                             <doclet>com.lunatech.doclets.jax.jaxrs.JAXRSDoclet</doclet>
@@ -445,12 +467,11 @@
                                 <version>0.10.0</version>
                             </docletArtifact>
                             <additionalparam>
-                                -jaxrscontext {BASE} -charset UTF-8
+                                -jaxrscontext {BASE}
+                                -charset UTF-8
                             </additionalparam>
 
-                            <!--
-                                                        <stylesheetfile>${project.parent.basedir}/config/doc/doclet.css</stylesheetfile>
-                            -->
+                            <!-- <stylesheetfile>${project.parent.basedir}/config/doc/doclet.css</stylesheetfile> -->
 
                             <header><![CDATA[<!--###BEGIN_CONTENT###--><div class="javadoc">]]></header>
                             <footer><![CDATA[</div><!--###END_CONTENT###-->]]></footer>
@@ -467,6 +488,10 @@
                 </executions>
             </plugin>
             <plugin>
+                <groupId>org.apache.marmotta</groupId>
+                <artifactId>repocheck-maven-plugin</artifactId>
+            </plugin>
+            <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-project-info-reports-plugin</artifactId>
             </plugin>
@@ -486,9 +511,7 @@
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-release-plugin</artifactId>
                 <configuration>
-                    <!--
-                      During release:perform, enable the "sign" profile
-                     -->
+                    <!-- During release:perform, enable the "sign" profile -->
                     <releaseProfiles>sign</releaseProfiles>
                 </configuration>
             </plugin>
@@ -515,7 +538,8 @@
                         <id>javaapi</id>
                         <configuration>
                             <name>Java API</name>
-                            <description>Aggregated Java API documentation</description>
+                            <description>Aggregated Java API
+                                documentation</description>
                             <destDir>javaapi</destDir>
                             <encoding>UTF-8</encoding>
                         </configuration>
@@ -526,7 +550,8 @@
 
                     <!-- Create REST API Documentation -->
                     <reportSet>
-                        <!-- configure how the REST API documentation will be produced -->
+                        <!-- configure how the REST API documentation will 
+                            be produced -->
                         <id>restapi</id>
                         <configuration>
                             <doclet>com.lunatech.doclets.jax.jaxrs.JAXRSDoclet</doclet>
@@ -539,7 +564,8 @@
                                 <version>0.10.0</version>
                             </docletArtifact>
                             <additionalparam>
-                                -jaxrscontext /LMF -charset UTF-8
+                                -jaxrscontext /LMF -charset
+                                UTF-8
                             </additionalparam>
                             <encoding>UTF-8</encoding>
                             <detectOfflineLinks>false</detectOfflineLinks>
@@ -1370,42 +1396,42 @@
 
             <!-- LDPath -->
             <dependency>
-               <groupId>org.apache.marmotta</groupId>
+                <groupId>org.apache.marmotta</groupId>
                 <artifactId>ldpath-core</artifactId>
                 <version>${project.version}</version>
             </dependency>
             <dependency>
-               <groupId>org.apache.marmotta</groupId>
+                <groupId>org.apache.marmotta</groupId>
                 <artifactId>ldpath-api</artifactId>
                 <version>${project.version}</version>
             </dependency>
             <dependency>
-               <groupId>org.apache.marmotta</groupId>
+                <groupId>org.apache.marmotta</groupId>
                 <artifactId>ldpath-backend-sesame</artifactId>
                 <version>${project.version}</version>
             </dependency>
             <dependency>
-               <groupId>org.apache.marmotta</groupId>
+                <groupId>org.apache.marmotta</groupId>
                 <artifactId>ldpath-functions-xml</artifactId>
                 <version>${project.version}</version>
             </dependency>
             <dependency>
-               <groupId>org.apache.marmotta</groupId>
+                <groupId>org.apache.marmotta</groupId>
                 <artifactId>ldpath-functions-math</artifactId>
                 <version>${project.version}</version>
             </dependency>
             <dependency>
-               <groupId>org.apache.marmotta</groupId>
+                <groupId>org.apache.marmotta</groupId>
                 <artifactId>ldpath-functions-html</artifactId>
                 <version>${project.version}</version>
             </dependency>
             <dependency>
-               <groupId>org.apache.marmotta</groupId>
+                <groupId>org.apache.marmotta</groupId>
                 <artifactId>ldpath-functions-date</artifactId>
                 <version>${project.version}</version>
             </dependency>
             <dependency>
-               <groupId>org.apache.marmotta</groupId>
+                <groupId>org.apache.marmotta</groupId>
                 <artifactId>ldpath-functions-text</artifactId>
                 <version>${project.version}</version>
             </dependency>