Skip to content

Commit

Permalink
OPEN - issue STS-3067: Validate parameter types for derived query
Browse files Browse the repository at this point in the history
  • Loading branch information
thon committed Jan 23, 2013
1 parent 2768242 commit 0004d59
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,8 @@ dataValidator.name=Data Validator

dataValidator.rule.invalidDerivedQuery.name=Invalid Derived Query
dataValidator.rule.invalidDerivedQuery.description=Checks for an invalid Spring Data query method.
dataValidator.rule.invalidDerivedQuery.message=Invalid Derived Query
dataValidator.rule.invalidDerivedQuery.message=Invalid Derived Query

dataValidator.rule.invalidParameterType.name=Invalid Parameter Type
dataValidator.rule.invalidParameterType.description=Checks for invalid parameter type for find by method.
dataValidator.rule.invalidParameterType.message=Invalid Parameter Type
8 changes: 8 additions & 0 deletions plugins/org.springframework.ide.eclipse.data.core/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,14 @@
name="%dataValidator.rule.invalidDerivedQuery.name">
<message id="INVALID_DERIVED_QUERY" label="%dataValidator.rule.invalidDerivedQuery.message" severity="ERROR" />
</rule>
<rule
class="org.springframework.ide.eclipse.data.internal.validation.InvalidParameterTypeRule"
description="%dataValidator.rule.invalidParameterType.description"
enabledByDefault="true"
id="invalidParameterType"
name="%dataValidator.rule.invalidParameterType.name">
<message id="INVALID_PARAMETER_TYPE" label="%dataValidator.rule.invalidParameterType.message" severity="WARNING" />
</rule>
</rules>
</extension>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package org.springframework.ide.eclipse.data.internal.validation;

import java.lang.reflect.Method;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.ILocalVariable;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeRoot;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.springframework.ide.eclipse.core.SpringCore;
import org.springframework.ide.eclipse.core.StringUtils;
import org.springframework.ide.eclipse.core.model.IModelElement;
import org.springframework.ide.eclipse.core.model.java.JavaModelSourceLocation;
import org.springframework.ide.eclipse.core.model.validation.IValidationContext;
import org.springframework.ide.eclipse.core.model.validation.IValidationRule;
import org.springframework.ide.eclipse.core.model.validation.ValidationProblemAttribute;
import org.springframework.ide.eclipse.data.jdt.core.RepositoryInformation;

/**
* @author Terry Denney
* @since 3.2.0
*
*/
public class InvalidParameterTypeRule implements
IValidationRule<CompilationUnit, SpringDataValidationContext> {

public boolean supports(IModelElement element, IValidationContext context) {
if (!(context instanceof SpringDataValidationContext)) {
return false;
}

if (element instanceof CompilationUnit) {
CompilationUnit cu = (CompilationUnit) element;
ITypeRoot typeRoot = cu.getTypeRoot();

if (typeRoot == null) {
return false;
}

IType type = typeRoot.findPrimaryType();
if (type == null) {
return false;
}

// Skip non-interfaces
try {
if (type == null || !type.isInterface() || type.isAnnotation()) {
return false;
}
} catch (JavaModelException e) {
SpringCore.log(e);
return false;
}

// Skip non-spring-data repositories
if (!RepositoryInformation.isSpringDataRepository(type)) {
return false;
}

// resolve repository information and generate problem markers
RepositoryInformation information = new RepositoryInformation(type);

Class<?> domainClass = information.getManagedDomainClass();
if (domainClass == null) {
return false;
}
return true;
}
return false;
}

public void validate(CompilationUnit element,
SpringDataValidationContext context, IProgressMonitor monitor) {

ITypeRoot typeRoot = element.getTypeRoot();
IType type = typeRoot.findPrimaryType();

// resolve repository information and generate problem markers
RepositoryInformation information = new RepositoryInformation(type);

Class<?> domainClass = information.getManagedDomainClass();
if (domainClass == null) {
return;
}

try {
for (IMethod method : type.getMethods()) {
String methodName = method.getElementName();
if (methodName.startsWith("findBy")) {
String propertyName = StringUtils.uncapitalize(methodName
.substring("findBy".length()));

ILocalVariable[] params = method.getParameters();

if (params.length == 1) {
String paramTypeSignature = params[0].getTypeSignature();
Method propertyMethod = null;
try {
propertyMethod = domainClass.getMethod("get"
+ StringUtils.capitalize(propertyName));
} catch (NoSuchMethodException e) {
// not a property method... ignore
continue;
}

if (propertyMethod != null) {
Class<?> propertyReturnType = propertyMethod.getReturnType();
String propertySimpleType = propertyReturnType.getSimpleName();
String paramSimpleType = Signature.getSignatureSimpleName(paramTypeSignature);
if (propertySimpleType != null && !(propertySimpleType.equals(paramSimpleType))) {
element.setElementSourceLocation(new JavaModelSourceLocation(params[0]));
ISourceRange paramSourceRange = params[0].getSourceRange();
ValidationProblemAttribute start = new ValidationProblemAttribute(
IMarker.CHAR_START, paramSourceRange.getOffset());
ValidationProblemAttribute end = new ValidationProblemAttribute(
IMarker.CHAR_END, paramSourceRange.getOffset() + paramSourceRange.getLength());
context.warning(element, "INVALID_PARAMETER_TYPE",
"Parameter type (" + paramSimpleType + ") does not match domain class property definition (" + propertySimpleType + ").",
new ValidationProblemAttribute[] {start, end });
}
}
}
}
}
} catch (JavaModelException e) {
SpringCore.log(e);
} catch (SecurityException e) {
SpringCore.log(e);
}
}

}

0 comments on commit 0004d59

Please sign in to comment.