2015-02-16 14 views
6

Ho qualcosa come il plug-in di seguito in cui ho uno spazio dei nomi esterno e al suo interno c'è una singola istanza "concreta" (mother) di un oggetto più un'altra raccolta (children).Aggiunta di istanza di oggetto all'estensione del plugin gradle

family { 
    mother { 
     firstname = 'John' 
     lastname = 'Cleese' 
    } 
    children { 
     son { 
     firstName = 'John' 
     lastName = 'Cleese' 
     } 
     daughter { 
     firstName = 'Jane' 
     lastName = 'Cleese' 
     } 
    } 
} 

sono in grado di aggiungere l'oggetto di raccolta e leggere le variabili in base a vari esempi che ho visto, ma non sicuro di come aggiungo l'istanza concreta in aggiunta.
Come si definisce sull'oggetto estensione?

Codice che mostra il problema - Vorrei aggiungere mother come singola istanza al plugin.

import org.gradle.api.DefaultTask 
import org.gradle.api.tasks.TaskAction 
import org.gradle.api.NamedDomainObjectContainer 
import org.gradle.api.* 

class Person 
{ 
    final String name 
    String firstName 
    String lastName 
    Person(String name) { this.name = name } 
} 

class FamilyExtension { 

    final NamedDomainObjectContainer<Person> children 
    Person mother 
    Person father 

    FamilyExtension(children) { 
    this.children = children 
    } 

    def children(Closure closure) { 
    children.configure(closure) 
    } 
} 

class FamilyPlugin implements Plugin<Project> { 

    void apply(Project project) { 
    project.task('sayHello', type: DefaultTask) << { 
     println(
     "Hello ${project.family.children["son"].firstName} " + 
     "and hello ${project.family.children["daughter"].firstName} ") 
    } 

    def children = project.container(Person) 

    project.extensions.create("family", FamilyExtension, children) 
    } 
} 
apply plugin: FamilyPlugin 

family { 
    // How do I add support for this? 
    // mother { 
    //  firstname = 'John' 
    //  lastname = 'Cleese' 
    // } 
    children { 
     son { 
     firstName = 'John' 
     lastName = 'Cleese' 
     } 
     daughter { 
     firstName = 'Jane' 
     lastName = 'Cleese' 
     } 
    } 
} 
+0

Non sei sicuro di ciò che si desidera raggiungere. Aggiungi supporto per l'impostazione di 'firstname' e' lastname' su mother o semplicemente su single mother? – Opal

+0

Vorrei impostare i valori del nome sulla madre single, ma in generale mi piace capire come ho questo mix di ObjectContainer e oggetti "semplici" nella DSL. –

+0

Non ho trovato nessun progetto di esempio utilizzando entrambi questi o come impostare oggetti sull'estensione che non usano configure (closure) –

risposta

0

ho avuto un problema simile al vostro, ma ho capito come creare la "madre" sul mio caso, ma non i "bambini". Il modo in cui ho realizzato questo è con un oggetto di estensione nidificato.

Ecco come l'ho fatto (il mio è in puro java, quindi potrebbe essere necessario apportare alcune modifiche per farlo in Groovy - Sono molto nuovo a Groovy, quindi non sono sicuro di cosa esattamente debba essere modificato):

Quando si aggiunge l'estensione nel plug-in, la classe supporterà automaticamente l'interfaccia ExtensionAware e, pertanto, potrà avere aggiunte estensioni. Nel costruttore FamilyExtension aggiungere una nuova estensione, gettando la classe per ExtensionAware prima:

public FamilyExtension(NamedDomainObjectContainer<Person> children) { 
    ((ExtensionAware) this).getExtensions().create("mother",Person.class); 
    this.children = children; 
} 

Questo consente solo una madre single dichiarato esattamente come si deve. Nota, tuttavia, che non imporrà solo un singolo, dato che puoi aggiungere quante madri vuoi, ma ogni dichiarazione successiva avrà il risultato di cambiare il valore su quella singola istanza, quindi ce n'è solo una. Potresti anche ottenere un valore nullo se la madre non fosse stata dichiarata, quindi dovrò testarla (alcuni dimostrano che ciò può accadere, ma nei miei esperimenti non sembra).

per ottenere il vostro oggetto madre, basta lanciare la vostra estensione a ExtensionAware e recuperare la classe Person fuori dal che, come si otterrebbe l'estensione famiglia dal progetto

FamilyExtension fext = project.getExtensions().findByType(Person.class) 
Person mother = (Person) ((ExtensionAware) fext).getExtensions().findByName("mother") 

Edit: Un modo alternativo sarebbe solo per definire una funzione sul proprio oggetto estensione che accetta una chiusura e delegare la chiusura a un nuovo oggetto madre. Quindi potresti usare una bandiera booleana per far rispettare il requisito di una sola madre.

private boolean mother_defined = false; 
private Person mother_value = null; // or Person mother = new Person() 

public void mother(Closure<?> motherdef) { 
    if (mother_defined) {throw new Exception("Only one mother allowed");} 
    mother_value = new Person(); 
    motherdef.setDelegate(mother); 
    motherdef.call(); 
    mother_defined = true; 
} 
0

Beh, per aggiungere mother chiusura al family si aggiunge il seguente codice alla classe FamilyExtension

Person mother(Closure closure) { 
    mother = new Person() 
    project.configure(mother, closure) 
    return mother 
} 

Se, allo stesso tempo, si desidera avere children estensione all'interno della famiglia uno si aggiunge il codice seguente nel metodo di FamilyPlugin.apply

project.extensions.create("family", FamilyExtension, instantiator, project) 
project.family.extensions.create("children", FamilyExtension.Children, project) 

e quindi si aggiunge

void son(Closure closure) { 
    Person son = new Person() 
    project.configure(son, closure) 
    children.add(son) 
} 

per essere in grado di aggiungere son chiusura all'interno del children uno.

Per vedere l'intero progetto e la spiegazione con maggiori dettagli visitate il progetto Github https://github.com/andriipanasiuk/family-gradle-plugin

Problemi correlati