Dmitry has posted 1 posts at DZone. View Full User Profile

GraniteDS: Gas3 template for complex enums

07.22.2011
| 4947 views |
  • submit to reddit

I use in projects GraniteDS and I recently was faced with the fact that the complex enumerators are not compiled by Gas3 to need appropriate AS3-class.

For this I changed enum.gsp from class:org/granite/generator/template/enum.gsp.

As an example of complex enum I took enum of playing cards:

import java.io.Serializable;

public enum Rank implements Serializable {
    ACE(11, 1), DEUCE(2), THREE(3), FOUR(4), FIVE(5), SIX(6), SEVEN(7), EIGHT(8), NINE(9), TEN(10), JACK(10), QUEEN(10), KING(10);
   
    private int value;
    private boolean isDifferentValue;
    private int differentValue;
   
    Rank(int value) {
        this.value = value;
        this.isDifferentValue = false;
        this.differentValue = 0;
    }
    Rank(int value, int differentValue) {
        this.value = value;
        this.isDifferentValue = true;
        this.differentValue = differentValue;
    }
    public int getValue() {
        return value;
    }
    public boolean getIsDifferentValue() {
        return isDifferentValue;
    }
    public int getDifferentValue() {
        return differentValue;
    }
}

Class has 3 private variable: value of card, availability of alternative value and alternative value (if it is).

If we compile the AS3-class with a standart template we get the following code:

    import org.granite.util.Enum;

    [Bindable]
    [RemoteClass(alias="com.somePackage.Rank")]
    public class Rank extends Enum {
        public static const ACE:Rank = new Rank("ACE", _);
        public static const DEUCE:Rank = new Rank("DEUCE", _);
        public static const THREE:Rank = new Rank("THREE", _);
        public static const FOUR:Rank = new Rank("FOUR", _);
        public static const FIVE:Rank = new Rank("FIVE", _);
        public static const SIX:Rank = new Rank("SIX", _);
        public static const SEVEN:Rank = new Rank("SEVEN", _);
        public static const EIGHT:Rank = new Rank("EIGHT", _);
        public static const NINE:Rank = new Rank("NINE", _);
        public static const TEN:Rank = new Rank("TEN", _);
        public static const JACK:Rank = new Rank("JACK", _);
        public static const QUEEN:Rank = new Rank("QUEEN", _);
        public static const KING:Rank = new Rank("KING", _);

        function Rank(value:String = null, restrictor:* = null) {
            super((value || ACE.name), restrictor);
        }
        protected override function getConstants():Array {
            return constants;
        }
        public static function get constants():Array {
            return [ACE, DEUCE, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING];
        }
        public static function valueOf(name:String):Rank {
            return Rank(ACE.constantOf(name));
        }
    }

But this code can not hold te developer ...

The modified template is in the attachment to this article.

With new template we get following code:

	import flash.utils.IDataInput;

import org.granite.util.Enum;

[Bindable] [RemoteClass(alias="com.somePackage.Rank")] public class Rank extends Enum { public static const ACE:Rank = new Rank("ACE", 11, 1, true, _); public static const DEUCE:Rank = new Rank("DEUCE", 2, 0, false, _); public static const THREE:Rank = new Rank("THREE", 3, 0, false, _); public static const FOUR:Rank = new Rank("FOUR", 4, 0, false, _); public static const FIVE:Rank = new Rank("FIVE", 5, 0, false, _); public static const SIX:Rank = new Rank("SIX", 6, 0, false, _); public static const SEVEN:Rank = new Rank("SEVEN", 7, 0, false, _); public static const EIGHT:Rank = new Rank("EIGHT", 8, 0, false, _); public static const NINE:Rank = new Rank("NINE", 9, 0, false, _); public static const TEN:Rank = new Rank("TEN", 10, 0, false, _); public static const JACK:Rank = new Rank("JACK", 10, 0, false, _); public static const QUEEN:Rank = new Rank("QUEEN", 10, 0, false, _); public static const KING:Rank = new Rank("KING", 10, 0, false, _); private var _value:*; private var _differentValue:*; private var _isDifferentValue:*; function Rank(name:String = null, value:* = null, differentValue:* = null, isDifferentValue:* = null, restrictor:* = null) { super((name || ACE.name), restrictor); if (restrictor != null) { _value = value; _differentValue = differentValue; _isDifferentValue = isDifferentValue; } } public function get value():* { return _value; } public function get differentValue():* { return _differentValue; } public function get isDifferentValue():* { return _isDifferentValue; } override protected function getConstants():Array { return constants; } override public function readExternal(input:IDataInput):void { super.readExternal(input); var constantObject:Rank = valueOf(name); _value = constantObject.value; _differentValue = constantObject.differentValue; _isDifferentValue = constantObject.isDifferentValue; } public static function get constants():Array { return [ACE, DEUCE, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING]; } public static function valueOf(name:String):Rank { return Rank(ACE.constantOf(name)); } }

This is what we want ...

Notes:

1. You can use more complex approach and use classes from package java.lang.reflect for strong typing in compiled AS3-class but experience shows that it is not necessary.

2. By default the created enum-class contains 2 private variables (or public getters as Gas3 takes for compiling AS3-class private variables of them) - class and declaringClass. Since they do not need we exclude them by the condition.

3. If Java enum-class is simple (without internal variables) then new template will not make changes to the as3-code.

 

To attach a new template for the project in project properties (only if Gas3 Code Generator used) select properties for GraniteD, tab Templates and template for ENUM, then "Edit...". If new template is in jar-file you can declare "class:com/your/package/enum.gsp"or if fil .gsp in your project then declare "file:///X:/path/workspace/project/path/enum.gsp". Or you can use for attaching new template Ant, Maven or IDE plugins.

0
Published at DZone with permission of its author, Dmitry Ionash.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Diego Leal replied on Mon, 2011/11/07 - 9:32am

Hello, This article is very important to me. Where is the attachment? Tnks.

Jay Rapote replied on Mon, 2012/03/12 - 6:18am in response to: Diego Leal

hi, where can we find the mdified enum.gsp? thanks!

Jay Rapote replied on Mon, 2012/03/12 - 6:24am

hi, where can we find the modified enum.gsp? thanks!

Johan Kustermans replied on Thu, 2012/04/12 - 8:50am in response to: Jay Rapote

As per suggestion by the author I have extended his template to incorporate typed  properties. The solution can be found at

 https://github.com/Krustie101/GasTransformerWithComplexEnums

 By code reuse from GraniteDS, this solution will also take into account @ExternalizedProperty and @IgnoredProperty annotations. You will need to use the accompanying custom Groovy transformer (+ complexEnum.gsp) that can be configured in Granite Builder.

regards

Johan Kustermans replied on Fri, 2013/03/15 - 4:29pm

I posted  a new version on github (master-branch) that works with GraniteDS 3.0.0. 

However, I believe the current version of 3.0.0.M1 on the eclipse update site contains bugs that will mess things up (not all necessary files were exported to the granite-generator.jar). Luckily, these bugs have been fixed and committed to github by the authors of GraniteDS:

https://github.com/graniteds/graniteds_builder 

So you can clone their repo and build the latest version of the plugin (simply by exporting the project as a plugin in eclipse. If you make some changes you will need to perform an ant prebuild-step first).


Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.