Skip to content

Commit 5365ae7

Browse files
ChengyuanZhaobalopat
authored andcommitted
Spanner entity and property classes (spring-attic#340) (spring-attic#404)
* Initial commit for Spanner template dependencies * Added unit tests * formatting fixes * javadoc fix * added unit tests, addressed comments * Style changes, comments * added more extensive Javadocs and followed Spring Data JPA naming for classes * Renamed package and annotations * fixed package name * added annotation javadoc
1 parent 91005b7 commit 5365ae7

File tree

13 files changed

+707
-0
lines changed

13 files changed

+707
-0
lines changed

pom.xml

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
<module>spring-cloud-gcp-samples</module>
3636
<module>spring-cloud-gcp-autoconfigure</module>
3737
<module>spring-cloud-gcp-pubsub-stream-binder</module>
38+
<module>spring-cloud-gcp-data-spanner</module>
3839
</modules>
3940

4041
<properties>

spring-cloud-gcp-data-spanner/pom.xml

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xmlns="http://maven.apache.org/POM/4.0.0"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
6+
<modelVersion>4.0.0</modelVersion>
7+
<parent>
8+
<artifactId>spring-cloud-gcp</artifactId>
9+
<groupId>org.springframework.cloud</groupId>
10+
<version>1.0.0.BUILD-SNAPSHOT</version>
11+
</parent>
12+
<groupId>org.springframework.data</groupId>
13+
<artifactId>spring-cloud-gcp-data-spanner</artifactId>
14+
<name>Spring Cloud GCP Spanner Module</name>
15+
<description>Spring Cloud GCP Spanner Module</description>
16+
<properties>
17+
<main.basedir>${basedir}/../..</main.basedir>
18+
</properties>
19+
20+
<dependencies>
21+
<dependency>
22+
<groupId>com.google.cloud</groupId>
23+
<artifactId>google-cloud-spanner</artifactId>
24+
</dependency>
25+
<dependency>
26+
<groupId>org.springframework.data</groupId>
27+
<artifactId>spring-data-commons</artifactId>
28+
</dependency>
29+
<dependency>
30+
<groupId>org.springframework</groupId>
31+
<artifactId>spring-context</artifactId>
32+
</dependency>
33+
<dependency>
34+
<groupId>org.springframework</groupId>
35+
<artifactId>spring-core</artifactId>
36+
</dependency>
37+
</dependencies>
38+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright 2018 original author or authors.
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, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.cloud.gcp.data.spanner.core.mapping;
18+
19+
import java.lang.annotation.Documented;
20+
import java.lang.annotation.ElementType;
21+
import java.lang.annotation.Retention;
22+
import java.lang.annotation.RetentionPolicy;
23+
import java.lang.annotation.Target;
24+
25+
/**
26+
* Annotation for a {@link SpannerPersistentProperty} that allows specifying the column name
27+
* instead of deriving it from the field's name.
28+
*
29+
* @author Ray Tsang
30+
* @author Chengyuan Zhao
31+
*/
32+
@Documented
33+
@Target(ElementType.FIELD)
34+
@Retention(RetentionPolicy.RUNTIME)
35+
public @interface SpannerColumn {
36+
37+
/**
38+
* The custom name of the column in the Spanner table, which can differ from the name of the
39+
* field which it annotates.
40+
* @return the name of the column in the Spanner table
41+
*/
42+
String name();
43+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Copyright 2018 original author or authors.
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, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.cloud.gcp.data.spanner.core.mapping;
18+
19+
import org.springframework.data.mapping.context.AbstractMappingContext;
20+
import org.springframework.data.mapping.model.FieldNamingStrategy;
21+
import org.springframework.data.mapping.model.Property;
22+
import org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy;
23+
import org.springframework.data.mapping.model.SimpleTypeHolder;
24+
import org.springframework.data.util.TypeInformation;
25+
26+
/**
27+
* A mapping context for Google Spanner that provides ways to create persistent entities and properties.
28+
*
29+
* @author Ray Tsang
30+
* @author Chengyuan Zhao
31+
*/
32+
public class SpannerMappingContext extends
33+
AbstractMappingContext<SpannerPersistentEntity<?>, SpannerPersistentProperty> {
34+
35+
private static final FieldNamingStrategy DEFAULT_NAMING_STRATEGY = PropertyNameFieldNamingStrategy.INSTANCE;
36+
37+
private FieldNamingStrategy fieldNamingStrategy = DEFAULT_NAMING_STRATEGY;
38+
39+
public SpannerMappingContext() {
40+
41+
}
42+
43+
/**
44+
* Set the field naming strategy used when creating persistent properties.
45+
* @param fieldNamingStrategy the field naming strategy passed used by created persistent
46+
* properties get column names.
47+
*/
48+
public void setFieldNamingStrategy(FieldNamingStrategy fieldNamingStrategy) {
49+
this.fieldNamingStrategy = fieldNamingStrategy == null ? DEFAULT_NAMING_STRATEGY
50+
: fieldNamingStrategy;
51+
}
52+
53+
/**
54+
* Gets the field naming strategy used by this mapping context.
55+
* @return
56+
*/
57+
public FieldNamingStrategy getFieldNamingStrategy() {
58+
return this.fieldNamingStrategy;
59+
}
60+
61+
@Override
62+
protected <T> SpannerPersistentEntity<T> createPersistentEntity(
63+
TypeInformation<T> typeInformation) {
64+
return new SpannerPersistentEntityImpl<>(typeInformation);
65+
}
66+
67+
@Override
68+
protected SpannerPersistentProperty createPersistentProperty(Property property,
69+
SpannerPersistentEntity<?> owner, SimpleTypeHolder simpleTypeHolder) {
70+
return new SpannerPersistentPropertyImpl(property, owner, simpleTypeHolder,
71+
this.fieldNamingStrategy);
72+
}
73+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright 2018 original author or authors.
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, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.cloud.gcp.data.spanner.core.mapping;
18+
19+
import org.springframework.data.mapping.model.MutablePersistentEntity;
20+
21+
/**
22+
* Spanner specific interface for a {@link MutablePersistentEntity} stored
23+
* in a Google Spanner table.
24+
*
25+
* @author Ray Tsang
26+
* @author Chengyuan Zhao
27+
*/
28+
public interface SpannerPersistentEntity<T>
29+
extends MutablePersistentEntity<T, SpannerPersistentProperty> {
30+
31+
/**
32+
* Gets the name of the Spanner table.
33+
* @return the name of the table.
34+
*/
35+
String tableName();
36+
37+
/**
38+
* Gets the property corresponding to the given column name.
39+
* @param columnName the name of the column corresponding to a stored property.
40+
* @return the property.
41+
*/
42+
SpannerPersistentProperty getPersistentPropertyByColumnName(String columnName);
43+
44+
/**
45+
* Gets the column names stored for this entity.
46+
* @return the column names.
47+
*/
48+
Iterable<String> columns();
49+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* Copyright 2018 original author or authors.
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, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.cloud.gcp.data.spanner.core.mapping;
18+
19+
import java.util.Collections;
20+
import java.util.HashMap;
21+
import java.util.HashSet;
22+
import java.util.Map;
23+
import java.util.Set;
24+
25+
import org.springframework.data.mapping.model.BasicPersistentEntity;
26+
import org.springframework.data.util.TypeInformation;
27+
import org.springframework.util.StringUtils;
28+
29+
/**
30+
* Represents a Google Spanner table and its columns' mapping to fields within an entity type.
31+
*
32+
* @author Ray Tsang
33+
* @author Chengyuan Zhao
34+
*/
35+
public class SpannerPersistentEntityImpl<T>
36+
extends BasicPersistentEntity<T, SpannerPersistentProperty>
37+
implements SpannerPersistentEntity<T> {
38+
39+
private final String tableName;
40+
41+
private final Set<String> columnNames = new HashSet<>();
42+
43+
private final Map<String, String> columnNameToPropertyName = new HashMap<>();
44+
45+
/**
46+
* Creates a {@link SpannerPersistentEntityImpl}
47+
* @param information type information about the underlying entity type.
48+
*/
49+
public SpannerPersistentEntityImpl(TypeInformation<T> information) {
50+
super(information);
51+
52+
Class<?> rawType = information.getType();
53+
String fallback = StringUtils.uncapitalize(rawType.getSimpleName());
54+
55+
SpannerTable table = this.findAnnotation(SpannerTable.class);
56+
this.tableName = table != null && StringUtils.hasText(table.name()) ? table.name() : fallback;
57+
}
58+
59+
@Override
60+
public void addPersistentProperty(SpannerPersistentProperty property) {
61+
addPersistentPropertyToPersistentEntity(property);
62+
this.columnNames.add(property.getColumnName());
63+
this.columnNameToPropertyName.put(property.getColumnName(), property.getName());
64+
}
65+
66+
private void addPersistentPropertyToPersistentEntity(SpannerPersistentProperty property) {
67+
super.addPersistentProperty(property);
68+
}
69+
70+
@Override
71+
public String tableName() {
72+
return this.tableName;
73+
}
74+
75+
@Override
76+
public SpannerPersistentProperty getPersistentPropertyByColumnName(
77+
String columnName) {
78+
return getPersistentProperty(this.columnNameToPropertyName.get(columnName));
79+
}
80+
81+
@Override
82+
public Iterable<String> columns() {
83+
return Collections.unmodifiableSet(this.columnNames);
84+
}
85+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright 2018 original author or authors.
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, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.cloud.gcp.data.spanner.core.mapping;
18+
19+
import org.springframework.data.mapping.PersistentProperty;
20+
21+
/**
22+
* Interface for a {@link PersistentProperty} of a {@link SpannerPersistentEntity}
23+
* to be stored in a Google Spanner table.
24+
*
25+
* @author Ray Tsang
26+
* @author Chengyuan Zhao
27+
*/
28+
public interface SpannerPersistentProperty
29+
extends PersistentProperty<SpannerPersistentProperty> {
30+
31+
/**
32+
* Gets the name of the column in the Google Spanner table mapped to this property.
33+
*
34+
* @return the name of the column.
35+
*/
36+
String getColumnName();
37+
}

0 commit comments

Comments
 (0)