1313import com .vaadin .flow .component .textfield .TextField ;
1414import com .vaadin .flow .shared .Registration ;
1515import java .io .IOException ;
16+ import java .time .LocalDate ;
1617import java .util .ArrayList ;
1718import java .util .Collections ;
1819import java .util .List ;
1920import java .util .Map ;
21+ import java .util .Objects ;
2022import java .util .concurrent .CompletableFuture ;
2123import java .util .concurrent .TimeUnit ;
2224import java .util .function .Function ;
2325import java .util .stream .Collectors ;
2426import life .qbic .application .commons .ApplicationException ;
25- import life .qbic .datamanager .download .DownloadContentProvider .XLSXDownloadContentProvider ;
26- import life .qbic .datamanager .download .DownloadProvider ;
2727import life .qbic .application .commons .FileNameFormatter ;
28- import life .qbic .datamanager .files .export .sample . TemplateService ;
28+ import life .qbic .datamanager .files .export .download . ByteArrayDownloadStreamProvider ;
2929import life .qbic .datamanager .files .parsing .MetadataParser .ParsingException ;
3030import life .qbic .datamanager .files .parsing .ParsingResult ;
3131import life .qbic .datamanager .files .parsing .SampleInformationExtractor ;
3232import life .qbic .datamanager .files .parsing .SampleInformationExtractor .SampleInformationForNewSample ;
3333import life .qbic .datamanager .files .parsing .xlsx .XLSXParser ;
3434import life .qbic .datamanager .views .general .WizardDialogWindow ;
35+ import life .qbic .datamanager .views .general .download .DownloadComponent ;
3536import life .qbic .datamanager .views .general .upload .UploadWithDisplay ;
3637import life .qbic .datamanager .views .general .upload .UploadWithDisplay .FileType ;
3738import life .qbic .datamanager .views .general .upload .UploadWithDisplay .SucceededEvent ;
3839import life .qbic .datamanager .views .general .upload .UploadWithDisplay .UploadedData ;
40+ import life .qbic .datamanager .views .notifications .MessageSourceNotificationFactory ;
3941import life .qbic .logging .api .Logger ;
4042import life .qbic .logging .service .LoggerFactory ;
4143import life .qbic .projectmanagement .application .ValidationResult ;
4244import life .qbic .projectmanagement .application .ValidationResultWithPayload ;
45+ import life .qbic .projectmanagement .application .api .AsyncProjectService ;
46+ import life .qbic .projectmanagement .application .api .AsyncProjectService .AccessDeniedException ;
4347import life .qbic .projectmanagement .application .api .SampleMetadata ;
48+ import life .qbic .projectmanagement .application .api .fair .DigitalObject ;
4449import life .qbic .projectmanagement .application .sample .SampleValidationService ;
45- import org .apache . poi . ss . usermodel . Workbook ;
50+ import org .springframework . util . MimeType ;
4651
4752public class RegisterSampleBatchDialog extends WizardDialogWindow {
48-
53+ private static final MimeType OPEN_XML = MimeType .valueOf (
54+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" );
4955 private final List <SampleMetadata > validatedSampleMetadata ;
5056 private final TextField batchNameField ;
5157 private static final Logger log = LoggerFactory .logger (RegisterSampleBatchDialog .class );
@@ -55,17 +61,22 @@ public class RegisterSampleBatchDialog extends WizardDialogWindow {
5561 private final Div succeededView ;
5662 private static final int MAX_FILE_SIZE = 25 * 1024 * 1024 ;
5763 private final UploadWithDisplay uploadWithDisplay ;
64+ private transient final MessageSourceNotificationFactory messageFactory ;
65+ private final DownloadComponent downloadComponent ;
5866
5967 private void setValidatedSampleMetadata (List <SampleMetadata > validatedSampleMetadata ) {
6068 this .validatedSampleMetadata .clear ();
6169 this .validatedSampleMetadata .addAll (validatedSampleMetadata );
6270 }
6371
6472 public RegisterSampleBatchDialog (SampleValidationService sampleValidationService ,
65- TemplateService templateService ,
73+ AsyncProjectService service , MessageSourceNotificationFactory messageFactory ,
6674 String experimentId ,
6775 String projectId ,
6876 String projectCode ) {
77+ this .messageFactory = Objects .requireNonNull (messageFactory );
78+ this .downloadComponent = new DownloadComponent ();
79+
6980
7081 setHeaderTitle ("Register Sample Batch" );
7182 setConfirmButtonLabel ("Register" );
@@ -86,7 +97,7 @@ public RegisterSampleBatchDialog(SampleValidationService sampleValidationService
8697 batchNameField .setErrorMessage ("Please provide a name for your batch." );
8798 batchNameField .setPlaceholder ("Please enter a name for your batch" );
8899
89- Div downloadMetadataSection = setupDownloadMetadataSection (templateService , experimentId ,
100+ Div downloadMetadataSection = setupDownloadMetadataSection (service , experimentId ,
90101 projectId , projectCode );
91102
92103 validatedSampleMetadata = new ArrayList <>();
@@ -110,7 +121,25 @@ public RegisterSampleBatchDialog(SampleValidationService sampleValidationService
110121 inProgressView .setVisible (false );
111122 failedView .setVisible (false );
112123 succeededView .setVisible (false );
113- add (initialView , inProgressView , failedView , succeededView );
124+ add (initialView , inProgressView , failedView , succeededView , downloadComponent );
125+ }
126+
127+ private void handleError (Throwable throwable ) {
128+ switch (throwable ) {
129+ case AccessDeniedException ignored :
130+ handleAccessDeniedError ();
131+ return ;
132+ default :
133+ handleUnexpectedError (throwable );
134+ }
135+ }
136+
137+ private void handleUnexpectedError (Throwable throwable ) {
138+ throw new ApplicationException ("We are sorry, an unexpected error occurred." , throwable );
139+ }
140+
141+ private void handleAccessDeniedError () {
142+ getUI ().ifPresent (ui -> ui .access (() -> messageFactory .toast ("access.denied.message" , new Object []{}, getLocale ()).open ()));
114143 }
115144
116145 private void onUploadSucceeded (SampleValidationService sampleValidationService ,
@@ -209,24 +238,36 @@ private void onUploadSucceeded(SampleValidationService sampleValidationService,
209238
210239 }
211240
212- private Div setupDownloadMetadataSection (TemplateService templateService , String experimentId ,
241+ private void triggerDownload (DigitalObject resource , String filename ) {
242+ getUI ().ifPresent (
243+ ui -> ui .access (() -> downloadComponent .trigger (new ByteArrayDownloadStreamProvider () {
244+ @ Override
245+ public byte [] getBytes () {
246+ try (var content = resource .content ()) {
247+ return content .readAllBytes ();
248+ } catch (IOException e ) {
249+ throw new RuntimeException (e );
250+ }
251+ }
252+
253+ @ Override
254+ public String getFilename () {
255+ return filename ;
256+ }
257+ })));
258+ }
259+
260+ private Div setupDownloadMetadataSection (AsyncProjectService service , String experimentId ,
213261 String projectId , String projectCode ) {
214262 Button downloadTemplate = new Button ("Download metadata template" );
215263 downloadTemplate .addClassName ("download-metadata-button" );
216264 downloadTemplate .addClickListener (buttonClickEvent -> {
217- try (Workbook workbook = templateService .sampleBatchRegistrationXLSXTemplate (
218- projectId ,
219- experimentId )) {
220- var filename = FileNameFormatter .formatWithVersion (
221- projectCode + "_sample metadata registration template" ,
222- 1 , "xlsx" );
223- var downloadProvider = new DownloadProvider (
224- new XLSXDownloadContentProvider (filename , workbook ));
225- add (downloadProvider );
226- downloadProvider .trigger ();
227- } catch (IOException e ) {
228- throw new ApplicationException (e .getMessage (), e );
229- }
265+ service .sampleRegistrationTemplate (projectId , experimentId ,
266+ OPEN_XML ).doOnSuccess (resource ->
267+ triggerDownload (resource ,
268+ FileNameFormatter .formatWithTimestampedSimple (LocalDate .now (), projectCode , " sample metadata template" ,
269+ "xlsx" )
270+ )).doOnError (this ::handleError ).subscribe ();
230271 });
231272 Div text = new Div ();
232273 text .addClassName ("download-metadata-text" );
0 commit comments