Package smtphandler

Source Code of smtphandler.DefaultEvaluator

/*
* ============================================================================
*                   The Apache Software License, Version 1.1
* ============================================================================
*
*    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modifica-
* tion, are permitted provided that the following conditions are met:
*
* 1. Redistributions of  source code must  retain the above copyright  notice,
*    this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. The end-user documentation included with the redistribution, if any, must
*    include  the following  acknowledgment:  "This product includes  software
*    developed  by the  Apache Software Foundation  (http://www.apache.org/)."
*    Alternately, this  acknowledgment may  appear in the software itself,  if
*    and wherever such third-party acknowledgments normally appear.
*
* 4. The names "log4j" and  "Apache Software Foundation"  must not be used to
*    endorse  or promote  products derived  from this  software without  prior
*    written permission. For written permission, please contact
*    apache@apache.org.
*
* 5. Products  derived from this software may not  be called "Apache", nor may
*    "Apache" appear  in their name,  without prior written permission  of the
*    Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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
* APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
* DING, 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.
*
* This software  consists of voluntary contributions made  by many individuals
* on  behalf of the Apache Software  Foundation.  For more  information on the
* Apache Software Foundation, please see <http://www.apache.org/>.
*
*/

package smtphandler;

import java.util.logging.*;

import java.util.Date;
import java.util.Properties;

import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

/**
   Send an e-mail when a specific logging record occurs, typically on
   {@link java.util.logging.Level#WARNING WARNING}
   or {@link java.util.logging.Level#SEVERE SEVERE}

   <p>The number of {@link LogRecord} objects delivered in this e-mail depend on
   the value of <b>bufferSize</b> option. The
   <code>SMTPHandler</code> keeps only the last
   <code>bufferSize</code> records in its cyclic buffer. This
   keeps memory requirements at a reasonable level while still
   delivering useful application context.</p>

   <p>
   <img src="doc-files/smtphandler-diagram.jpg">
   </p>

   <p>
   The code in this class is derived from 
   <a href="http://logging.apache.org/log4j/">log4j</a>'s
   SMTPAppender class.
   </p>
  
   @author Ceki G&uuml;lc&uuml; (author of log4j's SMTPAppender)
   @author Sean C. Sullivan

   */
public class SMTPHandler extends java.util.logging.Handler
{
  static private final int DEFAULT_ERROR_CODE = 1;
  static private final Formatter DEFAULT_FORMATTER = new SimpleFormatter();
  static private final Level DEFAULT_LEVEL = Level.WARNING;
  static private final int DEFAULT_BUFFER_SIZE = 512;
  static private final String name = SMTPHandler.class.getName();
  private String to;
  private String from;
  private String subject;
  private String smtpHost;
  private String smtpUsername;
  private String smtpPassword;
  private int bufferSize = DEFAULT_BUFFER_SIZE;
  protected CyclicBuffer cb = new CyclicBuffer(bufferSize);
  protected TriggeringRecordEvaluator evaluator;

  public SMTPHandler()
  {
    final String prefix = SMTPHandler.class.getName();

    LogManager manager = LogManager.getLogManager();
    
    String strLevel = manager.getProperty(prefix + ".level");
    Level lev;
    if (strLevel == null)
    {
      lev = DEFAULT_LEVEL;
    }
    try
    {
      lev = Level.parse(strLevel);
    }
    catch (Exception ex)
    {
      lev = DEFAULT_LEVEL;
    }
    setLevel(lev);

    String strFormatterClassName = manager.getProperty(prefix + ".formatter");
    Formatter f = (Formatter) instantiateByClassName(strFormatterClassName,
            DEFAULT_FORMATTER);
    this.setFormatter(f);


    setTo(manager.getProperty(prefix + ".to"));
    setFrom(manager.getProperty(prefix + ".from"));
    setSmtpHost(manager.getProperty(prefix + ".smtpHost"));
    setSmtpUsername(manager.getProperty(prefix + ".smtpUsername"));
    setSmtpPassword(manager.getProperty(prefix + ".smtpPassword"));
    setSubject(manager.getProperty(prefix + ".subject"));

    String strEvaluatorClassName = manager.getProperty(prefix + ".evaluatorClass");
    this.setEvaluatorClass(strEvaluatorClassName);
   
    try
    {
      String strBufSize = manager.getProperty(prefix + ".bufferSize");
      setBufferSize(Integer.parseInt(strBufSize));
    }
    catch (Exception ex)
    {
      setBufferSize(DEFAULT_BUFFER_SIZE);
    }

  }


  /**
     Perform SMTPHandler specific appending actions, mainly adding
     the record to a cyclic buffer and checking if the record triggers
     an e-mail to be sent. */
  public synchronized void publish(LogRecord record)
  {
    if (record == null)
    {
      return;
    }
    else if ( ! isLoggable(record))
    {
      return;
    }
    else if (!checkEntryConditions())
    {
      return;
    }

    cb.add(record);

    if (evaluator.isTriggeringRecord(record))
    {
      sendBuffer();
    }
  }

  /**
      This method determines if there is a sense in attempting to append.
 
      <p>It checks whether there is a "To" address set and also if
      there is a set evaluator. If these checks fail, then the boolean
      value <code>false</code> is returned. */
  protected boolean checkEntryConditions()
  {
    if (this.evaluator == null)
    {
      reportError(
        "No TriggeringRecordEvaluator is set for handler ["
          + name
          + "].",
        null,
        DEFAULT_ERROR_CODE);
   
      return false;
    }
   
    if (getTo() == null)
    {
      reportError(
        "No 'To' email address set for handler ["
          + name
          + "].",
        null,
        DEFAULT_ERROR_CODE);
      return false;
   
    }

    return true;
  }

  public synchronized void close()
  {
    // todo this.closed = true;
  }

  protected InternetAddress getAddress(String addressStr)
  {
    try
    {
      return new InternetAddress(addressStr);
    }
    catch (AddressException e)
    {
      reportError("Could not parse address [" + addressStr + "].",
        e,
        DEFAULT_ERROR_CODE);

      return null;
    }
  }

  protected InternetAddress[] parseAddress(String addressStr)
  {
    try
    {
      return InternetAddress.parse(addressStr, true);
    }
    catch (AddressException e)
    {
      reportError("Could not parse address [" + addressStr + "].",
          e,
          DEFAULT_ERROR_CODE);

      return new InternetAddress[0];
    }
  }

  /**
     Returns value of the <b>To</b> option.
   */
  public String getTo()
  {
    return to;
  }

  /**
     Send the contents of the cyclic buffer as an e-mail message.
   */
  protected void sendBuffer()
  {
    // Note: this code already owns the monitor for this
    // handler. This frees us from needing to synchronize on 'cb'.

    Properties props = new Properties(System.getProperties());

    if (smtpHost != null)
    {
      props.put("mail.smtp.host", smtpHost);
    }

    Authenticator auth = null;
   
    if (this.getSmtpUsername() != null)
    {
      auth = new UsernamePasswordAuthenticator(
                    this.getSmtpUsername(),
                    this.getSmtpPassword());
      props.put("mail.smtp.user", this.getSmtpUsername());
      props.put("mail.smtp.auth", "true");
    }
   
    Session session = Session.getInstance(props, auth);

    session.setDebug(true);

    MimeMessage msg = new MimeMessage(session);

    try
    {
      if (from != null)
      {
        msg.setFrom(getAddress(from));
      }
      else
      {
        msg.setFrom();
      }

      msg.setRecipients(Message.RecipientType.TO, parseAddress(to));

      if (subject != null)
      {
        msg.setSubject(subject);
      }

      MimeBodyPart part = new MimeBodyPart();

      StringBuffer sbuf = new StringBuffer();
     
      Formatter f = getFormatter();
     
      String head = f.getHead(this);

      if (head != null)
      {
        sbuf.append(head);
      }

      int len = cb.length();

      for (int i = 0; i < len; i++)
      {
        LogRecord record = cb.get();
        sbuf.append(getFormatter().format(record));
      }

      String tail = getFormatter().getTail(this);

      if (tail != null)
      {
        sbuf.append(tail);
      }

      part.setContent(sbuf.toString(), getEmailContentType());

      Multipart mp = new MimeMultipart();
      mp.addBodyPart(part);
      msg.setContent(mp);
     
      msg.setSentDate(new Date());
     
      Transport.send(msg);
    }
    catch (Exception ex)
    {
      this.reportError("sendBuffer",
            ex,
            DEFAULT_ERROR_CODE);
    }
  }

  protected String getEmailContentType()
  {
    return "text/plain";
  }
 
  /**
     Returns value of the <b>EvaluatorClass</b> option.
   */
  public String getEvaluatorClass()
  {
    return (evaluator == null) ? null : evaluator.getClass().getName();
  }

  /**
     Returns value of the <b>From</b> option.
   */
  public String getFrom()
  {
    return from;
  }

  /**
     Returns value of the <b>Subject</b> option.
   */
  public String getSubject()
  {
    return subject;
  }

  /**
     Returns value of the <b>SmtpHost</b> option.
   */
  public String getSmtpHost()
  {
    return smtpHost;
  }

  public void flush()
  {
    // todo - implement
  }

  /**
     Returns value of the <b>bufferSize</b> option.
   */
  public int getBufferSize()
  {
    return bufferSize;
  }

  /**
     The <b>from</b> option takes a string value which should be a
     e-mail address of the sender.
   */
  public void setFrom(String from)
  {
    this.from = from;
  }

  /**
     The <b>to</b> option takes a string value which should be a
     e-mail address of the sender.
   */
  public void setTo(String to)
  {
    this.to = to;
  }

  /**
     The <b>subject</b> option takes a string value which should be a
     the subject of the e-mail message.
   */
  public void setSubject(String subject)
  {
    this.subject = subject;
  }

  /**
     The <b>bufferSize</b> option takes a positive integer
     representing the maximum number of logging records to collect in a
     cyclic buffer. When the <code>bufferSize</code> is reached,
     oldest records are deleted as new records are added to the
     buffer. By default the size of the cyclic buffer is 512 records.
   */
  public void setBufferSize(int bufferSize)
  {
    this.bufferSize = bufferSize;
    cb.resize(bufferSize);
  }

  /**
     The <b>smtpHost</b> option takes a string value which should be a
     the host name of the SMTP server that will send the e-mail message.
   */
  public void setSmtpHost(String smtpHost)
  {
    this.smtpHost = smtpHost;
  }

  /**
     The <b>evaluatorClass</b> option takes a string value
     representing the name of the class implementing the {@link
     TriggeringRecordEvaluator} interface. A corresponding object will
     be instantiated and assigned as the triggering record evaluator
     for the SMTPHandler.
   */
  public void setEvaluatorClass(String value)
  {
    evaluator =
    (TriggeringRecordEvaluator) instantiateByClassName(value, new DefaultEvaluator());
  }

  static Object instantiateByClassName(String strClassName, Object defaultObj)
  {
    Object result;
   
    try
    {
      ClassLoader loader = Thread.currentThread().getContextClassLoader();
      Class clazz = loader.loadClass(strClassName);
      result = clazz.newInstance();
    }
    catch (Exception ex)
    {
      result = defaultObj;
    }
    return result;

  }
  public String toString()
  {
    StringBuffer sb = new StringBuffer();
    sb.append("SmtpHost=");
    sb.append(String.valueOf(this.getSmtpHost()));
    sb.append("\nFrom=");
    sb.append(String.valueOf(this.getFrom()));
    sb.append("\nTo=");
    sb.append(String.valueOf(this.getTo()));
    sb.append("\nSubject=");
    sb.append(String.valueOf(this.getSubject()));
    sb.append("\nFormatter=");
    sb.append(String.valueOf(this.getFormatter()));
    sb.append("\nLevel=");
    sb.append(String.valueOf(this.getLevel()));
    sb.append("\nBufferSize=");
    sb.append(String.valueOf(this.getBufferSize()));
    return sb.toString();
  }


  public String getSmtpPassword()
  {
    return smtpPassword;
  }


  public void setSmtpPassword(String value)
  {
    this.smtpPassword = value;
  }


  public String getSmtpUsername()
  {
    return smtpUsername;
  }


  public void setSmtpUsername(String value)
  {
    this.smtpUsername = value;
  }

}

class DefaultEvaluator implements TriggeringRecordEvaluator
{
  /**
 
     Should this <code>record</code> trigger an email message to
     be sent?
 
     <p>This method returns <code>true</code>, if the record level
     has WARNING level or higher. Otherwise it returns
     <code>false</code>.
     
     */
  public boolean isTriggeringRecord(final LogRecord record)
  {
    boolean result = false;
   
    if (record == null)
    {
      result = false;
    }
    else if (record.getLevel() == null)
    {
      result = false;
    }
    else
    {
      result = record.getLevel().intValue() >= java.util.logging.Level.WARNING.intValue();
    }
   
    return result;
  }
 

}
TOP

Related Classes of smtphandler.DefaultEvaluator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.