
net.ossindex.maven.utils.DependencyAuditor Maven / Gradle / Ivy
/**
* Copyright (c) 2015 Vör Security Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.ossindex.maven.utils;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import net.ossindex.common.ResourceFactory;
import net.ossindex.common.cache.MapDbCache;
import net.ossindex.common.resource.ArtifactResource;
import net.ossindex.common.resource.ScmResource;
import net.ossindex.common.utils.PackageDependency;
import org.apache.commons.lang3.ArrayUtils;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.collection.CollectRequest;
import org.eclipse.aether.collection.DependencyCollectionException;
import org.eclipse.aether.graph.Dependency;
import org.eclipse.aether.graph.DependencyNode;
import org.eclipse.aether.resolution.DependencyRequest;
import org.eclipse.aether.resolution.DependencyResolutionException;
import org.eclipse.aether.util.graph.visitor.PreorderNodeListGenerator;
/** Utility code that performs the Maven dependency auditing. Written in a manner
* that will allow it to be used within Maven plugins as well as outside.
*
* @author Ken Duck
*
*/
public class DependencyAuditor
{
private RepositorySystem repoSystem;
private RepositorySystemSession session;
/**
* Testing constructor only
*/
DependencyAuditor()
{
File root = getCacheDir();
if(root != null)
{
ResourceFactory.getResourceFactory().setCache(new MapDbCache(getCacheDir()));
}
}
/** Make a new dependency auditor
*
* @param repoSystem Maven repository system
* @param session Maven repository system session
*/
public DependencyAuditor(RepositorySystem repoSystem, RepositorySystemSession session)
{
File root = getCacheDir();
if(root != null)
{
ResourceFactory.getResourceFactory().setCache(new MapDbCache(getCacheDir()));
}
this.repoSystem = repoSystem;
this.session = session;
}
/** Get a cache directory
*
* @return The cache directory
*/
private File getCacheDir()
{
File tmp = new File(System.getProperty("java.io.tmpdir"));
File root = new File(tmp, "ossindex.cache");
if(tmp.exists())
{
if(!root.exists()) root.mkdirs();
if(root.exists() && root.isDirectory()) return root;
}
return null;
}
/** Audit the artifact and its dependencies
*
* @param groupId Artifact group ID
* @param artifactId Artifact OD
* @param version Version number
* @throws IOException On error
* @return Collection of dependencies
*/
public Collection auditArtifact(String groupId, String artifactId, String version) throws IOException
{
List deps = getPackageDependencies(groupId, artifactId, version);
setDependencyInformation(deps.toArray(new PackageDependency[deps.size()]));
return deps;
}
/** Find all of the dependencies for a specified artifact
*
* @param groupId Artifact group ID
* @param artifactId Artifact OD
* @param version Version number
* @return List of package dependencies
*/
private List getPackageDependencies(String groupId, String artifactId, String version)
{
List packageDependency = new LinkedList();
String aid = groupId + ":" + artifactId + ":";
if(version != null) aid += version;
Dependency dependency = new Dependency( new DefaultArtifact( aid ), "compile" );
CollectRequest collectRequest = new CollectRequest();
collectRequest.setRoot( dependency );
try
{
DependencyNode node = repoSystem.collectDependencies( session, collectRequest ).getRoot();
DependencyRequest dependencyRequest = new DependencyRequest();
dependencyRequest.setRoot( node );
repoSystem.resolveDependencies( session, dependencyRequest );
PreorderNodeListGenerator nlg = new PreorderNodeListGenerator();
node.accept( nlg );
List artifacts = nlg.getArtifacts(false);
for (Artifact artifact : artifacts)
{
PackageDependency pkgDep = new PackageDependency("maven", artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion());
packageDependency.add(pkgDep);
}
}
catch(DependencyCollectionException | DependencyResolutionException e)
{
// Ignore so we don't pollute Maven
//e.printStackTrace();
}
return packageDependency;
}
/** Query OSS Index to get useful information about the dependencies. Sets the
* information in the appropriate package dependency.
*
* Package protected to allow us to test
*
* @param pkgs Packages to retrieve additional information from OSS Index for
* @throws IOException On error
*/
void setDependencyInformation(PackageDependency[] pkgs) throws IOException
{
// AbstractRemoteResource.setDebug(true);
ArtifactResource[] artifactMatches = ResourceFactory.getResourceFactory().findArtifactResources(pkgs);
Map matches = new HashMap();
for (ArtifactResource artifact : artifactMatches)
{
if(artifact != null)
{
String name = artifact.getPackageName();
// System.err.println(" * " + name);
if(!matches.containsKey(name))
{
matches.put(name, artifact);
}
else
{
ArtifactResource ar = matches.get(name);
if(artifact.compareTo(ar) > 0) matches.put(name, artifact);
}
}
}
List packages = new LinkedList();
List scmIds = new LinkedList();
for(PackageDependency pkg: pkgs)
{
String pkgName = pkg.getName();
if(matches.containsKey(pkgName))
{
ArtifactResource artifact = matches.get(pkg.getName());
long scmId = artifact.getScmId();
// only continue with the artifact if it has a known SCM id.
if(scmId > 0)
{
pkg.setArtifact(artifact);
packages.add(pkg);
scmIds.add(artifact.getScmId());
}
}
else
{
//System.err.println("ZOUNDS: " + pkgName + " has no matching artifact");
}
}
Long[] tmp = scmIds.toArray(new Long[scmIds.size()]);
ScmResource[] scmResources = ResourceFactory.getResourceFactory().findScmResources(ArrayUtils.toPrimitive(tmp));
// This should never happen
if(scmResources == null) return;
for(int i = 0; i < packages.size(); i++)
{
PackageDependency pkg = packages.get(i);
pkg.setScm(scmResources[i]);
if(!pkg.equals(pkgs[0]))
{
pkg.setParent(pkgs[0]);
}
}
}
/**
* Close the cache, required for clean running
*/
public void close()
{
ResourceFactory.getResourceFactory().closeCache();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy