Skip to content

Commit 406f711

Browse files
committed
Added conditional builder methods
Also polished the javadocs as the APIs have become firm (2613)
1 parent 311aa95 commit 406f711

2 files changed

Lines changed: 186 additions & 9 deletions

File tree

springfox-core/src/main/java/springfox/documentation/builders/CompoundModelSpecificationBuilder.java

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package springfox.documentation.builders;
22

3+
import org.springframework.lang.NonNull;
4+
import org.springframework.lang.NonNullApi;
35
import springfox.documentation.schema.CompoundModelSpecification;
46
import springfox.documentation.schema.ModelKeyBuilder;
57
import springfox.documentation.schema.PropertySpecification;
@@ -26,26 +28,66 @@ private PropertySpecificationBuilder propertyBuilder(String name) {
2628
return properties.computeIfAbsent(name, PropertySpecificationBuilder::new);
2729
}
2830

29-
public Function<Consumer<PropertySpecificationBuilder>, CompoundModelSpecificationBuilder> property(String name) {
31+
/**
32+
* Provides method to create a property with given name
33+
* @param name - name of the property to create
34+
* @return returns a function that that provides a consumer for building a property
35+
*/
36+
public Function<Consumer<PropertySpecificationBuilder>, CompoundModelSpecificationBuilder> property(
37+
@NonNull String name) {
3038
return property -> {
3139
property.accept(propertyBuilder(name));
3240
return this;
3341
};
3442
}
43+
44+
/**
45+
* Provides method to maybe create a property with given name. If the property doesnt exist the consumer is a no-op.
46+
* Whatever we build downstream when the property doesnt exist is thrown away.
47+
* @param name - name of the property to create
48+
* @return returns a function that that provides a consumer for building a property
49+
*/
50+
public Function<Consumer<PropertySpecificationBuilder>, CompoundModelSpecificationBuilder> propertyIfExists(
51+
@NonNull String name) {
52+
return property -> {
53+
if (properties.containsKey(name)) {
54+
property.accept(propertyBuilder(name));
55+
} else {
56+
PropertySpecificationBuilder throwAwayBuilder = new PropertySpecificationBuilder(name);
57+
property.accept(throwAwayBuilder);
58+
}
59+
return this;
60+
};
61+
}
3562

36-
public CompoundModelSpecificationBuilder modelKey(Consumer<ModelKeyBuilder> consumer) {
63+
/**
64+
* Provides a fluent builder consumer for building a model key
65+
* @param consumer - builder consumer
66+
* @return this
67+
*/
68+
public CompoundModelSpecificationBuilder modelKey(@NonNull Consumer<ModelKeyBuilder> consumer) {
3769
if (modelKey == null) {
3870
this.modelKey = new ModelKeyBuilder();
3971
}
4072
consumer.accept(modelKey);
4173
return this;
4274
}
4375

76+
/**
77+
* Provides override for the max properties. It uses the number of actual properties when not provided.
78+
* @param maxProperties - maximum properties that need to be set
79+
* @return this
80+
*/
4481
public CompoundModelSpecificationBuilder maxProperties(Integer maxProperties) {
4582
this.maxProperties = maxProperties;
4683
return this;
4784
}
4885

86+
/**
87+
* Provides override for the min properties. It uses the number of actual properties when not provided.
88+
* @param minProperties - minimum properties that need to be set
89+
* @return this
90+
*/
4991
public CompoundModelSpecificationBuilder minProperties(Integer minProperties) {
5092
this.minProperties = minProperties;
5193
return this;
@@ -54,19 +96,26 @@ public CompoundModelSpecificationBuilder minProperties(Integer minProperties) {
5496
public CompoundModelSpecification build() {
5597
List<PropertySpecification> properties = this.properties.values().stream()
5698
.map(PropertySpecificationBuilder::build)
99+
.filter(prop -> !prop.getHidden())
57100
.collect(Collectors.toList());
58101
if (modelKey != null) {
59102
return new CompoundModelSpecification(
60103
modelKey.build(),
61104
properties,
62-
maxProperties,
63-
minProperties,
105+
maxProperties == null ? properties.size() : maxProperties,
106+
minProperties == null ? properties.size() : minProperties,
64107
discriminator,
65108
subclassReferences);
66109
}
67110
return null;
68111
}
69112

113+
114+
/**
115+
* Copies from an existing model
116+
* @param other - other model to copy from
117+
* @return this
118+
*/
70119
public CompoundModelSpecificationBuilder copyOf(CompoundModelSpecification other) {
71120
if (other == null) {
72121
return this;
@@ -79,6 +128,11 @@ public CompoundModelSpecificationBuilder copyOf(CompoundModelSpecification other
79128
.subclassReferences(other.getSubclassReferences());
80129
}
81130

131+
/**
132+
* Copies existing set of properties
133+
* @param properties - properties to copy from
134+
* @return this
135+
*/
82136
public CompoundModelSpecificationBuilder properties(Collection<PropertySpecification> properties) {
83137
properties.forEach(each -> this.property(each.getName())
84138
.apply(p -> {
@@ -103,11 +157,21 @@ public CompoundModelSpecificationBuilder properties(Collection<PropertySpecifica
103157
return this;
104158
}
105159

160+
/**
161+
* Inheritance discriminator
162+
* @param discriminator - property to discriminate on
163+
* @return this
164+
*/
106165
public CompoundModelSpecificationBuilder discriminator(String discriminator) {
107166
this.discriminator = discriminator;
108167
return this;
109168
}
110169

170+
/**
171+
* References to subclasses
172+
* @param subclassReferences - the reference specifications of subclasses
173+
* @return this
174+
*/
111175
public CompoundModelSpecificationBuilder subclassReferences(
112176
Collection<ReferenceModelSpecification> subclassReferences) {
113177
this.subclassReferences.addAll(subclassReferences);

springfox-core/src/main/java/springfox/documentation/builders/ModelSpecificationBuilder.java

Lines changed: 118 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package springfox.documentation.builders;
22

33
import org.springframework.lang.NonNull;
4+
import org.springframework.lang.Nullable;
5+
import springfox.documentation.annotations.Incubating;
46
import springfox.documentation.schema.CollectionSpecification;
57
import springfox.documentation.schema.CompoundModelSpecification;
68
import springfox.documentation.schema.MapSpecification;
@@ -15,6 +17,7 @@
1517
import java.util.function.Consumer;
1618
import java.util.stream.Stream;
1719

20+
import static springfox.documentation.builders.BuilderDefaults.*;
1821
import static springfox.documentation.builders.NoopValidator.*;
1922

2023
public class ModelSpecificationBuilder {
@@ -27,11 +30,21 @@ public class ModelSpecificationBuilder {
2730
private CompoundModelSpecificationBuilder compoundModelBuilder;
2831
private final Validator<ModelSpecificationBuilder> validator = this::validateSpecification;
2932

30-
public ModelSpecificationBuilder name(String name) {
31-
this.name = name;
33+
/**
34+
* Updates the name of the model
35+
* @param name - Name of the model
36+
* @return this
37+
*/
38+
public ModelSpecificationBuilder name(@NonNull String name) {
39+
this.name = defaultIfAbsent(name, this.name);
3240
return this;
3341
}
3442

43+
/**
44+
* Provides a consumer to build facets
45+
* @param facets - consumer that facilitates building a facet
46+
* @return this
47+
*/
3548
public ModelSpecificationBuilder facets(@NonNull Consumer<ModelFacetsBuilder> facets) {
3649
if (facetsBuilder == null) {
3750
facetsBuilder = new ModelFacetsBuilder();
@@ -40,6 +53,11 @@ public ModelSpecificationBuilder facets(@NonNull Consumer<ModelFacetsBuilder> fa
4053
return this;
4154
}
4255

56+
/**
57+
* Updates the scalar type
58+
* @param type - scalar type
59+
* @return this
60+
*/
4361
public ModelSpecificationBuilder scalarModel(ScalarType type) {
4462
if (type != null) {
4563
this.scalar = new ScalarModelSpecification(type);
@@ -54,37 +72,121 @@ private CompoundModelSpecificationBuilder compoundModelBuilder() {
5472
return compoundModelBuilder;
5573
}
5674

75+
/**
76+
* Provides a consumer to help building a compound model
77+
* @param compound - consumer that facilitates building a compound model
78+
* @return this
79+
*/
5780
public ModelSpecificationBuilder compoundModel(@NonNull Consumer<CompoundModelSpecificationBuilder> compound) {
5881
compound.accept(compoundModelBuilder());
5982
return this;
6083
}
6184

85+
/**
86+
* Provides a consumer to help build a compound model if one already exists. If the model is a different type,
87+
* then any operations done with the help of the consumer will be a no-op
88+
* @param compound consumer that facilitates building a compound model
89+
* @return this
90+
*/
91+
public ModelSpecificationBuilder compoundModelIfExists(
92+
@NonNull Consumer<CompoundModelSpecificationBuilder> compound) {
93+
if (compoundModelBuilder != null) {
94+
compound.accept(compoundModelBuilder);
95+
} else {
96+
CompoundModelSpecificationBuilder throwAwayBuilder = new CompoundModelSpecificationBuilder();
97+
compound.accept(throwAwayBuilder);
98+
}
99+
return this;
100+
}
101+
102+
/**
103+
* Provides a consumer to build the collection model
104+
* @param consumer consumer that facilitates building a collection
105+
* @return this
106+
*/
62107
public ModelSpecificationBuilder collectionModel(@NonNull Consumer<CollectionSpecificationBuilder> consumer) {
63108
consumer.accept(collectionBuilder());
64109
return this;
65110
}
66111

112+
/**
113+
* Conditionally provides a consumer to build the colleciton model. If the model is a different type,
114+
* then any operations done with the help of the consumer will be a no-op
115+
* @param consumer consumer that facilitates building a collection
116+
* @return this
117+
*/
118+
public ModelSpecificationBuilder collectionModelIfExists(
119+
@NonNull Consumer<CollectionSpecificationBuilder> consumer) {
120+
if (collection != null) {
121+
consumer.accept(collection);
122+
} else {
123+
CollectionSpecificationBuilder throwAwayBuilder = new CollectionSpecificationBuilder();
124+
consumer.accept(throwAwayBuilder);
125+
}
126+
return this;
127+
}
128+
67129
private CollectionSpecificationBuilder collectionBuilder() {
68130
if (collection == null) {
69131
collection = new CollectionSpecificationBuilder();
70132
}
71133
return collection;
72134
}
73135

136+
/**
137+
* Provides a consumer to build the map model.
138+
* @param consumer consumer that facilitates building a map
139+
* @return this
140+
*/
74141
public ModelSpecificationBuilder mapModel(@NonNull Consumer<MapSpecificationBuilder> consumer) {
75142
consumer.accept(mapBuilder());
76143
return this;
77144
}
78145

146+
/**
147+
* Conditionally provides a consumer to build the map model.
148+
* @param consumer consumer that facilitates building a map
149+
* @return this
150+
*/
151+
public ModelSpecificationBuilder mapModelIfExists(@NonNull Consumer<MapSpecificationBuilder> consumer) {
152+
if (map != null) {
153+
consumer.accept(map);
154+
} else {
155+
MapSpecificationBuilder throwAwayBuilder = new MapSpecificationBuilder();
156+
consumer.accept(throwAwayBuilder);
157+
}
158+
return this;
159+
}
160+
79161
private MapSpecificationBuilder mapBuilder() {
80162
if (map == null) {
81163
map = new MapSpecificationBuilder();
82164
}
83165
return map;
84166
}
85167

86-
public ModelSpecificationBuilder referenceModel(Consumer<ReferenceModelSpecificationBuilder> modelKey) {
87-
modelKey.accept(referenceModelBuilder());
168+
/**
169+
* Provides a consumer to build the reference model.
170+
* @param consumer consumer that facilitates building a reference model
171+
* @return this
172+
*/
173+
public ModelSpecificationBuilder referenceModel(Consumer<ReferenceModelSpecificationBuilder> consumer) {
174+
consumer.accept(referenceModelBuilder());
175+
return this;
176+
}
177+
178+
/**
179+
* Provides a consumer to build the reference model.
180+
* @param consumer consumer that facilitates building a reference model
181+
* @return this
182+
*/
183+
public ModelSpecificationBuilder referenceModelIfExists(Consumer<ReferenceModelSpecificationBuilder> consumer) {
184+
if (referenceModel != null) {
185+
consumer.accept(referenceModel);
186+
} else {
187+
ReferenceModelSpecificationBuilder throwAwayBuilder = new ReferenceModelSpecificationBuilder();
188+
consumer.accept(throwAwayBuilder);
189+
}
88190
return this;
89191
}
90192

@@ -112,7 +214,12 @@ public ModelSpecification build() {
112214
referenceModel != null ? referenceModel.build() : null);
113215
}
114216

115-
public ModelSpecificationBuilder copyOf(ModelSpecification other) {
217+
/**
218+
* Copies from an other model
219+
* @param other the other model
220+
* @return this
221+
*/
222+
public ModelSpecificationBuilder copyOf(@Nullable ModelSpecification other) {
116223
if (other != null) {
117224
ScalarType scalar = other.getScalar()
118225
.map(ScalarModelSpecification::getType)
@@ -180,6 +287,12 @@ private Object safeReferenceBuild() {
180287
return referenceModel != null ? referenceModel.build() : null;
181288
}
182289

290+
/**
291+
* This is an experimental API. May be removed/modified
292+
* @param scalar - scalar to replace the models with
293+
* @return this
294+
*/
295+
@Incubating("3.0.0")
183296
public ModelSpecificationBuilder maybeConvertToScalar(ScalarType scalar) {
184297
scalarModel(scalar);
185298
if (compoundModelBuilder != null) {

0 commit comments

Comments
 (0)