Apr 9 2007

Software Development Environment

I had to update our project wiki and detail our current software development environment. I found that we are lagging a bit behind the latest Java technologies and tools, but from a business perspective I think it is hard to up sell existing customers just so that developers can use the latest Java language features in their code. Large software clients usually invest a lot of time and money into the applications they use for their business processes and can’t upgrade based on the schedule of software tool vendors.

Thinking about the current state of tech tools, I wanted to jot down the tools of the trade that I use on a day to day basis.

Java Development/Work
Java 1.4.2
Maven 1.0
Eclipse 3.1.2 with Perforce plugin
TeamTrack

Java Development/Home
Java 1.5
Maven 2.0
Eclipse 3.2.1 with Subclipse, Groovy, JavaCC, and Aptana plugins
Subversion 1.3

Ruby on Rails
Ruby 1.8.4
Rails 1.2.2
RadRails 0.7.2

Database
SQL Server 2005 Express
Oracle 10g Express
Mysql 4.1.15

Firefox Plugins
Firebug 1.04
Web Developer 1.1.3
Selenium IDE 0.8.7

Miscellaneous Editors
SciTE 1.70
Komodo Edit 4.0
TextWrangler 2.2

Collaboration
Skype
Google Apps

Technorati Tags: , , , , , , , , , , , , , , ,


Apr 8 2007

Desc SQL Tables

When working with Oracle, SQL Server, or MySQL you might need to remind yourself the names of the columns for a table, I know I do. To describe the details of a table you can execute the following from a Oracle or MySQL client.

[source:sql]
desc <table_name>
[/source]

And just like everything else that Microsoft does, SQL Server does not follow the conventions or standards of other vendors and instead uses a different keyword to describe a given table. In SQL Server you display detailed information about a table use the sp_help command.

[source:sql]
sp_help <table_name>
[/source]

If you are interested in listing all the available tables in a database, for either Oracle, SQL Server, or MySQL, then you might want to take a look at the Show SQL Tables post.

Technorati Tags: , , , ,


Apr 4 2007

Class HighLite Calendar

I think that date manipulation in Java should be easier than it is. For example, there are two date classes in the JDK Standard Edition, one for sql and the util version. Another issue that I have with dates in Java is that the util Date class has about half of it’s methods deprecated. The only useful methods in the Date class which are not deprecated are the get/setTime method. The before and after methods are just convenience methods. On top of multiple date classes and deprecated methods, dates should be considered harmful without a properly localized calendar. Oh, yeah, JDK comes with two flavors of calendars.

It can safely be said that the util Date class is just a wrapper for a long and because of this you can use the Java util Calendar class instead. The Calendar class is an abstract class so you create a calendar instance as follows.

[source:java]
Calendar cal = Calendar.getInstance();
Date now = cal.getTime();
[/source]

As you can gather from the above code, the calendar is initialized with the current time for your time zone. The static getInstance method is overloaded to accept a locale, a time zone, or both. The calendar is plain simple and I most often use it to get/set the day of a calendar. Here is the code that does just that, I’ll set the day to the the beginning of the month.

[source:java]
cal.set(Calendar.DAY_OF_MONTH, 1);
[/source]

The first parameter of the set method in an integer value that represents the field you want to update. You can can change the year by using Calendar.YEAR or the month by using Calendar.MONTH. Once you have the correct date in the calendar instance, you can query for the hour by using the get method as demonstrated in the following snippet of code.

[source:java]
int hour = cal.get(Calendar.HOUR);
[/source]

With a calendar instance you can easily figure out how many days are in a given month.

[source:java]
int days_in_month = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
[/source]

You can also add five days, or subtract five minutes, to a calendar object with code similar to the following.

[source:java]
cal.add(Calendar.DAY_OF_YEAR, 5);
cal.add(Calendar.MINUTE, -5);
[/source]

This is part of the Class HighLite Series, which intends to highlight some interesting code and classes available from the JDK.

Technorati Tags: , , , , , ,


Apr 3 2007

Simply Helpful Rails Plugin

Before I begin let me just state that the Simply Helpful plugin requires Rails 1.2.2. If you already are using Rails 1.2.2 you can continue by downloading the plugin by executing the following command from the root directory of your Rails application using the terminal or command prompt.

script/plugin install simply_helpful

This plugin adds a few additional methods into the action view, action controller, and form helper that you will find more than helpful, if not essential.

In a very Rails like opinionated software fashion, Simply Helpful introduces the view helper method dom_id which will produce the right dom id for a given model instance. Since code is worth a thousands words, and since I can’t type a thousand words in one sitting let me get started with some sample code which can be placed in a rhtml view source file.

[source:ruby]
<%= dom_id @post %>
[/source]

If the @post variable was created through a model finder method and it represents a post identified with the primary key of 11, then the above line will print the following string, post_11. Notice that the recommended dom id is the model class name plus the record id. If you are using some cool Scriptaculous effects on the post title and the post body, you will need to uniquely identify each element. You can prefix an additional identifier to the dom id so as to uniquely identify different dom elements for the same post, say the title and the body. In this way, each element can have different effects. Here is an example that will produce the a id which can be used for the given title for the post.

[source:ruby]
<%= dom_id @post, ‘title’ %>
[/source]

The above snippet will produce a string that that reads title_post_11. Simply Helpful also provides a dom_class method that will return what it thinks should be the CSS class name for an element for a given model instance. As you can imagine, the dom_class recommends that the parameter’s class name be used as the dom name. Putting together a more complete example, you might have code like the following.

[source:ruby]
<H1 id=”<%= dom_id @post, ‘title’ %>” class=”<%= dom_class @post %>”>
<%= @post.title %>
</H1>
[/source]

The dom_id and dom_class methods are pretty helpful but as a co-worker stated, “I would not download a plugin just to concatenate the model class name and id together.” Luckily for my co-worker, Simply Helpful provides a lot more than that, such as form blocks. Here is an example of how I have been doing forms in Rails.

[source:ruby]
<%= start_form_tag :action => :update, :id => @post %>
<%= text_field ‘post’, ‘title’, :value => @post.title %>
<%= end_form_tag %>
[/source]

The new form_for method will create a put or post method for a form depending if the model instance is persisted in the database or if it represents a new model. In addition to automatically creating the correct action URL for the form, you have access to a form block variable which can be used to create form fields. Here is an example of a form block.

[source:ruby]
<% form_for @post do |f| %>
<%= f.text_field :title %>
<% end %>
[/source]

Compare Simply Helpful’s way of creating forms to the old school Rails ways. It might not be obvious at first, but f.text_field statement will create a text field for the title attribute of the post. If the @post model instance represents and existing record then the current title will be the default value in the text field.

As the name states, Simply Helpful provides a helpful set of methods. Simply Helpful is also required by other Rails plugins such as ResourceFeeder.

Technorati Tags: , , , , , , , , , ,


Apr 1 2007

SV RoR March Meetup

The February meetup of the Silicon Valley Ruby on Rails (SV RoR) group had speakers present on their experience with bringing a Rails application from concept to production. For the March meetup, Brian Moore from feder8 presented on his experience with bringing his social site to production.

Since most Railers are adherents of the Don’t Repeat Yourself (DRY) principle, Brian discussed how he found it convenient to share methods amongst different helpers. Brian reminded the audience of the Ruby mixin capabilities and suggested that you mixin helpers via the Ruby include method. I have written a Ruby mixins tutorial which describes this in detail.

Brian also warned that Rails logs everything, this includes login names, passwords, email addresses, credit card numbers, and any other value submitted via a form. Fortunately you can tell Rails to filter out certain form elements from being logged. For example, in your ApplicationController (application.rb) you can add the following code if you want the value of any text field named ‘password’ to not be logged.

[source:ruby]
filter_parameter_logging :password
[/source]

Brian also advised not to expose your default database id in the application’s URLs. By default database ids are mostly sequential and therefore can be used by competitors to decipher how many users you have, how many users sign up per day, how much User Generator Content is submitted to the site on a daily basis. In general Brian suggested that it is a bad idea to leak ids in your URLs.

As a general rule of thumb, Brian recommended that a given page should never take longer than half a second to load and render. To achieve this half a second rendering you might have to do a substantial amount of caching. Also to try to achieve this half second rendering time, Brian recommends to never ever calculate a value twice. For example, if your site contains images and you concatenate the image filename with the server URL. This type of calculation can be done once and the resulting value can be stored in the database so as to achieve a better overall performance.

In the question and answer discussion, he was asked how long it took him to go from idea to something real. Brian said six weeks and added, “You guys all know that it is pretty easy to ship something barely functional in rails.”

Technorati Tags: , , , , , , , , ,


Mar 26 2007

Builder Pattern Made Groovy

In Java, you might have come across with a class that has a ton of constructors, each of the constructor with a different number and arrangement of parameters. This usually happens because some of the parameters are optional or when there are different flavors of accepted parameter types. One way to clean up this type of situation is to use the Builder design pattern advocated by the Gang of Four in the seminal book Design Patterns: Elements of Reusable Object-Oriented Software. The builder pattern is a creational pattern which simplifies the creation of complex objects.

Groovy elevates the promotion of the builder pattern with the core Groovy Development Kit (GDK) making builders as commonplace and habitual for the average developer as Iterators. Groovy provides the NodeBuilder, MarkupBuilder, AntBuilder and the SwingBuilder to facilitate the constructor of nested object hierarchies, XML/HTML, ant tasks, and Swing components. But perhaps more importantly, the GDK provides the abstract class BuilderSupport which can be extended to create custom builders.

The way that MarkupBuilder works, for example, is that once you create an instance of the builder you invoke any method passing along named parameters or a closure. You can invoke any method name that is valid to the language. Even though the builder does not implement a given method, the method invocation will be routed or relayed to a createNode method that will create a tag element out of it. The named parameters will become tag attributes. Any method calls declared in the closure will become nested tag elements. Here is a typical example of the MarkupBuilder.

[source:groovy]
StringWriter writer = new java.io.StringWriter()
def build = new groovy.xml.MarkupBuilder(writer)
build.html {
head {
title ‘Juixe TechKnow’
}
body(bgcolor: ‘#ffffff’) {
h1 ‘Hello, World’
}
}
print writer;
[/source]

From the above example, you should note that the MarkupBuilder does not define or implement any HTML, head, title, body, or h1 method. Think of these methods as dynamic. When the HTML method is invoked, it will be delegated to a createNode which in this case will append an a tag named after the method into the string writer.

To drive this point home, lets define a builder of our own. The builder that I plan to write for this exercise will build a hierarchy of hashes, that is a hash of nested hashes. To create our HashBuilder we will extend the BuilderSupport abstract class that is part of the GDK. Our HashBuilder needs to implement one setParent and four createNode methods. What follows is the initial implementation of the HashBuilder class.

[source:groovy]
import groovy.util.BuilderSupport

class HashBuilder extends BuilderSupport {
protected void setParent(Object parent, Object child) {
if(parent)
parent[parent[‘name’]] = child
}

protected Object createNode(Object name) {
createNode name, null, null
}

protected Object createNode(Object name, Object value) {
createNode name, null, value
}

protected Object createNode(Object name, Map attrs) {
createNode name, attrs, null
}

protected Object createNode(Object name, Map attrs, Object value) {
// Create a hash/map
def node = [name:name]
if(attrs)
node[name] = attrs // Add map to hash
return node
}
}
[/source]

Once you have defined the above HashBuilder you can create a corporate hierarchy out of hash with code similar to the following trivial example.

[source:groovy]
HashBuilder apple = new HashBuilder();
print apple.departments {
management {
employee(firstname:’Steve’, lastname:’Jobs’, title:”CEO”)
}
}
[/source]

As you can gather from the examples presented here, Groovy builders leverage power of meta-programming, named parameters, closures, and optional parenthesis in an concise and elegant fashion.

Technorati Tags: , , , , , , ,