Skip to content

Commit 94f2b70

Browse files
authored
Merge pull request #159 from domaframework/nested-entity-class
エンティティクラスをネストした型として定義することをサポート
2 parents 00e684c + 5a35aca commit 94f2b70

18 files changed

+929
-18
lines changed

src/main/java/org/seasar/doma/internal/Constants.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ public final class Constants {
3939

4040
public static final String EXTERNAL_DOMAIN_METATYPE_ROOT_PACKAGE = "__";
4141

42-
public static final String BINARY_NAME_ENCLOSING_DELIMITER = "__";
42+
public static final String METATYPE_NAME_DELIMITER = "__";
43+
44+
public static final String BINARY_NAME_DELIMITER = "$";
4345

4446
}

src/main/java/org/seasar/doma/internal/Conventions.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,8 @@ public static String normalizeBinaryName(String binaryName) {
3838
base = packageName + ".";
3939
}
4040
return base
41-
+ enclosingNames
42-
.stream()
43-
.map(n -> n + Constants.BINARY_NAME_ENCLOSING_DELIMITER)
41+
+ enclosingNames.stream()
42+
.map(n -> n + Constants.METATYPE_NAME_DELIMITER)
4443
.collect(joining()) + simpleName;
4544
}
4645

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,8 @@ protected void validateEnclosingElement(Element element) {
136136
return;
137137
}
138138
String simpleName = typeElement.getSimpleName().toString();
139-
if (simpleName.contains("$")
140-
|| simpleName
141-
.contains(Constants.BINARY_NAME_ENCLOSING_DELIMITER)) {
139+
if (simpleName.contains(Constants.BINARY_NAME_DELIMITER)
140+
|| simpleName.contains(Constants.METATYPE_NAME_DELIMITER)) {
142141
throw new AptException(Message.DOMA4277, env, typeElement,
143142
new Object[] { typeElement.getQualifiedName() });
144143
}

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

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,23 @@
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;
3032
import javax.lang.model.element.AnnotationValue;
33+
import javax.lang.model.element.Element;
3134
import javax.lang.model.element.ElementKind;
3235
import javax.lang.model.element.ExecutableElement;
3336
import javax.lang.model.element.Modifier;
37+
import javax.lang.model.element.NestingKind;
3438
import javax.lang.model.element.TypeElement;
3539
import javax.lang.model.element.TypeParameterElement;
3640
import javax.lang.model.element.VariableElement;
@@ -45,6 +49,7 @@
4549
import org.seasar.doma.OriginalStates;
4650
import org.seasar.doma.ParameterName;
4751
import org.seasar.doma.Transient;
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;
@@ -210,14 +215,40 @@ protected void validateClass(TypeElement classElement, EntityMeta entityMeta) {
210215
entityMirror.getAnnotationMirror(),
211216
new Object[] { classElement.getQualifiedName() });
212217
}
213-
if (classElement.getNestingKind().isNested()) {
214-
throw new AptException(Message.DOMA4018, env, classElement,
215-
new Object[] { classElement.getQualifiedName() });
216-
}
217218
if (!classElement.getTypeParameters().isEmpty()) {
218219
throw new AptException(Message.DOMA4051, env, classElement,
219220
new Object[] { classElement.getQualifiedName() });
220221
}
222+
validateEnclosingElement(classElement);
223+
}
224+
225+
protected void validateEnclosingElement(Element element) {
226+
TypeElement typeElement = ElementUtil.toTypeElement(element, env);
227+
if (typeElement == null) {
228+
return;
229+
}
230+
String simpleName = typeElement.getSimpleName().toString();
231+
if (simpleName.contains(Constants.BINARY_NAME_DELIMITER)
232+
|| simpleName.contains(Constants.METATYPE_NAME_DELIMITER)) {
233+
throw new AptException(Message.DOMA4317, env, typeElement,
234+
new Object[] { typeElement.getQualifiedName() });
235+
}
236+
NestingKind nestingKind = typeElement.getNestingKind();
237+
if (nestingKind == NestingKind.TOP_LEVEL) {
238+
return;
239+
} else if (nestingKind == NestingKind.MEMBER) {
240+
Set<Modifier> modifiers = typeElement.getModifiers();
241+
if (modifiers.containsAll(Arrays.asList(Modifier.STATIC,
242+
Modifier.PUBLIC))) {
243+
validateEnclosingElement(typeElement.getEnclosingElement());
244+
} else {
245+
throw new AptException(Message.DOMA4315, env, typeElement,
246+
new Object[] { typeElement.getQualifiedName() });
247+
}
248+
} else {
249+
throw new AptException(Message.DOMA4316, env, typeElement,
250+
new Object[] { typeElement.getQualifiedName() });
251+
}
221252
}
222253

223254
protected void validateEntityListener(TypeElement classElement,

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,8 @@ protected void validateEnclosingElement(Element element) {
157157
return;
158158
}
159159
String simpleName = typeElement.getSimpleName().toString();
160-
if (simpleName.contains("$")
161-
|| simpleName
162-
.contains(Constants.BINARY_NAME_ENCLOSING_DELIMITER)) {
160+
if (simpleName.contains(Constants.BINARY_NAME_DELIMITER)
161+
|| simpleName.contains(Constants.METATYPE_NAME_DELIMITER)) {
163162
throw new AptException(Message.DOMA4280, env, typeElement,
164163
new Object[] { typeElement.getQualifiedName() });
165164
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,9 @@ public enum Message implements MessageResource {
450450
DOMA4307("永続プロパティの型[{0}]とコンストラクタパラメータの型[{1}]が[{2}]番目で一致しません。Kotlinでエンベッダブルクラスを定義する場合、永続プロパティとコンストラクタのパラメータの宣言順序は一致しなければいけません。継承している場合、コンストラクタパラメータの宣言順序は親クラスに定義されたプロパティ順でなければいけません。 at {3}"),
451451
DOMA4308("永続プロパティの型[{0}]とコンストラクタパラメータの型[{1}]が[{2}]番目で一致しません。Kotlinでエンティティクラスを定義する場合、永続プロパティとコンストラクタのパラメータの宣言順序は一致しなければいけません。継承している場合、コンストラクタパラメータの宣言順序は親クラスに定義されたプロパティ順でなければいけません。 at {3}"),
452452
DOMA4309("ファイルパス[{0}]の大文字小文字がファイルシステム上のパスと一致しません。ファイルシステム上のパスは\"{1}\"です。"),
453+
DOMA4315("型[{0}]がpublicかつstaticでありません。エンティティクラスもしくはエンティティクラスを囲む型はpublicかつstaticでなければいけません。"),
454+
DOMA4316("型[{0}]がローカルクラスもしくは無名クラスです。エンティティクラスもしくはエンティティクラスを囲む型はトップレベルもしくはメンバでなければいけません。"),
455+
DOMA4317("型[{0}]の単純名に\"$\"または\"__\"が含まれています。エンティティクラスもしくはエンティティクラスを囲む型はこれらの文字列を単純名に含んではいけません。"),
453456

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

src/test/java/org/seasar/doma/internal/apt/entity/EntityProcessorTest.java

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,57 @@ public void testVersionDuplicated() throws Exception {
7474
}
7575

7676
public void testNotTopLevel() throws Exception {
77-
Class<?> target = NotTopLevelEntity.class;
7877
EntityProcessor processor = new EntityProcessor();
7978
addProcessor(processor);
80-
addCompilationUnit(target);
79+
addCompilationUnit(NotTopLevelEntity.class);
80+
compile();
81+
assertGeneratedSource(NotTopLevelEntity.Hoge.class);
82+
assertTrue(getCompiledResult());
83+
}
84+
85+
public void testNotTopLevelImmutable() throws Exception {
86+
EntityProcessor processor = new EntityProcessor();
87+
addProcessor(processor);
88+
addCompilationUnit(NotTopLevelImmutableEntity.class);
89+
compile();
90+
assertGeneratedSource(NotTopLevelImmutableEntity.Hoge.class);
91+
assertTrue(getCompiledResult());
92+
}
93+
94+
public void testOuter_nonStatic() throws Exception {
95+
EntityProcessor processor = new EntityProcessor();
96+
addProcessor(processor);
97+
addCompilationUnit(Outer_nonStaticInner.class);
98+
compile();
99+
assertFalse(getCompiledResult());
100+
assertMessage(Message.DOMA4315);
101+
}
102+
103+
public void testOuter_nonPublic() throws Exception {
104+
EntityProcessor processor = new EntityProcessor();
105+
addProcessor(processor);
106+
addCompilationUnit(Outer_nonPublicInner.class);
107+
compile();
108+
assertFalse(getCompiledResult());
109+
assertMessage(Message.DOMA4315);
110+
}
111+
112+
public void testOuter_nonPublicMiddle() throws Exception {
113+
EntityProcessor processor = new EntityProcessor();
114+
addProcessor(processor);
115+
addCompilationUnit(Outer_nonPublicMiddle.class);
116+
compile();
117+
assertFalse(getCompiledResult());
118+
assertMessage(Message.DOMA4315);
119+
}
120+
121+
public void testOuter__illegalName() throws Exception {
122+
EntityProcessor processor = new EntityProcessor();
123+
addProcessor(processor);
124+
addCompilationUnit(Outer__illegalName.class);
81125
compile();
82126
assertFalse(getCompiledResult());
83-
assertMessage(Message.DOMA4018);
127+
assertMessage(Message.DOMA4317);
84128
}
85129

86130
public void testUnsupportedProperty() throws Exception {

src/test/java/org/seasar/doma/internal/apt/entity/NotTopLevelEntity.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,6 @@
2424
public class NotTopLevelEntity {
2525

2626
@Entity
27-
class Hoge {
27+
public static class Hoge {
2828
}
2929
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
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.entity;
17+
18+
import org.seasar.doma.Entity;
19+
20+
/**
21+
* @author taedium
22+
*
23+
*/
24+
public class NotTopLevelImmutableEntity {
25+
26+
@Entity(immutable = true)
27+
public static class Hoge {
28+
public final String name;
29+
30+
public Hoge(String name) {
31+
this.name = name;
32+
}
33+
}
34+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
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.entity;
17+
18+
import org.seasar.doma.Entity;
19+
20+
/**
21+
* @author nakamura-to
22+
*
23+
*/
24+
public class Outer__illegalName {
25+
26+
@Entity
27+
public static class Inner {
28+
}
29+
}

0 commit comments

Comments
 (0)