Skip to content

Commit 88dadda

Browse files
authored
Merge pull request #160 from domaframework/nested-embeddable-class
エンベッダブルクラスをネストした型として定義することをサポート
2 parents 94f2b70 + f4ae136 commit 88dadda

File tree

9 files changed

+358
-5
lines changed

9 files changed

+358
-5
lines changed

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

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,22 @@
1818
import static org.seasar.doma.internal.util.AssertionUtil.assertNotNull;
1919

2020
import java.util.ArrayList;
21+
import java.util.Arrays;
2122
import java.util.Collections;
2223
import java.util.HashMap;
2324
import java.util.Iterator;
2425
import java.util.LinkedList;
2526
import java.util.List;
2627
import java.util.Map;
28+
import java.util.Set;
2729

2830
import javax.annotation.processing.ProcessingEnvironment;
2931
import javax.lang.model.element.AnnotationMirror;
32+
import javax.lang.model.element.Element;
3033
import javax.lang.model.element.ElementKind;
3134
import javax.lang.model.element.ExecutableElement;
3235
import javax.lang.model.element.Modifier;
36+
import javax.lang.model.element.NestingKind;
3337
import javax.lang.model.element.TypeElement;
3438
import javax.lang.model.element.VariableElement;
3539
import javax.lang.model.type.DeclaredType;
@@ -45,11 +49,13 @@
4549
import org.seasar.doma.ParameterName;
4650
import org.seasar.doma.Transient;
4751
import org.seasar.doma.Version;
52+
import org.seasar.doma.internal.Constants;
4853
import org.seasar.doma.internal.apt.AptException;
4954
import org.seasar.doma.internal.apt.AptIllegalStateException;
5055
import org.seasar.doma.internal.apt.Notifier;
5156
import org.seasar.doma.internal.apt.Options;
5257
import org.seasar.doma.internal.apt.mirror.EmbeddableMirror;
58+
import org.seasar.doma.internal.apt.util.ElementUtil;
5359
import org.seasar.doma.internal.apt.util.TypeMirrorUtil;
5460
import org.seasar.doma.message.Message;
5561

@@ -95,14 +101,40 @@ protected void validateClass(TypeElement embeddableElement,
95101
embeddableMirror.getAnnotationMirror(),
96102
new Object[] { embeddableElement.getQualifiedName() });
97103
}
98-
if (embeddableElement.getNestingKind().isNested()) {
99-
throw new AptException(Message.DOMA4284, env, embeddableElement,
100-
new Object[] { embeddableElement.getQualifiedName() });
101-
}
102104
if (!embeddableElement.getTypeParameters().isEmpty()) {
103105
throw new AptException(Message.DOMA4285, env, embeddableElement,
104106
new Object[] { embeddableElement.getQualifiedName() });
105107
}
108+
validateEnclosingElement(embeddableElement);
109+
}
110+
111+
protected void validateEnclosingElement(Element element) {
112+
TypeElement typeElement = ElementUtil.toTypeElement(element, env);
113+
if (typeElement == null) {
114+
return;
115+
}
116+
String simpleName = typeElement.getSimpleName().toString();
117+
if (simpleName.contains(Constants.BINARY_NAME_DELIMITER)
118+
|| simpleName.contains(Constants.METATYPE_NAME_DELIMITER)) {
119+
throw new AptException(Message.DOMA4417, env, typeElement,
120+
new Object[] { typeElement.getQualifiedName() });
121+
}
122+
NestingKind nestingKind = typeElement.getNestingKind();
123+
if (nestingKind == NestingKind.TOP_LEVEL) {
124+
return;
125+
} else if (nestingKind == NestingKind.MEMBER) {
126+
Set<Modifier> modifiers = typeElement.getModifiers();
127+
if (modifiers.containsAll(Arrays.asList(Modifier.STATIC,
128+
Modifier.PUBLIC))) {
129+
validateEnclosingElement(typeElement.getEnclosingElement());
130+
} else {
131+
throw new AptException(Message.DOMA4415, env, typeElement,
132+
new Object[] { typeElement.getQualifiedName() });
133+
}
134+
} else {
135+
throw new AptException(Message.DOMA4416, env, typeElement,
136+
new Object[] { typeElement.getQualifiedName() });
137+
}
106138
}
107139

108140
protected void doFieldElements(TypeElement embeddableElement,

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,6 @@ public enum Message implements MessageResource {
425425
DOMA4281("イミュータブルなエンティティクラスではコンストラクタのパラメータの数と型と名前は永続対象フィールドに一致しなければいけません。 at {0}"),
426426
DOMA4282("Kotlinでイミュータブルなエンティティクラスを定義する場合、すべてのプロパティをコンストラクタで宣言しなければいけません。 at {0}"),
427427
DOMA4283("@Embeddableはクラス以外には注釈できません。 at {0}"),
428-
DOMA4284("エンベッダブルクラスはトップレベルでなければいけません。 at {0}"),
429428
DOMA4285("エンベッダブルクラスには型パラメータを定義できません。 at {0}"),
430429
DOMA4286("エンベッダブルクラスのフィールドには@OriginalStatesを注釈できません。 at {0}.{1}"),
431430
DOMA4288("アノテーション[{0}]とアノテーション[{1}]が競合しています。これらは同じフィールドに注釈できません。 at {2}.{3}"),
@@ -453,6 +452,9 @@ public enum Message implements MessageResource {
453452
DOMA4315("型[{0}]がpublicかつstaticでありません。エンティティクラスもしくはエンティティクラスを囲む型はpublicかつstaticでなければいけません。"),
454453
DOMA4316("型[{0}]がローカルクラスもしくは無名クラスです。エンティティクラスもしくはエンティティクラスを囲む型はトップレベルもしくはメンバでなければいけません。"),
455454
DOMA4317("型[{0}]の単純名に\"$\"または\"__\"が含まれています。エンティティクラスもしくはエンティティクラスを囲む型はこれらの文字列を単純名に含んではいけません。"),
455+
DOMA4415("型[{0}]がpublicかつstaticでありません。エンベッダブルクラスもしくはエンベッダブルクラスを囲む型はpublicかつstaticでなければいけません。"),
456+
DOMA4416("型[{0}]がローカルクラスもしくは無名クラスです。エンベッダブルクラスもしくはエンベッダブルクラスを囲む型はトップレベルもしくはメンバでなければいけません。"),
457+
DOMA4417("型[{0}]の単純名に\"$\"または\"__\"が含まれています。エンベッダブルクラスもしくはエンベッダブルクラスを囲む型はこれらの文字列を単純名に含んではいけません。"),
456458

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

src/test/java/org/seasar/doma/internal/apt/embeddable/EmbeddableProcessorTest.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import org.seasar.doma.internal.apt.AptTestCase;
1919
import org.seasar.doma.internal.apt.EmbeddableProcessor;
20+
import org.seasar.doma.message.Message;
2021

2122
/**
2223
* @author taedium
@@ -61,4 +62,49 @@ public void testAbstract() throws Exception {
6162
assertTrue(getCompiledResult());
6263
}
6364

65+
public void testNotTopLevel() throws Exception {
66+
EmbeddableProcessor processor = new EmbeddableProcessor();
67+
addProcessor(processor);
68+
addCompilationUnit(NotTopLevel.class);
69+
compile();
70+
assertGeneratedSource(NotTopLevel.Address.class);
71+
assertTrue(getCompiledResult());
72+
}
73+
74+
public void testOuter_nonStatic() throws Exception {
75+
EmbeddableProcessor processor = new EmbeddableProcessor();
76+
addProcessor(processor);
77+
addCompilationUnit(Outer_nonStaticInner.class);
78+
compile();
79+
assertFalse(getCompiledResult());
80+
assertMessage(Message.DOMA4415);
81+
}
82+
83+
public void testOuter_nonPublic() throws Exception {
84+
EmbeddableProcessor processor = new EmbeddableProcessor();
85+
addProcessor(processor);
86+
addCompilationUnit(Outer_nonPublicInner.class);
87+
compile();
88+
assertFalse(getCompiledResult());
89+
assertMessage(Message.DOMA4415);
90+
}
91+
92+
public void testOuter_nonPublicMiddle() throws Exception {
93+
EmbeddableProcessor processor = new EmbeddableProcessor();
94+
addProcessor(processor);
95+
addCompilationUnit(Outer_nonPublicMiddle.class);
96+
compile();
97+
assertFalse(getCompiledResult());
98+
assertMessage(Message.DOMA4415);
99+
}
100+
101+
public void testOuter__illegalName() throws Exception {
102+
EmbeddableProcessor processor = new EmbeddableProcessor();
103+
addProcessor(processor);
104+
addCompilationUnit(Outer__illegalName.class);
105+
compile();
106+
assertFalse(getCompiledResult());
107+
assertMessage(Message.DOMA4417);
108+
}
109+
64110
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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.embeddable;
17+
18+
import org.seasar.doma.Embeddable;
19+
20+
/**
21+
* @author nakamura-to
22+
*
23+
*/
24+
public class NotTopLevel {
25+
26+
@Embeddable
27+
public static class Address {
28+
29+
private final String city;
30+
31+
private final String street;
32+
33+
public Address(String city, String street) {
34+
this.city = city;
35+
this.street = street;
36+
}
37+
38+
public String getCity() {
39+
return city;
40+
}
41+
42+
public String getStreet() {
43+
return street;
44+
}
45+
}
46+
47+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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.embeddable;
17+
18+
import org.seasar.doma.Embeddable;
19+
20+
/**
21+
* @author nakamura-to
22+
*
23+
*/
24+
public class Outer__illegalName {
25+
26+
@Embeddable
27+
public static class Inner {
28+
29+
private final String city;
30+
31+
private final String street;
32+
33+
public Inner(String city, String street) {
34+
this.city = city;
35+
this.street = street;
36+
}
37+
38+
public String getCity() {
39+
return city;
40+
}
41+
42+
public String getStreet() {
43+
return street;
44+
}
45+
}
46+
47+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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.embeddable;
17+
18+
import org.seasar.doma.Embeddable;
19+
20+
/**
21+
* @author nakamura-to
22+
*
23+
*/
24+
public class Outer_nonPublicInner {
25+
26+
@Embeddable
27+
static class Inner {
28+
29+
private final String city;
30+
31+
private final String street;
32+
33+
public Inner(String city, String street) {
34+
this.city = city;
35+
this.street = street;
36+
}
37+
38+
public String getCity() {
39+
return city;
40+
}
41+
42+
public String getStreet() {
43+
return street;
44+
}
45+
}
46+
47+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
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.embeddable;
17+
18+
import org.seasar.doma.Embeddable;
19+
20+
/**
21+
* @author nakamura-to
22+
*
23+
*/
24+
public class Outer_nonPublicMiddle {
25+
26+
static class Middle {
27+
28+
@Embeddable
29+
public static class Inner {
30+
31+
private final String city;
32+
33+
private final String street;
34+
35+
public Inner(String city, String street) {
36+
this.city = city;
37+
this.street = street;
38+
}
39+
40+
public String getCity() {
41+
return city;
42+
}
43+
44+
public String getStreet() {
45+
return street;
46+
}
47+
}
48+
49+
}
50+
51+
}

0 commit comments

Comments
 (0)