I'm a Java developer (actually, I like to think of myself more of a back-end services developer who also does web stuff). I've been using Drupal for over a year now. Drupal is written in PHP. In my more snobby moments, I like to make fun of PHP, but really, it's the right tool for many jobs out there. It's the right tool for Drupal. But, there are some basic things that really bug me about Drupal (and most CMS's out there, I would presume). Here's a short list:
* Lack of referential integrity in the database (stop using MyISAM and use InnoDB with foreign keys)
* Modules that don't play well together
* Lack of scalability (e.g. horizontal database scaling) - and yes, I know there are plenty of modules out there to help out, but look at the previous point
* It's written in PHP (okay, this is me being snobby, I'll stop)
So I've been thinking lately, it's easy to complain, but how would I do it differently? Here's a stab at it.
(I'm going to call this system 'JCMS' for now, for lack of a better name.)
First, JCMS would be written in Java as a servlet. Modules would be developed as jars (and discovered using the javax.imageio.spi.ServiceRegistry API, or, better yet, OSGi). The output (usually HTML) would be written using any of the many Java templating tools out there e.g. JSP, Velocity, Freemaker, etc..
JCMS would need a kernel to control everything (like Drupal core). Drupal does this using hooks and theming. I think using AOP techniques would work well here. The kernel would publish interfaces and modules could execute code at various points of that interface (e.g. before user create). Modules would also implement interfaces to implement basic functionality (like the user module in Drupal implements the basic functionality of user management). (This means that "core" JCMS code would not live in the kernel, it would be implement in a module that implements various JCMS interfaces.)
Modules would have the ability to do the following:
* Create, update, delete, and read the database (data and schema)
* Create files on the file system
* Execute code using AOP techniques (pointcuts) and published kernel interfaces
* Define other public interfaces (like the ones that the kernel publishes)
* Declare dependencies on other module versions (not just modules, but versions of those modules)
JCMS would be set apart because of the ridged rules that it runs under:
* Every module must have an un-install operation that puts things as they were before the module was installed
* All database schema must use foreign keys to guarantee data integrity
* Side effects must be documented, or, better yet, it should be impossible for side effects to mess up other modules
I'm going to jump to some details right now, because I want to think through them. The first thing I'd like to touch on is how to get the HTML written. I'm going to base this very much off of Drupal. I like the idea of blocks (small rectangles of content that can be placed at various regions (e.g. left sidebar) on the page. A Layout would define the regions available. I'm thinking the standard layout would contain the following regions:
TOP
LEFT
MIDDLE
RIGHT
BOTTOM
This means a Layout would need to implement an interface that would define the available regions.
How would a module get stuff to show up in a browser? This is the big question, I believe. Each module must provide a base view of the content it wants to publish. This base view must be override-able by other modules or themes (this is a lot like Drupal).
A day later...
Okay, it's a day later. I think it would be best to work with the following example. A user module is defined by the kernel and a user profile module uses AOP pointcuts to (and maybe other stuff) to extend the user module.
First, here's the user module interface defined by the JCMS kernel:
import com.jcms.bean.User; public interface UserModule { public int createUser(User user); public void updateUser(User user); public User findUserById(int id); public List<User> findUsersByName(String name); public List<User> findUsersByEmail(String email); public List<User> findUsersByEmailAndEncryptedPassword(String email, String encryptedPassword); public boolean deleteUser(int id); // ... }
User is a POJO with the following fields:
* String name
* String encryptedPassword
* String email
* int id
So a module would implement the above UserModule interface to be used by the kernel as the user module.
Okay, this is pretty simple so far. Now, I think it's going to get complicated. Say we want to create a module that adds a first and last name to the user module. How would we do this?
Editers note: I don't have time to finish or edit this. In the end, this would be best written in Scala and it would be great.
- ian's blog
- Login or register to post comments