Skip to content

Commit 6726f66

Browse files
adutraolim7t
authored andcommitted
JAVA-1279: Mapper should exclude Groovy's "metaClass" property when looking for mapped properties (apache#737)
1 parent 404ff5a commit 6726f66

4 files changed

Lines changed: 120 additions & 3 deletions

File tree

changelog/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
## Changelog
22

3-
### 3.1.1
3+
### 3.1.1 (in progress)
44

55
- [bug] JAVA-1284: ClockFactory should check system property before attempting to load Native class.
66
- [bug] JAVA-1255: Allow nested UDTs to be used in Mapper.
@@ -22,6 +22,7 @@ Merged from 3.0.x:
2222
- [improvement] JAVA-1053: Add a metric for authentication errors
2323
- [improvement] JAVA-1263: Eliminate unnecessary memory copies in FrameCompressor implementations.
2424
- [improvement] JAVA-893: Make connection pool non-blocking
25+
- [bug] JAVA-1279: Mapper should exclude Groovy's "metaClass" property when looking for mapped properties
2526

2627

2728
### 3.1.0

driver-mapping/pom.xml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
<properties>
3232
<main.basedir>${project.parent.basedir}</main.basedir>
33+
<groovy.version>2.4.7</groovy.version>
3334
</properties>
3435

3536
<dependencies>
@@ -108,10 +109,36 @@
108109
<scope>test</scope>
109110
</dependency>
110111

112+
<dependency>
113+
<groupId>org.codehaus.groovy</groupId>
114+
<artifactId>groovy-all</artifactId>
115+
<version>${groovy.version}</version>
116+
<scope>test</scope>
117+
</dependency>
118+
111119
</dependencies>
112120

113121
<build>
114122
<plugins>
123+
<plugin>
124+
<groupId>org.codehaus.mojo</groupId>
125+
<artifactId>build-helper-maven-plugin</artifactId>
126+
<version>1.12</version>
127+
<executions>
128+
<execution>
129+
<id>add-source</id>
130+
<phase>generate-test-sources</phase>
131+
<goals>
132+
<goal>add-test-source</goal>
133+
</goals>
134+
<configuration>
135+
<sources>
136+
<source>${pom.basedir}/src/test/groovy</source>
137+
</sources>
138+
</configuration>
139+
</execution>
140+
</executions>
141+
</plugin>
115142
<plugin>
116143
<groupId>org.apache.felix</groupId>
117144
<artifactId>maven-bundle-plugin</artifactId>
@@ -140,6 +167,36 @@
140167
</supportedProjectTypes>
141168
</configuration>
142169
</plugin>
170+
<plugin>
171+
<groupId>org.codehaus.gmaven</groupId>
172+
<artifactId>gmaven-plugin</artifactId>
173+
<version>1.5</version>
174+
<extensions>true</extensions>
175+
<executions>
176+
<execution>
177+
<goals>
178+
<goal>testCompile</goal>
179+
</goals>
180+
<configuration>
181+
<sources>
182+
<fileset>
183+
<directory>${pom.basedir}/src/test/groovy</directory>
184+
<includes>
185+
<include>**/*.groovy</include>
186+
</includes>
187+
</fileset>
188+
</sources>
189+
</configuration>
190+
</execution>
191+
</executions>
192+
<dependencies>
193+
<dependency>
194+
<groupId>org.codehaus.groovy</groupId>
195+
<artifactId>groovy-all</artifactId>
196+
<version>${groovy.version}</version>
197+
</dependency>
198+
</dependencies>
199+
</plugin>
143200
</plugins>
144201
</build>
145202

driver-mapping/src/main/java/com/datastax/driver/mapping/ReflectionUtils.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package com.datastax.driver.mapping;
1717

1818
import com.google.common.base.Throwables;
19+
import com.google.common.collect.ImmutableSet;
1920

2021
import java.beans.BeanInfo;
2122
import java.beans.IntrospectionException;
@@ -25,12 +26,19 @@
2526
import java.lang.reflect.*;
2627
import java.util.HashMap;
2728
import java.util.Map;
29+
import java.util.Set;
2830

2931
/**
3032
* Utility methods related to reflection.
3133
*/
3234
class ReflectionUtils {
3335

36+
private static final Set<String> EXCLUDED_PROPERTIES = ImmutableSet.of(
37+
"class",
38+
// JAVA-1279: exclude Groovy's metaClass property
39+
"metaClass"
40+
);
41+
3442
static <T> T newInstance(Class<T> clazz) {
3543
Constructor<T> publicConstructor;
3644
try {
@@ -75,7 +83,7 @@ private static <T> Map<String, Field> scanFields(Class<T> baseClass) {
7583
HashMap<String, Field> fields = new HashMap<String, Field>();
7684
for (Class<?> clazz = baseClass; !clazz.equals(Object.class); clazz = clazz.getSuperclass()) {
7785
for (Field field : clazz.getDeclaredFields()) {
78-
if (field.getName().equals("class") || field.isSynthetic() || Modifier.isStatic(field.getModifiers()))
86+
if (field.isSynthetic() || Modifier.isStatic(field.getModifiers()) || isPropertyExcluded(field.getName()))
7987
continue;
8088
// never override a more specific field masking another one declared in a superclass
8189
if (!fields.containsKey(field.getName()))
@@ -94,13 +102,17 @@ private static <T> Map<String, PropertyDescriptor> scanProperties(Class<T> baseC
94102
}
95103
Map<String, PropertyDescriptor> properties = new HashMap<String, PropertyDescriptor>();
96104
for (PropertyDescriptor property : beanInfo.getPropertyDescriptors()) {
97-
if (property.getName().equals("class"))
105+
if (isPropertyExcluded(property.getName()))
98106
continue;
99107
properties.put(property.getName(), property);
100108
}
101109
return properties;
102110
}
103111

112+
private static boolean isPropertyExcluded(String name) {
113+
return EXCLUDED_PROPERTIES.contains(name);
114+
}
115+
104116
static Map<Class<? extends Annotation>, Annotation> scanPropertyAnnotations(Field field, PropertyDescriptor property) {
105117
Map<Class<? extends Annotation>, Annotation> annotations = new HashMap<Class<? extends Annotation>, Annotation>();
106118
// annotations on getters should have precedence over annotations on fields
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package com.datastax.driver.mapping
2+
3+
import com.datastax.driver.core.CCMTestsSupport
4+
import com.datastax.driver.mapping.annotations.Column
5+
import com.datastax.driver.mapping.annotations.PartitionKey
6+
import com.datastax.driver.mapping.annotations.Table
7+
import org.testng.annotations.Test
8+
9+
import static org.assertj.core.api.Assertions.assertThat
10+
11+
/**
12+
* A simple test to check that mapping a Groovy class works as expected.
13+
*
14+
* @jira_ticket JAVA-1279
15+
*/
16+
public class MapperGroovyTest extends CCMTestsSupport {
17+
18+
@Table(name = "users")
19+
static class User {
20+
21+
@PartitionKey
22+
@Column(name = "user_id")
23+
def UUID userId
24+
25+
def String name
26+
27+
}
28+
29+
@Override
30+
public void onTestContextInitialized() {
31+
execute("CREATE TABLE users (user_id uuid PRIMARY KEY, name text)")
32+
}
33+
34+
@Test(groups = "short")
35+
public void should_map_groovy_class() {
36+
def mapper = new MappingManager(session()).mapper(User)
37+
def user1 = new User()
38+
user1.userId = UUID.randomUUID()
39+
user1.name = "John Doe"
40+
mapper.save user1
41+
def user2 = mapper.get user1.userId
42+
assertThat(user2.userId).isEqualTo(user1.userId)
43+
assertThat(user2.name).isEqualTo(user1.name)
44+
}
45+
46+
}
47+

0 commit comments

Comments
 (0)