Question

Je me demande quelle est la meilleure façon de récupérer des propriétés imbriquées dans Groovy, en prenant un objet donné et une chaîne de "propriété" arbitraire.J'aimerais quelque chose comme ceci :

someGroovyObject.getProperty("property1.property2")

J'ai eu du mal à trouver un exemple d'autres personnes souhaitant faire cela, alors peut-être que je ne comprends pas certains concepts de base de Groovy.Il semble qu'il doit y avoir une manière élégante de procéder.

À titre de référence, il existe une fonctionnalité dans Wicket qui correspond exactement à ce que je recherche, appelée PropertyResolver :http://wicket.apache.org/apidocs/1.4/org/apache/wicket/util/lang/PropertyResolver.html

Tous les conseils seraient appréciés !

Était-ce utile?

La solution

Je ne sais pas si Groovy a une façon intégrée de le faire, mais voici 2 solutions. Exécutez ce code dans le Console groovy pour le tester.

def getProperty(object, String property) {

  property.tokenize('.').inject object, {obj, prop ->       
    obj[prop]
  }  
}

// Define some classes to use in the test
class Name {
  String first
  String second
}

class Person {
  Name name
}

// Create an object to use in the test
Person person = new Person(name: new Name(first: 'Joe', second: 'Bloggs'))

// Run the test
assert 'Joe' == getProperty(person, 'name.first')

/////////////////////////////////////////
// Alternative Implementation
/////////////////////////////////////////
def evalProperty(object, String property) {
  Eval.x(object, 'x.' + property)
}

// Test the alternative implementation
assert 'Bloggs' == evalProperty(person, 'name.second')

Autres conseils

Haricots groovy vous permettent d'accéder directement aux champs.Vous n'êtes pas obligé de définir des méthodes getter/setter.Ils sont générés pour vous.Chaque fois que vous accédez à une propriété du bean, la méthode getter/setter est appelée en interne.Vous pouvez contourner ce comportement en utilisant l'opérateur .@.Voir l'exemple suivant :

class Person {
    String name
    Address address
    List<Account> accounts = []
}

class Address {
    String street
    Integer zip
}

class Account {
    String bankName
    Long balance
}

def person = new Person(name: 'Richardson Heights', address: new Address(street: 'Baker Street', zip: 22222)) 
person.accounts << new Account(bankName: 'BOA', balance: 450)
person.accounts << new Account(bankName: 'CitiBank', balance: 300)

Si vous ne traitez pas de collections, vous pouvez simplement appeler le champ auquel vous souhaitez accéder.

assert 'Richardson Heights' == person.name
assert 'Baker Street' == person.address.street
assert 22222 == person.address.zip

Si vous souhaitez accéder à un champ au sein d'une collection, vous devez sélectionner l'élément :

assert 'BOA' == person.accounts[0].bankName
assert 300 == person.accounts[1].balance​​​​​​​​​

Vous pouvez aussi utiliser propertyMissing. C'est ce que vous pourriez appeler la méthode intégrée de Groovy.

Déclarer cela dans votre classe:

def propertyMissing(String name) {
    if (name.contains(".")) {
        def (String propertyname, String subproperty) = name.tokenize(".")
        if (this.hasProperty(propertyname) && this."$propertyname".hasProperty(subproperty)) {
            return this."$propertyname"."$subproperty"
        }
    }
}

Reportez-vous ensuite à vos propriétés comme vous le souhaitez:

def properties = "property1.property2"
assert someGroovyObject."$properties" == someValue

Ceci est automatiquement récursif, et vous n'avez pas à appeler explicitement une méthode. Ce n'est qu'un getteur, mais vous pouvez définir une deuxième version avec des paramètres pour créer un secteur également.

L'inconvénient est que, pour autant que je sache, vous ne pouvez définir qu'une seule version de propertyMissing, vous devez donc décider si la navigation de chemin dynamique est ce pour quoi vous souhaitez l'utiliser.

Voir

https://stackoverflow.com/a/15632027/2015517

Il utilise une syntaxe $ {} qui peut être utilisée dans le cadre de GString

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top