>from www.blojsom.com by david
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.