The Artima Developer Community
Sponsored Link

Java Buzz Forum
Enums in Preon

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Wilfred Springer

Posts: 176
Nickname: springerw
Registered: Sep, 2006

Wilfred Springer is a Software Architect at Xebia
Enums in Preon Posted: Aug 12, 2009 8:48 AM
Reply to this message Reply

This post originated from an RSS feed registered with Java Buzz by Wilfred Springer.
Original Post: Enums in Preon
Feed Title: Distributed Reflections of the Third Kind
Feed URL: http://blog.flotsam.nl/feeds/posts/default/-/Java
Feed Description: Anything coming to my mind having to do with Java
Latest Java Buzz Posts
Latest Java Buzz Posts by Wilfred Springer
Latest Posts From Distributed Reflections of the Third Kind

Advertisement
You might have noticed in my previous entry that I introduced a new annotation to map enum values to their encoded representation. I already thought about that a couple of times, but never found time to do it. Now I introduced it, I notice that there is actually something missing here. Question is: will it be possible to introduce it without overhauling the entire framework? I think it is possible.

The Problem

So what is actually missing here? Well, with the latest addition of @BoundEnumOption, you can easily map an enum value to its encoded representation. That's nice; now you can have a typed collection of enum values instead of arbitrary integer values.

However, there is a gotcha. What will you will see a lot is that the enum value read influences the way you are supposed to read the remainder of the file. In the snoop example, this is no different. Currently, the example doesn't do anything with the actual data packets, but if it did, then it would have to decode it differently depending on the value of datalinkType.

In the past, you could easily use @If or @Switch and refer to the value of datalinkType, as long as it was an integer, String or boolean. However, now you need to compare that value to another enum value, and that's something that wasn't supported yet.

The Requirements

We want to be able to do something like this:


@BoundNumber(size="8")
private DatalinkType datalinkType;

@If("datalinkType == DatalinkType.ETHERNET")


This means that Preon needs to be able to compare enums, and that it also needs to be able to resolve references to enum values.

The Challenge

Having the ability to compare enums doesn't look like a huge problem. In fact, I just wrote an additional test in LimboTest, and it seems to be working fine:

public void testComparingEnums() {
EasyMock.expect(defs.getType("a")).andReturn(Direction.class).anyTimes();
EasyMock.expect(defs.getType("b")).andReturn(Direction.class).anyTimes();
EasyMock.expect(resolver.get("a")).andReturn(Direction.LEFT).anyTimes();
EasyMock.expect(resolver.get("b")).andReturn(Direction.RIGHT).anyTimes();
EasyMock.replay(defs, resolver);
assertTrue(condition(context, resolver, "a == a"));
assertFalse(condition(context, resolver, "a == b"));
assertTrue(condition(context, resolver, "b == b"));
}

public static enum Direction {
LEFT,
RIGHT;
}


The difficulty is somewhere else: it's in resolving the enum values. Problem is Direction.LEFT is not something Limbo is capable of dereferencing; it's just not in lexical scope. So, the question is, do we need another version of Limbo now? One that is capable of resolving enum value references? The good new is: no, you don't.

The reason for that is that Limbo is extensible. It defines something called a ReferenceContext that needs to be implemented to allow Limbo to execute in a context.

Let's look at an example to clear things up a little. Let's assume that you want to evaluate "foo.bar + 3". When you feed this expression to Limbo, it will first try to see if this expression makes sense at all. So it will check if it *will* actually be able to resolve something named 'foo', and if that thing has an attribute called 'bar'. If it doesn't then it will just fail directly. Now, in order to check if there is something called 'foo' in its context, it will simply call selectAttribute("foo") on the current ReferenceContext. If that ReferenceContext decides that something like that is referenceable, it will return a Reference object representing the "foo" reference. Next, Limbo will check if there is actually an attribute "bar" on the type of object referenced by the Reference just created. If so, then it will return a Reference to that property.

The important thing to note here is that - whatever Limbo is trying to do - all requests always hit the ReferenceContext first. Once the References are 'linked', it will call resolve(…) on the references to resolve the values on an instance of that context.

So, if we want to put the enums into lexical scope, all we need to do is rewrite the ReferenceContext. And our ReferenceContext is defined by Preon, so we don't have to rewrite Limbo; we just need to write a small adjustment in Preon, in order to integrate Limbo slightly differently.

The Solution

The actual code required to make this work is a little bit more than I'm willing to list here. (It turns out you need a decorator for RefenceContext, and then two additional Reference implementations. One to refer to Classes, and one to reference static fields on a class. The solution works in the same way as outlined above. The only thing that you need to add is an @ImportStatic annotation, at the top of the class from which you are referencing the enum values:

@ImportStatic(DatalinkType.class)
public class SnoopFile {

@BoundNumber(size="8")
private DatalinkType datalinkType;

@If("datalinkType == DatalinkType.ETHERNET")


Read: Enums in Preon

Topic: Senator wins defeat of his own clunker plan after `What have I done?' moment Previous Topic   Next Topic Topic: How a denial-of-service cyberattack works, and how to keep your computer safe

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use