Thursday, July 29, 2010

Eclipse maven import - maven dependencies not showing up

If the maven dependencies are not showing up in your imported project, check the .classpath file in your project. Make sure it has the Maven specific entry:

<classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>

Saturday, April 24, 2010

JSP: Nested custom tags

Here is a simple example of a nested custom tag (which renders a pie chart). Note that I use JQuery to manipulate the DOM.

Here is the test JSP (PieChartTest.jsp):
<html>
<head>
<title>Pie Chart</title>
<script type="text/javascript" src="js/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="js/fasttags.js"></script>
<%@ taglib uri="/WEB-INF/tlds/FastTags.tld" prefix="fast" %>
</head>
<body>
<fast:piechart radius="100">
<fast:pieslice name='Vanguard 2045' value='75000'/>
<fast:pieslice name='Fidelity 2040' value='50000'/>
<fast:pieslice name='Principal 2035' value='20000'/>
<fast:pieslice name='Citibank Money Market' value='5000'/>
</fast:piechart>
</body>
</html>



Here is the PieChart Tag class (PieChartTag.java):
package org.fastkangaroo.fasttags;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;


public class PieChartTag implements Tag, Serializable {

private PageContext pc = null;
private Tag parent = null;
private int radius = 90;
private List<String> namesList = new ArrayList<String>();
private List<String> valuesList = new ArrayList<String>();

public void addSlice(String name, String value){
namesList.add(name);
valuesList.add(value);
}

public void setPageContext(PageContext p) {
pc = p;
}

public void setParent(Tag t) {
parent = t;
}

public Tag getParent() {
return parent;
}

public int doStartTag() throws JspException {
namesList = new ArrayList<String>();
valuesList = new ArrayList<String>();
return EVAL_BODY_INCLUDE;
}

public int doEndTag() throws JspException {
try {
pc.getOut().write("<table id='legend'/>");
pc.getOut().write("<br/>");
pc.getOut().write("<div id='tooltip'></div>");
pc.getOut().write("<canvas id='canvas' width='" + (radius+5)*2 + "' height='" + (radius+5)*2 + "'/>");
pc.getOut().write("<script>draw(" + this.namesList.toString() + "," + this.valuesList.toString() + "," + radius + ");</script>");
} catch(IOException e) {
throw new JspTagException("An IOException occurred.");
}
return EVAL_PAGE;
}

public void release() {
pc = null;
parent = null;
}


/**
* @param radius the radius to set
*/
public void setRadius(int radius) {
this.radius = radius;
}

/**
* @return the radius
*/
public int getRadius() {
return radius;
}

}



Here is the PieSlice Tag class (PieSliceTag.java):
package org.fastkangaroo.fasttags;

import java.io.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;


public class PieSliceTag extends BodyTagSupport {

private PageContext pc = null;
private Tag parent = null;
private String name = null;
private String value = null;

public void setPageContext(PageContext p) {
pc = p;
}

public void setParent(Tag t) {
parent = t;
}

public Tag getParent() {
return parent;
}

public int doStartTag() throws JspException {
try {
PieChartTag parent =
(PieChartTag)findAncestorWithClass(this, PieChartTag.class);
if (parent != null){
parent.addSlice("'" + this.name + "'", this.value);
}
}
catch(Exception e) {
throw new JspTagException("An IOException occurred.");
}
return SKIP_BODY;
}

public int doEndTag() throws JspException {
return EVAL_PAGE;
}

public void release() {
pc = null;
parent = null;
}

/**
* @return the name
*/
public String getName() {
return name;
}

/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}

/**
* @return the value
*/
public String getValue() {
return value;
}

/**
* @param value the value to set
*/
public void setValue(String value) {
this.value = value;
}

}

Here is the TLD (FastTags.tld):
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"
"http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">

<taglib>
<tlibversion>1.0</tlibversion>
<jspversion>1.1</jspversion>
<shortname>FastTags</shortname>
<uri>http://www.fastkangaroo-software.org</uri>
<info>Fast Tags Library</info>

<tag>
<name>piechart</name>
<tagclass>org.fastkangaroo.fasttags.PieChartTag</tagclass>
<bodycontent>scriptless</bodycontent>
<info>PieChart Tag</info>
<attribute>
<name>radius</name>
<required>false</required>
</attribute>
</tag>

<tag>
<name>pieslice</name>
<tagclass>org.fastkangaroo.fasttags.PieSliceTag</tagclass>
<bodycontent>empty</bodycontent>
<info>PieSlice Tag</info>
<attribute>
<name>name</name>
<required>true</required>
</attribute>
<attribute>
<name>value</name>
<required>true</required>
</attribute>
</tag>
</taglib>


Here is the javascript (fasttags.js)
var slices = new Array();
var pieTooltips = new Array();
var pie_radius = 90;
jQuery(document).ready(function(){
$("#canvas").mousemove(function(e){
tooltip(e);
});
})

function tooltip(e) {
var offset = $("#canvas").offset();
xpos = e.pageX - offset.left;
ypos = e.pageY - offset.top;
radius = Math.sqrt((xpos-(pie_radius+5))*(xpos-(pie_radius+5)) + (ypos-(pie_radius+5))*(ypos-(pie_radius+5)));
if (radius < pie_radius){
if (xpos > (pie_radius+5)) {
if (ypos < (pie_radius+5)) {
tan = ((pie_radius+5) - ypos)/(xpos -(pie_radius+5));
angle = 2*Math.PI - Math.atan(tan);
}
else {
tan = (ypos - (pie_radius+5))/(xpos -(pie_radius+5));
angle = Math.atan(tan);
}
}
else {
if (ypos < (pie_radius+5)) {
tan = ((pie_radius+5) - ypos)/((pie_radius+5) - xpos);
angle = Math.PI + Math.atan(tan);
}
else {
tan = (ypos - (pie_radius+5))/((pie_radius+5) - xpos);
angle = Math.PI - Math.atan(tan);
}
}
for (i = 0; i < slices.length; i++) {
if (angle < slices[i]){
$("#tooltip").html(pieTooltips[i-1]);
break;
}
}
}
}

function draw(names,values,radius) {
pie_radius = radius;
var canvas = document.getElementById("canvas");
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
var total = 0;
for (i=0; i < values.length; i++){
total += values[i];
}
slices = new Array();
slices[0] = 0;
for (i=0; i < values.length; i++){
slices[i+1] = slices[i] + 2*Math.PI*values[i]/total;
}
var colors = ["#F1CAA0", "#AB1100","#22CC00","#CCBB22","#FF6600","#FFDD00","#00CC00","#FF1100","#44CC00","#FFCC11"]
$('#legend tr').remove();
pieTooltips = new Array();
for (i = 0; i < slices.length-1; i++) {
// Draw shapes
ctx.beginPath();
ctx.moveTo(radius+5,radius+5);
ctx.arc(radius+5,radius+5,radius,slices[i],slices[i+1],false);
ctx.moveTo(radius+5,radius+5);
ctx.fillStyle = colors[i];
ctx.fill();
var newRow = '<tr><td bgcolor="' + colors[i] + '" width="20px"></td><td style="padding-left:10px">' + names[i] + '</td><td style="padding-left:10px">' + values[i] + '</td><td style="padding-left:10px">(' + divide(values[i]*100,total) + '%)</td></tr>';
$(newRow).appendTo('#legend');
pieTooltips[i] = names[i] + ' : ' + values[i] + ' (' + divide(values[i]*100,total) + '%)';
}
}
}

function divide ( numerator, denominator ) {
// In JavaScript, dividing integer values yields a floating point result (unlike in Java, C++, C)
// To find the integer quotient, reduce the numerator by the remainder first, then divide.
var remainder = numerator % denominator;
var quotient = ( numerator - remainder ) / denominator;

// Another possible solution: Convert quotient to an integer by truncating toward 0.
// Thanks to Frans Janssens for pointing out that the floor function is not correct for negative quotients.
if ( quotient >= 0 )
quotient = Math.floor( quotient );
else // negative
quotient = Math.ceil( quotient );

return quotient;

}

Tuesday, March 2, 2010

Could not start the MySQL service: Error 1067

I had to reinstall MySQL 5.1 - but once I did that, I could not start the service with the 1067 error. The problem was that the earlier install was writing the data to C:\MySQL InnoDB Datafiles\ and the new version was writing to C:\ProgramData\MySQL\MySQL Server 5.1\data

So I:
1. backed up my C:\ProgramData\MySQL\MySQL Server 5.1\data then deleted it
2. Reinstalled MySQL and started the service - this time the service started and it created a new C:\ProgramData\MySQL\MySQL Server 5.1\data
3. Stopped the service
4. I copied all my database folders from backup to this new \data directory
5. COpied the ibdata1 from C:\MySQL InnoDB Datafiles\ to this new \data (overwritng the existing file)
6. Restarted service