notification-portlet-webapp/src/main/java/org/jasig/portlet/notice/service/ssp/SSPTaskNotificationService.java
private NotificationEntry mapNotificationEntry(ReadContext readContext, int index, String source) {
        boolean completed = readContext.read(format(ROW_COMPLETED_QUERY_FMT, index), Boolean.class);
        if (completed) {
            return null;
        }

        NotificationEntry entry = new NotificationEntry();
        entry.setSource(source);

        String id = readContext.read(format(ROW_ID_QUERY_FMT, index));
        entry.setId(id);

        String title = readContext.read(format(ROW_NAME_QUERY_FMT, index));
        entry.setTitle(title);

        String desc = readContext.read(format(ROW_DESCRIPTION_QUERY_FMT, index));
        entry.setBody(desc);

        String link = readContext.read(format(ROW_LINK_QUERY_FMT, index));
        URL fixedLink = normalizeLink(link);
        if (fixedLink != null) {
            entry.setUrl(fixedLink.toExternalForm());
        }

        Date createDate = readContext.read(format("$.rows[%d].createdDate", index), Date.class);
        Map<NotificationState, Date> states = new HashMap<>();
        states.put(NotificationState.ISSUED, createDate);

        try {
            // the date is in an odd format, need to parse by hand...
            String dateStr = readContext.read(format(ROW_DUE_DATE_QUERY_FMT, index));
            if (!StringUtils.isBlank(dateStr)) {
                synchronized (dateFormat) {
                    Date dueDate = dateFormat.parse(dateStr);
                    entry.setDueDate(dueDate);
                }
            }
        } catch (Exception e) {
            log.warn("Error parsing due date.  Ignoring", e);
        }


        return entry;
    }
private NotificationEntry mapNotificationEntry(ReadContext readContext, int index, String source) {
        boolean completed = readContext.read(format(ROW_COMPLETED_QUERY_FMT, index), Boolean.class);
        if (completed) {
            return null;
        }

        NotificationEntry entry = new NotificationEntry();
        entry.setSource(source);

        String id = readContext.read(format(ROW_ID_QUERY_FMT, index));
        entry.setId(id);

        String title = readContext.read(format(ROW_NAME_QUERY_FMT, index));
        entry.setTitle(title);

        String desc = readContext.read(format(ROW_DESCRIPTION_QUERY_FMT, index));
        entry.setBody(desc);

        String link = readContext.read(format(ROW_LINK_QUERY_FMT, index));
        URL fixedLink = normalizeLink(link);
        if (fixedLink != null) {
            entry.setUrl(fixedLink.toExternalForm());
        }

        Date createDate = readContext.read(format("$.rows[%d].createdDate", index), Date.class);
        Map<NotificationState, Date> states = new HashMap<>();
        states.put(NotificationState.ISSUED, createDate);

        try {
            // the date is in an odd format, need to parse by hand...
            String dateStr = readContext.read(format(ROW_DUE_DATE_QUERY_FMT, index));
            if (!StringUtils.isBlank(dateStr)) {
                synchronized (dateFormat) {
                    Date dueDate = dateFormat.parse(dateStr);
                    entry.setDueDate(dueDate);
                }
            }
        } catch (Exception e) {
            log.warn("Error parsing due date.  Ignoring", e);
        }


        return entry;
    }
Map a single notification entry.

@param readContext the parsed JSON from SSP
@param index the index of the current entry to read
@param source the source value to use for the entry
@return a new Notification Entry.  May return null if the entry is invalid or complete