/*
* [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