package org.jboss.windup.rules.apps.java.scan.provider; import org.jboss.windup.ast.java.data.ResolutionStatus; import org.jboss.windup.config.AbstractRuleProvider; import org.jboss.windup.config.GraphRewrite; import org.jboss.windup.config.loader.RuleLoaderContext; import org.jboss.windup.config.operation.GraphOperation; import org.jboss.windup.config.phase.DependentPhase; import org.jboss.windup.config.phase.PostMigrationRulesPhase; import org.jboss.windup.config.phase.PreReportGenerationPhase; import org.jboss.windup.config.query.Query; import org.jboss.windup.graph.model.WindupVertexFrame; import org.jboss.windup.graph.service.GraphService; import org.jboss.windup.reporting.config.HasHint; import org.jboss.windup.reporting.model.InlineHintModel; import org.jboss.windup.reporting.service.InlineHintService; import org.jboss.windup.reporting.category.IssueCategoryRegistry; import org.jboss.windup.rules.apps.java.model.WindupJavaConfigurationModel; import org.jboss.windup.rules.apps.java.scan.ast.JavaTypeReferenceModel; import org.ocpsoft.rewrite.config.Configuration; import org.ocpsoft.rewrite.config.ConfigurationBuilder; import org.ocpsoft.rewrite.context.EvaluationContext; import com.tinkerpop.blueprints.Vertex; import com.tinkerpop.gremlin.java.GremlinPipeline; import org.jboss.windup.config.metadata.RuleMetadata; /** * Finds references to Java classes that were not found in the application and also not in the target environment. * * @author <a href="mailto:jesse.sightler@gmail.com">Jesse Sightler</a> * @author <a href="mailto:dynawest@gmail.com">Ondrej Zizka</a> */ @RuleMetadata( phase = DependentPhase.class, after = PostMigrationRulesPhase.class, before = PreReportGenerationPhase.class, tags = FindUnboundJavaReferencesRuleProvider.JAVA) public class FindUnboundJavaReferencesRuleProvider extends AbstractRuleProvider { public static final String JAVA = "java"; public static final String RULE_ID = FindUnboundJavaReferencesRuleProvider.class.getSimpleName(); public static final String TITLE = "Unresolved Class Binding"; // @formatter:off @Override public Configuration getConfiguration(RuleLoaderContext ruleLoaderContext) { return ConfigurationBuilder.begin() .addRule() .when(Query.fromType(WindupJavaConfigurationModel.class).withProperty(WindupJavaConfigurationModel.CLASS_NOT_FOUND_ANALYSIS_ENABLED, true)) .perform(new AttachHintOperation()) .withId(RULE_ID); } // @formatter:on private class AttachHintOperation extends GraphOperation { @Override public void perform(GraphRewrite event, EvaluationContext context) { // Has hint filter (so that we only add to those that do not have a hint) HasHint hasHint = new HasHint(); // Reuse the progress and commit logic from these GremlinPipeline<Vertex, Vertex> pipeline = new GremlinPipeline<>(event.getGraphContext().getGraph()); pipeline.V(); pipeline.has(WindupVertexFrame.TYPE_PROP, JavaTypeReferenceModel.TYPE); pipeline.hasNot(JavaTypeReferenceModel.RESOLUTION_STATUS, ResolutionStatus.RESOLVED); GraphService<JavaTypeReferenceModel> typeReferenceService = new GraphService<>(event.getGraphContext(), JavaTypeReferenceModel.class); int count = 0; for (Vertex vertex : pipeline) { JavaTypeReferenceModel typeReference = typeReferenceService.frame(vertex); if (hasHint.evaluate(event, context, typeReference)) { // we already have hints, so this would likely be redundant continue; } InlineHintModel hint = new InlineHintService(event.getGraphContext()).create(); hint.setRuleID(RULE_ID); hint.setLineNumber(typeReference.getLineNumber()); hint.setColumnNumber(typeReference.getColumnNumber()); hint.setLength(typeReference.getLength()); hint.setFileLocationReference(typeReference); hint.setFile(typeReference.getFile()); hint.setEffort(5); IssueCategoryRegistry issueCategoryRegistry = IssueCategoryRegistry.instance(event.getRewriteContext()); hint.setIssueCategory(issueCategoryRegistry.loadFromGraph(event.getGraphContext(), IssueCategoryRegistry.MANDATORY)); hint.setTitle(TITLE); hint.setHint("This class reference (" + typeReference.getDescription() + ") could not be found on the classpath"); typeReference.getFile().setGenerateSourceReport(true); count++; if (count % 1000 == 0) { event.getGraphContext().getGraph().getBaseGraph().commit(); } } } } }