AbstractGhantChartManagerImpl.java
/*
* Copyright 2014 James Pether Sörling
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Id$
* $HeadURL$
*/
package com.hack23.cia.web.impl.ui.application.views.common.chartfactory.impl;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.joda.time.DateTime;
import org.tltv.gantt.Gantt;
import org.tltv.gantt.client.shared.Resolution;
import org.tltv.gantt.client.shared.Step;
import org.tltv.gantt.client.shared.SubStep;
import com.hack23.cia.web.impl.ui.application.views.common.sizing.ContentRatio;
import com.vaadin.server.Sizeable.Unit;
import com.vaadin.ui.VerticalLayout;
/**
* The Class AbstractGhantChartManagerImpl.
*
* @param <T>
* the generic type
*/
public abstract class AbstractGhantChartManagerImpl<T extends Object> {
/** The Constant PARTY_END_TAG. */
private static final char PARTY_END_TAG = ')';
/** The Constant PARTY_START_TAG. */
private static final String PARTY_START_TAG = " (";
/** The Constant CONTENT_SEPARATOR. */
private static final char CONTENT_SEPARATOR = ' ';
/** The Constant FILTER_DATA_BEFORE_YEAR. */
private static final int FILTER_DATA_BEFORE_YEAR = 2000;
/**
* Instantiates a new abstract ghant chart manager impl.
*/
public AbstractGhantChartManagerImpl() {
super();
}
/**
* Creates the role ghant.
*
* @param roleSummaryLayoutTabsheet
* the role summary layout tabsheet
* @param assignmentList
* the assignment list
*/
public final void createRoleGhant(final VerticalLayout roleSummaryLayoutTabsheet, final List<T> assignmentList) {
final Comparator<T> compare = getComparator();
final List<T> list = assignmentList.stream().filter(
x -> new DateTime(getStepMapping().getFromDate(x).getTime()).getYear() > FILTER_DATA_BEFORE_YEAR)
.collect(Collectors.toList());
Collections.sort(list, compare);
final Gantt createGantt = createGenericGantt(list, getRoleMapping(), getStepMapping());
roleSummaryLayoutTabsheet.addComponent(createGantt);
roleSummaryLayoutTabsheet.setExpandRatio(createGantt, ContentRatio.GRID);
}
/**
* Gets the comparator.
*
* @return the comparator
*/
protected abstract Comparator<T> getComparator();
/**
* Gets the role mapping.
*
* @return the role mapping
*/
protected abstract Function<T, String> getRoleMapping();
/**
* Gets the step mapping.
*
* @return the step mapping
*/
protected abstract StepMapping<T> getStepMapping();
/**
* Creates the generic gantt.
*
* @param assignmentList
* the assignment list
* @param roleMapping
* the role mapping
* @param stepMapping
* the step mapping
* @return the gantt
*/
private Gantt createGenericGantt(final List<T> assignmentList, final Function<T, String> roleMapping,
final StepMapping<T> stepMapping) {
final Map<String, List<T>> assignmentListMap = assignmentList.stream()
.collect(Collectors.groupingBy(roleMapping, TreeMap::new, Collectors.toList()));
final Gantt gantt = createGantt();
if (!assignmentList.isEmpty()) {
gantt.setStartDate(stepMapping.getFromDate(assignmentList.get(0)));
gantt.setEndDate(
stripDatesAfterCurrentDate(stepMapping.getToDate(assignmentList.get(assignmentList.size() - 1))));
for (final Entry<String, List<T>> entry : entriesSortedByValues(assignmentListMap, stepMapping)) {
final String stepName = entry.getKey();
final Step step = new Step();
step.setDescription(stepName);
final List<T> assignments = entry.getValue();
Collections.sort(assignments, getComparator());
addViewGenericRoleMemberToStep(stepName, step, assignments, stepMapping);
gantt.addStep(step);
}
}
return gantt;
}
/**
* Entries sorted by values.
*
* @param map
* the map
* @param stepMapping
* the step mapping
* @return the sorted set
*/
private SortedSet<Map.Entry<String, List<T>>> entriesSortedByValues(final Map<String, List<T>> map,
final StepMapping<T> stepMapping) {
final Comparator<? super Entry<String, List<T>>> compare = (o1, o2) -> {
final Comparator<T> compare1 = (o11, o21) -> {
final int compareDate = stepMapping.getFromDate(o11).compareTo(stepMapping.getFromDate(o21));
if (compareDate == 0) {
final int compareType = stepMapping.getRoleCode(o11).compareTo(stepMapping.getRoleCode(o21));
if (compareType == 0) {
return stepMapping.getOrg(o11).compareTo(stepMapping.getOrg(o21));
} else {
return compareType;
}
}
return compareDate;
};
Collections.sort(o1.getValue(), compare1);
Collections.sort(o2.getValue(), compare1);
return compare1.compare(o1.getValue().get(0), o2.getValue().get(0));
};
final SortedSet<Map.Entry<String, List<T>>> sortedEntries = new TreeSet<>(compare);
sortedEntries.addAll(map.entrySet());
return sortedEntries;
}
/**
* Adds the view generic role member to step.
*
* @param stepName
* the step name
* @param step
* the step
* @param assignments
* the assignments
* @param stepMapping
* the step mapping
*/
private void addViewGenericRoleMemberToStep(final String stepName, final Step step, final List<T> assignments,
final StepMapping<T> stepMapping) {
for (final T assignmentData : assignments) {
String subStepName = "";
if (stepMapping.getRoleCode(assignmentData) != null) {
subStepName = new StringBuilder().append(stepMapping.getFirstName(assignmentData))
.append(CONTENT_SEPARATOR).append(stepMapping.getLastName(assignmentData))
.append(PARTY_START_TAG).append(stepMapping.getParty(assignmentData)).append(PARTY_END_TAG)
.toString();
}
final SubStep sameRoleSubStep = new SubStep(stepName + '.' + subStepName);
sameRoleSubStep.setBackgroundColor(stepMapping.getBackgroundColor(assignmentData));
sameRoleSubStep.setStartDate(stepMapping.getFromDate(assignmentData).getTime());
sameRoleSubStep.setEndDate(stripDatesAfterCurrentDate(stepMapping.getToDate(assignmentData)).getTime());
step.addSubStep(sameRoleSubStep);
}
}
/**
* Strip dates after current date.
*
* @param toDate
* the to date
* @return the date
*/
private static final Date stripDatesAfterCurrentDate(final Date toDate) {
final DateTime currentTime = new DateTime();
if (currentTime.isBefore(toDate.getTime())) {
return currentTime.plusDays(1).toDate();
} else {
return toDate;
}
}
/**
* Creates the gantt.
*
* @return the gantt
*/
private static final Gantt createGantt() {
final Gantt gantt = new Gantt();
gantt.setSizeFull();
gantt.setWidth(100, Unit.PERCENTAGE);
gantt.setHeight(100, Unit.PERCENTAGE);
gantt.setResizableSteps(false);
gantt.setMovableSteps(false);
gantt.setResolution(Resolution.Week);
return gantt;
}
/**
* The Interface StepMapping.
*
* @param <T>
* the generic type
*/
public interface StepMapping<T> {
/**
* Gets the from date.
*
* @param t
* the t
* @return the from date
*/
Date getFromDate(T t);
/**
* Gets the to date.
*
* @param t
* the t
* @return the to date
*/
Date getToDate(T t);
/**
* Gets the role code.
*
* @param t
* the t
* @return the role code
*/
String getRoleCode(T t);
/**
* Gets the org.
*
* @param t
* the t
* @return the org
*/
String getOrg(T t);
/**
* Gets the party.
*
* @param t
* the t
* @return the party
*/
String getParty(T t);
/**
* Gets the background color.
*
* @param t
* the t
* @return the background color
*/
String getBackgroundColor(T t);
/**
* Gets the first name.
*
* @param assignmentData
* the assignment data
* @return the first name
*/
Object getFirstName(T assignmentData);
/**
* Gets the last name.
*
* @param assignmentData
* the assignment data
* @return the last name
*/
Object getLastName(T assignmentData);
}
}