Skip to content

Commit 9a18d5f

Browse files
authored
Merge pull request #264 from jeffgbutler/master
Refactoring towards full immutability
2 parents 2d1c71e + cdd2caa commit 9a18d5f

17 files changed

+421
-195
lines changed

src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java

+28-13
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package org.mybatis.dynamic.sql;
1717

18+
import java.util.ArrayList;
1819
import java.util.Collection;
1920
import java.util.Objects;
2021
import java.util.function.Function;
@@ -28,20 +29,11 @@ public abstract class AbstractListValueCondition<T, S extends AbstractListValueC
2829
protected final UnaryOperator<Stream<T>> valueStreamTransformer;
2930
protected final Callback emptyCallback;
3031

31-
protected AbstractListValueCondition(Collection<T> values) {
32-
this(values, UnaryOperator.identity(), () -> { });
33-
}
34-
35-
protected AbstractListValueCondition(Collection<T> values, UnaryOperator<Stream<T>> valueStreamTransformer) {
36-
this(values, valueStreamTransformer, () -> { });
37-
}
38-
39-
protected AbstractListValueCondition(Collection<T> values, UnaryOperator<Stream<T>> valueStreamTransformer,
40-
Callback emptyCallback) {
41-
this.valueStreamTransformer = Objects.requireNonNull(valueStreamTransformer);
42-
this.values = valueStreamTransformer.apply(Objects.requireNonNull(values).stream())
32+
protected AbstractListValueCondition(AbstractListConditionBuilder<T, ?> builder) {
33+
this.valueStreamTransformer = Objects.requireNonNull(builder.valueStreamTransformer);
34+
this.values = valueStreamTransformer.apply(builder.values.stream())
4335
.collect(Collectors.toList());
44-
this.emptyCallback = Objects.requireNonNull(emptyCallback);
36+
this.emptyCallback = Objects.requireNonNull(builder.emptyCallback);
4537
}
4638

4739
public final <R> Stream<R> mapValues(Function<T, R> mapper) {
@@ -66,4 +58,27 @@ public <R> R accept(ConditionVisitor<T, R> visitor) {
6658
public abstract S withListEmptyCallback(Callback callback);
6759

6860
public abstract String renderCondition(String columnName, Stream<String> placeholders);
61+
62+
public abstract static class AbstractListConditionBuilder<T, S extends AbstractListConditionBuilder<T,S>> {
63+
protected Collection<T> values = new ArrayList<>();
64+
protected UnaryOperator<Stream<T>> valueStreamTransformer = UnaryOperator.identity();
65+
protected Callback emptyCallback = () -> { };
66+
67+
public S withValues(Collection<T> values) {
68+
this.values.addAll(values);
69+
return getThis();
70+
}
71+
72+
public S withValueStreamTransformer(UnaryOperator<Stream<T>> valueStreamTransformer) {
73+
this.valueStreamTransformer = valueStreamTransformer;
74+
return getThis();
75+
}
76+
77+
public S withEmptyCallback(Callback emptyCallback) {
78+
this.emptyCallback = emptyCallback;
79+
return getThis();
80+
}
81+
82+
protected abstract S getThis();
83+
}
6984
}

src/main/java/org/mybatis/dynamic/sql/Constant.java

+7-4
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,16 @@
2222

2323
public class Constant<T> implements BindableColumn<T> {
2424

25-
private String alias;
25+
private final String alias;
2626
private final String value;
2727

2828
private Constant(String value) {
29+
this(value, null);
30+
}
31+
32+
private Constant(String value, String alias) {
2933
this.value = Objects.requireNonNull(value);
34+
this.alias = alias;
3035
}
3136

3237
@Override
@@ -41,9 +46,7 @@ public String renderWithTableAlias(TableAliasCalculator tableAliasCalculator) {
4146

4247
@Override
4348
public Constant<T> as(String alias) {
44-
Constant<T> copy = new Constant<>(value);
45-
copy.alias = alias;
46-
return copy;
49+
return new Constant<>(value, alias);
4750
}
4851

4952
public static <T> Constant<T> of(String value) {

src/main/java/org/mybatis/dynamic/sql/SqlColumn.java

+68-52
Original file line numberDiff line numberDiff line change
@@ -28,28 +28,21 @@ public class SqlColumn<T> implements BindableColumn<T>, SortSpecification {
2828
protected final String name;
2929
protected final SqlTable table;
3030
protected final JDBCType jdbcType;
31-
protected boolean isDescending = false;
32-
protected String alias;
33-
protected String typeHandler;
34-
protected RenderingStrategy renderingStrategy;
35-
protected ParameterTypeConverter<T, ?> parameterTypeConverter;
31+
protected final boolean isDescending;
32+
protected final String alias;
33+
protected final String typeHandler;
34+
protected final RenderingStrategy renderingStrategy;
35+
protected final ParameterTypeConverter<T, ?> parameterTypeConverter;
3636

37-
private SqlColumn(Builder builder) {
37+
private SqlColumn(Builder<T> builder) {
3838
name = Objects.requireNonNull(builder.name);
39-
jdbcType = builder.jdbcType;
4039
table = Objects.requireNonNull(builder.table);
40+
jdbcType = builder.jdbcType;
41+
isDescending = builder.isDescending;
42+
alias = builder.alias;
4143
typeHandler = builder.typeHandler;
42-
}
43-
44-
protected SqlColumn(SqlColumn<T> sqlColumn) {
45-
name = sqlColumn.name;
46-
table = sqlColumn.table;
47-
jdbcType = sqlColumn.jdbcType;
48-
isDescending = sqlColumn.isDescending;
49-
alias = sqlColumn.alias;
50-
typeHandler = sqlColumn.typeHandler;
51-
renderingStrategy = sqlColumn.renderingStrategy;
52-
parameterTypeConverter = sqlColumn.parameterTypeConverter;
44+
renderingStrategy = builder.renderingStrategy;
45+
parameterTypeConverter = builder.parameterTypeConverter;
5346
}
5447

5548
public String name() {
@@ -82,16 +75,14 @@ public Object convertParameterType(T value) {
8275

8376
@Override
8477
public SortSpecification descending() {
85-
SqlColumn<T> column = new SqlColumn<>(this);
86-
column.isDescending = true;
87-
return column;
78+
Builder<T> b = copy();
79+
return b.withDescending(true).build();
8880
}
8981

9082
@Override
9183
public SqlColumn<T> as(String alias) {
92-
SqlColumn<T> column = new SqlColumn<>(this);
93-
column.alias = alias;
94-
return column;
84+
Builder<T> b = copy();
85+
return b.withAlias(alias).build();
9586
}
9687

9788
@Override
@@ -118,23 +109,20 @@ public Optional<RenderingStrategy> renderingStrategy() {
118109

119110
@NotNull
120111
public <S> SqlColumn<S> withTypeHandler(String typeHandler) {
121-
SqlColumn<S> column = copy();
122-
column.typeHandler = typeHandler;
123-
return column;
112+
Builder<S> b = copy();
113+
return b.withTypeHandler(typeHandler).build();
124114
}
125115

126116
@NotNull
127117
public <S> SqlColumn<S> withRenderingStrategy(RenderingStrategy renderingStrategy) {
128-
SqlColumn<S> column = copy();
129-
column.renderingStrategy = renderingStrategy;
130-
return column;
118+
Builder<S> b = copy();
119+
return b.withRenderingStrategy(renderingStrategy).build();
131120
}
132121

133122
@NotNull
134123
public <S> SqlColumn<S> withParameterTypeConverter(ParameterTypeConverter<S, ?> parameterTypeConverter) {
135-
SqlColumn<S> column = copy();
136-
column.parameterTypeConverter = parameterTypeConverter;
137-
return column;
124+
Builder<S> b = copy();
125+
return b.withParameterTypeConverter(parameterTypeConverter).build();
138126
}
139127

140128
/**
@@ -147,58 +135,86 @@ public <S> SqlColumn<S> withParameterTypeConverter(ParameterTypeConverter<S, ?>
147135
* @return a new SqlColumn of type S (S is the same as T)
148136
*/
149137
@SuppressWarnings("unchecked")
150-
private <S> SqlColumn<S> copy() {
151-
return new SqlColumn<>((SqlColumn<S>) this);
138+
private <S> Builder<S> copy() {
139+
return new Builder<S>()
140+
.withName(this.name)
141+
.withTable(this.table)
142+
.withJdbcType(this.jdbcType)
143+
.withDescending(this.isDescending)
144+
.withAlias(this.alias)
145+
.withTypeHandler(this.typeHandler)
146+
.withRenderingStrategy((this.renderingStrategy))
147+
.withParameterTypeConverter((ParameterTypeConverter<S, ?>) this.parameterTypeConverter);
152148
}
153149

154150
private String applyTableAlias(String tableAlias) {
155151
return tableAlias + "." + name(); //$NON-NLS-1$
156152
}
157153

158154
public static <T> SqlColumn<T> of(String name, SqlTable table) {
159-
return SqlColumn.withName(name)
155+
return new Builder<T>().withName(name)
160156
.withTable(table)
161157
.build();
162158
}
163159

164160
public static <T> SqlColumn<T> of(String name, SqlTable table, JDBCType jdbcType) {
165-
return SqlColumn.withName(name)
161+
return new Builder<T>().withName(name)
166162
.withTable(table)
167163
.withJdbcType(jdbcType)
168164
.build();
169165
}
170166

171-
public static Builder withName(String name) {
172-
return new Builder().withName(name);
173-
}
167+
public static class Builder<T> {
168+
protected String name;
169+
protected SqlTable table;
170+
protected JDBCType jdbcType;
171+
protected boolean isDescending = false;
172+
protected String alias;
173+
protected String typeHandler;
174+
protected RenderingStrategy renderingStrategy;
175+
protected ParameterTypeConverter<T, ?> parameterTypeConverter;
174176

175-
public static class Builder {
176-
private SqlTable table;
177-
private String name;
178-
private JDBCType jdbcType;
179-
private String typeHandler;
177+
public Builder<T> withName(String name) {
178+
this.name = name;
179+
return this;
180+
}
180181

181-
public Builder withTable(SqlTable table) {
182+
public Builder<T> withTable(SqlTable table) {
182183
this.table = table;
183184
return this;
184185
}
185186

186-
public Builder withName(String name) {
187-
this.name = name;
187+
public Builder<T> withJdbcType(JDBCType jdbcType) {
188+
this.jdbcType = jdbcType;
188189
return this;
189190
}
190191

191-
public Builder withJdbcType(JDBCType jdbcType) {
192-
this.jdbcType = jdbcType;
192+
public Builder<T> withDescending(boolean isDescending) {
193+
this.isDescending = isDescending;
193194
return this;
194195
}
195196

196-
public Builder withTypeHandler(String typeHandler) {
197+
public Builder<T> withAlias(String alias) {
198+
this.alias = alias;
199+
return this;
200+
}
201+
202+
public Builder<T> withTypeHandler(String typeHandler) {
197203
this.typeHandler = typeHandler;
198204
return this;
199205
}
200206

201-
public <T> SqlColumn<T> build() {
207+
public Builder<T> withRenderingStrategy(RenderingStrategy renderingStrategy) {
208+
this.renderingStrategy = renderingStrategy;
209+
return this;
210+
}
211+
212+
public Builder<T> withParameterTypeConverter(ParameterTypeConverter<T, ?> parameterTypeConverter) {
213+
this.parameterTypeConverter = parameterTypeConverter;
214+
return this;
215+
}
216+
217+
public SqlColumn<T> build() {
202218
return new SqlColumn<>(this);
203219
}
204220
}

src/main/java/org/mybatis/dynamic/sql/StringConstant.java

+7-4
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,16 @@
2222

2323
public class StringConstant implements BindableColumn<String> {
2424

25-
private String alias;
25+
private final String alias;
2626
private final String value;
2727

2828
private StringConstant(String value) {
29+
this(value, null);
30+
}
31+
32+
private StringConstant(String value, String alias) {
2933
this.value = Objects.requireNonNull(value);
34+
this.alias = alias;
3035
}
3136

3237
@Override
@@ -41,9 +46,7 @@ public String renderWithTableAlias(TableAliasCalculator tableAliasCalculator) {
4146

4247
@Override
4348
public StringConstant as(String alias) {
44-
StringConstant copy = new StringConstant(value);
45-
copy.alias = alias;
46-
return copy;
49+
return new StringConstant(value, alias);
4750
}
4851

4952
public static StringConstant of(String value) {

src/main/java/org/mybatis/dynamic/sql/select/SimpleSortSpecification.java

+8-4
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,21 @@
2828
public class SimpleSortSpecification implements SortSpecification {
2929

3030
private final String name;
31-
private boolean isDescending;
31+
private final boolean isDescending;
3232

3333
private SimpleSortSpecification(String name) {
3434
this.name = Objects.requireNonNull(name);
35+
this.isDescending = false;
36+
}
37+
38+
private SimpleSortSpecification(String name, boolean isDescending) {
39+
this.name = Objects.requireNonNull(name);
40+
this.isDescending = isDescending;
3541
}
3642

3743
@Override
3844
public SortSpecification descending() {
39-
SimpleSortSpecification answer = new SimpleSortSpecification(name);
40-
answer.isDescending = true;
41-
return answer;
45+
return new SimpleSortSpecification(name, true);
4246
}
4347

4448
@Override

0 commit comments

Comments
 (0)