Skip to content

Commit

Permalink
Merge pull request #1611 from kazuki43zoo/add-constructor-with-annota…
Browse files Browse the repository at this point in the history
…tion-on-sqlprovidersource

Add constructor that pass an Annotation type instead of Object on ProviderSqlSource
  • Loading branch information
kazuki43zoo authored Jul 22, 2019
2 parents 6cea6e1 + 4dbd30a commit e4b89ce
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ public class ProviderSqlSource implements SqlSource {
private Integer providerContextIndex;

/**
* @deprecated Please use the {@link #ProviderSqlSource(Configuration, Object, Class, Method)} instead of this.
* @deprecated Since 3.5.3, Please use the {@link #ProviderSqlSource(Configuration, Annotation, Class, Method)} instead of this.
* This constructor will remove at a future version.
*/
@Deprecated
public ProviderSqlSource(Configuration configuration, Object provider) {
Expand All @@ -55,16 +56,26 @@ public ProviderSqlSource(Configuration configuration, Object provider) {

/**
* @since 3.4.5
* @deprecated Since 3.5.3, Please use the {@link #ProviderSqlSource(Configuration, Annotation, Class, Method)} instead of this.
* This constructor will remove at a future version.
*/
@Deprecated
public ProviderSqlSource(Configuration configuration, Object provider, Class<?> mapperType, Method mapperMethod) {
this(configuration, (Annotation) provider , mapperType, mapperMethod);
}

/**
* @since 3.5.3
*/
public ProviderSqlSource(Configuration configuration, Annotation provider, Class<?> mapperType, Method mapperMethod) {
String providerMethodName;
try {
this.configuration = configuration;
this.mapperMethod = mapperMethod;
Lang lang = mapperMethod == null ? null : mapperMethod.getAnnotation(Lang.class);
this.languageDriver = configuration.getLanguageDriver(lang == null ? null : lang.value());
this.providerType = getProviderType(provider, mapperMethod);
providerMethodName = (String) provider.getClass().getMethod("method").invoke(provider);
providerMethodName = (String) provider.annotationType().getMethod("method").invoke(provider);

if (providerMethodName.length() == 0 && ProviderMethodResolver.class.isAssignableFrom(this.providerType)) {
this.providerMethod = ((ProviderMethodResolver) this.providerType.getDeclaredConstructor().newInstance())
Expand Down Expand Up @@ -192,18 +203,18 @@ private String invokeProviderMethod(Object... args) throws Exception {
return sql != null ? sql.toString() : null;
}

private Class<?> getProviderType(Object providerAnnotation, Method mapperMethod)
private Class<?> getProviderType(Annotation providerAnnotation, Method mapperMethod)
throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Class<?> type = (Class<?>) providerAnnotation.getClass().getMethod("type").invoke(providerAnnotation);
Class<?> value = (Class<?>) providerAnnotation.getClass().getMethod("value").invoke(providerAnnotation);
Class<?> type = (Class<?>) providerAnnotation.annotationType().getMethod("type").invoke(providerAnnotation);
Class<?> value = (Class<?>) providerAnnotation.annotationType().getMethod("value").invoke(providerAnnotation);
if (value == void.class && type == void.class) {
throw new BuilderException("Please specify either 'value' or 'type' attribute of @"
+ ((Annotation) providerAnnotation).annotationType().getSimpleName()
+ providerAnnotation.annotationType().getSimpleName()
+ " at the '" + mapperMethod.toString() + "'.");
}
if (value != void.class && type != void.class && value != type) {
throw new BuilderException("Cannot specify different class on 'value' and 'type' attribute of @"
+ ((Annotation) providerAnnotation).annotationType().getSimpleName()
+ providerAnnotation.annotationType().getSimpleName()
+ " at the '" + mapperMethod.toString() + "'.");
}
return value == void.class ? type : value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import static org.junit.jupiter.api.Assertions.fail;

import java.io.Reader;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
Expand Down Expand Up @@ -298,12 +299,14 @@ void methodOverload() throws NoSuchMethodException {
}

@Test
void notSqlProvider() {
@SuppressWarnings("deprecation")
void notSqlProvider() throws NoSuchMethodException {
Object testAnnotation = getClass().getDeclaredMethod("notSqlProvider").getAnnotation(Test.class);
try {
new ProviderSqlSource(new Configuration(), new Object(), null, null);
new ProviderSqlSource(new Configuration(), testAnnotation);
fail();
} catch (BuilderException e) {
assertTrue(e.getMessage().contains("Error creating SqlSource for SqlProvider. Cause: java.lang.NoSuchMethodException: java.lang.Object.type()"));
assertTrue(e.getMessage().contains("Error creating SqlSource for SqlProvider. Cause: java.lang.NoSuchMethodException: org.junit.jupiter.api.Test.type()"));
}
}

Expand Down Expand Up @@ -648,6 +651,15 @@ void providerContextAndMap() {
}
}

@Test
@SuppressWarnings("deprecation")
void keepBackwardCompatibilityOnDeprecatedConstructorWithAnnotation() throws NoSuchMethodException {
Class<?> mapperType = StaticMethodSqlProviderMapper.class;
Method mapperMethod = mapperType.getMethod("noArgument");
ProviderSqlSource sqlSource = new ProviderSqlSource(new Configuration(), (Object)mapperMethod.getAnnotation(SelectProvider.class), mapperType, mapperMethod);
assertEquals("SELECT 1 FROM INFORMATION_SCHEMA.SYSTEM_USERS", sqlSource.getBoundSql(null).getSql());
}

public interface ErrorMapper {
@SelectProvider(type = ErrorSqlBuilder.class, method = "methodNotFound")
void methodNotFound();
Expand Down

0 comments on commit e4b89ce

Please sign in to comment.