June 25, 2008

Create new eclipse workspace -- with all your old settings

It's all a matter of taste. Do you like to have just one workspace for all your projects, or do you prefer to have multiple separate workspaces?

Sure, the first way seems to be the official, supported. It should be easy to manage the workspace -- given the tools like working sets (and working set filters), mylyn and the ability to close projects.

But I still don't get it.

I hate when my workspace is overflowing with projects, I want to have as many workspaces as projects.

So I create new workspace and live happily ever after.

But wait -- all my settings are gone. All my carefully crafted custom templates, all my keybindings, my font settings, everything is gone.

It's all text, fortunately


Lucky us. All eclipse settings are saved as a plain text in the workspace directory. So if you want to create new workspace, but preserve your settings, I have two answers for you:

The short answer

All settings are stored in the .metadata/.plugins/org.eclipse.core.runtime/.settings directory. I mean -- all relevant settings. If you look into .metadata/.plugins directory there are many more directories with settings, but they are too project specific. I've walked trough these configuration files one by one, believe me, nothing useful lies hidden there.

So the short answer is: If you want to create a new eclipse workspace and preserve all your settings, simply copy the .metadata/.plugins/org.eclipse.core.runtime/.settings directory into your new workspace directory.

The long answer

Let the code do the talk for me.
I have created a (simple) shell script that automates new workspace creation. The downside is that it requires either *nix or windows with cygwin. It has been tested by me, I and myself so it should work (most of the time).

To use it, save it somewhere, make it executable (chmod +x new-workspace.sh) and run it either in interactive mode
./new-workspace.sh -i
where it will ask you the details, or with paths to your workspaces (the new workspace directory will be created for you, just specify the path)
./new-workspace.sh old-workspace new-workspace.
If the script doesn't work for you, drop me a comment. Feel free to improve it (you may drop me a comment too).

Update: the pastebin page expired (although I'd swear I checked the keep forever option), so I moved the script over to github.


May 27, 2008

Making JavaDoc a bit more usable

First of all, I know people realized JavaDoc is a pain in the ass to use. I am also well aware of all those "let's make better JavaDoc" projects out there. Just for reference, there is

  1. Javadoc online, which is a simple JavaDoc search engine
  2. Docjar, with its tiny, unintuitive flash based JavaDoc browser, which takes ages to load
  3. Windows Help format JavaDoc
  4. Doctree -- directory of (all) JavaDoc sites
  5. Globaldocs, a JavaDoc browser
I am also well aware that each modern IDE can display JavaDoc, if you configure the proper URL first.

Call me old-fogyish, but I tried most of them and always ultimately returned to the (good?) ol' JavaDoc.


Fortunately, I found a way to cure JavaDoc's biggest wound -- it's inability to let me search for a class or a method. The cure is called Greasemonkey and JavaDoc Search Frame or JavaDoc Incremental Search script. How does it work? Install Greasemonkey and install the script. Point your browser on some JavaDoc site and enjoy the search.

Fortunately, it will work on (almost) all JavaDocs in the wild and requires no support from the JavaDoc creator. When the class html frame is loaded, Greasemonkey runs the script and the script automagically adds the search box.

JavaDoc Incremental Search


This is the older of the two scripts. It will display a search box above the class list and will filter out the classes as you type.



JavaDoc Search Frame


Based on the JavaDoc Incremental Search. This script completely removes the packages frame and spans the class frame vertically. It can search package names too and groups the results into packages, classes, interfaces etc.

Now, if only I could also search the methods..


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.