Skip to content

Commit 9404a36

Browse files
committed
#87 - Make sure models are serializable
1 parent f25b10a commit 9404a36

34 files changed

+1126
-11
lines changed

hibernate-models-jandex/src/main/java/org/hibernate/models/jandex/internal/JandexAnnotationDescriptorRegistry.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package org.hibernate.models.jandex.internal;
66

77
import java.lang.annotation.Annotation;
8+
import java.util.Map;
89

910
import org.hibernate.models.internal.AnnotationDescriptorRegistryStandard;
1011
import org.hibernate.models.spi.AnnotationDescriptor;
@@ -24,4 +25,8 @@ protected <A extends Annotation> AnnotationDescriptor<A> buildAnnotationDescript
2425
AnnotationDescriptor<? extends Annotation> containerDescriptor) {
2526
return new JandexAnnotationDescriptorImpl<>( javaType, containerDescriptor, getModelBuildingContext() );
2627
}
28+
29+
public Map<Class<? extends Annotation>, AnnotationDescriptor<? extends Annotation>> getDescriptorMap() {
30+
return descriptorMap;
31+
}
2732
}

hibernate-models-jandex/src/main/java/org/hibernate/models/jandex/internal/JandexClassDetails.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
import java.util.List;
1010

1111
import org.hibernate.models.internal.ClassDetailsSupport;
12+
import org.hibernate.models.internal.jdk.SerialJdkClassDetails;
1213
import org.hibernate.models.internal.util.CollectionHelper;
14+
import org.hibernate.models.serial.spi.SerialClassDetails;
1315
import org.hibernate.models.spi.ClassDetails;
1416
import org.hibernate.models.spi.FieldDetails;
1517
import org.hibernate.models.spi.MethodDetails;
@@ -276,4 +278,9 @@ private static List<TypeVariableDetails> determineTypeParameters(ClassInfo class
276278
}
277279
return result;
278280
}
281+
282+
@Override
283+
public SerialClassDetails toStorableForm() {
284+
return new SerialJdkClassDetails( getName(), toJavaClass() );
285+
}
279286
}

hibernate-models-jandex/src/main/java/org/hibernate/models/jandex/internal/JandexClassDetailsRegistry.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
*/
55
package org.hibernate.models.jandex.internal;
66

7+
import java.util.Map;
8+
79
import org.hibernate.models.UnknownClassException;
810
import org.hibernate.models.internal.AbstractClassDetailsRegistry;
911
import org.hibernate.models.internal.jdk.JdkBuilders;
@@ -50,4 +52,8 @@ protected ClassDetails createClassDetails(String name) {
5052

5153
throw new UnknownClassException( "Unable to resolve ClassDetails for `" + name + "`" );
5254
}
55+
56+
protected Map<String, ClassDetails> getClassDetailsMap() {
57+
return classDetailsMap;
58+
}
5359
}

hibernate-models-jandex/src/main/java/org/hibernate/models/jandex/internal/JandexModelBuildingContextImpl.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
import org.hibernate.models.jandex.spi.JandexModelBuildingContext;
1414
import org.hibernate.models.jandex.spi.JandexValueConverter;
1515
import org.hibernate.models.jandex.spi.JandexValueExtractor;
16+
import org.hibernate.models.serial.internal.StorableContextImpl;
17+
import org.hibernate.models.serial.spi.StorableContext;
1618
import org.hibernate.models.spi.ClassLoading;
1719
import org.hibernate.models.spi.RegistryPrimer;
1820
import org.hibernate.models.spi.ValueTypeDescriptor;
@@ -22,6 +24,8 @@
2224
import static org.hibernate.models.internal.ModelsClassLogging.MODELS_CLASS_LOGGER;
2325

2426
/**
27+
* SourceModelBuildingContext implementation based on Jandex
28+
*
2529
* @author Steve Ebersole
2630
*/
2731
public class JandexModelBuildingContextImpl extends AbstractModelBuildingContext implements JandexModelBuildingContext {
@@ -96,4 +100,9 @@ public <V> JandexValueExtractor<V> getJandexValueExtractor(ValueTypeDescriptor<V
96100
this
97101
);
98102
}
103+
104+
@Override
105+
public StorableContext toStorableForm() {
106+
return new StorableContextImpl( classDetailsRegistry.getClassDetailsMap(), descriptorRegistry.getDescriptorMap() );
107+
}
99108
}
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright: Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.models.serialization;
6+
7+
import java.lang.annotation.ElementType;
8+
import java.lang.annotation.Retention;
9+
import java.lang.annotation.RetentionPolicy;
10+
import java.lang.annotation.Target;
11+
12+
import org.hibernate.models.SerializationHelper;
13+
import org.hibernate.models.SourceModelTestHelper;
14+
import org.hibernate.models.serial.spi.StorableContext;
15+
import org.hibernate.models.spi.ClassDetails;
16+
import org.hibernate.models.spi.SourceModelBuildingContext;
17+
import org.hibernate.models.spi.SourceModelContext;
18+
19+
import org.junit.jupiter.api.Test;
20+
21+
import static org.assertj.core.api.Assertions.assertThat;
22+
import static org.hibernate.models.internal.SimpleClassLoading.SIMPLE_CLASS_LOADING;
23+
24+
public class SimpleSerializationTests {
25+
protected SourceModelBuildingContext createModelContext(Class<?>... classes) {
26+
return SourceModelTestHelper.createBuildingContext( classes );
27+
}
28+
29+
@Test
30+
void serializeSimpleClass() {
31+
final SourceModelBuildingContext buildingContext = createModelContext( SimpleClass.class );
32+
33+
final ClassDetails classDetails = buildingContext.getClassDetailsRegistry().findClassDetails( SimpleClass.class.getName() );
34+
assertThat( classDetails ).isNotNull();
35+
36+
final StorableContext serialContext = buildingContext.toStorableForm();
37+
final StorableContext clonedSerialContext = SerializationHelper.clone( serialContext );
38+
assertThat( serialContext ).isNotSameAs( clonedSerialContext );
39+
40+
final SourceModelContext restored = clonedSerialContext.fromStorableForm( SIMPLE_CLASS_LOADING );
41+
assertThat( buildingContext ).isNotSameAs( restored );
42+
assertThat( buildingContext.getClassDetailsRegistry() ).isNotSameAs( restored.getClassDetailsRegistry() );
43+
assertThat( buildingContext.getAnnotationDescriptorRegistry() ).isNotSameAs( restored.getAnnotationDescriptorRegistry() );
44+
45+
final ClassDetails cloneCassDetails = restored.getClassDetailsRegistry().findClassDetails( SimpleClass.class.getName() );
46+
assertThat( cloneCassDetails ).isNotNull();
47+
assertThat( classDetails ).isNotSameAs( cloneCassDetails );
48+
}
49+
50+
@Test
51+
void serializeSimpleClassWithMembers() {
52+
final SourceModelBuildingContext buildingContext = createModelContext( SimpleClassWithMembers.class );
53+
54+
final ClassDetails classDetails = buildingContext.getClassDetailsRegistry().findClassDetails( SimpleClassWithMembers.class.getName() );
55+
assertThat( classDetails ).isNotNull();
56+
assertThat( classDetails.getFields() ).hasSize( 1 );
57+
assertThat( classDetails.getMethods() ).hasSize( 3 );
58+
59+
final StorableContext serialContext = buildingContext.toStorableForm();
60+
final StorableContext clonedSerialContext = SerializationHelper.clone( serialContext );
61+
assertThat( serialContext ).isNotSameAs( clonedSerialContext );
62+
63+
final SourceModelContext restored = clonedSerialContext.fromStorableForm( SIMPLE_CLASS_LOADING );
64+
assertThat( buildingContext ).isNotSameAs( restored );
65+
assertThat( buildingContext.getClassDetailsRegistry() ).isNotSameAs( restored.getClassDetailsRegistry() );
66+
assertThat( buildingContext.getAnnotationDescriptorRegistry() ).isNotSameAs( restored.getAnnotationDescriptorRegistry() );
67+
68+
final ClassDetails cloneCassDetails = restored.getClassDetailsRegistry().findClassDetails( SimpleClassWithMembers.class.getName() );
69+
assertThat( cloneCassDetails ).isNotNull();
70+
assertThat( classDetails ).isNotSameAs( cloneCassDetails );
71+
assertThat( cloneCassDetails.getFields() ).hasSize( 1 );
72+
assertThat( cloneCassDetails.getMethods() ).hasSize( 3 );
73+
}
74+
75+
@Test
76+
void serializeSimpleClassWithAnnotations() {
77+
final SourceModelBuildingContext buildingContext = createModelContext( SimpleClassWithAnnotations.class );
78+
79+
final ClassDetails classDetails = buildingContext.getClassDetailsRegistry().findClassDetails( SimpleClassWithAnnotations.class.getName() );
80+
assertThat( classDetails ).isNotNull();
81+
assertThat( classDetails.getDirectAnnotationUsages() ).hasSize( 1 );
82+
assertThat( classDetails.getFields() ).hasSize( 1 );
83+
assertThat( classDetails.getFields().iterator().next().getDirectAnnotationUsages() ).hasSize( 1 );
84+
assertThat( classDetails.getMethods() ).hasSize( 1 );
85+
assertThat( classDetails.getMethods().iterator().next().getDirectAnnotationUsages() ).hasSize( 1 );
86+
87+
final StorableContext serialContext = buildingContext.toStorableForm();
88+
final StorableContext clonedSerialContext = SerializationHelper.clone( serialContext );
89+
assertThat( serialContext ).isNotSameAs( clonedSerialContext );
90+
91+
final SourceModelContext restored = clonedSerialContext.fromStorableForm( SIMPLE_CLASS_LOADING );
92+
assertThat( restored ).isNotNull();
93+
assertThat( buildingContext ).isNotSameAs( restored );
94+
assertThat( buildingContext.getClassDetailsRegistry() ).isNotSameAs( restored.getClassDetailsRegistry() );
95+
assertThat( buildingContext.getAnnotationDescriptorRegistry() ).isNotSameAs( restored.getAnnotationDescriptorRegistry() );
96+
97+
final ClassDetails cloneCassDetails = restored.getClassDetailsRegistry().findClassDetails( SimpleClassWithAnnotations.class.getName() );
98+
assertThat( classDetails ).isNotSameAs( cloneCassDetails );
99+
assertThat( cloneCassDetails.getDirectAnnotationUsages() ).hasSize( 1 );
100+
assertThat( cloneCassDetails.getFields() ).hasSize( 1 );
101+
assertThat( cloneCassDetails.getFields().iterator().next().getDirectAnnotationUsages() ).hasSize( 1 );
102+
assertThat( cloneCassDetails.getMethods() ).hasSize( 1 );
103+
assertThat( cloneCassDetails.getMethods().iterator().next().getDirectAnnotationUsages() ).hasSize( 1 );
104+
105+
}
106+
107+
public static class SimpleClass {
108+
}
109+
110+
public static class SimpleClassWithMembers {
111+
public int anInt;
112+
113+
public int getAnInt() {
114+
return anInt;
115+
}
116+
117+
public void setAnInt(int anInt) {
118+
this.anInt = anInt;
119+
}
120+
121+
public void doStuff() {
122+
}
123+
}
124+
125+
@Target({ ElementType.FIELD,ElementType.METHOD,ElementType.TYPE})
126+
@Retention(RetentionPolicy.RUNTIME)
127+
public @interface AnAnnotation {
128+
}
129+
130+
@AnAnnotation
131+
public static class SimpleClassWithAnnotations {
132+
@AnAnnotation
133+
private int anInt;
134+
135+
@AnAnnotation
136+
public int getAnInt() {
137+
return anInt;
138+
}
139+
140+
}
141+
}

0 commit comments

Comments
 (0)