If you follow any of the normal Java patterns, you probably know what I'm talking about. You need the file for your business object. You need a service class responsible for returning instances or sets of instances from the DAO layer. You need a SQL file that defines the database table the business objects will be stored in. In our case, we also have queries in resource files, so we need a file for that as well. You need to edit your Spring config files to point to the new service. And so on. Your environment probably has some overlap with mine, and probably requires pieces mine doesn't.
You can simplify a lot of this, of course. You can make a service base class with Java Generics that will give you a lot of the type-safe methods you'd want. IDEs will let you set up templates, but you'll still have to click through a few menu options to get you the files you need. And the more files, the more clicks. And I like running an IDE-neutral team, so I wouldn't want to do something specific to one workflow.
I wanted a better way. Specifically, I wanted what Rails provides. You type a command at the command line, and you get all the files you need for working with the object. (XCode offers similar functionality.)
And I thought, "Well, why not?" My build system is written in Ruby, and Ruby's ERB templating system is built in to the language.
It took about an hour to get the main system up and running. I now type
buildr :biz_object object=com.ea.foo.TestTest
and I get a src/main/java/com/ea/foo directory, a TestTest.java and TestTestService.java file in that same directory, a sql file with the table definition (named test_test
), and an empty query file. I also get a perforce changelist (via p4Ruby) with the description filled in and all the new files added.Here's the heart of the code.
template_to_final
is a hash of template file name locations to the end file destination. The local variables exposed by the call to binding
include the package name, the Java object name, and the SQL-friendly name:
template_to_final.keys.each do |key|
File.open(key) do |file|
b = binding
erb = ERB.new(file.read)
outfile = File.new(template_to_final[key],"w")
puts "Creating #{outfile.path}"
outfile.write(erb.result(b))
outfile.close
end
end
To give you an idea of what the templates look like, here's some code from the java file templates:
package <%=java_pkg%>;
@Entity
@Table(name="<%=java_sql_name%>")
@SequenceGenerator(name="objIdGenerator",sequenceName="object_id_seq",allocationSize=1)
public class <%=java_obj%> {
I don't yet go the full Rails route and specify all the properties on the command line, but this takes care of getting the boring parts of business object development out of the way, enforcing consistent naming schemes, and ensuring that the developer doesn't forget to check in some file. I also don't yet modify my config files, but that won't be too tough to add.