/
MultipartResponseContent.groovy
169 lines (151 loc) 路 7.09 KB
/
MultipartResponseContent.groovy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/*
* Copyright (C) 2018 Christopher J. Stehno
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.stehno.ersatz
import com.stehno.ersatz.impl.ErsatzMultipartResponseContent
import groovy.transform.CompileStatic
import space.jasan.support.groovy.closure.ConsumerWithDelegate
import java.util.function.Consumer
import java.util.function.Function
import static groovy.lang.Closure.DELEGATE_FIRST
import static java.util.Collections.shuffle
/**
* Response content object used to return a multipart response to a request. Note that multipart responses are not reliably supported by most
* browsers; this feature is mainly intended to support RESTful interfaces that may want to implement multipart response content.
*
* When configuring multipart content, encoders must be provided to convert the content objects into the serialized transfer format. If a shared
* <code>ResponseEncoders</code> is provided, they will be used as defaults and overridden by any encoders specified on the response configuration
* itself.
*
* Note that the globally configured encoders will be injected when this content object is added to the response body.
*/
@CompileStatic @SuppressWarnings('ConfusingMethodName')
abstract class MultipartResponseContent {
private static final String ALPHANUMERICS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
/**
* Creates a new multipart response content object with the optional boundary (random default) and a Closure used to configure the parts.
*
* @param closure the configuration closure (Delegates to MultipartContent instance)
* @return a reference to this MultipartResponseContent instance
*/
static MultipartResponseContent multipart(final @DelegatesTo(value = MultipartResponseContent, strategy = DELEGATE_FIRST) Closure closure) {
multipart(ConsumerWithDelegate.create(closure))
}
/**
* Creates a new multipart response content object with the optional boundary (random default) and a Consumer used to configure the parts. The
* Consumer will have an instance of MultipartContent passed into it for configuration.
*
* @param closure the configuration consumer (given an instance of MultipartContent)
* @return a reference to this MultipartResponseContent instance
*/
static MultipartResponseContent multipart(final Consumer<MultipartResponseContent> consumer) {
MultipartResponseContent content = new ErsatzMultipartResponseContent()
consumer.accept(content)
content
}
/**
* Used to generate a random boundary tag.
*
* @return a random boundary label
*/
static String generateBoundary() {
def letters = ALPHANUMERICS as List
shuffle(letters)
letters[0..<18].join('')
}
/**
* Used to specify the set of shared (parent) encoders used - this encoder collection will be called when no encoder is specified in the current
* response configuration.
*
* @param responseEncoders the parent set of shared encoders
* @return a reference to this MultipartResponseContent instance
*/
abstract MultipartResponseContent encoders(final ResponseEncoders responseEncoders)
/**
* Used to override the default random boundary value with the provided one.
*
* @param value the boundary label to be used
* @return a reference to this MultipartResponseContent instance
*/
abstract MultipartResponseContent boundary(final String value)
/**
* Configures a response content encoder for the specified contentType and content class.
*
* @param contentType the response content-type
* @param type the response object type
* @param encoder the encoder
* @return a reference to this MultipartResponseContent instance
*/
abstract MultipartResponseContent encoder(final String contentType, final Class type, final Function<Object, String> encoder)
/**
* Configures a response content encoder for the specified contentType and content class.
*
* @param contentType the response content-type
* @param type the response object type
* @param encoder the encoder
* @return a reference to this MultipartResponseContent instance
*/
abstract MultipartResponseContent encoder(final ContentType contentType, final Class type, final Function<Object, String> encoder)
/**
* Used to add a "field" part to the response.
*
* @param fieldName the field name
* @param value the field value
* @return a reference to this MultipartResponseContent instance
*/
abstract MultipartResponseContent field(final String fieldName, final String value)
/**
* Used to add a "field" part to the response.
*
* @param fieldName the field name
* @param contentType the response part content-type
* @param value the field value
* @return a reference to this MultipartResponseContent instance
*/
abstract MultipartResponseContent part(final String fieldName, final String contentType, final Object value)
/**
* Used to add a "field" part to the response.
*
* @param fieldName the field name
* @param contentType the response part content-type
* @param value the field value
* @param transferEncoding the content-transfer-encoding value (defaults to none)
* @return a reference to this MultipartResponseContent instance
*/
abstract MultipartResponseContent part(
final String fieldName, final ContentType contentType, final Object value, final String transferEncoding = null)
/**
* Used to add a "file" part to the response.
*
* @param fieldName the field name
* @param fileName the file name
* @param contentType the response part content-type
* @param value the field value
* @param transferEncoding the content-transfer-encoding value (defaults to none)
* @return a reference to this MultipartResponseContent instance
*/
abstract MultipartResponseContent part(String fieldName, String fileName, String contentType, Object value, String transferEncoding = null)
/**
* Used to add a "file" part to the response.
*
* @param fieldName the field name
* @param fileName the file name
* @param contentType the response part content-type
* @param value the field value
* @param transferEncoding the content-transfer-encoding value (defaults to none)
* @return a reference to this MultipartResponseContent instance
*/
abstract MultipartResponseContent part(String fieldName, String fileName, ContentType contentType, Object value, String transferEncoding = null)
}