I was playing around with jQuery a bit and created a small app as example app.

It is a simple editor for pixel animation art.

Features implemented yet:

- Create a board with custom number of columns and rows.
- Drawing on board with four colors.
- Change drawing color.
- Push rows or columns around by clicking on board border.
- Add, clone delete and fill a board.
- Switch from one board to other.

Features to come:
- Persistance
- Board expansion
- …

and here is the URL: http://rlights.bomzhi.de/

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 ;)

A good friend of mine is working on encryption technology that let you protect your applications from decompilation.

It is not a typical obfuscation approach that just tries to make your code unreadable. It is encryption on binary level. This means that not only your code is completely encrypted but also the assets that are shipped within your application bundle.

Another interesting aspect of the BIS Guard approach is that the decryption is keyless. This means that it is impossible for tools (decompilers) to break the binary encryption. I also not sure if a skilled hacker may break the protection. My friend sad, he never met one (even for money).

The technology was first implemented in Java and now there is RC1 for Flash/Flex.
Flash Antidecompiler™ is an AIR application which creates a secured swf file from any SWF file you choose.

If you are interested visit the homepage of BIS Guard: http://www.bisguard.com/flash.html

The link to free download of Flash Antidecompiler™ is also provided there.

Nice psychologie references:
http://www.infoq.com/presentations/Why-Dont-We-Learn

http://www.infoq.com/presentations/1000-Year-old-Design-Patterns

http://www.infoq.com/presentations/couchdb-Will-Leinweber

© 2011 Max Blog Suffusion theme by Sayontan Sinha