Archive for the ‘Programming’ Category

A Reflective toString Method for Java

Often times I find the debugger to onerous for viewing DAOs. They usually contain lots, and lots of attributes and viewing those attributes is tedious, at least in my opinion. I prefer looking at them as text output. With text I can quickly scan through them or copy them or do any number of other things. With the debugger, their values reside strictly in the debugger.

My first reaction has been to create a toString method. This works rather well but it too is tedious. So I’ve created a toString method that uses reflection to create the output. The code for this method is located at the bottom of this post.

Some things to note:

  • This code has been created for my own use. Therefore you won’t have some of the objects I reference.
  • This code is free for all uses. If you’d like to use it commercially or for your own pet projects feel free to do so. Although I wouldn’t mind a mention (or a link) in the Javadoc or on the application’s web page if you see fit to do so.
  • This code is by no means feature complete. For example, I imagine it could be recursive so that when an object is encountered, this method is called instead of the Object’s toString method.
  • I also notice that my escape characters are no longer escaped. This means that you’ll have to add your own backslashes.
  • This code uses StringBuffer when StringBuilder would be more appropriate.  I used StringBuffer because of constraints that were put on me when I originally developed it. (If you’re interested in the differences between these two check out: http://forum.java.sun.com/thread.jspa?threadID=652378)

The Code

    public static String toString(Object a_oToConvert)
    {

         if(a_oToConvert == null)
         {
              return "Object is null";
         }

         StringBuffer sb = new StringBuffer();

         sb.append("n");

         sb.append("t" + Util.DASHES + "n");
         sb.append("t" + a_oToConvert.getClass().getName() + "n");
         sb.append("t" + Util.DASHES + "n");

         Class cls = a_oToConvert.getClass();

         Field[] arrFields = cls.getDeclaredFields();

         for(int idxField = 0; idxField < arrFields.length; idxField++)
         {

              Field fldCurrent = arrFields[idxField];

              String sName = fldCurrent.getName();

              Object oVal = new String("---");

              char[] arrChars = sName.toCharArray();
              char[] arrMod = new char[arrChars.length];

              for(int x = 3; x < arrChars.length; x++)
              {
            	  arrMod[x - 3] = arrChars[x];
              }

              String sFirstChar = new String("" + arrMod[0]);
              arrMod[0] = sFirstChar.toUpperCase().toCharArray()[0];

              String sGetMethod = "get" + new String(arrMod).trim();

              try
              {
                   Method methGet = cls.getMethod(sGetMethod, null);

                   if(methGet != null)
                   {
                        oVal = methGet.invoke(a_oToConvert, null);
                   }

                   if(oVal == null)
                   {
                        oVal = new String("Value is null");
                   }
                   else
                   {
                        if(oVal instanceof List)
                        {
                             oVal = "List Size: " + ((List)oVal).size();
                        }
                   }

              }
              catch(NoSuchMethodException nme)
              {
                   oVal = "No such getter - " + sGetMethod + "()";
              }
              catch(IllegalAccessException iae)
              {
                   oVal = "Not public - " + sGetMethod + "()";
              }
              catch(InvocationTargetException ite)
              {
                   oVal = "ITE" + ite.getLocalizedMessage();
              }

              sb.append("t" + Util.beautify(sName, oVal.toString()) + "n");

         }

         sb.append("t" + Util.DASHES);

         return sb.toString();

    }

Monday, February 18th, 2008

A Struts Compatible OpenID Authenticator for OpenId4Java

While working on a side project of mine, I decided that I wanted to allow users to authenticate themselves using OpenId. Being a Java programmer, who is reluctant to re-invent the wheel, I immediately searched Google in hopes that someone had already created a Java library I could use. After a few moments I came across OpenId4Java. These guys created a wonderful product which made implementation a breeze. It’s also worth noting that the support is pretty amazing as well.

After playing around with the code a little bit, I noticed that the sample code didn’t play too well with my Struts application. So I wrapped their code into my own class OpenIdAuthenticator. This class simply wraps the logic from the sample code to make it compatible with Struts.

Feel free to use the class for any purpose - commercial, private, etc. If you so desire, please give me some credit somewhere in the Javadoc.

Sunday, January 27th, 2008

Stay Hungry

My friend Colin and I are often asked to speak at the Computer Science Career Day that our alma mater holds every year. The night before, after we’ve had a few beers and have caught up, the conversation turns to what we should talk about the next day. Every year we include the same idea: Stay Hungry.

Some students get into computer science because they think it’s a great gig, others have a passion for computers. The passionate ones are often labeled “geeks” or “nerds.” These are the people that I’m writing for. Those with passion, those who love computers, those who love to learn.

Computer Science exposes you to a broad range of topics. I was exposed to compiler design, database design, language design, AI, application programming and internet programming, just to name a few. Within each of these topics there are countless languages and perspectives and theories. One can literally spend their entire life researching computer science and still never know everything there is.

This is the beauty and the pain of computer science - computer science encompasses a vast world of topics and college skims the surface of most and delves deeply into a few. You are forced to know a limited number of things, just enough to grasp the important points of the subject matter and then you’re given a diploma and sent into the world.

You’re a graduate now and go out into the world and find a job. Often times your first job allows you work on one system, with one language, solving one particular problem. This is great for a first job. It teaches you the business world, which we all must interact with. It teaches you problem solving skills, which you probably haven’t been taught well enough in college. It gives you real world experience.

The problem is that life comes at you fast - climbing the corporate ladder, relationships, children, mortgages and so on. Soon you realize that your skill set is stagnant. The passion you had as an undergrad is gone and now you’re simply a cog in the corporate machine. Going to work, coming home, sometimes making love and plucking at gray hairs.

What happened? You forgot to stay hungry.

Remember those nights that you stayed up late trying to work out the one last bug in some application you were working on? Remember when your thirst for something new and interesting kept you reading and experimenting?

Innovation has not stopped. Computer Science is a living, breathing, mutating, evolving subject. A quick look at the world around you will prove this. Look at operating systems, mobile devices, the internet, or even the appliances in your kitchen! There is no reason to starve.

The important thing is to find something that piques your curiosity. Does AI sound interesting to you? Research it. Try to write a simple application. Are you sick of Java? Learn Ruby-On-Rails. Maybe you always loved electronics class, learn more about electronics.

Life comes at you fast. Do not go to bed 25 and wake up when you’re 50 and wonder where the hell it all went. Stay hungry.

Monday, October 15th, 2007

Wiki Tip - Aggregate Pages

Lately Wiki’s have taken over my life - my team at work uses one, I’ve started one to share content from Ars Technica’s Boardroom and I’m even tempted to install TiddlyWiki on my USB drive!

For work, I’ve been using the wiki to store my meeting notes. I take my tagged notes and then transfer the most important ones over to the wiki. Great for sharing and for the if-I-get-hit-by-a-bus scenario! The problem is that the same subject matter can span multiple meetings and I like to break up my notes by meeting. So I began searching for a way to aggregate a bunch of single pages into one gigantic one. After a lot of searching I found a way to do it, unfortunately I lost the link but I do remember the instructions.

Below you’ll find the steps needed to create an aggregate page. The examples use the Boardroom Wiki.

  1. Create a new page. This page will become the aggregate page.
  2. Find the title of the pages you wish to aggregate. To do this I normally just copy the link and take the portion of the URL after the title=. For example the title of the following link http://www.theboardroomwiki.com/index.php?title=Business_Cards is “Business_Cards.”
  3. Edit the aggregate page. Insert the following tag: {{:PAGETITLE}}. Be sure to replace “PAGETITLE” with the title of the page you’ve selected. Example: {{:Business_Cards}}.
  4. Click the save button and voila!

My main issue is that there seems to be no way to group the individual pages on the aggregate page. I would expect the aggregate page to use the title from each individual page. Unfortunately this doesn’t seem to be case. Sure I could create my own group by adding a header before each instance of the aggregate tag, but this is a pain.

Another problem I have is the manual nature of this tag. Each time I want to add a page to the aggregate page, I have to do it manually. I’m not sure what an elegant solution to this problem would look like but I’m sure there’s one out there.

Please let me know if you found this post helpful - post a comment, Digg it, or share the link with your friends.

Monday, September 10th, 2007

Ars Technica Open Forum Firefox Search Add-On

I’ve been a member of Ars Technica for over 7 years now and I’ve never been a fan of its search functionality. Tonight was the last straw so I whipped up a quick-and-dirty Firefox add-on to search the Open Forum.

Please remember this is quick-and-dirty so its features are a little limited. That being said, below is its meager feature list.

  • Automatically sets the “Site” parameter to “episteme.arstechnica.com”
  • Automatically sets the “All Words” parameter to whatever you type into the search box.

I feel the add-on lacks the following.

  • A pretty Ars Technica icon. Anyone care to donate one?
  • Advanced search features such as “Exact Phrase,” “At Least One,” and “Without.”

You can install the add-on or view its source.

If you have any comments or suggestions, please post a comment or email me.

Monday, July 23rd, 2007

Two Books Reviewed

I am embarking on a new project and I’d like to use AJAX. Being unfamiliar with AJAX I decided to buy some books on the subject. After an hour or so spent browsing Barnes and Noble I settled on two books: Pro Apache Struts with Ajax and Practical Ajax Project with Java Technology both from Apress Publishing.

Below you’ll find mini-reviews of each book and the reason for this post.

Pro Apache Struts with Ajax

I have been using Struts for about two years now. By no means am I an expert but I am quite proficient. I was drawn to this book for two reasons: 1) I could use some more in-depth knowledge of Struts and 2) Combining Struts and Ajax seemed like a natural progression.

I perused the book before purchasing it and I found some interesting pieces of information and a very nice introduction to Ant. So I figured it was worth a shot. If the Struts part of this book is so in-depth, imagine the Ajax portion!

To say the least, the Ajax information in this book is lacking. By lacking, I mean the XMLHttpRequest object is explained and that is about it. If you look in the Index under “Ajax” there are a few references, but everything listed is in the appendix.

Although this book is interesting and still worth the price I found the title to be very misleading. I almost feel cheated because it seems like the publisher is trying to win sales on the back of the Ajax hype.

Practical Ajax Project with Java Technology

This is an excellent book. For a technical book it is a really great read!

The book is laid out in different projects starting from an implementation of Johnny Carson’s Karnak through a simple webmail application and onto a chat and RSS reader application.

Along the way the author, Frank Zammetti, shows us different Ajax Libraries such as Java Web Parts and DWR.

Also included in the book are some design patterns and anti-patterns. Although this falls more into the academic arena these sections are also a good read.

In the end, I would definitely recommend this book to someone who is looking for an introductory course in AJAX. As I mentioned, it is more of a big tutorial so those looking for a reference book may want to look elsewhere.

Sunday, July 15th, 2007

Review: Billings 2 - Time Tracking and Invoicing for Mac OSX

As many readers of this blog realize, I’ve been searching for financial programs that run on Mac OS. Unfortunately all of the software that I’ve tested thus far has sucked something fierce. Enter Billings 2 written by Marketcircle.

Billings 2 is a program that manages time tracking and invoicing.

The basis of time tracking is the “Time Slip.” A Time Slip can be thought of a piece of paper that identifies what you’re working on and how long it takes. (I think a lot of contractors can relate to this time tracking philosophy.) Time Slips are then bundled together into Invoices.

The application also tracks taxes, estimates, and retainers.

The application data seems to be stored in SQL Lite. This makes reporting easier.

This leads me to my favorite part of the application - the reporting engine. It is the most powerful reporting engine feature that I’ve come across. If you are familiar with Oracle Reports, or any other reporting engine then you can pretty much jump right into creating your own Invoices. For an in-depth look at the reporting engine and how to create custom invoices, check out the Report Engine Concepts document.

Overall, I definitely think that any consultant looking to change applications, or looking to make the switch to Mac should take a look at this application.

Billings 2 is provided by Marketcircle and costs $59.

Monday, April 30th, 2007

Voting Machines - Why the trouble?

Tonight I read an article in Dr. Dobbs Journal by Ed Nisley titled “Root the Vote: Wetware.” Although the article discusses the problems of voting machines, it doesn’t offer any idea on how to resolve them. A brief Google search didn’t yield any usable results, at least as far as I’m concerned. The question I have is this: What is so hard about writing voting machine software?

Here is my proposed solution:

1. Voter Verification
To insure that only the votes of registered people are countered there needs to be a method to validate them. Allow the machine to perform the verification. The voter swipes their card and is asked a series of questions to determine and validate their identity.

2. Voter Database
In order for the above to work the voting machine will need to have access to a database of voter data. Since setting up a network may prove difficult, copy the database to each machine. I don’t think the databases will be prohibitively large.

Since voters need to be registered a certain length of time before they vote the machines can be synced up well before the voting begins.

I do notice a big problem with this, and I will discuss it later on.

3. Vote Validation (for the Voter)
After the voter has cast his ballot bring up a simple screen that displays the position, the person that was voted for and two buttons: “Submit Ballot” and “Change.”

The “Submit Ballot” button would officially and irrevocably cast the voter’s ballot. The “Change” button would bring the voter to a screen that would allow him to fix which ever positions were found to be in error.

4. Determining the Winner
Each machine would be synced with a central computer. This computer would copy each machine’s data to its database. Thereby creating a duplicate of the information.

Having a local copy of the voter database does pose a problem, namely fraud. Since each machine has a copy of the voter database, and a record of who voted, it is possible for someone to vote on multiple machines. To prevent this the sync process would identify the votes that have been cast more than once and would only use the earliest recorded vote in its tally.

Once all the machines have been synced, and the votes verified, then the winner can be determined by simply counting the votes.

5. Vote Validation (for the Auditors)
Each machine would keep track of the voters who logged in and who they voted for. A simple database query could display this data.

Once the machines have been synced a report would be available to show any votes that weren’t counted for whatever reason.

I understand that I’ve taken a terribly simplistic approach to this but I just wanted to get my ideas out there for the public to tear apart. I am by no means an expert on electronic voting machines and I don’t since the issue with getting them correct. Maybe I’m dense or maybe I understand the complexities. Please feel free to leave a comment.

Monday, January 29th, 2007

JSP “Gotcha”

I just ran into an interesting situation with some JSPs I’ve been working with.
I have a common page element that I’ve been using on all of my “request” pages. To simplify development and future modifications, I started using a jsp:include. Unfortunately when using jsp:include the custom tags that are in the included page do not get rendered. A way around this is to use < %@ include file="" %>.
From what I’ve read the alternate way is a little slower but it does allow for the tags to be rendered on the included page.

Thursday, November 2nd, 2006