有没有办法将java arraylist对象复制到codemodel生成的源?

时间:2014-05-15 13:46:12

标签: java object arraylist reference jcodemodel

我在代码生成类中使用codemodel填充了一个arraylist(非代码模型),我想在生成的代码中使用它。有没有办法做到这一点?它跨越世界"一点点,因为生成的代码没有引用或依赖于生成它的代码,但是我仍然喜欢使用arraylist的值而不必通过值遍历值遍历手动复制它。必须有一种方法可以做到这一点,因为有字符串,数字等......?

我的示例代码如下:

private JMethod makeHeadersWrapper( String endPointName, ArrayList<BasicNameValuePair> headersList )
{

    JMethod wrapperMethod = definedClass.method( JMod.PUBLIC | JMod.STATIC, codeModel.ref( headersList.getClass() ).narrow( BasicNameValuePair.class ), StringUtils.formatName( "make" + endPointName + "Header", false, StringUtils.FormatType.UP_ENGLISH_WORDS ) );

    JVar headersListVar = wrapperMethod.body().decl( wrapperMethod.type(), "headersList", {X} ) );
    wrapperMethod.body()._return( headersListVar );

    return wrapperMethod;

}

正如你在我的作业声明中看到的那样,有一个{X}空白字段,这就是我想要弄清楚如何编写的字段。话虽如此,{X}应该引用&#39; headersList&#39; makeHeadersWrapper签名中的参数。是否有任何方法可以将变量的值引用为{X}并使其成为代码模型JExpr(ession)?请帮我解决{X}! :P

真诚地感谢, 彼得

1 个答案:

答案 0 :(得分:3)

基本上我不认为JExpression支持列表。它确实有一个JArray,但您仍然必须遍历headersList。直到codemode-2.6,JExprJExpression中没有迭代列表的方法。所以你无法摆脱迭代部分。因此,标准做法将迭代headersList并添加初始化语句。

比如说你有像

这样的Namevalue对
public class BasicNameValuePair {
    private String name;
    private String value;

    public BasicNameValuePair(String name, String value) {
        this.name = name;
        this.value = value;
    }
    //getters & setters
}

并初始化为

List<BasicNameValuePair> headerList = new ArrayList<BasicNameValuePair>();
headerList.add(new BasicNameValuePair("1", "1"));
headerList.add(new BasicNameValuePair("2", "2"));
headerList.add(new BasicNameValuePair("3", "3"));
headerList.add(new BasicNameValuePair("4", "4"));

然后你可以生成方法体

private JMethod makeHeadersWrapper( String endPointName, List<BasicNameValuePair> headersList ) {

    JClass headerClass = codeModel.ref( headersList.getClass() ).narrow( BasicNameValuePair.class );
    JMethod wrapperMethod = definedClass.method( JMod.PUBLIC | JMod.STATIC, headerClass, ( "make" + endPointName + "Header") );

    JVar headersListVar = wrapperMethod.body().decl( wrapperMethod.type(), "headersList", JExpr._new(headerClass) );
    for(BasicNameValuePair nameValuePair : headersList) {
        wrapperMethod.body().add(headersListVar.invoke("add").arg(JExpr._new(nameValuePairClass).arg(nameValuePair.getName()).arg(nameValuePair.getValue())));
    }
    wrapperMethod.body()._return( headersListVar );

    return wrapperMethod;
}

这将生成代码

public static ArrayList<BasicNameValuePair> makeTestHeader() {
    ArrayList<BasicNameValuePair> headersList = new ArrayList<BasicNameValuePair>();
    headersList.add(new BasicNameValuePair("1", "1"));
    headersList.add(new BasicNameValuePair("2", "2"));
    headersList.add(new BasicNameValuePair("3", "3"));
    headersList.add(new BasicNameValuePair("4", "4"));
    return headersList;
}

但是ArrayList有一个使用{{ }}的构造函数方法。所以你可以声明像

List<String> lst = new ArrayList<String>(){{ add("1"); add("2"); add("3"); add("4"); }};

JExprdirect()方法,我们可以直接传递源代码。使用这两个,我们可以生成如下代码。我不推荐这种方法,但它可能。

private JMethod makeHeadersWrapper( String endPointName, List<BasicNameValuePair> headersList ) {
    JMethod wrapperMethod = definedClass.method( JMod.PUBLIC | JMod.STATIC, codeModel.ref( headersList.getClass() ).narrow( BasicNameValuePair.class ), ( "make" + endPointName + "Header") );

    JVar headersListVar = wrapperMethod.body().decl( wrapperMethod.type(), "headersList", JExpr.direct(generateListConstructor(headersList)) );
    wrapperMethod.body()._return( headersListVar );

    return wrapperMethod;

}

private String generateListConstructor(List<BasicNameValuePair> headersList) {
    StringBuilder listEpr = new StringBuilder("new ArrayList<scope.BasicNameValuePair>(){{");
    for(BasicNameValuePair nameValuePair : headersList) {
        listEpr.append("add(new BasicNameValuePair(\"").append(nameValuePair.getName()).append("\", \"").append(nameValuePair.getValue()).append("\")); ");
    }
    return listEpr.append("}}").toString();
}

这将生成

public static ArrayList<BasicNameValuePair> makeTestHeader() {
    ArrayList<BasicNameValuePair> headersList = (new ArrayList<scope.BasicNameValuePair>(){{add(new BasicNameValuePair("1", "1")); add(new BasicNameValuePair("2", "2")); add(new BasicNameValuePair("3", "3")); add(new BasicNameValuePair("4", "4")); }});
    return headersList;
}

这也是一个有效的java代码。

这个答案可能不是您正在寻找的答案,但它可能会让您有进步的想法。希望这会有所帮助。