10000 feat: Add overloads with TransferContext (#21465) · vaadin/flow@ca68057 · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Commit ca68057

Browse files
authored
feat: Add overloads with TransferContext (#21465)
1 parent fa6a067 commit ca68057

File tree

2 files changed

+181
-3
lines changed

2 files changed

+181
-3
lines changed

flow-server/src/main/java/com/vaadin/flow/server/streams/TransferProgressAwareHandler.java

Lines changed: 137 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import com.vaadin.flow.function.SerializableBiConsumer;
2727
import com.vaadin.flow.function.SerializableConsumer;
2828
import com.vaadin.flow.function.SerializableRunnable;
29+
import com.vaadin.flow.function.SerializableTriConsumer;
2930
import com.vaadin.flow.server.Command;
3031
import com.vaadin.flow.shared.Registration;
3132

@@ -112,7 +113,96 @@ public void onStart(TransferContext context) {
112113
}
113114

114115
/**
115-
* Adds a listener to be notified of transfer progress.
116+
* Adds a listener to be notified when the transfer starts that receives the
117+
* transfer context as input.
118+
* <p>
119+
* The call of the given callback is wrapped by the
120+
* {@link com.vaadin.flow.component.UI#access(Command)} to send UI changes
121+
* defined here when the download or upload request is being handled. This
122+
* needs {@link com.vaadin.flow.component.page.Push} to be enabled in the
123+
* application to properly send the UI changes to client.
124+
*
125+
* @param startHandler
126+
* the handler to be called when the transfer starts
127+
* @return this instance for method chaining
128+
*/
129+
public R whenStart(SerializableConsumer<TransferContext> startHandler) {
130+
Objects.requireNonNull(startHandler, "Start handler cannot be null");
131+
addTransferProgressListenerInternal(new TransferProgressListener() {
132+
@Override
133+
public void onStart(TransferContext context) {
134+
context.getUI().access(() -> {
135+
startHandler.accept(context);
136+
});
137+
}
138+
});
139+
return (R) this;
140+
}
141+
142+
/**
143+
* Adds a listener to be notified of transfer progress with giving the
144+
* transfer context object and with the given interval.
145+
* <p>
146+
* The call of the given callback is wrapped by the
147+
* {@link com.vaadin.flow.component.UI#access(Command)} to send UI changes
148+
* defined here when the download or upload request is being handled. This
149+
* needs {@link com.vaadin.flow.component.page.Push} to be enabled in the
150+
* application to properly send the UI changes to client.
151+
*
152+
* @param progressHandler
153+
* the handler to be called with the transfer context, current
154+
* and total bytes
155+
* @param progressIntervalInBytes
156+
* the interval in bytes for reporting progress
157+
* @return this instance for method chaining
158+
*/
159+
public R onProgress(
160+
SerializableTriConsumer<TransferContext, Long, Long> progressHandler,
161+
long progressIntervalInBytes) {
162+
Objects.requireNonNull(progressHandler,
163+
"Progress handler cannot be null");
164+
addTransferProgressListenerInternal(new TransferProgressListener() {
165+
@Override
166+
public void onProgress(TransferContext context,
167+
long transferredBytes, long totalBytes) {
168+
context.getUI().access(() -> {
169+
progressHandler.accept(context, transferredBytes,
170+
totalBytes);
171+
});
172+
}
173+
174+
@Override
175+
public long progressReportInterval() {
176+
return progressIntervalInBytes;
177+
}
178+
});
179+
return (R) this;
180+
}
181+
182+
/**
183+
* Adds a listener to be notified of transfer progress with giving the
184+
* transfer context object and with the default progress interval.
185+
* <p>
186+
* The call of the given callback is wrapped by the
187+
* {@link com.vaadin.flow.component.UI#access(Command)} to send UI changes
188+
* defined here when the download or upload request is being handled. This
189+
* needs {@link com.vaadin.flow.component.page.Push} to be enabled in the
190+
* application to properly send the UI changes to client.
191+
*
192+
* @param progressHandler
193+
* the handler to be called with the transfer context, current
194+
* and total bytes
195+
* @return this instance for method chaining
196+
*/
197+
public R onProgress(
198+
SerializableTriConsumer<TransferContext, Long, Long> progressHandler) {
199+
return onProgress(progressHandler,
200+
TransferProgressListener.DEFAULT_PROGRESS_REPORT_INTERVAL_IN_BYTES);
201+
}
202+
203+
/**
204+
* Adds a listener to be notified of transfer progress with the given
205+
* interval.
116206
* <p>
117207
* The call of the given callback is wrapped by the
118208
* {@link com.vaadin.flow.component.UI#access(Command)} to send UI changes
@@ -174,8 +264,10 @@ public R onProgress(SerializableBiConsumer<Long, Long> progressHandler) {
174264

175265
/**
176266
* Adds a listener to be notified when the transfer is completed
177-
* successfully or with an error. Gives a <code>Boolean</code> indicating
178-
* whether the transfer was completed successfully (true) or not (false).
267+
* successfully or with an error.
268+
* <p>
269+
* Gives a <code>Boolean</code> indicating whether the transfer was
270+
* completed successfully (true) or not (false).
179271
* <p>
180272
* The call of the given callback is wrapped by the
181273
* {@link com.vaadin.flow.component.UI#access(Command)} to send UI changes
@@ -210,6 +302,48 @@ public void onComplete(TransferContext context,
210302
return (R) this;
211303
}
212304

305+
/**
306+
* Adds a listener to be notified when the transfer is completed
307+
* successfully or with an error with the trasfer context object given as an
308+
* input.
309+
* <p>
310+
* Gives a <code>Boolean</code> indicating whether the transfer was
311+
* completed successfully (true) or not (false) and transfer context to
312+
* obtain more meta-data.
313+
* <p>
314+
* The call of the given callback is wrapped by the
315+
* {@link com.vaadin.flow.component.UI#access(Command)} to send UI changes
316+
* defined here when the download or upload request is being handled. This
317+
* needs {@link com.vaadin.flow.component.page.Push} to be enabled in the
318+
* application to properly send the UI changes to client.
319+
*
320+
* @param completeOrTerminateHandler
321+
* the handler to be called when the transfer is completed
322+
* @return this instance for method chaining
323+
*/
324+
public R whenComplete(
325+
SerializableBiConsumer<TransferContext, Boolean> completeOrTerminateHandler) {
326+
Objects.requireNonNull(completeOrTerminateHandler,
327+
"Complete or terminate handler cannot be null");
328+
addTransferProgressListenerInternal(new TransferProgressListener() {
329+
@Override
330+
public void onError(TransferContext context, IOException reason) {
331+
context.getUI().access(() -> {
332+
completeOrTerminateHandler.accept(context, false);
333+ });
334+
}
335+
336+
@Override
337+
public void onComplete(TransferContext context,
338+
long transferredBytes) {
339+
context.getUI().access(() -> {
340+
completeOrTerminateHandler.accept(context, true);
341+
});
342+
}
343+
});
344+
return (R) this;
345+
}
346+
213347
/**
214348
* Get the listeners that are registered to this handler.
215349
* <p>

flow-server/src/test/java/com/vaadin/flow/server/streams/AbstractDownloadHandlerTest.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,4 +255,48 @@ public void handleDownloadRequest(DownloadEvent event)
255255
Assert.assertEquals(1024, context.contentLength());
256256
Assert.assertEquals("test.txt", context.fileName());
257257
}
258+
259+
@Test
260+
public void whenStartWithContext_onStartCalled() {
261+
AtomicBoolean invoked = new AtomicBoolean(false);
262+
handler.whenStart((context) -> invoked.set(true));
263+
handler.getListeners()
264+
.forEach(listener -> listener.onStart(mockContext));
265+
Assert.assertTrue("Start with context should be invoked",
266+
invoked.get());
267+
}
268+
269+
@Test
270+
public void whenProgressWithContext_onProgressCalled() {
271+
AtomicBoolean invoked = new AtomicBoolean(false);
272+
handler.onProgress((context, current, total) -> invoked.set(true),
273+
1024);
274+
handler.getListeners().forEach(listener -> listener
275+
.onProgress(mockContext, TRANSFERRED_BYTES, TOTAL_BYTES));
276+
Assert.assertTrue("Progress with context should be invoked",
277+
invoked.get());
278+
}
279+
280+
@Test
281+
public void whenProgressWithContextNoInterval_onProgressCalled() {
282+
AtomicBoolean invoked = new AtomicBoolean(false);
283+
handler.onProgress((context, current, total) -> invoked.set(true));
284+
handler.getListeners().forEach(listener -> listener
285+
.onProgress(mockContext, TRANSFERRED_BYTES, TOTAL_BYTES));
286+
Assert.assertTrue(
287+
"Progress with context and interval should be invoked",
288+
invoked.get());
289+
}
290+
291+
@Test
292+
public void whenCompleteWithContext() {
293+
AtomicBoolean invoked = new AtomicBoolean(false);
294+
handler.whenComplete((context, success) -> invoked.set(true));
295+
handler.getListeners().forEach(listener -> {
296+
listener.onComplete(mockContext, TRANSFERRED_BYTES);
297+
listener.onError(mockContext, EXCEPTION);
298+
});
299+
Assert.assertTrue("Progress with context should be invoked",
300+
invoked.get());
301+
}
258302
}

0 commit comments

Comments
 (0)
0