Skip to content

Commit b2c56cf

Browse files
committed
Add SerializableDeepCopier, and it became the default deepcopier.
1 parent 4a11692 commit b2c56cf

File tree

10 files changed

+408
-3
lines changed

10 files changed

+408
-3
lines changed

pom.xml

+5
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,11 @@
7272
<artifactId>jackson-datatype-jsr310</artifactId>
7373
<version>${jackson.version}</version>
7474
</dependency>
75+
<dependency>
76+
<groupId>org.apache.commons</groupId>
77+
<artifactId>commons-lang3</artifactId>
78+
<version>3.9</version>
79+
</dependency>
7580
<dependency>
7681
<groupId>junit</groupId>
7782
<artifactId>junit</artifactId>

src/main/java/com/github/meixuesong/aggregatepersistence/AggregateFactory.java

+10-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
* @author meixuesong
2020
*/
2121
public class AggregateFactory {
22+
private static DeepCopier copier = new SerializableDeepCopier();
2223
/**
2324
* The factory method.
2425
*
@@ -27,6 +28,14 @@ public class AggregateFactory {
2728
* @return
2829
*/
2930
public static <R extends Versionable> Aggregate<R> createAggregate(R root) {
30-
return new Aggregate<R>(root, new JsonDeepCopier(), new JavaUtilDeepComparator());
31+
return new Aggregate<R>(root, copier, new JavaUtilDeepComparator());
32+
}
33+
34+
/**
35+
* set deep copier.
36+
* @param copier
37+
*/
38+
public static void setCopier(DeepCopier copier) {
39+
AggregateFactory.copier = copier;
3140
}
3241
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
3+
* the License. You may obtain a copy of the License at
4+
*
5+
* http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
8+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
9+
* specific language governing permissions and limitations under the License.
10+
*
11+
* Copyright 2012-2020 the original author or authors.
12+
*/
13+
14+
package com.github.meixuesong.aggregatepersistence;
15+
16+
import org.apache.commons.lang3.SerializationUtils;
17+
18+
import java.io.Serializable;
19+
20+
/**
21+
* This deepcopier use Apache common lang to clone object. Objects need to implement Serializable interface
22+
* Use this deepcopier if your entity has no default constructor and setter methods.
23+
* This deepcopier has been the default deepcopier since 1.1.0
24+
*
25+
* @author meixuesong
26+
*/
27+
public class SerializableDeepCopier implements DeepCopier{
28+
@Override
29+
public <T> T copy(T object) {
30+
if (object instanceof Serializable) {
31+
return (T) SerializationUtils.clone((Serializable) object);
32+
}
33+
34+
throw new IllegalArgumentException("It's not a serializable object.");
35+
}
36+
}

src/test/java/com/github/meixuesong/aggregatepersistence/AggregateTest.java

+33-1
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,34 @@
1414
package com.github.meixuesong.aggregatepersistence;
1515

1616

17+
import com.github.meixuesong.aggregatepersistence.complex_object.Contract;
18+
import com.github.meixuesong.aggregatepersistence.complex_object.ContractBuilder;
19+
import com.github.meixuesong.aggregatepersistence.complex_object.ContractStatus;
20+
import com.github.meixuesong.aggregatepersistence.complex_object.LoanCustomer;
21+
import com.github.meixuesong.aggregatepersistence.complex_object.RepaymentType;
22+
import org.junit.Before;
1723
import org.junit.Test;
1824

1925
import java.math.BigDecimal;
2026
import java.text.ParseException;
2127
import java.text.SimpleDateFormat;
2228
import java.time.LocalDate;
29+
import java.time.LocalDateTime;
2330
import java.util.Collection;
2431

2532
import static org.hamcrest.CoreMatchers.is;
33+
import static org.junit.Assert.assertEquals;
2634
import static org.junit.Assert.assertThat;
2735

2836
/**
2937
* @author meixuesong
3038
*/
3139
public class AggregateTest {
40+
@Before
41+
public void setUp() throws Exception {
42+
AggregateFactory.setCopier(new SerializableDeepCopier());
43+
}
44+
3245
@Test
3346
public void should_be_new_when_version_is_NEW_VERSION() {
3447
SampleEntity entity = new SampleEntity();
@@ -176,7 +189,26 @@ public void should_find_removed_child() {
176189
BigDecimal v = new BigDecimal("10.00");
177190
}
178191

179-
192+
@Test
193+
public void should_create_snapshot() {
194+
LocalDateTime now = LocalDateTime.now();
195+
Contract expectedContract = new ContractBuilder()
196+
.setId("ABCD")
197+
.setCreatedAt(now)
198+
.setRepaymentType(RepaymentType.DEBJ)
199+
.setStatus(ContractStatus.ACTIVE)
200+
.setCustomer(new LoanCustomer("", "", "123456200012319876", ""))
201+
.setInterestRate(BigDecimal.TEN)
202+
.setMaturityDate(now.plusYears(1).toLocalDate())
203+
.setCommitment(BigDecimal.valueOf(1000.00))
204+
.createContract();
205+
206+
Aggregate<Contract> aggregate = AggregateFactory.createAggregate(expectedContract);
207+
Contract actualContract = aggregate.getRootSnapshot();
208+
209+
assertEquals(expectedContract, actualContract);
210+
new JavaUtilDeepComparator().isDeepEquals(actualContract, expectedContract);
211+
}
180212

181213
private Collection<SampleEntity> getNewChildren(Aggregate<SampleEntity> aggregate) {
182214
return aggregate.findNewEntities(SampleEntity::getChildren, (item) -> item.getVersion() == Versionable.NEW_VERSION);

src/test/java/com/github/meixuesong/aggregatepersistence/SampleEntity.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
import lombok.Data;
1717

18+
import java.io.Serializable;
1819
import java.math.BigDecimal;
1920
import java.time.LocalDate;
2021
import java.util.ArrayList;
@@ -25,7 +26,7 @@
2526
* @author meixuesong
2627
*/
2728
@Data
28-
public class SampleEntity implements Versionable{
29+
public class SampleEntity implements Versionable, Serializable {
2930
private String id = "";
3031
private boolean checked = true;
3132
private int age = 0;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
3+
* the License. You may obtain a copy of the License at
4+
*
5+
* http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
8+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
9+
* specific language governing permissions and limitations under the License.
10+
*
11+
* Copyright 2012-2020 the original author or authors.
12+
*/
13+
14+
package com.github.meixuesong.aggregatepersistence.complex_object;
15+
16+
import com.github.meixuesong.aggregatepersistence.Versionable;
17+
18+
import java.io.Serializable;
19+
import java.math.BigDecimal;
20+
import java.time.LocalDate;
21+
import java.time.LocalDateTime;
22+
23+
public class Contract implements Versionable, Serializable {
24+
private String id;
25+
private LoanCustomer customer;
26+
private BigDecimal interestRate;
27+
private RepaymentType repaymentType;
28+
private LocalDate maturityDate;
29+
private BigDecimal commitment;
30+
private LocalDateTime createdAt;
31+
private ContractStatus status;
32+
private int version;
33+
34+
35+
Contract(String id, LoanCustomer customer, BigDecimal interestRate, RepaymentType repaymentType, LocalDate maturityDate, BigDecimal commitment, LocalDateTime createdAt, ContractStatus status) {
36+
this.id = id;
37+
this.customer = customer;
38+
this.interestRate = interestRate;
39+
this.repaymentType = repaymentType;
40+
this.maturityDate = maturityDate;
41+
this.commitment = commitment;
42+
this.createdAt = createdAt;
43+
this.status = status;
44+
}
45+
46+
public String getId() {
47+
return id;
48+
}
49+
50+
public LoanCustomer getCustomer() {
51+
return customer;
52+
}
53+
54+
public BigDecimal getInterestRate() {
55+
return interestRate;
56+
}
57+
58+
public RepaymentType getRepaymentType() {
59+
return repaymentType;
60+
}
61+
62+
public LocalDate getMaturityDate() {
63+
return maturityDate;
64+
}
65+
66+
public BigDecimal getCommitment() {
67+
return commitment;
68+
}
69+
70+
public LocalDateTime getCreatedAt() {
71+
return createdAt;
72+
}
73+
74+
public ContractStatus getStatus() {
75+
return status;
76+
}
77+
78+
public void setCommitment(BigDecimal commitment) {
79+
this.commitment = commitment;
80+
}
81+
82+
@Override
83+
public int getVersion() {
84+
return 0;
85+
}
86+
87+
public void setVersion(int version) {
88+
this.version = version;
89+
}
90+
91+
@Override
92+
public boolean equals(Object o) {
93+
if (this == o) return true;
94+
if (o == null || getClass() != o.getClass()) return false;
95+
96+
Contract contract = (Contract) o;
97+
98+
if (version != contract.version) return false;
99+
if (!id.equals(contract.id)) return false;
100+
if (!customer.equals(contract.customer)) return false;
101+
if (!interestRate.equals(contract.interestRate)) return false;
102+
if (repaymentType != contract.repaymentType) return false;
103+
if (!maturityDate.equals(contract.maturityDate)) return false;
104+
if (!commitment.equals(contract.commitment)) return false;
105+
if (!createdAt.equals(contract.createdAt)) return false;
106+
return status == contract.status;
107+
}
108+
109+
@Override
110+
public int hashCode() {
111+
int result = id.hashCode();
112+
result = 31 * result + customer.hashCode();
113+
result = 31 * result + interestRate.hashCode();
114+
result = 31 * result + repaymentType.hashCode();
115+
result = 31 * result + maturityDate.hashCode();
116+
result = 31 * result + commitment.hashCode();
117+
result = 31 * result + createdAt.hashCode();
118+
result = 31 * result + status.hashCode();
119+
result = 31 * result + version;
120+
return result;
121+
}
122+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
3+
* the License. You may obtain a copy of the License at
4+
*
5+
* http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
8+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
9+
* specific language governing permissions and limitations under the License.
10+
*
11+
* Copyright 2012-2020 the original author or authors.
12+
*/
13+
14+
package com.github.meixuesong.aggregatepersistence.complex_object;
15+
16+
import java.math.BigDecimal;
17+
import java.time.LocalDate;
18+
import java.time.LocalDateTime;
19+
20+
public class ContractBuilder {
21+
private String id;
22+
private LoanCustomer customer;
23+
private BigDecimal interestRate;
24+
private RepaymentType repaymentType;
25+
private LocalDate maturityDate;
26+
private BigDecimal commitment;
27+
private LocalDateTime createdAt = LocalDateTime.now();
28+
private ContractStatus status = ContractStatus.ACTIVE;
29+
30+
public ContractBuilder setId(String id) {
31+
this.id = id;
32+
return this;
33+
}
34+
35+
public ContractBuilder setCustomer(LoanCustomer customer) {
36+
this.customer = customer;
37+
return this;
38+
}
39+
40+
public ContractBuilder setInterestRate(BigDecimal interestRate) {
41+
this.interestRate = interestRate;
42+
return this;
43+
}
44+
45+
public ContractBuilder setRepaymentType(RepaymentType repaymentType) {
46+
this.repaymentType = repaymentType;
47+
return this;
48+
}
49+
50+
public ContractBuilder setMaturityDate(LocalDate maturityDate) {
51+
this.maturityDate = maturityDate;
52+
return this;
53+
}
54+
55+
public ContractBuilder setCommitment(BigDecimal commitment) {
56+
this.commitment = commitment;
57+
return this;
58+
}
59+
60+
public ContractBuilder setCreatedAt(LocalDateTime createdAt) {
61+
this.createdAt = createdAt;
62+
return this;
63+
}
64+
65+
public ContractBuilder setStatus(ContractStatus status) {
66+
this.status = status;
67+
return this;
68+
}
69+
70+
public Contract createContract() {
71+
return new Contract(id, customer, interestRate, repaymentType, maturityDate, commitment, createdAt, status);
72+
}
73+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
3+
* the License. You may obtain a copy of the License at
4+
*
5+
* http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
8+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
9+
* specific language governing permissions and limitations under the License.
10+
*
11+
* Copyright 2012-2020 the original author or authors.
12+
*/
13+
14+
package com.github.meixuesong.aggregatepersistence.complex_object;
15+
16+
public enum ContractStatus {
17+
PENDING("待审批"),
18+
ACTIVE("激活"),
19+
DEACTIVE("吊销");
20+
21+
final String displayName;
22+
23+
ContractStatus(String displayName) {
24+
this.displayName = displayName;
25+
}
26+
27+
public String getDisplayName() {
28+
return displayName;
29+
}
30+
}

0 commit comments

Comments
 (0)