0

As the title suggests, I'm trying to add information held in one JsonBuilder object to a second JsonBuilder object.

Currently I have this:

public String buildOneUser(DyveUserDTO user)
{
    def userBuilder = new JsonBuilder()
        userBuilder user.collect { usr ->
            [
                    'Name': usr.userName,
                    'Allowance': usr.allowance,
                    'Total Holidays in Calendar': usr.totalHolidaysInCal,
                    'Holidays Booked': usr.numHolidaysBooked,
                    'Holidays Taken': usr.numHolidaysTaken,
                    'Holidays Remaining': usr.totalHolidaysLeft
            ]
        }

    def userHolidayBuilder = new JsonBuilder()
        userHolidayBuilder user.holidayEvents.collect { usr ->
            [
                    'Start Date': usr.startDate,
                    'End Date': usr.endDate,
                    'Days': usr.days
            ]
        }

    def userAndHolidays = userBuilder + userHolidayBuilder

    return userAndHolidays.toPrettyString()
}

user.holidayEvents is a list of objects representing holidays and it could be empty or have any number of objects in it. This made me hesitant of doing something like:

def userBuilder = new JsonBuilder()
        userBuilder user.collect { usr ->
            [
                    'Name': usr.userName,
                    'Allowance': usr.allowance,
                    'Total Holidays in Calendar': usr.totalHolidaysInCal,
                    'Holidays Booked': usr.numHolidaysBooked,
                    'Holidays Taken': usr.numHolidaysTaken,
                    'Holidays Remaining': usr.totalHolidaysLeft
                    'Holiday': usr.holidayEvents[0].startDate
                    'Holiday': usr.holidayEvents[0].endDate
                    'Holiday': usr.holidayEvents[0].days
            ]
        }

As I would only get the amount of holidays I write code for. It would also throw an exception if a user had no holidays and I told it look at usr.holidayEvents[1] as it's outside of the list range.

I've also tried nesting a .collect like this

def userBuilder = new JsonBuilder()
        userBuilder {
           'Name' user.userName,
           'Allowance' user.allowance,
           'Total Holidays in Calendar' user.totalHolidaysInCal,
           'Holidays Booked' user.numHolidaysBooked,
           'Holidays Taken' user.numHolidaysTaken,
           'Holidays Remaining' user.totalHolidaysLeft,
           'Holidays' user.holidayEvents.collect{ evt ->
               [
                  'Start Date': evt.startDate,
                  'End Date': evt.endDate,
                  'Days': evt.days
               ]
            }
        }

But this returned all the keys except the Holidays key.

Any help would be greatly appreciated!

EDIT - My code now looks like this:

public String buildOneUser(DyveUserDTO user)
{
    def userBuilder = new JsonBuilder()
        userBuilder user.collect { usr ->
            [
                    'Name': usr.userName,
                    'Allowance': usr.allowance,
                    'Total Holidays in Calendar': usr.totalHolidaysInCal,
                    'Holidays Booked': usr.numHolidaysBooked,
                    'Holidays Taken': usr.numHolidaysTaken,
                    'Holidays Remaining': usr.totalHolidaysLeft,
                    'Holidays': usr.holidayEvents.collect{ evt ->
                        [
                                'Start Date': evt.startDate,
                                'End Date': evt.endDate,
                                'Days': evt.days
                        ]
                    }
            ]
        }
}

EDIT 2 - Sample Code

Method to call:

public String buildOneUser(DyveUserDTO user)
{
    def userBuilder = new JsonBuilder()
    userBuilder {
        Name:
        user.userName
        Allowance:
        user.allowance
        TotalHolidaysInCalendar:
        user.totalHolidaysInCal
        HolidaysBooked:
        user.numHolidaysBooked
        HolidaysTaken:
        user.numHolidaysTaken
        HolidaysRemaining:
        user.totalHolidaysLeft
        Holidays:
        user.holidayEvents.collect { evt ->
            [
                    'Start Date': evt.startDate,
                    'End Date'  : evt.endDate,
                    'Days'      : evt.days
            ]
        }
    }

    return userBuilder.toPrettyString()
}

User to pass in:

class DyveUserDTO
{
    String firstName = "Foo"
    String userName = "FooBar"
    Integer userID = 42
    BigDecimal numHolidaysBooked = 3
    BigDecimal numHolidaysTaken = 0
    BigDecimal totalHolidaysInCal = 3
    BigDecimal totalHolidaysLeft = 12
    BigDecimal allowance = 12
    List<HolidayObject> holidayEvents = []

}

Holiday objects to go in holidayEvents:

class HolidayObject
{
    public Integer userID = 42
    public String title = "Foo Holiday"
    public String event = "Holiday"
    public String amPm = "Full Day"
    public String name = "Foo"
    public LocalDateTime startDate = LocalDateTime.parse(2015-02-20T00:00:00)
    public LocalDateTime endDate = LocalDateTime.parse(2015-02-20T00:00:00)
    public BigDecimal days = 1
}

class HolidayObject
{
    public Integer userID = 42
    public String title = "Foo Holiday Pm"
    public String event = "Holiday"
    public String amPm = "Pm"
    public String name = "Foo"
    public LocalDateTime startDate = LocalDateTime.parse(2015-02-23T00:00:00)
    public LocalDateTime endDate = LocalDateTime.parse(2015-02-24T00:00:00)
    public BigDecimal days = 2
}

1 Answers1

0

each just returns the list it's called upon, collect should be used for events. See the working code below:

import groovy.json.JsonBuilder

class UserEvent {
    def start
    def end
    def days
}

class User {
    def name
    def events
}

def u1 = new User(name: 'u1', events: [new UserEvent(start: 0, end: 1, days: 1), new UserEvent(start: 0, end: 2, days: 2)])
def u2 = new User(name: 'u2', events: [new UserEvent(start: 0, end: 3, days: 3)])

def users = [u1, u2]

def userBuilder = new JsonBuilder()
userBuilder users.collect { usr ->
   [
      'name': usr.name,   
      'events': usr.events.collect { e ->
         [
            start: e.start,
            end: e.end,
            days: e.days,
         ]
       }                   
    ]
}

print  userBuilder.toPrettyString()

EDIT

Below is a working example:

import groovy.json.JsonBuilder

user = new DyveUserDTO()

def userBuilder = new JsonBuilder()
    userBuilder {
        Name user.userName
        Allowance user.allowance
        TotalHolidaysInCalendar user.totalHolidaysInCal
        HolidaysBooked user.numHolidaysBooked
        HolidaysTaken user.numHolidaysTaken
        HolidaysRemaining user.totalHolidaysLeft
        Holidays user.holidayEvents.collect { evt ->
            [
                    'Start Date': evt.startDate,
                    'End Date'  : evt.endDate,
                    'Days'      : evt.days
            ]
        }
    }

println userBuilder.toPrettyString()

class DyveUserDTO {
    String firstName = "Foo"
    String userName = "FooBar"
    Integer userID = 42
    BigDecimal numHolidaysBooked = 3
    BigDecimal numHolidaysTaken = 0
    BigDecimal totalHolidaysInCal = 3
    BigDecimal totalHolidaysLeft = 12
    BigDecimal allowance = 12
    List<HolidayObject> holidayEvents = [new HolidayObject(), new HolidayObject()]
}

class HolidayObject {
    public Integer userID = 42
    public String title = "Foo Holiday"
    public String event = "Holiday"
    public String amPm = "Full Day"
    public String name = "Foo"
    public String startDate = '2015-02-20T00:00:00'
    public String endDate = '2015-02-20T00:00:00'
    public BigDecimal days = 1
}

No colons : needed. See the sample here. Also I have no Joda dependency so replaced with String.

Opal
  • 81,889
  • 28
  • 189
  • 210
  • I've removed the colons but it's still not picking up the Holidays key. I feel this probably warrants a new question rather than discussing it here. I'll accept your answer as it DOES work, I've tested it independently of my code, it just won't work with my code. Thanks anyway! – Supergoat21 Feb 20 '15 at 15:27