org.dspace.app.cris.batch.ScriptStatSubscribe.java Source code

Java tutorial

Introduction

Here is the source code for org.dspace.app.cris.batch.ScriptStatSubscribe.java

Source

/**
 * The contents of this file are subject to the license and copyright
 * detailed in the LICENSE and NOTICE files at the root of the source
 * tree and available online at
 *
 * https://github.com/CILEA/dspace-cris/wiki/License
 */
package org.dspace.app.cris.batch;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import javax.mail.MessagingException;

import jxl.CellView;
import jxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.PosixParser;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.solr.client.solrj.SolrServerException;
import org.dspace.app.cris.model.StatSubscription;
import org.dspace.app.cris.statistics.SummaryStatBean;
import org.dspace.app.cris.statistics.service.StatSubscribeService;
import org.dspace.app.cris.statistics.util.StatsConfig;
import org.dspace.core.ConfigurationManager;
import org.dspace.core.Context;
import org.dspace.core.Email;
import org.dspace.core.I18nUtil;
import org.dspace.core.LogManager;
import org.dspace.discovery.SearchServiceException;
import org.dspace.eperson.EPerson;
import org.dspace.statistics.SolrLogger;
import org.dspace.utils.DSpace;

/**
 * Class defining methods for sending statistics update to users
 * 
 * @author Andrea Bollini
 * @version $Revision: 3762 $
 */
public class ScriptStatSubscribe {
    /** log4j logger */
    private static Logger log = Logger.getLogger(ScriptStatSubscribe.class);

    /**
     * Process subscriptions. Should be run only one time to day, otherwise
     * duplicate notification could be send.
     * 
     * @param service
     * 
     * @param context
     *            DSpace context object
     * @param test
     * @throws SearchServiceException
     */
    public static void processDaily(DSpace dspace, StatSubscribeService service, Context context, int freq,
            boolean test) throws SQLException, IOException {
        EPerson currentEPerson = null;
        List<StatSubscription> rpSubscriptions = service.getAllStatSubscriptionByFreq(freq);
        for (StatSubscription rpSubscription : rpSubscriptions) {
            // Does this row relate to the same e-person as the last?
            if ((currentEPerson == null) || (rpSubscription.getEpersonID() != currentEPerson.getID())) {
                // New e-person. Send mail for previous e-person
                if (currentEPerson != null) {
                    try {
                        sendEmail(context, service, currentEPerson, rpSubscriptions, freq, test);
                    } catch (MessagingException me) {
                        log.error("Failed to send stat subscription to eperson_id=" + currentEPerson.getID());
                        log.error(me);
                    }
                }

                currentEPerson = EPerson.find(context, rpSubscription.getEpersonID());
                rpSubscriptions = new ArrayList<StatSubscription>();
            }
            rpSubscriptions.add(rpSubscription);
        }
        // Process the last person
        if (currentEPerson != null) {
            try {
                sendEmail(context, service, currentEPerson, rpSubscriptions, freq, test);
            } catch (MessagingException me) {
                log.error("Failed to send stat subscription to eperson_id=" + currentEPerson.getID());
                log.error(me);
            }
        }
    }

    /**
     * Sends an email to the given e-person with statistics details of the
     * subscribed objects.
     * 
     * @param context
     *            DSpace context object
     * @param eperson
     *            eperson to send to
     * @param statSubscriptions
     *            List of DSpace Objects
     * @param test
     * @throws IOException
     */
    public static void sendEmail(Context context, StatSubscribeService service, EPerson eperson,
            List<StatSubscription> statSubscriptions, int freq, boolean test)
            throws MessagingException, IOException {
        String sfreq = null;
        switch (freq) {
        case StatSubscription.FREQUENCY_DAILY:
            sfreq = "daily";
            break;

        case StatSubscription.FREQUENCY_WEEKLY:
            sfreq = "weekly";
            break;

        case StatSubscription.FREQUENCY_MONTHLY:
            sfreq = "monthly";
            break;

        default:
            throw new IllegalArgumentException("Unknow frequency: " + freq);
        }

        // Get a resource bundle according to the eperson language preferences
        Locale supportedLocale = I18nUtil.getEPersonLocale(eperson);

        String tmpfile = ConfigurationManager.getProperty(SolrLogger.CFG_STAT_MODULE, "subscribe-stat.tmpdir")
                + File.separator + "stat-" + sfreq + eperson.getID() + "_" + Thread.currentThread().getId()
                + ".xls";
        File file = new File(tmpfile);
        OutputStream os = null;
        try {
            os = new FileOutputStream(tmpfile);

            WritableWorkbook workbook = Workbook.createWorkbook(os);

            int r = 0;
            WritableSheet sheet = null;
            int sheetNumber = 0;

            int oldType = -1;
            for (StatSubscription statSub : statSubscriptions) {
                boolean changedType = false;
                if (oldType != statSub.getTypeDef()) {
                    changedType = true;
                    r = 0;
                }
                oldType = statSub.getTypeDef();
                SummaryStatBean statdetails = getStatBean(context, service, statSub);

                r++;
                if (statdetails == null)
                    continue;

                SummaryStatBean.StatDataBean statDataBean = statdetails.getData().get(0);

                if (changedType) {
                    sheet = workbook.createSheet(
                            I18nUtil.getMessage("it.cilea.hku.statistics.Subscribe.sheet." + statdetails.getType()),
                            sheetNumber);
                    WritableFont labelFont = new WritableFont(WritableFont.ARIAL, 10, WritableFont.BOLD);
                    WritableCellFormat cfobj = new WritableCellFormat(labelFont);
                    sheet.addCell(
                            new Label(0, 0, I18nUtil.getMessage("it.cilea.hku.statistics.Subscribe.type"), cfobj));
                    sheet.addCell(
                            new Label(1, 0, I18nUtil.getMessage("it.cilea.hku.statistics.Subscribe.name"), cfobj));
                    sheet.addCell(
                            new Label(2, 0, I18nUtil.getMessage("it.cilea.hku.statistics.Subscribe.url"), cfobj));
                    sheet.addCell(new Label(3, 0,
                            I18nUtil.getMessage("it.cilea.hku.statistics.Subscribe.totalView"), cfobj));
                    sheet.addCell(new Label(4, 0,
                            I18nUtil.getMessage("it.cilea.hku.statistics.Subscribe." + sfreq + "View"), cfobj));

                    int headerCell = 4;
                    if (statDataBean.isShowSelectedObjectDownload()) {
                        sheet.addCell(new Label(++headerCell, 0,
                                I18nUtil.getMessage("it.cilea.hku.statistics.Subscribe.totalDownload"), cfobj));
                        sheet.addCell(new Label(++headerCell, 0,
                                I18nUtil.getMessage("it.cilea.hku.statistics.Subscribe." + sfreq + "Download"),
                                cfobj));
                    }
                    for (String topKey : statDataBean.getPeriodAndTotalTopView().keySet()) {
                        if (!statDataBean.getPeriodAndTotalTopView().get(topKey).isEmpty()) {
                            sheet.addCell(
                                    new Label(++headerCell, 0,
                                            I18nUtil.getMessage(
                                                    "it.cilea.hku.statistics.Subscribe.total" + topKey + "View"),
                                            cfobj));
                            sheet.addCell(new Label(++headerCell, 0,
                                    I18nUtil.getMessage(
                                            "it.cilea.hku.statistics.Subscribe." + sfreq + topKey + "View"),
                                    cfobj));
                        }
                    }
                    for (String topKey : statDataBean.getPeriodAndTotalTopDownload().keySet()) {
                        if (!statDataBean.getPeriodAndTotalTopDownload().get(topKey).isEmpty()) {
                            sheet.addCell(new Label(++headerCell, 0,
                                    I18nUtil.getMessage(
                                            "it.cilea.hku.statistics.Subscribe.total" + topKey + "Download"),
                                    cfobj));
                            sheet.addCell(new Label(++headerCell, 0,
                                    I18nUtil.getMessage(
                                            "it.cilea.hku.statistics.Subscribe." + sfreq + topKey + "Download"),
                                    cfobj));
                        }
                    }
                    for (int i = 0; i < headerCell; i++) {
                        final CellView view = sheet.getColumnView(i);
                        view.setAutosize(true);
                        sheet.setColumnView(i, view);
                    }
                    sheetNumber++;
                }
                sheet.addCell(new Label(0, r,
                        I18nUtil.getMessage("it.cilea.hku.statistics.Subscribe.type." + statdetails.getType())));
                sheet.addCell(new Label(1, r, statdetails.getObjectName()));
                sheet.addCell(new Label(2, r, statdetails.getObjectURL()));
                if (statDataBean.getTotalSelectedView() == -1) {
                    sheet.addCell(new Label(3, r, I18nUtil.getMessage("it.cilea.hku.statistics.Subscribe.na")));
                } else {
                    sheet.addCell(new Label(3, r, new Long(statDataBean.getTotalSelectedView()).toString()));
                }

                if (statDataBean.getPeriodSelectedView() == -1) {
                    sheet.addCell(new Label(4, r, I18nUtil.getMessage("it.cilea.hku.statistics.Subscribe.na")));
                } else {
                    sheet.addCell(new Label(4, r, new Long(statDataBean.getPeriodSelectedView()).toString()));
                }

                int countTopCell = 4;
                if (statDataBean.isShowSelectedObjectDownload()) {
                    if (statDataBean.getTotalSelectedDownload() == -1) {
                        sheet.addCell(new Label(++countTopCell, r,
                                I18nUtil.getMessage("it.cilea.hku.statistics.Subscribe.na")));
                    } else {
                        sheet.addCell(new Label(++countTopCell, r,
                                new Long(statDataBean.getTotalSelectedDownload()).toString()));
                    }
                    if (statDataBean.getPeriodSelectedDownload() == -1) {
                        sheet.addCell(new Label(++countTopCell, r,
                                I18nUtil.getMessage("it.cilea.hku.statistics.Subscribe.na")));
                    } else {
                        sheet.addCell(new Label(++countTopCell, r,
                                new Long(statDataBean.getPeriodSelectedDownload()).toString()));
                    }

                }
                for (String topKey : statDataBean.getPeriodAndTotalTopView().keySet()) {
                    List<Long> tmpList = statDataBean.getPeriodAndTotalTopView().get(topKey);
                    if (!tmpList.isEmpty()) {
                        if (tmpList.get(1) == null) {
                            sheet.addCell(new Label(++countTopCell, r,
                                    I18nUtil.getMessage("it.cilea.hku.statistics.Subscribe.na")));
                        } else {
                            sheet.addCell(new Label(++countTopCell, r, new Long(tmpList.get(1)).toString()));
                        }
                    }
                    if (!tmpList.isEmpty()) {
                        if (tmpList.get(0) == null) {
                            sheet.addCell(new Label(++countTopCell, r,
                                    I18nUtil.getMessage("it.cilea.hku.statistics.Subscribe.na")));
                        } else {
                            sheet.addCell(new Label(++countTopCell, r, new Long(tmpList.get(0)).toString()));
                        }
                    }
                }
                for (String topKey : statDataBean.getPeriodAndTotalTopDownload().keySet()) {
                    List<Long> tmpList = statDataBean.getPeriodAndTotalTopDownload().get(topKey);
                    if (!tmpList.isEmpty()) {
                        if (tmpList.get(1) == null) {
                            sheet.addCell(new Label(++countTopCell, r,
                                    I18nUtil.getMessage("it.cilea.hku.statistics.Subscribe.na")));
                        } else {
                            sheet.addCell(new Label(++countTopCell, r, new Long(tmpList.get(1)).toString()));
                        }
                    }
                    if (!tmpList.isEmpty()) {
                        if (tmpList.get(0) == null) {
                            sheet.addCell(new Label(++countTopCell, r,
                                    I18nUtil.getMessage("it.cilea.hku.statistics.Subscribe.na")));
                        } else {
                            sheet.addCell(new Label(++countTopCell, r, new Long(tmpList.get(0)).toString()));
                        }
                    }
                }

            }
            workbook.write();
            workbook.close();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new MessagingException("Failed to create the stat report attachment", e);
        } finally {
            if (os != null) {
                os.close();
            }
        }

        if (test) {
            System.out.println("After check remove the follow file: " + tmpfile);
        } else {
            Email email = Email.getEmail(I18nUtil.getEmailFilename(supportedLocale, "statsubscription-" + sfreq));
            email.addRecipient(eperson.getEmail());
            email.addArgument(ConfigurationManager.getProperty("dspace.url")
                    + "/rp/tools/stats/subscription/unsubscribe?clear=all");
            email.addArgument(
                    ConfigurationManager.getProperty("dspace.url") + "/rp/tools/stats/subscription/list.htm");
            email.addAttachment(file, "stat-" + sfreq + "-update.xls");
            email.send();
            file.delete();
        }
        log.info(LogManager.getHeader(context, "sent_statsubscription",
                "eperson_id=" + eperson.getID() + ", freq=" + sfreq));
    }

    private static SummaryStatBean getStatBean(Context context, StatSubscribeService service,
            StatSubscription statSub) throws SolrServerException, SQLException {
        try {
            return service.getStatBean(context, statSub.getUid(), statSub.getTypeDef(), statSub.getFreq(), 1);
        } catch (IllegalArgumentException e) {
            log.warn("Found invalid StatSubscription - StatSubscriptionID: " + statSub.getId(), e);
            return null;
        }
    }

    /**
     * Method for invoking subscriptions via the command line
     * 
     * @param argv
     *            command-line arguments, none used yet
     */
    public static void main(String[] argv) {
        log.info("#### START STAT SUBSCRIBE: -----" + new Date() + " ----- ####");
        String usage = "org.dspace.app.cris.batch.ScriptStatSubscribe [-t] or nothing to send out subscriptions.";

        Options options = new Options();
        HelpFormatter formatter = new HelpFormatter();
        CommandLine line = null;

        {
            Option opt = new Option("m", "mode", true, "mode (1: daily, 7: weekly, 30: monthly)");
            opt.setRequired(true);
            options.addOption(opt);
        }

        {
            Option opt = new Option("t", "test", false, "Run test session");
            opt.setRequired(false);
            options.addOption(opt);
        }

        {
            Option opt = new Option("h", "help", false, "Print this help message");
            opt.setRequired(false);
            options.addOption(opt);
        }

        try {
            line = new PosixParser().parse(options, argv);
        } catch (Exception e) {
            // automatically generate the help statement
            formatter.printHelp(usage, e.getMessage(), options, "");
            System.exit(1);
        }

        String sfreq = line.getOptionValue('m');

        int freq = 0;

        try {
            freq = Integer.parseInt(sfreq);
        } catch (NumberFormatException nfe) {
            // ... do nothing as we deal with this next freq = 0

        }

        switch (freq) {
        case StatSubscription.FREQUENCY_DAILY:
        case StatSubscription.FREQUENCY_WEEKLY:
        case StatSubscription.FREQUENCY_MONTHLY:
            // ok
            break;
        default:
            System.out.println("Mode MUST be one of 1, 7 or 30");
            System.exit(1);
            break;
        }

        if (line.hasOption("h")) {
            // automatically generate the help statement
            formatter.printHelp(usage, options);
            System.exit(1);
        }

        boolean test = line.hasOption("t");

        if (test)
            log.setLevel(Level.DEBUG);
        Context context = null;
        try {
            DSpace dspace = new DSpace();
            StatSubscribeService service = dspace.getServiceManager().getServiceByName("statSubscribeService",
                    StatSubscribeService.class);

            context = new Context();
            processDaily(dspace, service, context, freq, test);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            if (context != null && context.isValid()) {
                // Nothing is actually written
                context.abort();
            }
        }
        log.info("#### END: -----" + new Date() + " ----- ####");
        // System.exit(0);
    }
}