Tuesday, March 27, 2007

Party on the patio

Its 70 degrees in NY today, and sunny. I'm inside doing this. That's ok, though. I have a handful of things to get done in the near future, but that should leave the late Spring and Summer to be not doing this stuff.

I've been plugging away on the Groovy/Wicket implementation. There's still a ways to go with regards to making everything work as it should, but I've made significant progress.
  • Dynamically generated classes are cached rather than re-generated each time.
  • Models, and soon behaviors and validators, can be added by the builder in the same way as components, including overridden methods.
  • Closure representation has been significantly cleaned up. Initially local references were banned, but there are certain situations which require them, so the wrappers attempt to handle that properly.


There's been a lot of other tweaks and additions. Right now I'm focused on getting the major stuff that you'd expect to work to actually work. I'm also hoping to build a reasonable example application and put that in the code base with everything else.

In the meantime, to better explain how the whole thing works, I recorded myself building a simple page. The quality isn't so hot, and my narration isn't the most exciting in the world, but I've got a few other things to get to today:

http://kgalligan.com/apache2-default/bigone.htm

At some point in the near future I'll try doing the same thing with a more complicated page.

Tuesday, March 20, 2007

Wicket and Groovy

I attempted to explain the concept of what I'm working on in a previous post, but its a little convoluted, and gets into implementation details, etc. Not very clear.

I'm getting ready to announce the project on a few mailing lists, so in preparation, I'm going to attempt to explain the idea again. Please bear with me...

Groovy, Grails, Rails, recent interviews and feeling a little like Old Gill...

I love Java. I've loved Java for a long time. I started coding Java in college, when it was version 1.0. Try this out. Its an asteroids clone I wrote. If you can dig up a Pentium 75, it will actually work.

For the past several years I've been running a small technology group building fairly heavyweight enterprise applications for a financial company. A relatively sheltered existence, to be sure. They move very slow on to new technologies. For my own part, I read a lot, but I'll admit I stuck pretty much to the Java realm. Maven, Hibernate, JSF? All over it. Ruby and Rails? Didn't even look.

So, I've been interviewing lately. It turns out that not everybody thinks Rails is mostly hype (as I did). Specifically, I spent a day at a company called Cyrus Innovation (cyrusinnovation.com). Its a small group of very intelligent people who actually believe in agile techniques, pair programming, do a lot of Java, and absolutely get into Ruby and Rails.

At 31, my interviewing experience left me feeling a little like Old Gill (simpsons reference). The prevailing attitude, at least in some areas, is that Java is old and Rails is the next big thing. That would be fine, except I really can't fathom tossing away such huge piles of quality, tested code that exist in the Java space. Also, Java is a great language for certain classes of applications. Part of the value of Rails comes from the language dynamics of Ruby, but a lot of the advertised productivity improvement comes simply from the framework. In short, there's no magic going on. Good ideas, but ideas are transferable.

It didn't take long to stumble onto Groovy and Grails. Its like an intellectual slap in the face for a long time Java programmer. Groovy is a dynamic language, syntactically similar to Java, which can seamlessly inter-operate with Java. Grails is a Rails-like framework built on top of Groovy. Assuming some time for stabilization and optimization, it levels the playing field in my mind. You can use the platform you're currently on, and extend it with a significantly more expressive language where needed. Not throwing the baby out with the bathwater.

Groovy and Grails are behind in terms of IDE support and general "smoothness" of development. I personally think Groovy is a fantastic technology, and my biggest concern is it simply won't get the time and effort needed to make it a first class option for the Java platform. It should, though. Java and Groovy together is a fantastic combination.

Wicket?

Right before I started with the dynamic languages, I had first tried out Wicket. For the past year or so I've been working with JSF. First on my own, then with my soon to be released major project. JSF is more productive than simpler options like Struts, and has some major industry support, but many things with JSF feel unnatural.

I had read about Wicket here and there, but had mentally stuffed it into the, "Oh man, another web framework" category (ie. the circular file). I finally gave it a shot, though. Yep, I was totally wrong. Wicket does some things in a way that seems, in retrospect, obvious. I think it has the freedom of not trying to be everything to everybody, and not having large committees making decisions, as JSF has to deal with. Its a great technology for the 98% of web applications that aren't be hit by thousands of users concurrently. Its a component framework, like JSF, which is nice for creating more complex user input constructs. Its page creation and linking features, however, are much better than Struts and JSF. By "much better", I mean respectively: Struts, JSF, Wicket -> walking, skateboard, ferrari. The way models can detach and reattach data objects is just awesome. I'll stop there. In summary, I like it.

So, now I'm all big on Groovy. What I disliked about Rails, and what I like about Groovy and Grails, is that you can use Java's existing code base in your new apps. Along with that, as Wicket really is great technology, I want to use it from Groovy code. Can you use Wicket and Groovy together? Yes, but its clunky. Why? Well, if you compile your Groovy into classes, it'll just work. That's good. However, Wicket relies on anonymous inner classes all over the place. You can create regular classes and override methods in them, but anonymous inner classes make that process much easier. Works great in Java. Groovy, however, doesn't do anonymous inner classes. Groovy uses closures, which are sweet as well, but you can't use closures with Wicket (obviously. If that wasn't obvious, you should probably stop now because you're going to be really lost soon). My goal with this project is to make Wicket programming with Groovy at least as easy as it is with Java, and hopefully easier. Besides, of course, the inherent expressiveness of the language itself.

Wicket Groovy Builder

Groovy has a concept called a builder. See here...

http://www-128.ibm.com/developerworks/java/library/j-pg04125/

The idea came to me to use a builder when I saw the SwingBuilder. It allows you to build a Swing app in groovy, with significantly simpler code. The Swing component structure is roughly tree shaped. Well, that's the first thing I noticed about Wicket code. It looked a lot like Swing code.

Simple concept. Write a builder implementation that build a Wicket component tree. Sounds easy, but its fairly complex. I won't go in to it, but lets say I do some things with closures that they weren't meant to do. Over the next couple weeks I'm going to be working on the project as well as the documentation, so hopefully I'll have some more detail on the implementation soon.

Originally I started doing this as a seperate project, but Eelco Hillenius from wicketstuff contacted me about the project. He had done some work on the 'wicket-groovy' project from wicketstuff, and proposed I move the builder code in there. Here's the website...

http://wicketstuff.org/confluence/display/STUFFWIKI/wicket-groovy

Right now my code is in the 1.3 branch only. You can see the latest subversion tree at...

https://wicket-stuff.svn.sourceforge.net/svnroot/wicket-stuff/branches/wicket-1.3/wicket-contrib-groovy

Does it help? Here are two screen shots of roughly equivalent code:

Java Version



Groovy Version



The larger the form, the more obvious the benefit.

Future Plans

The biggest thing is just using it in some applications, and writing some better test cases. I was banging my head against a wall today and yesterday over some pretty major stuff, so I'm sure there are a few other issues in there somewhere.

There are certain places where optimization would help significantly. Specifically on the dynamic class generation. Its generating a new class on each run. This isn't good. I have to sort out a problem with the Closure's owner, and then I can re-enable class caching. Today, though, a production implementation would probably run into trouble not too far down the road.

I haven't looked at the wicket-extensions at all.

I'm going to add GORM support from the Grails package. That is a really cool technology. Alternatively, we might be able to use Wicket as a render technology inside a grails app. Anybody know if this is possible? I have very little Grails experience.

Simplify the IDE and build procedure. This is one of those things that quickly turns off new users. Frustrating build experiences are bad.

Add some template applications. Set it up so getting off the ground takes little effort.

If anybody would like to pitch in, let me know.

Monday, March 19, 2007

Backwards Magic

Just spent a long, long time on this puppy. I couldn't get the overridden methods on a Form object to see a variable reference at the Page level from inside a closure.

class CompClosuresPage extends WebPage {

SomeData someData = new SomeData(name:"heyo", value:"someval")

public CompClosuresPage()
{
Closure testClosure = {
println someData.name
}

Class newFormClass = CompClosuresPageTestForm.generateClassInJava(testClosure)
Form form = newFormClass.getConstructor((Class [])[String.class]).newInstance((Object[])['baseForm'] )
form.setModel(new CompoundPropertyModel(someData))
form.onTestEvent()
}
}

Pretend 'onTestEvent' is like 'onSubmit'.

This fails. 'CompClosuresPageTestForm' is a test class I came up with that extends a Wicket Component of some type. If I remove that base class, the code above works.

Anyway, very long story short, If I changed the base class to a non-Wicket one, it worked. A Wicket one, it didn't. After a long walk all over the class hierarchy, I sorted it out. Inside wicket.Component:

/**
* Gets the component at the given path.
*
* @param path
* Path to component
* @return The component at the path
*/
Component get(final String path)
{
// Path to this component is an empty path
if (path.equals(""))
{
return this;
}
throw new IllegalArgumentException(
exceptionMessage("Component is not a container and so does not contain the path "
+ path));
}

It looks like Groovy is calling this all the time. I'm not sure what to do about it. At 'wicket.MarkupContainer', its final, so I can't override it and try to handle it gracefully. I can't really try to change the guts of groovy either. For today, if you want to access a class level property from an overridden closure, you'll have to call the getter method (implicitly or explicitly defined). The above closure would have to be written as follows:

Closure testClosure = {
println getSomeData().name
}

Ok, I spent a little more time on this. It is in fact the issue. The MetaClass picks up the 'get(String)' method as the general property accessor method. What I tried to do was put a delegating metaclass into the registry for that class type after its dynamically generated. Then, if the access fails, bubble that up and it should check the Page class. Its not working for some reason, though, and I've spent too much time on it today. I'll leave the MetaClass class in the code and get back to it later. I think without altering either groovy or wicket, that would be the way to go.

Sunday, March 18, 2007

Wicket Groovy Builder finds a home

After a chat with Eelco Hillenius from wicketstuff.org, my new wicket groovy project is now integrating with wicket-groovy over at wicketstuff.org. The wiki page is at...

http://wicketstuff.org/confluence/display/STUFFWIKI/wicket-groovy

Putting it there makes a whole lot more sense than starting a new project.

I've converted the package name and committed the first version of the builder project to...

https://wicket-stuff.svn.sourceforge.net/svnroot/wicket-stuff/branches/wicket-1.3/wicket-contrib-groovy

The trunk has not been updated yet, as it works with wicket 2.0, and I haven't even looked at that code yet.

The original wicket-groovy project had one maven project with an example app mixed in. I've moved that into two maven projects:
  1. jar: This is the java-only base package
  2. webapp-example: This is an example webapp (as of today, I haven't added anything here)
Setting up the project and IDE can be a bit complex. I have a basic description on my site at:

http://www.kgalligan.com/wicketgroovy-setup

Wiki updates and mailing list announcements coming soon...

Friday, March 16, 2007

Roadblocks

Sometimes all the clever stuff in the world can't get you past something seemingly simple. I'm still plugging away on my groovy/wicket builder implementation. In order to emulate anonymous inner classes I pass a closure to the builder, with the same name as the overridden method. An example:

Java:

add(new Form("someForm"){
protected void onSubmit()
{
//Do something
}
}


Groovy:

form("someForm", onSubmit:
{
//Do something
}
)

Under the hood, I generate a new class that overrides the base class (in this case, wicket.markup.html.form.Form). The method is overridden. The overridden method calls the Closure. Complicated? Yeah, but functional.

Well, almost functional. There's one little thing (so far) that doesn't work. It looks like the following:

form("someForm", onSubmit:
{
super.onSubmit()
}
)

Since the class under the hood overrides 'onSubmit', you can't use 'this'. From what I can gather, there's no way to call 'super' through reflection. I tried several different things, but in the interest of getting on with life, I made a shortcut. Each method that is overridden will now have another method that looks as follows:

[access] [return] super_[method name]([params])
{
super.[method name]([params])
}

An example:

protected void super_onSubmit()
{
super.onSubmit()
}

Hey. It works.

I've been out for a few days. Checking with sourceforge again...

Wednesday, March 14, 2007

Groovy Wicket Continued

Ok. I wrote a setup guide for trying out the Groovy Wicket stuff. Take a look:

http://www.kgalligan.com/wicketgroovy-setup

Also added a simple example page tutorial:

http://www.kgalligan.com/wicketgroovy-simplepage

I'm still waiting for sourceforge approval. More to come...

Sunday, March 11, 2007

Groovy Wicket

Intro

This is going to be a long post. The first part is a ramble and background info on dynamic languages and other stuff. If you want to read about the wicket/groovy thing, skip ahead. Also, I'm currently interviewing in NY. Shameless plug at the end...

Its been a strange time for me, technology wise. Well, all over the place, but certainly on the technical front. I'm about to go live with my big project of months past. Its based on JSF/Facelets and Hibernate. I've been a huge Java fan for quite some time, so new front end technologies, along with the solid ORM tool we've come to love seemed like a natural fit. I'd heard a little about these new fangled dynamic technologies, but it all sounded like a lot of hype to me.

About a month ago I spent a day interviewing at a company call Cyrus Innovation. This was a huge eye opener. They actual follow agile techniques, including actual pair programming all the time, which is something I've never seen. I've heard a lot about it, but in most cases, management didn't have the will to actually do it. I, as a manager, thought it was kind of a crazy concept, but having seen it, I think it works. I also learned that unit testing is actually important. Seeing full unit testing in practice makes that clear. I also saw a group of people who actually thought Ruby and Rails is a revolutionary platform. That, I just didn't get.

Its easy to call it hype, but the people at Cyrus are very intelligent, and they are very, very efficient, so hype would burn out pretty quick if it didn't deliver. So why were they so big on it?

See, here's the thing. I actually don't dislike Ruby or Rails. What I don't like is the concept of dumping all of your existing code (and all of the world's open source code, and the non-open source stuff, if you like that sort of thing). It seems a little drastic to just toss everything out. Right? I've been reading lots of blogs and opinions, and the pro-dynamic camp have the opinion that languages age and die out, and new ones come and take their place. This is logical, as its what's happened in the past. However, as you hear in the omnipresent financial services commercials, "past performance does not predict future results". I just think we have too much value in existing platforms to simply toss it out and start over. On top of that, I don't think dynamic languages serve all purposes, and I certainly don't agree with the productivity improvement claims in all cases.

So, with all that in mind, there are a few options:

JRuby would be one, but there's some work to get it functional with Rails (as far as I know). It also seems a little reactionary for my taste. Not that there's anything wrong with it. Jython is another entry into this category. Both have the issue of a foreign syntax, at least for a Java person. I also just get the impression that neither is really going to pull ahead.

You know where I'm going. Groovy rules. At least for the Java platform, it seems like the obvious choice. You could argue that it doesn't have all of the features of Ruby, or maybe isn't quite so "dynamic", but you'd really have to wow me with something to get me to think it would make a difference. Groovy is well suited for the JVM, and it only took a little while to love it. If you add on top of that Grails support for Rails-like ORM, but on top of, and compatible with, standard Hibernate, and I'm sold.

In fact, I think Java would be best served to be largely left alone, and have Java and Groovy co-exist. Java is a solid platform and well suited to more system level stuff. Groovy isn't as good on performance, but is easier to code and test with. You can call classes back and forth, seamlessly, and use either flavor of language as the situation dictated. I think Groovy is a fantastic technology and all I'm worried about is that it'll get buried industry momentum alone. (I also think the name should be changed. I was on an interview yesterday and mentioned it. Doesn't sound professional, and the reaction reflected that. Just my $.02)

Anyway, yeah, Groovy is good. Right before I got into Groovy, I started looking at a technology called Wicket. After working with JSF for almost a year, trying Wicket was like that movie scene where the clouds part and this big ray of light hits you in the face. I just had this feeling while JSF'ing that certain things were harder than they needed to be. Well, I was right, and the Wicket people figured it out.

Wicket and Groovy

Technically, you can use Wicket and Groovy with no changes. You can just compile your groovy classes into java classes, and that's it. There is, in fact, an existing library for wicket/groovy integration, but from what I can tell its just providing a classloader for groovy classes. If you're compiling, you don't really need it.

There is a problem, though. You *can* code Wicket pages with Groovy, but its painful. Groovy doesn't allow for inner classes, and certainly not the anonymous kind. Wicket can get by with name subclasses, but you'd be doing a whole lot of extra coding. Groovy is supposed to be cutting that down. So, I started looking for a way to smooth this out a bit. Since Groovy is dynamic, I figured there must be a way to do better.

I first tried to look at enhancing Wicket's library, like Groovy does with the GDK and standard Java library. I could add closure support to the standard extension points, and this would solve the problem for Groovy. Sounds nice, but there are a few problems:

  1. The first critical issue; I don't think you can use the MetaClass functionality when calling from outside Groovy. At least not directly. This will take a Groovy expert to verify, but here's what I think is going on. If you call an object that is 100% Groovy from Java, it makes the call through the MetaClass proxy. If you call a Java class from Groovy, it'll use the global Registry MetaClass for that Java type. If you extend a Java class in Groovy, and call it from Groovy, that object will get its own MetaClass. However, if you extend a Java class in Groovy, and call it again from Java, you're calling the methods directly again. No MetaClass proxy. If that is not correct, let me know, but that's what it looked like to me. The rest of the app is coming from Wicket, which is coming from Java, and wouldn't have access to the dynamic features until you've completely crossed the blood/brain barrier (and you wouldn't have).
  2. Even if you got around that, some Wicket classes are abstract. Simply intercepting calls and handed them to closures would be pointless. You'd have to implement a complex scheme to handle that.
  3. Another issue that I had to deal with anyway, Closures aren't Serializable. Hanging on to a reference in your objects doesn't work with Wicket.
To put it lightly, the start was painful. So, I kept digging away, and pretty soon I stumbled on the answer. Builders.

It was really the SwingBuilder that tipped me off. One of the first things you notice when starting with Wicket, assuming you've had some Swing, is the similar object model relationship. Its tree-like. Lots of 'add(component)' calls. So, we could just build the tree, add closures where needed, and we'd be off. Sounds nice.

Pretty quickly I ran into problems #2 and #3 above, compounded by a frustrating attempt to use the MetaClass to do a lot of the work for me. In the end, here's what I came up with.

  1. The name of each builder "function" node will correspond to a Wicket component. The builder will look through various packages for a component matching that name. A string is provided for the key. Pretty much every component needs one, so that was a no-brainer.
  2. Most components correspond to the [String] and [String, IModel] constructors. Some, however, do not. It would've been easier to just figure out the whole model and implement what was needed for each component type that strayed from the standard, but we want to play nice and support sub-classes and all that. Plus, there are special circumstances where you can use shortcuts to save you time. So, I built a facility to register custom component builder factories. You register a factory, and that class and its sub-classes will attempt to use it. You can override it for a sub-class, so you're not locked in. Also, if you have a custom component library, you can add it to the configuration in your application start up.
  3. The builder naturally follows the tree model, so in simpler cases the code cleans up significantly. As an example, the following Java:
item.add(new Label("id"));
item.add(new Label("name"));
item.add(new Link("setItem"){

@Override
public void onClick()
{
form.setPersistentObject(item.getModelObject());
}

});

turned into...

label("id")
label("name")
link("setItem", onClick:{ form.setPersistentObject(item.getModelObject()) })

  1. The subclassing issue was ultimately handled with closures. How that works is a bit complicated, and to be perfectly honest, I'm not sure if the solution is elegant and ugly. But it works.
In a nutshell, that's it. Keep your builder names the same as the component class names, and keep the component reference page (not yet created) handy, and you should be ok. This project is still FAR from prime time, but I think if the kinks can be worked out, it'll make Wicket development on Groovy much more compelling. At least I'm going to use it ;)

Something very important to keep in mind. The syntax looks like I'm substituting Java for a whole different language, and would be rigid and cause problems as you go forward. However, inside the builder you can use regular Java/Groovy code, and directly create Components with regular constructors, and add them manually. All of this while still in the builder tree. Because of this, you get the 80%-90% easy case with the builder, and can still seamlessly do the painful 10% that doesn't fit right.

An Example Page

Let's take a quick look. I made a demo application with a very simple data object, using databinder and hibernate. This should give you a quick visual overview on what the wicket/groovy builder can do. I'm using screen shots because posting code in the blog was difficult. Plus, this gives you a good idea of what it'll look like in the editor (which is where you'll see it anyway, right?)

Java Version



Groovy Version



If you take a look you'll notice the Groovy file looks similar, but just has less clutter. That, in a nutshell, is a lot of what the dynamic language stuff is about. I didn't "get it" for a long time, but I do now. The great thing about Groovy is that its type optional, so if you want your types in there, you can have them. Now all we need is some better IDE support, and I think Groovy will be (groovy).

Details

If you know a lot about Wicket and/or Groovy, and you have some time, I'd like to lay out the details of my implementation. Or, at least start. Hopefully I can get some feedback as I'm a beginner in both technologies. Also, I started this on Saturday, and I had been out pretty late the night before. The code is a little on the messy side right now, but I think the general design is functional.

Here's how things work. We match up components based on name. Right now the matching facility is pretty flat. It looks through the configured packages for the name, and uses the first one found. After that, the name is cached. It will also look in the same package as the page. This allows you to override a class right in your groovy file and use it. The configuration needs to be more robust. Maybe you only want certain parts of the app to use certain figurations? For today, there are bigger problems, but this is on the list.

WicketBuilder builder = new WicketBuilder(page)
builder.label("pageTitleHeader", model:new PropertyModel(this, "name"))


The first line creates the builder. You supply a context argument. The second line is the root level call, to 'label' in this case. It does a simple match to the Wicket 'Label' component. Next is the list of arguments to 'label'. The first is the main one, which is the Wicket key value. After that, you supply [name:value] pairs. In this case, 'model' is the name, and a new 'PropertyModel' object is the value. Anyway...

So, you've found the component you want. Now you need to look in the configuration for a ComponentBuilder factory for that particular component class. The structure is in a class called 'ClassHierarchyTree'. I'm sure there are plenty of similar implementations, but I wanted something quick and dirty. It works like a tree map. You can add Class definitions as key values, and associate them with data objects. When you go to look something up, you pass it a Class object. It'll pull the data associated with that Class, or the closest superclass. Pretty simple.

Ok, so you have a factory class. This factory will get the attributes you set for the object and use them to initialize an instance. If you are missing something, it should throw an exception and bomb out with a reasonable message (cleaning the messages up is a todo). In the example above, the factory will call the standard constructor for Label with the String key, then call 'setModel' with the model argument.

Things get interesting when you supply a closure as an argument:

link("setItem", onClick:{ form.setPersistentObject(item.getModelObject()) })

Here, 'link' matches with the Link component. 'setItem' is the key, similar to the Label above. However, 'onClick' has a closure as an argument. What happens now is the factory class builds a list of all closure arguments, then actually generates a new sub-class of the component. This sub-class will override all relevant methods, and delegate to the closure at runtime. If a method isn't found for the named closure, it will throw an exception and the page will fail (say, if we'd typed 'inClick' instead of 'onClick').

Rigth now there is no caching going on, so each time this happens a new class is generated dynamically. It works, but we could cache classes with the same signature. That's on the todo list.

My big concern is how I'm handling closures. Closure instances aren't Serializable, so keeping them in Components doesn't work. However, Closures correspond to Classes under the hood. So, I actually stuff a reference to the Class representing the closure into the Component instance. It seems to work ok. There are some issues I had to deal with. First, local variable references would be worthless. Luckily, the Closure has a different constructor in these situations. If local references are found when the Closure class is set, it will fail with a useful message.

So, anyway, sub-classes. The beauty is that abstract classes get concrete implementations as a result. It all sort of works. I'm sure there's a big issue in there somewhere, but tonight I feel pretty good about the whole thing.

I'm going to upload a zip of the code for now in case you'd like to take a peek. Hopefully the sourceforge project will be up soon, but in the meantime, this should do.

Wrap Up

If you're still with me here, congrats. Here's my immediate plan. I've posted a sourceforge project request. When that comes back, I'll add everything there. I'm working on a big project right now that I've been mildly neglecting to get this functional, but will start using this on that project. Just the back end pages, of course. I'd like to find somebody with serious Groovy and/or Wicket understanding who would be interested in taking a look and seeing if there's anything glaringly horrible going on. If anybody wants to help, obviously let me know.

Off the top of my head the todo's are as follows:

  1. Stabilize configuration and come up with a decent demo app
  2. Do some real unit tests (there are some, but they're pretty light)
  3. Explore integrating GORM from Grails, or the other way, using this as an alternate view layer in grails. I have very little grails understanding, although the GORM stuff is pretty sweet, and I'd love to hook it into this for an easy win
  4. Make sure there aren't big issues with the way Closures and dynamic classes are being generated. I'm not sure how a clustered environment would react
  5. Implement the extension stuff. Right now its just the standards and a little of databinder
  6. Cache generated classes
  7. Build some simple CRUD generation tools. Similar to Grails scaffolding, but far less robust. Just point at a domain class and build a list display and edit form
That's it for now. I'm wiped.

Employment

If you're still with me, I'd like to put out a call for employment opportunity. I've been taking my time finding my next career step. Its been a couple months of interviewing now and I'd like to make a decision soon. See my page for resume, other work, etc.

More to come...

Thursday, February 08, 2007

Wicket BPM Update

I got the sourceforge project running...

https://sourceforge.net/projects/wicketbpm

I'm going to try to add info on the project to the forum page for now. I have absolutely no time for documentation right now. I'm involved in about 20 different things.

I did go back and start writing tests for the code. See my previous blog post. I recently spent a day with a shop that actually does unit testing 100% of the time, and I got to see how it actually works in a real system. I've been an arrogant fool, what with all of my untested code. I was wrong.

Back to my big JSF/Facelets project till, probably, sometime next week. Then back to Wicket land.

I Finally Get It

I paid lip service to test driven development for a while now. Did the same for "agile" techniques and pair programming, etc. From my last job I had a very cynical view of the way this type of environment would actually work.

Well, I recently spent a day at a little consulting shop here in the city. It was a full day interview. I went in in the morning (very tough if you've been waking up without an alarm clock for 6 months), and worked with them all day. At first I thought the way they were developing was pretty anal. I still think SOME of it is, which I'll get to in a minute. However, later in the day, I switched seats and worked with someone else. The difference in people didn't matter so much. Its just that this second task was very different. It was modifying a data structure that went across several systems and screens, and was modeled in the database, as a class data structure in 2 languages, and as xml between systems (plus, you know, screens and whatnot). This guy hadn't ever seen this code. Obviously, I hadn't either. So we start banging away, and the tests are bombing. It took a little while, but by the time we were done, all the changes were made and it really looked like the system was going to be ok. We had stuff shake out that we'd NEVER have found by manual searching. It was awesome (you know, for a huge nerd such as myself).

I admit, I was totally wrong. Great system.

I do, of course, have some things I disagreed with. They were using Velocity as their front end technology. They did this because its simple and allows testing isolation. This is where I think a dogmatic test-all approach is a little wasteful. The first task that I was referring to above was to change the display of one report screen. What they would do is build a 'gold master' screen of html from test data. Then their unit test would periodically compare that and current output to see if they match. Then, if you change the screen, write out the new 'gold master'.

I asked him, you know, what's the point? Yeah, there are possible situations where you might trip something, but I have to imagine there are ways to get a warm fuzzy from your code without all this explicit work. I was thinking if you used an IDE with some code completion for JSTL, it should be able to recognize that your accessor string no longer matches up to a property of the object you're using. I know that, ideally, the tests should be able to run on their own, but this is a situation where you're painting yourself into a corner with regards to tool choice.

However, that's not the big take away. The big point is I saw test driven development in a real project setting, and it was as sweet as the hype claims.

On top of that, I saw immediately the benefits of pair programming. As a manager, I implicitly thought it was like paying double for the same work. I now realize there are many things pair programming saves. Nobody is browsing CNN or IM friends from the office. That right there probably pays for it. You also get the obvious stuff. Less bugs. All that jazz.

When we sort out my employment status there, I'll post the name of the company and maybe I can get them some business or whatever. All I can tell you is as a manager who worked at a high stress financial company, I always thought every place was about the same with regards to real world vs. ideal. I couldn't be more wrong. This was like the Shangri-La of programming. They were very productive, but not stressed. Awesome. The biggest golf clap ever.

Sunday, February 04, 2007

Wicket and JBPM

* Update * Since this post, I've published the initial project at...

http://www.kgalligan.com/wicketbpm

Now back to the original post...

Settle in. This will be a long one. I know its Superbowl Sunday. Maybe its my HS football knee injury, or my shocking inability to remember names, but I just don't care. What we should do is put it on a Tuesday, then make it a national holiday. This would result in a day off of work, and maybe that would induce me to care. I can dream.

Anyway, I've been working on a drop-in web app client for JBPM for a while now. I started it a long time ago, but didn't take it very far. Its hard to explain exactly what it does or why its useful. The first thing to understand about this implementation is that its essentially a wrapper around the concepts I've learned over the past several years implementing a BPM solution inside an organization. Its an attempt to whittle out the stuff that we found commonly popped up. The end result? You should be able to include this application in YOUR web application, dress it up to make it look native, and seamlessly provide workflow/BPM functionality.

Lets have some background first.

What is BPM?

BPM, or Business Process Managment, describes a class of tools, platforms, frameworks, standards, etc. for modeling business processes with software systems. Its what you might call "workflow".

I'll have to come back and flush this out a bit later. For now, please read the following, as its a much better explanation than I could give here.

The major points to take away for this project are that with BPM you can graphically model a business process. Once that is done, certain steps in that process can be set up as tasks to be performed by a human user. When you start an actual process instance, and a task is assigned to a particular user, that user can see the task in a list on their screen, and do whatever is needed with it.

What is Wicket?

Wicket is a web application framework, built for the Java/J2EE platform. See the wicket project for more information.

Why Wicket?

There are a few reasons here. Probably the biggest driver is that I have recently started looking at Wicket and see many good concepts. I'm finishing a rather large project built on top of JSF and Facelets right now, and have done tons of Struts stuff in the past, and as such I've been exposed to a few web application framework concepts. Originally I was anti-Wicket, under the idea that we have too many frameworks already, and time would be better spent on augmenting an existing one (Tapestry, JSF/Myfaces, etc). However, there are some very compelling ideas that, even if Wicket doesn't stand the test of time, should be incorporated in other frameworks. I wanted a chance to test Wicket out. For that I needed a small, relatively isolated project. This was that.

Wicket is configured and extended through the use of standard OOP concepts, rather than relying on XML configurations and complex reflection practices. This is the first thing I really liked. Extensive XML configuration always got me a little upset. I never understood why it was better to do stuff outside of the code. In code, the IDE will tell you when you've got problems. You can extend and refactor easily, etc (this is one of my issues with the "dynamic" languages popular of late, but that's a whole different discussion). My recent foray into JSF showed me what extensive XML config means. Just my JSF config files on my recent project come out to about 2500 lines. That doesn't include hibernate, web.xml, or the various other config files I have *.

I like the way Wicket manages its page state. The initial problem I had with JSF was that if you kept the bean object in the request object you have to manually hold onto all of your state between requests. If you put it in the session you've got all sorts of problems with state coherence, back button, etc. Its a mess. The myfaces project includes t:saveState, which is awesome and saved my life, but I found it to be clunky at times, and in general odd to require a third party extension to make the platform functional. Wicket keeps a copy of the page object in a special Queue of pages. If you have a page with specific state in it, the back button keeps itself straight. This makes life a LOT easier. If used properly, of course.

One of the best things about Wicket? You can enforce an interface to your page. If you have data requirements for your page, just make a constructor with them. No default constructor. I can't tell you how awesome that is. I was mentally designing a way to do that in JSF, as I'd run into this problem on a number of occasions. JSF just gives you a way to define your bean in an xml file. You can't say, "the application needs to provide x, y, and z to make this bean valid". You could code that yourself somewhere, but again, this theme of avoiding the OOP platform we're building the application on. It doesn't make sense. I think Wicket hit this one dead on with a simple, and after seeing it, obvious solution.

By the way, related to that, I'd like to address the old "you can change the paths without recompiling argument" that went way back to the days of home grown control Servlets. This is just about the stupidest thing I've ever heard, and I've actually heard it. I have what I call the "Darwin test" for co-workers. Essentially, bring up a horrible idea in a meeting. I mean so bad you'd have to be totally incompetent to think it was a good idea. So bad, the people who aren't total nuts will know you're kidding. Then, whoever says something positive about it, and isn't themselves kidding, should be immediately fired. The first horrible idea I had? Telling everybody that we've "pre-debugged" everything, so we didn't need any QA. The "changing paths without recompiling" argument is now the second horrible idea.

Why is the "change paths" thing related? In JSF, which should be a modern example of a web app framework, the links between pages are stuffed into an XML file. The first problem? Well, the idea is that you're supposed to be able to change the target of a link. Could you? Yes. What's the problem? Very few pages can be shown "raw", as in without context arguments. You almost always need an ID, or a value, or SOMETHING. Right? Well, lets say you coded the application a year ago, or somebody else did it, and you go around changing those links later on. You might run into data trouble, but you won't know it till you start mucking around with the app. Similarly, if you change the target page around a bit and add new required fields, all calling pages will need updates. You won't know about problems till somebody clicks on the source page and it bombs. Wicket's method of linking essentially fixes this problem.

What's the other JSF problem? Not only does the config file not ensure data integrity, you really CAN'T pass data back and forth. You actually have to wire a link to the new bean into your current page's bean, stuff data into it in a method call, then ALSO put the link mapping into the config file. Of course, you could use myfaces t:updateActionListener (also saved my life), but once again we need something third party just to make the platform functional. Also, by way of full disclosure, I totally abused the t:updateActionListener thing. After a while you just get tired of doing things "properly".

Its complicated. I could go on, but that's not what this post is about. Its about my JBPM client. In truth, there's a lot I like about JSF too. Its just that there are some things that seem really poorly designed. I would still suggest JSF, especially with facelets, for most larger applications. Its got huge industry momentum. Also, the components that have already been committed by the industry, open source and commercial, are very useful. I do like Wicket better, but I'm still new to Wicket and perhaps haven't yet seen all of the downside.

Oh yeah. One other thing about Wicket that's pretty sweet. The detachable models. I've run into all sorts of trouble with Hibernate and detached sessions. You really have to know what you're doing to code around these problems and not get into trouble. Wicket allows you to wrap model objects and detach them when your request is done. I've used this for the TaskInstance object in this client (see kg.bpm.jbpm.web.wicket.TaskInstanceModel). Also see databinder.net for a great hibernate based toolkit for use with Wicket.

Anyway, there's some of "Why Wicket?". If you use the client app, you'll see that extending and customizing it should be relatively easy. Originally this app was built with a servlet/JSP task list, xml config file(s), and standard URL forwards so it could be used with any standard web framework technology. While this might have been a little more useful to the average user, I think this version is cleaner, easier to extend and use, and I just plain old want to support Wicket on this one.

What I don't like about Wicket? The name. It needs something cooler. Like "Wicked". Ok, that's lame, but you get the idea.

Why This Client?

In my experience, BPM platforms provide the server functionality, and many connectors and whatnot, but only provide minimal client tools for user task lists. They may provide an example application for inclusion inside your application, but you still wind up doing much of the coding yourself. I've concluded the reason for this is that many clients will want something that is simply too customized. Attempting to write an app to make everybody happy will fail, and the resulting application will be too complicated to give to somebody as an example of using the framework. This client will not make everybody happy, but should provide a quick implementation for your application.

BPM functionality is very powerful. There are many domains that would benefit from a little BPM, but they don't get it. Why? Well, until recently, BPM engines were ridiculously expensive. They still are, except for JBPM and other open source versions. Also, including this functionality in your app is not a trivial exercise. Add to that the learning curve, and you have some problems. Besides the standard technical learning curve, you really have to think differently when implementing on BPM. Why bother? Once you get it, you really get it. There's just a lot more you can do with minimal effort once you get BPM set up and you understand how it works.

You CAN hardcode the same stuff into your application. There's no magic with BPM. You can do the same thing with straight code. The problem, of course, is that you'll be doing all sorts of extra work.

So, again, why this client? You could use the client tools provided by the platform. At least internally you could. Log in, see your tasks, do them and mark them complete. No so hard, right? The problem is that many screens require custom input or display. It is an application, remember. Maybe the BPM process has an id value to an Account. If you used the standard tool, you'll see a number. The id value. What you WANT to see is the account data. You could, of course, stuff some other account identifier into the BPM process and get the whole thing to work, but your clients will get tired of this kind of thing pretty quickly.

This client provides for a few things. Each task can be mapped to a standard or customized task screen (or set of screens, as in a wizard). So, lets say you need to input a final price for something that is only known by you. When you get the task, it shows up in your list. Click the task, and there will be an input box, complete with validation specific to the task at hand. This is very important, and is the primary reason this project exists.

The second major feature of the client is process reporting. This is a simple concept, although the implementation is a little difficult to explain. Although you can fully customize the reporting (or completely rip it out and provide a totally proprietary solution), a standard templating system has been included. This will allow you to define templates to display the data associated with a particular process instance. Currently there is a simple implementation based on Velocity.

This has changed into a rant about different types of web frameworks rather than about the project, so I'll cut this off here. If you want to read just pure instructions, see my website...

* Yes, I realize that my anti-config-file stance would support Rails and Ruby. However, I would counter that its the way Rails configures itself rather than anything inherent in the Ruby the language that removes the config files. The extensive config files I mentioned above are due to implementation choice. Hibernate could use reflection to map its tables, stuff like that.

Tuesday, January 23, 2007

Screen shots with Gimp

I kept going with the gimp scripting. Yesterday I had planned on adding another script that would be quick and easy. Ha ha. No such luck.

When I take a screen shot and want to highlight certain areas, I add a layer on top, set the opacity to like 30-50, then use an eraser to uncover the part. Then I set the layer to "difference" and put the opacity at like 20-25.

Here's an example...

Does a pretty good job. Not a particularly pretty thing, but works. What looks a little better? Add some texture to the outline. I add a drop shadow, 2x, 2y, 3px radius. However, I only want it on the exposed area inside the outline. The drop shadow, however, darkens the whole thing...

To deal with this, take the original cutout layer, and paste it as a mask on the drop shadow layer. You need to invert the original layer first. Its complicated, however the output looks like the following...

The accent is minor, but I really like it. However, the steps involved to produce it are more than I'd like to do every time I want to do a screen shot. But hey, I just learned gimp scripting, so this should be easy? Right?

It is and it isn't. The problem I had was getting the layer into the mask of another layer. In theory I needed a channel object, then could plug that in as the mask. However, for the life of me, I couldn't figure out how to get a reference to a channel of the layer. I still don't know how. I spent (ie. wasted) much of yesterday working on it. Finally, instead of doing that, I just copy the layer, and paste it into the mask. I had tried this and couldn't get that to work either. A couple hours later I realized I need to invert the colors first, then it worked. Here's the interesting part of the code...

(gimp-invert inDrawable)
(gimp-layer-set-opacity inDrawable 100)

(set! shadowMask (car(gimp-layer-create-mask shadowLayer ADD-ALPHA-MASK)))
(gimp-layer-add-mask shadowLayer shadowMask)

(gimp-selection-all inImage)
(gimp-edit-copy inDrawable)
(set! floatingSel (car (gimp-edit-paste shadowMask FALSE)))
(gimp-floating-sel-anchor floatingSel)

(gimp-layer-remove-mask shadowLayer MASK-APPLY)

(gimp-invert inDrawable)
(gimp-layer-set-opacity inDrawable 20)
(gimp-layer-set-mode inDrawable DIFFERENCE-MODE)

I had to do a few other tricks. I'll post the full code at the end. One included a general function to get the layer below the selected layer. That kind of thing.

Anyway, using the plug in works as follows. Get a screen shot into gimp. Add a layer, all white. Set the opacity to whatever you want so you can see through. Use the eraser to cut out parts. (By the way, how to draw straight lines in gimp). Once that's done, just run the script. Make sure the cut out layer is selected. That's it. Make sure its white and selected. The script handles setting the opacity, putting it in "difference" mode, etc.

Put it together with my script from yesterday and you've got one fancy screen shot for web pages...


Full code...


(define (internal-getLayerBelow
inImage
inLayer
)

(set! layerArray (car(cdr(gimp-image-get-layers inImage))))
(internal-getLayerBelowRecurse
inLayer
layerArray
0
)
)

(define (internal-getLayerBelowRecurse
inLayer
layerArray
index
)

(set! currentLayer (aref layerArray index))

(if (= currentLayer inLayer)

(aref layerArray (+ index 1))

(internal-getLayerBelowRecurse
inLayer
layerArray
(+ index 1)
)
)
)


(define (script-fu-kev-style-cutout
inImage
inDrawable
)

(script-fu-drop-shadow
inImage
inDrawable
2
2
3
'(0 0 0)
80
0)

(set! shadowLayer (internal-getLayerBelow
inImage
inDrawable
)
)

(gimp-invert inDrawable)
(gimp-layer-set-opacity inDrawable 100)

(set! shadowMask (car(gimp-layer-create-mask shadowLayer ADD-ALPHA-MASK)))
(gimp-layer-add-mask shadowLayer shadowMask)

(gimp-selection-all inImage)
(gimp-edit-copy inDrawable)
(set! floatingSel (car (gimp-edit-paste shadowMask FALSE)))
(gimp-floating-sel-anchor floatingSel)

(gimp-layer-remove-mask shadowLayer MASK-APPLY)

(gimp-invert inDrawable)
(gimp-layer-set-opacity inDrawable 20)
(gimp-layer-set-mode inDrawable DIFFERENCE-MODE)

;(gimp-selection-all inImage)
;(gimp-edit-copy inDrawable)

;(set! floatingSel (car (gimp-edit-paste shadowMask FALSE)))
;(gimp-floating-sel-anchor floatingSel)


;(gimp-image-remove-layer inImage (internal-getLayerBelow
; inImage
; inDrawable
; )
;)
)

(script-fu-register
"script-fu-kev-style-cutout" ;func name
"Kev Styleize Cutout" ;menu label
"Make the cutout areas pretty" ;description
"Kevin Galligan" ;author
"copyright 2007, Kevin Galligan" ;copyright notice
"January 21, 2007" ;date created
"*"
SF-IMAGE "Input image" 0
SF-DRAWABLE "Input drawable" 0
)
(script-fu-menu-register "script-fu-kev-style-cutout" "/Script-Fu/Kev")

Sunday, January 21, 2007

Scripting Gimp

Last night I wrote a script-fu scheme script to automate some relatively simple stuff in Gimp. I'd put off trying to do this for a while, and even put up a request on guru.com to pay someone to do it.

You'd think I'd be able to do this fairly easily. In college we had to learn scheme for a class. I know gimp fairly well, and I've actually seen the handful of functions I wanted to call. It should just be a matter of getting a few things straight and that's it.

The problem is as follows. I hate scheme. Its confusing. I got the impression there was a lot of emporer's new clothes going on with it. There tended to be a higher quality and level of code with scheme projects, but I think that had a lot more to do with the people coding scheme rather than any advantage of the language itself. In fact, I find coding in scheme like swimming with a coat on. But maybe that's just me.

However, the only guru.com bid was for $200. The guy basically wanted to learn gimp's api on my dime. Personally, I was avoiding the exercise because of the time investment, but whatever. I'm a programming nerd. Once I got over the initial stuff, it wasn't so bad. On top of that, now I think I could do a lot quickly.

However, finding the right documentation quickly was difficult. Gimp has been around for a long time and several different scripting methods exist, so the documentation is fragmented and confusing. It turns out, the best place to start is on gimp's site (shocker).

http://docs.gimp.org/en/gimp-using-script-fu-tutorial.html

This will teach you a lot about scheme and writing scripts. Very, very, very useful.

I think the first question you have for yourself is which language should you use. Python, Perl, etc. seem like better options. However, there was some complication involved in the installation of those bindings. To be honest, I haven't figured out exactly what would be needed to use them. Because I was only calling a few simple functions, I decided to use scheme. I can deal with any language for a few functions.

For the person like me, who's been exposed to scheme before, I'll give the summary of the important things about the api that weren't clear before I started.
  • A "plugin" is defined by a main function. You can name the function whatever you want, but there's a naming scheme that gimp uses. You can read about it in the link above.
  • There are 2 types of functions. Those that operate globally (not a specific image). You can get the list of all images, or (more likely) create a new one. The other type is the image specific.
  • To write an image specific plugin, simply register an Image object as the first parameter and a Drawable object as the second. Gimp will provide those arguments.
  • All gimp functions return a list. ALL GIMP FUNCTIONS RETURN A LIST. Say it again. You need to wrap all returns in, at a minimum, '(car (gimp-some-funtion ...))'. This took me a little while.
  • One of the really cool things I didn't get was that those little dialogs that pop up for plugins aren't specifically coded. That's the part I thought would take a really long time. All you have to do is declare your variables. They show up in the dialog. I'm sure in certain situations this will be restrictive, but for the mast majority of situations, its much easier.
There's other stuff, but its redundant. For the most part, you can find it in the link above. I promise if you following along, you'll get it quick.

I'm including my code because I had a hard time finding simple examples on the web. All mine does is apply a border to an image, then apply a drop shadow. The idea is to dress up screen shots for documentation. Here's an example:

Its a screenshot of a little part of the gimp website. Functional, but hard to see what's really going on, where the shot starts and stops, etc. Well, it WOULD be if the screen background was white ;)

Here's the modified version:

Its a little easier to get your eyes around that one. The process? I applied a 1px gray border. Then I did a drop shadow. Pretty simple. However, the specific series of steps, while not terribly labor intensive, get annoying if you're doing a lot of them.

Here's the code...


(define (script-fu-kev-border-shadow
inImage
inDrawable
inBorderWidth
inBorderColor
inOffsetX
inOffsetY
inBlurRadius
inShadowColor
inShadowOpacity)

(let* ( (newLayer) )

(if (> (car (gimp-image-get-layers inImage)) 1)
(gimp-image-merge-visible-layers inImage 1)
)

(script-fu-addborder inImage (car (gimp-image-get-active-layer inImage)) inBorderWidth inBorderWidth inBorderColor 25)
(gimp-image-merge-down inImage (car (gimp-image-get-active-layer inImage)) 0)
(script-fu-drop-shadow
inImage
(car (gimp-image-get-active-layer inImage))
inOffsetX
inOffsetY
inBlurRadius
inShadowColor
inShadowOpacity
1)

(set! newLayer
(car
(gimp-layer-new
inImage
(car (gimp-image-width inImage))
(car (gimp-image-height inImage))
RGB-IMAGE
"layer 1"
100
NORMAL
)
)
)

(gimp-image-add-layer inImage newLayer 2)

(gimp-drawable-fill newLayer 2)

(gimp-image-merge-visible-layers inImage 1)
)
)

(script-fu-register
"script-fu-kev-border-shadow" ;func name
"Kev Border Shadow" ;menu label
"Convenience call to border and shadow" ;description
"Kevin Galligan" ;author
"copyright 2007, Kevin Galligan" ;copyright notice
"January 21, 2007" ;date created
"*"
SF-IMAGE "Input image" 0
SF-DRAWABLE "Input drawable" 0
SF-VALUE "Border Width:" "1" ;a string variable
SF-COLOR "Border Color:" '(102 102 102) ;color variable
SF-VALUE "Shadow Offset X:" "3" ;a string variable
SF-VALUE "Shadow Offset Y:" "3" ;a string variable
SF-VALUE "Shadow Blur Radius:" "5" ;a string variable
SF-COLOR "Shadow Color:" '(0 0 0) ;color variable
SF-VALUE "Shadow Opacity:" "80" ;a string variable
)
(script-fu-menu-register "script-fu-kev-border-shadow" "/Script-Fu/Kev")


More later.

Friday, January 12, 2007

IPhone 2012

I was thinking about the future of the IPhone. We'll assume they sort out the lawsuits.

The device I see coming out around 2012 is just about the coolest thing you've ever had. I'm guessing it'll look similar in size to the current version, although I have this strange feeling that the IPhone will be coming in two basic flavors.

IPhone Big: This is what they debuted recently. It'll be an ipod replacement, smart phone and media player. Will really wind up being a laptop replacement. Everybody seems to agree on that at this point.

IPhone Small: This will be primarily a phone. Smaller form and screen. Under the hood, some of the really sweet laptop replacement stuff may be there, but the physical size constraint will push out some of the interface fanciness.

Because of the split in form factor, I'm thinking there's a small possibility that Apple will attempt to put the little keyboard on the Big one. While not as elegant as the '07 design, the keyboard is pretty sweet. Here's what they may do. On one side have the main, full form display. On the back, have a partial size display, with a very slim factor (height wise) keyboard. The weight sensor should be able to guess which side you're looking at, and if not, when you hit a key it'll be pretty obvious. This will also allow for some interesting display options while you're talking, as you'll have the whole other side of the phone to display stuff on while talking (to annoy other train passengers or whatever. Maybe you can start a mobile ad service...)

Anyway, we're getting ahead of ourselves here. Smartphones will start to replace full sized machines as time goes on. This has been discussed a lot recently, and it seems like an obvious move. Coupled with a flash based drive of reasonable size, 50-100gb, the phone will serve as a computer itself. Here's what I'd like to see:

Wireless monitor connections. Hold the phone next to your (or any) monitor, press some confirmation on your phone, and you start broadcasting an image to the screen. This is nice for displaying on a real screen. I could see this working on a plane, in little airport booths, meetings, etc. Also, expand it out a bit, and you can imagine a little "work station" (not a new word/phrase, but its used in many different contexts with different meanings, so I put it in quotes). A small reciever/transmitter. Put the phone next to it, click the confirm, and you have access to keyboard, mouse, network connections (if you need something other than wireless), and monitor(s). You can do some work, then just grab and go.

These little work stations should also have another really awesome thing. The little node you communicate through should have a universal charger. You really need to connect nothing. When you get home, put the phone on that little stand, and you have keyboard, mouse, monitor, and its charging. Awesome.

Phone will have built in firewall services. I think its also imperative that the long term storage on a such a device should should encryption built in. If stolen, the data should not be readable without a key of some type. This is an absolute, and certainly not out of the realm of current possibility.

On the OS end, we absolutely need more transparent management. I like using windows, but lets be honest, even nerdly experts such as myself wind up with tons of gunk running after a while. I'm not even talking about all the spyware out there. Stuff like the "Install Anywhere" update process that completely hides itself, but occasionally pops up to tell me it wants to update itself. Apple annoys me to no end with the Quicktime install. I DON'T CARE IF IT TAKES LONGER TO SHOW A VIDEO!!! I don't want something resident in memory. I'm sure it won't happen, but on my wish list is better management for this kind of gunk. Come on, we're all grown up now. Time for something more professional.

Hmm, what else? Oh yeah. Smart card payment technology. Obviously.

Really weird. My roommate barged into my room to give me an article about the iPhone, and he's not a computer guy. Pretty funny. I was actually writing this when he did it. We talked, and I thought of something else. If the phone is going to replace my laptop, I need to be able to buy it and then choose the wireless service. No two year lock-ins, etc. Also, as part of service, I'm thinking some type of online backup.

This could merge with a google business idea I had way back when. Offer wireless service. In exchange, you get location based advertising. Like if I walk past a starbucks, a little deal might pop up on my screen. Walk past Best Buy. The phone knows I like metal and I have an Xbox, so it pops up some type of deal. It would have to be relatively un-annoying. Like google ads now. However, this type of coupling, advertising on the phone in exchange for service, might work. I'd be ok with it as long as it didn't get too detailed into my personal info.

Also, along with this, I was thinking Google might just come out with its own gadget. Something like the iPhone, that offered phone and smartphone/computer service, in exchange for location based always-on advertising. The economics would probably be way off to do it ALL for free, but if google said I could have a mini laptop and service for $300 and some moderately annoying ads, assuming the device and service were quality, sign me up. Sorry Steve.

By the way, I'm looking for a job right now.

Other stuff, like a mini projector would be nice, but I'm thinking the wireless monitor thing might make that less useful.

That's it for today.