Wednesday, 29 March 2006
Frappr
There's a blojsom group on Frappr.
Damn you web 2.0! Damn you to hell! Big ups to my homies in Austrialia, Italy, and the UK.
Secured
...
Nine Inch Nails, Saratoga Performing Arts Center
Number of tickets: 2, Seat Locations: Section 1, Row J, Seats (121, 122)
...
Technorati Tags: nin nine inch nails
Monday, 27 March 2006
Seattle Geek Bowling Dinner
I'm flying into Seattle next week. I'll be there Wednesday, April 5th through Friday, April 7th.
I've booked a Geek Bowling Dinner (thanks Upcoming) to be held at Garage Bowling and Billiards.
Thursday, April 6, 2006 (7:30 PM - 11:00 PM).
Bowling! 'Nuff said
I'm also thinking of a less informal event on Wednesday evening at Tini Biggs. But, let's start with the bowling and go from there.
Technorati Tags: seattle geek dinner bowling
"Why’d you put your quarter down on me?"
Saturday, 25 March 2006
dbloader
I think I've made setting up your database in blojsom 3.0 as painless as possible. Let's assume you've already created a database called "blojsom" and have a user and password created that can interact with that database.
<!-- Initial database creation bean -->
<bean id="dbloader" class="org.blojsom.util.database.DatabaseLoader" init-method="init">
<property name="sessionFactory">
<ref bean="hibernateSessionFactory"/>
</property>
<property name="dbScript" value="/WEB-INF/classes/blojsom-full-initial-data-mysql.sql"/>
<property name="servletConfig">
<ref bean="servletConfigFactoryBean"/>
</property>
</bean>
After starting blojsom for the first time, you'll see the following in the log file.
Mar 25 12:17:00 INFO [main] database.DatabaseLoader - About to create blojsom database
Mar 25 12:17:00 INFO [main] database.DatabaseLoader - Read in sql script
Mar 25 12:17:01 INFO [main] database.DatabaseLoader - Finised blojsom database creation
Mar 25 12:17:01 DEBUG [main] servlet.BlojsomServlet - blojsom: All Your Blog Are Belong To Us
Then, just login to your blog and start blogging.
If the database has already been created, nothing happens.
Mar 25 12:17:27 INFO [main] database.DatabaseLoader - About to create blojsom database
Mar 25 12:17:27 INFO [main] database.DatabaseLoader - blojsom database already created
Mar 25 12:17:27 DEBUG [main] servlet.BlojsomServlet - blojsom: All Your Blog Are Belong To Us
Maybe that bean can also take a list of upgrade scripts to apply as versions of blojsom change and the database needs to be updated. Better yet, maybe the bean checks the version of the database in use and applies the database upgrade scripts automatically. This way all you need to do to upgrade blojsom is to update the JAR files.
Well, we'll see ... Basically I want to ensure blojsom retains its simple 5-minute (or less) installation.
Technorati Tags: blojsom
Thursday, 23 March 2006
blojsom 3.0
Executive Summary
blojsom 3.0 was re-architected using Spring and Hibernate.
Detailed Summary
Let's start with a brief history of time.
01/29/2003 - blojsom project was registered on SourceForge and development was started.
02/02/2003 - blojsom 1.0 was officially released. 18 releases were made in the 1.x cycle.
09/10/2003 - blojsom 2.0 was officially released.
06/28/2004 - Apple officially announces Tiger Server wherein blojsom is bundled as Weblog Server.
03/14/2006 - blojsom 2.30 was officially released. 30 releases have been made in the 2.x cycle.
blojsom was my first foray into developing open source software. After starting the project, just over a year in development, it makes it into a server operating system. And after 3 years, the project is still very active. I'd like to think the project has been successful.
Yet, for the past few months I've been feeling like I've put blojsom in maintenance mode. I'm not really sure I can put my finger on why that's the case, even though quite a bit has been done ... at least according to the log of changes.
I guess I needed things to change, to be challenged, to be different ... to be anything but what blojsom currently is. And so last week at night and throughout this week at night, I've re-written most of blojsom. Hmmmmm .... re-written is a bit of a stretch. Re-architected is more like it since I re-used all of the code from blojsom 2.x. The fruit of that labor is blojsom 3.0. Let me try and explain, at least at a high level, what changes have been made and why.
Developers, haters, player haters, skips, skaps, skallywags, etc... may be interested in following along blojsom 3.0 via CVS. I've already seeded the blojsom 3.0 module.
Spring
The first major change has been in the way blojsom is “wired†together. I’ve rewritten blojsom to use Spring for its dependency injection and bean management. There were aspects of the blojsom 2.x codebase that were more "patchwork" with respect to how certain components used or referenced other components.
This is how blojsom is initialized in blojsom 3.0.
protected String[] BLOJSOM_CONFIGURATION_FILES = {"blojsom.xml"};
public void init(ServletConfig servletConfig) throws ServletException {
super.init(servletConfig);
ServletConfigFactoryBean.setServletConfig(servletConfig);
_classPathXmlApplicationContext = new ClassPathXmlApplicationContext(BLOJSOM_CONFIGURATION_FILES);
if (_logger.isDebugEnabled()) {
_logger.debug("blojsom: All Your Blog Are Belong To Us");
}
}
Suffice it to say that the initialization code in blojsom 2.x was longer. Spring allowed me to delegate all the initialization and dependency management of the components used in blojsom to Spring. And therein lies the rub, that's exactly what Spring is supposed to be used for. Imagine that! If you look at BlojsomServlet, all of the "meat" is in the service(...) method, exactly where I want it to be. blojsom should be good at servicing blog requests, not managing dependencies or lifecycles for components.
There were also a number of Spring bean lifecycle methods that matched various lifecycle methods in some blojsom components. Namely, init and destroy methods. The Spring integration was simple and I think more meaningful to the codebase. For example, plugins that require the use of the fetcher (to do stuff with categories or entries or users), now simply add a setFetcher(Fetcher fetcher) method and then declare that bean dependency in blojsom-plugins.xml. It allowed a lot of boiler plate/cookie cutter code to be removed from a lot of places.
Sincerely, a hats off to the Spring developers.
Hibernate
The second major change has been in the datastore. I don’t necessarily think I’ve exhausted all that can be done using the filesystem as a content database, but I’ve been feeling like there’s a lot of development energy into making relations between data in the filesystem that can be expressed very easy using a relational database.
In blojsom 3.0, I’ve settled on using a relational database for the datastore. I'm using Hibernate as the ORM library to manage the data. This means goodbye to all the .properties files for configuration! It was fun while it lasted. The templates and themes are still stored on the filesystem, but I’d envision also storing the template data within the database as well. I've already prototyped use of the Velocity database template loader. I imagine removing any filesystem dependency will allow blojsom to be used in a clustered environment more easily.
Hibernate made the interaction with the blog data straightforward. For example, here's an example of some code where I'm checking to see if a Pingback has already been registered. The Pingback specification says you MAY choose to only register a single pingback from a source URI to a target URI. Nerdy digression here ... yes ... but one of those, "Damn, that's smooth" moments working with Hibernate.
Session session = _sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Map metaData = new HashMap();
metaData.put("pingback-source-uri", sourceURI);
metaData.put("pingback-target-uri", targetURI);
Pingback pingbackToFind = newPingback();
pingbackToFind.setBlogId(blog.getBlogId());
pingbackToFind.setMetaData(metaData);
Criteria pingbackCriteria = session.createCriteria(org.blojsom.blog.database.DatabasePingback.class);
pingbackCriteria.add(Example.create(pingbackToFind));
pingback = (Pingback) pingbackCriteria.uniqueResult();
tx.commit();
session.close();
Ultimately I think this will allow blojsom to scale much more than I think it can using the filesystem as a content database. I don’t believe there are any esoteric relationships among the data in blojsom as to require a full-time DBA to manage an installation of blojsom.
Also, and this remains to be proven, but aside from the database creation scripts which may differ between say MySQL or Oracle (or some other database), you should be able to change the "dialect" Hibernate uses and be running on something other than MySQL in no time.
This is probably the one that there will be the most discussion on, but I've already got migration paths for current installations on blojsom 2.x.
Again, sincerely, a hats off to the Hibernate developers.
Blojsom API
The last major change has been in evolving blojsom's API.
For awhile now there are aspects of the API that were a throwback to needing certain data or referring to elements a certain way. I just wanted a more self-documenting and less redundant API.
For example, I’ve renamed the BlojsomPlugin interface to Plugin. I felt that having the org.blojsom.plugin package was declarative enough, but that keeping BlojsomPlugin was too redundant. None of the APIs have gone away, they're just more simple and straightforward. For example:
- BlojsomDispatcher -> Dispatcher
- BlojsomAuthorizationProvider -> AuthorizationProvider
- BlojsomFetcher -> Fetcher
- BlojsomEvent -> Event
- BlojsomListener -> Listener
- BlojsomEventBroadcaster -> EventBroadcaster
- BlojsomFilter -> Filter
- and so on
I guess that's all there is to say on that.
Entries, comments, trackbacks, pingbacks, and users have a status field allowing for more complex workflows to be applied to these objects. Entries have a modified date. The User object differentiates between login ID and a more friendly user "name". There are many other changes I've left out.
Again, I think blojsom 3.0 has a more meaningful and richer API.
Conclusion/Roadmap
The long and short of it is that you can do all of the things in blojsom 3.0 that were done in previous releases of blojsom. There are a few more components and plugins to migrate to 3.0, but I'm happy with how far things have come in such a short time given the scope of the changes.
Over the next few days, I'm going to finish the work on:
- Initial database creation
- Bulk response management
- Comment API
- Static site rendering
You're more than welcome to start playing with blojsom 3.0 right now. All that you need to do after setting up your database is to add a blog and a user for that blog and you'll be able to login through the administration console.
If any of this interests you, feel free to participate on the blojsom-developers mailing list.
Wednesday, 22 March 2006
"All of a sudden, I found myself in love with the world"
Friday, 17 March 2006
"Well I know it sounds strange but it could be the other way"
Ripped
I've started ripping all the CDs from my 400 disc CD carousel. It's not a painful process, but ripping really requires you to devote the computer's resources to the ripping, otherwise it's slow.
It's been great re-discovering all this music.
Also, the acoustic and electric guitars are wired into the computer and ready to go when it strikes my fancy. I've forgotten how many great songs there are to play along with. Highlights include, but not limited to (in no particular order):
- Matthew Sweet - Girlfriend: I love every single lead guitar part throughout this song. It's why I learned it all note for note.
- Meat Puppets - Backwater
- Tom Petty - You Wreck Me: I want to buy a Telecaster just to play Tom Petty songs.
- Led Zeppelin - The Ocean: It's hard to pick any Zeppelin song as a favorite to play. They're all good. Jimmy Page could've stopped after "Good Times, Bad Times". I mean ... damn. Maybe the only cover of "Good Times, Bad Times" worth a damn has been done by Phish. But, I could be wrong.
- Smashing Pumpkins - Cherub Rock
- Jimi Hendrix - Red House: In 3:50, Jimi said and played everything I could ever want to hear in the blues. This song is the reason I really started playing guitar. "'Cause if my baby don't love me no more, I know her sister will." Just ... wow.
- Primus - Wynona's Big Brown Beaver: Primus is just fun. Also, their cover of Pink Floyd's "Have A Cigar" off Miscellaneous Debris is spot on.
- Van Halen - Hot for Teacher: I should be so lucky as to approach any Van Halen song with the ol' 6 string. There's a reason Eddie Van Halen is one of the greatest guitarists of all time, this is just one of those reasons.
- Soundgarden - Outshined
- Jane's Addiction - Mountain Song: I need to listen to this snowboarding at some point. Cliched? Yes. Kick ass song? You betcha.
Well, just a sample there. Back to the ripping.
Thursday, 16 March 2006
"I'll keep you my dirty little secret"
"I just want to start things over"
Tuesday, 14 March 2006
blojsom 2.30 available
Blojsom 2.30 is now available.
Changelog
Upgrading instructions
Download updates
Download Quickstart
Bugs fixed
I improved blojsom's support for Pingback in this release.
Technorati Tags: blojsom
"I guess I'll save the best for last"
Monday, 13 March 2006
NIN (Saratoga)
Nine Inch Nails just updated their summer tour page and they're playing at the Saratoga Performing Arts Center. That's 15 minutes from home.
I ... am ... so ... there.
Technorati Tags: nine inch nails saratoga performing arts center
Season Finale
It's raining. That's not good for what's left of the snow here in the Northeast. Bummer. It's also going to make for less-than-stellar conditions for the U.S. Open Snowboarding Championships.
Thankfully, there were better-than-decent conditions at Stratton this past Saturday. It was warm and partly sunny, which made for some fun "mashed potatoes" in the afternoon. The crowds weren't all bad except for the 2 times coming from the top where one of the mid-mountain lifts was first time, closed, and second time, down for maintenance. That meant cattle conditions in line for the gondola. But, the wait was only 15 minutes, so I guess it's all good.
I finally got a chance to really break in the iPod jacket. This jacket is the bomb! It really is a different experience charging down a double black and having music to affect your mood.
And I'd say that my trip to Whistler/Blackcomb really affected my snowboarding in such a positive way. In 2005, when I started snowboarding, the last place I went was Stratton at the end of March. It's been just over a year since getting into the sport and coming back to Stratton, I could tell that I felt entirely different on the snowboard and about the mountain. Whereas last year it was the land of the green and blue, this year it was the land of the black and double black.
In April, I'm contemplating a trip to Killington for some real Spring riding.
Technorati Tags: snowboarding stratton killington
Wednesday, 8 March 2006
Bottom Shelf Liquor
The worst of the worst here at Bottom Shelf Liquor! Hands down the winner goes to Mellow Gold.
Vodka... in a paper carton.
'Nuff said!
Technorati Tags: bottom shelf liquor liquor mellow gold
Saturday, 4 March 2006
TextileMe
TextileMe is simple gui swing based application to write textile files. This application implements all known textile processors written in java (Textile4J, JTextile).
It's good to know people are still benefiting from Textile4J.
Friday, 3 March 2006
Geo-Blogging
Adam Burt at Ravensbourne College of Design and Communcation in London, has put together a comprehensive tutorial on Geo-Blogging.
Blog in three dimensions! Geo-blogging is a super-simple way to link geographical locations with time-based blogging. How is this possible? Geo-blogging draws on the power of blojsom's metadata and flavour chains, and taps into Google Earth's network feed capability.
It's spectacularly nerdly. He's put together step-by-step screencasts in addition to the various scripts and utilities you'll need to get your geo-blogging on.
Ogle Earth, a blog about Google Earth, picked up on Adam's work. It also got him a New Statesman New Media Award nomination.
Technorati Tags: geo-blogging google earth blojsom
Getting a ServletConfig reference within Spring?
Let's say I've got the following in web.xml.
...
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/foo-applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
...
And let's say I've got a servlet with the following in its init method.
public void init(ServletConfig servletConfig) throws ServletException {
super.init(servletConfig);
WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(this.getServletContext());
_logger.debug(servletConfig.getInitParameter("foo"));
}
That call to getInitParameter works just fine here. But, what if I need access to the ServletConfig object from beans managed by Spring?
For some reason I'm not making the connection on how to make the connection and get the ServletConfig into the beans.
Scratching my head on what's probably a simple solution. Thanks in advance.
Update: It looks like the following Apache class from Jetspeed 2 does the trick.
import javax.servlet.ServletConfig;
import org.springframework.beans.factory.config.AbstractFactoryBean;
/**
* <p/>
* PreSetInstanceFactoryBean
* </p>
* <p/>
* <p/>
* </p>
*
* @author <a href="mailto:weaver@apache.org">Scott T. Weaver</a>
* @version $Id$
*/
public class ServletConfigFactoryBean extends AbstractFactoryBean {
private static ServletConfig servletConfig;
/**
* <p/>
* createInstance
* </p>
*
* @return
* @throws Exception
* @see org.springframework.beans.factory.config.AbstractFactoryBean#createInstance()
*/
protected final Object createInstance() throws Exception {
verifyState();
return servletConfig;
}
/**
* <p/>
* getObjectType
* </p>
*
* @return
* @see org.springframework.beans.factory.FactoryBean#getObjectType()
*/
public final Class getObjectType() {
return ServletConfig.class;
}
public final static void setServletConfig(ServletConfig servletConfig) {
ServletConfigFactoryBean.servletConfig = servletConfig;
}
protected final void verifyState() throws IllegalStateException {
if (servletConfig == null) {
throw new IllegalStateException("You invoke the ServletConfigFactoryBean.setServletConfig() " +
"method prior to attempting to get the ServletConfig.");
}
}
}
And then add the following in the Servlet.init method.
ServletConfigFactoryBean.setServletConfig(servletConfig);
That about does it.
Technorati Tags: spring servletconfig
Wednesday, 1 March 2006
Conference Call Strip Tease
I'm right now waiting for a conference call to start. The funk-a-delic music playing while we all wait for the conference organizer to arrive has this drop fade in there. The music almost goes silent. The first go-round, I thought, "Excellent! A conference call that's going to start on time."
WRONG!
At least the music is funk-a-licious, but this drop fade is pissing me off!

