Skip to content

Commit e4b89ce

Browse files
authored
Merge pull request #1611 from kazuki43zoo/add-constructor-with-annotation-on-sqlprovidersource
Add constructor that pass an Annotation type instead of Object on ProviderSqlSource
2 parents 6cea6e1 + 4dbd30a commit e4b89ce

File tree

2 files changed

+33
-10
lines changed

2 files changed

+33
-10
lines changed

src/main/java/org/apache/ibatis/builder/annotation/ProviderSqlSource.java

+18-7
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ public class ProviderSqlSource implements SqlSource {
4646
private Integer providerContextIndex;
4747

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

5657
/**
5758
* @since 3.4.5
59+
* @deprecated Since 3.5.3, Please use the {@link #ProviderSqlSource(Configuration, Annotation, Class, Method)} instead of this.
60+
* This constructor will remove at a future version.
5861
*/
62+
@Deprecated
5963
public ProviderSqlSource(Configuration configuration, Object provider, Class<?> mapperType, Method mapperMethod) {
64+
this(configuration, (Annotation) provider , mapperType, mapperMethod);
65+
}
66+
67+
/**
68+
* @since 3.5.3
69+
*/
70+
public ProviderSqlSource(Configuration configuration, Annotation provider, Class<?> mapperType, Method mapperMethod) {
6071
String providerMethodName;
6172
try {
6273
this.configuration = configuration;
6374
this.mapperMethod = mapperMethod;
6475
Lang lang = mapperMethod == null ? null : mapperMethod.getAnnotation(Lang.class);
6576
this.languageDriver = configuration.getLanguageDriver(lang == null ? null : lang.value());
6677
this.providerType = getProviderType(provider, mapperMethod);
67-
providerMethodName = (String) provider.getClass().getMethod("method").invoke(provider);
78+
providerMethodName = (String) provider.annotationType().getMethod("method").invoke(provider);
6879

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

195-
private Class<?> getProviderType(Object providerAnnotation, Method mapperMethod)
206+
private Class<?> getProviderType(Annotation providerAnnotation, Method mapperMethod)
196207
throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
197-
Class<?> type = (Class<?>) providerAnnotation.getClass().getMethod("type").invoke(providerAnnotation);
198-
Class<?> value = (Class<?>) providerAnnotation.getClass().getMethod("value").invoke(providerAnnotation);
208+
Class<?> type = (Class<?>) providerAnnotation.annotationType().getMethod("type").invoke(providerAnnotation);
209+
Class<?> value = (Class<?>) providerAnnotation.annotationType().getMethod("value").invoke(providerAnnotation);
199210
if (value == void.class && type == void.class) {
200211
throw new BuilderException("Please specify either 'value' or 'type' attribute of @"
201-
+ ((Annotation) providerAnnotation).annotationType().getSimpleName()
212+
+ providerAnnotation.annotationType().getSimpleName()
202213
+ " at the '" + mapperMethod.toString() + "'.");
203214
}
204215
if (value != void.class && type != void.class && value != type) {
205216
throw new BuilderException("Cannot specify different class on 'value' and 'type' attribute of @"
206-
+ ((Annotation) providerAnnotation).annotationType().getSimpleName()
217+
+ providerAnnotation.annotationType().getSimpleName()
207218
+ " at the '" + mapperMethod.toString() + "'.");
208219
}
209220
return value == void.class ? type : value;

src/test/java/org/apache/ibatis/submitted/sqlprovider/SqlProviderTest.java

+15-3
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import static org.junit.jupiter.api.Assertions.fail;
2323

2424
import java.io.Reader;
25+
import java.lang.annotation.Annotation;
2526
import java.lang.reflect.Method;
2627
import java.util.ArrayList;
2728
import java.util.Collections;
@@ -298,12 +299,14 @@ void methodOverload() throws NoSuchMethodException {
298299
}
299300

300301
@Test
301-
void notSqlProvider() {
302+
@SuppressWarnings("deprecation")
303+
void notSqlProvider() throws NoSuchMethodException {
304+
Object testAnnotation = getClass().getDeclaredMethod("notSqlProvider").getAnnotation(Test.class);
302305
try {
303-
new ProviderSqlSource(new Configuration(), new Object(), null, null);
306+
new ProviderSqlSource(new Configuration(), testAnnotation);
304307
fail();
305308
} catch (BuilderException e) {
306-
assertTrue(e.getMessage().contains("Error creating SqlSource for SqlProvider. Cause: java.lang.NoSuchMethodException: java.lang.Object.type()"));
309+
assertTrue(e.getMessage().contains("Error creating SqlSource for SqlProvider. Cause: java.lang.NoSuchMethodException: org.junit.jupiter.api.Test.type()"));
307310
}
308311
}
309312

@@ -648,6 +651,15 @@ void providerContextAndMap() {
648651
}
649652
}
650653

654+
@Test
655+
@SuppressWarnings("deprecation")
656+
void keepBackwardCompatibilityOnDeprecatedConstructorWithAnnotation() throws NoSuchMethodException {
657+
Class<?> mapperType = StaticMethodSqlProviderMapper.class;
658+
Method mapperMethod = mapperType.getMethod("noArgument");
659+
ProviderSqlSource sqlSource = new ProviderSqlSource(new Configuration(), (Object)mapperMethod.getAnnotation(SelectProvider.class), mapperType, mapperMethod);
660+
assertEquals("SELECT 1 FROM INFORMATION_SCHEMA.SYSTEM_USERS", sqlSource.getBoundSql(null).getSql());
661+
}
662+
651663
public interface ErrorMapper {
652664
@SelectProvider(type = ErrorSqlBuilder.class, method = "methodNotFound")
653665
void methodNotFound();

0 commit comments

Comments
 (0)