Есть ли способ скопировать объект Java 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} должен ссылаться на параметр 'headersList' в сигнатуре makeHeadersWrapper. Есть ли способ сделать это, чтобы ссылаться на значение переменной как {X} и иметь его кодовой моделью JExpr(ession)? пожалуйста, помогите мне решить для {X}!:П
искренне спасибо Петр
1 ответ
В основном я не думаю 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"); }};
А также JExpr
имеет direct()
метод, в котором мы могли бы передать исходный код напрямую. Используя оба из них, мы можем сгенерировать код, как показано ниже. Я не рекомендую этот подход, но это возможно.
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.
Этот ответ может быть не тем, который вы ищете, но он может дать вам представление о том, как двигаться дальше. Надеюсь это поможет.