0

I'm creating a grid with a variable number of columns. I'm almost done but only one thing left... I cant access attribute Address (PersonProperties interface). I dont know how to write @Path properly. If anyone has any idea, Please give me advice.

I have this JSON: [ { "FirstName": "John", "LastName": "Doe", "Age": 23, "Details": [ { "Address": "Apt R113", "City": "Boston", "ZipCode": "30523" }, { "Address": "ABC 22", "City": "Paris", "ZipCode": "51112" } ] } ]

and then PropertyAccess interface:

public interface PersonProperties extends PropertyAccess<PersonDTO> {

ModelKeyProvider<PersonDTO> key();

ValueProvider<PersonDTO, String> FirstName();

ValueProvider<PersonDTO, String> LastName();

ValueProvider<PersonDTO, Integer> Age();

@Path("Details???Address")
ValueProvider<PersonDTO, String> Address();

}

ladinho10
  • 3
  • 1
  • Are you using AutoBeans to marshall the JSON into an object graph? Based on what you posted it looks like you're missing that step. – Bionic_Geek Dec 28 '12 at 13:31

1 Answers1

2

Assuming your PersonDTO object is the object representation of the JSON, I would assume you have an interface model (for using AutoBeans) which looks something like this:

// I'm leaving the setters out for brevity
public interface PersonDTO {
  @PropertyName(value="FirstName")
  String getFirstName();
  @PropertyName(value="LastName")
  String getLastName();
  @PropertyName(value="Age")
  Integer getAge();
  @PropertyName(value="Details")
  List<Details> getDetails();
}

public interface Details {
  @PropertyName(value="Address")
  String getAddress();
  @PropertyName(value="City")
  String getCity();
  @PropertyName(value="ZipCode")
  String getZipCode();
}

Assuming this maps to the interface model you are using (or closely approximates it), then to answer your question, that @Path annotation is used to specify the object attribute names to access a property (not the JSON names). So for single attributes, the path annotation can be used if your PropertyAccess value is not the same as the name of the attribute. In your example, your PersonProperties attributes are capitalized, so you can use something like this:

@Path("firstName")
ValueProvider<PersonDTO, String> FirstName();

If your Details object was just a single object then you could use notation similar to what you wrote (remember the @Path annotation is implicity specifying the getters to use to access the property from the object shim):

@Path("details.address")
ValueProvider<PersonDTO, String> address(); 
// would return the address if Details was a single object

However the Details values are a little different as your JSON example indicates that the Details values are actually a collection of Details. As a result your grid won't know how to display Details because there are multiple Details objects for every PersonDTO object. But I'm guessing that was already clear to you so let's assume that you are trying to display an address in a given row when certain conditions apply. In a case like that, you can implement your own ValueProvider. For example (dervied from a Sencha example I think):

public class AddressByCityValueProvider implements ValueProvider<PersonDTO, String> {
  public final String cityKey;

  public AddressByCityValueProvider(String specifiedKey) {
    this.cityKey = specifiedKey;
  }

  // we will display their Address if the city is Boston
  @Override
  public String getValue(PersonDTO person) {
    if (null != person.getDetails()) {
      for (Details detail : person.getDetails()) {
        if (detail.getCity().equalsIgnoreCase(cityKey)) {
          return detail.getAddress();
        }
      }
    }
    return ""; // no address for specified city in object, return a blank String
  }

  @Override
  public String getPath() {
    return key;
  }

Then where you were using the ValueProvider from your PropertyAccess class you will substitute your own ValueProvider and specify the key to use. For a Column Configuration, you could use this ValueProvider to return the street address when the city is Boston:

ColumnConfig<PersonDTO, String> addressColumn = 
   new ColumConfig<PersonDTO, String>(new AddressByCityValueProvider("Boston"), 100, "Address");

Obviously this is just one example but hopefully you get the idea.

Bionic_Geek
  • 536
  • 4
  • 24