Automatic Email [Spring]

Okay, I had a requirement at my work. Everyday I had to arrive at work by 8 am and had to send some email, some kinda report. And for me, it was kind of annoying to arrive at work early only for the sake of an email. Anyways, Spring made my day better. Spring has awesome supports for Task Schedular and I just made a task schedular to send email every morning automatically without my need.

So, here goes the project. I created a very very simple project with maven. The project structure goes as shown below,
image

Now, lets see the artifacts of the project.

Step 1 . The pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.anupam</groupId>
	<artifactId>Reporter</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<name>Reporter Maven Webapp</name>
	<url>http://maven.apache.org</url>
	<dependencies>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>4.2.2.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
			<version>4.2.2.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>4.2.2.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>4.2.2.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>net.sourceforge.jtds</groupId>
			<artifactId>jtds</artifactId>
			<version>1.3.1</version>
		</dependency>
		<dependency>
			<groupId>commons-dbcp</groupId>
			<artifactId>commons-dbcp</artifactId>
			<version>1.2.2</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>4.0.0-b01</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</artifactId>
			<version>4.2.2.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>javax.mail</groupId>
			<artifactId>mail</artifactId>
			<version>1.5.0-b01</version>
		</dependency>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.17</version>
		</dependency>

	</dependencies>
	<build>
		<finalName>Reporter</finalName>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

Step 2. Reporter\src\main\webapp\WEB-INF\spring\app-config.xml

Here I have configured the cron clock. You can configure anything you like. Also configured JavaMail to send email.

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.2.xsd">

	<context:annotation-config />
	<context:component-scan base-package="com.anupam.*" />

	<!-- Task -->
	<task:scheduled-tasks scheduler="myScheduler">
		<task:scheduled ref="reporterService" method="sendReport" cron="0 0 15 * * ?" />
	</task:scheduled-tasks>
	<task:scheduler id="myScheduler" />

	<!-- Email -->
	<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
		<property name="host">
			<value>sedna.xyz.org.br</value>
		</property>
		<property name="protocol">
			<value>smtp</value>
		</property>
		<property name="javaMailProperties">
			<props>
				<prop key="mail.smtp.auth">false</prop>
			</props>
		</property>
	</bean>

</beans>

Step 3. Reporter\src\main\webapp\WEB-INF\spring\hibernate-config.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd">


	<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName" value="net.sourceforge.jtds.jdbc.Driver" />
		<property name="url" value="jdbc:jtds:sqlserver://localhost/test" />
		<property name="username" value="admin" />
		<property name="password" value="admin" />
	</bean>
</beans>

Step 4. Reporter\src\main\webapp\WEB-INF\web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app>
	<servlet>
		<servlet-name>myspring</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet
		</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>/WEB-INF/spring/app-config.xml,/WEB-INF/spring/hibernate-config.xml
			</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>myspring</servlet-name>
		<url-pattern>/post/*</url-pattern>
	</servlet-mapping>
	<welcome-file-list>
		<welcome-file>index.html</welcome-file>
	</welcome-file-list>
</web-app>

Step 5. com.anupam.dao.ReportDAO

package com.anupam.dao;

public interface ReportDAO
{

   public String getResult(String date) throws Exception;

}

Step 6. com.anupam.dao.ReportDAOImpl

package com.anupam.dao;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringReader;
import java.io.Writer;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;

import javax.servlet.ServletContext;
import javax.sql.DataSource;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;

@Repository
public class ReportDAOImpl implements ReportDAO
{

    @Autowired
    private ServletContext ctx;

    @Autowired
    private DataSource ds;

    @Override
    public String getResult(String date)
    {
	String filePath = "";
	String sql = "SELECT i.info FROM TB_INTERFACE i WHERE i.insertTime > ? AND i.infoType = ? ";
	Connection conn = null;
	ResultSet rs = null;
	try
	{
	    conn = ds.getConnection();
	    PreparedStatement ps = conn.prepareStatement(sql);
	    ps.setString(1, date);
	    ps.setString(2, "RESULT_INFO");
	    rs = ps.executeQuery();
	    if (rs.next())
	    {
		StringBuffer data = new StringBuffer("<?xml version=\"1.0\" encoding=\"WINDOWS-1252\"?>");
		filePath = formatAndWriteXML(data.append(rs.getString("info")).toString());

	    }

	}
	catch (Exception e)
	{
	    Logger.getLogger(this.getClass()).info("getResult" + e.getMessage());
	}
	finally
	{

	    try
	    {
		rs.close();
		conn.close();
	    }
	    catch (SQLException e)
	    {
		Logger.getLogger(this.getClass()).info("getResult" + e.getMessage());
	    }
	}
	return filePath;
    }

    private String formatAndWriteXML(String info)
    {
	Writer out = null;
	try
	{
	    String filePath = ctx.getRealPath("/") + "reports" + "/Report_" + new Date().getTime() + ".xml";

	    DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
	    DocumentBuilder dBuilder = dFactory.newDocumentBuilder();
	    Document xml = dBuilder.parse(new InputSource(new StringReader(info)));

	    TransformerFactory tf = TransformerFactory.newInstance();
	    tf.setAttribute("indent-number", 5);
	    Transformer t = tf.newTransformer();
	    t.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
	    t.setOutputProperty(OutputKeys.INDENT, "yes");

	    File file = new File(filePath);
	    if (!file.exists())
	    {
		file.createNewFile();
	    }
	    out = new FileWriter(file);
	    t.transform(new DOMSource(xml), new StreamResult(out));
	    return filePath;
	}
	catch (Exception e)
	{
	    Logger.getLogger(this.getClass()).error(e.getMessage());
	}
	finally
	{
	    try
	    {
		out.close();
	    }
	    catch (IOException e)
	    {
		e.printStackTrace();
	    }
	}

	return null;
    }
}

Step 7. com.anupam.report.ReporterService

package com.anupam.report;

import java.util.Date;

import javax.mail.internet.MimeMessage;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;

import com.anupam.Utils.Utility;
import com.anupam.dao.ReportDAO;

@Component("reporterService")
public class ReporterService
{

    @Autowired
    private JavaMailSender mailSender;

    @Autowired
    private ReportDAO reportDAO;

    public void sendReport()
    {
	try
	{
	    String filePath = reportDAO.getResult(Utility.getPreviousDate(new Date()));
	    System.out.println("Report: " + filePath);
	    sendEmail(filePath);
	}
	catch (Exception e)
	{
	    Logger.getLogger(this.getClass()).error(e.getMessage());
	}
    }

    private void sendEmail(String attachment)
    {

	MimeMessage message = mailSender.createMimeMessage();

	try
	{

	    String subject = Utility.getPropertyValue("email.subject").concat(Utility.getPreviousDate(new Date(), "dd/MM/yyyy"));
	    String text = Utility.getPropertyValue("email.text").concat(Utility.formatDate(new Date(), "dd/MM/yyyy"));
	    String regards = Utility.getPropertyValue("email.regards");
	    text=text.concat("\n\n\n").concat(regards);

	    MimeMessageHelper helper = new MimeMessageHelper(message, true);
	    helper.setFrom(Utility.getPropertyValue("email.from"));
	    helper.setTo(Utility.getPropertyValue("email.to"));
	    helper.setSubject(subject);
	    helper.setText(text);

	    FileSystemResource file = new FileSystemResource(attachment);
	    helper.addAttachment(file.getFilename(), file);

	    // Send email.
	    mailSender.send(message);
	    Logger.getLogger(this.getClass()).info("sendEmail" + "Email sent successfully ");
	}
	catch (Exception e)
	{
	    Logger.getLogger(this.getClass()).error(e.getMessage());
	}

    }

}

Step 8. com.anupam.Utils.Utility

package com.anupam.Utils;

import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Utility
{

    public static Properties getInitProperties()
    {
	Properties prop = null;
	try
	{
	    prop = new Properties();
	    InputStream input = Utility.class.getClassLoader().getResourceAsStream("init.properties");
	    prop.load(input);
	    input.close();
	    return prop;
	}
	catch (IOException ex)
	{
	    Logger.getLogger(Utility.class.getName()).log(Level.SEVERE, null, ex);
	}
	return prop;
    }

    public static String getPropertyValue(String key)
    {
	Properties prop = getInitProperties();
	return prop.getProperty(key);
    }

    public static String formatDate(Date date) throws Exception
    {
	SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
	String str = df.format(date);
	return str;
    }

    public static String formatDate(Date date, String format) throws Exception
    {
	SimpleDateFormat df = new SimpleDateFormat(format);
	String str = df.format(date);
	return str;
    }

    public static String getPreviousDate(Date date) throws Exception
    {
	Calendar cal = Calendar.getInstance();
	cal.setTime(date);
	cal.add(Calendar.DATE, -1);
	return formatDate(cal.getTime());
    }
    public static String getPreviousDate(Date date,String format) throws Exception
    {
	Calendar cal = Calendar.getInstance();
	cal.setTime(date);
	cal.add(Calendar.DATE, -1);
	return formatDate(cal.getTime(),format);
    }
}

Step 9. Reporter\src\main\resources\log4j.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">

<log4j:configuration debug="false" xmlns:log4j="http://jakarta.apache.org/log4j/">    
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
     <param name="target" value="System.out" />
     <layout class="org.apache.log4j.PatternLayout">     
     <param name="ConversionPattern" value="%d{HH:mm:ss.SSS} %-5p %-40.70C{6} %x - %m%n" />                     
     </layout>              
</appender>                
<appender name="myReporter" class="org.apache.log4j.RollingFileAppender">
                         
<!-- Change the log path and file name here! -->
                                   
<param name="File" value="f:/Reporter/report.log" />                 
<param name="Append" value="true" />               
<param name="MaxFileSize" value="2MB" />
<param name="MaxBackupIndex" value="8" />

<layout class="org.apache.log4j.PatternLayout">          
<param name="ConversionPattern" value="%d{HH:mm:ss.SSS} %-5p %-40.70C{6} %x - %m%n" /></layout>                      
</appender>      
<appender name="LOG_APACHE" class="org.apache.log4j.RollingFileAppender">
                      
<!-- Change the log path and file name here! -->
                                   
<param name="File" value="f:/Reporter/apache.log" />                  
<param name="Append" value="true" />                           
<param name="MaxFileSize" value="2MB" />                          
<param name="MaxBackupIndex" value="8" />                           
<layout class="org.apache.log4j.PatternLayout">                                   
<param name="ConversionPattern" value="%d{HH:mm:ss.SSS} %-5p %-40.70C{6} %x - %m%n" />                             
</layout>                      
</appender>
                    
<logger name="com.adobe" additivity="false">                        
     <level value="INFO" />                         
     <appender-ref ref="myReporter" />                        
     <appender-ref ref="STDOUT" />                    
</logger>
                      
<!-- Hibernate                          
<logger name="org.hibernate">                              
    <level value="ALL" />                    
</logger>
<logger name="org.hibernate.SQL">
    <level value="ALL" />   
</logger>
-->   

<!-- Spring -->
        <logger name="org.springframework.flex">
		<level value="INFO" />
	</logger>
   
<!-- Apache Commons -->                            
<logger name="org.apache.commons">
                                   
<level value="INFO" />                      
     <appender-ref ref="LOG_APACHE" />                 
     <appender-ref ref="STDOUT" />                        
</logger>

<!-- Apache Jasper -->
                             
<logger name="org.apache.jasper">                                   
     <level value="INFO" />                                   
     <appender-ref ref="LOG_APACHE" />                        
     <appender-ref ref="STDOUT" />                        
</logger>
 
<!-- Apache Catalina -->          
<logger name="org.apache.catalina">                   
     <level value="INFO" />                              
     <appender-ref ref="LOG_APACHE" />                       
     <appender-ref ref="STDOUT" />                        
</logger>
                             
<!-- Apache Coyote -->
<logger name="org.apache.coyote">                                   
     <level value="INFO" />
     <appender-ref ref="LOG_APACHE" />                     
     <appender-ref ref="STDOUT" />                  
</logger>
 
<logger name="net">                                  
     <level value="WARN" />                             
     <appender-ref ref="myReporter" />                            
     <appender-ref ref="STDOUT" />
</logger>
 
                             
<!-- DEFAULT: All log message are send to Appender myReporter and STDOUT. Log Level Order: DEBUG, INFO, WARN, ERROR, FATAL -->
                             
    <root>
                                   
        <priority value="INFO" />                                   
        <appender-ref ref="STDOUT" />                       
        <appender-ref ref="myReporter" />
                             
    </root>
 
</log4j:configuration>

Step 10. Reporter\src\main\resources\init.properties

email.to=anupam.gogoi@abc.org.br
email.from=webplan@abc.org.br
email.subject=Hey buddy
email.text=Report sent via robot.
email.regards=Anupam Gogoi

Okay, here you go. Just take a break and enjoy sleeping for longer hours !!!!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s