/* * [SentEmailTracker.java] * * Summary: A persistent cache of email ids we have already sent. Used to ensure we don't process an email twice. * * Copyright: (c) 2002-2017 Roedy Green, Canadian Mind Products, http://mindprod.com * * Licence: This software may be copied and used freely for any purpose but military. * http://mindprod.com/contact/nonmil.html * * Requires: JDK 1.8+ * * Created with: JetBrains IntelliJ IDEA IDE http://www.jetbrains.com/idea/ * * Version History: * 1.7 2007-08-21 tidy code, fix MX-Comparator so will work even if no * riorities on MX records, add VALIDATE_EMAIL_SERVERS configuration parameter * o can run where IAP blocks mailserver access. */ package com.mindprod.bulk; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.HashMap; import java.util.Iterator; import static com.mindprod.bulk.CustConfig.CUST_ABBREVIATION; import static java.lang.System.*; /** * A persistent cache of email ids we have already sent. Used to ensure we don't process an email twice. *

* priorities on MX records, add VALIDATE_EMAIL_SERVERS configuration parameter * so can run where IAP blocks mailserver access. * * @author Roedy Green, Canadian Mind Products * @version 1.7 2007-08-21 tidy code, fix MX-Comparator so will work even if no * riorities on MX records, add VALIDATE_EMAIL_SERVERS configuration parameter * o can run where IAP blocks mailserver access. * @since 2002-08-29 */ final class SentEmailTracker { /** * name of the file where we cache message ids of previously sent emails. */ private static final String SENT_EMAILS_CACHE_FILE = CUST_ABBREVIATION + "-sent-emails-cache.ser"; /** * collection of previously probed AlreadySent email ids, one per batch, not one per recipient. */ private static HashMap sentEmailsCache; static { /* load up serialised cache from before */ fireup(); } /** * Called when class is loaded to reconstitute the serialised cache. Called automatically when class is loaded. */ @SuppressWarnings( "unchecked" ) private static void fireup() { try { // O P E N FileInputStream fis = new FileInputStream( SENT_EMAILS_CACHE_FILE ); ObjectInputStream ois = new ObjectInputStream( fis ); // R E A D sentEmailsCache = ( HashMap ) ois.readObject(); // C L O S E ois.close(); } catch ( Exception e ) { out.println( "Troubles restoring the " + SENT_EMAILS_CACHE_FILE + " file. Not to worry, starting afresh." ); sentEmailsCache = new HashMap<>( 32, 0.75f ); } } // end fireup /** * Test if this email id has been sent before. * * @param id email id. * * @return true if the email has been sent before. */ static boolean isAlreadySent( String id ) { return id != null && sentEmailsCache.get( id.trim().toLowerCase() ) != null; } /** * Mark this email batch as sent. * * @param id email id. */ static void markSent( String id ) { if ( id == null ) { return; } id = id.trim().toLowerCase(); sentEmailsCache.put( id, new AlreadySent( id ) ); } /** * Called when class is shut down to save the cache in serialised form. */ public static void close() { flush(); sentEmailsCache = null; } // end close /** * Save contents of cache to disk. */ public static void flush() { try { // C U L L for ( Iterator iter = sentEmailsCache.values().iterator(); iter.hasNext(); ) { AlreadySent a = iter.next(); if ( a.shouldCull() ) { iter.remove();// avoid ConcurrentModificationException } } // end for // O P E N FileOutputStream fos = new FileOutputStream( SENT_EMAILS_CACHE_FILE, false /* append */ ); ObjectOutputStream oos = new ObjectOutputStream( fos ); // W R I T E oos.writeObject( sentEmailsCache ); // C L O S E oos.close(); } catch ( IOException e ) { err.println(); e.printStackTrace( err ); err.println( "Troubles writing out the " + SENT_EMAILS_CACHE_FILE + " file" ); err.println(); } } // end flush } // end SentEmailTracker