
/**
 * Class SendMailTransformer
 * Transformer to send MimeMessages  on encountering "mtxsm:sendmail" tag
 * @author Sreelatha
 * @version 1, 0
 * @(C) Copyright 2001. Metatomix, Inc., Waltham, Massachusetts. All Rights Reserved.
 */

package com.metatomix.connector.transformation;

import org.apache.avalon.framework.parameters.Parameters;
import org.apache.cocoon.util.Tokenizer;
import org.apache.cocoon.environment.SourceResolver;
import org.apache.cocoon.transformation.AbstractTransformer;
import org.xml.sax.*;
import java.util.*;
import org.apache.xerces.parsers.*;
import javax.mail.*;
import javax.mail.internet.*;
import org.xml.sax.helpers.AttributesImpl;

public class SendMailTransformer extends AbstractTransformer
{

/** boolean taking the value from sitemap, defined to indicate wether the specified
	    are to be removed from final o/p */
	private boolean removeTags = false;

	protected XMLReader parser  = null;
	protected static final String START_TAG ="<";
	protected static final String CLOSE_TAG = ">";
	protected static final String END_TAG ="/>";
	protected static final String START_END_TAG ="</";
	protected static final String SMTP_HOST ="mail.smtp.host";
	String m_FromMailAddress = "";
	String m_FromName = "";

	String m_Message = "";
	boolean bHTML = false;
	boolean bTextContent =false;
	boolean bHTMLPart =false;
	boolean bToAddress =false;
	boolean bSendmail = false;
	boolean m_bMailSendStatus = false;
	boolean m_bSetMailStatus = false;
	//for handling the removal of XML portion for the send mail from the XML data received
	boolean bSendmailRemove = false;

	String m_strSubjectData = "";
	String m_strData="";
	String m_strHost = "";
	//buffer for keeping the inline HTML  data
	StringBuffer m_strHTMLContent = new StringBuffer();
	MimeMultipart  m_MimeMultipart = null;
	Message m_Msg = null ;
	Properties m_MailProps = null;
	String m_strParamHost = "";
	public class CAddress
	{
		public String m_Name = "";
		public String m_MailAddress = "" ;
	};
	Vector m_ToAddr = new Vector();
	Vector m_CCAddr = new Vector();
	Vector m_BCCAddr = new Vector();
	//Request request;
	public SendMailTransformer()
	{
		super();

	}
   public void setup(SourceResolver resolver, Map objectModel,
                      String source, Parameters parameters)

    {
		//request = (Request)(objectModel.get(Constants.REQUEST_OBJECT));
		m_strParamHost = parameters.getParameter(SMTP_HOST, "127.0.0.1");
			//for bypassing the data in the XML file
		if(!(parameters.getParameter("removetags", null) == null))
			removeTags = (new Boolean(parameters.getParameter("removetags", null))).booleanValue();


	}



/**
 * Method startElement
 *
 *
 * @param namespaceURI
 * @param localName
 * @param rawName
 * @param atts
 *
 * @throws SAXException
 *
 */
public void startElement(String namespaceURI, String localName, String rawName, Attributes atts)
						throws SAXException
{

	try
	{

		if(rawName.equals("mtxsm:sendmail"))
		{
			//flag sets true for processing further data from the pipe
			bSendmail = true;
			bSendmailRemove = true;
			if(bHTML)
			{
				AppendHTMLStartTag(rawName,atts);
			}


		}
		if(bSendmail)
		{

			 if(rawName.equals("mtxsm:from"))
			{
				for(int count=0;count<atts.getLength();count++)
				{
					if(atts.getLocalName(count).trim().equals("addr"))
					m_FromMailAddress = atts.getValue(count);
					else if(atts.getLocalName(count).trim().equals("name"))
					m_FromName =atts.getValue(count);


				}
				if(bHTML)
				{
					AppendHTMLStartTag(rawName,atts);
				}
			}
			else if(rawName.equals("mtxsm:to"))
			{
				CAddress addr = new CAddress();
				for(int count=0;count<atts.getLength();count++)
				{
					if(atts.getLocalName(count).trim().equals("addr"))
					addr.m_MailAddress  = atts.getValue(count);
					else if(atts.getLocalName(count).trim().equals("name"))
					addr.m_Name =atts.getValue(count);
				}
				m_ToAddr.add(addr);
				if(bHTML)
				{
					AppendHTMLStartTag(rawName,atts);
				}

			}
			else if(rawName.equals("mtxsm:cc"))
			{
				CAddress addr = new CAddress();
				for(int count=0;count<atts.getLength();count++)
				{
					if(atts.getLocalName(count).trim().equals("addr"))
					addr.m_MailAddress  = atts.getValue(count);
					else if(atts.getLocalName(count).trim().equals("name"))
					addr.m_Name =atts.getValue(count);
				}
				m_CCAddr.add(addr);

				if(bHTML)
				{
					AppendHTMLStartTag(rawName,atts);
				}

			}

			else if(rawName.equals("mtxsm:bcc"))
			{
				CAddress addr = new CAddress();
				for(int count=0;count<atts.getLength();count++)
				{
					if(atts.getLocalName(count).trim().equals("addr"))
					addr.m_MailAddress  = atts.getValue(count);
					else if(atts.getLocalName(count).trim().equals("name"))
					addr.m_Name =atts.getValue(count);
				}
				m_BCCAddr.add(addr);

				if(bHTML)
				{
					AppendHTMLStartTag(rawName,atts);
				}

			}




			else if(rawName.equals("mtxsm:subject"))
			{
				if(bHTML)
				{
					AppendHTMLStartTag(rawName,atts);
				}
			}
			else if(rawName.equals("mtxsm:smtphost"))
			{
				if(bHTML)
				{
					AppendHTMLStartTag(rawName,atts);
				}

			}
			else if(rawName.equals("mtxsm:multipart"))
			{
				if(null == m_MimeMultipart)
						m_MimeMultipart = new MimeMultipart();
				String strType = "";
				for(int count=0;count<atts.getLength();count++)
				{
					if(atts.getLocalName(count).trim().equals("type"))
					strType = atts.getValue(count);
				}
				if(0!= strType.length())
				m_MimeMultipart.setSubType(strType);//"alternative"

				if(bHTML)
				{
					AppendHTMLStartTag(rawName,atts);
				}

			}
			else if(rawName.equals("mtxsm:part"))
			{

				String strTypevalue = "";
				for(int count=0;count<atts.getLength();count++)
				{
					if(atts.getLocalName(count).trim().equals("type"))
					if(atts.getValue(count).trim().equals("text/plain"))
					{
						bTextContent = true;
					}
					else if(atts.getValue(count).trim().equals("text/html"))
					{
						bHTMLPart = true;
					}
					if(bHTMLPart &&(atts.getLocalName(count).trim().equals("src")))
					{
						String strSource = atts.getValue(count).trim();
						MimeBodyPart MBPhtml = new MimeBodyPart();
						MBPhtml.setContent(strSource,"text/plain");
						if(null == m_MimeMultipart)
							m_MimeMultipart = new MimeMultipart();
						m_MimeMultipart.addBodyPart(MBPhtml);
						bHTMLPart = false;
					}

				}

				if(bHTML)
				{
					AppendHTMLStartTag(rawName,atts);
				}

			}
			else if(rawName.equals("html"))
			{
				bHTML = true;
				if(bHTML)
				{
					AppendHTMLStartTag(rawName,atts);
				}
			}

			else
			{
				if(bHTML)
				{
					AppendHTMLStartTag(rawName,atts);
				}

			}
		}
	}
	catch(Exception e)
	{
		ClearAll();
		m_bMailSendStatus = false;
		getLogger().error("MTX:SendmailError: " + e.toString());
	}


	if (removeTags == false )
	{
			if (super.contentHandler!=null)
			super.contentHandler.startElement(namespaceURI,localName,rawName, atts);
	}
	else if(!bSendmailRemove)
	{

		if (super.contentHandler!=null)
		super.contentHandler.startElement(namespaceURI,localName,rawName, atts);
	}

	if(false == bSendmail ) bSendmailRemove = false;

	}

/**
	* Method SendMimemail
	*
	*
	* @throws SAXException
	*
	*/

	void SendMimemail()
	{
		try
		{
			if(null != m_MailProps)
			{
				InternetAddress [] 	ToAddr =null;
				InternetAddress [] 	CCAddr =null;

				m_MailProps.put(SMTP_HOST,m_strHost);
				Session ss = Session.getInstance(m_MailProps,null);
				m_Msg= new MimeMessage(ss);

				InternetAddress	FromAddr =new  InternetAddress(m_FromMailAddress,m_FromName);
				m_Msg.setFrom(FromAddr);


				if(!m_ToAddr.isEmpty())
				{
					InternetAddress Temp;
					ToAddr = new InternetAddress[m_ToAddr.size()];
					for(int count =0;count<m_ToAddr.size();count++)
					{
						Temp =new InternetAddress(((CAddress)m_ToAddr.get(count)).m_MailAddress,
													((CAddress)m_ToAddr.get(count)).m_Name)	;
						ToAddr[count] =Temp;
					}
					m_Msg.setRecipients(Message.RecipientType.TO, ToAddr) ;
					bToAddress = true;
				}
				else
				{

					getLogger().error("MTX:SendmailError: 'To' field is empty ");
				}

				if(!m_CCAddr.isEmpty())
				{
					InternetAddress Temp;
					CCAddr = new InternetAddress[m_CCAddr.size()];
					for(int count =0;count<m_CCAddr.size();count++)
					{
						Temp =new InternetAddress(((CAddress)m_CCAddr.get(count)).m_MailAddress,
													((CAddress)m_CCAddr.get(count)).m_Name)	;
						CCAddr[count] =Temp;
					}
					m_Msg.setRecipients(Message.RecipientType.CC, CCAddr) ;
				}

				if(!m_BCCAddr.isEmpty())
				{
					InternetAddress Temp;
					CCAddr = new InternetAddress[m_BCCAddr.size()];
					for(int count =0;count<m_BCCAddr.size();count++)
					{
						Temp =new InternetAddress(((CAddress)m_BCCAddr.get(count)).m_MailAddress,
													((CAddress)m_BCCAddr.get(count)).m_Name)	;
						CCAddr[count] =Temp;
					}
					m_Msg.setRecipients(Message.RecipientType.BCC, CCAddr) ;
				}

				if(bToAddress)
				{
					bToAddress = false;
					if(null != m_MimeMultipart)
					m_Msg.setContent(m_MimeMultipart);
					m_Msg.setSubject(m_strSubjectData);
					Transport.send(m_Msg);
					m_bMailSendStatus = true;

				}


					ClearAll();


			}

			else
			{
 				ClearAll();
 				m_bMailSendStatus = false;
				getLogger().debug("No mail server found !");
			}
		}
		catch(Exception e)
		{
				m_bMailSendStatus = false;
				ClearAll();
				getLogger().error("MTX:SendmailError: " + e.toString());

		}
	}

/**
	 * Method ClearAll

	 * Descr :Clears the member variables
	 */
	void ClearAll()
	{
		m_ToAddr.clear();
		m_CCAddr.clear();
		m_BCCAddr.clear();
		m_strData = "";
		m_strSubjectData = null;
		m_MimeMultipart = null;
		m_Msg = null;
		m_FromMailAddress = "";
		m_FromName = "";
		m_strHost = "";
		m_strHTMLContent = null;
		m_MailProps = null;

		bHTML = false;
		bTextContent =false;
		bHTMLPart =false;
		bToAddress =false;
		bSendmail = false;

	}
	/**
	 * Method characters
	 * @param text
	 * @param start
	 * @param length
	 *
	 * @throws SAXException
	 */




	public void characters(char[] Buf, int Offset, int length)
		throws SAXException
	{
		if(bSendmail)
		{
			m_strData =new String(Buf,Offset,length) ;
			m_strData = m_strData.trim();
		}


		if (removeTags == false )
			{

				if (super.contentHandler!=null)
					super.contentHandler.characters(Buf,Offset,length);
			}
			else if(!bSendmailRemove)
			{
				if (super.contentHandler!=null)
				super.contentHandler.characters(Buf,Offset,length);

			}


	}

	/**
	* Method endElement
	*
	*
	* @param namespaceURI
	* @param localName
	* @param rawName
	*
	* @throws SAXException
	*
	*/
	public void endElement(	String namespaceURI, String localName, String rawName)
							throws SAXException
	{
	try
	{
		//need to process the data from the pipe only if Send mail tag is encountered

		if(bSendmail)
		{

			if(rawName.equals("mtxsm:subject"))
			{
				if(0!= m_strData.length())
				m_strSubjectData = m_strData;
				else
				m_strSubjectData = "No Subject";
				if(bHTML)
				{
				AppendHTMLEndTag(localName);
				}
			}
			else if(rawName.equals("mtxsm:from"))
			{
				if(bHTML)
				{
				AppendHTMLEndTag(localName);
				}
			}

			else if(rawName.equals("mtxsm:to"))
			{

				if(bHTML)
				{
				AppendHTMLEndTag(localName);
				}
			}
			else if(rawName.equals("mtxsm:cc"))
			{

				if(bHTML)
				{
				AppendHTMLEndTag(localName);
				}
			}
			else if(rawName.equals("mtxsm:smtphost"))
			{
				if(0!= m_strData.length())
					m_strHost = m_strData;
				else
					m_strHost = m_strParamHost;
					m_MailProps = new Properties();
				if(bHTML)
				{
					AppendHTMLEndTag(localName);
				}

			}
			else if(rawName.equals("mtxsm:multipart"))
			{
				if(bHTML)
				{
					AppendHTMLEndTag(localName);
				}
			}

			else if(rawName.equals("mtxsm:part"))
			{
				if(bTextContent &&(0 != m_strData.length()))
				{
					MimeBodyPart MBP = new MimeBodyPart();
					String strr = m_strData;
					//MBP.setText(strr);
					MBP.setContent(strr,"text/plain");
					if(null == m_MimeMultipart)
						m_MimeMultipart = new MimeMultipart();
					m_MimeMultipart.addBodyPart(MBP);
					bTextContent = false;
				}
				if(bHTMLPart)bHTMLPart = false;
				if(bHTML)
				{
					AppendHTMLEndTag(localName);
				}


			}
			else if(rawName.equals("html"))
			{
				AppendHTMLEndTag(localName);
				bHTML = false;
				if(null!= m_strHTMLContent)
				{
					MimeBodyPart MBPhtml = new MimeBodyPart();
					MBPhtml.setContent(m_strHTMLContent.toString(),"text/html");
					if(null == m_MimeMultipart)
							m_MimeMultipart = new MimeMultipart();
					m_MimeMultipart.addBodyPart(MBPhtml);
			    }


			}
			else if(rawName.equals("mtxsm:sendmail"))
			{

				if(bHTML)
				{
					AppendHTMLEndTag(localName);
				}
				SendMimemail();
				bSendmail = false;
				m_bSetMailStatus = true;

			}
			else
			{
				if(bHTML)
				{
				AppendHTMLEndTag(localName);
				}

			}
			m_strData = null;
		}

	}
	catch(Exception e)
	{
		 ClearAll();
		m_bMailSendStatus = false;
		getLogger().error("MTX:SendmailError: " + e.toString());


	}

	if (removeTags == false )
	{

		if (super.contentHandler!=null)
			super.contentHandler.endElement(namespaceURI,localName,rawName);
	}
	else if(!bSendmailRemove)
	{
			if (super.contentHandler!=null)
			super.contentHandler.endElement(namespaceURI,localName,rawName);

	}

	if(false == bSendmail)	bSendmailRemove = false;
	if(m_bSetMailStatus)
	{
		AttributesImpl attr = new AttributesImpl() ;
		if(m_bMailSendStatus)
		attr.addAttribute(namespaceURI, localName, "confirmation", "","true");
		else
		attr.addAttribute(namespaceURI, localName, "confirmation", "","false");
		super.contentHandler.startElement(namespaceURI,localName,rawName,attr);
		super.contentHandler.endElement(namespaceURI,localName,rawName);
		m_bSetMailStatus =false;
		m_bMailSendStatus = false;

	}

	}

	/**
	 * Method AppendHTMLStartTag
	 *
	 *
	 * @param strStartTag
	 * @param Attr
	 *
	 * @throws SAXException
	 *
	 */

void AppendHTMLStartTag(String strStartTag,Attributes Attr)
{
	try
	{
		if(null == m_strHTMLContent)
		m_strHTMLContent = new StringBuffer();
		m_strHTMLContent.append(START_TAG).append(strStartTag);
		for(int count =0;count<Attr.getLength();count++)
		{
			m_strHTMLContent.append(Attr.getLocalName(count));
			if(""!= Attr.getValue(count))
			{
				m_strHTMLContent.append("=").append(Attr.getValue(count));
			}
		}
		m_strHTMLContent.append(CLOSE_TAG);
	}
	catch(Exception e)
	{
		m_strHTMLContent = null;
		getLogger().error("MTX:SendmailError: " + e.toString());
	}
}

/**
	 * Method AppendHTMLEndTag
	 *
	 *
	 * @param strStartTag
	 * @param Attr
	 *
	 * @throws SAXException
	 *
	 */

void AppendHTMLEndTag(String strEndTag)
{

	try
	{
		if(null == m_strHTMLContent)
			m_strHTMLContent = new StringBuffer();
		if(0!= m_strData.length())
		m_strHTMLContent.append(m_strData);
		m_strHTMLContent.append(START_END_TAG);
		m_strHTMLContent.append(strEndTag).append(CLOSE_TAG);
	}
	catch(Exception e)
	{
		m_strHTMLContent = null;
		getLogger().error("MTX:SendmailError: " + e.toString());
	}

}


}


