2013-03-19 13 views
5

Ho un percorso per un oggetto all'interno di un oggetto all'interno di un oggetto e voglio impostarlo usando le abilità dinamiche di Groovy. In genere è possibile farlo semplicemente facendo quanto segue:Groovy: imposta il metodo nidificato dinamico usando string come percorso

class Foo { 
    String bar 
} 


Foo foo = new Foo 
foo."bar" = 'foobar' 

Che funziona OK. Ma cosa succede se hai oggetti nidificati? Qualcosa di simile:

class Foo { 
    Bar bar 
} 

class Bar { 
    String setMe 
} 

Ora voglio utilizzare l'impostazione dinamica, ma

Foo foo = new Foo() 
foo."bar.setMe" = 'This is the string I set into Bar' 

Restituisce un MissingFieldException.

Eventuali suggerimenti?

AGGIORNAMENTO: Grazie a Tim per avermi indirizzato nella giusta direzione, il codice iniziale lì funziona perfettamente nel recupero di una proprietà, ma ho bisogno di impostare il valore utilizzando la stringa del percorso.

Ecco cosa mi è venuta dalla pagina Tim suggerito:

def getProperty(object, String propertyPath) { 
    propertyPath.tokenize('.').inject object, {obj, prop -> 
     obj[prop] 
    } 
    } 

    void setProperty(Object object, String propertyPath, Object value) { 
    def pathElements = propertyPath.tokenize('.') 
    Object parent = getProperty(object, pathElements[0..-2].join('.')) 
    parent[pathElements[-1]] = value 
    } 
+1

http: //stackoverflow.com/questions/5488689/how-to-retrieve-nested-properties-in-groovy –

+0

Sono stato in grado di completare l'operazione sviluppando e utilizzando il metodo getProperty, inserirò la risposta sopra dal commento sezione non è molto buona per inserire il codice in –

risposta

1

seguito funziona correttamente.

foo."bar"."setMe" = 'This is the string I set into Bar'; 

Senza getProperty sovrascrivendo si può ottenere lo stesso risultato utilizzando "$ {}" sintassi per GString come il seguente codice illustra

class Baz { 
    String something 
} 

class Bar { 

    Baz baz 

} 

class Foo { 
    Bar bar 
} 

def foo = new Foo() 
foo.bar = new Bar() 
foo.bar.baz = new Baz() 

def target = foo 
def path = ["bar", "baz"] 
for (value in path) { 
    target = target."${value}" 
} 

target."something" = "someValue" 
println foo.bar.baz.something 

stampe println finali "someValue" come previsto

+1

Solo una piccola aggiunta a questa eccellente risposta per gli altri per evitare di inciampare su questo: dovrai usare esplicitamente "virgolette doppie" perché funzioni, poiché le GStrings (con espressioni all'interno) sono definite in questo modo. Ma immagino che tutti i programmatori groovy lo sapessero già :) – kaskelotti

Problemi correlati