I am currently working on a project that switched the UI framework from JSF2 to Wicket.
In my opinion it is a very productive decision, but I don’t want to discuss pros and cons of Web frameworks.
What I want to discuss here is the Eclipse Wicket PlugIn “qwickie“.

It is a nice plugin and it has some cool features like hyperlinking from Java to HTML wicket components and vice versa. Autocompletion and Error Highlighting.

Than I looked under the hood and saw some stuff that could be done better in my opinion. I contacted the project owner and he asked me to write down some ideas.

So hear I am :)

First of all the main concept that drives the plugin is the evaluation of wicket id.
This is made text based at this moment and in my opinion it should be structure based.

So here is an example of wicket id evaluation for wicket id in java source code.

At first we need a data structure that represents wicket id found in java code.

 
package qwickie.model;
 
import java.lang.ref.WeakReference;
 
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jface.text.IRegion;
 
public class JavaWicketId {
	private String id;
	private IRegion idRegion;
	private WeakReference<IType> complonentType = new WeakReference<IType>(null);
	private WeakReference<IVariableBinding> representingVariable = new WeakReference<IVariableBinding>(null);
 
	public JavaWicketId(String id, IRegion idRegion) {
		this.id = id;
		this.idRegion = idRegion;
	}
 
	public String getId() {
		return id;
	}
 
	public IRegion getIdRegion() {
		return idRegion;
	}
 
	public IType getComplonentType() {
		return complonentType.get();
	}
 
	public void setComplonentType(IType complonentType) {
		this.complonentType = new WeakReference<IType>(complonentType);
	}
 
	public void setRepresentingVariable(IVariableBinding representingVariable) {
		this.representingVariable = new WeakReference<IVariableBinding>(representingVariable);
	}
 
	public IVariableBinding getRepresentingVariable() {
		return representingVariable.get();
	}
 
	@Override
	public String toString() {
		return "WicketId [id=" + id + ", componentType=" + getComplonentType().getFullyQualifiedName() + ", representingVariable=" + getRepresentingVariable() + ", idRegion=" + idRegion + "]";
	}
}

The Class is not only hosting the id itself but also the region where it was found in the document, a type that is representing the component like for example Label and the representing variable.

Why should we care about component type and representing variable?

Well with component type we could evaluate if the component type matching the HTML tag counterpart. For example if you create a new Label with wicket id of an form tag that should be marked as error.

Representing variable is needed to evaluate the structure of tags. Lets imagine we collected all components that are created in java code. Than we can trace the add method invocation to reproduce the structure of the components – how they are nested. Than we can compare the structure to HTML counterpart and show errors if there are some.

The evaluation has to be fuzzy but it is better that runtime errors I guess :) .

Here is a simple visitor implementation for JavaWicketIdCollector:

package qwickie.util;
 
import java.util.ArrayList;
import java.util.List;
 
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.Assignment;
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.IBinding;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.StringLiteral;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jface.text.Region;
 
import qwickie.model.JavaWicketId;
 
public class JavaWicketIdCollector extends ASTVisitor {
 
	private List<JavaWicketId> wicketIds = new ArrayList<JavaWicketId>();
 
	@Override
	public boolean visit(ClassInstanceCreation node) {
		IMethodBinding methodBinding = node.resolveConstructorBinding();
		IMember javaElement = (IMember) methodBinding.getJavaElement();
		try {
			if (!TypeHelper.isWicketComponent(javaElement)) {
				return super.visit(node);
			}
			JavaWicketId wicketId = getWicketId(node.arguments());
			// javaElement.getDe
			if (wicketId != null) {
				wicketIds.add(wicketId);
			}
			wicketId.setComplonentType(javaElement.getDeclaringType());
			wicketId.setRepresentingVariable(computeVariableBinding(node));
		} catch (JavaModelException e) {
			e.printStackTrace();
		}
		return super.visit(node);
	}
 
	private JavaWicketId getWicketId(List<?> arguments) {
		if (arguments.size() < 1 || !(arguments.get(0) instanceof ASTNode)) {
			return null;
		}
		ASTNode argument = (ASTNode) arguments.get(0);
 
		if (argument instanceof StringLiteral) {
			StringLiteral stringLiteral = (StringLiteral) argument;
			// Region is computed only for text. Exclude ".
			Region idRegion = new Region(argument.getStartPosition() + 1, argument.getLength() - 2);
			return new JavaWicketId(stringLiteral.getLiteralValue(), idRegion);
		} else if (argument instanceof SimpleName) {
			SimpleName simpleName = (SimpleName) argument;
			IBinding resolveBinding = simpleName.resolveBinding();
			if (resolveBinding instanceof IVariableBinding) {
				Object constantValue = ((IVariableBinding) resolveBinding).getConstantValue();
				if (constantValue instanceof String) {
					Region idRegion = new Region(argument.getStartPosition(), argument.getLength());
					return new JavaWicketId((String) constantValue, idRegion);
				}
			}
		}
		return null;
	}
 
	private IVariableBinding computeVariableBinding(ClassInstanceCreation node) {
		IVariableBinding variableBinding = null;
		VariableDeclarationFragment variableDecl = ASTNodeHelper.getParent(node, VariableDeclarationFragment.class);
		if (variableDecl != null) {
			variableBinding = variableDecl.resolveBinding();
		}
		Assignment assignment;
		assignment = ASTNodeHelper.getParent(node, Assignment.class);
		if(assignment!=null){
			Expression leftHandSide = assignment.getLeftHandSide();
			if (leftHandSide instanceof SimpleName) {
				IBinding resolveBinding = ((SimpleName)leftHandSide).resolveBinding();
				if(resolveBinding instanceof IVariableBinding){
					variableBinding = (IVariableBinding)resolveBinding;
				}
			}
		}
		return variableBinding;
	}
 
	public List<JavaWicketId> getWicketIds() {
		return wicketIds;
	}
}

The ASTNodeHelpre is an old friend from my post category “to Test or not to Test
Here is the code anyway:

package qwickie.util;
 
import org.eclipse.jdt.core.dom.ASTNode;
 
public class ASTNodeHelper {
	@SuppressWarnings("unchecked")
	public static <T extends ASTNode> T getParent(ASTNode node, Class<T> parentClass) {
		ASTNode searchNode = node;
		while(searchNode.getParent() != null && !parentClass.isInstance(searchNode.getParent())){
			searchNode = searchNode.getParent();
		}
		return (T) searchNode.getParent();
	}
}

If you want to test the collector you will need something like this:

	IFile javaFile = (IFile) resource;
	final ICompilationUnit cu = JavaCore.createCompilationUnitFrom(javaFile);
	final ASTParser parser = ASTParser.newParser(AST.JLS3);
	parser.setResolveBindings(true);
	parser.setSource(cu);
 
	ASTNode ast = parser.createAST(null);
	JavaWicketIdCollector collector = new JavaWicketIdCollector();
	ast.accept(collector);
	List<JavaWicketId> wicketIds = collector.getWicketIds();

Anyway I will ping qwickie project owner about this things and maybe I will become a comitter for the project.

PS: tip for everybody who want to do static code analysis in Eclipse. JDT AST View is your friend ;)

Lately I was asked to write a few words about Pflection. So I decided two write a new Blog Post.

What is Pflection?
Pflection is FDT View used for code review.

The view is separated in three columns.

First column contains information collected by FDT on elements you selected. Pflection reacts on selections made in Project or Outline View. Multi selection is also supported.

As you can see there are two kinds of collected data.
1. A list of a certain elements with a quantity
2. A list of OO and functional characteristics with absolute quantity and average distribution.

On metric selection in first column, second column will show the compound items.

In case of certain elements list user gets a quick view on names of elements and can open the element in source editor by double click. This way user may find poorly named elements.

When a characteristic item is selected, user will see the distribution list in second column and the elements compound in the distribution if one is selected in second column.

So how does Pflection help me to improve my design?

As already mentioned, you can improve the naming of your elements by browsing through element lists.
You can lookup the distribution of interface implementations and class inheritance depth.
I suggest deep class inheritance is not always a good solution and an interface should be implemented more than one time.
You also can lookup coupling of elements through Incoming/Outgoing Reference ratio.

Complexity of functions may be monitored by:
- number of method lines of code,
- number of parameters you may use to call this function
- number of blocks in a function
- number of conditions / branches introduced in function btw. this number correlates with number of test you need to get a 100% code coverage
- number of flow terminations

Thank you for your time and have fun with Pflection.

PS: I used funk-as3 for demonstration / screenshot creation.

I don’t think I would write something new to this topic because this year I kind of changed my sphere of action.

And to summarize the category I would like to post a link to the talk I gave on Adobe User Group Nederland.

It’s kind of embarrassing for me, because this video doesn’t put my presentation skills at the glance, but the content is quit interesting in my opinion. It is quit long though, it was a strange slot on this conference I got two hours. Too short for a tutorial and pretty long for a talk. But enough with explanations, here it is:

http://www.adobeusergroup.nl/site/list_messages/391

http://www.infoq.com/news/2010/03/egit-released

code_swarm: A Design Study in Organic Software Visualization from Michael Ogawa on Vimeo.

Found it in this Talk:
http://www.infoq.com/presentations/ford-large-rails;jsessionid=3845F7FE536C1E9F18F22A67176001F3

When I worked in FDT Project I was always thinking about a contributor program, so when I leaved Powerflasher I arranged to start an OpenSource project for FDT. http://code.google.com/p/fdt-os/

And here is the first born out of this arrangement.

The Idea:
I was always interested in Software Metrics. I think it is a very strong instrument to improve your design, and detect code smell. Pflection gives you the possibility to reflect on your code (project) directly in your IDE. It also provides you with possibility to navigate to this code smells and think about refactoring :) .

So at the moment it is still work in progress I implemented only a few metrics, but it is more to go. And maybe I will start a parallel Project for JDT.

PS: If you want to try it out, navigate to this URL download the jar file and place it in your FDT/Eclipse “dropins/plugins” folder.

An IDE is not a Text Editor. It is a complex piece of software that helps you develop your projects faster.
In my opinion, static analysis is the heart of this software.
When you look at it closer most of the modern compiler also make static analysis on the code before they turn it to byte code.
This gives you a possibility to connect to the compiler and just visualize found errors in the editor.
But now you are facing some requirements for compiler. The compiler has to provide an interface for error collection, it has to be able to compile only the file you are working on, and it has to be very fast if you want to show errors live when the user is typing.
Eclipse JDT for example provides its own modified compiler for this purpose.

But still we covered only one problem, the error highlighting.

What’s about auto completion? For auto completion you also have to do static analysis to identify the scope the auto completion was triggered in and the possible proposals in this context. The static analysis for auto completion is much complex than by error highlighting. The user started to type something and now when his code is not complete he wants to auto complete it. The code is not complete so it won’t compile. I know only one compiler that is able to give auto completion suggestions (haXe).

A good IDE provide you also with ability to navigate/search/format and visualize your code.

Code generation is the next big feature that every IDE have to provide and it also have to be based on static analysis, because code generation should not break code. The generated code should be close to programmers intention. The main goal is you don’t have to modify generated code it should be formatted as you expected it should be placed where you expect it, you are ready to go to extend the generated code.

Refactoring is the key feature of every enhanced IDE and it’s also based on the static analysis because it is the same principle as by code generation: don’t break code, refactor it. Refactoring is also much complicated than just code generation. Because in refactoring you delete existing code and generate a new one. So the danger of breaking code is bigger.

Let’s discuss the second part of a good IDE, simplicity and management.
Creation of projects should be simple. People should be able to make shortcut’s for work flows they do frequently.
Frameworks and other technologies that are used by developers should be supported and seamless integrated in the IDE.
It should be easy to launch the developed application so you can have a look at result of your work at any stage.

© 2011 Max Blog Suffusion theme by Sayontan Sinha