Java tutorial
/** * 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 */ /* * Subscribe.java * * Version: $Revision: 3762 $ * * Date: $Date: 2009-05-07 06:36:47 +0200 (gio, 07 mag 2009) $ * * Copyright (c) 2002-2009, The DSpace Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of the DSpace Foundation nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. */ package org.dspace.app.cris.batch; import java.io.IOException; import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; import javax.mail.MessagingException; 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.SolrQuery; import org.apache.solr.client.solrj.response.QueryResponse; import org.apache.solr.common.SolrDocument; import org.apache.solr.common.SolrDocumentList; import org.dspace.app.cris.configuration.RelationConfiguration; import org.dspace.app.cris.discovery.CrisSearchService; import org.dspace.app.cris.integration.CrisComponentsService; import org.dspace.app.cris.integration.ICRISComponent; import org.dspace.app.cris.model.CrisConstants; import org.dspace.app.cris.model.CrisSubscription; import org.dspace.app.cris.service.ApplicationService; import org.dspace.app.cris.util.Researcher; import org.dspace.app.cris.util.ResearcherPageUtils; import org.dspace.content.DCValue; import org.dspace.content.Item; import org.dspace.core.ConfigurationManager; import org.dspace.core.Constants; 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.eperson.Subscribe; import org.dspace.handle.HandleManager; /** * Class defining methods for sending new item e-mail alerts to users. Based on * {@link Subscribe} written by Robert Tansley * * @author pascarelli */ public class ScriptCrisSubscribe { /** log4j logger */ private static Logger log = Logger.getLogger(ScriptCrisSubscribe.class); private static Map<Integer, List<String>> mapRelationFields = new HashMap<Integer, List<String>>(); /** * Process subscriptions. This must be invoked only once a day. Messages are * only sent out when a rp has actually received new items, so that people's * mailboxes are not clogged with many "no new items" mails. * <P> * Yesterday's newly available items are included. If this is run at for * example midday, any items that have been made available during the * current day will not be included, but will be included in the next day's * run. * <P> * For example, if today's date is 2002-10-10 (in UTC) items made available * during 2002-10-09 (UTC) will be included. * * @param applicationService * * @param context * DSpace context object * @param test * @throws SearchServiceException */ public static void processDaily(Researcher researcher, ApplicationService applicationService, Context context, boolean test) throws SQLException, IOException, SearchServiceException { List<CrisSubscription> rpSubscriptions = applicationService.getList(CrisSubscription.class); EPerson currentEPerson = null; List<String> rpkeys = null; // List of rp keys List<String> relationField = new LinkedList<String>(); for (CrisSubscription 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 { relationField = mapRelationFields.get(rpSubscription.getTypeDef()); sendEmail(researcher, context, currentEPerson, rpkeys, test, relationField); } catch (MessagingException me) { log.error("Failed to send subscription to eperson_id=" + currentEPerson.getID()); log.error(me); } } currentEPerson = EPerson.find(context, rpSubscription.getEpersonID()); rpkeys = new ArrayList<String>(); } rpkeys.add(ResearcherPageUtils .getPersistentIdentifier(applicationService.getEntityByUUID(rpSubscription.getUuid()))); } // Process the last person if (currentEPerson != null) { try { sendEmail(researcher, context, currentEPerson, rpkeys, test, relationField); } catch (MessagingException me) { log.error("Failed to send subscription to eperson_id=" + currentEPerson.getID()); log.error(me); } } } /** * Sends an email to the given e-person with details of new items in the * given dspace object (MUST be a community or a collection), items that * appeared yesterday. No e-mail is sent if there aren't any new items in * any of the dspace objects. * * @param context * DSpace context object * @param eperson * eperson to send to * @param rpkeys * List of DSpace Objects * @param test * @throws SearchServiceException */ public static void sendEmail(Researcher researcher, Context context, EPerson eperson, List<String> rpkeys, boolean test, List<String> relationFields) throws IOException, MessagingException, SQLException, SearchServiceException { CrisSearchService searchService = researcher.getCrisSearchService(); // Get a resource bundle according to the eperson language preferences Locale supportedLocale = I18nUtil.getEPersonLocale(eperson); StringBuffer emailText = new StringBuffer(); boolean isFirst = true; for (String rpkey : rpkeys) { SolrQuery query = new SolrQuery(); query.setFields("search.resourceid"); query.addFilterQuery("{!field f=search.resourcetype}" + Constants.ITEM, "{!field f=inarchive}true"); for (String tmpRelations : relationFields) { String fq = "{!field f=" + tmpRelations + "}" + rpkey; query.addFilterQuery(fq); } query.setRows(Integer.MAX_VALUE); if (ConfigurationManager.getBooleanProperty("eperson.subscription.onlynew", false)) { // get only the items archived yesterday query.setQuery("dateaccessioned:(NOW/DAY-1DAY)"); } else { // get all item modified yesterday but not published the day // before // and all the item modified today and archived yesterday query.setQuery( "(item.lastmodified:(NOW/DAY-1DAY) AND dateaccessioned:(NOW/DAY-1DAY)) OR ((item.lastmodified:(NOW/DAY) AND dateaccessioned:(NOW/DAY-1DAY)))"); } QueryResponse qResponse = searchService.search(query); SolrDocumentList results = qResponse.getResults(); // Only add to buffer if there are new items if (results.getNumFound() > 0) { if (!isFirst) { emailText.append("\n---------------------------------------\n"); } else { isFirst = false; } emailText.append(I18nUtil.getMessage("org.dspace.eperson.Subscribe.new-items", supportedLocale)) .append(" ").append(rpkey).append(": ").append(results.getNumFound()).append("\n\n"); for (SolrDocument solrDoc : results) { Item item = Item.find(context, (Integer) solrDoc.getFieldValue("search.resourceid")); DCValue[] titles = item.getDC("title", null, Item.ANY); emailText.append(" ") .append(I18nUtil.getMessage("org.dspace.eperson.Subscribe.title", supportedLocale)) .append(" "); if (titles.length > 0) { emailText.append(titles[0].value); } else { emailText.append( I18nUtil.getMessage("org.dspace.eperson.Subscribe.untitled", supportedLocale)); } DCValue[] authors = item.getDC("contributor", Item.ANY, Item.ANY); if (authors.length > 0) { emailText.append("\n ").append( I18nUtil.getMessage("org.dspace.eperson.Subscribe.authors", supportedLocale)) .append(" ").append(authors[0].value); for (int k = 1; k < authors.length; k++) { emailText.append("\n ").append(authors[k].value); } } emailText.append("\n ") .append(I18nUtil.getMessage("org.dspace.eperson.Subscribe.id", supportedLocale)) .append(" ").append(HandleManager.getCanonicalForm(item.getHandle())).append("\n\n"); context.removeCached(item, item.getID()); } } } // Send an e-mail if there were any new items if (emailText.length() > 0) { if (test) { log.info(LogManager.getHeader(context, "subscription:", "eperson=" + eperson.getEmail())); log.info(LogManager.getHeader(context, "subscription:", "text=" + emailText.toString())); } else { Email email = Email.getEmail(I18nUtil.getEmailFilename(supportedLocale, "subscription")); email.addRecipient(eperson.getEmail()); email.addArgument(emailText.toString()); email.send(); log.info(LogManager.getHeader(context, "sent_subscription", "eperson_id=" + eperson.getID())); } } } /** * 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 DELETE: -----" + new Date() + " ----- ####"); String usage = "it.cilea.hku.authority.ScriptRPSubscribe [-t] or nothing to send out subscriptions."; Options options = new Options(); HelpFormatter formatter = new HelpFormatter(); CommandLine line = null; { 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); } 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 { context = new Context(); Researcher researcher = new Researcher(); ApplicationService applicationService = researcher.getApplicationService(); List<CrisComponentsService> serviceComponent = researcher.getAllCrisComponents(); for (CrisComponentsService service : serviceComponent) { for (ICRISComponent component : service.getComponents().values()) { RelationConfiguration relationConfiguration = component.getRelationConfiguration(); if (Item.class.isAssignableFrom(relationConfiguration.getRelationClass())) { Integer key = CrisConstants.getEntityType(component.getTarget()); String query = relationConfiguration.getQuery(); if (!mapRelationFields.containsKey(key)) { List<String> rels = new LinkedList<String>(); rels.add(query); mapRelationFields.put(key, rels); } else { mapRelationFields.get(key).add(query); } } } } processDaily(researcher, applicationService, context, 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); } }