Skip to content

Commit 8f8fbe4

Browse files
Add builders as alternatives to factories when creating operation requests and responses
The intent of this change is to provide a better api to work with, dispensing repeated code from the factories Fixes spring-projectsgh-886
1 parent ca43a16 commit 8f8fbe4

File tree

2 files changed

+266
-0
lines changed

2 files changed

+266
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
/*
2+
* Copyright 2014-2022 the 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+
* https://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.restdocs.operation;
18+
19+
import java.net.URI;
20+
import java.util.Collection;
21+
import java.util.Collections;
22+
23+
import org.springframework.http.HttpHeaders;
24+
import org.springframework.http.HttpMethod;
25+
26+
/**
27+
* A builder for creating {@link OperationRequest OperationRequests}.
28+
*
29+
* @author Augusto Ravazoli
30+
*/
31+
public class OperationRequestBuilder {
32+
33+
private URI uri;
34+
private HttpMethod method;
35+
private byte[] content;
36+
private HttpHeaders headers;
37+
private Collection<OperationRequestPart> parts;
38+
private Collection<RequestCookie> cookies;
39+
40+
/**
41+
* Creates a new OperationRequestBuilder.
42+
* @return the {@code OperationRequestBuilder}.
43+
*/
44+
public OperationRequestBuilder() {}
45+
46+
/**
47+
* Creates a new OperationRequestBuilder using an existing {@link OperationRequest} as default.
48+
* @param The original {@link OperationRequest}.
49+
* @return {@code OperationRequestBuilder}.
50+
*/
51+
public OperationRequestBuilder(OperationRequest original) {
52+
uri = original.getUri();
53+
method = original.getMethod();
54+
content = original.getContent();
55+
headers = original.getHeaders();
56+
parts = original.getParts();
57+
cookies = original.getCookies();
58+
}
59+
60+
/**
61+
* Sets the URI of the request.
62+
* @param uri the request's uri.
63+
* @return a reference to this object.
64+
*/
65+
public OperationRequestBuilder uri(URI uri) {
66+
this.uri = uri;
67+
return this;
68+
}
69+
70+
/**
71+
* Sets the HTTP method of the request.
72+
* @param method the request's method.
73+
* @return a reference to this object.
74+
*/
75+
public OperationRequestBuilder method(HttpMethod method) {
76+
this.method = method;
77+
return this;
78+
}
79+
80+
/**
81+
* Sets the content of the request.
82+
* @param content the request's content.
83+
* @return a reference to this object.
84+
*/
85+
public OperationRequestBuilder content(byte[] content) {
86+
this.content = content;
87+
return this;
88+
}
89+
90+
/**
91+
* Sets the headers of the request.
92+
* @param headers the request's headers.
93+
* @return a reference to this object.
94+
*/
95+
public OperationRequestBuilder headers(HttpHeaders headers) {
96+
this.headers = headers;
97+
return this;
98+
}
99+
100+
/**
101+
* Sets the parts of the request.
102+
* @param parts the request's parts.
103+
* @return a reference to this object.
104+
*/
105+
public OperationRequestBuilder parts(Collection<OperationRequestPart> parts) {
106+
this.parts = parts;
107+
return this;
108+
}
109+
110+
/**
111+
* Sets the cookies of the request.
112+
* @param cookies the request's cookies.
113+
* @return a reference to this object.
114+
*/
115+
public OperationRequestBuilder cookies(Collection<RequestCookie> cookies) {
116+
this.cookies = cookies;
117+
return this;
118+
}
119+
120+
/**
121+
* Builds the new operation request object. The {@code headers} will be augmented
122+
* to ensure that they always include a {@code Content-Length} header if the request
123+
* has any content and a {@code Host} header.
124+
* @return the {@code OperationRequest}.
125+
*/
126+
public OperationRequest build() {
127+
return new StandardOperationRequest(
128+
uri,
129+
method,
130+
content,
131+
augmentHeaders(headers, uri, content),
132+
parts != null ? parts : Collections.emptyList(),
133+
cookies != null ? cookies : Collections.emptyList()
134+
);
135+
}
136+
137+
private HttpHeaders augmentHeaders(HttpHeaders originalHeaders, URI uri, byte[] content) {
138+
String hostHeader = createHostHeader(uri);
139+
return new HttpHeadersHelper(originalHeaders)
140+
.addIfAbsent(HttpHeaders.HOST, hostHeader)
141+
.setContentLengthHeader(content)
142+
.getHeaders();
143+
}
144+
145+
private String createHostHeader(URI uri) {
146+
if (uri.getPort() == -1) {
147+
return uri.getHost();
148+
}
149+
return uri.getHost() + ":" + uri.getPort();
150+
}
151+
152+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/*
2+
* Copyright 2014-2022 the 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+
* https://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.restdocs.operation;
18+
19+
import java.util.Collection;
20+
import java.util.Collections;
21+
22+
import org.springframework.http.HttpHeaders;
23+
import org.springframework.http.HttpStatusCode;
24+
25+
/**
26+
* A builder for creating {@code OperationResponse OperationsResponses}.
27+
*
28+
* @author Augusto Ravazoli
29+
*/
30+
public class OperationResponseBuilder {
31+
32+
private HttpStatusCode status;
33+
private HttpHeaders headers;
34+
private byte[] content;
35+
private Collection<ResponseCookie> cookies;
36+
37+
/**
38+
* Creates a new OperationResponseBuilder.
39+
* @return the {@code OperationResponseBuilder}.
40+
*/
41+
public OperationResponseBuilder() {}
42+
43+
/**
44+
* Creates a new OperationResponseBuilder using an existing {@link OperationResponse} as default.
45+
* @param The original {@link OperationResponse}.
46+
* @return {@code OperationResponseBuilder}.
47+
*/
48+
public OperationResponseBuilder(OperationResponse original) {
49+
status = original.getStatus();
50+
headers = original.getHeaders();
51+
content = original.getContent();
52+
cookies = original.getCookies();
53+
}
54+
55+
/**
56+
* Sets the status code of the response.
57+
* @param status the response's status.
58+
* @return a reference to this object.
59+
*/
60+
public OperationResponseBuilder status(HttpStatusCode status) {
61+
this.status = status;
62+
return this;
63+
}
64+
65+
/**
66+
* Sets the headers of the response.
67+
* @param headers the response's headers.
68+
* @return a reference to this object.
69+
*/
70+
public OperationResponseBuilder headers(HttpHeaders headers) {
71+
this.headers = headers;
72+
return this;
73+
}
74+
75+
/**
76+
* Sets the content of the response.
77+
* @param content the request's content.
78+
* @return a reference to this object.
79+
*/
80+
public OperationResponseBuilder content(byte[] content) {
81+
this.content = content;
82+
return this;
83+
}
84+
85+
/**
86+
* Sets the cookies of the response.
87+
* @param cookies the response's cookies.
88+
* @return a reference to this object.
89+
*/
90+
public OperationResponseBuilder cookies(Collection<ResponseCookie> cookies) {
91+
this.cookies = cookies;
92+
return this;
93+
}
94+
95+
/**
96+
* Builds the new operation response object. If the response has any content, the given
97+
* {@code headers} will be augmented to ensure that they include a
98+
* {@code Content-Length} header.
99+
* @return the {@code OperationResponse}.
100+
*/
101+
public OperationResponse build() {
102+
return new StandardOperationResponse(
103+
status,
104+
augmentHeaders(headers, content),
105+
content,
106+
cookies != null ? cookies : Collections.emptyList()
107+
);
108+
}
109+
110+
private HttpHeaders augmentHeaders(HttpHeaders originalHeaders, byte[] content) {
111+
return new HttpHeadersHelper(originalHeaders).setContentLengthHeader(content).getHeaders();
112+
}
113+
114+
}

0 commit comments

Comments
 (0)