Вложенный объект внутри пользовательского расширения плагина

Я разрабатываю собственный плагин Gradle и хочу определить закрытие конфигурации (расширение плагина) следующим образом:

myplugin {
   property1 'value'

   property2 {
     a1 'hello'
     a2 'bye'
   }
}

У меня есть эти классы:

public class MyPluginExtension { //root extension

    String property1;
    Property2 peroperty2;

    //getters and setters
}

public class Property2 {
    String a1;
    String a2;
    //getters and setters
}

И в проекте плагина я создаю расширение следующим образом:

project.getExtensions().create("myplugin", MyPluginExtension.class);

Но в моем клиентском проекте, когда я применяю и настраиваю плагин, как показано выше, я получаю эту ошибку:

Метод Gradle DSL не найден: 'property2()'

Как я могу определить замыкание property2 в моем классе MyPluginExtension?

ИЗМЕНИТЬ

Я пробовал это:

 public class MyPluginExtension { //root extension

    String property1;
    Property2 peroperty2;

        //getters and setters

    public void property2(Closure c) {
        c.setResolveStrategy(Closure.DELEGATE_FIRST);
        c.setDelegate(property2);
        c.call();
    }
}

Но теперь я получаю эту ошибку:

Метод Gradle DSL не найден: a1()

Он не может разрешать вложенные поля замыкания.


person Héctor    schedule 09.11.2015    source источник


Ответы (1)


Вам нужно использовать Closure с делегатом, установленным для определенного объекта:

class SamplePlugin implements Plugin {
   void apply(Object p) {
      p.extensions.create("e", MyPluginExtension)
   }
}

class MyPluginExtension { 

    Property2 property2 = new Property2()
    String property1

    def property2(Closure c) {
      c.resolveStrategy = Closure.DELEGATE_FIRST
      c.delegate = property2
      c()
    }
}

class Property2 {
    String a1
    String a2

    def a1(a1) {
      this.a1 = a1
    }

    def a2(a2) {
      this.a2 = a2
    }
}

apply plugin: SamplePlugin

e {
   property1 'lol'
   property2 {
      a1 'lol2'
      a2 'lol3'
   }
}

println e.property1
println e.property2.a1

Пожалуйста, также посмотрите здесь, почему дополнительные методы нужный. И здесь вы можете найти рабочую демонстрацию, реализованную в java.

person Opal    schedule 09.11.2015
comment
Спасибо. А если я использую Java вместо Groovy? - person Héctor; 09.11.2015
comment
Просто определите все это, используя синтаксис Java. Тоже должно работать. - person Opal; 09.11.2015
comment
Спасибо. Я попробовал это и кажется решенным, но теперь он не может разрешить вложенные поля закрытия. Посмотрите на мою правку. - person Héctor; 09.11.2015
comment
Смотрите мой ответ, в моем коде есть метод с именем a1. - person Opal; 09.11.2015
comment
@bigdestroyer, вам нужно добавить: void a1(String a1) { this.a1 = a1; } метод. - person Opal; 09.11.2015
comment
Спасибо. теперь я понимаю - person Héctor; 09.11.2015