Matt, RTFM! Commons Collections HAS CLOSURES.

Thanks to everyone who pointed me to Commons Collections and its Functor package yesterday. To me, this is just one step below having closures natively present in the language. FYI, I was able to remove all duplication from my class and reduce the LOC from 211 to 136 - in other words, 75 lines of useless code GONE.

Here is what I did. First, I defined Predicates for each of my conditions. The simplest ones called a boolean method on the User object:

private final Predicate isX = new Predicate() {
public boolean evaluate(Object object) {
return ((User) object).isX();
}
}

Only slightly more complicated ones checked to see if a given Collection was empty on the User object:

private final Predicate isX = new Predicate() {
public boolean evaluate(Object object) {
return CollectionUtils.isNotEmpty(((User) object).getItems());
}
}

Next, I defined a method that would check the delegations for the User to see if any of them were an X:

boolean checkDelegations(User user, Predicate checkPredicate) {
return CollectionUtils.exists(user.getDelegations(), checkPredicate);
}

Finally, I implemented the security methods:

public boolean canDoThis() {
return isX.evaluate(loggedInUser) || checkDelegations(loggedInUser, isX);
}

Maybe it isn’t the most elegant or simplest of solutions, but it sure is a lot better than what I posted yesterday!

P.S. Since this is a Christian blog, I must remind you that RTFM stands for Read The FINE Manual!


Java needs closures

I’m sure everyone is sick of reading this same rant over and over, but I just had to add more fuel to the fire. I’m attempting to implement access privilege delegation in a JSF application - basically, users can delegate their ability to do “stuff” in our application to other users. I have a backing bean that has several methods that are called by the JSF components, returning whether or not to render that component based on security privileges. Well, I now have to make all of those methods aware of delegation! I have something like this in several methods:

boolean notX = (loggedInUser.isX());
if (notX) {
boolean result = false;
Set delegations = loggedInUser.getDelegations();
for (Iterator i = delegations.iterator(); i.hasNext();) {
User delegator = (User) i.next();
if (delegator.isX()) {
result = true;
break;
}
}
return result;
} else {
return true;
}

Now, it would be nice if I could extract the contents of that if block into a new method, say “checkDelegations()”. Unfortunately, the isX() that I need to call is different for every method following this pattern. I’d like to be able to pass a function that calls isX() on the delegator into the checkDelegations() method. No dice in Java. Does anyone else have a solution to this problem?


Raible’s Wiki: AppFuseRoadmap

Raible updated the AppFuseRoadmap yesterday. I’m really excited about where the project is going. XDoclet has been a good friend, but I’m really happy to see its demise in favor of annotations. JDK 5 and JSP 2.0 will also be really helpful - I’ve wanted to leverage these technologies for a long time, but haven’t had an easy way to do so. I think the most interesting thing for me will be the switch over to Maven 2. I have absolutely ZERO experience with Maven, other that seeing the pretty websites that it generates for many of my favorite open source projects. I consider myself to be something of an Ant wizard, so I hope that I’ll be able to leverage that experience in Maven.

It looks like TestNG replacing JUnit is a nice-to-have for 2.0 - I hope this becomes a configuration option. I don’t know anything about TestNG. Perhaps it’s time to learn. :-)

AppFuse 2.2 is where things are really going to start getting cool. Convention over configuration (ala RoR) will really speed development, and features by plugin will make my life really easier. I spend a lot of time stripping things out that I don’t need for particular projects - the time I save by using AppFuse is worth the pain of stripping them out - so this will be yet another way that AppFuse will make Java EE development a pleasure.


It seems that AppFuse has a competitor!

I found Project Able while reading Raible’s blog this morning. While it doesn’t claim to duplicate everything that AppFuse does (i.e. they pick a framework and stick with it instead of providing choice), they are doing some neat things. I may take a look at it if I ever have time. :-)

Project Able is a full Java-based web development stack designed to make web development painless. In a sense, it is an attempt to bring together quality opensource tools in one cohesive stack, similar to what Rails has done for Ruby, while also encouraging common practices I’ve used in software engineering for a long time.

It is very similar to projects such as Trails, Grails, and AppFuse. However, there are a few key differences:

  • The stack components are different (WebWork, Spring, iBatis, etc).
  • In addition to the basic framework, Able also encourages common development techniques and patterns (more below).

Seven simple reasons to use AppFuse

I’ve wanted for some time now to write a blog entry promoting my favorite open source project - AppFuse. Since I started developing web applications using AppFuse as a base, I can truly say that I’ve rediscovered the joy of software development. I’ve found no other technology or methodology that has allowed me to place as much focus as I now do on solving business problems and not on technology ramp-up or figuring out the eccentricities of “framework X.” In this article, Matt Raible, the founder of the AppFuse project, humbly states very compelling reasons that you should use AppFuse for your J2EE development. To summarize, here are the 7 reaons:

  1. Testing
  2. Integration
  3. Automation
  4. Security Features and Extensibility
  5. Code Generation with AppGen
  6. Documentation
  7. Community

Read the article to get the meat:

Seven simple reasons to use AppFuse


JFreeChart-AppFuse Integration

I recently finished integrating JFreeChart with AppFuse for a project I'm working on. JFreeChart is a really powerful Java chart library. If your application has any requirements for charts/graphs, I highly recommend it. The user manual and demo code come with a price tag ($39.95 for a single developer), but they are well worth the purchase - especially the demo code. If you don't have the $$$, the support forum is also very helpful.

I plan to put together a tutorial to help anyone interested in using JFreeChart in their AppFuse application. Look for it here and on the appfuse-user mailing list. It will be based on JSF since that's what I'm using right now.


I Made Raible's Blog

Apparently Matt Raible thought my JSF modifications to the AppFuse-Compass tutorial were good enough to merit a mention on his blog: AppFuse Videos updated for 1.9.3. Check out the bottom of the entry.

Compass really is a nice tool - I was able to provide search capabilities for an app I'm working on right now with about 2 days worth of work (having never worked w/ Compass before), and man is it fast! I can't get a search to exceed 1.5 seconds!


Stiff asks, Matt answers

I found an interesting article this morning by way of Digg.com Programming: Stiff asks, great programmers answer. The author posed 5 questions to some of the more well-known programmers of today, and their answers made for very interesting reading. Not to say that I'm a great programmer or anything, but I thought it might be a fun thought exercise to answer these questions myself. Here we go:

How did you learn programming? Were any schools of any use? Or maybe you didn't even bother with attending any schools :) ?

How did I learn programming? There have been several different stages of my development as a programmer. I started out copying BASIC programs from magazines into my Atari 800 and then modifying them to see what would happen. This progressed through the Commodore 64 and Apple II. In the 8th grade I earned the distinction of “Best Programmer,” not that that means very much - I figured out how to make the U.S. flag program run with only a handful of lines of code using loop and control structures vs. typing out the entire graphics display line by line.

In High School I jumped to the exciting world of Quick Basic. I can't remember the exact name of the course I took, but it was not very far above the level of what I did in Middle School/Junior High, nor was it very far below the level of my intro-level course in College. As I recall, we spent a lot of time hacking the machines to see what we could do with them. Of course you couldn't do anything cool like change your class schedule ala Hackers.

At some point I decided I would major in Computer Science at the University of Mississippi. I really enjoyed my time at Ole Miss, and I learned a lot - unfortunately, I also picked up a lot of bad programming habits. You ask were schools of any use? Definitely - one of my favorite professors secured me an internship at St. Jude, which led to my current and only full-time software development job. It wasn't until I started developing real code for real clients that I got truly serious about programming as a profession. It was then that I learned that hacking out quick and dirty scripts that worked most of the time and would get past a graduate assistant's grading wasn't what programming was all about. I think the turning point of my career was when I attended XP/Agile Universe in 2002. It was here that I really started to grasp agility, test-driven development, refactoring, and simple design - principles and practices that I consider essential to developing software of any magnitude.

What do you think is the most important skill every programmer should possess?

I'll answer this question very much like David Heinemeier Hansson answered the 10-100 times question below. I think the ability to quickly view a problem in the abstract and then mentally apply Occam's razor to it until you have what is needed for implementation is essential to programming. When I'm not managing a project team/schedule - i.e. I'm actually doing software development - I would consider this to be the core of what I do every day.

Do you think mathematics and/or physics are important skills for a programmer? Why?

I can't remember ever using any of the physics I've learned. Take that back, the concept of the electromagnetic field was useful when I was trying to understand Mass Spectrometry, which is at the heart of several of my clients' work. Mathematics, on the other hand, is key. The concepts I learned in my discrete mathematics course seem to lie under the surface of many of the problems that I face. Even if I don't directly apply the mathematics on a day-to-day basis, the “way of thinking” that you develop when studying mathematics really sharpens you as a programmer in my opinion.

What do you think will be the next big thing in computer programming? X-oriented programming, Y language, quantum computers, etc?

Like many of those interviewed, I'm not into fortune telling and/or hype. The next big thing always quickly becomes yesterday's news as we cut through the hype to the core value of what product/technique/practice X offers. We then integrate that core value into our regular day-to-day toolset and then go back to business as usual.

If you had three months to learn one relatively new technology, which one would you choose?

THREE MONTHS?!?!? WOW! Although it isn't that new, it's still fairly new to me. I would spend the next three months learning everything I can about the Spring framework.

What do you think makes some programmers 10 or 100 times more productive than others?

This flies in the face of a lot of the agile methodologies out there, but I think solving as many problems as you can without interrupting any of your other team members will turn you into an uber-productive programmer. I taught myself 90% of what I know through self-study and independent troubleshooting. If every time you have an issue with your work you quickly run to someone on your team that “knows that software/technology/issue better,” you'll never advance past infancy as a programmer. Just like babies have to be spoon-fed, so do infant programmers. You have to learn how to feed yourself. The next time you have a problem in code that you're not familiar with, trace the execution, line-by-line. Understand for yourself how the program works. If you run across a technology or API that you're not familiar with, study the available resources related to it. “Google it” for crying out loud. The more you do this, the better you'll get at it. Soon you'll find yourself asking questions of your team members only about 5% of the time, and you'll become the most productive member of your team. Don't believe me? Give it a try.

What are your favorite tools (operating system, programming/scripting language, text editor, version control system, shell, database engine, other tools you can't live without) and why do you like them more than others?

My current tool set includes IntelliJ IDEA (as well as a smattering of Eclipse when I need it), AppFuse - probably the best thing that has ever happened to J2EE development, Cygwin, Tomcat, and MySQL. If I'm doing anything else in a text editor besides coding, vim is my friend. Wiki-wise we're very invested in Confluence - it rocks as a wiki. Of course I really can't live without Firefox - besides my IDE I probably spend more time there than anywhere else.

What is your favorite book related to computer programming?

I think I have to call a tie here between Agile Software Development, Principles, Patterns, and Practices by Robert C. Martin and Test Driven Development: A Practical Guide by David Astels. Both of these books were instrumental in my development as a more agile developer.

What is your favorite book NOT related to computer programming?

This is an easy one - the Bible. My main translation is the English Standard Version.

If I had to choose a book that wasn't the Bible, it would be The Way of the Master by Ray Comfort. This book literally changed my life.

What are your favorite music bands/performers/composers?

Right now my favorite artists include The David Crowder Band, Casting Crowns, and Todd Agnew.