Sunday, February 28, 2010

EveryTrail.com GPS Visualizer

I went for a mountain bike ride today (the trails are finally dry enough) and I was packing my Holux GPS to record the trek. I was running the new GPS Sport Tracker softare on my Windows Mobile 6.0 phone and the logs are in GPX file format. I found EveryTrail.com that will create a Flash animation of your GPX trip:

45 Minutes in Powhite


Map your trip with EveryTrail

Wednesday, February 24, 2010

Windows Mobile GPS Sport Tracker Software

I just discovered an excellent free (donations accepted) GPS software for Windows Mobile phones called GPS Sport Tracker.  It has amazing features for running, biking, hiking, boating and probably many other things.  I can’t wait to get this in the boat and fine tune the sail adjustments.  The features I particularly like are:

  • Speed in 1/10s of MPH
  • Distance travelled
  • Average/Max speed
  • Elevation change
  • Data logging to GPX file format
  • Maps of your track
  • Profile of your elevation

This is fantastic work!

 

Tuesday, February 23, 2010

New in Tomcat 6.0.19 - Realm lock-out feature

NOW they tell me.  Man it pays to RTFM...

http://www.jeremythomerson.com/blog/2008/11/apachecon-securing-apache-tomcat-for-your-environment/

New in 6.0.19 [the] LockOut realm - it wraps around standard realms and provides a lock-out mechanism for multiple failed attempts for the same user.  With this, there will also be the ability to have multiple realms for authentication - if any match, you get access - so you could use, for example, a tomcat users file for admins and a JNDI realm for users.

Full details here:
http://tomcat.apache.org/tomcat-6.0-doc/config/realm.html

You just wrap this around your existing realm (JDBC in our case).  I got this working and it will serve as a "backup" to my custom login attempts table.  The LockOut realm will prevent a brute force attack that hits the JAAS servlet directly.

Monday, February 22, 2010

SQL that return 1 or more rows, but is never empty

The alternate title for this post is "how I worked around the Spring JdbcTemplate queryForObject method throwing an EmptyResultDataAccessException when the query returned zero rows", but that didn't seemed a little verbose.

I added a SELECT 0 as a table source and joined to that to ensure there would always be one row:


SELECT Coalesce(i.UserID, 0) UserID, Coalesce(i.Password, '') Password, Count(a.UserID) Attempts
FROM (SELECT 0 AS id) mstr LEFT JOIN
(SELECT 0 AS id, UserID, UserName, Password FROM User WHERE UserName = 'Scooby') i ON mstr.id = i.id
LEFT JOIN UserAttempts a ON i.UserID = a.UserID AND LastAttempt > 1266602785
GROUP BY i.UserID,i.Password

Using Spring JdbcTemplate to queryForObject example

I needed to make a quick query to check some data before inserting a new record. The queryForObject allows you to create an inner RowMapper class to handle the ResultSet…in this case, I needed to return two integers so I mapped the results to an integer array with two elements:


JdbcTemplate springTemplate = new JdbcTemplate(this.currDs);
int[] user = springTemplate.queryForObject(
"select UserID, count(*) from t_actor where orgID = ?",
new Object[]{new Long(1212)},
new RowMapper<int[]>() {

public int[] mapRow(ResultSet rs, int rowNum) throws SQLException {
int[] user = new int[2];
user[0] = rs.getInt(0);
user[1] = rs.getInt(1);
return user;
}
});

Friday, February 19, 2010

Adding new folders in Eclipse


I discovered a great feature/shortcut for adding new folders in Eclipse. Java/Flex packages sometimes have very deep folder structures which are a bit of a pain to recreate by hand. The good news is Eclipse will create the folder structure in one fell swoop if you enter it. Here's what I do: I find the folder in Windows Explorer and copy the location (e.g. com\adobe\crypto ) and paste it into the new folder dialog and viola!

Wednesday, February 10, 2010

Eclipse WTP Axis2 Web Service Tutorial Hints

I have attempted to follow this Axis2 Tutorial and it has been painful.  I will attempt to ease other’s pain by providing the mistakes that I made to prevent others from making the same…

When I got this error:

ClassDefNotFoundException org.apache.http.HttpResponseFactory

It was because I was using Axis2 ver 1.5.1.  When I switched to 1.4.1 it was gone.

The tutorial says that opening http://localhost:8080/MyProject should display the Axis2 start page, but I found another Axis2 tutorial that said there was a bug and you actually needed to use:

http://localhost:8080/MyProject/axis2-web/index.jsp

 

Tuesday, February 9, 2010

Flex mx:Label htmlText and Font color behaviors

I just discovered a few qwerks with the Flex Label’s htmlText property that I thought were worth passing along.

First off, Labels are limited to one line, so the default behavior of the <mx:htmlText> <![CDATA[ will not display:

<mx:Label>

      <mx:htmlText>

            <![CDATA[

                  <font color="Red">*</font> indicates required field.

                  ]]>

      </mx:htmlText>

</mx:Label>

Once I consolidated the the CDATA lines into one it displayed:

<mx:Label>

      <mx:htmlText>

            <![CDATA[ <font color="Red ">*</font> indicates required field.]]>

      </mx:htmlText>

</mx:Label>

…but the color still didn’t work.  Turns out you have to use Hex to specify font color:

<mx:Label>

      <mx:htmlText>

            <![CDATA[ <font color="#FF0000">*</font> indicates required field.]]>

      </mx:htmlText>

</mx:Label>

The Adobe LiveDocs explain all this in more detail.

Thursday, February 4, 2010

Flex Builder stopped generating HTML wrapper after adding VSS

 

After adding my Flex project to VSS, the Flex Builder silently stopped generating the HTML wrapper files.  To fix the problem, I unchecked the Generate HTML wrapper file in the project properties.  I was prompted to delete the html-template directory and I did remove it (including the VSS linkage).  I then changed the project properties back and the HTML wrappers generated again.  Note, I did not check the html-template directory back in to VSS.

Tuesday, February 2, 2010

Improved Flex Validation: Display Error Tooltip

I combined two validation concepts to arrive at my Improved Flex Validation. The key component is Joel Hooks Form Validation for the Lazy Programmer. I incorporated the UIComponent.callLater() hack for displaying error ToolTips and viola!

Full Source

Here is what the callLater() looks like:

...
// display errorTip
if (showErrorsImmediately &&
currentControlIsValid == false &&
supressEvents == false)
{
// cast the focussed control to a UIComp to use callLater
var ffc:UIComponent = focusedFormControl as UIComponent;
ffc.callLater(showDeferred, [focusedFormControl]);
}

return currentControlIsValid;
}

private function showDeferred(target:DisplayObject):void {
target.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_OUT));
target.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_OVER));
}

Flex CompareValidator custom Validator

I have been using Matt Holden's Password Strength Indicator component with great success, but I was asked to make the input errors more obvious. The Flex Validators are a nice start, but their red-outline + tooltip approach is not the most intuitive. So, in conjunction with my improved Flex validation, I created a custom Validator for the password component to do the confirmation password comparison. The CompareValidator is generic enough that it can be reused for other components like account numbers or email addresses.

package core.util
{
import mx.validators.ValidationResult;
import mx.validators.Validator;


public class CompareValidator extends Validator
{
public var valueToCompare:Object;
public var errorMessage:String = "Value does not match.";

public function CompareValidator()
{
super();
}

override protected function doValidation(value:Object):Array {
var results:Array = [];
var srcVal:Object = this.getValueFromSource();

if (srcVal != valueToCompare) {
results.push(new ValidationResult(true, null, "Match",errorMessage));
}
return results;

}
}
}


The MXML looks like this:


<coreutil:CompareValidator
id="comparePasswords"
source="{password2}"
property="text"
valueToCompare="{password.text}"
errorMessage="Passwords do not match."
/>