package org.jboss.windup.rules.apps.java.query;
import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.gremlin.java.GremlinPipeline;
import com.tinkerpop.pipes.PipeFunction;
import org.jboss.forge.furnace.util.Lists;
import org.jboss.windup.graph.GraphContext;
import org.jboss.windup.graph.model.FileLocationModel;
import org.jboss.windup.graph.model.resource.FileModel;
import org.jboss.windup.reporting.model.ClassificationModel;
import org.jboss.windup.reporting.model.InlineHintModel;
import org.jboss.windup.rules.apps.java.model.JavaClassFileModel;
import org.jboss.windup.rules.apps.java.model.JavaSourceFileModel;
import org.jboss.windup.util.ExecutionStatistics;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
/**
* This provides a helper class that can be used execute a Gremlin search returning all FileModels that do not have associated
* {@link FileLocationModel}s or @{link ClassificationModel}s.
*
* @author <a href="mailto:jesse.sightler@gmail.com">Jesse Sightler</a>
*/
public class FindFilesNotClassifiedOrHintedGremlinCriterion
{
public Iterable<Vertex> query(final GraphContext context, Iterable<Vertex> initialVertices)
{
ExecutionStatistics.get().begin("FindFilesNotClassifiedOrHintedGremlinCriterion.total");
final List<Vertex> initialVerticesList = Lists.toList(initialVertices);
GremlinPipeline<Vertex, Vertex> pipeline = new GremlinPipeline<>(initialVertices);
final Set<Vertex> allClassifiedOrHintedVertices = new HashSet<>();
ExecutionStatistics.get().begin("FindFilesNotClassifiedOrHintedGremlinCriterion.hintPipeline");
// create a pipeline to get all hinted items
GremlinPipeline<Vertex, Vertex> hintPipeline = new GremlinPipeline<>(
context.getQuery().type(InlineHintModel.class).vertices());
hintPipeline.as("fileLocation1").out(FileLocationModel.FILE_MODEL).retain(initialVerticesList);
hintPipeline.fill(allClassifiedOrHintedVertices);
ExecutionStatistics.get().end("FindFilesNotClassifiedOrHintedGremlinCriterion.hintPipeline");
ExecutionStatistics.get().begin("FindFilesNotClassifiedOrHintedGremlinCriterion.classificationPipeline");
// create a pipeline to get all items with attached classifications
GremlinPipeline<Vertex, Vertex> classificationPipeline = new GremlinPipeline<>(
context.getQuery().type(ClassificationModel.class).vertices());
classificationPipeline.as("fileModel2").out(ClassificationModel.FILE_MODEL).retain(initialVerticesList);
classificationPipeline.fill(allClassifiedOrHintedVertices);
ExecutionStatistics.get().end("FindFilesNotClassifiedOrHintedGremlinCriterion.classificationPipeline");
pipeline.filter(new PipeFunction<Vertex, Boolean>()
{
@Override
public Boolean compute(Vertex v)
{
FileModel f = context.getFramed().frame(v, FileModel.class);
//1. we don't want to show files with hints/classifications
if (allClassifiedOrHintedVertices.contains(v))
{
return false;
}
//2. we don't want to show our decompiled classes in the report
if (f.isWindupGenerated())
{
return false;
}
//3. we don't want to show class in case it's .java decompiled file has hints/classifications
if (f instanceof JavaClassFileModel)
{
Iterator<Vertex> decompiled = v.getVertices(Direction.OUT, JavaClassFileModel.DECOMPILED_FILE).iterator();
if (decompiled.hasNext())
{
JavaSourceFileModel source = context.getFramed().frame(decompiled.next(), JavaSourceFileModel.class);
if (allClassifiedOrHintedVertices.contains(source.asVertex()))
{
return false;
}
}
}
return true;
}
});
ExecutionStatistics.get().end("FindFilesNotClassifiedOrHintedGremlinCriterion.total");
return pipeline;
}
}