Skip to content

Commit d1371fa

Browse files
committed
Dao インタフェースがデフォルトメソッドのみが定義されたインタフェースを継承可能に変更
1 parent 74d7808 commit d1371fa

File tree

13 files changed

+417
-30
lines changed

13 files changed

+417
-30
lines changed

src/main/java/org/seasar/doma/internal/apt/meta/DaoMetaFactory.java

Lines changed: 53 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package org.seasar.doma.internal.apt.meta;
1717

18+
import static java.util.stream.Collectors.toList;
1819
import static org.seasar.doma.internal.util.AssertionUtil.assertNotNull;
1920

2021
import java.io.File;
@@ -209,35 +210,61 @@ protected void doAnnotateWith(DaoMeta daoMeta) {
209210
}
210211

211212
protected void doParentDao(DaoMeta daoMeta) {
212-
List<? extends TypeMirror> interfaces = daoMeta.getDaoElement()
213-
.getInterfaces();
214-
int size = interfaces.size();
215-
if (size == 0) {
216-
return;
217-
}
218-
if (size > 1) {
219-
throw new AptException(Message.DOMA4187, env,
220-
daoMeta.getDaoElement(), new Object[] { daoMeta
221-
.getDaoElement().getQualifiedName() });
213+
List<TypeElement> interfaces = daoMeta.getDaoElement()
214+
.getInterfaces()
215+
.stream().map(type -> TypeMirrorUtil.toTypeElement(type, env))
216+
.peek(element -> {
217+
if (element == null) {
218+
throw new AptIllegalStateException(
219+
"failed to convert to TypeElement.");
220+
}
221+
}).collect(toList());
222+
for (TypeElement typeElement : interfaces) {
223+
DaoMirror daoMirror = DaoMirror.newInstance(typeElement, env);
224+
if (daoMirror == null) {
225+
ExecutableElement nonDefaultMethod = findNonDefaultMethod(
226+
typeElement);
227+
if (nonDefaultMethod == null) {
228+
continue;
229+
}
230+
throw new AptException(Message.DOMA4440, env,
231+
daoMeta.getDaoElement(),
232+
new Object[] { nonDefaultMethod.getSimpleName(),
233+
daoMeta.getDaoElement().getQualifiedName() });
234+
}
235+
if (daoMeta.getParentDaoMeta() != null) {
236+
throw new AptException(Message.DOMA4188, env,
237+
daoMeta.getDaoElement(),
238+
new Object[] {
239+
daoMeta.getDaoElement().getQualifiedName() });
240+
}
241+
ParentDaoMeta parentDaoMeta = new ParentDaoMeta(daoMirror);
242+
parentDaoMeta.setDaoType(typeElement.asType());
243+
parentDaoMeta.setDaoElement(typeElement);
244+
daoMeta.setParentDaoMeta(parentDaoMeta);
222245
}
223-
TypeMirror parentMirror = interfaces.get(0);
224-
TypeElement parentElement = TypeMirrorUtil.toTypeElement(parentMirror,
225-
env);
226-
if (parentElement == null) {
227-
throw new AptIllegalStateException(
228-
"failed to convert to TypeElement.");
246+
}
247+
248+
protected ExecutableElement findNonDefaultMethod(
249+
TypeElement interfaceElement) {
250+
Optional<ExecutableElement> method = ElementFilter
251+
.methodsIn(interfaceElement.getEnclosedElements()).stream()
252+
.filter(m -> !m.isDefault()).findAny();
253+
if (method.isPresent()) {
254+
return method.get();
229255
}
230-
DaoMirror daoMirror = DaoMirror.newInstance(parentElement, env);
231-
if (daoMirror == null) {
232-
throw new AptException(Message.DOMA4188, env,
233-
daoMeta.getDaoElement(), new Object[] {
234-
parentElement.getQualifiedName(),
235-
daoMeta.getDaoElement().getQualifiedName() });
256+
for (TypeMirror typeMirror : interfaceElement.getInterfaces()) {
257+
TypeElement i = TypeMirrorUtil.toTypeElement(typeMirror, env);
258+
if (i == null) {
259+
throw new AptIllegalStateException(
260+
"failed to convert to TypeElement.");
261+
}
262+
ExecutableElement m = findNonDefaultMethod(i);
263+
if (m != null) {
264+
return m;
265+
}
236266
}
237-
ParentDaoMeta parentDaoMeta = new ParentDaoMeta(daoMirror);
238-
parentDaoMeta.setDaoType(parentMirror);
239-
parentDaoMeta.setDaoElement(parentElement);
240-
daoMeta.setParentDaoMeta(parentDaoMeta);
267+
return null;
241268
}
242269

243270
protected void doMethodElements(TypeElement interfaceElement,

src/main/java/org/seasar/doma/message/Message.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -338,8 +338,7 @@ public enum Message implements MessageResource {
338338
DOMA4184("列挙型に@Domainを注釈する場合、factoryMethod属性に\"new\"は指定できません(\"new\"はコンストラクタで生成することを示します)。staticで非privateなファクトリメソッドの名前を指定してください。 at {0}"),
339339
DOMA4185(" ... /** SQLが長すぎるため最初の{0}文字のみを表示しています。 */"),
340340
DOMA4186("java.util.Listに対する実型引数の型[{0}]はサポートされていません。サポートされている型は次のものです。基本型、ドメインクラス、エンティティクラス、java.util.Map<String, Object>。 at {1}.{2}"),
341-
DOMA4187("@Daoが注釈されたインタフェースは2つ以上のインタフェースをextendsできません。 at {0}"),
342-
DOMA4188("@Daoが注釈されたインタフェースは@Daoが注釈されてないインタフェース[{0}]をextendsできません。 at {1}"),
341+
DOMA4188("継承先に指定できる「@Daoが注釈されたインタフェース」は1つのみです。@Daoが注釈されておらず全てのメソッドがデフォルトメソッドであるインタフェースは複数指定できます。 at {0}"),
343342
DOMA4189("式[{0}]([{1}]番目の文字付近)の関数[{2}]の解決に失敗しました。注釈処理のオプションdoma.expr.functionsに指定されたクラス[{3}]が見つかりません。"),
344343
DOMA4190("式[{0}]([{1}]番目の文字付近)の関数[{2}]の解決に失敗しました。注釈処理のオプションdoma.expr.functionsに指定されたクラス[{3}]はorg.seasar.doma.expr.ExpressionFunctionsのサブタイプでなければいけません。"),
345344
DOMA4191("@ExternalDomainはorg.seasar.doma.jdbc.domain.DomainConverterのサブタイプにのみ注釈できます。 at {0}"),
@@ -478,6 +477,7 @@ public enum Message implements MessageResource {
478477
DOMA4437("BiFunctionの1番目の実型引数の型は、org.seasar.doma.jdbc.Configでなければいけません。 at {0}.{1}"),
479478
DOMA4438("パラメータの型[{0}]を原型にしてはいけません。 at {1}.{2}"),
480479
DOMA4439("パラメータの型[{0}]にワイルカード型の型パラメータを含めてはいけません。 at {1}.{2}"),
480+
DOMA4440("継承先のメソッド[{0}]がデフォルトメソッドではありません。@Daoが注釈されていないインタフェースをextendsする場合、そのインタフェースの継承先を含む全てのメソッドはデフォルトメソッドでなければいけません。 at {1}"),
481481

482482
// other
483483
DOMA5001("JDBCドライバがロードされていない可能性があります。まず、JDBCドライバがクラスパスにあることを確認してください。次に、JDBCドライバが自動でロードされない場合は、Class.forNameで明示的にロードしてください。 ex) Class.forName(\"oracle.jdbc.driver.OracleDriver\")"),

src/test/java/org/seasar/doma/internal/apt/dao/DaoProcessorTest.java

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -307,8 +307,8 @@ public void testNonDaoExtends() throws Exception {
307307
addProcessor(processor);
308308
addCompilationUnit(target);
309309
compile();
310-
assertFalse(getCompiledResult());
311-
assertMessage(Message.DOMA4188);
310+
assertGeneratedSource(target);
311+
assertTrue(getCompiledResult());
312312
}
313313

314314
public void testIncludeAndExclude() throws Exception {
@@ -1078,4 +1078,34 @@ public void testSqlProcessorWildcardType() throws Exception {
10781078
assertMessage(Message.DOMA4439);
10791079
}
10801080

1081+
public void testOnlyDefaultMethodsExtends() throws Exception {
1082+
Class<?> target = OnlyDefaultMethodsExtendsDao.class;
1083+
DaoProcessor processor = new DaoProcessor();
1084+
addProcessor(processor);
1085+
addCompilationUnit(target);
1086+
compile();
1087+
assertGeneratedSource(target);
1088+
assertTrue(getCompiledResult());
1089+
}
1090+
1091+
public void testNotOnlyDefaultMethodsExtends() throws Exception {
1092+
Class<?> target = NotOnlyDefaultMethodsExtendsDao.class;
1093+
DaoProcessor processor = new DaoProcessor();
1094+
addProcessor(processor);
1095+
addCompilationUnit(target);
1096+
compile();
1097+
assertFalse(getCompiledResult());
1098+
assertMessage(Message.DOMA4440);
1099+
}
1100+
1101+
public void testMultiDaoExtends() throws Exception {
1102+
Class<?> target = MultiDaoExtendsDao.class;
1103+
DaoProcessor processor = new DaoProcessor();
1104+
addProcessor(processor);
1105+
addCompilationUnit(target);
1106+
compile();
1107+
assertFalse(getCompiledResult());
1108+
assertMessage(Message.DOMA4188);
1109+
}
1110+
10811111
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright 2004-2010 the Seasar Foundation and the Others.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13+
* either express or implied. See the License for the specific language
14+
* governing permissions and limitations under the License.
15+
*/
16+
package org.seasar.doma.internal.apt.dao;
17+
18+
import org.seasar.doma.Dao;
19+
20+
/**
21+
* @author nakamura
22+
*
23+
*/
24+
@Dao(config = MyConfig.class)
25+
public interface MultiDaoExtendsDao extends MyDao, MyDao2 {
26+
27+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright 2004-2010 the Seasar Foundation and the Others.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13+
* either express or implied. See the License for the specific language
14+
* governing permissions and limitations under the License.
15+
*/
16+
package org.seasar.doma.internal.apt.dao;
17+
18+
import org.seasar.doma.Dao;
19+
20+
/**
21+
* @author nakamura
22+
*
23+
*/
24+
@Dao(config = MyConfig.class)
25+
public interface MyDao {
26+
27+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright 2004-2010 the Seasar Foundation and the Others.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13+
* either express or implied. See the License for the specific language
14+
* governing permissions and limitations under the License.
15+
*/
16+
package org.seasar.doma.internal.apt.dao;
17+
18+
import org.seasar.doma.Dao;
19+
20+
/**
21+
* @author nakamura
22+
*
23+
*/
24+
@Dao(config = MyConfig.class)
25+
public interface MyDao2 {
26+
27+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright 2004-2010 the Seasar Foundation and the Others.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13+
* either express or implied. See the License for the specific language
14+
* governing permissions and limitations under the License.
15+
*/
16+
package org.seasar.doma.internal.apt.dao;
17+
18+
/**
19+
* @author nakamura
20+
*
21+
*/
22+
public interface NotOnlyDefaultMethodsChild<T>
23+
extends NotOnlyDefaultMethodsParent {
24+
25+
default void bbb() {
26+
}
27+
28+
default T ccc(T value) {
29+
return value;
30+
}
31+
32+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright 2004-2010 the Seasar Foundation and the Others.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13+
* either express or implied. See the License for the specific language
14+
* governing permissions and limitations under the License.
15+
*/
16+
package org.seasar.doma.internal.apt.dao;
17+
18+
import org.seasar.doma.Dao;
19+
20+
/**
21+
* @author nakamura
22+
*
23+
*/
24+
@Dao(config = MyConfig.class)
25+
public interface NotOnlyDefaultMethodsExtendsDao
26+
extends NotOnlyDefaultMethodsChild<String> {
27+
28+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright 2004-2010 the Seasar Foundation and the Others.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13+
* either express or implied. See the License for the specific language
14+
* governing permissions and limitations under the License.
15+
*/
16+
package org.seasar.doma.internal.apt.dao;
17+
18+
/**
19+
* @author nakamura
20+
*
21+
*/
22+
public interface NotOnlyDefaultMethodsParent {
23+
24+
void aaa();
25+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Copyright 2004-2010 the Seasar Foundation and the Others.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13+
* either express or implied. See the License for the specific language
14+
* governing permissions and limitations under the License.
15+
*/
16+
package org.seasar.doma.internal.apt.dao;
17+
18+
/**
19+
* @author nakamura
20+
*
21+
*/
22+
public interface OnlyDefaultMethods<T> {
23+
24+
default void aaa() {
25+
}
26+
27+
default T bbb(T value) {
28+
return value;
29+
}
30+
}

0 commit comments

Comments
 (0)