package org.jboss.windup.reporting.service; import java.util.Comparator; import java.util.Set; import java.util.TreeSet; import org.jboss.forge.furnace.util.Iterators; import org.jboss.windup.graph.GraphContext; import org.jboss.windup.graph.model.ProjectModel; import org.jboss.windup.graph.model.WindupVertexFrame; import org.jboss.windup.graph.model.resource.FileModel; import org.jboss.windup.graph.model.resource.SourceFileModel; import org.jboss.windup.graph.service.GraphService; import org.jboss.windup.graph.traversal.ProjectModelTraversal; import org.jboss.windup.reporting.model.DefaultTechnologyTagComparator; import org.jboss.windup.reporting.model.TechnologyTagLevel; import org.jboss.windup.reporting.model.TechnologyTagModel; import com.thinkaurelius.titan.core.attribute.Text; import com.tinkerpop.blueprints.Vertex; import com.tinkerpop.frames.FramedGraphQuery; import com.tinkerpop.frames.structures.FramedVertexIterable; import com.tinkerpop.gremlin.java.GremlinPipeline; import com.tinkerpop.pipes.PipeFunction; import com.tinkerpop.pipes.util.structures.Pair; /** * Contains methods for finding, creating, and deleting {@link TechnologyTagModel} instances. * * @author <a href="mailto:jesse.sightler@gmail.com">Jesse Sightler</a> * */ public class TechnologyTagService extends GraphService<TechnologyTagModel> { public TechnologyTagService(GraphContext context) { super(context, TechnologyTagModel.class); } /** * Adds the provided tag to the provided {@link FileModel}. If a {@link TechnologyTagModel} cannot be found with the provided name, then one will * be created. */ public TechnologyTagModel addTagToFileModel(FileModel fileModel, String tagName, TechnologyTagLevel level) { FramedGraphQuery q = getGraphContext().getQuery().type(TechnologyTagModel.class) .has(TechnologyTagModel.NAME, tagName); TechnologyTagModel technologyTag = super.getUnique(q); if (technologyTag == null) { technologyTag = create(); technologyTag.setName(tagName); technologyTag.setLevel(level); } if (level == TechnologyTagLevel.IMPORTANT && fileModel instanceof SourceFileModel) ((SourceFileModel) fileModel).setGenerateSourceReport(true); technologyTag.addFileModel(fileModel); return technologyTag; } /** * Removes the provided tag from the provided {@link FileModel}. If a {@link TechnologyTagModel} cannot be found with the provided name, then this * operation will do nothing. */ public void removeTagFromFileModel(FileModel fileModel, String tagName) { FramedGraphQuery q = getGraphContext().getQuery().type(TechnologyTagModel.class) .has(TechnologyTagModel.NAME, tagName); TechnologyTagModel technologyTag = super.getUnique(q); if (technologyTag != null) technologyTag.removeFileModel(fileModel); } /** * Return an {@link Iterable} containing all {@link TechnologyTagModel}s that are directly associated with the provided {@link FileModel}. */ public Iterable<TechnologyTagModel> findTechnologyTagsForFile(FileModel fileModel) { GremlinPipeline<Vertex, Vertex> pipeline = new GremlinPipeline<>(fileModel.asVertex()); pipeline.in(TechnologyTagModel.TECH_TAG_TO_FILE_MODEL).has(WindupVertexFrame.TYPE_PROP, Text.CONTAINS, TechnologyTagModel.TYPE); pipeline.order(new PipeFunction<Pair<Vertex, Vertex>, Integer>() { private Comparator<TechnologyTagModel> comparator = new DefaultTechnologyTagComparator(); @Override public Integer compute(Pair<Vertex, Vertex> argument) { return comparator.compare(frame(argument.getA()), frame(argument.getB())); } }); return new FramedVertexIterable<>(getGraphContext().getFramed(), pipeline, TechnologyTagModel.class); } /** * Return an {@link Iterable} containing all {@link TechnologyTagModel}s that are directly associated with the provided {@link ProjectModel}. */ public Iterable<TechnologyTagModel> findTechnologyTagsForProject(ProjectModelTraversal traversal) { Set<TechnologyTagModel> results = new TreeSet<>(new DefaultTechnologyTagComparator()); GremlinPipeline<Vertex, Vertex> pipeline = new GremlinPipeline<>(traversal.getCanonicalProject().asVertex()); pipeline.out(ProjectModel.PROJECT_MODEL_TO_FILE); pipeline.in(TechnologyTagModel.TECH_TAG_TO_FILE_MODEL).has(WindupVertexFrame.TYPE_PROP, Text.CONTAINS, TechnologyTagModel.TYPE); Iterable<TechnologyTagModel> modelIterable = new FramedVertexIterable<>(getGraphContext().getFramed(), pipeline, TechnologyTagModel.class); results.addAll(Iterators.asSet(modelIterable)); for (ProjectModelTraversal childTraversal : traversal.getChildren()) { results.addAll(Iterators.asSet(findTechnologyTagsForProject(childTraversal))); } return results; } }