package org.dspace.app.itemexport;
import java.io.File;
import java.io.FileOutputStream;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.concurrent.Callable;
import org.apache.log4j.Logger;
import org.dspace.content.Item;
import org.dspace.content.ItemIterator;
import org.dspace.content.packager.PackageDisseminator;
import org.dspace.content.packager.PackageIngester;
import org.dspace.content.packager.PackageParameters;
import org.dspace.core.ConfigurationManager;
import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.dspace.core.PluginManager;
import org.dspace.eperson.EPerson;
import org.dspace.eperson.Group;
import uk.ac.jorum.licence.ItemLicence;
import uk.ac.jorum.licence.LicenceController;
import uk.ac.jorum.utils.ExceptionLogger;
class CallableExport implements Callable<Integer> {
private EPerson eperson = null;
private String email = null;
private ArrayList<Integer> items;
private boolean migrate;
private final boolean imsDissemination = ConfigurationManager.getBooleanProperty("ims.dissemination.enable");
private static final String ZIP_EXTENSION = ".zip";
/** log4j category */
private static Logger log = Logger.getLogger(CallableExport.class);
/**
* Constructor
*
* @param eperson
* eperson requesting export
**/
public CallableExport(EPerson eperson, ArrayList<Integer> items, Boolean migrate) {
this.eperson = eperson;
this.items = items;
this.migrate = migrate;
}
/**
* Constructor
*
* @param email
* email address of user requesting export
**/
public CallableExport(String email, ArrayList<Integer> items, Boolean migrate) {
this.email = email;
this.items = items;
this.migrate = migrate;
}
public Integer call() throws Exception {
Context context = null;
ItemIterator iitems = null;
try {
// create a new dspace context
context = new Context();
// ignore auths
context.setIgnoreAuthorization(true);
iitems = new ItemIterator(context, items);
// GWaller IssueID #579 26/1/11 Need to block export if user isn't authorized to view resource
//NOTE: Creating a new ItemIterator so that the original iterator isn't altered (this is used later)
ItemIterator tempIterator = new ItemIterator(context, items);
Item itemToExport = tempIterator.next();
tempIterator.close();
boolean authorised = false;
ItemLicence itemLicence = LicenceController.getItemLicence(itemToExport);
if (itemLicence != null){
Group[] authorisedGroups = itemLicence.authorisedGroupsForViewing();
if (authorisedGroups.length == 0){
authorised = true;
} else {
// Check to see if the current user belongs to one of the groups
// Make sure the user is set in the context
context.setCurrentUser(eperson);
// NOTE: if the user hasn't logged in ie its an anon export, they won't match any groups
// Do we need to lookup the eperson based on an email?
for (Group g: authorisedGroups){
if (Group.isMember(context, g.getID())){
authorised = true;
break;
}
}
}
} else {
// Couldn't find a licence on the item - allow the export as no licence prohibits it
authorised = true;
}
if (!authorised){
throw new Exception("You are not authorised to export the resource due to the licence");
}
String fileName = null;
String downloadDir = null;
if (eperson != null) {
fileName = ItemExport.assembleFileName("item", eperson, new Date());
downloadDir = ItemExport.getExportDownloadDirectory(eperson.getID());
}
if (email != null) {
fileName = AnonItemExport.assembleFileName("item", email, new Date());
downloadDir = AnonItemExport.getExportDownloadDirectory();
}
String workDir = ItemExport.getExportWorkDirectory() + System.getProperty("file.separator") + fileName;
File dnDir = new File(downloadDir);
if (!dnDir.exists()) {
dnDir.mkdirs();
}
//If this flag is true, we will attempt to export the item as an IMS CP. Otherwise, export in the normal Dspace format.
if (imsDissemination) {
String imsZip = new StringBuilder(fileName).append(ZIP_EXTENSION).toString();
File imsContentPackage = new File(dnDir, imsZip);
if (!imsContentPackage.exists()) {
imsContentPackage.createNewFile();
log.debug("Created file for ims dissemination: " + imsZip);
}
//TODO: "IMS" shouldn't be hard coded here
PackageDisseminator dip = (PackageDisseminator) PluginManager.getNamedPlugin(PackageDisseminator.class,
"IMS");
PackageParameters params = new PackageParameters();
params.addProperty(Constants.METADATA_FORMAT_LABEL,
Constants.SupportedDisseminationMetadataFormats.QDC.toString());
dip.disseminate(context, iitems.next(), params, new FileOutputStream(imsContentPackage));
} else {
File wkDir = new File(workDir);
if (!wkDir.exists()) {
wkDir.mkdirs();
}
// export the items using normal export method
ItemExport.exportItem(context, iitems, workDir, 1, migrate);
// now zip up the export directory created above
ItemExport.zip(workDir,
new StringBuilder(downloadDir).append(File.separator).append(fileName).append(ZIP_EXTENSION)
.toString());
}
// email message letting user know the file is ready for download
if (eperson != null)
ItemExport.emailSuccessMessage(context, eperson, fileName + ".zip");
if (email != null)
AnonItemExport.emailSuccessMessage(context, email, fileName + ".zip");
// return to enforcing auths
context.setIgnoreAuthorization(false);
} catch (Exception e1) {
ExceptionLogger.logException(log, e1);
try {
if (eperson != null)
ItemExport.emailErrorMessage(eperson, e1.getMessage());
if (email != null)
AnonItemExport.emailErrorMessage(email, e1.getMessage());
} catch (Exception e) {
// wont throw here
}
throw new RuntimeException(e1);
} finally {
if (iitems != null)
iitems.close();
// Make sure the database connection gets closed in all conditions.
try {
context.complete();
} catch (SQLException sqle) {
context.abort();
}
}
return 1;
}
}