1. Project Clover database Sat Feb 2 2019 06:45:20 CET
  2. Package org.xwiki.notifications.notifiers.internal.email

File EventsSorter.java

 

Coverage histogram

../../../../../../img/srcFileCovDistChart9.png
41% of files have more coverage

Code metrics

28
52
7
1
167
106
22
0.42
7.43
7
3.14

Classes

Class Line # Actions
EventsSorter 37 52 0% 22 16
0.8160919581.6%
 

Contributing tests

This file is covered by 1 test. .

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package org.xwiki.notifications.notifiers.internal.email;
21   
22    import java.util.ArrayList;
23    import java.util.Collections;
24    import java.util.Comparator;
25    import java.util.HashMap;
26    import java.util.List;
27    import java.util.Map;
28   
29    import org.xwiki.notifications.CompositeEvent;
30   
31    /**
32    * Sort composite events (wrapped by {@link SortedEvent}) so that it is easy to display a table of content in the email.
33    *
34    * @version $Id: 9e839cff1b392a79741d2befb81b604f53b0c7f5 $
35    * @since 9.11RC1
36    */
 
37    public class EventsSorter
38    {
39    private List<SortedEvent> sortedEvents = new ArrayList<>();
40   
41    /**
42    * Add a new event to take into account.
43    *
44    * @param event event to add
45    * @param html the HTML-rendered version of the event
46    * @param plainText the plain text-rendered version of the event
47    */
 
48  4 toggle public void add(CompositeEvent event, String html, String plainText)
49    {
50  4 sortedEvents.add(new SortedEvent(event, html, plainText));
51    }
52   
53    /**
54    * @return a map of sorted events, grouped by wiki
55    */
 
56  3 toggle public Map<String, List<SortedEvent>> sort()
57    {
58    // Sort the top level events, that have no parent
59  3 Collections.sort(sortedEvents, getSortedEventComparator());
60   
61    // Group sorted events that concern the same document
62  3 groupEventsWithSameDocument();
63   
64    // Here we are going to store only events that have no parent
65  3 List<SortedEvent> topLevelEvents = new ArrayList<>();
66    // Group events so that children are stored in their parent
67  3 for (SortedEvent sortedEvent : sortedEvents) {
68  4 SortedEvent nearestParent = findNearestParent(sortedEvent);
69  4 if (nearestParent != null) {
70  0 nearestParent.addChild(sortedEvent);
71    } else {
72  4 topLevelEvents.add(sortedEvent);
73    }
74    }
75   
76    // Replace the inner list by the hierarchy
77  3 this.sortedEvents = topLevelEvents;
78   
79    // Create a map of sorted events, grouped by wiki
80  3 Map<String, List<SortedEvent>> sortedEventsByWikis = new HashMap<>();
81  3 for (SortedEvent sortedEvent: sortedEvents) {
82  4 String wiki = getWiki(sortedEvent);
83  4 List<SortedEvent> list = getList(sortedEventsByWikis, wiki);
84  4 list.add(sortedEvent);
85    }
86  3 return sortedEventsByWikis;
87    }
88   
 
89  3 toggle private Comparator<SortedEvent> getSortedEventComparator()
90    {
91    // Sort by document first (if document == null, go last)
92    // Sort by date (more recent first) then, when document is the same
93  3 return (e1, e2) -> {
94  1 if (e1.getDocument() == null) {
95  0 return e2.getDocument() == null ? 0 : 1;
96    }
97  1 if (e2.getDocument() == null) {
98  0 return -1;
99    }
100  1 int documentSort = e1.getDocument().compareTo(e2.getDocument());
101  1 if (documentSort == 0) {
102  0 return e2.getDate().compareTo(e1.getDate());
103    }
104  1 return documentSort;
105    };
106    }
107   
 
108  4 toggle private String getWiki(SortedEvent sortedEvent)
109    {
110  4 return sortedEvent.getEvent().getDocument() != null
111    ? sortedEvent.getEvent().getDocument().getWikiReference().getName()
112    : "";
113    }
114   
 
115  4 toggle private SortedEvent findNearestParent(SortedEvent sortedEvent)
116    {
117  4 if (sortedEvent.getEvent().getDocument() == null) {
118  2 return null;
119    }
120   
121  2 SortedEvent nearestParent = null;
122  2 int nearestParentLevel = 0;
123   
124  2 for (SortedEvent possibleParent : sortedEvents) {
125  4 if (possibleParent == sortedEvent) {
126  2 continue;
127    }
128  2 if (possibleParent.isParent(sortedEvent)
129    && possibleParent.getEvent().getDocument().size() > nearestParentLevel) {
130  0 nearestParent = possibleParent;
131  0 nearestParentLevel = possibleParent.getEvent().getDocument().size();
132    }
133    }
134  2 return nearestParent;
135    }
136   
 
137  4 toggle private List<SortedEvent> getList(Map<String, List<SortedEvent>> sortedEventsByWikis, String wiki)
138    {
139  4 List<SortedEvent> list = sortedEventsByWikis.get(wiki);
140  4 if (list == null) {
141  3 list = new ArrayList<>();
142  3 sortedEventsByWikis.put(wiki, list);
143    }
144  4 return list;
145    }
146   
 
147  3 toggle private void groupEventsWithSameDocument()
148    {
149  7 for (int i = 0; i < sortedEvents.size(); ++i) {
150  4 SortedEvent event = sortedEvents.get(i);
151   
152  4 if (event.getDocument() != null) {
153    // We start at (i + 1) because the sortedEvents list is ordered
154  2 int j = i + 1;
155  3 while (j < sortedEvents.size()) {
156  1 SortedEvent otherEvent = sortedEvents.get(j);
157  1 if (event.getDocument().equals(otherEvent.getDocument())) {
158  0 event.addEventWithTheSameDocument(otherEvent);
159  0 sortedEvents.remove(j);
160    } else {
161  1 ++j;
162    }
163    }
164    }
165    }
166    }
167    }