package archmapper.stylespecific.spring.rules;
import java.util.List;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.Block;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.tptp.platform.analysis.codereview.java.CodeReviewResource;
import org.eclipse.tptp.platform.analysis.core.history.AnalysisHistory;
import archmapper.main.conformance.rules.AbstractArchitectureConformanceRule;
import archmapper.main.model.architecture.Component;
import static archmapper.stylespecific.spring.SpringStyleTypeConstants.MODEL_COMPONENT_TYPE;
public class NoComputationInModelRule extends AbstractArchitectureConformanceRule {
@Override
public void analyze(AnalysisHistory history) {
CodeReviewResource resource = getCurrentResource(history);
List<?> list = resource.getTypedNodeList(resource.getResourceCompUnit(),
ASTNode.TYPE_DECLARATION, true);
for (Object obj : list) {
TypeDeclaration typeDec = (TypeDeclaration) obj;
ITypeBinding binding = typeDec.resolveBinding();
String compName = mappingHelper.getComponentName(binding);
if (compName != null) {
Component comp = arch.getComponentByName(compName);
if (comp != null && MODEL_COMPONENT_TYPE.equals(comp.getStyleType())) {
// look at the methods...
List<?> methods = resource.getTypedNodeList(typeDec, ASTNode.METHOD_DECLARATION, false);
for (Object methObj : methods) {
MethodDeclaration meth = (MethodDeclaration) methObj;
IMethodBinding methBinding = meth.resolveBinding();
// The name must begin with get or set
if (!methBinding.getName().startsWith("set") &&
!methBinding.getName().startsWith("get") &&
!methBinding.getName().startsWith("is") &&
!methBinding.isConstructor()) {
generateResultsForASTNode(history, meth, resource, "The method "+
methBinding.getName() + " in the Model class "+
binding.getName() + " is not a getter or setter");
continue;
}
if (methBinding.getName().startsWith("set")) {
if (!methBinding.getReturnType().getName().equals("void")) {
generateResultsForASTNode(history, meth, resource, "The setter "+
methBinding.getName() + " in the Model class "+
binding.getName() + " does not return void");
}
if (methBinding.getParameterTypes().length != 1) {
generateResultsForASTNode(history, meth, resource, "The setter "+
methBinding.getName() + " in the Model class "+
binding.getName() + " must have exactly one parameter");
}
} else if (methBinding.getName().startsWith("get") ||
methBinding.getName().startsWith("is")) {
if (methBinding.getParameterTypes().length != 0) {
generateResultsForASTNode(history, meth, resource, "The getter "+
methBinding.getName() + " in the Model class "+
binding.getName() + " may not have any parameters");
}
}
if (!methBinding.isConstructor()) {
// Method is a getter or setter. Check if there is only
// one statement in the method so that there can be no
// computations.
Block body = meth.getBody();
if (body != null) {
if (body.statements().size() != 1) {
generateResultsForASTNode(history, meth, resource, "The getter "+
methBinding.getName() + " in the Model class "+
binding.getName() + " must include exactly one statement.");
}
}
}
}
}
}
}
}
}