java类转换为AS3的工具以及一些注意事项

项目中需要将以前的java代码转到flex中,手动写非常费劲.然后用baidu搜,csnd上有资源,但杯具的发现全都要资源分,而更杯具的是自己的资源分已经是负数.只能感慨了一下国人的开源精神和奉献精神又创新低.

google搜,无果.

最后用俺相当烂的英语拼了一下"Converting Java to ActionScript 3" 没想到竟然找到了.只恨百度不争气,甘做井底之蛙.csdn太功利,外国的开源项目到它那就要积分了.悲哀.最后,就恨自己英语太差了.不想看老外的文章……

 

言归正传,最终发现了J2AS3 这个开源项目,地址如下:http://code.google.com/p/j2as3/

一老外写的,不过有一些缺陷,就是对java的泛型支持的不是太好,不能转换泛型.

又在网上搜了一下啊,发现有一个哥们已经使用过并且写出了十分不错的使用行的.在此表示敬意.

地址如下:http://blog.sina.com.cn/s/blog_67532f7c0100ozbv.html

 

全文如下:

有些情况下我们需要将Java类转换成AS3类,比如使用Flash Remoting时,为了方便映射,我们会在AS3中定义与Java后台相关的值对像,用于序列化与反序列化。如果要互通的类有很多,手工去建立这两端的类太麻烦了。

在网上搜到了一个将Java 类文件转换为AS3类文件的开源项目,J2as3:http://code.google.com/p/j2as3/

在使用这个工具转换由Jaxb生的ImsQti_v2p1规范中的java类为as3类时,还是由一些不完美之处。主要是由于在Java类大量的使用List泛型,J2as3并不支持这个转换,目前作者还在进行修改。

下面就是我对J2as3的代码进行一些修改,以方便在BlazeDs4环境中使用。

修改的代码位置是J2AS3Application.as的convertFile函数中,这个方法读取java类文件,并通过转换器将文件内容转换,然后再重新生成新的as类文件。

var converter:Converter = new Converter(code);
var as3Code:String = converter.getNewClass();

其中的as3Code将为转换后的代码。在将as3Code生成类文件之前,进行我的处理。在此本人并不深入到converter内部去逐个处理,而是直接在as3Code上使用正则表达式来处理。本文是在Jaxb生成的imsqti_v2p1规范的java类转换成适用于BlazeDS与Flash间值对象映射的情景下练习用的,并未优化,也不考虑通用场景,切勿生搬硬套到别的场合。

 

1、List<type>的转换

默认情况下,对于无法识别的AS3语法之外的字符串,J2AS3会保留不动,BlazeDS的官方文档中描述到Java中的List类型在AS3中可以使用Array来映射。在Flex中,我使用mx.collections.ArrayCollection类来映射。

例如protected List<Serializable> content;要转换成:protected var content :ArrayCollection;

实现代码:

myPattern=/List<(\w+)> (\w+);/g; 
as3Code=as3Code.replace(myPattern,"var $2 :ArrayCollection;");

其中的myPattern为RegExp类。

()表示是使用组;这样可以在替换时使用$1,$2来引用匹配的串;

“组是模式的子部分。您可以使用组实现以下操作:
■ 将数量表示符应用到多个字符。
■ 界定要应用逻辑“或”(通过使用 | 字符)的子模式。
■ 捕获正则表达式中的子字符串匹配(例如,在正则表达式中使用 \1 以匹配先前匹配的
组,或类似地在 String 类的 replace() 方法中使用 $1)。”

\w用法:匹配单词字符(A-Z、a-z、0-9 或 _)

/g表现全局,对as3Code全串进行查找。“指定是否为正则表达式使用全局匹配。如果 global == true ,找到一个匹配项后将设置 lastIndex 属性。下次请求查找匹配项时,此正则表达式引擎将从字符串中的 lastIndex 位置开始查找。构造正则表达式时,使用 g 标志将 global 设置为true 。”

2、将protected改为public

之所以这样做是因为 Jaxb自动生成的imsqti_v2p1类的成员变量是protected的,然后通过get/set来实现读写,这对于与Flash端的序列化有影响,为了方便两者互操作,统统将成员变量变成public,

实现代码:

myPattern= /protected/gi;
as3Code=as3Code.replace(myPattern,"public");

3、在AS3中做valueObject的映射

要指定远程对象的别名,即如下形式:

[RemoteClass(alias="edu.lltang.jaxb.imsqti_v2p1.AbbrType")]
public class AbbrType {

 

在做转换时,可以这样实现:

myPattern=/public class (\w+) {/g;
as3Code=as3Code.replace(myPattern,"[Bindable]\n[RemoteClass(alias="edu.lltang.jaxb.imsqti_v2p1.$1")]\npublic class $1 {");

 

4、枚举类型

关于AS中的枚举,AS3官方文档是这样描述的:

“枚举”是您创建的一些自定义数据类型,用于封装一小组值。ActionScript 3.0 并不支持具体的枚举工具,这与 C++ 使用 enum 关键字或 Java 使用 Enumeration 接口不一样。不过,您可以使用类或静态常量创建枚举。例如,ActionScript 3.0 中的 PrintJob 类使用名为 PrintJobOrientation 的枚举来存储由 "landscape" 和"portrait" 组成的一组值,如下面的代码所示:

public final class PrintJobOrientation { public static const LANDSCAPE:String = "landscape"; public static const PORTRAIT:String = "portrait"; }

按照惯例,枚举类是使用 final 属性声明的,因为不需要扩展该类。该类仅由静态成员组成,这表示不创建该类的实例。而是直接通过类对象来访问枚举值。

先看Java类:

public enum CardinalityType {

    @XmlEnumValue("multiple")
    MULTIPLE("multiple"),
    @XmlEnumValue("ordered")
    ORDERED("ordered"),
    @XmlEnumValue("record")
    RECORD("record"),
    @XmlEnumValue("single")
    SINGLE("single");
    private final String value;

    CardinalityType(String v) {
        value = v;
    }

    public String value() {
        return value;
    }

    public static CardinalityType fromValue(String v) {
        for (CardinalityType c: CardinalityType.values()) {
            if (c.value.equals(v)) {
                return c;
            }
        }
        throw new IllegalArgumentException(v);
    }

}

改变成:

public final class CardinalityType {
        public static const MULTIPLE:String = "multiple";
        public static const ORDERED:String = "ordered";
        public static const RECORD:String = "record";
        public static const SINGLE:String = "single";
    }

实现代码:(如下代码是根据Jaxb生成java类而改的,并未优化,切勿生搬硬套到别的场合。)

if(as3Code.indexOf("enum")!=-1)
            {
                as3Code="package edu.lltang.qti.as3{\n"+as3Code+"}";
                myPattern=/public enum (\w+) {/g;
                as3Code=as3Code.replace(myPattern,"public final class $1 {");
                li=as3Code.indexOf("private",0);
                as3Code=as3Code.substring(0,li);
                as3Code+="}"
                myPattern=/(\w+)\("(\w+)"\),/g;
                as3Code=as3Code.replace(myPattern,"public static const $1:String = "$2";");
                myPattern=/(\w+)\("(\w+)"\);/g;
                as3Code=as3Code.replace(myPattern,"public static const $1:String = "$2";");
            }else
            {

5、Double

J2AS3在关键字列表(Tokenizer.as)中没有包含Double(有double),在进行查找时,虽然能匹配,但转换的时候,没有将Double转换成Number。

public var lowerBound:Double;

这样的转换会造成编译错误。

在Converter.as的toASType方法中,将:

if (type == "double" || type == "float" )
                return "Number";

改为:

if (type == "double" || type == "float" || type=="Double")
                return "Number";

即可。

 

 

附:jaxb>Imsqti_v2p1.xsd->Java Class->AS3 Class,加在J2AS3项目的J2AS3Application类的convertFile方法末。

//lltang
            var myPattern:RegExp = /   ,/gi;
            var li:int=as3Code.indexOf("*/",0);
            as3Code=as3Code.substring(li+2,as3Code.length);
            li=as3Code.indexOf("/*",0);
            as3Code=as3Code.substr(0,li);
            as3Code+="}";
            as3Code=as3Code.replace(myPattern,"");
            as3Code=as3Code.replace("})","");
            //如果是枚举类:
            if(as3Code.indexOf("enum")!=-1)
            {
                as3Code="package edu.lltang.qti.as3{\n"+as3Code+"}";
                myPattern=/public enum (\w+) {/g;
                as3Code=as3Code.replace(myPattern,"public final class $1 {");
                li=as3Code.indexOf("private",0);
                as3Code=as3Code.substring(0,li);
                as3Code+="}\n}";
                myPattern=/(\w+)\("(\w+)"\),/g;
                as3Code=as3Code.replace(myPattern,"public static const $1:String = "$2";");
                myPattern=/(\w+)\("(\w+)"\);/g;
                as3Code=as3Code.replace(myPattern,"public static const $1:String = "$2";");
            }else
            {
                as3Code="package edu.lltang.qti.as3{\n import mx.collections.ArrayCollection;\n"+as3Code+"}";
                myPattern= /protected/gi;
                as3Code=as3Code.replace(myPattern,"public");
                myPattern=/List<(\w+)> (\w+);/g;  //demo:List<Serializable> content->var content :ArrayCollection
                as3Code=as3Code.replace(myPattern,"var $2 :ArrayCollection;");
                //添加映射类
                myPattern=/public class (\w+) {/g;
                as3Code=as3Code.replace(myPattern,"[Bindable]\n[RemoteClass(alias="edu.lltang.jaxb.imsqti_v2p1.$1")]\npublic class $1 {");
            }
            //trace(as3Code);

 

 

 

你可能感兴趣的:(java,正则表达式,Flex,Flash,actionscript)