3232import org .apache .commons .lang3 .StringUtils ;
3333import org .dspace .app .rest .model .BitstreamRest ;
3434import org .dspace .app .rest .model .ClarinUserMetadataRest ;
35+ import org .dspace .app .rest .model .ItemRest ;
3536import org .dspace .authorize .AuthorizeException ;
3637import org .dspace .content .Bitstream ;
38+ import org .dspace .content .Bundle ;
39+ import org .dspace .content .DSpaceObject ;
40+ import org .dspace .content .Item ;
3741import org .dspace .content .clarin .ClarinLicense ;
3842import org .dspace .content .clarin .ClarinLicenseResourceMapping ;
3943import org .dspace .content .clarin .ClarinLicenseResourceUserAllowance ;
4044import org .dspace .content .clarin .ClarinUserMetadata ;
4145import org .dspace .content .clarin .ClarinUserRegistration ;
4246import org .dspace .content .service .BitstreamService ;
47+ import org .dspace .content .service .ItemService ;
4348import org .dspace .content .service .clarin .ClarinLicenseResourceMappingService ;
4449import org .dspace .content .service .clarin .ClarinLicenseResourceUserAllowanceService ;
4550import org .dspace .content .service .clarin .ClarinUserMetadataService ;
@@ -76,9 +81,105 @@ public class ClarinUserMetadataRestController {
7681 ClarinUserRegistrationService clarinUserRegistrationService ;
7782 @ Autowired
7883 BitstreamService bitstreamService ;
84+
85+ @ Autowired
86+ ItemService itemService ;
87+
7988 @ Autowired
8089 ConfigurationService configurationService ;
8190
91+ @ RequestMapping (value = "/zip" , method = POST , consumes = APPLICATION_JSON )
92+ @ PreAuthorize ("permitAll()" )
93+ public ResponseEntity manageUserMetadataForZIP (@ RequestParam ("itemUUID" ) UUID itemUUID ,
94+ HttpServletRequest request )
95+ throws SQLException , ParseException , IOException , AuthorizeException , MessagingException {
96+
97+ // Get context from the request
98+ Context context = obtainContext (request );
99+ // Validate parameters
100+ if (Objects .isNull (context )) {
101+ return null ;
102+ }
103+ if (Objects .isNull (itemUUID )) {
104+ return null ;
105+ }
106+
107+ // Get current user from the context to find out if the user is signed in
108+ EPerson currentUser = context .getCurrentUser ();
109+ String downloadToken = this .generateToken ();
110+
111+ Item item = itemService .find (context , itemUUID );
112+ if (Objects .isNull (item )) {
113+ log .error ("Cannot find the item with ID: " + itemUUID );
114+ throw new NotFoundException ("Cannot find the item with ID: " + itemUUID );
115+ }
116+ // Load the name because it is used in the email, and it must be loaded before the `sendEmailWithDownloadLink`
117+ // method otherwise it will throw an exception about Lazy loading.
118+ item .getName ();
119+
120+ boolean shouldEmailToken = false ;
121+ ClarinLicense clarinLicense = null ;
122+ // Get ClarinUserMetadataRest Array from the request body
123+ ClarinUserMetadataRest [] clarinUserMetadataRestArray =
124+ new ObjectMapper ().readValue (request .getInputStream (), ClarinUserMetadataRest [].class );
125+ if (Objects .isNull (clarinUserMetadataRestArray )) {
126+ throw new RuntimeException ("The clarinUserMetadataRestArray cannot be null. It could be empty, but" +
127+ " not null" );
128+ }
129+
130+ // Convert Array to the List
131+ List <ClarinUserMetadataRest > clarinUserMetadataRestList = Arrays .asList (clarinUserMetadataRestArray );
132+ List <Bundle > bundles = item .getBundles ("ORIGINAL" );
133+ for (Bundle original : bundles ) {
134+ List <Bitstream > bss = original .getBitstreams ();
135+ for (Bitstream bitstream : bss ) {
136+ UUID bitstreamUUID = bitstream .getID ();
137+ // Get mapping between clarin license and the bitstream
138+ ClarinLicenseResourceMapping clarinLicenseResourceMapping =
139+ this .getLicenseResourceMapping (context , bitstreamUUID );
140+ if (Objects .isNull (clarinLicenseResourceMapping )) {
141+ throw new NotFoundException ("Cannot find the license resource mapping between clarin license" +
142+ " and the bitstream" );
143+ }
144+ if (Objects .isNull (currentUser )) {
145+ // The user is not signed in
146+ this .processNonSignedInUser (context , clarinUserMetadataRestList , clarinLicenseResourceMapping ,
147+ downloadToken );
148+
149+ } else {
150+ // The user is signed in
151+ this .processSignedInUser (context , currentUser , clarinUserMetadataRestList ,
152+ clarinLicenseResourceMapping , downloadToken );
153+ }
154+
155+ // Check (only once) if the Clarin License contains the required information to SEND_TOKEN, which means
156+ // the item must be downloaded after the user confirms the download with the token sent by email.
157+ if (Objects .isNull (clarinLicense )) {
158+ clarinLicense = this .getClarinLicense (clarinLicenseResourceMapping );
159+ shouldEmailToken = this .shouldEmailToken (clarinLicenseResourceMapping );
160+ }
161+ }
162+ }
163+
164+ context .commit ();
165+ if (shouldEmailToken ) {
166+ // If yes - send token to e-mail
167+ try {
168+ String email = getEmailFromUserMetadata (clarinUserMetadataRestList );
169+ this .sendEmailWithDownloadLink (context , item , clarinLicense ,
170+ email , downloadToken );
171+ } catch (MessagingException e ) {
172+ log .error ("Cannot send the download email because: " + e .getMessage ());
173+ throw new RuntimeException ("Cannot send the download email because: " + e .getMessage ());
174+ }
175+
176+ return ResponseEntity .ok ().body (CHECK_EMAIL_RESPONSE_CONTENT );
177+ } else {
178+ // If no - send token in the response to download the bitstream immediately
179+ return ResponseEntity .ok ().body (downloadToken );
180+ }
181+ }
182+
82183 @ RequestMapping (method = POST , consumes = APPLICATION_JSON )
83184 @ PreAuthorize ("permitAll()" )
84185 public ResponseEntity manageUserMetadata (@ RequestParam ("bitstreamUUID" ) UUID bitstreamUUID ,
@@ -91,13 +192,24 @@ public ResponseEntity manageUserMetadata(@RequestParam("bitstreamUUID") UUID bit
91192 if (Objects .isNull (context )) {
92193 return null ;
93194 }
94- if (Objects .isNull (bitstreamUUID )) {
195+
196+
197+ Bitstream bitstream = bitstreamService .find (context , bitstreamUUID );
198+ if (Objects .isNull (bitstream )) {
199+ log .error ("Cannot find the bitstream with ID: " + bitstreamUUID );
95200 return null ;
96201 }
202+ // Load the name because it is used in the email, and it must be loaded before the `sendEmailWithDownloadLink`
203+ // method otherwise it will throw an exception about Lazy loading.
204+ bitstream .getName ();
205+
206+ // Get current user from the context to find out if the user is signed in
207+ EPerson currentUser = context .getCurrentUser ();
208+ String downloadToken = this .generateToken ();
97209
98210 // Get mapping between clarin license and the bitstream
99211 ClarinLicenseResourceMapping clarinLicenseResourceMapping =
100- this .getLicenseResourceMapping (context , bitstreamUUID );
212+ this .getLicenseResourceMapping (context , bitstream . getID () );
101213 if (Objects .isNull (clarinLicenseResourceMapping )) {
102214 throw new NotFoundException ("Cannot find the license resource mapping between clarin license" +
103215 " and the bitstream" );
@@ -113,28 +225,26 @@ public ResponseEntity manageUserMetadata(@RequestParam("bitstreamUUID") UUID bit
113225
114226 // Convert Array to the List
115227 List <ClarinUserMetadataRest > clarinUserMetadataRestList = Arrays .asList (clarinUserMetadataRestArray );
116-
117- // Get current user from the context to find out if the user is signed in
118- EPerson currentUser = context .getCurrentUser ();
119- String downloadToken = this .generateToken ();
120228 if (Objects .isNull (currentUser )) {
121229 // The user is not signed in
122230 this .processNonSignedInUser (context , clarinUserMetadataRestList , clarinLicenseResourceMapping ,
123- bitstreamUUID , downloadToken );
231+ downloadToken );
124232
125233 } else {
126234 // The user is signed in
127235 this .processSignedInUser (context , currentUser , clarinUserMetadataRestList , clarinLicenseResourceMapping ,
128- bitstreamUUID , downloadToken );
236+ downloadToken );
129237 }
130238
131- boolean shouldEmailToken = this .shouldEmailToken (context , bitstreamUUID , clarinLicenseResourceMapping );
239+ boolean shouldEmailToken = this .shouldEmailToken (clarinLicenseResourceMapping );
132240 context .commit ();
133241 if (shouldEmailToken ) {
134242 // If yes - send token to e-mail
135243 try {
136- this .sendEmailWithDownloadLink (context , bitstreamUUID , clarinLicenseResourceMapping ,
137- clarinUserMetadataRestList , downloadToken );
244+ String email = getEmailFromUserMetadata (clarinUserMetadataRestList );
245+ ClarinLicense clarinLicense = this .getClarinLicense (clarinLicenseResourceMapping );
246+ this .sendEmailWithDownloadLink (context , bitstream , clarinLicense ,
247+ email , downloadToken );
138248 } catch (MessagingException e ) {
139249 log .error ("Cannot send the download email because: " + e .getMessage ());
140250 throw new RuntimeException ("Cannot send the download email because: " + e .getMessage ());
@@ -147,30 +257,19 @@ public ResponseEntity manageUserMetadata(@RequestParam("bitstreamUUID") UUID bit
147257 }
148258 }
149259
150- private void sendEmailWithDownloadLink (Context context , UUID bitstreamUUID ,
151- ClarinLicenseResourceMapping clarinLicenseResourceMapping ,
152- List < ClarinUserMetadataRest > clarinUserMetadataRestList ,
260+ private void sendEmailWithDownloadLink (Context context , DSpaceObject dso ,
261+ ClarinLicense clarinLicense ,
262+ String email ,
153263 String downloadToken )
154264 throws IOException , SQLException , MessagingException {
155- // Get the recipient email
156- String email = getEmailFromUserMetadata (clarinUserMetadataRestList );
157265 if (StringUtils .isBlank (email )) {
158266 log .error ("Cannot send email with download link because the email is empty." );
159267 throw new BadRequestException ("Cannot send email with download link because the email is empty." );
160268 }
161269
162- // Get the file name
163- Bitstream bitstream = bitstreamService .find (context , bitstreamUUID );
164- if (Objects .isNull (bitstream )) {
165- log .error ("Cannot find bitstream with ID: " + bitstreamUUID );
166- throw new BadRequestException ("Cannot find bitstream with ID: " + bitstreamUUID );
167- }
168-
169- // Get Clarin License
170- ClarinLicense clarinLicense = getClarinLicense (context , bitstreamUUID , clarinLicenseResourceMapping );
171- if (Objects .isNull (clarinLicense )) {
172- log .error ("Cannot find the clarin license for the bitstream with ID: " + bitstreamUUID );
173- throw new BadRequestException ("Cannot find the clarin license for the bitstream with ID: " + bitstreamUUID );
270+ if (Objects .isNull (dso )) {
271+ log .error ("Cannot send email with download link because the DSpaceObject is null." );
272+ throw new BadRequestException ("Cannot send email with download link because the DSpaceObject is null." );
174273 }
175274
176275 // Fetch DSpace main cfg info and send it in the email
@@ -185,13 +284,15 @@ private void sendEmailWithDownloadLink(Context context, UUID bitstreamUUID,
185284 throw new RuntimeException ("Cannot load the `dspace.ui.url` property from the cfg." );
186285 }
187286 // Compose download link
188- String downloadLink = uiUrl + "/" + BitstreamRest .PLURAL_NAME + "/" + bitstream .getID () + "/download?dtoken=" +
189- downloadToken ;
287+ // Redirect to `/api/bitstreams/{bitstreamId}/download?dtoken={downloadToken}` or
288+ // `/api/items/{itemId}/download?dtoken={downloadToken}`
289+ String downloadLink = uiUrl + "/" + (dso instanceof Item ? ItemRest .PLURAL_NAME : BitstreamRest .PLURAL_NAME ) +
290+ "/" + dso .getID () + "/download?dtoken=" + downloadToken ;
190291
191292 try {
192293 Locale locale = context .getCurrentLocale ();
193294 Email bean = Email .getEmail (I18nUtil .getEmailFilename (locale , "clarin_download_link" ));
194- bean .addArgument (bitstream .getName ());
295+ bean .addArgument (dso .getName ());
195296 bean .addArgument (downloadLink );
196297 bean .addArgument (clarinLicense .getDefinition ());
197298 bean .addArgument (helpDeskEmail );
@@ -220,7 +321,7 @@ private String getEmailFromUserMetadata(List<ClarinUserMetadataRest> clarinUserM
220321 public List <ClarinUserMetadata > processSignedInUser (Context context , EPerson currentUser ,
221322 List <ClarinUserMetadataRest > clarinUserMetadataRestList ,
222323 ClarinLicenseResourceMapping clarinLicenseResourceMapping ,
223- UUID bitstreamUUID , String downloadToken )
324+ String downloadToken )
224325 throws SQLException {
225326 // If exists userMetadata records in the table update them or create them in other case
226327 // Get UserRegistration which has the UserMetadata list
@@ -289,7 +390,6 @@ private ClarinLicenseResourceUserAllowance createClrua(Context context,
289390 public List <ClarinUserMetadata > processNonSignedInUser (Context context ,
290391 List <ClarinUserMetadataRest > clarinUserMetadataRestList ,
291392 ClarinLicenseResourceMapping clarinLicenseResourceMapping ,
292- UUID bitstreamUUID ,
293393 String downloadToken ) throws SQLException {
294394 // Create ClarinUserMetadataRecord from the ClarinUserMetadataRest List.
295395 // Add created ClarinUserMetadata to the List.
@@ -343,9 +443,7 @@ public ClarinLicenseResourceMapping getLicenseResourceMapping(Context context, U
343443 return clarinLicenseResourceMapping ;
344444 }
345445
346- private ClarinLicense getClarinLicense (Context context , UUID bitstreamUUID ,
347- ClarinLicenseResourceMapping clarinLicenseResourceMapping )
348- throws SQLException {
446+ private ClarinLicense getClarinLicense (ClarinLicenseResourceMapping clarinLicenseResourceMapping ) {
349447 if (Objects .isNull (clarinLicenseResourceMapping )) {
350448 throw new NullPointerException ("The clarinLicenseResourceMapping object is null." );
351449 }
@@ -359,9 +457,8 @@ private ClarinLicense getClarinLicense(Context context, UUID bitstreamUUID,
359457 return clarinLicense ;
360458 }
361459
362- private boolean shouldEmailToken (Context context , UUID bitstreamUUID ,
363- ClarinLicenseResourceMapping clarinLicenseResourceMapping ) throws SQLException {
364- ClarinLicense clarinLicense = this .getClarinLicense (context , bitstreamUUID , clarinLicenseResourceMapping );
460+ private boolean shouldEmailToken (ClarinLicenseResourceMapping clarinLicenseResourceMapping ) {
461+ ClarinLicense clarinLicense = this .getClarinLicense (clarinLicenseResourceMapping );
365462 if (Objects .isNull (clarinLicense )) {
366463 throw new NullPointerException ("The ClarinLicense is null." );
367464 }
0 commit comments