Subversion Repositories javautils

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
  3.  * Copyright 2009 Jason Mehrens. All Rights Reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  *   - Redistributions of source code must retain the above copyright
  10.  *     notice, this list of conditions and the following disclaimer.
  11.  *
  12.  *   - Redistributions in binary form must reproduce the above copyright
  13.  *     notice, this list of conditions and the following disclaimer in the
  14.  *     documentation and/or other materials provided with the distribution.
  15.  *
  16.  *   - Neither the name of Sun Microsystems nor the names of its
  17.  *     contributors may be used to endorse or promote products derived
  18.  *     from this software without specific prior written permission.
  19.  *
  20.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  21.  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  22.  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  23.  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  24.  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  25.  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  26.  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  27.  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  28.  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  29.  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  30.  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31.  */
  32.  
  33.  
  34. import com.sun.mail.util.logging.MailHandler;
  35. import java.util.logging.*;
  36. import javax.mail.*;
  37. import java.util.Comparator;
  38. import java.io.*;
  39.  
  40. /**
  41.  * Demo for the different configurations for the MailHandler.
  42.  * If the logging properties file or class is not specified then this
  43.  * demo will apply some default settings to store emails in the users temp dir.
  44.  * @author Jason Mehrens
  45.  */
  46. public class MailHandlerDemo {
  47.  
  48.     private static final String CLASS_NAME = MailHandlerDemo.class.getName();
  49.     private static final Logger LOGGER = Logger.getLogger(CLASS_NAME);
  50.  
  51.     /**
  52.      * @param args the command line arguments
  53.      */
  54.     public static void main(String[] args) {
  55.         init(); //may create log messages.
  56.         try {
  57.             LOGGER.log(Level.FINEST, "This is the finest part of the demo.",
  58.                     new MessagingException("Fake"));
  59.             LOGGER.log(Level.FINER, "This is the finer part of the demo.",
  60.                     new NullPointerException("Fake"));
  61.             LOGGER.log(Level.FINE, "This is the fine part of the demo.");
  62.             LOGGER.log(Level.CONFIG, "Logging config file is {0}.", getConfigLocation());
  63.             LOGGER.log(Level.INFO, "Your temp directory is {0}, please wait...", getTempDir());
  64.  
  65.             try { //waste some time for the custom formatter.
  66.                 Thread.sleep(3L * 1000L);
  67.             } catch (InterruptedException ex) {
  68.                 Thread.currentThread().interrupt();
  69.             }
  70.  
  71.             LOGGER.log(Level.WARNING, "This is a warning.", new FileNotFoundException("Fake"));
  72.             LOGGER.log(Level.SEVERE, "The end of the demo.", new IOException("Fake"));
  73.         } finally {
  74.             closeHandlers();
  75.         }
  76.     }
  77.  
  78.     /**
  79.      * Example for body only messages.
  80.      * On close the remaining messages are sent.
  81.      */
  82.     private static void initBodyOnly() {
  83.         MailHandler h = new MailHandler();
  84.         h.setSubject("Body only demo");
  85.         LOGGER.addHandler(h);
  86.     }
  87.  
  88.     /**
  89.      * Example showing that when the mail handler reaches capacity it
  90.      * will format and send the current records.  Capacity is used to roughly
  91.      * limit the size of an outgoing message.
  92.      * On close any remaining messages are sent.
  93.      */
  94.     private static void initLowCapacity() {
  95.         MailHandler h = new MailHandler(5);
  96.         h.setSubject("Low capacity demo");
  97.         LOGGER.addHandler(h);
  98.     }
  99.  
  100.     /**
  101.      * Example for body only messages.
  102.      * On close any remaining messages are sent.
  103.      */
  104.     private static void initSimpleAttachment() {
  105.         MailHandler h = new MailHandler();
  106.         h.setSubject("Body and attachment demo");
  107.         h.setAttachmentFormatters(new Formatter[]{new XMLFormatter()});
  108.         h.setAttachmentNames(new String[]{"data.xml"});
  109.         LOGGER.addHandler(h);
  110.     }
  111.  
  112.     /**
  113.      * Example setup for priority messages by level.
  114.      * If the push level is triggered the message is high priority.
  115.      * Otherwise, on close any remaining messages are sent.
  116.      */
  117.     private static void initWithPushLevel() {
  118.         MailHandler h = new MailHandler();
  119.         h.setSubject("Push level demo");
  120.         h.setPushLevel(Level.WARNING);
  121.         LOGGER.addHandler(h);
  122.     }
  123.  
  124.     /**
  125.      * Example for priority messages by custom trigger.
  126.      * If the push filter is triggered the message is high priority.
  127.      * Otherwise, on close any remaining messages are sent.
  128.      */
  129.     private static void initWithPushFilter() {
  130.         MailHandler h = new MailHandler();
  131.         h.setSubject("Push on MessagingException demo");
  132.         h.setPushLevel(Level.ALL);
  133.         h.setPushFilter(new MessageErrorsFilter(true));
  134.         LOGGER.addHandler(h);
  135.     }
  136.  
  137.     /**
  138.      * Example for circular buffer behavior.  The level, push level, and
  139.      * capacity are set the same so that the memory handler push results
  140.      * in a mail handler push.  All messages are high priority.
  141.      * On close any remaining records are discarded because they never reach
  142.      * the mail handler.
  143.      */
  144.     private static void initPushOnly() {
  145.         final int capacity = 3;
  146.         final Level pushLevel = Level.WARNING;
  147.         final MailHandler h = new MailHandler(capacity);
  148.         h.setPushLevel(pushLevel);
  149.         h.setSubject("Push only demo");
  150.         MemoryHandler m = new MemoryHandler(h, capacity, pushLevel);
  151.         h.setLevel(m.getLevel());
  152.         LOGGER.addHandler(m);
  153.         pushOnlyHandler = h;
  154.     }
  155.     private static Handler pushOnlyHandler;
  156.  
  157.     /**
  158.      * Example for circular buffer behavior as normal priority.  The push level,
  159.      * and capacity are set the same so that the memory handler push results
  160.      * in a mail handler push.  All messages are normal priority.
  161.      * On close any remaining records are discarded because they never reach
  162.      * the mail handler.
  163.      */
  164.     private static void initPushNormal() {
  165.         final int capacity = 3;
  166.         final MailHandler h = new MailHandler(capacity);
  167.         h.setSubject("Push normal demo");
  168.         MemoryHandler m = new MemoryHandler(h, capacity, Level.WARNING) {
  169.  
  170.             public void push() {
  171.                 super.push();  //push to target.
  172.                 super.flush(); //make the target send the email.
  173.             }
  174.         };
  175.         LOGGER.addHandler(m);
  176.         pushNormalHandler = h;
  177.     }
  178.     private static Handler pushNormalHandler;
  179.  
  180.     /**
  181.      *  Example for various kinds of custom sorting, formatting, and filtering
  182.      *  for multiple attachment messages.
  183.      *  On close any remaining messages are sent.
  184.      */
  185.     private static void initCustomAttachments() {
  186.         MailHandler h = new MailHandler();
  187.  
  188.         //Sort records by level keeping the severe messages at the top.
  189.         h.setComparator(new LevelAndSeqComparator(true));
  190.  
  191.         //Use subject to provide a hint as to what is in the email.
  192.         h.setSubject(new SummaryNameFormatter("Log containing {0} records with {1} errors."));
  193.  
  194.         //Make the body give a simple summary of what happened.
  195.         h.setFormatter(new SummaryFormatter());
  196.  
  197.         //Create 3 attachments.
  198.         h.setAttachmentFormatters(new Formatter[]{new XMLFormatter(), new XMLFormatter(), new SimpleFormatter()});
  199.  
  200.         //filter each attachment differently.
  201.         h.setAttachmentFilters(new Filter[]{null, new MessageErrorsFilter(false),
  202.                     new MessageErrorsFilter(true)});
  203.  
  204.  
  205.         //create simple names.
  206.         h.setAttachmentNames(new String[]{"all.xml", "errors.xml", "errors.txt"});
  207.  
  208.         //extract simple name, replace the rest with formatters.
  209.         h.setAttachmentNames(new Formatter[]{h.getAttachmentNames()[0],
  210.                     new SummaryNameFormatter("{0} records and {1} mail errors"),
  211.                     new SummaryNameFormatter("{0,choice,0#no records|1#1 record|" +
  212.                     "1<{0,number,integer} records} and " +
  213.                     "{1,choice,0#no errors|1#1 error|1<" +
  214.                     "{1,number,integer} errors}")});
  215.  
  216.         LOGGER.addHandler(h);
  217.     }
  218.  
  219.     /**
  220.      * Sets up the demos that will run.
  221.      */
  222.     private static void init() {
  223.         initBodyOnly();
  224.         initLowCapacity();
  225.         initSimpleAttachment();
  226.         initWithPushLevel();
  227.         initWithPushFilter();
  228.         initCustomAttachments();
  229.         initPushOnly();
  230.         initPushNormal();
  231.         applyFallbackSettings();
  232.     }
  233.  
  234.     private static void closeHandlers() {
  235.         Handler[] handlers = LOGGER.getHandlers();
  236.         for (int i = 0; i < handlers.length; i++) {
  237.             Handler h = handlers[i];
  238.             h.close();
  239.             LOGGER.removeHandler(h);
  240.         }
  241.     }
  242.  
  243.     private static void applyFallbackSettings() {
  244.         if (getConfigLocation() == null) {
  245.             LOGGER.setLevel(Level.ALL);
  246.             LOGGER.info("Check your user temp dir for output.");
  247.             Handler[] handlers = LOGGER.getHandlers();
  248.             for (int i = 0; i < handlers.length; i++) {
  249.                 Handler h = handlers[i];
  250.                 fallbackSettings(h);
  251.             }
  252.             fallbackSettings(pushOnlyHandler);
  253.             fallbackSettings(pushNormalHandler);
  254.         }
  255.     }
  256.  
  257.     private static void fallbackSettings(Handler h) {
  258.         h.setErrorManager(new FileErrorManager());
  259.         h.setLevel(Level.ALL);
  260.     }
  261.  
  262.     private static String getTempDir() {
  263.         return System.getProperty("java.io.tmpdir");
  264.     }
  265.  
  266.     private static String getConfigLocation() {
  267.         String file = System.getProperty("java.util.logging.config.file");
  268.         if (file == null) {
  269.             return System.getProperty("java.util.logging.config.class");
  270.         }
  271.         return file;
  272.     }
  273.  
  274.     private static final class MessageErrorsFilter implements Filter {
  275.  
  276.         private final boolean complement;
  277.  
  278.         MessageErrorsFilter(boolean complement) {
  279.             this.complement = complement;
  280.         }
  281.  
  282.         public boolean isLoggable(LogRecord r) {
  283.             return r.getThrown() instanceof MessagingException == complement;
  284.         }
  285.     }
  286.  
  287.     /**
  288.      * Orders log records by level then sequence number.
  289.      */
  290.     private static final class LevelAndSeqComparator
  291.             implements Comparator, java.io.Serializable {
  292.  
  293.         private static final long serialVersionUID = 6269562326337300267L;
  294.         private final boolean reverse;
  295.  
  296.         LevelAndSeqComparator() {
  297.             this(false);
  298.         }
  299.  
  300.         LevelAndSeqComparator(final boolean reverse) {
  301.             this.reverse = reverse;
  302.         }
  303.  
  304.         public int compare(Object o1, Object o2) {
  305.             LogRecord r1 = (LogRecord) o1;
  306.             LogRecord r2 = (LogRecord) o2;
  307.             final int first = r1.getLevel().intValue();
  308.             final int second = r2.getLevel().intValue();
  309.             if (first < second) {
  310.                 return reverse ? 1 : -1;
  311.             } else if (first > second) {
  312.                 return reverse ? -1 : 1;
  313.             } else {
  314.                 return compareSeq(r1, r2);
  315.             }
  316.         }
  317.  
  318.         private int compareSeq(LogRecord r1, LogRecord r2) {
  319.             final long first = r1.getSequenceNumber();
  320.             final long second = r2.getSequenceNumber();
  321.             if (first < second) {
  322.                 return reverse ? 1 : -1;
  323.             } else if (first > second) {
  324.                 return reverse ? -1 : 1;
  325.             } else {
  326.                 return 0;
  327.             }
  328.         }
  329.     }
  330. }
  331.