3

codemodel を使用してコード生成クラスに入力された arraylist (非 codemodel) があり、生成されたコードでそれを使用したいと考えています。これを行う方法はありますか?生成されたコードはそれを生成するコードを参照したり依存したりしないため、少し「世界を横断」していますが、値のトラバーサルで手動でコピーすることなく、配列リストの値を使用したいと思います値...文字列、数値などと同じように、これを行う方法が必要です...?

私のコード例は次のとおりです。

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} は makeHeadersWrapper 署名の「headersList」パラメーターを参照する必要があります。変数の値を {X} として参照し、それをコードモデル JExpr(ession) にする方法はありますか? {X}の解決を手伝ってください!:P

心から感謝します、ピョートル

4

1 に答える 1

3

JExpression基本的にはリストをサポートしていないと思います。はありJArrayますが、それでも を反復処理する必要がありますheadersList。codemode-2.6 までは、JExprまたはJExpressionリストを反復処理するメソッドはありません。したがって、反復部分を回避することはできません。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 コードです。

この答えはあなたが探している正確なものではないかもしれませんが、前進するためのアイデアを与えるかもしれません. お役に立てれば。

于 2014-05-20T18:10:35.390 に答える