1

I created the following method, which returns a HashMap<Date, List<Date>> where the key is a Date object and the value is a List of Date Objects. The method accepts a List of timeStamps and groups them by day. It then returns those grouped timestamps in the aforementioned HashMap construct.

 public class GroupDatesByDay {

    HashMap<Date, List<Date>> groupedUserLogins = new HashMap<Date, List<Date>>();
    Calendar cal = Calendar.getInstance();

    public HashMap<Date, List<Date>> parseTimeStamps(List<Date> timeStamps) {

    DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss.SSS", Locale.US);
    List<Date> timeStamps = new ArrayList<Date>();

        for (Date ts : timeStamps) {

            cal.setTime(ts);
            cal.set(cal.HOUR_OF_DAY, 0);
            cal.set(cal.MINUTE, 0);
            cal.set(cal.SECOND, 0);
            cal.set(cal.MILLISECOND, 0);

            if (!groupedUserLogins.containsKey(cal.getTime())) {

                groupedUserLogins.put(cal.getTime(), new ArrayList<Date>());
            }
            groupedUserLogins.get(cal.getTime()).add(ts);
        }

        keySet = groupedUserLogins.keySet();
        keyList.addAll(keySet);
        return groupedUserLogins;
    }
}

The data within the HashMap should look something like this:

Key                          List<Date> 

2018-07-11 
                  2018-07-11 08:14:08.540000 
                  2018-07-11 10:46:23.575000 

2018-07-12  
                  2018-07-12 12:51:48.928000 
                  2018-07-12 13:09:00.701000 
                  2018-07-12 16:04:45.890000 

2018-07-13 
                  2018-07-13 14:14:17.461000 

In my XHTML, I would like to display this data within a dataTable, and RowExpansion to see the individual timestamps, per day. I have written the following XHTML. As you can see, userLogins is what my Java method has returned. I am iterating over it in this dataTable, but I don't know how to display the values inside it in the manner described above.

<p:dataTable var="userLogin" value="#{userEdit.userLogins}"class="DataTable">
        <p:column headerText=" Recent Logins">
          <h:outputLabel value="#{userLogin}">
          </h:outputLabel>
        </p:column>
</p:dataTable>
Ebony Maw
  • 514
  • 7
  • 23
  • Have you tried this: https://stackoverflow.com/a/4735096/1199132 – Aritz Jul 14 '18 at 20:29
  • I omitted that to make my code look cleaner for StackOverflow. The question is about actually getting those values out of the Hashmap and displaying them. – Ebony Maw Jul 14 '18 at 22:28
  • You mean you want to iterate over the list? Use `ui:repeat` – Aritz Jul 15 '18 at 09:56
  • As per this: https://stackoverflow.com/a/8552872/2242047 - It's not possible. Please read my question in its entirety. I'm trying to use square-brackets to access the contents of my HashMap. The dataTable / column construct is already iterating over the values. – Ebony Maw Jul 15 '18 at 16:35
  • It is possible starting from JSF 2.2. The answer you link to was last modified 7 years ago, so you can't consider it anymore. But you don't mention the JSF impl/version being used. If you're still in JSF 2.0-2.1 I would recommend you to upgrade to 2.2, at least. If not, you can still consider using `Map#entrySet`. You're plenty of choices here. – Aritz Jul 15 '18 at 17:18
  • We are using PrimeFaces. I listed that as a tag in the original question. – Ebony Maw Jul 15 '18 at 18:03
  • Primefaces is a JSF component library. You're using JSF too.. Which version? – Aritz Jul 15 '18 at 18:18
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/176022/discussion-between-ebony-maw-and-xtreme-biker). – Ebony Maw Jul 15 '18 at 19:27
  • 2
    I know you guys took this offline but don't forget to post your final solution below. I didn't want to chime in but I typically avoid using Maps in JSF and write wrapper components that expose the map values as Lists. Just my two cents... – Melloware Jul 16 '18 at 14:24
  • @Melloware Here you go - I utilized your recommendation. Answer posted :) – Ebony Maw Jul 22 '18 at 00:50

1 Answers1

1

Here is how I finally solved it. As suggested by Melloware, I had to involve a List.

My implementation changed slightly:

private Hashtable<Date, List<Date>> groupedUserLogins = new Hashtable<Date, List<Date>>();
private Calendar cal = Calendar.getInstance();
private Set<Date> keySet = new TreeSet<Date>();
private List<Date> keyList = new ArrayList<Date>();

...

public Hashtable<Date, List<Date>> parseUserLogins(List<UserLogin> userLogins) {

        DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss.SSS", Locale.US);
        List<Date> timeStamps = new ArrayList<Date>();

        for (UserLogin u : userLogins) {
            timeStamps.add(u.getTimeStamp());
        }

        for (Date ts : timeStamps) {

            cal.setTime(ts);
            cal.set(cal.HOUR_OF_DAY, 0);
            cal.set(cal.MINUTE, 0);
            cal.set(cal.SECOND, 0);
            cal.set(cal.MILLISECOND, 0);
            dateFormat.format(ts);

            if (!groupedUserLogins.containsKey(cal.getTime())) {

                groupedUserLogins.put(cal.getTime(), new ArrayList<Date>());
            }
            groupedUserLogins.get(cal.getTime()).add(ts);
        }

        keySet = groupedUserLogins.keySet();
        keyList.addAll(keySet);
        return groupedUserLogins;
    }

My XHTML:

<p:dataTable var="loginDayDate" value="#{userEdit.keyList}"
    sortOrder="descending" sortBy="#{loginDayDate}" class="DataTable">

    <p:column width="15">
        <p:rowToggler />
    </p:column>

    <p:column headerText=" Recent Logins" width="110"
        sortBy="#{loginDayDate}">

        <h:outputLabel value="#{loginDayDate}">
            <f:convertDateTime pattern="#{Constants.DATE_FORMAT}" />

        </h:outputLabel>
    </p:column>
    <p:column headerText=" # of Logins" style="text-align : left">
        #{fn:length(userEdit.groupedUserLogins[loginDayDate])}
    </p:column>
    <p:rowExpansion>
        <p:dataTable var="specificDate"
            value="#{userEdit.groupedUserLogins[loginDayDate]}"
            class="DataTable">
            <p:column headerText="Time" style="text-align: left">
                <h:outputLabel value="#{specificDate}">
                    <f:convertDateTime pattern="#{Constants.DATETIME_FORMAT}" />
                </h:outputLabel>
            </p:column>
        </p:dataTable>
    </p:rowExpansion>
</p:dataTable>

How it looks:

enter image description here

Ebony Maw
  • 514
  • 7
  • 23