[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[News.eclipse.dsdp.mtj] Re: Preprocessing Discussion

Hello!

First of all, thanks to Richard for his opinion. It is good to have a discussion. Well, that's true that using annotations for code fragmentation is quite different approach than some established solutions based on preprocessing with directives, e.g. J2ME Polish. This does not only mean that a developer has to change his way of programming. This also means that using annotations provides such capabilitys like syntax cheking or the ability to be processed by refactoring operations like any other Java element - "out of the box" and not only through extra tools.
The scope of annotations is not only a field or a method, as mentioned by Richard. They can be used along with much more elements:


- Type
- Field
- Method
- Constructor
- Parameter
- Local variable
- Pakage declaration
- Annotation

On the one hand it can be seen as not enough in a comparison to the omnipresence of Java comments wich are used to bring a preprocessing directive into the code. But on the other hand this can be seen as reasonable limitations. Fragmenting the code should go along with taking the structure of this code into account. This strategy provides also a limitation of mistakes - like setting some //#endif on the wrong line or forgetting to set it at all. Or managing all occurencies of an element that should exist only in some case. According to a method this means to manage all its invocations by surrounding them with appropriate directives. In a complex structure this could easily be forgotten. If you use an Existence-Annotation in Annocracy, than the system takes care of all occurencies, invocations, etc. All you need is probably add a comment for yourself to see the dependency or use some visual decoration provided by a tool - yet to come but not impemented at the moment because Annocracy is quite "young".

Richard also demurs about the handling of complex statements like /#if polish.hasCommandKeyEvents || (polish.key.LeftSoftKey.defined && polish.key.RightSoftKey.defined). Maybe it is a misunderstanding of concept which Annocracy follows. In the most annotations there is an element that is called "dependsOn". It's used to represent a case, e.g. that a device has some capability. In our small example application there are not many of such cases used, e.g. "midp1.0". This is not always, as it could seem to be, equivalent to some atomar case like polish.hasCommandKeyEvents. It is only a placeholder or a label for a rule which contains all the logic for a comparison of device properties with some values you expect. You could specify a rule that handles cases of any complexity - using the usual operators like AND, OR, NOT -, give it a name and reference it by this name in the annotations. Annocracy provides a way of this specification in an external file that easily can be modified or completed. I would say, it is even less verbose in an annotation, than in a comment based directive. Besides you have to specify such a rule - as it is called in the context of Annocracy - only once - in the mentioned file. If you prefer to use it other way, it's quite easy to provide an appropriate RuleValidator by yourself that can handle the same input like polish.hasCommandKeyEvents || (polish.key.LeftSoftKey.defined && polish.key.RightSoftKey.defined). Annocracy alows you to extend its functionality at various points.

Concerning imports - you have no need to handle them in Annocracy in the way you would if you were using J2ME Polish. Let us analyse what the cases are for handling imports. The simple one can be that you are using some functionality in your application that should exist only in some special case. Importing the needed classes that comes along with it should also be handled in the same way. In J2ME Polish you can achieve this by surrounding such an import declaration with directives, as shown in the example provided by Richard:

//#if polish.api.nokia-ui
   import com.nokia.mid.ui.*;
//#endif

Annocracy handles such a case in a different way. The functionality is removed from code if the corresponding condition is not fulfiled - e.g. using @Existence. The import which of cource is not touched by any annotation and is not needed in the enclosing compilation unit will be removed by Annocracy at the end of the processing. It's just the same if you were using Eclipse as IDE and invoking "organize imports" action.
The second case for handling imports could be that you have to "toggle" an import of a functionality that is provided by an advanced API but is not included in the old one, e.g. GameCanvas in MIDP-2.0. In such a case you would provide an own implementation - with the same name - and just want to "link" the import to yours one. In J2ME Polish this could by something like this:


//#if polish.midp2
    import javax.microedition.lcdui.game.GameCanvas;
//#else
    import my.own.GameCanvas;
//#endif

In Annocracy you could use @Types instead to change the type of your element containing the declaration of your GameCanvas (because changing the type is what you want in such a case, isn't it?) :

@Types(types = { @Type(dependsOn = "midp1.0" typeOwner = "canvasTypeOwner") })
private javax.microedition.lcdui.game.GameCanvas canvas;


@TypeOwner
private my.own.GameCanvas canvasTypeOwner;

Although this annotation was not used in our example application this does not mean that there is no such functionality provided by the annotations of Annocracy. Just look at the annotations in the package de.four2b.annocracy.annotations.core. By the way, you are not limited by using only this annotations. You can easily specify your own if there is a need. This comes along with providing of the appropriate processing component, but it's also nothing complex according to the simple API and using utilities included in Annocracy for such purposes.

If you are working with annotations you need Java 5 - there is nothing to appeal against. You should have this installed on your computer if you want to use Annocracy. But I don't really understand the problem mentioned by Richard: "... The plugin processing the annotated classes need to run in a Java5 VM. This is in contrast to the claim eclipse runs on 1.4..." I'm currenlty using Eclipse with Java 5 VM and being still able to develop J2ME applications. As mentioned in the readme file, that is shipped with our example application, you have to include the rt.jar from Java 5 JRE in the classpath of your project if you want to use all of the core annotations. It's also mentioned how you can limit the access to this JAR by adding some restrictions. This is e.g. one way if you do not want to have functionality from Java 5 in your project, besides the annotations. This way you could not use autoboxing e.g. by mistake. The code is absolutely valid for the platform you're targeting, e.g. 1.2. By the way, it's planned to provide a processing component for transforming the other features of Java 5 in the code to the needed code version, e.g. 1.2. This way you'll be able to write your code as if you would develop for Java 5 platform. So, J2ME Polish would be not the only one tool with such abilities.

At the moment Annocracy dose not provide a GUI tool for assisting the developement process. But, as mentioned above, it's planned to do one in the near future. So it's just a matter of time. The advantage of J2ME Polish in this case is of course unchallenged - at the moment. Annocracy does not exist as long as other tools and has no big crew behind it. That's why there are not all features integrated yet. But it's going to change.

Kind regards,

Artjom