Skip to content

Commit

Permalink
WINDUP-766: Scan JSP's for potential migration issues
Browse files Browse the repository at this point in the history
  • Loading branch information
jsight committed Sep 24, 2015
1 parent 1a949ed commit 7f6f4e9
Show file tree
Hide file tree
Showing 18 changed files with 759 additions and 94 deletions.
Expand Up @@ -97,7 +97,12 @@ public enum TypeReferenceLocation
* int foo = mypackage.MyConstants.FOO;
* </pre>
*/
VARIABLE_INITIALIZER("Variable Initializer");
VARIABLE_INITIALIZER("Variable Initializer"),

/**
* This is only relevant for JSP sources and represents the import of a taglib into the JSP source file.
*/
TAGLIB_IMPORT("Taglib Import");

private String readablePrefix;

Expand Down
@@ -0,0 +1,19 @@
package org.jboss.windup.rules.apps.javaee.model;

import org.jboss.windup.rules.apps.java.model.AbstractJavaSourceModel;

import com.tinkerpop.frames.modules.typedgraph.TypeValue;

/**
* Represents a JSP file on disk.
*
* @author <a href="mailto:jesse.sightler@gmail.com">Jesse Sightler</a>
*/
@TypeValue(JspSourceFileModel.TYPE)
public interface JspSourceFileModel extends AbstractJavaSourceModel
{
String UNPARSEABLE_JSP_CLASSIFICATION = "Unparseable JSP File";
String UNPARSEABLE_JSP_DESCRIPTION = "This JSP file could not be parsed";

String TYPE = "JspSourceFile";
}
@@ -0,0 +1,174 @@
package org.jboss.windup.rules.apps.javaee.rules;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.jboss.windup.ast.java.data.ClassReference;
import org.jboss.windup.ast.java.data.ResolutionStatus;
import org.jboss.windup.ast.java.data.TypeReferenceLocation;
import org.jboss.windup.config.AbstractRuleProvider;
import org.jboss.windup.config.GraphRewrite;
import org.jboss.windup.config.metadata.MetadataBuilder;
import org.jboss.windup.config.operation.iteration.AbstractIterationOperation;
import org.jboss.windup.config.phase.InitialAnalysisPhase;
import org.jboss.windup.config.query.Query;
import org.jboss.windup.graph.GraphContext;
import org.jboss.windup.reporting.service.ClassificationService;
import org.jboss.windup.rules.apps.java.model.JavaClassModel;
import org.jboss.windup.rules.apps.java.scan.ast.JavaTypeReferenceModel;
import org.jboss.windup.rules.apps.java.scan.ast.TypeInterestFactory;
import org.jboss.windup.rules.apps.java.service.JavaClassService;
import org.jboss.windup.rules.apps.java.service.TypeReferenceService;
import org.jboss.windup.rules.apps.javaee.model.JspSourceFileModel;
import org.ocpsoft.rewrite.config.Configuration;
import org.ocpsoft.rewrite.config.ConfigurationBuilder;
import org.ocpsoft.rewrite.context.EvaluationContext;

/**
* Extracts type references from JSP files.
*
* @author <a href="mailto:jesse.sightler@gmail.com">Jesse Sightler</a>
*/
public class AnalyzeJSPFileRuleProvider extends AbstractRuleProvider
{
public AnalyzeJSPFileRuleProvider()
{
super(MetadataBuilder.forProvider(AnalyzeJSPFileRuleProvider.class)
.setPhase(InitialAnalysisPhase.class)
.setHaltOnException(true));
}

// @formatter:off
@Override
public Configuration getConfiguration(GraphContext context)
{
return ConfigurationBuilder.begin()
.addRule()
.when(Query.fromType(JspSourceFileModel.class))
.perform(new ParseSourceOperation());
}
// @formatter:on

private class ParseSourceOperation extends AbstractIterationOperation<JspSourceFileModel>
{
@Override
public void perform(GraphRewrite event, EvaluationContext context, JspSourceFileModel sourceFile)
{

TypeReferenceService typeReferenceService = new TypeReferenceService(event.getGraphContext());

try
{
// Setup some basic details about the "Java Class"
// source root, is decompiled, javaclass. package name
sourceFile.setPackageName("");
sourceFile.setDecompiled(false);
JavaClassService javaClassService = new JavaClassService(event.getGraphContext());
JavaClassModel classModel = javaClassService.create();
classModel.setPackageName("");
classModel.setSimpleName(sourceFile.getFileName());
classModel.setQualifiedName(sourceFile.getFileName());
classModel.setExtends(javaClassService.getOrCreatePhantom("javax.servlet.http.HttpServlet"));
sourceFile.addJavaClass(classModel);

Iterable<ClassReference> references = getClassReferences(typeReferenceService, sourceFile);
for (ClassReference reference : references)
{
JavaTypeReferenceModel typeReference = typeReferenceService.createTypeReference(sourceFile,
reference.getLocation(),
reference.getResolutionStatus(),
reference.getLineNumber(), reference.getColumn(), reference.getLength(),
reference.getQualifiedName(),
reference.getLine());
}
}
catch (Exception e)
{
ClassificationService classificationService = new ClassificationService(event.getGraphContext());
classificationService.attachClassification(context, sourceFile, JspSourceFileModel.UNPARSEABLE_JSP_CLASSIFICATION,
JspSourceFileModel.UNPARSEABLE_JSP_DESCRIPTION);
}
}
}

private Iterable<ClassReference> getClassReferences(TypeReferenceService service, JspSourceFileModel sourceFile) throws IOException
{
String source = FileUtils.readFileToString(sourceFile.asFile());

List<ClassReference> results = new ArrayList<>();
results.addAll(findImports(source));
results.addAll(findTaglib(source));
return results;
}

private List<ClassReference> findImports(String source)
{
List<ClassReference> results = new ArrayList<>();

Pattern jspImport = Pattern.compile("<%@\\s*page\\s+[^>]*\\s*import\\s*=\\s*['\"]([^'\"]+)['\"].*?%>",
Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
Matcher matcher = jspImport.matcher(source);
while (matcher.find())
{
String matched = matcher.group(1);
if (StringUtils.isNotBlank(matched))
{
String[] imports = StringUtils.split(matched, ",");
if (imports != null)
{
for (String imported : imports)
{
imported = StringUtils.trim(imported);
if (TypeInterestFactory.matchesAny(imported, TypeReferenceLocation.IMPORT))
{
ClassReference reference = createClassReference(TypeReferenceLocation.IMPORT, source, imported, matcher.start());
results.add(reference);
}
}
}
}
}
return results;
}

private List<ClassReference> findTaglib(String source)
{
List<ClassReference> results = new ArrayList<>();

Pattern taglibPattern = Pattern.compile("<%@\\s*taglib\\s+[^>]*\\s*uri\\s*=\\s*['\"]([^'\"]+)['\"].*?%>",
Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
Matcher matcher = taglibPattern.matcher(source);
while (matcher.find())
{
String matched = matcher.group(1);
if (StringUtils.isNotBlank(matched))
{
if (TypeInterestFactory.matchesAny(matched, TypeReferenceLocation.TAGLIB_IMPORT))
{
ClassReference reference = createClassReference(TypeReferenceLocation.TAGLIB_IMPORT, source, matched, matcher.start());
results.add(reference);
}
}
}
return results;
}

private ClassReference createClassReference(TypeReferenceLocation location, String source, String reference, int startPosition)
{
String subString = StringUtils.substring(source, 0, startPosition + 1);
String[] lines = subString.split("\r\n|\r|\n");

int lineNumber = lines.length;
int column = lines[lines.length - 1].indexOf(source.substring(startPosition));
int length = reference.length();

return new ClassReference(reference, ResolutionStatus.UNKNOWN, location, lineNumber, column, length,
reference);
}

}
Expand Up @@ -14,8 +14,8 @@
import org.jboss.windup.graph.service.GraphService;
import org.jboss.windup.graph.service.Service;
import org.jboss.windup.rules.apps.java.condition.JavaClass;
import org.jboss.windup.rules.apps.java.model.AbstractJavaSourceModel;
import org.jboss.windup.rules.apps.java.model.JavaClassModel;
import org.jboss.windup.rules.apps.java.model.JavaSourceFileModel;
import org.jboss.windup.rules.apps.java.scan.ast.JavaTypeReferenceModel;
import org.jboss.windup.rules.apps.java.scan.ast.annotations.JavaAnnotationListTypeValueModel;
import org.jboss.windup.rules.apps.java.scan.ast.annotations.JavaAnnotationLiteralTypeValueModel;
Expand Down Expand Up @@ -197,7 +197,7 @@ else if (annotationTypeReferenceModel instanceof JavaAnnotationTypeReferenceMode
private JavaClassModel getJavaClass(JavaTypeReferenceModel javaTypeReference)
{
JavaClassModel result = null;
JavaSourceFileModel javaSource = javaTypeReference.getFile();
AbstractJavaSourceModel javaSource = javaTypeReference.getFile();
for (JavaClassModel javaClassModel : javaSource.getJavaClasses())
{
// there can be only one public one, and the annotated class should be public
Expand Down
Expand Up @@ -14,8 +14,8 @@
import org.jboss.windup.graph.model.WindupVertexFrame;
import org.jboss.windup.graph.service.GraphService;
import org.jboss.windup.rules.apps.java.condition.JavaClass;
import org.jboss.windup.rules.apps.java.model.AbstractJavaSourceModel;
import org.jboss.windup.rules.apps.java.model.JavaClassModel;
import org.jboss.windup.rules.apps.java.model.JavaSourceFileModel;
import org.jboss.windup.rules.apps.java.scan.ast.JavaTypeReferenceModel;
import org.jboss.windup.rules.apps.java.scan.ast.annotations.JavaAnnotationListTypeValueModel;
import org.jboss.windup.rules.apps.java.scan.ast.annotations.JavaAnnotationLiteralTypeValueModel;
Expand Down Expand Up @@ -202,7 +202,7 @@ private void addNamedQuery(GraphService<JPANamedQueryModel> namedQueryService, J
private JavaClassModel getJavaClass(JavaTypeReferenceModel javaTypeReference)
{
JavaClassModel result = null;
JavaSourceFileModel javaSource = javaTypeReference.getFile();
AbstractJavaSourceModel javaSource = javaTypeReference.getFile();
for (JavaClassModel javaClassModel : javaSource.getJavaClasses())
{
// there can be only one public one, and the annotated class should be public
Expand Down
Expand Up @@ -11,8 +11,8 @@
import org.jboss.windup.config.phase.InitialAnalysisPhase;
import org.jboss.windup.graph.GraphContext;
import org.jboss.windup.rules.apps.java.condition.JavaClass;
import org.jboss.windup.rules.apps.java.model.AbstractJavaSourceModel;
import org.jboss.windup.rules.apps.java.model.JavaClassModel;
import org.jboss.windup.rules.apps.java.model.JavaSourceFileModel;
import org.jboss.windup.rules.apps.java.scan.ast.JavaTypeReferenceModel;
import org.jboss.windup.rules.apps.java.scan.ast.annotations.JavaAnnotationLiteralTypeValueModel;
import org.jboss.windup.rules.apps.java.scan.ast.annotations.JavaAnnotationTypeReferenceModel;
Expand Down Expand Up @@ -93,7 +93,7 @@ private String getAnnotationLiteralValue(JavaAnnotationTypeReferenceModel model,
private JavaClassModel getJavaClass(JavaTypeReferenceModel javaTypeReference)
{
JavaClassModel result = null;
JavaSourceFileModel javaSource = javaTypeReference.getFile();
AbstractJavaSourceModel javaSource = javaTypeReference.getFile();
for (JavaClassModel javaClassModel : javaSource.getJavaClasses())
{
// there can be only one public one, and the annotated class should be public
Expand Down
Expand Up @@ -12,6 +12,7 @@
import org.jboss.windup.config.phase.InitialAnalysisPhase;
import org.jboss.windup.graph.GraphContext;
import org.jboss.windup.rules.apps.java.condition.JavaClass;
import org.jboss.windup.rules.apps.java.model.AbstractJavaSourceModel;
import org.jboss.windup.rules.apps.java.model.JavaClassModel;
import org.jboss.windup.rules.apps.java.model.JavaSourceFileModel;
import org.jboss.windup.rules.apps.java.scan.ast.JavaTypeReferenceModel;
Expand Down Expand Up @@ -99,7 +100,7 @@ private void extractMetadata(GraphRewrite event, JavaTypeReferenceModel typeRefe
private JavaClassModel getJavaClass(JavaTypeReferenceModel javaTypeReference)
{
JavaClassModel result = null;
JavaSourceFileModel javaSource = javaTypeReference.getFile();
AbstractJavaSourceModel javaSource = javaTypeReference.getFile();
for (JavaClassModel javaClassModel : javaSource.getJavaClasses())
{
// there can be only one public one, and the annotated class should be public
Expand Down
Expand Up @@ -12,6 +12,7 @@
import org.jboss.windup.config.phase.MigrationRulesPhase;
import org.jboss.windup.graph.GraphContext;
import org.jboss.windup.rules.apps.java.condition.JavaClass;
import org.jboss.windup.rules.apps.java.model.AbstractJavaSourceModel;
import org.jboss.windup.rules.apps.java.model.JavaClassModel;
import org.jboss.windup.rules.apps.java.model.JavaSourceFileModel;
import org.jboss.windup.rules.apps.java.scan.ast.JavaTypeReferenceModel;
Expand Down Expand Up @@ -116,7 +117,7 @@ public boolean isRemoteInterface(JavaClassModel jcm)
private JavaClassModel getJavaClass(JavaTypeReferenceModel javaTypeReference)
{
JavaClassModel result = null;
JavaSourceFileModel javaSource = javaTypeReference.getFile();
AbstractJavaSourceModel javaSource = javaTypeReference.getFile();

for (JavaClassModel javaClassModel : javaSource.getJavaClasses())
{
Expand Down
@@ -0,0 +1,35 @@
package org.jboss.windup.rules.apps.javaee.rules;

import org.jboss.windup.config.AbstractRuleProvider;
import org.jboss.windup.config.metadata.MetadataBuilder;
import org.jboss.windup.config.phase.ClassifyFileTypesPhase;
import org.jboss.windup.graph.GraphContext;
import org.jboss.windup.rules.apps.javaee.model.JspSourceFileModel;
import org.jboss.windup.rules.files.FileMapping;
import org.ocpsoft.rewrite.config.Configuration;
import org.ocpsoft.rewrite.config.ConfigurationBuilder;

/**
* Insures that basic JSP file extensions are mapped to {@link JspSourceFileModel}.
*
* @author <a href="mailto:jesse.sightler@gmail.com">Jesse Sightler</a>
*/
public class JspFileMappingRuleProvider extends AbstractRuleProvider
{

public JspFileMappingRuleProvider()
{
super(MetadataBuilder.forProvider(JspFileMappingRuleProvider.class)
.setPhase(ClassifyFileTypesPhase.class));
}

@Override
public Configuration getConfiguration(GraphContext context)
{
return ConfigurationBuilder.begin()
.addRule(FileMapping.from(".*\\.jsp$").to(JspSourceFileModel.class))
.addRule(FileMapping.from(".*\\.jspx$").to(JspSourceFileModel.class))
.addRule(FileMapping.from(".*\\.jsf$").to(JspSourceFileModel.class))
.addRule(FileMapping.from(".*\\.xhtml$").to(JspSourceFileModel.class));
}
}
Expand Up @@ -29,6 +29,7 @@
import org.jboss.windup.config.query.QueryPropertyComparisonType;
import org.jboss.windup.graph.model.WindupVertexFrame;
import org.jboss.windup.graph.model.resource.FileModel;
import org.jboss.windup.rules.apps.java.model.AbstractJavaSourceModel;
import org.jboss.windup.rules.apps.java.model.JavaClassFileModel;
import org.jboss.windup.rules.apps.java.model.JavaClassModel;
import org.jboss.windup.rules.apps.java.model.JavaSourceFileModel;
Expand Down Expand Up @@ -239,8 +240,8 @@ private boolean evaluate(GraphRewrite event, EvaluationContext context, Evaluati
{
FileModel fileModel = ((FileReferenceModel) frame).getFile();
Iterable<JavaClassModel> javaClasses = null;
if (fileModel instanceof JavaSourceFileModel)
javaClasses = ((JavaSourceFileModel) fileModel).getJavaClasses();
if (fileModel instanceof AbstractJavaSourceModel)
javaClasses = ((AbstractJavaSourceModel) fileModel).getJavaClasses();
else if (fileModel instanceof JavaClassFileModel)
javaClasses = Arrays.asList(((JavaClassFileModel) fileModel).getJavaClass());

Expand Down

0 comments on commit 7f6f4e9

Please sign in to comment.