package org.jboss.windup.rules.apps.javaee.rules; import java.util.logging.Logger; import org.apache.commons.lang3.StringUtils; 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.loader.RuleLoaderContext; import org.jboss.windup.config.metadata.RuleMetadata; import org.jboss.windup.config.operation.Iteration; import org.jboss.windup.config.operation.iteration.AbstractIterationOperation; import org.jboss.windup.config.phase.MigrationRulesPhase; 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.service.JavaClassService; import org.jboss.windup.rules.apps.javaee.model.RMIServiceModel; import org.jboss.windup.rules.apps.javaee.service.RMIServiceModelService; import org.jboss.windup.util.Logging; import org.ocpsoft.rewrite.config.Configuration; import org.ocpsoft.rewrite.config.ConfigurationBuilder; import org.ocpsoft.rewrite.context.EvaluationContext; /** * Scans for classes with JAX-WS related annotations, and adds JAX-WS related metadata for these. * * @author <a href="mailto:bradsdavis@gmail.com">Brad Davis</a> */ @RuleMetadata(phase = MigrationRulesPhase.class) public class DiscoverRmiRuleProvider extends AbstractRuleProvider { private static final Logger LOG = Logging.get(DiscoverRmiRuleProvider.class); private static final String RMI_INHERITANCE = "rmiInheritance"; @Override public Configuration getConfiguration(RuleLoaderContext ruleLoaderContext) { String ruleIDPrefix = getClass().getSimpleName(); return ConfigurationBuilder .begin() .addRule() .when(JavaClass .references("java.rmi.Remote") .at(TypeReferenceLocation.IMPORT) .as(RMI_INHERITANCE)) .perform(Iteration.over(RMI_INHERITANCE).perform(new AbstractIterationOperation<JavaTypeReferenceModel>() { @Override public void perform(GraphRewrite event, EvaluationContext context, JavaTypeReferenceModel payload) { extractMetadata(event, payload); } }).endIteration()) .withId(ruleIDPrefix + "_RMIInheritanceRule"); } private void extractMetadata(GraphRewrite event, JavaTypeReferenceModel typeReference) { // get the rmi interface class from the graph JavaClassModel javaClassModel = getJavaClass(typeReference); if (!isRemoteInterface(javaClassModel)) { LOG.warning("Is not remote: " + javaClassModel.getQualifiedName()); return; } LOG.info("Processing: " + typeReference); // Make sure we create a source report for the interface source typeReference.getFile().setGenerateSourceReport(true); RMIServiceModelService rmiService = new RMIServiceModelService(event.getGraphContext()); if (javaClassModel != null) { RMIServiceModel rmiServiceModel = rmiService.getOrCreate(typeReference.getFile().getApplication(), javaClassModel); // Create the source report for the RMI Implementation. JavaClassService javaClassService = new JavaClassService(event.getGraphContext()); if (rmiServiceModel != null && rmiServiceModel.getImplementationClass() != null) { for (AbstractJavaSourceModel source : javaClassService.getJavaSource(rmiServiceModel.getImplementationClass().getQualifiedName())) { source.setGenerateSourceReport(true); } } } } public boolean isRemoteInterface(JavaClassModel jcm) { if (!jcm.isInterface()) return false; LOG.info("Class: " + jcm.getQualifiedName()); for (JavaClassModel im : jcm.getInterfaces()) { if (StringUtils.equals("java.rmi.Remote", im.getQualifiedName())) { return true; } LOG.info(" - Implements: " + im.getQualifiedName()); } if (jcm.getExtends() != null) { LOG.info(" - Extends: " + jcm.getExtends().getQualifiedName()); return (StringUtils.equals("java.rmi.Remote", jcm.getExtends().getQualifiedName())); } return false; } private JavaClassModel getJavaClass(JavaTypeReferenceModel javaTypeReference) { JavaClassModel result = null; AbstractJavaSourceModel javaSource = javaTypeReference.getFile(); for (JavaClassModel javaClassModel : javaSource.getJavaClasses()) { // there can be only one public one, and the annotated class should be public if (javaClassModel.isPublic() != null && javaClassModel.isPublic()) { result = javaClassModel; break; } } if (result == null) { // no public classes found, so try to find any class (even non-public ones) result = javaSource.getJavaClasses().iterator().next(); } return result; } @Override public String toString() { return "DiscoverEJBAnnotatedClasses"; } }