February 28, 2008

Effective Eclipse V: Template mix

The same way I try to avoid the redundancy in my code, the same way I try to avoid the redundancy in my writing. I am lazy and templates do the most writing for me. Eclipse comes bundled with predefined templates, but they are too general and not all of them are too useful. The real power is in custom templates. In this article I would like to show you how to create them and list few useful pieces for inspiration.

What are templates


Exactly as the name suggests, templates are little pieces of code with defined placeholders. An example of simple template is
System.out.println(${text});
Each template has a name, which serves as a shortcut to the template itself. You type the name, press CTRL + SPACE and it will be expanded.

Our first template would expand to

I will not explain here what it all means, I already did this in my previous post on templates. What is important now, is that the ${text} placeholder (variable) was highlighted and can be edited immediately.

The true power of templates can be fully seen in more complex templates. The first power point lies in the fact, that you can have more than one variable with same name. Our second template will have more variables:
int ${increment} = ${value};
y = ${increment} + ${increment};
and will expand to
When you start typing now, all occurrences of increment variable will be changed. You can then switch to the next variable by pressing TAB key. In the end, you can have

in just three key presses - one for i, one for TAB and one for 2.

To make it even better, the template system provides predefined variables, which will be expanded depending on their context. I will not list them, you can find them under the Insert variable button.

Notice, that you are not getting only a list, you are also getting a description and an usage example.

To make it clear, I will illustrate one builtin variable - ${enclosing_type}. When this one is expanded you will get a name of the class (or interface, enum) in which your template was expanded.

"But how can I use it?", I hear you asking. I have prepared few templates just for inspiration, I believe that after reading this you will find thousands others and I believe that you will create them and share them with us.

Custom templates


Open Window -> Preferences and type Templates into the search box.


You will get a list of all editors, and their respective template settings. This is because templates are closely bound to editors - you will get different builtin variables in different editors. Also note, that your list may vary from my list, it all depends on installed plugins.

Now you must decide what type of template you would like to create. If it is a Java template, which will be applicable in context of classes, interfaces and enums, then choose Java -> Editor -> Templates. If you create a Java template you won't be able to use it in XML editor, that's quite expected.

So click on the New button, to get a dialog. Here it is, in all its glory:

Name is the name of the template. Choose it well, because it will serve as a shortcut to your template. After you type the name of the template (or at least a few characters from its name) and hit CTRL+SPACE it will be expanded.

Description is what you will see next to the template name when the template name is ambiguous.

Pattern is the template body. And the Context? This varies in every editor. If you look in the combobox in Java templates, you will see Java and Javadoc. It is simple a context within the respective editor in which the template would be applicable.

Check Automatically insert if you want the template to expand automatically on ctrl-space when there is no other matching template available. It is usually good idea to leave the checkbox checked, otherwise you would get a template proposal "popup". See what happens when I uncheck it on sysout template.

If I would have checked it, it would automatically expand, as there is no other template matching sysout* pattern.

My list


So here is the list I promised. I have categorized it.

Java (Java->Editor->Templates)
  • logger - create new Logger
    private static final Logger logger = Logger.getLogger(${enclosing_type}.class.getName());
    Notice the usage of ${enclosing_type} variable. This way you can create a logger in few hits. After the template expands, you will probably get red lines, indicating that Logger clas could not be found. Just hit CTRL + SHIFT + O to invoke the organize imports function. You are using shortcuts, aren't you?

  • loglevel - log with specified level
    if(${logger:var(java.util.logging.Logger)}.isLoggable(Level.${LEVEL})) {
    ${logger:var(java.util.logging.Logger)}.${level}(${});
    }
    ${cursor}
    Let me explain the details. ${logger:var(java.util.logging.Logger)} uses a builtin "var" variable. It starts with logger, the default name, in case the var variable finds no match. It is then followed by var(java.util.logging.Logger), what will evaluate to the name of the variable (member or local) of the specified type (in our case of the Logger type). Further, the ${cursor} variable marks the place where the cursor will jump after you press enter. So the result after expanding could be

    You might wonder what is the purpose of the if. It is there only for performance gain. If specified level is not allowed the logging method will never be called and we can spare JVM some string manipulation to build the message.

  • readfile - read text from file

    Never can remember how to open that pesky file and read from it? Nor can I, so I have a template for it.

    BufferedReader in;
    try {
    in = new BufferedReader(new FileReader(${file_name}));
    String str;
    while ((str = in.readLine()) != null) {
    ${process}
    }
    } catch (IOException e) {
    ${handle}
    } finally {
    in.close();
    }
    ${cursor}
Maven (Web and XML -> XML Files -> Templates)
  • dependency - maven dependency
    <dependency>
    <groupId>${groupId}</groupId>
    <artifactId>${artifactId}</artifactId>
    <version>${version}</version>
    </dependency>
    ${cursor}
  • parent - maven parent project definition
    <parent>
    <artifactId>${artifactId}</artifactId>
    <groupId>${groupId}</groupId>
    <version>${version}</version>
    <relativePath>{$path}/pom.xml</relativePath>
    </parent>
    ${cursor}
web.xml (Web and XML -> XML Files -> Templates)
  • servlet - new servlet definition
    <servlet>
    <servlet-name>${servlet_name}</servlet-name>
    <servlet-class>${servlet_class}</servlet-class>
    <load-on-startup>${0}</load-on-startup>
    </servlet>

    <servlet-mapping>
    <servlet-name>${servlet_name}</servlet-name>
    <url-pattern>*.html</url-pattern>
    </servlet-mapping>
    ${cursor}
JSP pages (Web and XML -> JSP Files -> Templates)
  • spring-text - spring text field with label and error
    <label for="${path}" class="${label_class}"><fmt:message key="${path}"/></label>
    <spring:input path="${path}" cssClass="${input_class}"/>
    <spring:errors path="${path}"/> <br/>
    ${cursor}
  • spring-checkbox
    <label for="${path}" class="${label_class}"><fmt:message key="${path}"/></label>
    <spring:checkbox path="${path}" cssClass="${input_class}"/> <br/>
    ${cursor}
  • spring-select
    <label for="${path}" class="${label_class}"><fmt:message key="${path}"/></label>
    <spring:select path="${path}" cssClass="${input_class}">
    <spring:options items="${items}" itemLabel="${label}" itemValue="${value}"/>
    </spring:select>
    <spring:errors path="${path}"/> <br/>
    ${cursor}
  • spring-generic
    <label for="${path}" class="${label_class}"><fmt:message key="${path}"/></label>
    <spring:${type} path="${path}" cssClass="${input_class}"/>
    <spring:errors path="${path}"/> <br/>
    ${cursor}
    These are my favorites. They regularly save me a huge amount of time. Creating spring forms has never been easier for me.
In some editor types you can set the template to 'new', for example, in XML editor it is new XML. This is really useful, as you can prepare the skeleton of a new file. For example, this is what I use to create new Spring servlet configuration for freemarker application.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">

<context:component-scan base-package="" />

<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="/"/>
</bean>

<bean id="viewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView"/>
<property name="exposeSpringMacroHelpers"><value>true</value></property>
<property name="cache" value="true"/>
<property name="prefix" value="/pages/"/>
<property name="suffix" value=".ftl"/>
</bean>

<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename"><value>messages</value></property>
</bean>
</beans>
Now, I can create new XML file from template and it will be ready to use. Before I knew about templates, I used to copy this from an older project, or search for it in Spring documentation. Now I don't have to..

If you can overcome the initial laziness and create your own templates from the pieces of code you really use, than this investment will shortly return in form of less typing. If you have some interesting templates, please, share them with us.

You can download the templates mentioned in this post and import them using the Import button in the editor template settings.


February 15, 2008

And so I wasted my time: OC4J and EJB Syntax error in source

oracle.oc4j.admin.internal.DeployerException:
Error initializing ejb-module;
Exception Error in application ejb-module:
Error loading package at file:/opt/oracle/ejb.jar,
Error compiling /opt/oracle/ejb.jar:
Syntax error in source
This was all I got from OC4J as a response to my attempt to deploy application. Compilation went fine, so it had to be some error in generated wrapper code.

Google search yielded only three results, including one from oracle forums with unanswered question. So I begun removing last changes, line by line, to discover the source of the error. In the end, it turned to be a missing RemoteException in remote interface. Doing it remotely, without IDE and XDoclet I forgot to add this one.

So I am writing it now, hoping that your search yielded four results and that one of them - mine, just saved you an hour of precious time.


February 9, 2008

Add jQuery autocompletion to your Eclipse

It's easy with jQueryWTP. It is not an Eclipse plugin, it is a nice tool, which modifies some WTP plugin autocompletion definitions to make it support jQuery.

Installation is easy:

  • run the tool
  • find the plugin jar and patch it
The complete instructions with a video guide are available on the jqueryWTP homepage.

It works nicely, there is one gotcha however, which is not mentioned in the official instructions. You must choose the correct jar, the one, which is being used by WTP. It is possible to have multiple version of the same plugin jar - it is even anticipated if you update your plugins. So choose the correct version - it should be the most recent, with the highest version number. If you are unsure, try all of them, but don't forget to do a backup of the original plugin jar.

It can spare you few key strokes and eventually few trips to visualjquery.


February 3, 2008

Effective Eclipse IV: Fix it, quickly

You are in trouble. Red lines are everywhere. There is no easy way out, so you just either start googling what went wrong, or start a copy&pasting session. If it is so smart, it can tell me that I have an error in my code, why cannot it just fix it?

Well, let me introduce you a powerful ally: Quick Fix.

A small example

On the image above is a well-known situation. The method is throwing a checked exception, so the calling method must either enclose it in a try-catch block, or rethrow it. A typical solution to this problem is to manually write the try-catch block or throws clause. But there is a better way, the way of quick fix.

It can be invoked in two ways

  • clicking on the bulb, left of the line number
  • hitting CTRL + 1 - the preffered way
The result will be..

..that quick fix will propose you both fixes. In the yellow box is a preview, it looks messy, but the code will be properly formatted. If you don't like the generated code, you can change it under Window->Preferences->Java->Code Style->Code Templates. I don't like the default e.printStackTrace(), so I changed the Catch block body template to
logger.severe("Exception caught: " + ${exception_var});
Whenever a red line appears, quick fix can eliminate it. It is applicable not only to the situation above, it can fix:
  • Typos
  • Imports
  • Casting

    Starting with the simple casts...


    .. to even more intricate

  • and any other kind of problem I am unable to think up at the moment.
I found quick fix helpful even in the desperate situations like this one:


Project needs to migrate WTP metadata? Ok then, have your fun.


When there is nothing to fix, quick fix turns itself to a quick refactoring. Let's see what will it propose on our list.


See, it provides all sorts of context sensitive advices. Refactoring, renaming, annotations, everything is there, hidden under one shortcut key. A powerful shortcut key, definitely.


February 2, 2008

Improve your jQuery-fu, write plugins


jQuery is a simple, yet powerful JavaScript library, which really changed my point of view of JavaScript-ing. A new wave JavaScript they call it and it receives this title righteously. The code you create is a pure elegance.

You start with 10 lines of jQuery that would have been 20 lines of tedious DOM Javascript. By the time you are done it's down to two or three lines and it couldn't get any shorter unless it read your mind.

But of course it can get shorter. It can get shorter by refactoring your script into jQuery plugin.

When it comes to writing, plugins people (including me) usually back off in horror. I heard about jQuery plugins long ago, but never dared to write one. Somewhere in my mind crept a thought, that

  • It must be hard and thus left only to true masters
  • It must require a deep knowledge of jQuery
  • what could I possibly gain?
(I come from a Java world if you wonder).

None of the above is true. Writing jQuery plugin is as easy as writing jQuery script. It does not require any special knowledge. All that is needed, is to extend a jQuery object. Something like

$.fn.myPlugin = function() {
$this = $(this);
// plugin code
return $this;
}
Remember? This is JavaScript, not Java and the code above is the only thing needed to create a plugin. Inside the function, $this is reference to the jQuery object the plugin was called at.
$("table").myPlugin().addClass("surprise");
Now, $this is table and you can do all sorts of things with it. Because the plugin returns $this, jQuery operations can be chained.

By extending jQuery object, you do not only inherit its fields and methods, you inherit its elegance.

Now, back to my question, what could you possibly gain by creating a plugin? Mainly

  • Higher degree of reusability JavaScript scripts are generally reusable, but when you create a plugin you can move it up one level. It is similar to refactoring the common code into reusable classes.
  • Configurability This is related to the first point. The usual scenario without plugin is to have a snippet of code, then copy and paste it over to html and change the code to customize its behavior. It is much easier with plugin. You can write your plugin to accept some settings. This is how it could look:
    $(table).myPlugin({url: 'edit.htm', param: 'id'});
  • Elegance
  • The code above surely looks better than a whole script, doesn't it?


Now it's time to show some real life example. I have been using a script, to make each row of a table clickable.

$("table tr").click(function() {
location.href = 'edit.html?id=' + $("td:first a", $(this)).html();
});
Whenever I wanted to make the rows clickable I copied the snippet and changed the url or parameter name. But with the plugin..
$.fn.clickable = function(settings) {
defaults = {
href: 'edit.htm',
paramName: 'id'
}

settings = $.extend(defaults, settings); //overwrite the defaults with provided setings

$this = $(this);

$("tr", $this).click(function() {
location.href = settings.href + '?' + settings.paramName + '=' + $("td:first", $(this)).html();
});

return $this;
}
..I can use it:
$("table").clickable();
or when I am not confident with default settings, I can change them
$("table").clickable({href: 'change.htm'});

If you want to know more about plugins, read the official plugin authoring guide or Mike Alsup's excellent plugin development pattern.
I hope I inspired you.