View Javadoc
1   /*
2    * Copyright 2014 James Pether Sörling
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *   http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   *
16   *	$Id$
17   *  $HeadURL$
18  */
19  package com.hack23.cia.web.impl.ui.application.views.common.chartfactory.impl;
20  
21  import java.util.Collections;
22  import java.util.Comparator;
23  import java.util.Date;
24  import java.util.List;
25  import java.util.Map;
26  import java.util.Map.Entry;
27  import java.util.SortedSet;
28  import java.util.TreeMap;
29  import java.util.TreeSet;
30  import java.util.function.Function;
31  import java.util.stream.Collectors;
32  
33  import org.joda.time.DateTime;
34  import org.tltv.gantt.Gantt;
35  import org.tltv.gantt.client.shared.Resolution;
36  import org.tltv.gantt.client.shared.Step;
37  import org.tltv.gantt.client.shared.SubStep;
38  
39  import com.hack23.cia.web.impl.ui.application.views.common.sizing.ContentRatio;
40  import com.vaadin.server.Sizeable.Unit;
41  import com.vaadin.ui.VerticalLayout;
42  
43  /**
44   * The Class AbstractGhantChartManagerImpl.
45   *
46   * @param <T>
47   *            the generic type
48   */
49  public abstract class AbstractGhantChartManagerImpl<T extends Object> {
50  
51  	/** The Constant PARTY_END_TAG. */
52  	private static final char PARTY_END_TAG = ')';
53  
54  	/** The Constant PARTY_START_TAG. */
55  	private static final String PARTY_START_TAG = " (";
56  
57  	/** The Constant CONTENT_SEPARATOR. */
58  	private static final char CONTENT_SEPARATOR = ' ';
59  
60  	/** The Constant FILTER_DATA_BEFORE_YEAR. */
61  	private static final int FILTER_DATA_BEFORE_YEAR = 2000;
62  
63  	/**
64  	 * Instantiates a new abstract ghant chart manager impl.
65  	 */
66  	public AbstractGhantChartManagerImpl() {
67  		super();
68  	}
69  
70  	/**
71  	 * Creates the role ghant.
72  	 *
73  	 * @param roleSummaryLayoutTabsheet
74  	 *            the role summary layout tabsheet
75  	 * @param assignmentList
76  	 *            the assignment list
77  	 */
78  	public final void createRoleGhant(final VerticalLayout roleSummaryLayoutTabsheet, final List<T> assignmentList) {
79  
80  		final Comparator<T> compare = getComparator();
81  
82  		final List<T> list = assignmentList.stream().filter(
83  				x -> new DateTime(getStepMapping().getFromDate(x).getTime()).getYear() > FILTER_DATA_BEFORE_YEAR)
84  				.collect(Collectors.toList());
85  
86  		Collections.sort(list, compare);
87  
88  		final Gantt createGantt = createGenericGantt(list, getRoleMapping(), getStepMapping());
89  		roleSummaryLayoutTabsheet.addComponent(createGantt);
90  		roleSummaryLayoutTabsheet.setExpandRatio(createGantt, ContentRatio.GRID);
91  
92  	}
93  
94  	/**
95  	 * Gets the comparator.
96  	 *
97  	 * @return the comparator
98  	 */
99  	protected abstract Comparator<T> getComparator();
100 
101 	/**
102 	 * Gets the role mapping.
103 	 *
104 	 * @return the role mapping
105 	 */
106 	protected abstract Function<T, String> getRoleMapping();
107 
108 	/**
109 	 * Gets the step mapping.
110 	 *
111 	 * @return the step mapping
112 	 */
113 	protected abstract StepMapping<T> getStepMapping();
114 
115 	/**
116 	 * Creates the generic gantt.
117 	 *
118 	 * @param assignmentList
119 	 *            the assignment list
120 	 * @param roleMapping
121 	 *            the role mapping
122 	 * @param stepMapping
123 	 *            the step mapping
124 	 * @return the gantt
125 	 */
126 	private Gantt createGenericGantt(final List<T> assignmentList, final Function<T, String> roleMapping,
127 			final StepMapping<T> stepMapping) {
128 
129 		final Map<String, List<T>> assignmentListMap = assignmentList.stream()
130 				.collect(Collectors.groupingBy(roleMapping, TreeMap::new, Collectors.toList()));
131 
132 		final Gantt gantt = createGantt();
133 
134 		if (!assignmentList.isEmpty()) {
135 
136 			gantt.setStartDate(stepMapping.getFromDate(assignmentList.get(0)));
137 			gantt.setEndDate(
138 					stripDatesAfterCurrentDate(stepMapping.getToDate(assignmentList.get(assignmentList.size() - 1))));
139 
140 			for (final Entry<String, List<T>> entry : entriesSortedByValues(assignmentListMap, stepMapping)) {
141 
142 				final String stepName = entry.getKey();
143 
144 				final Step step = new Step();
145 				step.setDescription(stepName);
146 
147 				final List<T> assignments = entry.getValue();
148 
149 				Collections.sort(assignments, getComparator());
150 
151 				addViewGenericRoleMemberToStep(stepName, step, assignments, stepMapping);
152 
153 				gantt.addStep(step);
154 			}
155 		}
156 
157 		return gantt;
158 	}
159 
160 	/**
161 	 * Entries sorted by values.
162 	 *
163 	 * @param map
164 	 *            the map
165 	 * @param stepMapping
166 	 *            the step mapping
167 	 * @return the sorted set
168 	 */
169 	private SortedSet<Map.Entry<String, List<T>>> entriesSortedByValues(final Map<String, List<T>> map,
170 			final StepMapping<T> stepMapping) {
171 		final Comparator<? super Entry<String, List<T>>> compare = (o1, o2) -> {
172 
173 			final Comparator<T> compare1 = (o11, o21) -> {
174 				final int compareDate = stepMapping.getFromDate(o11).compareTo(stepMapping.getFromDate(o21));
175 				if (compareDate == 0) {
176 					final int compareType = stepMapping.getRoleCode(o11).compareTo(stepMapping.getRoleCode(o21));
177 					if (compareType == 0) {
178 						return stepMapping.getOrg(o11).compareTo(stepMapping.getOrg(o21));
179 					} else {
180 						return compareType;
181 					}
182 				}
183 
184 				return compareDate;
185 			};
186 
187 			Collections.sort(o1.getValue(), compare1);
188 			Collections.sort(o2.getValue(), compare1);
189 
190 			return compare1.compare(o1.getValue().get(0), o2.getValue().get(0));
191 		};
192 
193 		final SortedSet<Map.Entry<String, List<T>>> sortedEntries = new TreeSet<>(compare);
194 		sortedEntries.addAll(map.entrySet());
195 		return sortedEntries;
196 	}
197 
198 	/**
199 	 * Adds the view generic role member to step.
200 	 *
201 	 * @param stepName
202 	 *            the step name
203 	 * @param step
204 	 *            the step
205 	 * @param assignments
206 	 *            the assignments
207 	 * @param stepMapping
208 	 *            the step mapping
209 	 */
210 	private void addViewGenericRoleMemberToStep(final String stepName, final Step step, final List<T> assignments,
211 			final StepMapping<T> stepMapping) {
212 
213 		for (final T assignmentData : assignments) {
214 
215 			String subStepName = "";
216 
217 			if (stepMapping.getRoleCode(assignmentData) != null) {
218 				subStepName = new StringBuilder().append(stepMapping.getFirstName(assignmentData))
219 						.append(CONTENT_SEPARATOR).append(stepMapping.getLastName(assignmentData))
220 						.append(PARTY_START_TAG).append(stepMapping.getParty(assignmentData)).append(PARTY_END_TAG)
221 						.toString();
222 			}
223 
224 			final SubStep sameRoleSubStep = new SubStep(stepName + '.' + subStepName);
225 
226 			sameRoleSubStep.setBackgroundColor(stepMapping.getBackgroundColor(assignmentData));
227 
228 			sameRoleSubStep.setStartDate(stepMapping.getFromDate(assignmentData).getTime());
229 			sameRoleSubStep.setEndDate(stripDatesAfterCurrentDate(stepMapping.getToDate(assignmentData)).getTime());
230 
231 			step.addSubStep(sameRoleSubStep);
232 		}
233 	}
234 
235 	/**
236 	 * Strip dates after current date.
237 	 *
238 	 * @param toDate
239 	 *            the to date
240 	 * @return the date
241 	 */
242 	private static final Date stripDatesAfterCurrentDate(final Date toDate) {
243 		final DateTime currentTime = new DateTime();
244 
245 		if (currentTime.isBefore(toDate.getTime())) {
246 			return currentTime.plusDays(1).toDate();
247 		} else {
248 			return toDate;
249 		}
250 	}
251 
252 	/**
253 	 * Creates the gantt.
254 	 *
255 	 * @return the gantt
256 	 */
257 	private static final Gantt createGantt() {
258 		final Gantt gantt = new Gantt();
259 		gantt.setSizeFull();
260 		gantt.setWidth(100, Unit.PERCENTAGE);
261 		gantt.setHeight(100, Unit.PERCENTAGE);
262 		gantt.setResizableSteps(false);
263 		gantt.setMovableSteps(false);
264 		gantt.setResolution(Resolution.Week);
265 		return gantt;
266 	}
267 
268 	/**
269 	 * The Interface StepMapping.
270 	 *
271 	 * @param <T>
272 	 *            the generic type
273 	 */
274 	public interface StepMapping<T> {
275 
276 		/**
277 		 * Gets the from date.
278 		 *
279 		 * @param t
280 		 *            the t
281 		 * @return the from date
282 		 */
283 		Date getFromDate(T t);
284 
285 		/**
286 		 * Gets the to date.
287 		 *
288 		 * @param t
289 		 *            the t
290 		 * @return the to date
291 		 */
292 		Date getToDate(T t);
293 
294 		/**
295 		 * Gets the role code.
296 		 *
297 		 * @param t
298 		 *            the t
299 		 * @return the role code
300 		 */
301 		String getRoleCode(T t);
302 
303 		/**
304 		 * Gets the org.
305 		 *
306 		 * @param t
307 		 *            the t
308 		 * @return the org
309 		 */
310 		String getOrg(T t);
311 
312 		/**
313 		 * Gets the party.
314 		 *
315 		 * @param t
316 		 *            the t
317 		 * @return the party
318 		 */
319 		String getParty(T t);
320 
321 		/**
322 		 * Gets the background color.
323 		 *
324 		 * @param t
325 		 *            the t
326 		 * @return the background color
327 		 */
328 		String getBackgroundColor(T t);
329 
330 		/**
331 		 * Gets the first name.
332 		 *
333 		 * @param assignmentData
334 		 *            the assignment data
335 		 * @return the first name
336 		 */
337 		Object getFirstName(T assignmentData);
338 
339 		/**
340 		 * Gets the last name.
341 		 *
342 		 * @param assignmentData
343 		 *            the assignment data
344 		 * @return the last name
345 		 */
346 		Object getLastName(T assignmentData);
347 
348 	}
349 
350 }