Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
189 changes: 189 additions & 0 deletions MIGRATION_GUIDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
# Migration Guide: StreamResource to DownloadHandler

## Overview

Starting with version 2.6.0, Grid Exporter Add-on introduces new `DownloadHandler`-based methods to replace the deprecated `StreamResource` methods. This migration is necessary for compatibility with Vaadin 25, where `StreamResource` will be removed.

## What's Changing?

The Grid Exporter Add-on now provides two sets of methods:

- **Old API (Deprecated)**: Methods returning `StreamResource` or `GridExporterStreamResource`
- **New API (Recommended)**: Methods returning `DownloadHandler`

## Backward Compatibility

✅ **Your existing code will continue to work!** The old methods are deprecated but still functional. You can migrate at your own pace.

## Migration Steps

### 1. Update Vaadin Version

The new `DownloadHandler` API requires **Vaadin 24.8.0 or later**.

**pom.xml:**
```xml
<properties>
<vaadin.version>24.8.0</vaadin.version>
</properties>
```

### 2. Update Method Calls

Replace the deprecated `get*StreamResource()` methods with the new `get*DownloadHandler()` methods.

#### Excel Export

**Before:**
```java
Anchor excelLink = new Anchor("", FontAwesome.Regular.FILE_EXCEL.create());
excelLink.setHref(exporter.getExcelStreamResource());
excelLink.getElement().setAttribute("download", true);
```

**After:**
```java
Anchor excelLink = new Anchor("", FontAwesome.Regular.FILE_EXCEL.create());
excelLink.setHref(exporter.getExcelDownloadHandler());
excelLink.getElement().setAttribute("download", true);
```

#### DOCX Export

**Before:**
```java
exporter.getDocxStreamResource()
exporter.getDocxStreamResource(customTemplate)
```

**After:**
```java
exporter.getDocxDownloadHandler()
exporter.getDocxDownloadHandler(customTemplate)
```

#### PDF Export

**Before:**
```java
exporter.getPdfStreamResource()
exporter.getPdfStreamResource(customTemplate)
```

**After:**
```java
exporter.getPdfDownloadHandler()
exporter.getPdfDownloadHandler(customTemplate)
```

#### CSV Export

**Before:**
```java
exporter.getCsvStreamResource()
```

**After:**
```java
exporter.getCsvDownloadHandler()
```

### 3. Update Custom Export Links (if applicable)

If you're creating custom export links instead of using auto-attached buttons:

**Before:**
```java
GridExporter<Person> exporter = GridExporter.createFor(grid);
exporter.setAutoAttachExportButtons(false);

Anchor customLink = new Anchor("", "Download Excel");
customLink.setHref(exporter.getExcelStreamResource().forComponent(customLink));
```

**After:**
```java
GridExporter<Person> exporter = GridExporter.createFor(grid);
exporter.setAutoAttachExportButtons(false);

Anchor customLink = new Anchor("", "Download Excel");
customLink.setHref(exporter.getExcelDownloadHandler());
// Note: forComponent() is handled internally for DownloadHandler
```

## API Comparison

| Old Method (Deprecated) | New Method | Notes |
|------------------------|------------|-------|
| `getExcelStreamResource()` | `getExcelDownloadHandler()` | Excel export |
| `getExcelStreamResource(String)` | `getExcelDownloadHandler(String)` | Excel with template |
| `getDocxStreamResource()` | `getDocxDownloadHandler()` | DOCX export |
| `getDocxStreamResource(String)` | `getDocxDownloadHandler(String)` | DOCX with template |
| `getPdfStreamResource()` | `getPdfDownloadHandler()` | PDF export |
| `getPdfStreamResource(String)` | `getPdfDownloadHandler(String)` | PDF with template |
| `getCsvStreamResource()` | `getCsvDownloadHandler()` | CSV export |

## Features Preserved

All existing features continue to work with the new API:

- ✅ Concurrent download control
- ✅ Download timeouts
- ✅ Button disable/enable during download
- ✅ Custom templates
- ✅ All export formats (Excel, DOCX, PDF, CSV)
- ✅ Custom columns and headers
- ✅ Hierarchical data support

## Timeline

- **Version 2.6.0**: New `DownloadHandler` methods introduced, old methods deprecated
- **Version 3.0.0**: Old `StreamResource` methods will be removed

## Need Help?

If you encounter any issues during migration, please:
1. Check that you're using Vaadin 24.8.0 or later
2. Review the deprecation warnings in your IDE
3. Open an issue on [GitHub](https://github.com/FlowingCode/GridExporterAddon/issues)

## Example: Complete Migration

**Before (Version 2.5.x):**
```java
Grid<Person> grid = new Grid<>(Person.class);
grid.setItems(people);

GridExporter<Person> exporter = GridExporter.createFor(grid);
// Auto-attached buttons use StreamResource internally
```

**After (Version 2.6.0+):**
```java
Grid<Person> grid = new Grid<>(Person.class);
grid.setItems(people);

GridExporter<Person> exporter = GridExporter.createFor(grid);
// Auto-attached buttons now use DownloadHandler internally
// No code changes needed if using auto-attached buttons!
```

**Custom Implementation:**
```java
Grid<Person> grid = new Grid<>(Person.class);
grid.setItems(people);

GridExporter<Person> exporter = GridExporter.createFor(grid);
exporter.setAutoAttachExportButtons(false);

// Create custom export buttons
Anchor excelBtn = new Anchor("", "Excel");
excelBtn.setHref(exporter.getExcelDownloadHandler());
excelBtn.getElement().setAttribute("download", true);

Anchor pdfBtn = new Anchor("", "PDF");
pdfBtn.setHref(exporter.getPdfDownloadHandler());
pdfBtn.getElement().setAttribute("download", true);

add(excelBtn, pdfBtn);
```
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,34 @@ To see the demo, navigate to http://localhost:8080/

See [here](https://github.com/FlowingCode/GridExporterAddon/releases)

## Migration to DownloadHandler API (Version 2.6.0+)

**Important for Vaadin 25 compatibility**: Starting with version 2.6.0, Grid Exporter Add-on introduces new `DownloadHandler`-based methods to replace the deprecated `StreamResource` methods.

### Quick Migration

**Old API (Deprecated):**
```java
exporter.getExcelStreamResource()
exporter.getDocxStreamResource()
exporter.getPdfStreamResource()
exporter.getCsvStreamResource()
```

**New API (Recommended):**
```java
exporter.getExcelDownloadHandler()
exporter.getDocxDownloadHandler()
exporter.getPdfDownloadHandler()
exporter.getCsvDownloadHandler()
```

### Requirements

- **Vaadin 24.8.0 or later** is required to use the new `DownloadHandler` methods
- Old `StreamResource` methods will continue to work until version 3.0.0
- See [MIGRATION_GUIDE.md](./MIGRATION_GUIDE.md) for detailed migration instructions

## Issue tracking

The issues for this add-on are tracked on its github.com page. All bug reports and feature requests are appreciated.
Expand Down
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@

<groupId>org.vaadin.addons.flowingcode</groupId>
<artifactId>grid-exporter-addon</artifactId>
<version>2.5.3-SNAPSHOT</version>
<version>2.6.0-SNAPSHOT</version>
<name>Grid Exporter Add-on</name>
<description>Grid Exporter Add-on for Vaadin Flow</description>
<url>https://www.flowingcode.com/en/open-source/</url>

<properties>
<vaadin.version>24.3.9</vaadin.version>
<vaadin.version>24.8.0</vaadin.version>
<selenium.version>4.1.2</selenium.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*-
* #%L
* Grid Exporter Add-on
* %%
* Copyright (C) 2022 - 2024 Flowing Code
* %%
* 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.
* #L%
*/
package com.flowingcode.vaadin.addons.gridexporter;

import com.vaadin.flow.server.streams.DownloadHandler;
import com.vaadin.flow.server.streams.DownloadEvent;
import com.vaadin.flow.server.VaadinSession;

Check warning on line 24 in src/main/java/com/flowingcode/vaadin/addons/gridexporter/ConcurrentDownloadHandler.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this unused import 'com.vaadin.flow.server.VaadinSession'.

See more on https://sonarcloud.io/project/issues?id=FlowingCode_GridExporterAddon&issues=AZrBFODLZzgyS1d0Prb_&open=AZrBFODLZzgyS1d0Prb_&pullRequest=189
import java.io.IOException;
import java.io.InterruptedIOException;
import java.nio.channels.InterruptedByTimeoutException;

/**
* An implementation of {@link DownloadHandler} that controls access to the
* {@link #handleDownloadRequest(DownloadEvent) handleDownloadRequest} method
* using a semaphore to
* manage concurrency.
*
* @author Javier Godoy
*/
@SuppressWarnings("serial")
abstract class ConcurrentDownloadHandler extends ConcurrentOperationBase implements DownloadHandler {

private final DownloadHandler delegate;

/**
* Constructs a {@code ConcurrentDownloadHandler} with the specified delegate.
* The delegate is a
* {@link DownloadHandler} that performs the actual download handling.
*
* @param delegate the delegate {@code DownloadHandler}
*/
ConcurrentDownloadHandler(DownloadHandler delegate) {
this.delegate = delegate;
}

/**
* Handles the download request using the provided {@link DownloadEvent}.
* <p>
* Note that the method is not called under the session lock. It means that if
* implementation
* requires access to the application/session data then the session has to be
* locked explicitly.
* <p>
* If a semaphore has been set, it controls access to this method, enforcing a
* timeout. A permit
* will be acquired from the semaphore, if one becomes available within the
* given waiting time and
* the current thread has not been {@linkplain Thread#interrupt interrupted}.
*
* @param event the download event containing the output stream and session
* @throws IOException if an IO error occurred
* @throws InterruptedIOException if the current thread is interrupted
* @throws InterruptedByTimeoutException if the waiting time elapsed before a
* permit was acquired
*/
@Override
public final void handleDownloadRequest(DownloadEvent event) throws IOException {
runWithSemaphore(event.getSession(), () -> delegate.handleDownloadRequest(event));
}

}
Loading