Monthly Archives:

May 2008

Posted on May 30, 2008 by Joel Potischman

try { go_fish(); } catch(JDOMException){}

In .NET, calling the selectSingleNode() method on XML documents returns a single node if the XPath expression finds a hit, and null if it doesn't.

So imagine my surprise when I found that JDOM in Java throws a JDOMException if no node was found! I think of exceptions as being exceptional events, so the designers of JDOM either disagree, or they think that not finding a node is a truly rare event. I'd argue that JDOM is wrong. Even strongly-typed XML documents can have optional elements, so throwing an exception when you don't find one is a serious escalation on a perfectly foreseeable outcome.

The Go Fish equivalent of selectSingleNode() either gets you the card you asked for, or your opponent squealing "Go Fish!". The JDOM version of Go Fish would instruct your opponent to either return a card or punch you in the face, and would instruct you to defend yourself from being knocked out in case your card wasn't found.

Hence, I wrote the following utility function to return a null result instead of an exception when we don't find our node:

public static Element selectSingleNodeSafe(Object xmlContext, String xPath) {
     try {
          return (Element) XPath.selectSingleNode(xmlContext, xPath);
     } catch (JDOMException e) {
          return null;
     }
}

| Comments (1) | Technorati Tags :

Posted on May 29, 2008 by Alex Gutierrez

Troubleshooting Presentation for IE6/7

I've had my share of issues with IE6/7. From my end, they mostly come in layout issues - not forgetting transparency for IE6.

Below is my two step approach when dealing with this monster:

  1. Make use of conditional statements for IE and create a separate css file. Lets name this file "ie_style.css"
  2. Use the underscore hack to address IE6 like so:

#myJucyTable {
	width: 100%; /* Hi IE7 */
	_width: 99%; /* Hi IE6 */
}

Note: Make sure to address IE7 first.


EXAMPLE:

Below we have mark-up for a two column layout. The left container(#left) has an inner two column layout(.col_container).

<div id="right">
	Navigation
</div>
<div id="left">
	<div class="col_container">
		<div class="left">
			Left Container
		</div>
		<div class="right">
			Right Container
		</div>
	</div>
</div>

Styled like so:

#right { width: 9em; float: right; }
#left { margin-right: 9em; }

.col_container div { border: 1px solid #000; }
.col_container:after { /* Used to clear the float */
    display: block;
    clear: both;
    content: " ";
}
.right { margin-left: 50%; }
.left {
	float: left;
	width: 50%;
}

Adding content to the layout and previewing on IE6/7 show the right inner container(.right) to not have the given 50%.

Add the property below to ie_style.css and presto.

.col_container { height: 1%; /* for both IEs */ }

Here is a preview of IE7:

An alternative way of laying out elements is with the position property.

Add this mark-up to our left container(#left)

<div id="user_account">
	<h2>Account Name</h2>
	<ul>
		<li><a href="#">Edit Account</a></li>
		<li><a href="#">Delete Account</a></li>
	</ul>
</div>

And style:

	#user_account { position: relative; }
	#user_account ul { margin: 0; position: absolute; top: 0; right: 0; }
	#user_account li { display: inline; }

Refreshing IE6 show the unordered list leaks to the right container(navigation)

To fix this, add the property below to ie_style.css and refresh browser.

#user_account { _height: 1%; /* Hello IE6 */}
		

Using "height: 1%" is my #1 tool when dealing with IE. What's yours?

| Comments (1) | Technorati Tags :

Posted on May 29, 2008 by Javier Julio

Centering an Application or Window In AIR

I've run into several AIR applications that don't center the main window on your desktop by default. This positioning is something I would prefer because I've had many AIR applications that have installed partially hidden under my OSX dock.

Originally, I came across a simple way of centering a window by doing the following on the applicationComplete event:

If you add the above block in your MXML component containing the WindowedApplication tag, you won't need to import anything for the centering to take place. However, you do need to apply it on the applicationComplete event, otherwise an error occurs on the last line.

Recently, though, I came across a sample in the Adobe Flex LiveDocs where a much shorter snippet performs the same desired functionality and works in all three events: initialize, creationComplete and applicationComplete.

| Comments (0) | Technorati Tags :

Posted on May 22, 2008 by Avi Flax

Keynote Suggestion: Add Diagramming Support

Just submitted to Apple via their Keynote Feedback page:

I'm using Keynote all the time to display complex diagrams step by step. I find that by building the components in one by one I can walk people through a complex diagram much, much easier than if I make a static diagram in OmniGraffle, where I'd need to show the entire thing all at once. And then, after I've built in all the various components of the diagram, I can even use the awesome animation actions to move things around and change things, to explain a plan to people.

So, I'm frequently creating diagrams in Keynote. And it's going well - it's totally worth it. But there are a few things that Keynote could make easier for me. The #1 thing would be the ability to connect shapes using lines (usually with arrowheads). That way if I move a shape around, the connections to it would move with it.

Another feature which would be very helpful would be more alignment help. In OmniGraffle, when I drag a shape around, little lines will appear which help me know how the shape is aligning with other shapes. This is very useful for making diagrams which have an orderly feel to them.

Thanks for the great software!
Avi Flax

Thus continues my infatuation with Keynote.

| Comments (1) | Technorati Tags :

Posted on May 22, 2008 by Javier Julio

jQuery Docs: Bookmark It!

Recently, a fellow developer asked me for some help to see if there was an easier way to filter a collection of objects than just writing a long for loop with some logic. My instincts had us head straight to the jQuery documentation site, and we were not disappointed. Their jQuery docs are some of the best we'd seen. Nicely categorized, information on all properties, example code, and demos provided.

Sifting through the Array/Object operations section we came across the "grep" utility method. With the "grep" method, you can easily filter any array with a callback function that returns a boolean. Return true to keep the element and false to remove it. A simple solution to a simple, yet common, problem. This is all the developer really needed but he was probably over-thinking it.

The lesson? Well, to put it bluntly: Documentation is your best friend. I've always felt that, most of the time, a simple, built-in method (or set of methods) is all you need to solve a problem. Or at least the common ones I get asked about. Do yourself a favor, bookmark the docs, and don't be afraid to embrace it. Make it a habit. A good one.

| Comments (0) | Technorati Tags :

Posted on May 20, 2008 by Joel Potischman

But It Worked On Dev!

If you use SQL Server's CLR integration to write .NET stored procedures, you may one day deploy your working proc to another server, only to see it blow up with an error like the following:

Msg 6522, Level 16, State 1, Procedure prcMyCLRProc, Line 0
 A .NET Framework error occurred during execution of user-defined routine or aggregate "prcMyCLRProc":
 System.TypeInitializationException:
    The type initializer for 'System.Data.SqlClient.MetaType' threw an exception. --->
 System.TypeLoadException:
    Could not load type 'System.DateTimeOffset' from assembly 'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.
 System.TypeLoadException:
    at System.Data.SqlClient.MetaType..cctor()
 System.TypeInitializationException:
    at StoredProcedures.prcMyCLRProc(String query)

You check permissions. You confirm CLR integration is enabled and configured properly. You even backup the database on the working box and restore it on the offending one, but no dice. The culprit? Both your servers have .NET Framework 2.0 installed, but only the working one has Service Pack 1, and you're using one of the new types or methods it introduced.

In our case, SP1 seems to have been corrupted by an extra-large batch of Windows updates, causing System.DateTimeOffset to cease to exist. Not that we're bitter.

| Comments (0) | Technorati Tags :

Posted on May 16, 2008 by Corey Maass

A jQuery Tip: Don't Use jQuery

Sometimes, there's too much of a good thing. jQuery fires its "$(document).ready()" as soon as the DOM is loaded, but what if that's too soon?

I recently ran into a problem when I was using a script that will resize an iframe, but the iframe hadn't loaded yet. So, after some debugging I realized that--for once--jQuery was not the answer. Resorting to the classic window.onload, which waits until everything is loaded, solved the problem.

The real solution here? Sometimes a Ferrari just won't replace the old pick-up truck.

| Comments (2) | Technorati Tags :

Posted on May 14, 2008 by Doug Burns

Unit Testing with JUnit 4 and Spring

I really like Java annotations for reducing XML configuration and simplifying code. Spring 2.5 introduced a new annotation-based unit test framework that further improved the great one it already provided. Using this, along with JUnit 4, you can create Spring unit tests without having to subclass anything.

An example unit test is shown below, along with an explanation of the annotations used.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:/applicationContext.xml"})
public class ExampleTest
{
	ExampleObject objectUnderTest;
	
	@Test
	public void testSomethingTrue() {
		Assert.assertNotNull(objectUnderTest);
		Assert.assertTrue(objectUnderTest.getSomethingTrue());
	}
	
	@Test
	@Ignore
	public void testSomethingElse() {
		Assert.assertNotNull(objectUnderTest);
		Assert.assertTrue(objectUnderTest.getSomethingFalse());
	}

	@Autowired
	public void setObjectUnderTest(ExampleObject objectUnderTest)
	{
		this.objectUnderTest = objectUnderTest;
	}
}
  • @RunWith - JUnit annotation that specifies that the Spring class runner should be used for running the test.
  • @ContextConfiguration - Specifies the location of your Spring application context xml file(s). This gets inherited by subclasses, so you can use it in a base class to configure all of the tests in your application.
  • @Test - Indicates that the method should be run as a test. Note that although I used the pre JUnit 4 naming conventions (class names postfixed with "Test" and method names prefixed with "test"), this is not a requirement.
  • @Ignore - When this annotation is added, the associated test method will not be run. This is a great alternative to commenting out the methods which was required prior to JUnit 4. In this case, the test would fail if the @Ignore annotation wasn't used because objectUnderTest.getSomethingFalse() does not equal true.
  • @Autowired - Indicates that Spring should "wire" this dependency when initializing the test. In this case, a Spring bean named objectUnderTest will be provided.

| Comments (0) | Technorati Tags :

Posted on May 13, 2008 by Ben Sgro

Formatting Debug Output with print_r(

PHP's built in debugging functions, var_dump and print_r, are great for displaying a structured representation of a complex object or array and for viewing data printed to stdout. But what if you want to write that information to a log file?

There are a few decent recursive functions that iterate through the array or object. But there's really nothing quite like the format provided by print_r.

Many programmers don't realize that you can supply the print_r function with a second boolean argument. When set to TRUE (example below), debugging output will be not be rendered to stdout, which allows you to save it to a variable instead.


PHPCODE

   $complexDebug = print_r($_SERVER, TRUE);
   error_log($complexDebug);

END_PHPCODE

The previous code will take the print_r output of the SERVER array and save it as a string to the 'complexDebug' variable.The second line writes the string (preserving its format) to the error log file.

| Comments (0) | Technorati Tags :

Posted on May 9, 2008 by Javier Julio

Multiple File Extension Filters For CFDirectory

In a recent blog post by Ben Nadel (which should be his...oh, I don't know...56,423rd CF tip?!) he explained that by using the pipe character you can specify multiple file extension filters on the cfdirectory tag. For example, you can do the following:

That would return only Excel and CSV files. You can specify more filters by simply separating them with a pipe character. It seems like the Adobe Documentation team needs to update the ColdFusion Reference because it currently states the following for the filter attribute:

"File extension filter applied to returned names, for example, *.cfm. One filter can be applied."

Such a helpful tip really ought to be stated in the documentation or, even better yet, used as an example. So instead, I'll do all the work for you! Here is an example I wrote up matching the style used in the cfdirectory reference page:

| Comments (5) | Technorati Tags :

Posted on May 6, 2008 by Josh Diehl

When technology isn't the power behind a killer software feature

Like so many people I waited until the last minute to do my 2007 taxes. After some deliberation I decided to prepare them myself with the caveat that I'd need software to help.  I did a little research and decided to go with Intuit's TurboTax desktop version.  Intuit also offers an online version of Turbotax for about half the price but I wanted control over my data and didn't want to get locked into one vendor for next year

On whole I think they've gotten the user experience down to about a B+.  Its questionnaire format does a good job of guiding you through the various tax issues and making sure you're saving as much money as is allowed.  Once completed it can be a little confusing when you need to change something but overall my complaints were minor. Solid but unremarkable software.

Except... Turbotax had a trump up its sleeve.  It turns out they've negotiated data sharing agreements with a range of payroll providers, including mine. I was shocked to discover that in about 60 seconds (after entering my provider's ID and then a figure from my W2 as a "password") all of my wage information was imported automatically.  No typing, no double checking.  Wow! What a killer feature. Not only did it validate my decision to purchase Turbotax it got me excited enough to come into the office the next day and rave about it.

It struck me that the real work in including this feature wasn't accomplished at the keyboard but in the board room.  Sure it was probably hard work to format and import the data but the real sweat was in getting all those payroll providers to sign up and share their information.  It seems like an obvious move but it took someone at Intuit to not only have the bright idea but to pick up the phone and start calling payroll companies.

I think software folks too often attack problems with a strictly technical mindset.  Can you picture the W2 brainstorming meeting?  "What if we have them scan the W2 then OCR the data?  Wait! What if they enter only half the fields and we can calculate the rest?"  Technical wizardry is great but it's only one tool in the software palette.  It's easy for developers (and ex-developer manager-types) to default to this way of thinking.  It's in their comfort zone, it doesn't require unpleasantness like negotiations and contracts, and it offers the chance to write whiz-bang code. For some challenges the technical approach works, but for others it's sub-optimal or just impossible.

The marketplace has lots of examples of software that wouldn't have succeeded without this approach: Apple's iTunes store, OpenTable's reservations, Seamlessweb's ordering.  All of these work because people at those companies were willing to step out of the realm of code and do some old-fashioned horse trading.  In the context of software as a product, the non-technical approach can mean golden opportunities for companies versatile enough to take it. 

| Comments (2) | Technorati Tags :

Posted on May 5, 2008 by Doug Burns

Java Quick Tip: Restlet & Spring Integration

Here at arc90 we use the Restlet framework for Java REST web services. Recently, we’ve also been considering Spring for dependency injection and AOP within these services. Restlet 1.0.x provides an extension for Spring integration, but I had a hard time finding an example of its use, so I thought I would post one here.

DemoApplication Class

package com.arc90.demo;

import ...

/**
 * Starts the Restlet application and defines its resources
 */
public class DemoApplication extends Application
{
	private static final String RESOURCE_MAP = "resourceMap";
	private static final int HTTP_PORT = 8182;
	
	public DemoApplication(Context context)
	{
		super(context);
	}

	/**
	 * Initialize the application when this class is executed.
	 * @param args
	 */
	public static void main(String[] args)
	{
		try
		{
			Component component = new Component();
			component.getServers().add(Protocol.HTTP, HTTP_PORT);
			DemoApplication application = new DemoApplication(component.getContext());
			component.getDefaultHost().attach(application);
			component.start();
		}
		catch (Exception e)
		{
			/*
			 * Convert any checked exceptions to unchecked for the purpose of this demo.
			 */
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * Set up the spring-defined resources
	 */
	public Restlet createRoot()
	{
		Router router = new Router(getContext());
		
		/*
		 * Retrieve a map of available resources from spring and attach each to the router
		 */
		ApplicationContext context = 
			new ClassPathXmlApplicationContext(new String[] { "applicationContext.xml" });
		Map<String, Finder> resourceMap = (Map<String, Finder>) context.getBean(RESOURCE_MAP);
		for (String key : resourceMap.keySet())
		{
			router.attach(key, resourceMap.get(key));
		}
		
		return router;
	}
}

DemoResource Class

package com.arc90.demo;

import ...

/**
 * Handles all requests to the demo resource.
 */
public class DemoResource extends Resource
{
	@Override
	public void init(Context context, Request request, Response response)
	{
		super.init(context, request, response);
		getVariants().add(new Variant(MediaType.TEXT_PLAIN));
	}

	@Override
	public Representation getRepresentation(Variant variant)
	{		
		return new StringRepresentation("Restlet Spring Integration Demo", MediaType.TEXT_PLAIN);
	}
}

Spring applicationContext.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"
	xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">
		
	<util:map id="resourceMap">
		<entry key="/demo">
			<bean id="configurationFinder" class="org.restlet.ext.spring.SpringFinder">
				<lookup-method name="createResource" bean="demoResource"/> 
			</bean>
		</entry>
	</util:map>
	
	<!-- Resources classes -->
	<bean name="demoResource"
		class="com.arc90.demo.DemoResource" scope="prototype" />
</beans>

This uses Restlet's built in HTTP server, so to access the demo resource, simply run DemoApplication, then point your browser to: http://localhost:8182/demo

As you can see, it takes a little non-Spring code to get Restlet up and running. However, the Resources themselves are Spring beans, so everything from the Resource level down can be wired by Spring.

Restlet version 1.1 (currently in testing) provides improved Spring integration where the entire Restlet framework can be configured in the Spring application context. I plan to post another quick tip demonstrating the 1.1 configuration soon.

| Comments (0) | Technorati Tags :

Posted on May 4, 2008 by Chris LoSacco

JetBlue has a great writing staff

JetBlue Logo

I signed up for JetBlue's TrueBlue point program today, and I was greeted with this success page:

Thanks for joining. Your TrueBlue number is ###. Unless you've got a photographic memory, you might want to print this page for your reference. (You can also cut out the card below for your traveling convenience - or to impress your friends.)

Awesome. Made me smile and I immediately felt good about booking a flight with them (I hadn't yet, as I wanted to get the number before I booked). They really sealed the deal.

In addition, they had a really concise, clear way to describe the terms of the program:

TrueBlue points live for 1 year. So to earn your free flight, you need to accumulate your 100 points in a consecutive 12 month period. Just to be clear, that means any unused points automatically expire on their first birthday. For example, if you earn 12 points on 12/31/04, those 12 points expire on 12/31/05.

No complicated rules, just a plan English description in a down-to-earth tone.

We're currently working on our first product offering at Arc90, and crafting the writing within and about a product isn't easy. It's good to see that JetBlue took the time to put some effort and creativity into how they speak to their customers.

| Comments (1) | Technorati Tags :

Posted on May 1, 2008 by Dave Hauenstein

Supporting Milliseconds Date Formatting in Strtotime()

Today I ran into an issue where the values being returned from datetime columns in my MSSQL database were unreadable by PHP's strtotime() function.

Here's what was happening: All the values were in this format: Aug 27 2007 12:00:00:000AM. This was problematic because PHP's strtotime() function cannot parse dates where milliseconds are separated from the seconds by a colon rather than a period (dot).

At first, I was concerned about why this was happening and, according to a bug report on php.net, it was due to the combination of FreeTDS + php5.2.3 + MSSQL and their formatting of columns cast as datetime. Although it's fixed in the trunk of PHP's repository, it hasn't made its way to a release. So, if you happen to run into this--here's a solution:

    strtotime(preg_replace("/:\d{3}([AP]M)$/", " $1", $timeStamp));

In this case, $timeStamp is equal to Aug 27 2007 12:00:00:000AM. So use preg_replace() to replace the milliseconds (:000) with a space and then puts the am/pm back at the end. Now strtotime() has a value that's readable.

That's it!

| Comments (0) | Technorati Tags :

April 2008 | Main | June 2008