Thursday, August 12, 2010

Embedding images in E-Mail





We have been using XML XSL transformation for generating the emails and it was working well . XML Provides the data and Styling is provided in XSL . It becomes tricky when including images . One easy way to do is to include images as URL . This may not be the right approach as the user may not be online when looking a the email and can be lost during forwarding .

Best way is to use javax.mail.internet.MimeMultipart and set the images as header .
Here is the example
XSL to include images will look like this

<img>
<xsl:attribute name="src">cid:image1</xsl:attribute>
<xsl:attribute name="border">0</xsl:attribute>
</img>


Include the images in the email service after the transformation


MimeMultipart multipart = new MimeMultipart();
BodyPart messageBodyPart = new MimeBodyPart();

messageBodyPart.setContent("All Email contents from Transformation", "text/html");
multipart.addBodyPart(messageBodyPart);

// add first image
messageBodyPart = new MimeBodyPart();
DataSource fds = new FileDataSource
("C:\\image_path");
messageBodyPart.setHeader("Content-ID","<image1>");
messageBodyPart.setDataHandler(new DataHandler(fds));
multipart.addBodyPart(messageBodyPart);

//add another image
messageBodyPart = new MimeBodyPart();
DataSource fds1 = new FileDataSource
("C:\\image-path");
messageBodyPart.setHeader("Content-ID","<image2>");
messageBodyPart.setDataHandler(new DataHandler(fds1));
multipart.addBodyPart(messageBodyPart);

message.setContent(multipart);


You will see the image replaced .Images are downloaded with the message and is replaced where the tag is used . It's solves all the issues related to using them as URL.

Friday, July 9, 2010

Prototype JavaScript framework - Light weight framework





Redesigning websites for Rich user interface may involve significant changes not only to the UI layer but also the server side programming . Programmers and Designers often find it as a big project to do a total redesign UI .

If you already have a website with lot stylesheets and javascript's change can be substantial . Prototype (http://www.prototypejs.org/) can be actually help take the first step , as its a light weight and provides a lot of utilities .

Here is an example of a project that was using vanilla AJAX and moving to prototype was very simple

Old Code

function loadXMLDocs(object)
{

xmlhttp=new ActiveXObject("Microsoft.XMLHTTP")
if (xmlhttp)
{
var xmlUrl = 'search.do';
xmlhttp.onreadystatechange=xmlhttpChange
xmlhttp.open("GET",xmlUrl,true)
xmlhttp.send()
}
}

function xmlhttpChange()
{

if (xmlhttp.readyState==4)
{
if (xmlhttp.status==200)
{
var xmlDoc=xmlhttp.responseXML
}
}
}


New Code after including prototype



function loadXMLDocs(object)
{

var myAjax = new Ajax.Request(url,{ method: 'post', parameters: param, onComplete: ccxmlhttpChange });
}

function xmlhttpChange()
{

var xmlDoc=originalRequest.responseXML
}




Notice the considerable reduction in boiler plate code . Also using a framework like prototype gives a added advantage of using more options -
http://www.prototypejs.org/api/ajax/options

My testing showed that the Performance was actually better than using vanilla ajax and our team is more inclined to use it .

Friday, November 27, 2009

MySQL Connect by prior using procedure





MySQL doesn't provide a way to do connect by , so how do you tackle it ? You have to write your own function or procedure that will do the connect by . Here is an example of the skill table that is related to itself by s_parentskillid .

Here is the Code that will get the skills related till it gets to the parent .
Code:

DROP PROCEDURE IF EXISTS getskillpath;
CREATE PROCEDURE `getskillpath`(in skillid int ,in delimiter varchar(5), out v_skillpath varchar(500))
BEGIN

DECLARE v_skill VARCHAR(50); /* variable stores the name */
DECLARE v_skillid INT DEFAULT 0; /* skill id - primary key */
DECLARE v_parentskillid INT DEFAULT 0;
/* parent skill id - foreign key that maps to skill id */

SET v_skillid = skillid; /* assign first skillid to variable */

skill_loop: LOOP

SELECT s_parentskillid,
s_name
INTO
v_parentskillid,
v_skill
FROM skills
where s_id =v_skillid;

SET v_skillpath = CONCAT_WS ( delimiter,v_skill,v_skillpath );
/* set skillpath initially null */


IF v_parentskillid is null THEN
LEAVE skill_loop; /* condition to exit parent found */
else
SET v_skillid = v_parentskillid; /* reset the skill id to loop */
END IF;


END LOOP skill_loop;
SELECT v_skillpath; /* check output */


END;

Example output - sap>SAP Functional>Reports>Reports Sub . if I use 9 as the input skill and > as the delimiter .( rows affected are marked in the image ) .