Ci potrebbe essere un modo migliore, ma un trucco è quello di chiamare direttamente invokeMethod
:
String buildCatalog(Catalog catalog) {
def writer = new StringWriter()
def xml = new MarkupBuilder(writer)
xml.catalog(xmlns:'http://www.sybrium.com/XMLSchema/NodeCatalog') {
delegate.invokeMethod('identity', [{
groupId(catalog.groupId)
artifactId(catalog.artifactId)
version(catalog.version)
}])
}
return writer.toString();
}
Questo è effettivamente ciò che Groovy sta facendo dietro le quinte. Non sono riuscito a far funzionare delegate.identity
o owner.identity
, che sono i soliti trucchi.
Edit: ho capito cosa sta succedendo.
Groovy adds a method con una firma di identity(Closure c)
ad ogni oggetto.
Ciò significa che quando si è tentato di richiamare in modo dinamico l'elemento identity
sul costruttore di XML, passando in un unico argomento di chiusura, si stava chiamando il metodo identity()
, che è come chiamare delegate({...})
sulla chiusura esterna.
Utilizzando il trucco invokeMethod
, Groovy ignora il Meta Object Protocol e tratta il metodo come metodo dinamico, anche se il metodo identity
esiste già su MetaObject.
Sapendo questo, possiamo mettere insieme una soluzione migliore, più leggibile. Tutto ciò che dobbiamo fare è cambiare la firma del metodo, in questo modo:
String buildCatalog(Catalog catalog) {
def writer = new StringWriter()
def xml = new MarkupBuilder(writer)
xml.catalog(xmlns:'http://www.sybrium.com/XMLSchema/NodeCatalog') {
// NOTE: LEAVE the empty map here to prevent calling the identity method!
identity([:]) {
groupId(catalog.groupId)
artifactId(catalog.artifactId)
version(catalog.version)
}
}
return writer.toString();
}
Questo è molto più leggibile, è chiaro l'intento, e il commento dovrebbe (si spera) impedire a chiunque di rimuovere il "superfluo" vuoto carta geografica.
Ha funzionato, ma puoi spiegarlo? Cosa è delegato e perché delegate.identity è diverso da delegate.invokeMethod ('identity')? –
L'ho capito, aggiornerò la mia risposta. – OverZealous
FYI: Ho rintracciato questo usando la GroovyConsole per ispezionare l'oggetto XML. Questo fammi sapere che il metodo 'identity' esisteva già con un singolo' Closure' come argomento. – OverZealous