Update Commons Lang.

Code refactoring.
This commit is contained in:
Vova Perebykivskyi 2016-04-29 15:31:01 +03:00 committed by Dgray16
parent 3852c49972
commit 5d2cb8683c
44 changed files with 1992 additions and 1858 deletions

View file

@ -112,8 +112,8 @@
<artifactId>commons-logging</artifactId>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>commons-collections</groupId>

View file

@ -21,7 +21,7 @@
package org.zkoss.ganttz;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.zkoss.ganttz.extensions.ICommand;
import org.zkoss.ganttz.extensions.IContext;
import org.zkoss.zk.ui.event.Event;
@ -31,8 +31,7 @@ import org.zkoss.zul.Button;
class CommandContextualized<T> {
public static <T> CommandContextualized<T> create(ICommand<T> command,
IContext<T> context) {
public static <T> CommandContextualized<T> create(ICommand<T> command, IContext<T> context) {
return new CommandContextualized<T>(command, context);
}
@ -52,28 +51,31 @@ class CommandContextualized<T> {
}
Button toButton() {
if (button != null) {
if ( button != null ) {
return button;
}
Button result = new Button();
if (StringUtils.isEmpty(command.getImage())) {
if ( StringUtils.isEmpty(command.getImage()) ) {
result.setLabel(command.getName());
} else {
result.setImage(command.getImage());
result.setTooltiptext(command.getName());
}
if (command.isDisabled()) {
if ( command.isDisabled() ) {
result.setDisabled(true);
} else {
result.addEventListener(Events.ON_CLICK, new EventListener() {
@Override
public void onEvent(Event event) {
doAction();
}
});
}
button = result;
return result;
}

View file

@ -19,15 +19,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
*
*/
package org.zkoss.ganttz;
import java.math.BigDecimal;
import java.math.RoundingMode;
import org.apache.commons.lang.math.Fraction;
import org.apache.commons.lang3.math.Fraction;
import org.joda.time.DateTime;
import org.joda.time.Duration;
import org.joda.time.LocalDate;
@ -43,16 +41,13 @@ public class DatesMapperOnInterval implements IDatesMapper {
public DatesMapperOnInterval(int horizontalSize, Interval interval) {
this.horizontalSize = horizontalSize;
this.interval = interval;
this.millisecondsPerPixel = interval.getLengthBetween().getMillis()
/ horizontalSize;
this.pixelsPerDay = Fraction.getFraction(horizontalSize, interval
.getDaysBetween().getDays());
this.millisecondsPerPixel = interval.getLengthBetween().getMillis() / horizontalSize;
this.pixelsPerDay = Fraction.getFraction(horizontalSize, interval.getDaysBetween().getDays());
}
@Override
public LocalDate toDate(int pixels) {
int daysInto = Fraction.getFraction(pixels, 1).divideBy(pixelsPerDay)
.intValue();
int daysInto = Fraction.getFraction(pixels, 1).divideBy(pixelsPerDay).intValue();
return getInterval().getStart().plusDays(daysInto);
}
@ -71,29 +66,29 @@ public class DatesMapperOnInterval implements IDatesMapper {
private int toPixels(Fraction proportion) {
try {
return proportion.multiplyBy(Fraction.getFraction(horizontalSize, 1))
.intValue();
return proportion.multiplyBy(Fraction.getFraction(horizontalSize, 1)).intValue();
} catch (ArithmeticException e) {
double d = Math.log10(horizontalSize);
int scale = (int) d + 1;
BigDecimal quotient = new BigDecimal(proportion.getNumerator())
.divide(new BigDecimal(proportion.getDenominator()), scale,
RoundingMode.HALF_UP);
return quotient.multiply(new BigDecimal(horizontalSize))
.intValue();
.divide(new BigDecimal(proportion.getDenominator()), scale, RoundingMode.HALF_UP);
return quotient.multiply(new BigDecimal(horizontalSize)).intValue();
}
}
@Override
public int toPixels(ReadableDuration duration) {
DateTime end = getInterval().getStart().toDateTimeAtStartOfDay()
.plus(duration);
DateTime end = getInterval().getStart().toDateTimeAtStartOfDay().plus(duration);
return toPixels(getProportion(end));
}
@Override
public int toPixelsAbsolute(long milliseconds) {
DateTime date = new DateTime(milliseconds);
return this.toPixels(getProportion(date));
}

View file

@ -26,7 +26,7 @@ import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import org.apache.commons.lang.Validate;
import org.apache.commons.lang3.Validate;
import org.zkoss.ganttz.data.Dependency;
import org.zkoss.ganttz.data.DependencyType;
import org.zkoss.ganttz.data.GanttDate;
@ -62,13 +62,13 @@ public class DependencyComponent extends XulElement implements AfterCompose {
private boolean violated = false;
public DependencyComponent(TaskComponent source, TaskComponent destination,
Dependency dependency) {
public DependencyComponent(TaskComponent source, TaskComponent destination, Dependency dependency) {
Validate.notNull(dependency);
Validate.notNull(source);
Validate.notNull(destination);
Validate.isTrue(source.getTask() == dependency.getSource());
Validate.isTrue(destination.getTask() == dependency.getDestination());
this.type = dependency.getType();
this.source = source;
this.destination = destination;
@ -76,8 +76,7 @@ public class DependencyComponent extends XulElement implements AfterCompose {
}
private void sendCSSUpdate() {
response("constraintViolated", new AuInvoke(DependencyComponent.this,
"setCSSClass", getCSSClass()));
response("constraintViolated", new AuInvoke(DependencyComponent.this, "setCSSClass", getCSSClass()));
}
public String getCSSClass() {
@ -88,9 +87,10 @@ public class DependencyComponent extends XulElement implements AfterCompose {
@Override
public void afterCompose() {
if (listenerAdded) {
if ( listenerAdded ) {
return;
}
listener = new PropertyChangeListener() {
@Override
@ -98,11 +98,11 @@ public class DependencyComponent extends XulElement implements AfterCompose {
redrawDependency();
}
};
this.source.getTask().addFundamentalPropertiesChangeListener(listener);
this.destination.getTask().addFundamentalPropertiesChangeListener(listener);
violationListener = Constraint
.onlyOnZKExecution(new IConstraintViolationListener<GanttDate>() {
violationListener = Constraint.onlyOnZKExecution(new IConstraintViolationListener<GanttDate>() {
@Override
public void constraintViolated(Constraint<GanttDate> constraint, GanttDate value) {
@ -116,16 +116,17 @@ public class DependencyComponent extends XulElement implements AfterCompose {
sendCSSUpdate();
}
});
this.dependency.addConstraintViolationListener(violationListener,
Mode.RECEIVE_PENDING);
this.dependency.addConstraintViolationListener(violationListener, Mode.RECEIVE_PENDING);
listenerAdded = true;
}
public void removeChangeListeners() {
if (!listenerAdded) {
if ( !listenerAdded ) {
return;
}
this.source.getTask().removePropertyChangeListener(listener);
this.destination.getTask().removePropertyChangeListener(listener);
listenerAdded = false;
@ -169,6 +170,7 @@ public class DependencyComponent extends XulElement implements AfterCompose {
public boolean contains(Task task) {
Task sourceTask = getSource().getTask();
Task destinationTask = getDestination().getTask();
return task.equals(sourceTask) || task.equals(destinationTask);
}
@ -191,8 +193,8 @@ public class DependencyComponent extends XulElement implements AfterCompose {
public boolean hasSameSourceAndDestination(Dependency dependency) {
Task sourceTask = source.getTask();
Task destinationTask = destination.getTask();
return sourceTask.equals(dependency.getSource())
&& destinationTask.equals(dependency.getDestination());
return sourceTask.equals(dependency.getSource()) && destinationTask.equals(dependency.getDestination());
}
protected void renderProperties(ContentRenderer renderer) throws IOException{

View file

@ -21,7 +21,7 @@
package org.zkoss.ganttz;
import org.apache.commons.lang.math.Fraction;
import org.apache.commons.lang3.math.Fraction;
import org.joda.time.LocalDate;
import org.joda.time.ReadableDuration;
import org.zkoss.ganttz.util.Interval;

View file

@ -29,7 +29,7 @@ import java.util.Arrays;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.joda.time.LocalDate;
@ -71,8 +71,6 @@ public class LeftTasksTreeRow extends GenericForwardComposer {
LeftTasksTreeRow getAboveRow();
}
private static final Log LOG = LogFactory.getLog(LeftTasksTreeRow.class);
private final Task task;
private Label nameLabel;
@ -101,20 +99,22 @@ public class LeftTasksTreeRow extends GenericForwardComposer {
private final IDisabilityConfiguration disabilityConfiguration;
public static LeftTasksTreeRow create(
IDisabilityConfiguration disabilityConfiguration, Task bean,
ILeftTasksTreeNavigator taskDetailnavigator, Planner planner) {
return new LeftTasksTreeRow(disabilityConfiguration, bean,
taskDetailnavigator, planner);
public static LeftTasksTreeRow create(IDisabilityConfiguration disabilityConfiguration,
Task bean,
ILeftTasksTreeNavigator taskDetailnavigator,
Planner planner) {
return new LeftTasksTreeRow(disabilityConfiguration, bean, taskDetailnavigator, planner);
}
private LeftTasksTreeRow(IDisabilityConfiguration disabilityConfiguration,
Task task, ILeftTasksTreeNavigator leftTasksTreeNavigator,
Planner planner) {
Task task,
ILeftTasksTreeNavigator leftTasksTreeNavigator,
Planner planner) {
this.disabilityConfiguration = disabilityConfiguration;
this.task = task;
this.dateFormat = DateFormat.getDateInstance(DateFormat.SHORT, Locales
.getCurrent());
this.dateFormat = DateFormat.getDateInstance(DateFormat.SHORT, Locales.getCurrent());
this.leftTasksTreeNavigator = leftTasksTreeNavigator;
this.planner = planner;
}
@ -143,13 +143,14 @@ public class LeftTasksTreeRow extends GenericForwardComposer {
* the component that has received focus
*/
public void userWantsDateBox(Component component) {
if (component == startDateTextBox) {
if (canChangeStartDate()) {
if ( component == startDateTextBox ) {
if ( canChangeStartDate() ) {
createDateBox(startDateTextBox);
}
}
if (component == endDateTextBox) {
if (canChangeEndDate()) {
if ( component == endDateTextBox ) {
if ( canChangeEndDate() ) {
createDateBox(endDateTextBox);
}
}
@ -185,7 +186,7 @@ public class LeftTasksTreeRow extends GenericForwardComposer {
public void focusGoUp(int position) {
LeftTasksTreeRow aboveDetail = leftTasksTreeNavigator.getAboveRow();
if (aboveDetail != null) {
if ( aboveDetail != null ) {
aboveDetail.receiveFocus(position);
}
}
@ -200,7 +201,7 @@ public class LeftTasksTreeRow extends GenericForwardComposer {
public void focusGoDown(int position) {
LeftTasksTreeRow belowDetail = leftTasksTreeNavigator.getBelowRow();
if (belowDetail != null) {
if ( belowDetail != null ) {
belowDetail.receiveFocus(position);
} else {
getListDetails().getGoingDownInLastArrowCommand().doAction();
@ -212,6 +213,7 @@ public class LeftTasksTreeRow extends GenericForwardComposer {
while (!(current instanceof LeftTasksTree)) {
current = current.getParent();
}
return (LeftTasksTree) current;
}
@ -220,13 +222,15 @@ public class LeftTasksTreeRow extends GenericForwardComposer {
List<Textbox> textBoxes = getTextBoxes();
int position = textBoxes.indexOf(textbox);
switch (navigation) {
case UP:
case UP:
focusGoUp(position);
break;
case DOWN:
case DOWN:
focusGoDown(position);
break;
default:
default:
throw new RuntimeException("case not covered: " + navigation);
}
}
@ -261,7 +265,7 @@ public class LeftTasksTreeRow extends GenericForwardComposer {
}
private void registerTextboxesListeners() {
if (disabilityConfiguration.isTreeEditable()) {
if ( disabilityConfiguration.isTreeEditable() ) {
registerKeyboardListener(nameBox);
registerOnChange(nameBox);
registerKeyboardListener(startDateTextBox);
@ -275,9 +279,9 @@ public class LeftTasksTreeRow extends GenericForwardComposer {
private void findComponents(Treerow row) {
List<Object> rowChildren = row.getChildren();
List<Treecell> treeCells = ComponentsFinder.findComponentsOfType(Treecell.class,
rowChildren);
List<Treecell> treeCells = ComponentsFinder.findComponentsOfType(Treecell.class, rowChildren);
assert treeCells.size() == 4;
findComponentsForNameCell(treeCells.get(0));
findComponentsForStartDateCell(treeCells.get(1));
findComponentsForEndDateCell(treeCells.get(2));
@ -286,12 +290,11 @@ public class LeftTasksTreeRow extends GenericForwardComposer {
private static Textbox findTextBoxOfCell(Treecell treecell) {
List<Object> children = treecell.getChildren();
return ComponentsFinder.findComponentsOfType(Textbox.class, children)
.get(0);
return ComponentsFinder.findComponentsOfType(Textbox.class, children).get(0);
}
private void findComponentsForNameCell(Treecell treecell) {
if (disabilityConfiguration.isTreeEditable()) {
if ( disabilityConfiguration.isTreeEditable() ) {
nameBox = (Textbox) treecell.getChildren().get(0);
} else {
nameLabel = (Label) treecell.getChildren().get(0);
@ -318,8 +321,7 @@ public class LeftTasksTreeRow extends GenericForwardComposer {
});
}
private void registerOnChangeDatebox(final Datebox datebox,
final Textbox textbox) {
private void registerOnChangeDatebox(final Datebox datebox, final Textbox textbox) {
datebox.addEventListener("onChange", new EventListener() {
@Override
@ -351,7 +353,7 @@ public class LeftTasksTreeRow extends GenericForwardComposer {
}
private void findComponentsForStartDateCell(Treecell treecell) {
if (disabilityConfiguration.isTreeEditable()) {
if ( disabilityConfiguration.isTreeEditable() ) {
startDateTextBox = findTextBoxOfCell(treecell);
} else {
startDateLabel = (Label) treecell.getChildren().get(0);
@ -359,7 +361,7 @@ public class LeftTasksTreeRow extends GenericForwardComposer {
}
private void findComponentsForEndDateCell(Treecell treecell) {
if (disabilityConfiguration.isTreeEditable()) {
if ( disabilityConfiguration.isTreeEditable() ) {
endDateTextBox = findTextBoxOfCell(treecell);
} else {
endDateLabel = (Label) treecell.getChildren().get(0);
@ -369,8 +371,7 @@ public class LeftTasksTreeRow extends GenericForwardComposer {
private void findComponentsForStatusCell(Treecell treecell) {
List<Object> children = treecell.getChildren();
Hlayout hlayout = ComponentsFinder.findComponentsOfType(Hlayout.class,
children).get(0);
Hlayout hlayout = ComponentsFinder.findComponentsOfType(Hlayout.class, children).get(0);
hoursStatusDiv = (Div) hlayout.getChildren().get(0);
// there is a <label> "/" between the divs
@ -389,15 +390,18 @@ public class LeftTasksTreeRow extends GenericForwardComposer {
}
public void updateBean(Component updatedComponent) {
if (updatedComponent == getNameBox()) {
if ( updatedComponent == getNameBox() ) {
task.setName(getNameBox().getValue());
if (StringUtils.isEmpty(getNameBox().getValue())) {
if ( StringUtils.isEmpty(getNameBox().getValue()) ) {
getNameBox().setValue(task.getName());
}
} else if (updatedComponent == getStartDateTextBox()) {
} else if ( updatedComponent == getStartDateTextBox() ) {
try {
final Date begin = dateFormat.parse(getStartDateTextBox()
.getValue());
final Date begin = dateFormat.parse(getStartDateTextBox().getValue());
task.doPositionModifications(new IModifications() {
@Override
@ -408,23 +412,26 @@ public class LeftTasksTreeRow extends GenericForwardComposer {
} catch (ParseException e) {
// Do nothing as textbox is rested in the next sentence
}
getStartDateTextBox().setValue(
dateFormat.format(task.getBeginDate().toDayRoundedDate()));
} else if (updatedComponent == getEndDateTextBox()) {
getStartDateTextBox().setValue(dateFormat.format(task.getBeginDate().toDayRoundedDate()));
} else if ( updatedComponent == getEndDateTextBox() ) {
try {
Date newEnd = dateFormat.parse(getEndDateTextBox().getValue());
task.resizeTo(LocalDate.fromDateFields(newEnd));
} catch (ParseException e) {
// Do nothing as textbox is rested in the next sentence
}
getEndDateTextBox().setValue(
asString(task.getEndDate().toDayRoundedDate()));
getEndDateTextBox().setValue(asString(task.getEndDate().toDayRoundedDate()));
}
planner.updateTooltips();
}
private void updateComponents() {
if (disabilityConfiguration.isTreeEditable()) {
if ( disabilityConfiguration.isTreeEditable() ) {
getNameBox().setValue(task.getName());
getNameBox().setDisabled(!canRenameTask());
getNameBox().setTooltiptext(task.getName());
@ -432,42 +439,35 @@ public class LeftTasksTreeRow extends GenericForwardComposer {
getStartDateTextBox().setDisabled(!canChangeStartDate());
getEndDateTextBox().setDisabled(!canChangeEndDate());
getStartDateTextBox().setValue(
asString(task.getBeginDate().toDayRoundedDate()));
getEndDateTextBox().setValue(
asString(task.getEndDate().toDayRoundedDate()));
getStartDateTextBox().setValue(asString(task.getBeginDate().toDayRoundedDate()));
getEndDateTextBox().setValue(asString(task.getEndDate().toDayRoundedDate()));
} else {
nameLabel.setValue(task.getName());
nameLabel.setTooltiptext(task.getName());
nameLabel.setSclass("clickable-rows");
nameLabel.addEventListener(Events.ON_CLICK, new EventListener() {
@Override
public void onEvent(Event arg0) throws Exception {
Executions.getCurrent().sendRedirect(
"/planner/index.zul;order="
+ task.getProjectCode());
Executions.getCurrent().sendRedirect("/planner/index.zul;order=" + task.getProjectCode());
}
});
startDateLabel.setValue(asString(task.getBeginDate()
.toDayRoundedDate()));
endDateLabel.setValue(asString(task.getEndDate()
.toDayRoundedDate()));
}
setHoursStatus(task.getProjectHoursStatus(),
task.getTooltipTextForProjectHoursStatus());
setBudgetStatus(task.getProjectBudgetStatus(),
task.getTooltipTextForProjectBudgetStatus());
startDateLabel.setValue(asString(task.getBeginDate().toDayRoundedDate()));
endDateLabel.setValue(asString(task.getEndDate().toDayRoundedDate()));
}
setHoursStatus(task.getProjectHoursStatus(), task.getTooltipTextForProjectHoursStatus());
setBudgetStatus(task.getProjectBudgetStatus(), task.getTooltipTextForProjectBudgetStatus());
}
private boolean canChangeStartDate() {
return disabilityConfiguration.isMovingTasksEnabled()
&& task.canBeExplicitlyMoved();
return disabilityConfiguration.isMovingTasksEnabled() && task.canBeExplicitlyMoved();
}
private boolean canChangeEndDate() {
return disabilityConfiguration.isResizingTasksEnabled()
&& task.canBeExplicitlyResized();
return disabilityConfiguration.isResizingTasksEnabled() && task.canBeExplicitlyResized();
}
private boolean canRenameTask() {
@ -508,29 +508,31 @@ public class LeftTasksTreeRow extends GenericForwardComposer {
private String getProjectStatusSclass(ProjectStatusEnum status) {
String cssClass;
switch (status) {
case MARGIN_EXCEEDED:
case MARGIN_EXCEEDED:
cssClass = "status-red";
break;
case WITHIN_MARGIN:
case WITHIN_MARGIN:
cssClass = "status-orange";
break;
case AS_PLANNED:
default:
case AS_PLANNED:
default:
cssClass = "status-green";
}
return cssClass;
}
private void onProjectStatusClick(Component statucComp) {
if (!disabilityConfiguration.isTreeEditable()) {
if ( !disabilityConfiguration.isTreeEditable() ) {
statucComp.addEventListener(Events.ON_CLICK, new EventListener() {
@Override
public void onEvent(Event arg0) throws Exception {
Executions.getCurrent()
.sendRedirect(
"/planner/index.zul;order="
+ task.getProjectCode());
Executions.getCurrent().sendRedirect("/planner/index.zul;order=" + task.getProjectCode());
}
});
}

View file

@ -28,7 +28,7 @@ import java.util.Date;
import java.util.Map;
import java.util.UUID;
import org.apache.commons.lang.Validate;
import org.apache.commons.lang3.Validate;
import org.joda.time.DateTime;
import org.joda.time.Days;
import org.joda.time.Duration;
@ -40,7 +40,6 @@ import org.zkoss.ganttz.data.ITaskFundamentalProperties.IUpdatablePosition;
import org.zkoss.ganttz.data.Milestone;
import org.zkoss.ganttz.data.Task;
import org.zkoss.ganttz.data.Task.IReloadResourcesTextRequested;
import org.zkoss.ganttz.data.TaskContainer;
import org.zkoss.ganttz.data.constraint.Constraint;
import org.zkoss.ganttz.data.constraint.Constraint.IConstraintViolationListener;
import org.zkoss.ganttz.util.WeakReferencedListeners.Mode;
@ -81,88 +80,91 @@ public class TaskComponent extends Div implements AfterCompose {
private PropertyChangeListener showingMoneyCostBarPropertyListener;
public static TaskComponent asTaskComponent(Task task,
IDisabilityConfiguration disabilityConfiguration,
boolean isTopLevel) {
IDisabilityConfiguration disabilityConfiguration,
boolean isTopLevel) {
final TaskComponent result;
if (task.isContainer()) {
result = TaskContainerComponent.asTask((TaskContainer) task,
disabilityConfiguration);
} else if (task instanceof Milestone) {
if ( task.isContainer() ) {
result = TaskContainerComponent.asTask(task, disabilityConfiguration);
} else if ( task instanceof Milestone ) {
result = new MilestoneComponent(task, disabilityConfiguration);
} else {
result = new TaskComponent(task, disabilityConfiguration);
}
result.isTopLevel = isTopLevel;
return TaskRow.wrapInRow(result);
}
public static TaskComponent asTaskComponent(Task task,
IDisabilityConfiguration disabilityConfiguration) {
public static TaskComponent asTaskComponent(Task task, IDisabilityConfiguration disabilityConfiguration) {
return asTaskComponent(task, disabilityConfiguration, true);
}
private IReloadResourcesTextRequested reloadResourcesTextRequested;
public TaskComponent(Task task,
IDisabilityConfiguration disabilityConfiguration) {
public TaskComponent(Task task, IDisabilityConfiguration disabilityConfiguration) {
setHeight(HEIGHT_PER_TASK + "px");
setContext("idContextMenuTaskAssignment");
this.task = task;
setClass(calculateCSSClass());
setId(UUID.randomUUID().toString());
this.disabilityConfiguration = disabilityConfiguration;
taskViolationListener = Constraint
.onlyOnZKExecution(new IConstraintViolationListener<GanttDate>() {
taskViolationListener = Constraint.onlyOnZKExecution(new IConstraintViolationListener<GanttDate>() {
@Override
public void constraintViolated(Constraint<GanttDate> constraint,
GanttDate value) {
public void constraintViolated(Constraint<GanttDate> constraint, GanttDate value) {
// TODO mark graphically task as violated
}
@Override
public void constraintSatisfied(Constraint<GanttDate> constraint,
GanttDate value) {
public void constraintSatisfied(Constraint<GanttDate> constraint, GanttDate value) {
// TODO mark graphically dependency as not violated
}
});
this.task.addConstraintViolationListener(taskViolationListener,
Mode.RECEIVE_PENDING);
});
this.task.addConstraintViolationListener(taskViolationListener, Mode.RECEIVE_PENDING);
reloadResourcesTextRequested = new IReloadResourcesTextRequested() {
@Override
public void reloadResourcesTextRequested() {
if (canShowResourcesText()) {
if ( canShowResourcesText() ) {
smartUpdate("resourcesText", getResourcesText());
}
String cssClass = calculateCSSClass();
response("setClass", new AuInvoke(TaskComponent.this,
"setClass", cssClass));
response("setClass", new AuInvoke(TaskComponent.this, "setClass", cssClass));
// FIXME: Refactorize to another listener
// FIXME: Refactor to another listener
updateDeadline();
invalidate();
}
};
this.task.addReloadListener(reloadResourcesTextRequested);
setAuService(new AuService(){
public boolean service(AuRequest request, boolean everError){
String command = request.getCommand();
final TaskComponent ta;
if (command.equals("onUpdatePosition")){
if ( command.equals("onUpdatePosition") ){
ta = retrieveTaskComponent(request);
ta.doUpdatePosition(
toInteger(retrieveData(request, "left")),
toInteger(retrieveData(request, "top")));
toInteger(retrieveData(request, "left"))
);
Events.postEvent(new Event(getId(), ta, request.getData()));
return true;
}
if (command.equals("onUpdateWidth")){
if ( command.equals("onUpdateWidth") ){
ta = retrieveTaskComponent(request);
ta.doUpdateSize(toInteger(retrieveData(request, "width")));
@ -170,7 +172,8 @@ public class TaskComponent extends Div implements AfterCompose {
return true;
}
if (command.equals("onAddDependency")){
if ( command.equals("onAddDependency") ){
ta = retrieveTaskComponent(request);
ta.doAddDependency((String) retrieveData(request, "dependencyId"));
@ -178,6 +181,7 @@ public class TaskComponent extends Div implements AfterCompose {
return true;
}
return false;
}
@ -188,9 +192,8 @@ public class TaskComponent extends Div implements AfterCompose {
private TaskComponent retrieveTaskComponent(AuRequest request){
final TaskComponent ta = (TaskComponent) request.getComponent();
if (ta == null) {
throw new UiException(MZk.ILLEGAL_REQUEST_COMPONENT_REQUIRED,
this);
if ( ta == null ) {
throw new UiException(MZk.ILLEGAL_REQUEST_COMPONENT_REQUIRED, this);
}
return ta;
@ -198,9 +201,8 @@ public class TaskComponent extends Div implements AfterCompose {
private Object retrieveData(AuRequest request, String key){
Object value = request.getData().get(key);
if ( value == null)
throw new UiException(MZk.ILLEGAL_REQUEST_WRONG_DATA,
new Object[] { key, this });
if ( value == null )
throw new UiException(MZk.ILLEGAL_REQUEST_WRONG_DATA, new Object[] { key, this });
return value;
}
@ -209,27 +211,29 @@ public class TaskComponent extends Div implements AfterCompose {
/* Generate CSS class attribute depending on task properties */
protected String calculateCSSClass() {
String cssClass = isSubcontracted() ? "box subcontracted-task"
: "box standard-task";
String cssClass = isSubcontracted() ? "box subcontracted-task" : "box standard-task";
cssClass += isResizingTasksEnabled() ? " yui-resize" : "";
if (isContainer()) {
if ( isContainer() ) {
cssClass += task.isExpanded() ? " expanded" : " closed ";
cssClass += task.isInCriticalPath() && !task.isExpanded() ? " critical"
: "";
cssClass += task.isInCriticalPath() && !task.isExpanded() ? " critical" : "";
} else {
cssClass += task.isInCriticalPath() ? " critical" : "";
if (!task.canBeExplicitlyMoved()) {
if ( !task.canBeExplicitlyMoved() ) {
cssClass += " fixed";
}
}
cssClass += " " + task.getAssignedStatus();
if (task.isLimiting()) {
cssClass += task.isLimitingAndHasDayAssignments() ? " limiting-assigned "
: " limiting-unassigned ";
if ( task.isLimiting() ) {
cssClass += task.isLimitingAndHasDayAssignments() ? " limiting-assigned " : " limiting-unassigned ";
}
if (task.isRoot() && task.belongsClosedProject()) {
if ( task.isRoot() && task.belongsClosedProject() ) {
cssClass += " project-closed ";
}
return cssClass;
}
@ -243,7 +247,7 @@ public class TaskComponent extends Div implements AfterCompose {
public final void afterCompose() {
updateProperties();
if (propertiesListener == null) {
if ( propertiesListener == null ) {
propertiesListener = new PropertyChangeListener() {
@Override
@ -252,52 +256,52 @@ public class TaskComponent extends Div implements AfterCompose {
}
};
}
this.task
.addFundamentalPropertiesChangeListener(propertiesListener);
if (showingAdvancePropertyListener == null) {
this.task.addFundamentalPropertiesChangeListener(propertiesListener);
if ( showingAdvancePropertyListener == null ) {
showingAdvancePropertyListener = new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (isInPage() && !(task instanceof Milestone)) {
if ( isInPage() && !(task instanceof Milestone) ) {
updateCompletionAdvance();
}
}
};
}
this.task
.addAdvancesPropertyChangeListener(showingAdvancePropertyListener);
if (showingReportedHoursPropertyListener == null) {
this.task.addAdvancesPropertyChangeListener(showingAdvancePropertyListener);
if ( showingReportedHoursPropertyListener == null ) {
showingReportedHoursPropertyListener = new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (isInPage() && !(task instanceof Milestone)) {
if ( isInPage() && !(task instanceof Milestone) ) {
updateCompletionReportedHours();
}
}
};
}
this.task
.addReportedHoursPropertyChangeListener(showingReportedHoursPropertyListener);
if (showingMoneyCostBarPropertyListener == null) {
this.task.addReportedHoursPropertyChangeListener(showingReportedHoursPropertyListener);
if ( showingMoneyCostBarPropertyListener == null ) {
showingMoneyCostBarPropertyListener = new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (isInPage() && !(task instanceof Milestone)) {
if ( isInPage() && !(task instanceof Milestone) ) {
updateCompletionMoneyCostBar();
}
}
};
}
this.task
.addMoneyCostBarPropertyChangeListener(showingMoneyCostBarPropertyListener);
if (criticalPathPropertyListener == null) {
this.task.addMoneyCostBarPropertyChangeListener(showingMoneyCostBarPropertyListener);
if ( criticalPathPropertyListener == null ) {
criticalPathPropertyListener = new PropertyChangeListener() {
@Override
@ -307,8 +311,8 @@ public class TaskComponent extends Div implements AfterCompose {
};
}
this.task
.addCriticalPathPropertyChangeListener(criticalPathPropertyListener);
this.task.addCriticalPathPropertyChangeListener(criticalPathPropertyListener);
updateClass();
}
@ -328,15 +332,14 @@ public class TaskComponent extends Div implements AfterCompose {
private transient PropertyChangeListener propertiesListener;
private IConstraintViolationListener<GanttDate> taskViolationListener;
// FIXME Bug #1270
private String progressType;
public TaskRow getRow() {
if (getParent() == null) {
if ( getParent() == null ) {
throw new IllegalStateException(
"the TaskComponent should have been wraped by a "
+ TaskRow.class.getName());
"the TaskComponent should have been wraped by a " + TaskRow.class.getName());
}
return (TaskRow) getParent();
}
@ -353,19 +356,19 @@ public class TaskComponent extends Div implements AfterCompose {
}
public boolean isResizingTasksEnabled() {
return (disabilityConfiguration != null)
&& disabilityConfiguration.isResizingTasksEnabled()
&& !task.isSubcontracted() && task.canBeExplicitlyResized();
return (disabilityConfiguration != null) &&
disabilityConfiguration.isResizingTasksEnabled() &&
!task.isSubcontracted() && task.canBeExplicitlyResized();
}
public boolean isMovingTasksEnabled() {
return (disabilityConfiguration != null)
&& disabilityConfiguration.isMovingTasksEnabled()
&& task.canBeExplicitlyMoved();
return (disabilityConfiguration != null) &&
disabilityConfiguration.isMovingTasksEnabled() &&
task.canBeExplicitlyMoved();
}
void doUpdatePosition(int leftX, int topY) {
void doUpdatePosition(int leftX) {
GanttDate startBeforeMoving = this.task.getBeginDate();
final LocalDate newPosition = getMapper().toDate(leftX);
this.task.doPositionModifications(new IModifications() {
@ -375,24 +378,23 @@ public class TaskComponent extends Div implements AfterCompose {
position.moveTo(GanttDate.createFrom(newPosition));
}
});
boolean remainsInOriginalPosition = this.task.getBeginDate().equals(
startBeforeMoving);
if (remainsInOriginalPosition) {
boolean remainsInOriginalPosition = this.task.getBeginDate().equals(startBeforeMoving);
if ( remainsInOriginalPosition ) {
updateProperties();
}
}
void doUpdateSize(int size) {
DateTime end = new DateTime(this.task.getBeginDate()
.toDayRoundedDate().getTime()).plus(getMapper().toDuration(
size));
DateTime end =
new DateTime(this.task.getBeginDate().toDayRoundedDate().getTime()).plus(getMapper().toDuration(size));
this.task.resizeTo(end.toLocalDate());
updateProperties();
}
void doAddDependency(String destinyTaskId) {
getTaskList().addDependency(this,
((TaskComponent) getFellow(destinyTaskId)));
getTaskList().addDependency(this, ((TaskComponent) getFellow(destinyTaskId)));
}
public String getColor() {
@ -401,11 +403,11 @@ public class TaskComponent extends Div implements AfterCompose {
public void setColor(String color) {
if ((color != null) && (color.length() == 0)) {
if ( (color != null) && (color.length() == 0) ) {
color = null;
}
if (!Objects.equals(_color, color)) {
if ( !Objects.equals(_color, color) ) {
_color = color;
}
}
@ -415,13 +417,12 @@ public class TaskComponent extends Div implements AfterCompose {
* of the style
*/
protected void renderProperties(ContentRenderer renderer) throws IOException{
if(getColor() != null)
setStyle("background-color : " + getColor());
if( getColor() != null ) setStyle("background-color : " + getColor());
setWidgetAttribute("movingTasksEnabled",((Boolean)isMovingTasksEnabled()).toString());
setWidgetAttribute("movingTasksEnabled", ((Boolean)isMovingTasksEnabled()).toString());
setWidgetAttribute("resizingTasksEnabled", ((Boolean)isResizingTasksEnabled()).toString());
/*We can't use setStyle because of restrictions
/* We can't use setStyle because of restrictions
* involved with UiVisualizer#getResponses and the
* smartUpdate method (when the request is asynchronous) */
render(renderer, "style", "position : absolute");
@ -461,9 +462,10 @@ public class TaskComponent extends Div implements AfterCompose {
}
public void updateProperties() {
if (!isInPage()) {
if ( !isInPage() ) {
return;
}
setLeft("0");
setLeft(this.task.getBeginDate().toPixels(getMapper()) + "px");
updateWidth();
@ -483,23 +485,27 @@ public class TaskComponent extends Div implements AfterCompose {
private void updateDeadline() {
// Task mark is placed after midnight date of the deadline day
if (task.getDeadline() != null) {
if ( task.getDeadline() != null ) {
String position = (getMapper().toPixels(
LocalDate.fromDateFields(task.getDeadline()).plusDays(1)) - HALF_DEADLINE_MARK)
+ "px";
LocalDate.fromDateFields(task.getDeadline()).plusDays(1)) - HALF_DEADLINE_MARK) + "px";
response(null, new AuInvoke(this, "moveDeadline", position));
} else {
// Move deadline out of visible area
response(null, new AuInvoke(this, "moveDeadline","-100px"));
}
if (task.getConsolidatedline() != null) {
int pixels = getMapper().toPixels(
LocalDate.fromDateFields(task.getConsolidatedline()
.toDayRoundedDate()))
if ( task.getConsolidatedline() != null ) {
int pixels = getMapper()
.toPixels(LocalDate.fromDateFields(task.getConsolidatedline().toDayRoundedDate()))
- CONSOLIDATED_MARK_HALF_WIDTH;
String position = pixels + "px";
response(null, new AuInvoke(this, "moveConsolidatedline", position));
} else {
// Move consolidated line out of visible area
response(null, new AuInvoke(this, "moveConsolidatedline", "-100px"));
@ -507,43 +513,45 @@ public class TaskComponent extends Div implements AfterCompose {
}
public void updateCompletionIfPossible() {
if (task instanceof Milestone) {
if ( task instanceof Milestone ) {
return;
}
updateCompletionReportedHours();
updateCompletionMoneyCostBar();
updateCompletionAdvance();
}
public void updateCompletionReportedHours() {
if (task.isShowingReportedHours()) {
if ( task.isShowingReportedHours() ) {
int startPixels = this.task.getBeginDate().toPixels(getMapper());
String widthHoursAdvancePercentage = pixelsFromStartUntil(
startPixels,
this.task.getHoursAdvanceBarEndDate()) + "px";
response(null, new AuInvoke(this, "resizeCompletionAdvance",
widthHoursAdvancePercentage));
String widthHoursAdvancePercentage =
pixelsFromStartUntil(startPixels, this.task.getHoursAdvanceBarEndDate()) + "px";
response(null, new AuInvoke(this, "resizeCompletionAdvance", widthHoursAdvancePercentage));
Date firstTimesheetDate = task.getFirstTimesheetDate();
Date lastTimesheetDate = task.getLastTimesheetDate();
if (firstTimesheetDate != null && lastTimesheetDate != null) {
if ( firstTimesheetDate != null && lastTimesheetDate != null ) {
Duration firstDuration = Days.daysBetween(
task.getBeginDateAsLocalDate(),
LocalDate.fromDateFields(firstTimesheetDate))
.toStandardDuration();
LocalDate.fromDateFields(firstTimesheetDate)).toStandardDuration();
int pixelsFirst = getMapper().toPixels(firstDuration);
String positionFirst = pixelsFirst + "px";
Duration lastDuration = Days
.daysBetween(
task.getBeginDateAsLocalDate(),
LocalDate.fromDateFields(lastTimesheetDate)
.plusDays(1)).toStandardDuration();
Duration lastDuration = Days.daysBetween(
task.getBeginDateAsLocalDate(),
LocalDate.fromDateFields(lastTimesheetDate).plusDays(1)).toStandardDuration();
int pixelsLast = getMapper().toPixels(lastDuration);
String positionLast = pixelsLast + "px";
response(null, new AuInvoke(this, "showTimsheetDateMarks",
positionFirst, positionLast));
response(null, new AuInvoke(this, "showTimsheetDateMarks", positionFirst, positionLast));
} else {
response(null, new AuInvoke(this, "hideTimsheetDateMarks"));
}
@ -555,44 +563,38 @@ public class TaskComponent extends Div implements AfterCompose {
}
public void updateCompletionMoneyCostBar() {
if (task.isShowingMoneyCostBar()) {
if ( task.isShowingMoneyCostBar() ) {
int startPixels = this.task.getBeginDate().toPixels(getMapper());
int endPixels = this.task.getEndDate().toPixels(getMapper());
int widthPixels = (int) ((endPixels - startPixels) * this.task
.getMoneyCostBarPercentage().doubleValue());
int widthPixels = (int) ((endPixels - startPixels) * this.task.getMoneyCostBarPercentage().doubleValue());
String widthMoneyCostBar = widthPixels + "px";
response(null, new AuInvoke(this, "resizeCompletionMoneyCostBar",
widthMoneyCostBar));
response(null, new AuInvoke(this, "resizeCompletionMoneyCostBar", widthMoneyCostBar));
} else {
response(null, new AuInvoke(this, "resizeCompletionMoneyCostBar",
"0px"));
response(null, new AuInvoke(this, "resizeCompletionMoneyCostBar", "0px"));
}
}
private void updateCompletionAdvance() {
if (task.isShowingAdvances()) {
if ( task.isShowingAdvances() ) {
int startPixels = this.task.getBeginDate().toPixels(getMapper());
String widthAdvancePercentage = pixelsFromStartUntil(startPixels,
this.task.getAdvanceBarEndDate()) + "px";
response(null, new AuInvoke(this, "resizeCompletion2Advance",
widthAdvancePercentage));
String widthAdvancePercentage = pixelsFromStartUntil(startPixels, this.task.getAdvanceBarEndDate()) + "px";
response(null, new AuInvoke(this, "resizeCompletion2Advance", widthAdvancePercentage));
} else {
response(null,
new AuInvoke(this, "resizeCompletion2Advance", "0px"));
response(null, new AuInvoke(this, "resizeCompletion2Advance", "0px"));
}
}
public void updateCompletion(String progressType) {
if (task.isShowingAdvances()) {
if ( task.isShowingAdvances() ) {
int startPixels = this.task.getBeginDate().toPixels(getMapper());
String widthAdvancePercentage = pixelsFromStartUntil(startPixels,
this.task.getAdvanceBarEndDate(progressType)) + "px";
response(null, new AuInvoke(this, "resizeCompletion2Advance",
widthAdvancePercentage));
String widthAdvancePercentage =
pixelsFromStartUntil(startPixels, this.task.getAdvanceBarEndDate(progressType)) + "px";
response(null, new AuInvoke(this, "resizeCompletion2Advance", widthAdvancePercentage));
} else {
response(null,
new AuInvoke(this, "resizeCompletion2Advance", "0px"));
response(null, new AuInvoke(this, "resizeCompletion2Advance", "0px"));
}
}
@ -603,12 +605,10 @@ public class TaskComponent extends Div implements AfterCompose {
}
public void updateTooltipText() {
// FIXME Bug #1270
this.progressType = null;
}
public void updateTooltipText(String progressType) {
// FIXME Bug #1270
this.progressType = progressType;
}
@ -635,8 +635,7 @@ public class TaskComponent extends Div implements AfterCompose {
}
public String getTooltipText() {
// FIXME Bug #1270
if (progressType == null) {
if ( progressType == null ) {
return task.getTooltipText();
} else {
return task.updateTooltipText(progressType);

View file

@ -33,7 +33,7 @@ import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import org.apache.commons.lang.math.Fraction;
import org.apache.commons.lang3.math.Fraction;
import org.joda.time.LocalDate;
import org.zkoss.ganttz.adapters.IDisabilityConfiguration;
import org.zkoss.ganttz.data.Dependency;
@ -75,7 +75,7 @@ public class TaskList extends XulElement implements AfterCompose {
private FilterAndParentExpandedPredicates predicate;
private Set<Task> visibleTasks = new HashSet<Task>();
private Set<Task> visibleTasks = new HashSet<>();
private Map<Task, TaskComponent> taskComponentByTask;
@ -86,9 +86,10 @@ public class TaskList extends XulElement implements AfterCompose {
List<? extends CommandOnTaskContextualized<?>> commandsOnTasksContextualized,
IDisabilityConfiguration disabilityConfiguration,
FilterAndParentExpandedPredicates predicate) {
this.context = context;
this.doubleClickCommand = doubleClickCommand;
this.currentTotalTasks = new ArrayList<Task>(tasks);
this.currentTotalTasks = new ArrayList<>(tasks);
this.commandsOnTasksContextualized = commandsOnTasksContextualized;
this.disabilityConfiguration = disabilityConfiguration;
this.predicate = predicate;
@ -103,7 +104,7 @@ public class TaskList extends XulElement implements AfterCompose {
}
public List<Task> getAllTasks() {
return new ArrayList<Task>(currentTotalTasks);
return new ArrayList<>(currentTotalTasks);
}
public static TaskList createFor(
@ -112,20 +113,26 @@ public class TaskList extends XulElement implements AfterCompose {
List<? extends CommandOnTaskContextualized<?>> commandsOnTasksContextualized,
IDisabilityConfiguration disabilityConfiguration,
FilterAndParentExpandedPredicates predicate) {
TaskList result = new TaskList(context, doubleClickCommand, context
.getDiagramGraph().getTopLevelTasks(),
commandsOnTasksContextualized, disabilityConfiguration,
TaskList result = new TaskList(
context,
doubleClickCommand,
context.getDiagramGraph().getTopLevelTasks(),
commandsOnTasksContextualized,
disabilityConfiguration,
predicate);
return result;
}
public List<DependencyComponent> asDependencyComponents(Collection<? extends Dependency> dependencies) {
List<DependencyComponent> result = new ArrayList<DependencyComponent>();
List<DependencyComponent> result = new ArrayList<>();
for (Dependency dependency : dependencies) {
result.add(new DependencyComponent(taskComponentByTask
.get(dependency.getSource()), taskComponentByTask
.get(dependency.getDestination()), dependency));
result.add(new DependencyComponent(
taskComponentByTask.get(dependency.getSource()),
taskComponentByTask.get(dependency.getDestination()), dependency));
}
return result;
}
@ -133,11 +140,14 @@ public class TaskList extends XulElement implements AfterCompose {
return asDependencyComponents(Arrays.asList(dependency)).get(0);
}
private synchronized void addTaskComponent(TaskRow beforeThis, final TaskComponent taskComponent, boolean relocate) {
private synchronized void addTaskComponent(TaskRow beforeThis, final TaskComponent taskComponent,
boolean relocate) {
insertBefore(taskComponent.getRow(), beforeThis);
addContextMenu(taskComponent);
addListenerForTaskComponentEditForm(taskComponent);
taskComponent.afterCompose();
if ( relocate ) {
getGanttPanel().adjustZoomColumnsHeight();
}
@ -145,12 +155,14 @@ public class TaskList extends XulElement implements AfterCompose {
public void addTasks(Position position, Collection<? extends Task> newTasks) {
createAndPublishComponentsIfNeeded(newTasks);
if (position.isAppendToTop()) {
if ( position.isAppendToTop() ) {
currentTotalTasks.addAll(newTasks);
} else if (position.isAtTop()) {
} else if ( position.isAtTop() ) {
final int insertionPosition = position.getInsertionPosition();
currentTotalTasks.addAll(insertionPosition, newTasks);
}
// if the position is children of some already existent task when
// reloading it will be added if the predicate tells so
reload(true);
@ -159,7 +171,7 @@ public class TaskList extends XulElement implements AfterCompose {
public TaskComponent find(Task task) {
List<TaskComponent> taskComponents = getTaskComponents();
for (TaskComponent taskComponent : taskComponents) {
if (taskComponent.getTask().equals(task)) {
if ( taskComponent.getTask().equals(task) ) {
return taskComponent;
}
}
@ -196,13 +208,14 @@ public class TaskList extends XulElement implements AfterCompose {
}
protected List<TaskComponent> getTaskComponents() {
ArrayList<TaskComponent> result = new ArrayList<TaskComponent>();
ArrayList<TaskComponent> result = new ArrayList<>();
for (Object child : getChildren()) {
if (child instanceof TaskRow) {
if ( child instanceof TaskRow ) {
TaskRow row = (TaskRow) child;
result.add(row.getChild());
}
}
return result;
}
@ -218,42 +231,44 @@ public class TaskList extends XulElement implements AfterCompose {
}
private void publishOriginalTasksAsComponents() {
taskComponentByTask = new HashMap<Task, TaskComponent>();
taskComponentByTask = new HashMap<>();
createAndPublishComponentsIfNeeded(currentTotalTasks);
}
private List<TaskComponent> createAndPublishComponentsIfNeeded(
Collection<? extends Task> newTasks) {
if (predicate.isFilterContainers()) {
List<Task> taskLeafs = new ArrayList<Task>();
private List<TaskComponent> createAndPublishComponentsIfNeeded(Collection<? extends Task> newTasks) {
if ( predicate.isFilterContainers() ) {
List<Task> taskLeafs = new ArrayList<>();
for (Task task : newTasks) {
taskLeafs.addAll(task.getAllTaskLeafs());
}
newTasks = taskLeafs;
}
List<TaskComponent> result = new ArrayList<TaskComponent>();
List<TaskComponent> result = new ArrayList<>();
for (Task task : newTasks) {
TaskComponent taskComponent = taskComponentByTask.get(task);
if (taskComponent == null) {
taskComponent = TaskComponent.asTaskComponent(task,
disabilityConfiguration);
if ( taskComponent == null ) {
taskComponent = TaskComponent.asTaskComponent(task, disabilityConfiguration);
taskComponent.publishTaskComponents(taskComponentByTask);
}
if (task.isContainer()) {
if ( task.isContainer() ) {
addExpandListenerTo((TaskContainer) task);
}
result.add(taskComponent);
}
return result;
}
private Map<TaskContainer, IExpandListener> autoRemovedListers = new WeakHashMap<TaskContainer, IExpandListener>();
private Map<TaskContainer, IExpandListener> autoRemovedListers = new WeakHashMap<>();
private void addExpandListenerTo(TaskContainer container) {
if (autoRemovedListers.containsKey(container)) {
if ( autoRemovedListers.containsKey(container) ) {
return;
}
IExpandListener expandListener = new IExpandListener() {
@Override
@ -261,12 +276,13 @@ public class TaskList extends XulElement implements AfterCompose {
reload(true);
}
};
container.addExpandListener(expandListener);
autoRemovedListers.put(container, expandListener);
}
private void registerZoomLevelChangedListener() {
if (zoomLevelChangedListener == null) {
if ( zoomLevelChangedListener == null ) {
zoomLevelChangedListener = new IZoomLevelChangedListener() {
@Override
public void zoomLevelChanged(ZoomLevel detailLevel) {
@ -281,12 +297,11 @@ public class TaskList extends XulElement implements AfterCompose {
}
public LocalDate toDate(int pixels, Fraction pixelsPerDay, Interval interval) {
int daysInto = Fraction.getFraction(pixels, 1).divideBy(pixelsPerDay)
.intValue();
int daysInto = Fraction.getFraction(pixels, 1).divideBy(pixelsPerDay).intValue();
return interval.getStart().plusDays(daysInto);
}
private Map<TaskComponent, Menupopup> contextMenus = new HashMap<TaskComponent, Menupopup>();
private Map<TaskComponent, Menupopup> contextMenus = new HashMap<>();
private Menupopup getContextMenuFor(TaskComponent taskComponent) {
if ( contextMenus.get(taskComponent) == null ) {
@ -295,7 +310,6 @@ public class TaskList extends XulElement implements AfterCompose {
if ( disabilityConfiguration.isAddingDependenciesEnabled() ) {
menuBuilder.item(_("Add Dependency"), "/common/img/ico_dependency.png",
new ItemAction<TaskComponent>() {
@Override
public void onEvent(TaskComponent choosen, Event event) {
choosen.addDependency();
@ -308,10 +322,13 @@ public class TaskList extends XulElement implements AfterCompose {
menuBuilder.item(command.getName(), command.getIcon(), command.toItemAction());
}
}
Menupopup result = menuBuilder.createWithoutSettingContext();
contextMenus.put(taskComponent, result);
return result;
}
return contextMenus.get(taskComponent);
}
@ -330,16 +347,16 @@ public class TaskList extends XulElement implements AfterCompose {
public void remove(Task task) {
currentTotalTasks.remove(task);
for (TaskComponent taskComponent : getTaskComponents()) {
if (taskComponent.getTask().equals(task)) {
if ( taskComponent.getTask().equals(task) ) {
taskComponent.remove();
return;
}
}
}
public void addDependency(TaskComponent source, TaskComponent destination) {
context.addDependency(new Dependency(source.getTask(), destination
.getTask(), DependencyType.END_START));
context.addDependency(new Dependency(source.getTask(), destination.getTask(), DependencyType.END_START));
}
public IDisabilityConfiguration getDisabilityConfiguration() {
@ -347,7 +364,7 @@ public class TaskList extends XulElement implements AfterCompose {
}
private void reload(boolean relocate) {
ArrayList<Task> tasksPendingToAdd = new ArrayList<Task>();
ArrayList<Task> tasksPendingToAdd = new ArrayList<>();
reload(currentTotalTasks, tasksPendingToAdd, relocate);
addPendingTasks(tasksPendingToAdd, null, relocate);
getGanttPanel().getDependencyList().redrawDependencies();
@ -358,6 +375,7 @@ public class TaskList extends XulElement implements AfterCompose {
if ( visibleTasks.contains(task) ) {
addPendingTasks(tasksPendingToAdd, rowFor(task), relocate);
}
final boolean isShown = visibleTasks.contains(task);
if ( predicate.accepts(task) != isShown ) {
@ -367,6 +385,7 @@ public class TaskList extends XulElement implements AfterCompose {
tasksPendingToAdd.add(task);
}
}
if ( task instanceof TaskContainer ) {
reload(task.getTasks(), tasksPendingToAdd, relocate);
}
@ -389,6 +408,7 @@ public class TaskList extends XulElement implements AfterCompose {
if ( tasksPendingToAdd.isEmpty() ) {
return;
}
for (TaskComponent each : createAndPublishComponentsIfNeeded(tasksPendingToAdd)) {
addTaskComponent(insertBefore, each, relocate);
visibleTasks.add(each.getTask());

View file

@ -31,7 +31,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.Validate;
import org.apache.commons.lang3.Validate;
import org.zkoss.ganttz.Planner;
import org.zkoss.ganttz.data.GanttDate;
import org.zkoss.ganttz.data.GanttDiagramGraph.IGraphChangeListener;
@ -53,15 +53,15 @@ import org.zkoss.zk.ui.Component;
public class PlannerConfiguration<T> implements IDisabilityConfiguration {
public interface IPrintAction {
public void doPrint();
void doPrint();
public void doPrint(Map<String, String> parameters);
void doPrint(Map<String, String> parameters);
public void doPrint(HashMap<String, String> parameters, Planner planner);
void doPrint(HashMap<String, String> parameters, Planner planner);
}
public interface IReloadChartListener {
public void reloadChart();
void reloadChart();
}
private static class NullCommand<T> implements ICommand<T> {
@ -123,13 +123,13 @@ public class PlannerConfiguration<T> implements IDisabilityConfiguration {
private List<? extends T> data;
private List<ICommand<T>> globalCommands = new ArrayList<ICommand<T>>();
private List<ICommand<T>> globalCommands = new ArrayList<>();
private List<ICommandOnTask<T>> commandsOnTasks = new ArrayList<ICommandOnTask<T>>();
private List<ICommandOnTask<T>> commandsOnTasks = new ArrayList<>();
private ICommand<T> goingDownInLastArrowCommand = new NullCommand<T>();
private ICommand<T> goingDownInLastArrowCommand = new NullCommand<>();
private ICommandOnTask<T> doubleClickCommand = new NullCommandOnTask<T>();
private ICommandOnTask<T> doubleClickCommand = new NullCommandOnTask<>();
private Component chartComponent;
@ -167,26 +167,25 @@ public class PlannerConfiguration<T> implements IDisabilityConfiguration {
// private String identifier = null;
private IDetailItemModificator firstLevelModificators = SeveralModificators
.empty();
private IDetailItemModificator firstLevelModificators = SeveralModificators.empty();
private IDetailItemModificator secondLevelModificators = SeveralModificators
.empty();
private IDetailItemModificator secondLevelModificators = SeveralModificators.empty();
private List<IReloadChartListener> reloadChartListeners = new ArrayList<IReloadChartListener>();
private List<IReloadChartListener> reloadChartListeners = new ArrayList<>();
private IPrintAction printAction;
private boolean expandPlanningViewCharts;
private final List<IGraphChangeListener> preGraphChangeListeners = new ArrayList<IGraphChangeListener>();
private final List<IGraphChangeListener> preGraphChangeListeners = new ArrayList<>();
private final List<IGraphChangeListener> postGraphChangeListeners = new ArrayList<IGraphChangeListener>();
private final List<IGraphChangeListener> postGraphChangeListeners = new ArrayList<>();
private boolean scheduleBackwards = false;
public PlannerConfiguration(IAdapterToTaskFundamentalProperties<T> adapter,
IStructureNavigator<T> navigator, List<? extends T> data) {
IStructureNavigator<T> navigator,
List<? extends T> data) {
this.adapter = adapter;
this.navigator = navigator;
this.data = data;
@ -234,8 +233,7 @@ public class PlannerConfiguration<T> implements IDisabilityConfiguration {
this.notAfterThan = GanttDate.createFrom(notAfterThan);
}
public void setGoingDownInLastArrowCommand(
ICommand<T> goingDownInLastArrowCommand) {
public void setGoingDownInLastArrowCommand(ICommand<T> goingDownInLastArrowCommand) {
Validate.notNull(goingDownInLastArrowCommand);
this.goingDownInLastArrowCommand = goingDownInLastArrowCommand;
}
@ -293,11 +291,11 @@ public class PlannerConfiguration<T> implements IDisabilityConfiguration {
this.editingDatesEnabled = editingDatesEnabled;
}
public static List<Constraint<GanttDate>> getStartConstraintsGiven(
GanttDate notBeforeThan) {
if (notBeforeThan != null) {
public static List<Constraint<GanttDate>> getStartConstraintsGiven(GanttDate notBeforeThan) {
if ( notBeforeThan != null ) {
return Collections.singletonList(biggerOrEqualThan(notBeforeThan));
}
return Collections.emptyList();
}
@ -305,11 +303,11 @@ public class PlannerConfiguration<T> implements IDisabilityConfiguration {
return getStartConstraintsGiven(notBeforeThan);
}
public static List<Constraint<GanttDate>> getEndConstraintsGiven(
GanttDate notAfterThan) {
if (notAfterThan != null) {
public static List<Constraint<GanttDate>> getEndConstraintsGiven(GanttDate notAfterThan) {
if ( notAfterThan != null ) {
return Collections.singletonList(lessOrEqualThan(notAfterThan));
}
return Collections.emptyList();
}
@ -401,20 +399,16 @@ public class PlannerConfiguration<T> implements IDisabilityConfiguration {
return secondLevelModificators;
}
public void setSecondLevelModificators(
IDetailItemModificator... secondLevelModificators) {
this.secondLevelModificators = SeveralModificators
.create(secondLevelModificators);
public void setSecondLevelModificators(IDetailItemModificator... secondLevelModificators) {
this.secondLevelModificators = SeveralModificators.create(secondLevelModificators);
}
public IDetailItemModificator getFirstLevelModificators() {
return firstLevelModificators;
}
public void setFirstLevelModificators(
IDetailItemModificator... firstLevelModificators) {
this.firstLevelModificators = SeveralModificators
.create(firstLevelModificators);
public void setFirstLevelModificators(IDetailItemModificator... firstLevelModificators) {
this.firstLevelModificators = SeveralModificators.create(firstLevelModificators);
}
public void addReloadChartListener(IReloadChartListener reloadChartListener) {
@ -437,21 +431,21 @@ public class PlannerConfiguration<T> implements IDisabilityConfiguration {
}
public void print() {
if (!isPrintEnabled()) {
if ( !isPrintEnabled() ) {
throw new UnsupportedOperationException("print not supported");
}
printAction.doPrint();
}
public void print(Map<String, String> parameters) {
if (!isPrintEnabled()) {
if ( !isPrintEnabled() ) {
throw new UnsupportedOperationException("print not supported");
}
printAction.doPrint(parameters);
}
public void print(HashMap<String, String> parameters, Planner planner) {
if (!isPrintEnabled()) {
if ( !isPrintEnabled() ) {
throw new UnsupportedOperationException("print not supported");
}
printAction.doPrint(parameters, planner);
@ -466,18 +460,16 @@ public class PlannerConfiguration<T> implements IDisabilityConfiguration {
return expandPlanningViewCharts;
}
public void addPreGraphChangeListener(
IGraphChangeListener preGraphChangeListener) {
public void addPreGraphChangeListener(IGraphChangeListener preGraphChangeListener) {
Validate.notNull(preGraphChangeListener);
if (!preGraphChangeListeners.contains(preGraphChangeListener)) {
if ( !preGraphChangeListeners.contains(preGraphChangeListener) ) {
preGraphChangeListeners.add(preGraphChangeListener);
}
}
public void addPostGraphChangeListener(
IGraphChangeListener postGraphChangeListener) {
public void addPostGraphChangeListener(IGraphChangeListener postGraphChangeListener) {
Validate.notNull(postGraphChangeListener);
if (!postGraphChangeListeners.contains(postGraphChangeListener)) {
if ( !postGraphChangeListeners.contains(postGraphChangeListener) ) {
postGraphChangeListeners.add(postGraphChangeListener);
}
}

View file

@ -25,8 +25,8 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.zkoss.ganttz.data.DependencyType.Point;
import org.zkoss.ganttz.data.constraint.Constraint;
import org.zkoss.ganttz.data.constraint.Constraint.IConstraintViolationListener;
@ -42,12 +42,14 @@ public class Dependency implements IDependency<Task> {
public static List<Constraint<GanttDate>> getConstraintsFor(
ConstraintCalculator<Task> calculator,
Collection<Dependency> dependencies, Point pointBeingModified) {
List<Constraint<GanttDate>> result = new ArrayList<Constraint<GanttDate>>();
Collection<Dependency> dependencies,
Point pointBeingModified) {
List<Constraint<GanttDate>> result = new ArrayList<>();
for (Dependency each : dependencies) {
result.addAll(each.withViolationNotification(calculator
.getConstraints(each, pointBeingModified)));
result.addAll(each.withViolationNotification(calculator.getConstraints(each, pointBeingModified)));
}
return result;
}
@ -59,60 +61,62 @@ public class Dependency implements IDependency<Task> {
private final boolean visible;
private ConstraintViolationNotificator<GanttDate> violationsNotificator = ConstraintViolationNotificator
.create();
private ConstraintViolationNotificator<GanttDate> violationsNotificator = ConstraintViolationNotificator.create();
public Dependency(Task source, Task destination,
DependencyType type, boolean visible) {
if (source == null) {
public Dependency(Task source, Task destination, DependencyType type, boolean visible) {
if ( source == null ) {
throw new IllegalArgumentException("source cannot be null");
}
if (destination == null) {
if ( destination == null ) {
throw new IllegalArgumentException("destination cannot be null");
}
if (type == null) {
if ( type == null ) {
throw new IllegalArgumentException("type cannot be null");
}
this.source = source;
this.destination = destination;
this.type = type;
this.visible = visible;
}
public Dependency(Task source, Task destination,
DependencyType type) {
public Dependency(Task source, Task destination, DependencyType type) {
this(source, destination, type, true);
}
private List<Constraint<GanttDate>> withViolationNotification(
List<Constraint<GanttDate>> original) {
private List<Constraint<GanttDate>> withViolationNotification(List<Constraint<GanttDate>> original) {
return violationsNotificator.withListener(original);
}
public void addConstraintViolationListener(
IConstraintViolationListener<GanttDate> listener, Mode mode) {
public void addConstraintViolationListener(IConstraintViolationListener<GanttDate> listener, Mode mode) {
violationsNotificator.addConstraintViolationListener(listener, mode);
}
@Override
public int hashCode() {
return new HashCodeBuilder().append(source).append(destination).append(
type).toHashCode();
return new HashCodeBuilder().append(source).append(destination).append(type).toHashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
if ( this == obj ) {
return true;
}
if (obj == null) {
if ( obj == null ) {
return false;
}
if (getClass() != obj.getClass()) {
if ( getClass() != obj.getClass() ) {
return false;
}
Dependency other = (Dependency) obj;
return new EqualsBuilder().append(this.destination, other.destination)
return new EqualsBuilder()
.append(this.destination, other.destination)
.append(this.source, other.source)
.append(this.type, other.type).isEquals();
}

View file

@ -24,7 +24,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import org.apache.commons.lang.Validate;
import org.apache.commons.lang3.Validate;
import org.joda.time.LocalDate;
import org.zkoss.ganttz.IDatesMapper;
@ -60,16 +60,18 @@ import org.zkoss.ganttz.IDatesMapper;
public abstract class GanttDate implements Comparable<GanttDate> {
public static LocalDateBased createFrom(Date date) {
if (date == null) {
if ( date == null ) {
return null;
}
return createFrom(LocalDate.fromDateFields(date));
}
public static LocalDateBased createFrom(LocalDate localDate) {
if (localDate == null) {
if ( localDate == null ) {
return null;
}
return new LocalDateBased(localDate);
}
@ -83,13 +85,15 @@ public abstract class GanttDate implements Comparable<GanttDate> {
@Override
public final boolean equals(Object obj) {
if (obj == this) {
if ( obj == this ) {
return true;
}
if (obj instanceof GanttDate) {
if ( obj instanceof GanttDate ) {
GanttDate other = (GanttDate) obj;
return isEqualsTo(other);
}
return false;
}
@ -99,13 +103,12 @@ public abstract class GanttDate implements Comparable<GanttDate> {
public abstract int hashCode();
public interface ICases<R> {
public R on(LocalDateBased localDateBased);
R on(LocalDateBased localDateBased);
public R on(CustomDate customType);
R on(CustomDate customType);
}
public static abstract class Cases<T extends CustomDate, R> implements
ICases<R> {
public static abstract class Cases<T extends CustomDate, R> implements ICases<R> {
private final Class<T> klass;
@ -243,6 +246,7 @@ public abstract class GanttDate implements Comparable<GanttDate> {
@Override
public int compareTo(GanttDate o) {
return o.byCases(new ICases<Integer>() {
@Override
public Integer on(LocalDateBased localDateBased) {
return compareToLocalDate(localDateBased.localDate);

View file

@ -38,9 +38,9 @@ import java.util.Map;
import java.util.Queue;
import java.util.Set;
import org.apache.commons.lang.Validate;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jgrapht.DirectedGraph;
@ -197,7 +197,6 @@ public class GanttDiagramGraph<V, D extends IDependency<V>> implements ICritical
@Override
public void setEndDateFor(Task task, final GanttDate newEnd) {
task.doPositionModifications(new IModifications() {
@Override
public void doIt(IUpdatablePosition position) {
position.setEndDate(newEnd);
@ -213,7 +212,6 @@ public class GanttDiagramGraph<V, D extends IDependency<V>> implements ICritical
@Override
public void setStartDateFor(Task task, final GanttDate newStart) {
task.doPositionModifications(new IModifications() {
@Override
public void doIt(IUpdatablePosition position) {
position.setBeginDate(newStart);
@ -247,8 +245,11 @@ public class GanttDiagramGraph<V, D extends IDependency<V>> implements ICritical
public static class GanttZKDiagramGraph extends GanttDiagramGraph<Task, Dependency> {
private GanttZKDiagramGraph(boolean scheduleBackwards, List<Constraint<GanttDate>> globalStartConstraints,
List<Constraint<GanttDate>> globalEndConstraints, boolean dependenciesConstraintsHavePriority) {
private GanttZKDiagramGraph(
boolean scheduleBackwards,
List<Constraint<GanttDate>> globalStartConstraints,
List<Constraint<GanttDate>> globalEndConstraints,
boolean dependenciesConstraintsHavePriority) {
super(scheduleBackwards, GANTTZK_ADAPTER, globalStartConstraints, globalEndConstraints,
dependenciesConstraintsHavePriority);

View file

@ -25,7 +25,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.commons.lang.Validate;
import org.apache.commons.lang3.Validate;
/**
* Represents a position for a task <br />
@ -40,13 +40,13 @@ public abstract class Position {
* @param positionInParent
* @return a {@link Position} specified by the params
*/
public static Position createPosition(
List<? extends TaskContainer> parents, int positionInParent) {
public static Position createPosition(List<? extends TaskContainer> parents, int positionInParent) {
Validate.notEmpty(parents);
Validate.noNullElements(parents);
Validate.isTrue(positionInParent >= 0);
Task firstParent = parents.get(0);
Validate.isTrue(positionInParent < firstParent.getTasks().size());
return new ChildPosition(parents, positionInParent);
}
@ -115,9 +115,10 @@ public abstract class Position {
* @return
*/
public Position down(TaskContainer current, int positionInParent) {
List<TaskContainer> ancestors = new ArrayList<TaskContainer>();
List<TaskContainer> ancestors = new ArrayList<>();
ancestors.add(current);
ancestors.addAll(getAncestors());
return new ChildPosition(ancestors, positionInParent);
}
@ -127,11 +128,12 @@ public abstract class Position {
private static class ChildPosition extends Position {
private final List<? extends TaskContainer> parents;
private TaskContainer parent;
ChildPosition(List<? extends TaskContainer> parents,
int positionInParent) {
ChildPosition(List<? extends TaskContainer> parents, int positionInParent) {
super(positionInParent);
this.parents = parents;
this.parent = parents.get(0);
}
@ -153,8 +155,7 @@ public abstract class Position {
@Override
public Position pop() {
return new ChildPosition(parents.subList(0, parents.size() - 1),
getInsertionPosition());
return new ChildPosition(parents.subList(0, parents.size() - 1), getInsertionPosition());
}
@Override

View file

@ -32,7 +32,7 @@ import java.util.Collections;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang.Validate;
import org.apache.commons.lang3.Validate;
import org.joda.time.Duration;
import org.joda.time.LocalDate;
import org.joda.time.ReadableDuration;
@ -56,28 +56,22 @@ import org.zkoss.ganttz.util.WeakReferencedListeners.Mode;
public abstract class Task implements ITaskFundamentalProperties {
public interface IReloadResourcesTextRequested {
public void reloadResourcesTextRequested();
void reloadResourcesTextRequested();
}
private List<IReloadResourcesTextRequested> reloadRequestedListeners = new ArrayList<IReloadResourcesTextRequested>();
private List<IReloadResourcesTextRequested> reloadRequestedListeners = new ArrayList<>();
private PropertyChangeSupport fundamentalPropertiesListeners = new PropertyChangeSupport(
this);
private PropertyChangeSupport fundamentalPropertiesListeners = new PropertyChangeSupport(this);
private PropertyChangeSupport visibilityProperties = new PropertyChangeSupport(
this);
private PropertyChangeSupport visibilityProperties = new PropertyChangeSupport(this);
private PropertyChangeSupport criticalPathProperty = new PropertyChangeSupport(
this);
private PropertyChangeSupport criticalPathProperty = new PropertyChangeSupport(this);
private PropertyChangeSupport advancesProperty = new PropertyChangeSupport(
this);
private PropertyChangeSupport advancesProperty = new PropertyChangeSupport(this);
private PropertyChangeSupport reportedHoursProperty = new PropertyChangeSupport(
this);
private PropertyChangeSupport reportedHoursProperty = new PropertyChangeSupport(this);
private PropertyChangeSupport moneyCostBarProperty = new PropertyChangeSupport(
this);
private PropertyChangeSupport moneyCostBarProperty = new PropertyChangeSupport(this);
private final ITaskFundamentalProperties fundamentalProperties;
@ -91,32 +85,31 @@ public abstract class Task implements ITaskFundamentalProperties {
private boolean showingMoneyCostBar = false;
private ConstraintViolationNotificator<GanttDate> violationNotificator = ConstraintViolationNotificator
.create();
private ConstraintViolationNotificator<GanttDate> violationNotificator = ConstraintViolationNotificator.create();
private IDependenciesEnforcerHook dependenciesEnforcerHook = GanttDiagramGraph
.doNothingHook();
private IDependenciesEnforcerHook dependenciesEnforcerHook = GanttDiagramGraph.doNothingHook();
private final INotificationAfterDependenciesEnforcement notifyDates = new INotificationAfterDependenciesEnforcement() {
private final INotificationAfterDependenciesEnforcement notifyDates =
new INotificationAfterDependenciesEnforcement() {
@Override
public void onStartDateChange(GanttDate previousStart, GanttDate previousEnd, GanttDate newStart) {
@Override
public void onStartDateChange(GanttDate previousStart,
GanttDate previousEnd, GanttDate newStart) {
fundamentalPropertiesListeners.firePropertyChange("beginDate",
previousStart, fundamentalProperties.getBeginDate());
fireEndDate(previousEnd);
}
fundamentalPropertiesListeners.firePropertyChange(
"beginDate", previousStart, fundamentalProperties.getBeginDate());
@Override
public void onEndDateChange(GanttDate previousEnd, GanttDate newEnd) {
fireEndDate(previousEnd);
}
fireEndDate(previousEnd);
}
private void fireEndDate(GanttDate previousEnd) {
fundamentalPropertiesListeners.firePropertyChange("endDate",
previousEnd, fundamentalProperties.getEndDate());
}
};
@Override
public void onEndDateChange(GanttDate previousEnd, GanttDate newEnd) {
fireEndDate(previousEnd);
}
private void fireEndDate(GanttDate previousEnd) {
fundamentalPropertiesListeners.firePropertyChange(
"endDate", previousEnd, fundamentalProperties.getEndDate());
}
};
public Task(ITaskFundamentalProperties fundamentalProperties) {
this.fundamentalProperties = fundamentalProperties;
@ -124,13 +117,11 @@ public abstract class Task implements ITaskFundamentalProperties {
@Override
public List<Constraint<GanttDate>> getStartConstraints() {
return violationNotificator.withListener(fundamentalProperties
.getStartConstraints());
return violationNotificator.withListener(fundamentalProperties.getStartConstraints());
}
public List<Constraint<GanttDate>> getEndConstraints() {
return violationNotificator.withListener(fundamentalProperties
.getEndConstraints());
return violationNotificator.withListener(fundamentalProperties.getEndConstraints());
}
@Override
@ -149,13 +140,13 @@ public abstract class Task implements ITaskFundamentalProperties {
@Override
public void setEndDate(GanttDate value) {
if (value == null) {
if ( value == null ) {
return;
}
GanttDate previousEnd = fundamentalProperties.getEndDate();
getFundamentalPropertiesPosition().setEndDate(value);
dependenciesEnforcerHook.setNewEnd(previousEnd,
fundamentalProperties.getEndDate());
dependenciesEnforcerHook.setNewEnd(previousEnd, fundamentalProperties.getEndDate());
}
@Override
@ -163,8 +154,7 @@ public abstract class Task implements ITaskFundamentalProperties {
GanttDate previousValue = fundamentalProperties.getBeginDate();
GanttDate previousEnd = fundamentalProperties.getEndDate();
getFundamentalPropertiesPosition().setBeginDate(newStart);
dependenciesEnforcerHook.setStartDate(previousValue, previousEnd,
newStart);
dependenciesEnforcerHook.setStartDate(previousValue, previousEnd, newStart);
}
@Override
@ -179,20 +169,18 @@ public abstract class Task implements ITaskFundamentalProperties {
GanttDate previousStart = getBeginDate();
GanttDate previousEnd = getEndDate();
getFundamentalPropertiesPosition().moveTo(date);
dependenciesEnforcerHook.setStartDate(previousStart, previousEnd,
date);
dependenciesEnforcerHook.setStartDate(previousStart, previousEnd, date);
}
private IUpdatablePosition getFundamentalPropertiesPosition() {
final IUpdatablePosition[] result = new IUpdatablePosition[1];
fundamentalProperties.doPositionModifications(new IModifications() {
@Override
public void doIt(IUpdatablePosition position) {
result[0] = position;
}
});
assert result[0] != null;
return result[0];
}
};
@ -203,8 +191,7 @@ public abstract class Task implements ITaskFundamentalProperties {
public abstract boolean isExpanded() throws UnsupportedOperationException;
public abstract List<Task> getTasks()
throws UnsupportedOperationException;
public abstract List<Task> getTasks() throws UnsupportedOperationException;
public boolean isVisible() {
return visible;
@ -213,8 +200,7 @@ public abstract class Task implements ITaskFundamentalProperties {
public void setVisible(boolean visible) {
boolean previousValue = this.visible;
this.visible = visible;
visibilityProperties.firePropertyChange("visible", previousValue,
this.visible);
visibilityProperties.firePropertyChange("visible", previousValue, this.visible);
}
public boolean isInCriticalPath() {
@ -224,15 +210,13 @@ public abstract class Task implements ITaskFundamentalProperties {
public void setInCriticalPath(boolean inCriticalPath) {
boolean previousValue = this.inCriticalPath;
this.inCriticalPath = inCriticalPath;
criticalPathProperty.firePropertyChange("inCriticalPath",
previousValue, this.inCriticalPath);
criticalPathProperty.firePropertyChange("inCriticalPath", previousValue, this.inCriticalPath);
}
public void setShowingAdvances(boolean showingAdvances) {
boolean previousValue = this.showingAdvances;
this.showingAdvances = showingAdvances;
advancesProperty.firePropertyChange("showingAdvances", previousValue,
this.showingAdvances);
advancesProperty.firePropertyChange("showingAdvances", previousValue, this.showingAdvances);
}
public boolean isShowingAdvances() {
@ -242,8 +226,7 @@ public abstract class Task implements ITaskFundamentalProperties {
public void setShowingReportedHours(boolean showingReportedHours) {
boolean previousValue = this.showingReportedHours;
this.showingReportedHours = showingReportedHours;
reportedHoursProperty.firePropertyChange("showingReportedHours",
previousValue, this.showingReportedHours);
reportedHoursProperty.firePropertyChange("showingReportedHours", previousValue, this.showingReportedHours);
}
public boolean isShowingReportedHours() {
@ -253,8 +236,7 @@ public abstract class Task implements ITaskFundamentalProperties {
public void setShowingMoneyCostBar(boolean showingMoneyCostBar) {
boolean previousValue = this.showingMoneyCostBar;
this.showingMoneyCostBar = showingMoneyCostBar;
moneyCostBarProperty.firePropertyChange("showingMoneyCostBar",
previousValue, this.showingMoneyCostBar);
moneyCostBarProperty.firePropertyChange("showingMoneyCostBar", previousValue, this.showingMoneyCostBar);
}
public boolean isShowingMoneyCostBar() {
@ -268,12 +250,10 @@ public abstract class Task implements ITaskFundamentalProperties {
public void setName(String name) {
String previousValue = fundamentalProperties.getName();
fundamentalProperties.setName(name);
fundamentalPropertiesListeners.firePropertyChange("name",
previousValue, name);
fundamentalPropertiesListeners.firePropertyChange("name", previousValue, name);
}
public void registerDependenciesEnforcerHook(
IDependenciesEnforcerHookFactory<Task> factory) {
public void registerDependenciesEnforcerHook(IDependenciesEnforcerHookFactory<Task> factory) {
Validate.notNull(factory);
dependenciesEnforcerHook = factory.create(this, notifyDates);
Validate.notNull(dependenciesEnforcerHook);
@ -288,52 +268,42 @@ public abstract class Task implements ITaskFundamentalProperties {
}
public long getLengthMilliseconds() {
return getEndDate().toDayRoundedDate().getTime()
- getBeginDate().toDayRoundedDate().getTime();
return getEndDate().toDayRoundedDate().getTime() - getBeginDate().toDayRoundedDate().getTime();
}
public ReadableDuration getLength() {
return new Duration(getBeginDate().toDayRoundedDate().getTime(),
getEndDate().toDayRoundedDate().getTime());
return new Duration(getBeginDate().toDayRoundedDate().getTime(), getEndDate().toDayRoundedDate().getTime());
}
public void addVisibilityPropertiesChangeListener(
PropertyChangeListener listener) {
public void addVisibilityPropertiesChangeListener(PropertyChangeListener listener) {
this.visibilityProperties.addPropertyChangeListener(listener);
}
public void addCriticalPathPropertyChangeListener(
PropertyChangeListener listener) {
public void addCriticalPathPropertyChangeListener(PropertyChangeListener listener) {
this.criticalPathProperty.addPropertyChangeListener(listener);
}
public void addAdvancesPropertyChangeListener(
PropertyChangeListener listener) {
public void addAdvancesPropertyChangeListener(PropertyChangeListener listener) {
this.advancesProperty.addPropertyChangeListener(listener);
}
public void addReportedHoursPropertyChangeListener(
PropertyChangeListener listener) {
public void addReportedHoursPropertyChangeListener(PropertyChangeListener listener) {
this.reportedHoursProperty.addPropertyChangeListener(listener);
}
public void addMoneyCostBarPropertyChangeListener(
PropertyChangeListener listener) {
public void addMoneyCostBarPropertyChangeListener(PropertyChangeListener listener) {
this.moneyCostBarProperty.addPropertyChangeListener(listener);
}
public void addFundamentalPropertiesChangeListener(
PropertyChangeListener listener) {
public void addFundamentalPropertiesChangeListener(PropertyChangeListener listener) {
this.fundamentalPropertiesListeners.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
this.fundamentalPropertiesListeners
.removePropertyChangeListener(listener);
this.fundamentalPropertiesListeners.removePropertyChangeListener(listener);
}
public void removeVisibilityPropertiesChangeListener(
PropertyChangeListener listener) {
public void removeVisibilityPropertiesChangeListener(PropertyChangeListener listener) {
this.visibilityProperties.removePropertyChangeListener(listener);
}
@ -344,16 +314,15 @@ public abstract class Task implements ITaskFundamentalProperties {
@Override
public List<Constraint<GanttDate>> getCurrentLengthConstraint() {
if (isContainer()) {
if ( isContainer() ) {
return Collections.emptyList();
}
return violationNotificator.withListener(fundamentalProperties
.getCurrentLengthConstraint());
return violationNotificator.withListener(fundamentalProperties.getCurrentLengthConstraint());
}
public Constraint<GanttDate> getEndDateBiggerThanStartDate() {
return violationNotificator
.withListener(biggerOrEqualThan(getBeginDate()));
return violationNotificator.withListener(biggerOrEqualThan(getBeginDate()));
}
public String getNotes() {
@ -363,16 +332,17 @@ public abstract class Task implements ITaskFundamentalProperties {
public void setNotes(String notes) {
String previousValue = fundamentalProperties.getNotes();
this.fundamentalProperties.setNotes(notes);
fundamentalPropertiesListeners.firePropertyChange("notes",
previousValue, this.fundamentalProperties.getNotes());
fundamentalPropertiesListeners.firePropertyChange(
"notes", previousValue, this.fundamentalProperties.getNotes());
}
public void resizeTo(final LocalDate date) {
if (date.compareTo(getBeginDateAsLocalDate()) < 0) {
if ( date.compareTo(getBeginDateAsLocalDate()) < 0 ) {
return;
}
doPositionModifications(new IModifications() {
doPositionModifications(new IModifications() {
@Override
public void doIt(IUpdatablePosition position) {
position.resizeTo(GanttDate.createFrom(date));
@ -447,8 +417,7 @@ public abstract class Task implements ITaskFundamentalProperties {
public void setDeadline(Date date) {
Date previousValue = fundamentalProperties.getDeadline();
fundamentalProperties.setDeadline(date);
fundamentalPropertiesListeners.firePropertyChange("deadline",
previousValue, date);
fundamentalPropertiesListeners.firePropertyChange("deadline", previousValue, date);
}
@Override
@ -456,19 +425,16 @@ public abstract class Task implements ITaskFundamentalProperties {
return fundamentalProperties.getConsolidatedline();
}
public void addConstraintViolationListener(
IConstraintViolationListener<GanttDate> listener, Mode mode) {
public void addConstraintViolationListener(IConstraintViolationListener<GanttDate> listener, Mode mode) {
violationNotificator.addConstraintViolationListener(listener, mode);
}
public void addReloadListener(
IReloadResourcesTextRequested reloadResourcesTextRequested) {
public void addReloadListener(IReloadResourcesTextRequested reloadResourcesTextRequested) {
Validate.notNull(reloadResourcesTextRequested);
this.reloadRequestedListeners.add(reloadResourcesTextRequested);
}
public void removeReloadListener(
IReloadResourcesTextRequested reloadResourcesTextRequested) {
public void removeReloadListener(IReloadResourcesTextRequested reloadResourcesTextRequested) {
this.reloadRequestedListeners.remove(reloadResourcesTextRequested);
}
@ -481,8 +447,8 @@ public abstract class Task implements ITaskFundamentalProperties {
public static void reloadResourcesText(IContextWithPlannerTask<?> context) {
Task task = context.getTask();
task.reloadResourcesText();
List<? extends TaskContainer> parents = context.getMapper().getParents(
task);
List<? extends TaskContainer> parents = context.getMapper().getParents(task);
for (TaskContainer each : parents) {
each.reloadResourcesText();
}
@ -545,8 +511,7 @@ public abstract class Task implements ITaskFundamentalProperties {
}
public void updateSizeDueToDateChanges(GanttDate previousStart, GanttDate previousEnd) {
dependenciesEnforcerHook.setStartDate(previousStart, previousEnd,
getBeginDate());
dependenciesEnforcerHook.setStartDate(previousStart, previousEnd, getBeginDate());
}
@Override
@ -565,10 +530,8 @@ public abstract class Task implements ITaskFundamentalProperties {
}
public void firePropertyChangeForTaskDates() {
fundamentalPropertiesListeners.firePropertyChange("beginDate", null,
getBeginDate());
fundamentalPropertiesListeners.firePropertyChange("endDate", null,
getEndDate());
fundamentalPropertiesListeners.firePropertyChange("beginDate", null, getBeginDate());
fundamentalPropertiesListeners.firePropertyChange("endDate", null, getEndDate());
}
public String getCode() {

View file

@ -23,22 +23,19 @@ package org.zkoss.ganttz.data.constraint;
import java.util.Arrays;
import java.util.Collections;
import org.apache.commons.lang.Validate;
import org.apache.commons.lang3.Validate;
/**
* @author Óscar González Fernández
*
*/
public class ConstraintOnComparableValues<T extends Comparable<T>> extends
Constraint<T> {
public class ConstraintOnComparableValues<T extends Comparable<T>> extends Constraint<T> {
public static <T extends Comparable<T>> Constraint<T> biggerOrEqualThan(
T value) {
public static <T extends Comparable<T>> Constraint<T> biggerOrEqualThan(T value) {
return instantiate(ComparisonType.BIGGER_OR_EQUAL_THAN, value);
}
public static <T extends Comparable<T>> Constraint<T> lessOrEqualThan(
T value) {
public static <T extends Comparable<T>> Constraint<T> lessOrEqualThan(T value) {
return instantiate(ComparisonType.LESS_OR_EQUAL_THAN, value);
}
@ -46,11 +43,11 @@ public class ConstraintOnComparableValues<T extends Comparable<T>> extends
return instantiate(ComparisonType.EQUAL_TO, value);
}
public static <T extends Comparable<T>> Constraint<T> instantiate(
ComparisonType type, T value) {
if (value == null) {
public static <T extends Comparable<T>> Constraint<T> instantiate(ComparisonType type, T value) {
if ( value == null ) {
return Constraint.voidConstraint();
}
return new ConstraintOnComparableValues<T>(type, value);
}
@ -70,21 +67,28 @@ public class ConstraintOnComparableValues<T extends Comparable<T>> extends
@Override
@SuppressWarnings("unchecked")
protected T applyConstraintTo(T value) {
if (value == null) {
if ( value == null ) {
return comparisonValue;
}
switch (comparisonType) {
case LESS_OR_EQUAL_THAN:
return min(comparisonValue, value);
case LESS_OR_EQUAL_THAN_RIGHT_FLOATING:
case BIGGER_OR_EQUAL_THAN_LEFT_FLOATING:
return comparisonValue;
case BIGGER_OR_EQUAL_THAN:
return max(comparisonValue, value);
case EQUAL_TO:
return comparisonValue;
default:
throw new RuntimeException("can't handle "+comparisonType);
case LESS_OR_EQUAL_THAN:
return min(comparisonValue, value);
case LESS_OR_EQUAL_THAN_RIGHT_FLOATING:
case BIGGER_OR_EQUAL_THAN_LEFT_FLOATING:
return comparisonValue;
case BIGGER_OR_EQUAL_THAN:
return max(comparisonValue, value);
case EQUAL_TO:
return comparisonValue;
default:
throw new RuntimeException("can't handle "+comparisonType);
}
}
@ -99,16 +103,22 @@ public class ConstraintOnComparableValues<T extends Comparable<T>> extends
@Override
public boolean isSatisfiedBy(T value) {
switch (comparisonType) {
case LESS_OR_EQUAL_THAN:
case LESS_OR_EQUAL_THAN_RIGHT_FLOATING:
return value.compareTo(comparisonValue) <= 0;
case BIGGER_OR_EQUAL_THAN:
case BIGGER_OR_EQUAL_THAN_LEFT_FLOATING:
return value.compareTo(comparisonValue) >= 0;
case EQUAL_TO:
return value.compareTo(comparisonValue) == 0;
default:
throw new RuntimeException("can't handle " + comparisonType);
case LESS_OR_EQUAL_THAN:
case LESS_OR_EQUAL_THAN_RIGHT_FLOATING:
return value.compareTo(comparisonValue) <= 0;
case BIGGER_OR_EQUAL_THAN:
case BIGGER_OR_EQUAL_THAN_LEFT_FLOATING:
return value.compareTo(comparisonValue) >= 0;
case EQUAL_TO:
return value.compareTo(comparisonValue) == 0;
default:
throw new RuntimeException("can't handle " + comparisonType);
}
}

View file

@ -21,7 +21,7 @@
package org.zkoss.ganttz.data.resourceload;
import org.apache.commons.lang.Validate;
import org.apache.commons.lang3.Validate;
public class LoadLevel {
@ -33,18 +33,21 @@ public class LoadLevel {
return percentage == 0;
}
},
SOME_LOAD {
@Override
public boolean contains(int percentage) {
return percentage > 0 && percentage < 100;
}
},
FULL_LOAD {
@Override
public boolean contains(int percentage) {
return percentage == 100;
}
},
OVERLOAD {
@Override
public boolean contains(int percentage) {
@ -55,10 +58,11 @@ public class LoadLevel {
protected abstract boolean contains(int percentage);
public static Category categoryFor(int percentage) {
for (Category category : values()) {
if (category.contains(percentage)) {
if ( category.contains(percentage) ) {
return category;
}
}
throw new IllegalArgumentException("couldn't handle " + percentage);
}
}

View file

@ -27,8 +27,8 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.apache.commons.lang.Validate;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.zkoss.ganttz.data.GanttDate;
@ -47,14 +47,20 @@ public class LoadPeriod {
private final String assignedEffort;
public LoadPeriod(GanttDate start, GanttDate end, String availableEffort,
String assignedEffort, LoadLevel loadLevel) {
public LoadPeriod(
GanttDate start,
GanttDate end,
String availableEffort,
String assignedEffort,
LoadLevel loadLevel) {
Validate.notNull(start);
Validate.notNull(end);
Validate.notNull(loadLevel);
Validate.notNull(availableEffort);
Validate.notNull(assignedEffort);
Validate.isTrue(start.compareTo(end) <= 0);
this.start = start;
this.end = end;
this.loadLevel = loadLevel;
@ -80,27 +86,28 @@ public class LoadPeriod {
* @throws IllegalArgumentException
* if some of the LoadPeriod overlaps
*/
public static List<LoadPeriod> sort(
Collection<? extends LoadPeriod> notOverlappingPeriods)
public static List<LoadPeriod> sort(Collection<? extends LoadPeriod> notOverlappingPeriods)
throws IllegalArgumentException {
ArrayList<LoadPeriod> result = new ArrayList<LoadPeriod>(
notOverlappingPeriods);
ArrayList<LoadPeriod> result = new ArrayList<>(notOverlappingPeriods);
Collections.sort(result, new Comparator<LoadPeriod>() {
@Override
public int compare(LoadPeriod o1, LoadPeriod o2) {
if (o1.overlaps(o2)) {
if ( o1.overlaps(o2) ) {
LOG.warn(o1 + " overlaps with " + o2);
throw new IllegalArgumentException(o1 + " overlaps with "
+ o2);
throw new IllegalArgumentException(o1 + " overlaps with " + o2);
}
int comparison = o1.start.compareTo(o2.start);
if (comparison != 0) {
if ( comparison != 0 ) {
return comparison;
}
return o1.end.compareTo(o2.end);
}
});
return result;
}

View file

@ -27,7 +27,7 @@ import java.util.Comparator;
import java.util.List;
import org.apache.commons.collections.ComparatorUtils;
import org.apache.commons.lang.Validate;
import org.apache.commons.lang3.Validate;
import org.joda.time.LocalDate;
import org.zkoss.ganttz.data.GanttDate;
import org.zkoss.ganttz.util.Interval;
@ -35,20 +35,19 @@ import org.zkoss.ganttz.util.Interval;
public class LoadTimeLine {
@SuppressWarnings("unchecked")
private static final Comparator<GanttDate> nullSafeComparator = ComparatorUtils
.nullLowComparator(ComparatorUtils.naturalComparator());
private static final Comparator<GanttDate> nullSafeComparator =
ComparatorUtils.nullLowComparator(ComparatorUtils.naturalComparator());
public static Comparator<LoadTimeLine> byStartAndEndDate() {
return new Comparator<LoadTimeLine>() {
@Override
public int compare(LoadTimeLine o1, LoadTimeLine o2) {
int result = nullSafeComparator.compare(o1.getStartPeriod(),
o2.getStartPeriod());
if (result == 0) {
return nullSafeComparator.compare(o1.getEndPeriod(),
o2.getEndPeriod());
int result = nullSafeComparator.compare(o1.getStartPeriod(), o2.getStartPeriod());
if ( result == 0 ) {
return nullSafeComparator.compare(o1.getEndPeriod(), o2.getEndPeriod());
}
return result;
}
@ -63,40 +62,43 @@ public class LoadTimeLine {
private final List<LoadTimeLine> children;
public LoadTimeLine(String conceptName, List<LoadPeriod> loadPeriods,
TimeLineRole<?> role) {
public LoadTimeLine(String conceptName,
List<LoadPeriod> loadPeriods,
TimeLineRole<?> role) {
Validate.notEmpty(conceptName);
Validate.notNull(loadPeriods);
this.loadPeriods = LoadPeriod.sort(loadPeriods);
this.conceptName = conceptName;
this.type = "";
this.timeLineRole = role;
this.children = Collections
.unmodifiableList(new ArrayList<LoadTimeLine>());
this.children = Collections.unmodifiableList(new ArrayList<LoadTimeLine>());
}
public LoadTimeLine(String conceptName, List<LoadPeriod> loadPeriods,
String type, TimeLineRole<?> role) {
public LoadTimeLine(String conceptName, List<LoadPeriod> loadPeriods, String type, TimeLineRole<?> role) {
Validate.notEmpty(conceptName);
Validate.notNull(loadPeriods);
this.loadPeriods = LoadPeriod.sort(loadPeriods);
this.conceptName = conceptName;
this.timeLineRole = role;
this.type = type;
this.children = Collections
.unmodifiableList(new ArrayList<LoadTimeLine>());
this.children = Collections.unmodifiableList(new ArrayList<LoadTimeLine>());
}
public LoadTimeLine(LoadTimeLine main, List<LoadTimeLine> children) {
Validate.notEmpty(main.getConceptName());
Validate.notNull(main.getLoadPeriods());
this.loadPeriods = LoadPeriod.sort(main.getLoadPeriods());
this.conceptName = main.getConceptName();
this.timeLineRole = main.getRole();
this.type = main.getType();
Validate.notNull(children);
this.children = Collections
.unmodifiableList(new ArrayList<LoadTimeLine>(children));
this.children = Collections.unmodifiableList(new ArrayList<>(children));
}
@ -121,9 +123,10 @@ public class LoadTimeLine {
}
public GanttDate getStartPeriod() {
if (isEmpty()) {
if ( isEmpty() ) {
return null;
}
return getFirst().getStart();
}
@ -132,9 +135,10 @@ public class LoadTimeLine {
}
public GanttDate getEndPeriod() {
if (isEmpty()) {
if ( isEmpty() ) {
return null;
}
return getLast().getEnd();
}
@ -145,38 +149,46 @@ public class LoadTimeLine {
public static Interval getIntervalFrom(List<LoadTimeLine> timeLines) {
GanttDate start = null;
GanttDate end = null;
for (LoadTimeLine loadTimeLine : timeLines) {
if(!loadTimeLine.isEmpty()) {
if( !loadTimeLine.isEmpty() ) {
Validate.notNull(loadTimeLine.getStart());
start = min(start, loadTimeLine.getStart());
Validate.notNull(loadTimeLine.getEnd());
end = max(end, loadTimeLine.getEnd());
}
}
if (timeLines.isEmpty() || start == null || end == null) {
if ( timeLines.isEmpty() || start == null || end == null ) {
LocalDate localDateNow = new LocalDate();
return new Interval(localDateNow, localDateNow.plusYears(5));
}
return new Interval(start.toLocalDate(), end.asExclusiveEnd());
}
private static GanttDate max(GanttDate one, GanttDate other) {
if (one == null) {
if ( one == null ) {
return other;
}
if (other == null) {
if ( other == null ) {
return one;
}
return one.compareTo(other) > 0 ? one : other;
}
private static GanttDate min(GanttDate one, GanttDate other) {
if (one == null) {
if ( one == null ) {
return other;
}
if (other == null) {
if ( other == null ) {
return one;
}
return one.compareTo(other) < 0 ? one : other;
}
@ -189,35 +201,39 @@ public class LoadTimeLine {
}
public List<LoadTimeLine> getAllChildren() {
List<LoadTimeLine> result = new ArrayList<LoadTimeLine>();
List<LoadTimeLine> result = new ArrayList<>();
for (LoadTimeLine child : children) {
result.add(child);
result.addAll(child.getAllChildren());
}
return result;
}
public GanttDate getStart() {
GanttDate result = getStartPeriod();
for (LoadTimeLine loadTimeLine : getChildren()) {
GanttDate start = loadTimeLine.getStart();
if (start != null) {
result = result == null || result.compareTo(start) > 0 ? start
: result;
if ( start != null ) {
result = result == null || result.compareTo(start) > 0 ? start : result;
}
}
return result;
}
public GanttDate getEnd() {
GanttDate result = getEndPeriod();
for (LoadTimeLine loadTimeLine : getChildren()) {
GanttDate end = loadTimeLine.getEnd();
if (end != null) {
result = result == null || result.compareTo(end) < 0 ? end
: result;
if ( end != null ) {
result = result == null || result.compareTo(end) < 0 ? end : result;
}
}
return result;
}

View file

@ -20,7 +20,7 @@
*/
package org.zkoss.ganttz.extensions;
import org.apache.commons.lang.Validate;
import org.apache.commons.lang3.Validate;
import org.zkoss.zk.ui.Component;

View file

@ -25,7 +25,7 @@ import static org.zkoss.ganttz.i18n.I18nHelper._;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.LocalDate;
import org.zkoss.ganttz.IChartVisibilityChangedListener;
import org.zkoss.ganttz.data.resourceload.LoadTimeLine;
@ -53,14 +53,15 @@ import org.zkoss.zul.SimpleListModel;
import org.zkoss.zul.api.Combobox;
import org.zkoss.zul.api.Listbox;
import org.zkoss.zul.api.South;
public class ResourcesLoadPanel extends HtmlMacroComponent {
public interface IToolbarCommand {
public void doAction();
void doAction();
public String getLabel();
String getLabel();
public String getImage();
String getImage();
}
private TimeTrackerComponent timeTrackerComponent;
@ -81,8 +82,7 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
private final Component componentOnWhichGiveFeedback;
private WeakReferencedListeners<IFilterChangedListener> zoomListeners = WeakReferencedListeners
.create();
private WeakReferencedListeners<IFilterChangedListener> zoomListeners = WeakReferencedListeners.create();
private Listbox listZoomLevels;
@ -98,14 +98,14 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
private final PaginationType paginationType;
private WeakReferencedListeners<IPaginationFilterChangedListener> nameFilterListener =
WeakReferencedListeners.create();
WeakReferencedListeners.create();
private Component loadChart;
private boolean visibleChart = true;
private WeakReferencedListeners<IChartVisibilityChangedListener> chartVisibilityListeners = WeakReferencedListeners
.create();
private WeakReferencedListeners<IChartVisibilityChangedListener> chartVisibilityListeners =
WeakReferencedListeners.create();
private final boolean expandResourceLoadViewCharts;
@ -113,12 +113,17 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
private Component secondOptionalFilter;
public ResourcesLoadPanel(List<LoadTimeLine> groups,
TimeTracker timeTracker, Component componentOnWhichGiveFeedback,
boolean expandResourceLoadViewCharts, PaginationType paginationType) {
public ResourcesLoadPanel(
List<LoadTimeLine> groups,
TimeTracker timeTracker,
Component componentOnWhichGiveFeedback,
boolean expandResourceLoadViewCharts,
PaginationType paginationType) {
this.componentOnWhichGiveFeedback = componentOnWhichGiveFeedback;
this.expandResourceLoadViewCharts = expandResourceLoadViewCharts;
this.paginationType = paginationType;
init(groups, timeTracker);
}
@ -138,17 +143,19 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
public ListModel getFilters() {
String[] filters = new String[] { FILTER_RESOURCES, FILTER_CRITERIA };
return new SimpleListModel(filters);
}
public void setFilter(String filterby) {
if (filterby.equals(FILTER_RESOURCES)) {
if ( filterby.equals(FILTER_RESOURCES) ) {
this.filterbyResources = true;
this.feedBackMessage = _("showing resources");
} else {
this.filterbyResources = false;
this.feedBackMessage = _("showing criteria");
}
refreshNameFilter = true;
filterByNamePosition = 0;
invalidatingChangeHappenedWithFeedback();
@ -159,19 +166,17 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
}
private void invalidatingChangeHappenedWithFeedback() {
LongOperationFeedback.execute(componentOnWhichGiveFeedback,
new ILongOperation() {
LongOperationFeedback.execute(componentOnWhichGiveFeedback, new ILongOperation() {
@Override
public void doAction() {
applyFilter();
}
@Override
public void doAction() {
applyFilter();
}
@Override
public String getName() {
return getFeedBackMessage();
}
});
@Override
public String getName() {
return getFeedBackMessage();
}
});
}
private String getFeedBackMessage() {
@ -179,13 +184,12 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
}
private void applyFilter() {
zoomListeners
.fireEvent(new IListenerNotification<IFilterChangedListener>() {
@Override
public void doNotify(IFilterChangedListener listener) {
listener.filterChanged(getFilter());
}
});
zoomListeners.fireEvent(new IListenerNotification<IFilterChangedListener>() {
@Override
public void doNotify(IFilterChangedListener listener) {
listener.filterChanged(getFilter());
}
});
}
public void addFilterListener(IFilterChangedListener listener) {
@ -193,9 +197,13 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
}
public ListModel getZoomLevels() {
ZoomLevel[] selectableZoomlevels = { ZoomLevel.DETAIL_ONE,
ZoomLevel.DETAIL_TWO, ZoomLevel.DETAIL_THREE,
ZoomLevel.DETAIL_FOUR, ZoomLevel.DETAIL_FIVE };
ZoomLevel[] selectableZoomlevels = {
ZoomLevel.DETAIL_ONE,
ZoomLevel.DETAIL_TWO,
ZoomLevel.DETAIL_THREE,
ZoomLevel.DETAIL_FOUR,
ZoomLevel.DETAIL_FIVE };
return new SimpleListModel(selectableZoomlevels);
}
@ -239,6 +247,7 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
Component toolbar = getToolbar();
resetToolbar(toolbar);
Separator separator = getSeparator();
for (IToolbarCommand c : commands) {
toolbar.insertBefore(asButton(c), separator);
}
@ -246,8 +255,8 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
private void resetToolbar(Component toolbar) {
List<Component> children = toolbar.getChildren();
List<Button> buttons = ComponentsFinder.findComponentsOfType(
Button.class, children);
List<Button> buttons = ComponentsFinder.findComponentsOfType(Button.class, children);
for (Button b : buttons) {
toolbar.removeChild(b);
}
@ -255,63 +264,66 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
private Button asButton(final IToolbarCommand c) {
Button result = new Button();
result.addEventListener(Events.ON_CLICK, new EventListener() {
@Override
public void onEvent(Event event) {
c.doAction();
}
});
if (!StringUtils.isEmpty(c.getImage())) {
if ( !StringUtils.isEmpty(c.getImage()) ) {
result.setImage(c.getImage());
result.setTooltiptext(c.getLabel());
} else {
result.setLabel(c.getLabel());
}
return result;
}
@SuppressWarnings("unchecked")
private Separator getSeparator() {
List<Component> children = getToolbar().getChildren();
Separator separator = ComponentsFinder.findComponentsOfType(
Separator.class, children).get(0);
Separator separator = ComponentsFinder.findComponentsOfType(Separator.class, children).get(0);
return separator;
}
private Component getToolbar() {
Component toolbar = getFellow("toolbar");
return toolbar;
}
private MutableTreeModel<LoadTimeLine> createModelForTree() {
MutableTreeModel<LoadTimeLine> result = MutableTreeModel
.create(LoadTimeLine.class);
MutableTreeModel<LoadTimeLine> result = MutableTreeModel.create(LoadTimeLine.class);
for (LoadTimeLine loadTimeLine : this.getGroupsToShow()) {
result.addToRoot(loadTimeLine);
result = addNodes(result, loadTimeLine);
}
return result;
}
private MutableTreeModel<LoadTimeLine> addNodes(
MutableTreeModel<LoadTimeLine> tree, LoadTimeLine parent) {
if (!parent.getChildren().isEmpty()) {
private MutableTreeModel<LoadTimeLine> addNodes(MutableTreeModel<LoadTimeLine> tree, LoadTimeLine parent) {
if ( !parent.getChildren().isEmpty() ) {
tree.add(parent, parent.getChildren());
for (LoadTimeLine loadTimeLine : parent.getChildren()) {
tree = addNodes(tree, loadTimeLine);
}
}
return tree;
}
private TimeTrackerComponent timeTrackerForResourcesLoadPanel(
TimeTracker timeTracker) {
private TimeTrackerComponent timeTrackerForResourcesLoadPanel(TimeTracker timeTracker) {
return new TimeTrackerComponent(timeTracker) {
@Override
protected void scrollHorizontalPercentage(int daysDisplacement) {
response("", new AuInvoke(resourceLoadList,
"scroll_horizontal", daysDisplacement + ""));
response("", new AuInvoke(resourceLoadList, "scroll_horizontal", daysDisplacement + ""));
moveCurrentPositionScroll();
}
@ -321,20 +333,18 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
LocalDate previousStart = getPreviousStart();
// get the current data
int diffDays = getTimeTrackerComponent().getDiffDays(
previousStart);
int diffDays = getTimeTrackerComponent().getDiffDays(previousStart);
double pixelPerDay = getTimeTrackerComponent().getPixelPerDay();
response("move_scroll", new AuInvoke(resourceLoadList,
"move_scroll", "" + diffDays, "" + pixelPerDay));
response("move_scroll", new AuInvoke(resourceLoadList, "move_scroll", "" + diffDays, "" + pixelPerDay));
}
protected void updateCurrentDayScroll() {
double previousPixelPerDay = getTimeTracker().getMapper()
.getPixelsPerDay().doubleValue();
double previousPixelPerDay = getTimeTracker().getMapper().getPixelsPerDay().doubleValue();
response("update_day_scroll", new AuInvoke(resourceLoadList,
"update_day_scroll", "" + previousPixelPerDay));
response(
"update_day_scroll",
new AuInvoke(resourceLoadList, "update_day_scroll", "" + previousPixelPerDay));
}
};
@ -354,11 +364,12 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
// Insert additional filters if any
Component additionalFilter = getFirstOptionalFilter();
if(additionalFilter != null) {
if( additionalFilter != null ) {
getFellow("additionalFilterInsertionPoint1").appendChild(additionalFilter);
}
additionalFilter = getSecondOptionalFilter();
if(additionalFilter != null) {
if( additionalFilter != null ) {
getFellow("additionalFilterInsertionPoint2").appendChild(additionalFilter);
}
@ -367,10 +378,10 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
listZoomLevels = (Listbox) getFellow("listZoomLevels");
listZoomLevels.setSelectedIndex(timeTracker.getDetailLevel().ordinal());
if(paginationType == PaginationType.INTERNAL_PAGINATION && refreshNameFilter) {
if( paginationType == PaginationType.INTERNAL_PAGINATION && refreshNameFilter ) {
setupNameFilter();
}
else if(paginationType == PaginationType.NONE) {
else if( paginationType == PaginationType.NONE ) {
getFellow("filterByNameCombo").setVisible(false);
getFellow("filterByNameLabel").setVisible(false);
}
@ -406,8 +417,7 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
}
private TimeTrackerComponent createTimeTrackerHeader() {
return new TimeTrackerComponent(
timeTracker) {
return new TimeTrackerComponent(timeTracker) {
@Override
protected void scrollHorizontalPercentage(int pixelsDisplacement) {
@ -415,20 +425,15 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
@Override
protected void moveCurrentPositionScroll() {
// TODO Auto-generated method stub
}
@Override
protected void updateCurrentDayScroll() {
// TODO Auto-generated method stub
}
};
}
public void addSeeScheduledOfListener(
ISeeScheduledOfListener seeScheduledOfListener) {
public void addSeeScheduledOfListener(ISeeScheduledOfListener seeScheduledOfListener) {
leftPane.addSeeScheduledOfListener(seeScheduledOfListener);
resourceLoadList.addSeeScheduledOfListener(seeScheduledOfListener);
}
@ -438,19 +443,19 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
filterByNameCombo.getChildren().clear();
int size = groups.size();
if(size > numberOfGroupsByName) {
if( size > numberOfGroupsByName ) {
int position = 0;
while(position < size) {
String firstName = groups.get(position).getConceptName();
String lastName;
int newPosition = position + numberOfGroupsByName;
if(newPosition - 1 < size) {
lastName = groups.get(newPosition - 1)
.getConceptName();
if( newPosition - 1 < size ) {
lastName = groups.get(newPosition - 1).getConceptName();
}
else {
lastName = groups.get(size - 1)
.getConceptName();
lastName = groups.get(size - 1).getConceptName();
}
Comboitem item = new Comboitem();
@ -478,34 +483,34 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
* @return
*/
private List<LoadTimeLine> getGroupsToShow() {
if(paginationType != PaginationType.INTERNAL_PAGINATION ||
filterByNamePosition == -1) {
if( paginationType != PaginationType.INTERNAL_PAGINATION || filterByNamePosition == -1 ) {
return groups;
}
int endPosition =
(filterByNamePosition + numberOfGroupsByName < groups.size())?
filterByNamePosition + numberOfGroupsByName :
groups.size();
boolean condition = (filterByNamePosition + numberOfGroupsByName < groups.size());
int endPosition = condition ? filterByNamePosition + numberOfGroupsByName : groups.size();
return groups.subList(filterByNamePosition, endPosition);
}
public void onSelectFilterByName(Combobox comboByName) {
if (comboByName.getSelectedItemApi() == null) {
if ( comboByName.getSelectedItemApi() == null ) {
resetComboByName(comboByName);
} else {
Integer filterByNamePosition = (Integer) comboByName
.getSelectedItemApi().getValue();
if (paginationType != PaginationType.NONE) {
this.filterByNamePosition = filterByNamePosition.intValue();
Integer filterByNamePosition = (Integer) comboByName.getSelectedItemApi().getValue();
if ( paginationType != PaginationType.NONE ) {
this.filterByNamePosition = filterByNamePosition;
this.lastSelectedName = comboByName.getSelectedIndex();
this.feedBackMessage = _("filtering by name");
changeNameFilterWithFeedback();
}
}
}
private void resetComboByName(Combobox comboByName) {
if (this.lastSelectedName == -1) {
if ( this.lastSelectedName == -1 ) {
comboByName.setSelectedIndex(0);
} else {
comboByName.setSelectedIndex(this.lastSelectedName);
@ -514,24 +519,26 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
}
private void changeNameFilterWithFeedback() {
LongOperationFeedback.execute(componentOnWhichGiveFeedback,
new ILongOperation() {
LongOperationFeedback.execute(componentOnWhichGiveFeedback, new ILongOperation() {
@Override
public void doAction() {
if(paginationType == PaginationType.INTERNAL_PAGINATION) {
if( paginationType == PaginationType.INTERNAL_PAGINATION ) {
//if the pagination is internal, we are in charge of repainting the graph
treeModel = createModelForTree();
timeTrackerComponent = timeTrackerForResourcesLoadPanel(timeTracker);
resourceLoadList = new ResourceLoadList(timeTracker, treeModel);
leftPane = new ResourceLoadLeftPane(treeModel, resourceLoadList);
}
nameFilterListener.fireEvent(new IListenerNotification<IPaginationFilterChangedListener>() {
@Override
public void doNotify(IPaginationFilterChangedListener listener) {
listener.filterChanged(filterByNamePosition);
}
});
afterCompose();
}
@ -544,36 +551,31 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
public void setInternalPaginationDisabled(boolean disabled) {
Combobox combo = ((Combobox) getFellow("filterByNameCombo"));
if (combo != null && combo.isDisabled() != disabled) {
filterByNamePosition = disabled? -1 :
((Integer)combo.getSelectedItemApi().getValue()).intValue();
if ( combo != null && combo.isDisabled() != disabled ) {
filterByNamePosition = disabled? -1 : (Integer) combo.getSelectedItemApi().getValue();
combo.setDisabled(disabled);
}
}
public void addPaginationFilterListener(
IPaginationFilterChangedListener iFilterChangedListener) {
public void addPaginationFilterListener(IPaginationFilterChangedListener iFilterChangedListener) {
nameFilterListener.addListener(iFilterChangedListener);
}
public void changeChartVisibility(boolean visible) {
visibleChart = visible;
chartVisibilityListeners
.fireEvent(new IListenerNotification<IChartVisibilityChangedListener>() {
@Override
public void doNotify(
IChartVisibilityChangedListener listener) {
listener.chartVisibilityChanged(visibleChart);
}
});
chartVisibilityListeners.fireEvent(new IListenerNotification<IChartVisibilityChangedListener>() {
@Override
public void doNotify(IChartVisibilityChangedListener listener) {
listener.chartVisibilityChanged(visibleChart);
}
});
}
public boolean isVisibleChart() {
return visibleChart;
}
public void addChartVisibilityListener(
IChartVisibilityChangedListener chartVisibilityChangedListener) {
public void addChartVisibilityListener(IChartVisibilityChangedListener chartVisibilityChangedListener) {
chartVisibilityListeners.addListener(chartVisibilityChangedListener);
}
@ -586,9 +588,10 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
}
public Combobox getPaginationFilterCombobox() {
if(paginationType == PaginationType.EXTERNAL_PAGINATION) {
if( paginationType == PaginationType.EXTERNAL_PAGINATION ) {
return (Combobox) getFellow("filterByNameCombo");
}
return null;
}
@ -606,7 +609,7 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
/**
* Disables pagination. Shows all the LoadTimeLine objects received.
*/
NONE;
NONE
}
}

View file

@ -37,7 +37,7 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.Validate;
import org.apache.commons.lang3.Validate;
import org.zkoss.web.servlet.http.HttpServlet;
/**
@ -49,20 +49,16 @@ public class CallbackServlet extends HttpServlet {
private static final String MAPPING = "/callback/";
private static final long CLEANING_PERIOD_MILLIS = 1000 * 60 * 1; // one
// minute
// minutes
private static final long CLEANING_PERIOD_MILLIS = 1000 * 60; // one minute
private static Random random = new Random();
private static ConcurrentMap<String, IHandler> handlersCallbacks = new ConcurrentHashMap<String, IHandler>();
private static ConcurrentMap<String, IHandler> handlersCallbacks = new ConcurrentHashMap<>();
private static Timer cleaningTimer = new Timer(true);
public interface IServletRequestHandler {
public void handle(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException;
void handle(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException;
}
public enum DisposalMode {
@ -72,26 +68,24 @@ public class CallbackServlet extends HttpServlet {
return new WeakReferencedHandler(handler);
}
},
AFTER_TEN_MINUTES {
@Override
public IHandler create(IServletRequestHandler handler) {
return new BasedOnExpirationTimeHandler(handler,
tenMinutesInMillis);
return new BasedOnExpirationTimeHandler(handler, tenMinutesInMillis);
}
};
private static final long tenMinutesInMillis = TimeUnit.MILLISECONDS
.convert(10, TimeUnit.MINUTES);
private static final long tenMinutesInMillis = TimeUnit.MILLISECONDS.convert(10, TimeUnit.MINUTES);
public abstract IHandler create(
IServletRequestHandler handler);
public abstract IHandler create(IServletRequestHandler handler);
}
private interface IHandler {
abstract boolean hasExpired();
boolean hasExpired();
abstract IServletRequestHandler getHandler();
IServletRequestHandler getHandler();
}
private static class BasedOnExpirationTimeHandler implements IHandler {
@ -101,9 +95,9 @@ public class CallbackServlet extends HttpServlet {
private final long creationTime;
private final long expirationTimeMilliseconds;
public BasedOnExpirationTimeHandler(IServletRequestHandler handler,
long expirationTimeMilliseconds) {
public BasedOnExpirationTimeHandler(IServletRequestHandler handler, long expirationTimeMilliseconds) {
Validate.notNull(handler);
this.handler = handler;
this.creationTime = System.currentTimeMillis();
this.expirationTimeMilliseconds = expirationTimeMilliseconds;
@ -125,7 +119,7 @@ public class CallbackServlet extends HttpServlet {
private final WeakReference<IServletRequestHandler> handler;
WeakReferencedHandler(IServletRequestHandler handler) {
this.handler = new WeakReference<IServletRequestHandler>(handler);
this.handler = new WeakReference<>(handler);
}
@Override
@ -140,40 +134,44 @@ public class CallbackServlet extends HttpServlet {
}
public static String registerAndCreateURLFor(HttpServletRequest request,
IServletRequestHandler handler) {
return registerAndCreateURLFor(request, handler,
DisposalMode.AFTER_TEN_MINUTES);
public static String registerAndCreateURLFor(HttpServletRequest request, IServletRequestHandler handler) {
return registerAndCreateURLFor(request, handler, DisposalMode.AFTER_TEN_MINUTES);
}
public static String registerAndCreateURLFor(HttpServletRequest request,
IServletRequestHandler handler, DisposalMode disposalMode) {
public static String registerAndCreateURLFor(HttpServletRequest request, IServletRequestHandler handler,
DisposalMode disposalMode) {
return registerAndCreateURLFor(request, handler, true, disposalMode);
}
public static String registerAndCreateURLFor(HttpServletRequest request,
IServletRequestHandler handler, boolean withContextPath) {
return registerAndCreateURLFor(request, handler, withContextPath,
DisposalMode.AFTER_TEN_MINUTES);
public static String registerAndCreateURLFor(HttpServletRequest request, IServletRequestHandler handler,
boolean withContextPath) {
return registerAndCreateURLFor(request, handler, withContextPath, DisposalMode.AFTER_TEN_MINUTES);
}
public static String registerAndCreateURLFor(HttpServletRequest request,
IServletRequestHandler handler, boolean withContextPath,
DisposalMode disposalMode) {
IServletRequestHandler handler,
boolean withContextPath,
DisposalMode disposalMode) {
Validate.notNull(disposalMode);
// theoretically could be an infinite loop, could be improved.
String generatedKey = "";
String generatedKey;
IHandler toBeRegistered = disposalMode.create(handler);
do {
generatedKey = generateKey();
} while (handlersCallbacks.putIfAbsent(generatedKey, toBeRegistered) != null);
return buildURLFromKey(request, generatedKey, withContextPath);
}
private static synchronized String buildURLFromKey(
HttpServletRequest request, String generatedKey,
boolean withContextPath) {
private static synchronized String buildURLFromKey(HttpServletRequest request, String generatedKey,
boolean withContextPath) {
String contextPath = withContextPath ? request.getContextPath() : "";
return contextPath + MAPPING + generatedKey;
}
@ -182,9 +180,10 @@ public class CallbackServlet extends HttpServlet {
}
private static String getId(String pathInfo) {
if (pathInfo.startsWith("/")) {
if ( pathInfo.startsWith("/") ) {
return pathInfo.substring(1);
}
return pathInfo;
}
@ -199,14 +198,15 @@ public class CallbackServlet extends HttpServlet {
}
private static List<String> findExpired() {
ArrayList<Entry<String, IHandler>> handlersList = new ArrayList<Entry<String, IHandler>>(
handlersCallbacks.entrySet());
List<String> expired = new ArrayList<String>();
ArrayList<Entry<String, IHandler>> handlersList = new ArrayList<>(handlersCallbacks.entrySet());
List<String> expired = new ArrayList<>();
for (Entry<String, IHandler> entry : handlersList) {
if (entry.getValue().hasExpired()) {
if ( entry.getValue().hasExpired() ) {
expired.add(entry.getKey());
}
}
return expired;
}
@ -217,8 +217,7 @@ public class CallbackServlet extends HttpServlet {
}
private void scheduleTimer() {
cleaningTimer.schedule(cleaningTask(), CLEANING_PERIOD_MILLIS,
CLEANING_PERIOD_MILLIS);
cleaningTimer.schedule(cleaningTask(), CLEANING_PERIOD_MILLIS, CLEANING_PERIOD_MILLIS);
}
private TimerTask cleaningTask() {
@ -231,11 +230,11 @@ public class CallbackServlet extends HttpServlet {
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String callbackId = getId(req.getPathInfo());
IServletRequestHandler handler = handlerFor(callbackId);
if (handler == null) {
if ( handler == null ) {
resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
} else {
handler.handle(req, resp);
@ -244,6 +243,7 @@ public class CallbackServlet extends HttpServlet {
private IServletRequestHandler handlerFor(String callbackId) {
IHandler h = handlersCallbacks.get(callbackId);
return h != null ? h.getHandler() : null;
}

View file

@ -27,32 +27,36 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.apache.commons.lang.Validate;
import org.apache.commons.lang3.Validate;
import org.zkoss.zk.ui.Component;
import org.zkoss.zul.Row;
import org.zkoss.zul.RowRenderer;
public class OnColumnsRowRenderer<C, T> implements RowRenderer {
public static <C, T> OnColumnsRowRenderer<C, T> create(
ICellForDetailItemRenderer<C, T> cellRenderer, Collection<C> columns) {
public static <C, T> OnColumnsRowRenderer<C, T> create(ICellForDetailItemRenderer<C, T> cellRenderer,
Collection<C> columns) {
return create(inferGenericType(cellRenderer), cellRenderer, columns);
}
public static <C, T> OnColumnsRowRenderer<C, T> create(Class<T> type,
ICellForDetailItemRenderer<C, T> cellRenderer, Collection<C> columns) {
return new OnColumnsRowRenderer<C, T>(type, cellRenderer, columns);
ICellForDetailItemRenderer<C, T> cellRenderer,
Collection<C> columns) {
return new OnColumnsRowRenderer<>(type, cellRenderer, columns);
}
private static <T> Class<T> inferGenericType(
ICellForDetailItemRenderer<?, T> renderer) {
private static <T> Class<T> inferGenericType(ICellForDetailItemRenderer<?, T> renderer) {
ParameterizedType parametrizedType = findRenderererInterfaceType(renderer);
Type[] actualTypeArguments = parametrizedType.getActualTypeArguments();
final int genericTypePosition = 1;
Type type = actualTypeArguments[genericTypePosition];
if (!isActualType(type)) {
if ( !isActualType(type) ) {
informCannotBeInferred(renderer);
}
return (Class<T>) actualTypeArguments[genericTypePosition];
}
@ -60,39 +64,41 @@ public class OnColumnsRowRenderer<C, T> implements RowRenderer {
return t instanceof Class;
}
private static ParameterizedType findRenderererInterfaceType(
ICellForDetailItemRenderer<?, ?> renderer) {
private static ParameterizedType findRenderererInterfaceType(ICellForDetailItemRenderer<?, ?> renderer) {
Type[] genericInterfaces = renderer.getClass().getGenericInterfaces();
for (Type type : genericInterfaces) {
if (isTypeForInterface(type, ICellForDetailItemRenderer.class)) {
if (type instanceof ParameterizedType) {
if ( isTypeForInterface(type, ICellForDetailItemRenderer.class) ) {
if ( type instanceof ParameterizedType ) {
return (ParameterizedType) type;
} else {
informCannotBeInferred(renderer);
}
}
}
throw new RuntimeException("shouldn't reach here. Uncovered case for "
+ renderer);
throw new RuntimeException("shouldn't reach here. Uncovered case for " + renderer);
}
private static boolean isTypeForInterface(Type type,
Class<?> interfaceBeingSearched) {
if (type instanceof ParameterizedType) {
private static boolean isTypeForInterface(Type type, Class<?> interfaceBeingSearched) {
if ( type instanceof ParameterizedType ) {
ParameterizedType p = (ParameterizedType) type;
Type rawType = p.getRawType();
return rawType.equals(interfaceBeingSearched);
}
return type.equals(interfaceBeingSearched);
}
private static void informCannotBeInferred(
ICellForDetailItemRenderer<?, ?> renderer) {
private static void informCannotBeInferred(ICellForDetailItemRenderer<?, ?> renderer) {
throw new IllegalArgumentException(
"the generic type cannot be inferred "
+ "if actual type parameters are not declared "
+ "or implements the raw interface: "
+ renderer.getClass().getName());
"the generic type cannot be inferred " +
"if actual type parameters are not declared " +
"or implements the raw interface: " +
renderer.getClass().getName());
}
private final List<C> columns;
@ -100,22 +106,24 @@ public class OnColumnsRowRenderer<C, T> implements RowRenderer {
private Class<T> type;
private OnColumnsRowRenderer(Class<T> type,
ICellForDetailItemRenderer<C, T> cellRenderer, Collection<C> columns) {
ICellForDetailItemRenderer<C, T> cellRenderer,
Collection<C> columns) {
Validate.notNull(type);
Validate.notNull(columns);
Validate.notNull(cellRenderer);
Validate.noNullElements(columns);
this.cellRenderer = cellRenderer;
this.columns = new ArrayList<C>(columns);
this.columns = new ArrayList<>(columns);
this.type = type;
}
@Override
public void render(Row row, Object data) {
if (!type.isInstance(data)) {
throw new IllegalArgumentException(data + " is not instance of "
+ type);
if ( !type.isInstance(data) ) {
throw new IllegalArgumentException(data + " is not instance of " + type);
}
for (C item : columns) {
Component child = cellRenderer.cellFor(item, type.cast(data));
child.setParent(row);

View file

@ -28,7 +28,7 @@ import java.beans.PropertyChangeListener;
import java.util.Collection;
import java.util.Date;
import org.apache.commons.lang.Validate;
import org.apache.commons.lang3.Validate;
import org.joda.time.LocalDate;
import org.zkoss.ganttz.DatesMapperOnInterval;
import org.zkoss.ganttz.IDatesMapper;
@ -50,22 +50,19 @@ public class TimeTracker {
public interface IDetailItemFilter {
public Collection<DetailItem> selectsFirstLevel(
Collection<DetailItem> firstLevelDetails);
Collection<DetailItem> selectsFirstLevel(Collection<DetailItem> firstLevelDetails);
public Collection<DetailItem> selectsSecondLevel(
Collection<DetailItem> secondLevelDetails);
Collection<DetailItem> selectsSecondLevel(Collection<DetailItem> secondLevelDetails);
public Interval getCurrentPaginationInterval();
Interval getCurrentPaginationInterval();
public void resetInterval();
void resetInterval();
}
private ZoomLevel detailLevel = ZoomLevel.DETAIL_ONE;
private WeakReferencedListeners<IZoomLevelChangedListener> zoomListeners = WeakReferencedListeners
.create();
private WeakReferencedListeners<IZoomLevelChangedListener> zoomListeners = WeakReferencedListeners.create();
private IDatesMapper datesMapper = null;
@ -90,35 +87,38 @@ public class TimeTracker {
}
public TimeTracker(Interval interval, ZoomLevel zoomLevel, Component parent) {
this(interval, zoomLevel, SeveralModificators.empty(),
SeveralModificators.empty(), parent);
this(interval, zoomLevel, SeveralModificators.empty(), SeveralModificators.empty(), parent);
}
public TimeTracker(Interval interval, Component componentOnWhichGiveFeedback) {
this(interval, SeveralModificators.empty(),
SeveralModificators.empty(), componentOnWhichGiveFeedback);
this(interval, SeveralModificators.empty(), SeveralModificators.empty(), componentOnWhichGiveFeedback);
}
public TimeTracker(Interval interval,
public TimeTracker(
Interval interval,
IDetailItemModificator firstLevelModificator,
IDetailItemModificator secondLevelModificator,
Component componentOnWhichGiveFeedback) {
Validate.notNull(interval);
Validate.notNull(firstLevelModificator);
Validate.notNull(secondLevelModificator);
Validate.notNull(componentOnWhichGiveFeedback);
this.interval = interval;
this.firstLevelModificator = firstLevelModificator;
this.secondLevelModificator = secondLevelModificator;
this.componentOnWhichGiveFeedback = componentOnWhichGiveFeedback;
}
public TimeTracker(Interval interval, ZoomLevel zoomLevel,
public TimeTracker(
Interval interval,
ZoomLevel zoomLevel,
IDetailItemModificator firstLevelModificator,
IDetailItemModificator secondLevelModificator,
Component componentOnWhichGiveFeedback) {
this(interval, firstLevelModificator, secondLevelModificator,
componentOnWhichGiveFeedback);
this(interval, firstLevelModificator, secondLevelModificator, componentOnWhichGiveFeedback);
detailLevel = zoomLevel;
}
@ -136,60 +136,58 @@ public class TimeTracker {
}
public Collection<DetailItem> getDetailsFirstLevel() {
if (detailsFirstLevelCached == null) {
detailsFirstLevelCached = getTimeTrackerState()
.getFirstLevelDetails(interval);
if ( detailsFirstLevelCached == null ) {
detailsFirstLevelCached = getTimeTrackerState().getFirstLevelDetails(interval);
}
return filterFirstLevel(detailsFirstLevelCached);
}
private Collection<DetailItem> filterFirstLevel(
Collection<DetailItem> firstLevelDetails) {
if (filter == null) {
private Collection<DetailItem> filterFirstLevel(Collection<DetailItem> firstLevelDetails) {
if ( filter == null ) {
return firstLevelDetails;
}
return filter.selectsFirstLevel(firstLevelDetails);
}
public Collection<DetailItem> getDetailsSecondLevel() {
if (detailsSecondLevelCached == null) {
detailsSecondLevelCached = getTimeTrackerState()
.getSecondLevelDetails(interval);
if ( detailsSecondLevelCached == null ) {
detailsSecondLevelCached = getTimeTrackerState().getSecondLevelDetails(interval);
}
return filterSecondLevel(detailsSecondLevelCached);
}
private Collection<DetailItem> filterSecondLevel(
Collection<DetailItem> secondLevelDetails) {
if (filter == null) {
private Collection<DetailItem> filterSecondLevel(Collection<DetailItem> secondLevelDetails) {
if ( filter == null ) {
return secondLevelDetails;
}
return filter.selectsSecondLevel(secondLevelDetails);
}
private Interval realIntervalCached;
public Interval getRealInterval() {
if (realIntervalCached == null) {
realIntervalCached = getTimeTrackerState().getRealIntervalFor(
interval);
if ( realIntervalCached == null ) {
realIntervalCached = getTimeTrackerState().getRealIntervalFor(interval);
}
return realIntervalCached;
}
public TimeTrackerState getTimeTrackerState() {
return detailLevel.getTimeTrackerState(firstLevelModificator,
secondLevelModificator);
return detailLevel.getTimeTrackerState(firstLevelModificator, secondLevelModificator);
}
private void fireZoomChanged() {
zoomListeners
.fireEvent(new IListenerNotification<IZoomLevelChangedListener>() {
@Override
public void doNotify(IZoomLevelChangedListener listener) {
listener.zoomLevelChanged(detailLevel);
}
});
zoomListeners.fireEvent(new IListenerNotification<IZoomLevelChangedListener>() {
@Override
public void doNotify(IZoomLevelChangedListener listener) {
listener.zoomLevelChanged(detailLevel);
}
});
}
public int getHorizontalSize() {
@ -197,6 +195,7 @@ public class TimeTracker {
for (DetailItem detailItem : getDetailsSecondLevel()) {
horizontalSize += detailItem.getSize();
}
return horizontalSize;
}
@ -212,15 +211,14 @@ public class TimeTracker {
}
public IDatesMapper getMapper() {
if (datesMapper == null) {
if (filter == null) {
datesMapper = new DatesMapperOnInterval(getHorizontalSize(),
getRealInterval());
if ( datesMapper == null ) {
if ( filter == null ) {
datesMapper = new DatesMapperOnInterval(getHorizontalSize(), getRealInterval());
} else {
datesMapper = new DatesMapperOnInterval(getHorizontalSize(),
filter.getCurrentPaginationInterval());
datesMapper = new DatesMapperOnInterval(getHorizontalSize(), filter.getCurrentPaginationInterval());
}
}
return datesMapper;
}
@ -230,19 +228,17 @@ public class TimeTracker {
}
private void invalidatingChangeHappenedWithFeedback() {
LongOperationFeedback.execute(componentOnWhichGiveFeedback,
new ILongOperation() {
LongOperationFeedback.execute(componentOnWhichGiveFeedback, new ILongOperation() {
@Override
public void doAction() {
invalidatingChangeHappened();
}
@Override
public void doAction() {
invalidatingChangeHappened();
}
@Override
public String getName() {
return _("changing zoom");
}
});
@Override
public String getName() {
return _("changing zoom");
}
});
}
public void setZoomLevel(ZoomLevel zoomLevel) {
@ -261,40 +257,38 @@ public class TimeTracker {
}
public void trackPosition(final Task task) {
task
.addFundamentalPropertiesChangeListener(new PropertyChangeListener() {
task.addFundamentalPropertiesChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
updateIntervalIfNeeded(task);
}
});
@Override
public void propertyChange(PropertyChangeEvent evt) {
updateIntervalIfNeeded(task);
}
});
updateIntervalIfNeeded(task);
}
private void updateIntervalIfNeeded(Task task) {
if (registeredFirstTask == false) {
if ( !registeredFirstTask ) {
registeredFirstTask = true;
interval = new Interval(startMinusTwoWeeks(task),
endPlusOneMonth(task));
interval = new Interval(startMinusTwoWeeks(task), endPlusOneMonth(task));
invalidatingChangeHappened();
} else {
LocalDate newStart = interval.getStart();
LocalDate newFinish = interval.getFinish();
boolean changed = false;
if (interval.getStart().compareTo(startMinusTwoWeeks(task)) > 0) {
if ( interval.getStart().compareTo(startMinusTwoWeeks(task) ) > 0) {
newStart = startMinusTwoWeeks(task);
changed = true;
}
if (interval.getFinish()
.compareTo(endPlusOneMonth(task)) < 0) {
if ( interval.getFinish().compareTo(endPlusOneMonth(task)) < 0 ) {
newFinish = endPlusOneMonth(task);
changed = true;
}
if (changed) {
if ( changed ) {
interval = new Interval(newStart, newFinish);
invalidatingChangeHappened();
}
@ -302,39 +296,43 @@ public class TimeTracker {
}
private Date max(Date date1, Date date2) {
if (date1 == null) {
if ( date1 == null ) {
return date2;
}
if (date2 == null) {
if ( date2 == null ) {
return date1;
}
return date1.compareTo(date2) > 0 ? date1 : date2;
}
private Date min(Date date1, Date date2) {
if (date1 == null) {
if ( date1 == null ) {
return date2;
}
if (date2 == null) {
if ( date2 == null ) {
return date1;
}
return date1.compareTo(date2) <= 0 ? date1 : date2;
}
private LocalDate endPlusOneMonth(Task task) {
Date taskEnd = max(task.getEndDate().toDayRoundedDate(),
task.getDeadline());
Date taskEnd = max(task.getEndDate().toDayRoundedDate(), task.getDeadline());
return new LocalDate(taskEnd).plusMonths(1);
}
private LocalDate startMinusTwoWeeks(Task task) {
// the deadline could be before the start
Date start = min(task.getBeginDate().toDayRoundedDate(),
task.getDeadline());
Date start = min(task.getBeginDate().toDayRoundedDate(), task.getDeadline());
// the last consolidated value could be before the start
if (task.getConsolidatedline() != null) {
if ( task.getConsolidatedline() != null ) {
start = min(start, task.getConsolidatedline().toDayRoundedDate());
}
return new LocalDate(start).minusWeeks(2);
}

View file

@ -26,7 +26,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.apache.commons.lang.Validate;
import org.apache.commons.lang3.Validate;
/**
* @author Óscar González Fernández <ogonzalez@igalia.com>
@ -35,26 +35,22 @@ import org.apache.commons.lang.Validate;
public class SeveralModificators implements IDetailItemModificator {
public static IDetailItemModificator empty() {
return new SeveralModificators(Collections
.<IDetailItemModificator> emptyList());
return new SeveralModificators(Collections.<IDetailItemModificator> emptyList());
}
public static IDetailItemModificator create(
IDetailItemModificator... modificators) {
public static IDetailItemModificator create(IDetailItemModificator... modificators) {
return new SeveralModificators(Arrays.asList(modificators));
}
public static IDetailItemModificator create(
Collection<? extends IDetailItemModificator> modificators) {
public static IDetailItemModificator create(Collection<? extends IDetailItemModificator> modificators) {
return new SeveralModificators(modificators);
}
private final List<IDetailItemModificator> modificators;
private SeveralModificators(
Collection<? extends IDetailItemModificator> modificators) {
private SeveralModificators(Collection<? extends IDetailItemModificator> modificators) {
Validate.noNullElements(modificators);
this.modificators = new ArrayList<IDetailItemModificator>(modificators);
this.modificators = new ArrayList<>(modificators);
}
@Override
@ -63,6 +59,7 @@ public class SeveralModificators implements IDetailItemModificator {
for (IDetailItemModificator each : modificators) {
result = each.applyModificationsTo(result, z);
}
return result;
}

View file

@ -22,7 +22,7 @@ package org.zkoss.ganttz.timetracker.zoom;
import java.util.Iterator;
import org.apache.commons.lang.Validate;
import org.apache.commons.lang3.Validate;
import org.joda.time.LocalDate;
import org.joda.time.ReadablePeriod;
@ -30,16 +30,17 @@ import org.joda.time.ReadablePeriod;
* @author Óscar González Fernández
*
*/
public abstract class TimeTrackerStateWithSubintervalsFitting extends
TimeTrackerState {
public abstract class TimeTrackerStateWithSubintervalsFitting extends TimeTrackerState {
protected TimeTrackerStateWithSubintervalsFitting(
IDetailItemModificator firstLevelModificator,
IDetailItemModificator secondLevelModificator) {
super(firstLevelModificator, secondLevelModificator);
}
private final class PeriodicalGenerator extends LazyGenerator<LocalDate> {
private final ReadablePeriod period;
private PeriodicalGenerator(LocalDate first, ReadablePeriod period) {
@ -55,8 +56,7 @@ public abstract class TimeTrackerStateWithSubintervalsFitting extends
}
@Override
protected Iterator<LocalDate> getPeriodsFirstLevelGenerator(
final LocalDate start) {
protected Iterator<LocalDate> getPeriodsFirstLevelGenerator(final LocalDate start) {
return new PeriodicalGenerator(start, getPeriodFirstLevel());
}

View file

@ -19,9 +19,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
*
*/
package org.zkoss.ganttz.util;
import static java.util.Arrays.asList;
@ -29,8 +26,8 @@ import static java.util.Arrays.asList;
import java.util.Collections;
import java.util.Date;
import org.apache.commons.lang.Validate;
import org.apache.commons.lang.math.Fraction;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.math.Fraction;
import org.joda.time.DateTime;
import org.joda.time.Days;
import org.joda.time.Duration;
@ -54,13 +51,15 @@ public class Interval {
Validate.notNull(startInclusive);
Validate.notNull(endExclusive);
Validate.isTrue(endExclusive.isAfter(startInclusive));
this.startInclusive = startInclusive;
this.endExclusive = endExclusive;
this.lengthBetween = new Duration(
this.startInclusive.toDateTimeAtStartOfDay(),
this.endExclusive.toDateTimeAtStartOfDay());
this.daysBetween = Days.daysBetween(this.startInclusive,
this.endExclusive);
this.daysBetween = Days.daysBetween(this.startInclusive, this.endExclusive);
}
public Days getDaysBetween() {
@ -80,10 +79,9 @@ public class Interval {
}
public Fraction getProportion(DateTime date) {
Days fromStartToDate = Days.daysBetween(startInclusive,
date.toLocalDate());
Fraction result = Fraction.getFraction(fromStartToDate.getDays(),
this.daysBetween.getDays());
Days fromStartToDate = Days.daysBetween(startInclusive, date.toLocalDate());
Fraction result = Fraction.getFraction(fromStartToDate.getDays(), this.daysBetween.getDays());
try {
return result.add(inTheDayIncrement(date));
} catch (ArithmeticException e) {
@ -94,18 +92,17 @@ public class Interval {
private Fraction inTheDayIncrement(DateTime date) {
DateTime atStartOfDay = date.toLocalDate().toDateTimeAtStartOfDay();
Duration duration = new Duration(atStartOfDay, date);
double result = ((double) duration.getMillis())
/ lengthBetween.getMillis();
double result = ((double) duration.getMillis()) / lengthBetween.getMillis();
return Fraction.getFraction(result);
}
@SuppressWarnings("unchecked")
public Interval coalesce(Interval otherInterval) {
Validate.notNull(otherInterval);
LocalDate minStart = Collections.min(asList(startInclusive,
otherInterval.startInclusive));
LocalDate maxEnd = Collections.max(asList(endExclusive,
otherInterval.endExclusive));
LocalDate minStart = Collections.min(asList(startInclusive, otherInterval.startInclusive));
LocalDate maxEnd = Collections.max(asList(endExclusive, otherInterval.endExclusive));
return new Interval(minStart, maxEnd);
}
}

View file

@ -28,7 +28,7 @@ import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import org.apache.commons.lang.Validate;
import org.apache.commons.lang3.Validate;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.zkoss.zk.ui.Component;
@ -46,8 +46,7 @@ import org.zkoss.zk.ui.util.Clients;
*/
public class LongOperationFeedback {
private static final Log LOG = LogFactory
.getLog(LongOperationFeedback.class);
private static final Log LOG = LogFactory.getLog(LongOperationFeedback.class);
public interface ILongOperation {
void doAction() throws Exception;
@ -62,12 +61,11 @@ public class LongOperationFeedback {
}
};
public static void execute(final Component component,
final ILongOperation longOperation) {
public static void execute(final Component component, final ILongOperation longOperation) {
Validate.notNull(component);
Validate.notNull(longOperation);
if (alreadyInside.get()) {
if ( alreadyInside.get() ) {
dispatchActionDirectly(longOperation);
return;
}
@ -88,10 +86,10 @@ public class LongOperationFeedback {
});
}
public static void executeLater(final Component component,
final Runnable runnable) {
public static void executeLater(final Component component, final Runnable runnable) {
Validate.notNull(runnable);
Validate.notNull(component);
final String eventName = generateEventName();
component.addEventListener(eventName, new EventListener() {
@ -105,11 +103,11 @@ public class LongOperationFeedback {
}
}
});
Events.echoEvent(eventName, component, null);
}
private static void dispatchActionDirectly(
final ILongOperation longOperation) {
private static void dispatchActionDirectly(final ILongOperation longOperation) {
try {
longOperation.doAction();
} catch (Exception e) {
@ -125,11 +123,11 @@ public class LongOperationFeedback {
}
public interface IDesktopUpdatesEmitter<T> {
public void doUpdate(T value);
void doUpdate(T value);
}
public interface IDesktopUpdate {
public void doUpdate();
void doUpdate();
}
public static IDesktopUpdate and(final IDesktopUpdate... desktopUpdates) {
@ -145,11 +143,10 @@ public class LongOperationFeedback {
}
public interface IBackGroundOperation<T> {
public void doOperation(IDesktopUpdatesEmitter<T> desktopUpdateEmitter);
void doOperation(IDesktopUpdatesEmitter<T> desktopUpdateEmitter);
}
private static final ExecutorService executor = Executors
.newCachedThreadPool();
private static final ExecutorService executor = Executors.newCachedThreadPool();
public static <T> IDesktopUpdatesEmitter<T> doNothingEmitter() {
return new IDesktopUpdatesEmitter<T>() {
@ -164,16 +161,13 @@ public class LongOperationFeedback {
* {@link IDesktopUpdate} objects that can update desktop state. Trying to
* update the components in any other way would fail
*/
public static void progressive(final Desktop desktop,
final IBackGroundOperation<IDesktopUpdate> operation) {
progressive(desktop, operation,
new IDesktopUpdatesEmitter<IDesktopUpdate>() {
@Override
public void doUpdate(IDesktopUpdate update) {
update.doUpdate();
}
});
public static void progressive(final Desktop desktop, final IBackGroundOperation<IDesktopUpdate> operation) {
progressive(desktop, operation, new IDesktopUpdatesEmitter<IDesktopUpdate>() {
@Override
public void doUpdate(IDesktopUpdate update) {
update.doUpdate();
}
});
}
/**
@ -182,15 +176,17 @@ public class LongOperationFeedback {
* {@link IDesktopUpdatesEmitter} that handle these objects is necessary.
* Trying to update the components in any other way would fail.
*/
public static <T> void progressive(final Desktop desktop,
public static <T> void progressive(
final Desktop desktop,
final IBackGroundOperation<T> operation,
final IDesktopUpdatesEmitter<T> emitter) {
desktop.enableServerPush(true);
executor.execute(new Runnable() {
public void run() {
try {
IBackGroundOperation<T> operationWithAsyncUpates = withAsyncUpates(
operation, desktop);
IBackGroundOperation<T> operationWithAsyncUpates = withAsyncUpates(operation, desktop);
operationWithAsyncUpates.doOperation(emitter);
} catch (Exception e) {
LOG.error("error executing background operation", e);
@ -204,14 +200,16 @@ public class LongOperationFeedback {
private static <T> IBackGroundOperation<T> withAsyncUpates(
final IBackGroundOperation<T> backgroundOperation,
final Desktop desktop) {
return new IBackGroundOperation<T>() {
return new IBackGroundOperation<T>() {
@Override
public void doOperation(
IDesktopUpdatesEmitter<T> originalEmitter) {
NotBlockingDesktopUpdates<T> notBlockingDesktopUpdates = new NotBlockingDesktopUpdates<T>(
desktop, originalEmitter);
public void doOperation(IDesktopUpdatesEmitter<T> originalEmitter) {
NotBlockingDesktopUpdates<T> notBlockingDesktopUpdates =
new NotBlockingDesktopUpdates<T>(desktop, originalEmitter);
Future<?> future = executor.submit(notBlockingDesktopUpdates);
try {
backgroundOperation.doOperation(notBlockingDesktopUpdates);
} finally {
@ -230,15 +228,13 @@ public class LongOperationFeedback {
};
}
private static class NotBlockingDesktopUpdates<T> implements
IDesktopUpdatesEmitter<T>, Runnable {
private static class NotBlockingDesktopUpdates<T> implements IDesktopUpdatesEmitter<T>, Runnable {
private BlockingQueue<EndOrValue<T>> queue = new LinkedBlockingQueue<EndOrValue<T>>();
private BlockingQueue<EndOrValue<T>> queue = new LinkedBlockingQueue<>();
private final IDesktopUpdatesEmitter<T> original;
private final Desktop desktop;
NotBlockingDesktopUpdates(Desktop desktop,
IDesktopUpdatesEmitter<T> original) {
NotBlockingDesktopUpdates(Desktop desktop, IDesktopUpdatesEmitter<T> original) {
this.original = original;
this.desktop = desktop;
}
@ -254,40 +250,48 @@ public class LongOperationFeedback {
@Override
public void run() {
List<T> batch = new ArrayList<T>();
List<T> batch = new ArrayList<>();
while (true) {
batch.clear();
EndOrValue<T> current = null;
EndOrValue<T> current;
try {
current = queue.take();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
if (current.isEnd()) {
if ( current.isEnd() ) {
return;
}
if (!desktop.isAlive() || !desktop.isServerPushEnabled()) {
if ( !desktop.isAlive() || !desktop.isServerPushEnabled() ) {
return;
}
try {
Executions.activate(desktop);
} catch (Exception e) {
LOG.error("unable to access desktop", e);
throw new RuntimeException(e);
}
try {
original.doUpdate(current.getValue());
while ((current = queue.poll()) != null) {
if (current.isEnd()) {
if ( current.isEnd() ) {
break;
}
batch.add(current.getValue());
original.doUpdate(current.getValue());
}
} finally {
Executions.deactivate(desktop);
}
if (current != null && current.isEnd()) {
if ( current != null && current.isEnd() ) {
return;
}
}
@ -297,11 +301,11 @@ public class LongOperationFeedback {
private static abstract class EndOrValue<T> {
public static <T> EndOrValue<T> end() {
return new End<T>();
return new End<>();
}
public static <T> EndOrValue<T> value(T value) {
return new Value<T>(value);
return new Value<>(value);
}
public abstract boolean isEnd();

View file

@ -21,7 +21,7 @@
package org.zkoss.ganttz.util;
import org.apache.commons.lang.Validate;
import org.apache.commons.lang3.Validate;
import org.zkoss.zk.ui.Desktop;
import org.zkoss.zk.ui.Executions;
@ -37,6 +37,7 @@ public class OnZKDesktopRegistry<T> {
public OnZKDesktopRegistry(Class<T> klass) {
Validate.notNull(klass);
this.klass = klass;
this.attributeName = klass.getName() + "_locator";
}
@ -51,6 +52,7 @@ public class OnZKDesktopRegistry<T> {
public boolean isRegistered() {
Object result = get();
return result != null;
}
@ -59,10 +61,10 @@ public class OnZKDesktopRegistry<T> {
}
public T retrieve() throws IllegalStateException {
if (!isRegistered()) {
throw new IllegalStateException("no " + klass.getSimpleName()
+ " registered");
if ( !isRegistered() ) {
throw new IllegalStateException("no " + klass.getSimpleName() + " registered");
}
return klass.cast(get());
}

View file

@ -20,7 +20,7 @@
*/
package org.zkoss.ganttz.util;
import org.apache.commons.lang.Validate;
import org.apache.commons.lang3.Validate;
/**
* @author Óscar González Fernández <ogonzalez@igalia.com>
@ -38,7 +38,7 @@ public abstract class PreAndPostNotReentrantActionsWrapper {
public void doAction(IAction action) {
Validate.notNull(action);
if (inside.get()) {
if ( inside.get() ) {
action.doAction();
} else {
executeWithPreAndPostActions(action);

View file

@ -27,7 +27,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import org.apache.commons.lang.Validate;
import org.apache.commons.lang3.Validate;
public class WeakReferencedListeners<T> {
@ -38,10 +38,10 @@ public class WeakReferencedListeners<T> {
}
public static <T> WeakReferencedListeners<T> create() {
return new WeakReferencedListeners<T>();
return new WeakReferencedListeners<>();
}
private LinkedList<WeakReference<T>> listeners = new LinkedList<WeakReference<T>>();
private LinkedList<WeakReference<T>> listeners = new LinkedList<>();
private WeakReferencedListeners() {
@ -58,13 +58,13 @@ public class WeakReferencedListeners<T> {
public synchronized void addListener(T listener, Mode mode) {
Validate.notNull(listener);
if (getActiveListeners().isEmpty() && mode == Mode.RECEIVE_PENDING) {
if ( getActiveListeners().isEmpty() && mode == Mode.RECEIVE_PENDING ) {
notifyPendingOfNotificationTo(listener);
}
listeners.add(new WeakReference<T>(listener));
}
private List<IListenerNotification<? super T>> pendingOfNotification = new ArrayList<WeakReferencedListeners.IListenerNotification<? super T>>();
private List<IListenerNotification<? super T>> pendingOfNotification = new ArrayList<>();
private void notifyPendingOfNotificationTo(T listener) {
for (IListenerNotification<? super T> each : pendingOfNotification) {
@ -73,30 +73,31 @@ public class WeakReferencedListeners<T> {
pendingOfNotification.clear();
}
public synchronized void fireEvent(
IListenerNotification<? super T> notification) {
public synchronized void fireEvent(IListenerNotification<? super T> notification) {
List<T> active = getActiveListeners();
for (T listener : active) {
notification.doNotify(listener);
}
if (active.isEmpty()) {
if ( active.isEmpty() ) {
pendingOfNotification.add(notification);
}
}
private List<T> getActiveListeners() {
ListIterator<WeakReference<T>> listIterator = listeners.listIterator();
List<T> result = new ArrayList<T>();
List<T> result = new ArrayList<>();
while (listIterator.hasNext()) {
T listener = listIterator.next().get();
if (listener == null) {
if ( listener == null ) {
listIterator.remove();
} else {
result.add(listener);
}
}
return result;
}
}

View file

@ -50,8 +50,7 @@ public class LoadPeriodTest {
}
private void givenExampleLoadPeriod(LocalDate start, LocalDate end) {
givenExampleLoadPeriod(GanttDate.createFrom(start),
GanttDate.createFrom(end));
givenExampleLoadPeriod(GanttDate.createFrom(start), GanttDate.createFrom(end));
}
private void givenExampleLoadPeriod(GanttDate start, GanttDate end) {
@ -59,16 +58,13 @@ public class LoadPeriodTest {
givenExampleLoadPeriod(start, end, loadLevel);
}
private void givenExampleLoadPeriod(GanttDate start, GanttDate end,
LoadLevel loadLevel) {
loadPeriod = new LoadPeriod(start, end, totalHours, assignedHours,
loadLevel);
private void givenExampleLoadPeriod(GanttDate start, GanttDate end, LoadLevel loadLevel) {
loadPeriod = new LoadPeriod(start, end, totalHours, assignedHours, loadLevel);
}
@Test(expected = IllegalArgumentException.class)
@Test(expected = NullPointerException.class)
public void aLoadPeriodMustHaveAStartDate() {
new LoadPeriod(null, GanttDate.createFrom(new LocalDate()), totalHours,
assignedHours, correctLoadLevel());
new LoadPeriod(null, GanttDate.createFrom(new LocalDate()), totalHours, assignedHours, correctLoadLevel());
}
private static final String totalHours = "100";
@ -79,26 +75,33 @@ public class LoadPeriodTest {
return new LoadLevel(40);
}
@Test(expected = IllegalArgumentException.class)
@Test(expected = NullPointerException.class)
public void aLoadPeriodMustHaveAnEndDate() {
new LoadPeriod(GanttDate.createFrom(new LocalDate()), null, totalHours,
assignedHours, correctLoadLevel());
new LoadPeriod(GanttDate.createFrom(new LocalDate()), null, totalHours, assignedHours, correctLoadLevel());
}
@Test(expected = IllegalArgumentException.class)
public void theEndDateCantBeBeforeTheStartDate() {
LocalDate start = new LocalDate(2009, 10, 4);
LocalDate end = new LocalDate(2009, 10, 3);
new LoadPeriod(GanttDate.createFrom(start), GanttDate.createFrom(end),
totalHours, assignedHours, correctLoadLevel());
new LoadPeriod(
GanttDate.createFrom(start),
GanttDate.createFrom(end),
totalHours, assignedHours,
correctLoadLevel());
}
@Test
public void theEndDateCanBeTheSameThanTheStartDate() {
LocalDate start = new LocalDate(2009, 10, 4);
LocalDate end = new LocalDate(2009, 10, 4);
new LoadPeriod(GanttDate.createFrom(start), GanttDate.createFrom(end),
totalHours, assignedHours, correctLoadLevel());
new LoadPeriod(
GanttDate.createFrom(start),
GanttDate.createFrom(end),
totalHours, assignedHours,
correctLoadLevel());
}
@Test
@ -115,8 +118,8 @@ public class LoadPeriodTest {
@Test
public void twoLoadPeriodOverlapCanOverlap() {
givenExampleLoadPeriod(new LocalDate(2009, 11, 1), new LocalDate(2009,
12, 1));
givenExampleLoadPeriod(new LocalDate(2009, 11, 1), new LocalDate(2009, 12, 1));
assertTrue(loadPeriod.overlaps(create(2009, 11, 2, 2009, 11, 3)));
assertTrue(loadPeriod.overlaps(create(2009, 10, 30, 2009, 11, 2)));
assertTrue(loadPeriod.overlaps(create(2009, 10, 20, 2009, 12, 2)));
@ -128,31 +131,31 @@ public class LoadPeriodTest {
@Test
// [start, end)
public void startInclusiveButEndExclusive() {
givenExampleLoadPeriod(new LocalDate(2009, 11, 1), new LocalDate(2009,
12, 1));
givenExampleLoadPeriod(new LocalDate(2009, 11, 1), new LocalDate(2009, 12, 1));
assertFalse(loadPeriod.overlaps(create(2009, 12, 1, 2009, 12, 3)));
assertFalse(loadPeriod.overlaps(create(2009, 10, 1, 2009, 11, 1)));
}
@Test
public void pointDontOverlap() {
givenExampleLoadPeriod(new LocalDate(2009, 11, 1), new LocalDate(2009,
12, 1));
givenExampleLoadPeriod(new LocalDate(2009, 11, 1), new LocalDate(2009, 12, 1));
assertFalse(loadPeriod.overlaps(create(2009, 11, 1, 2009, 11, 1)));
}
private static LoadPeriod create(int startYear, int startMonth,
int startDay, int endYear, int endMonth, int endDay) {
return new LoadPeriod(GanttDate.createFrom(new LocalDate(startYear,
startMonth, startDay)), GanttDate.createFrom(new LocalDate(
endYear, endMonth, endDay)), totalHours,
assignedHours, correctLoadLevel());
private static LoadPeriod create(
int startYear, int startMonth, int startDay, int endYear, int endMonth, int endDay) {
return new LoadPeriod(
GanttDate.createFrom(new LocalDate(startYear, startMonth, startDay)),
GanttDate.createFrom(new LocalDate(endYear, endMonth, endDay)),
totalHours, assignedHours,
correctLoadLevel());
}
@Test(expected = IllegalArgumentException.class)
public void loadPeriodsThatOverlapCannotBeSorted() {
LoadPeriod.sort(Arrays.asList(create(2009, 4, 10, 2010, 1, 12), create(
2009, 4, 11, 2011, 1, 20)));
LoadPeriod.sort(Arrays.asList(create(2009, 4, 10, 2010, 1, 12), create(2009, 4, 11, 2011, 1, 20)));
}
@Test
@ -164,15 +167,16 @@ public class LoadPeriodTest {
@Test
public void aZeroDaysLoadPeriodStartingTheSameDateThanANoZeroDaysLoadPeriodGoesAfter() {
givenUnsortedListOfPeriods(create(2009, 4, 10, 2010, 1, 12), create(
2009, 4, 10, 2009, 4, 10));
givenUnsortedListOfPeriods(create(2009, 4, 10, 2010, 1, 12), create(2009, 4, 10, 2009, 4, 10));
List<LoadPeriod> sorted = LoadPeriod.sort(unsortedList);
thenIsSorted(sorted);
}
private void givenUnsortedListOfPeriods() {
givenUnsortedListOfPeriods(create(2009, 4, 10, 2010, 1, 12), create(
2010, 1, 12, 2010, 1, 12), create(2010, 2, 13, 2010, 5, 7),
givenUnsortedListOfPeriods(
create(2009, 4, 10, 2010, 1, 12),
create(2010, 1, 12, 2010, 1, 12),
create(2010, 2, 13, 2010, 5, 7),
create(2009, 3, 5, 2009, 3, 10));
}
@ -182,18 +186,19 @@ public class LoadPeriodTest {
private void thenIsSorted(List<LoadPeriod> sorted) {
ListIterator<LoadPeriod> listIterator = sorted.listIterator();
LoadPeriod previous = null;
LoadPeriod previous;
LoadPeriod current = null;
while (listIterator.hasNext()) {
previous = current;
current = listIterator.next();
if (previous != null) {
if ( previous != null ) {
assertFalse(current.getStart().compareTo(previous.getEnd()) < 0);
}
}
}
@Test(expected = IllegalArgumentException.class)
@Test(expected = NullPointerException.class)
public void aLoadPeriodMustHaveANotNullLoadLevel() {
givenExampleLoadPeriod();
new LoadPeriod(start, end, totalHours, assignedHours, null);

View file

@ -39,7 +39,7 @@ public class LoadTimelineTest {
private LoadTimeLine loadTimeLine;
private String conceptName;
@Test(expected = IllegalArgumentException.class)
@Test(expected = NullPointerException.class)
public void aLoadTimelineMustHaveANotNullName() {
new LoadTimeLine(null, Collections.<LoadPeriod> emptyList(), null);
}
@ -49,7 +49,7 @@ public class LoadTimelineTest {
new LoadTimeLine("", Collections.<LoadPeriod> emptyList(), null);
}
@Test(expected = IllegalArgumentException.class)
@Test(expected = NullPointerException.class)
public void aLoadTimelineCannotHaveNullLoadPeriods() {
new LoadTimeLine("bla", null, null);
}
@ -62,30 +62,34 @@ public class LoadTimelineTest {
private void givenValidLoadTimeLine() {
conceptName = "bla";
loadTimeLine = new LoadTimeLine(conceptName,
loadTimeLine = new LoadTimeLine(
conceptName,
Arrays.asList(new LoadPeriod(GanttDate
.createFrom(new LocalDate(2009, 10, 5)), GanttDate
.createFrom(new LocalDate(2009, 10, 11)), "100", "20",
new LoadLevel(20))), null);
new LoadLevel(20))),
null);
}
@Test
public void aLoadTimelineWithZeroLoadPeriodsIsEmpty() {
LoadTimeLine timeline = new LoadTimeLine("bla", Collections
.<LoadPeriod> emptyList(), null);
LoadTimeLine timeline = new LoadTimeLine("bla", Collections.<LoadPeriod> emptyList(), null);
assertTrue(timeline.isEmpty());
}
@Test
public void aLoadTimelineSortsItsReceivedPeriods() {
LoadPeriod l1 = new LoadPeriod(GanttDate.createFrom(new LocalDate(2009,
10, 5)), GanttDate.createFrom(new LocalDate(2009, 10, 11)),
LoadPeriod l1 = new LoadPeriod(
GanttDate.createFrom(new LocalDate(2009, 10, 5)),
GanttDate.createFrom(new LocalDate(2009, 10, 11)),
"100", "20", new LoadLevel(20));
LoadPeriod l2 = new LoadPeriod(GanttDate.createFrom(new LocalDate(2009,
5, 3)), GanttDate.createFrom(new LocalDate(2009, 6, 3)), "100",
"20", new LoadLevel(20));
LoadTimeLine loadTimeLine = new LoadTimeLine("bla", Arrays.asList(l1,
l2), null);
LoadPeriod l2 = new LoadPeriod(
GanttDate.createFrom(new LocalDate(2009, 5, 3)),
GanttDate.createFrom(new LocalDate(2009, 6, 3)),
"100", "20", new LoadLevel(20));
LoadTimeLine loadTimeLine = new LoadTimeLine("bla", Arrays.asList(l1, l2), null);
List<LoadPeriod> loadPeriods = loadTimeLine.getLoadPeriods();
assertThat(loadPeriods.get(0), sameInstance(l2));
@ -94,12 +98,16 @@ public class LoadTimelineTest {
@Test(expected = IllegalArgumentException.class)
public void theLoadPeriodsMustNotOverlap() {
LoadPeriod l1 = new LoadPeriod(GanttDate.createFrom(new LocalDate(2009,
10, 5)), GanttDate.createFrom(new LocalDate(2009, 10, 11)),
LoadPeriod l1 = new LoadPeriod(
GanttDate.createFrom(new LocalDate(2009, 10, 5)),
GanttDate.createFrom(new LocalDate(2009, 10, 11)),
"100", "20", new LoadLevel(20));
LoadPeriod l2 = new LoadPeriod(GanttDate.createFrom(new LocalDate(2009,
5, 3)), GanttDate.createFrom(new LocalDate(2009, 10, 10)),
LoadPeriod l2 = new LoadPeriod(
GanttDate.createFrom(new LocalDate(2009, 5, 3)),
GanttDate.createFrom(new LocalDate(2009, 10, 10)),
"100", "20", new LoadLevel(20));
new LoadTimeLine("bla", Arrays.asList(l1, l2), null);
}

View file

@ -47,8 +47,7 @@ public class OnColumnsRowRendererTest {
}
private static class CellRenderer implements
ICellForDetailItemRenderer<DetailItem, Data> {
private static class CellRenderer implements ICellForDetailItemRenderer<DetailItem, Data> {
@Override
public Component cellFor(DetailItem item, Data data) {
@ -57,8 +56,7 @@ public class OnColumnsRowRendererTest {
}
private static class CellRendererNotInferable<T> implements
ICellForDetailItemRenderer<DetailItem, T> {
private static class CellRendererNotInferable<T> implements ICellForDetailItemRenderer<DetailItem, T> {
@Override
public Component cellFor(DetailItem item, T data) {
@ -75,20 +73,19 @@ public class OnColumnsRowRendererTest {
private List<Data> data;
private void givenOnDetailItemsRowRenderer(
ICellForDetailItemRenderer<DetailItem, Data> cellRenderer) {
if (detailItems == null) {
private void givenOnDetailItemsRowRenderer(ICellForDetailItemRenderer<DetailItem, Data> cellRenderer) {
if ( detailItems == null ) {
givenDetailItems();
}
rowRenderer = OnColumnsRowRenderer.create(Data.class, cellRenderer,
detailItems);
rowRenderer = OnColumnsRowRenderer.create(Data.class, cellRenderer, detailItems);
}
private void givenDetailItems() {
detailItems = new ArrayList<DetailItem>();
detailItems = new ArrayList<>();
start = new LocalDate(2010, 1, 1).toDateMidnight().toDateTime();
DateTime current = start;
Period period = Period.months(2);
for (int i = 1; i <= 10; i++) {
DateTime end = current.plus(period);
DetailItem detail = new DetailItem(200, i + "", current, end);
@ -98,62 +95,55 @@ public class OnColumnsRowRendererTest {
}
private void givenData() {
data = new ArrayList<Data>();
data = new ArrayList<>();
data.add(new Data());
data.add(new Data());
}
@Test(expected = IllegalArgumentException.class)
@Test(expected = NullPointerException.class)
public void itNeedsNotNullDetailItems() {
OnColumnsRowRenderer.create(Data.class, createStub(), null);
}
@Test(expected = IllegalArgumentException.class)
@Test(expected = NullPointerException.class)
public void itNeedsNotNullCellRenderer() {
OnColumnsRowRenderer.create(Data.class, null,
new ArrayList<DetailItem>());
OnColumnsRowRenderer.create(Data.class, null, new ArrayList<DetailItem>());
}
@Test(expected = IllegalArgumentException.class)
@Test(expected = NullPointerException.class)
public void itNeedsTheTypeAsClass() {
OnColumnsRowRenderer.create(null, createStub(),
new ArrayList<DetailItem>());
OnColumnsRowRenderer.create(null, createStub(), new ArrayList<DetailItem>());
}
@Test
public void itCanHaveEmptyDetailItems() {
OnColumnsRowRenderer.create(Data.class, createStub(),
new ArrayList<DetailItem>());
OnColumnsRowRenderer.create(Data.class, createStub(), new ArrayList<DetailItem>());
}
@Test
public void itCanInferTheGenericType() {
OnColumnsRowRenderer.create(new CellRenderer(),
new ArrayList<DetailItem>());
OnColumnsRowRenderer.create(new CellRenderer(), new ArrayList<DetailItem>());
}
@Test(expected = IllegalArgumentException.class)
public void ifComesFromRawTypeIsNotInferrable() {
OnColumnsRowRenderer.create(createStub(),
new ArrayList<DetailItem>());
OnColumnsRowRenderer.create(createStub(), new ArrayList<DetailItem>());
}
@Test(expected = IllegalArgumentException.class)
public void ifItNotShowsTheActualTypeIsNotInferrable() {
OnColumnsRowRenderer.create(new CellRendererNotInferable<Data>(),
new ArrayList<DetailItem>());
OnColumnsRowRenderer.create(new CellRendererNotInferable<Data>(), new ArrayList<DetailItem>());
}
@SuppressWarnings("serial")
@Test(expected = IllegalArgumentException.class)
public void noDetailItemCanBeNull() {
OnColumnsRowRenderer.create(Data.class, createStub(),
new ArrayList<DetailItem>() {
{
add(new DetailItem(300, "bla"));
add(null);
}
});
OnColumnsRowRenderer.create(Data.class, createStub(), new ArrayList<DetailItem>() {
{
add(new DetailItem(300, "bla"));
add(null);
}
});
}
@Test(expected = IllegalArgumentException.class)
@ -193,6 +183,7 @@ public class OnColumnsRowRendererTest {
}
}
replay(mock);
return mock;
}
@ -209,17 +200,16 @@ public class OnColumnsRowRendererTest {
verify(labelMock);
}
private Label expectTheCreatedLabelIsAddedToTheRow(
ICellForDetailItemRenderer<DetailItem, Data> mock) {
private Label expectTheCreatedLabelIsAddedToTheRow(ICellForDetailItemRenderer<DetailItem, Data> mock) {
Label labelMock = createStrictMock(Label.class);
for (Data d : data) {
for (DetailItem item : detailItems) {
expect(mock.cellFor(isA(DetailItem.class), isA(Data.class)))
.andReturn(labelMock);
for (Data ignored1 : data) {
for (DetailItem ignored2 : detailItems) {
expect(mock.cellFor(isA(DetailItem.class), isA(Data.class))).andReturn(labelMock);
labelMock.setParent(isA(Row.class));
}
}
replay(mock, labelMock);
return labelMock;
}

View file

@ -53,12 +53,15 @@ public class AvailabilityTimeLine {
@Override
public final int compareTo(DatePoint obj) {
Validate.notNull(obj);
if (obj instanceof FixedPoint) {
if ( obj instanceof FixedPoint ) {
return compareTo((FixedPoint) obj);
} else if (obj instanceof EndOfTime) {
} else if ( obj instanceof EndOfTime ) {
return compareTo((EndOfTime) obj);
} else if (obj instanceof StartOfTime) {
} else if ( obj instanceof StartOfTime ) {
return compareTo((StartOfTime) obj);
} else {
throw new RuntimeException("unknown subclass for " + obj);
}
@ -69,15 +72,19 @@ public class AvailabilityTimeLine {
@Override
public final boolean equals(Object obj) {
if (!(obj instanceof DatePoint)) {
if ( !(obj instanceof DatePoint) ) {
return false;
}
if (obj instanceof FixedPoint) {
if ( obj instanceof FixedPoint ) {
return equalTo((FixedPoint) obj);
} else if (obj instanceof EndOfTime) {
} else if ( obj instanceof EndOfTime ) {
return equalTo((EndOfTime) obj);
} else if (obj instanceof StartOfTime) {
} else if ( obj instanceof StartOfTime ) {
return equalTo((StartOfTime) obj);
} else {
throw new RuntimeException("unknown subclass for " + obj);
}
@ -142,6 +149,7 @@ public class AvailabilityTimeLine {
public static LocalDate tryExtract(DatePoint start) {
FixedPoint point = (FixedPoint) start;
return point.getDate();
}
}
@ -243,8 +251,7 @@ public class AvailabilityTimeLine {
}
}
public static class Interval implements
Comparable<Interval> {
public static class Interval implements Comparable<Interval> {
/**
* Creates an interval. Null values can be provided.
@ -256,10 +263,9 @@ public class AvailabilityTimeLine {
* @return an interval from start to end
*/
public static Interval create(LocalDate start, LocalDate end) {
DatePoint startPoint = start == null ? new StartOfTime()
: new FixedPoint(start);
DatePoint endPoint = end == null ? new EndOfTime()
: new FixedPoint(end);
DatePoint startPoint = start == null ? new StartOfTime() : new FixedPoint(start);
DatePoint endPoint = end == null ? new EndOfTime() : new FixedPoint(end);
return new Interval(startPoint, endPoint);
}
@ -272,13 +278,11 @@ public class AvailabilityTimeLine {
}
public static Interval to(LocalDate date) {
return new Interval(StartOfTime.create(), new FixedPoint(
date));
return new Interval(StartOfTime.create(), new FixedPoint(date));
}
static Interval point(LocalDate start) {
return new Interval(new FixedPoint(start), new FixedPoint(start
.plusDays(1)));
return new Interval(new FixedPoint(start), new FixedPoint(start.plusDays(1)));
}
private final DatePoint start;
@ -300,17 +304,17 @@ public class AvailabilityTimeLine {
@Override
public int compareTo(Interval other) {
return this.start.compareTo(other.start) * 2
- this.end.compareTo(other.end);
return this.start.compareTo(other.start) * 2 - this.end.compareTo(other.end);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Interval) {
if ( obj instanceof Interval ) {
Interval other = (Interval) obj;
return start.equals(other.getStart())
&& end.equals(other.getEnd());
return start.equals(other.getStart()) && end.equals(other.getEnd());
}
return false;
}
@ -324,35 +328,32 @@ public class AvailabilityTimeLine {
}
private boolean includes(FixedPoint point) {
return start.equals(point) || start.compareTo(point) <= 0
&& point.compareTo(end) < 0;
return start.equals(point) || start.compareTo(point) <= 0 && point.compareTo(end) < 0;
}
public boolean overlaps(Interval other) {
return start.compareTo(other.end) <= 0
&& end.compareTo(other.start) >= 0;
return start.compareTo(other.end) <= 0 && end.compareTo(other.start) >= 0;
}
public Interval intersect(Interval other) {
Validate.isTrue(overlaps(other));
return new Interval(max(start, other.start), min(end, other.end));
}
public Interval coalesce(Interval other) {
if (!overlaps(other)) {
throw new IllegalArgumentException(
"in order to coalesce two intervals must overlap");
if ( !overlaps(other) ) {
throw new IllegalArgumentException("in order to coalesce two intervals must overlap");
}
return new Interval(min(start, other.start), max(end,
other.end));
return new Interval(min(start, other.start), max(end, other.end));
}
private DatePoint min(DatePoint... values) {
return (DatePoint) Collections.min(Arrays.asList(values));
return Collections.min(Arrays.asList(values));
}
private DatePoint max(DatePoint... values) {
return (DatePoint) Collections.max(Arrays.asList(values));
return Collections.max(Arrays.asList(values));
}
@Override
@ -362,7 +363,7 @@ public class AvailabilityTimeLine {
}
public interface IVetoer {
public boolean isValid(LocalDate date);
boolean isValid(LocalDate date);
}
public static AvailabilityTimeLine allValid() {
@ -372,6 +373,7 @@ public class AvailabilityTimeLine {
public static AvailabilityTimeLine createAllInvalid() {
AvailabilityTimeLine result = new AvailabilityTimeLine();
result.allInvalid();
return result;
}
@ -385,7 +387,7 @@ public class AvailabilityTimeLine {
private IVetoer vetoer = NO_VETOER;
private List<Interval> invalids = new ArrayList<Interval>();
private List<Interval> invalids = new ArrayList<>();
private AvailabilityTimeLine() {
}
@ -395,23 +397,27 @@ public class AvailabilityTimeLine {
}
private boolean isValidBasedOnInvaidIntervals(LocalDate date) {
if (invalids.isEmpty()) {
if ( invalids.isEmpty() ) {
return true;
}
Interval possibleInterval = findPossibleIntervalFor(date);
return possibleInterval == null || !possibleInterval.includes(date);
}
private Interval findPossibleIntervalFor(LocalDate date) {
Interval point = Interval.point(date);
int binarySearch = Collections.binarySearch(invalids, point);
if (binarySearch >= 0) {
if ( binarySearch >= 0) {
return invalids.get(binarySearch);
} else {
int insertionPoint = insertionPoint(binarySearch);
if (insertionPoint == 0) {
if ( insertionPoint == 0 ) {
return null;
}
return invalids.get(insertionPoint - 1);
}
}
@ -439,10 +445,11 @@ public class AvailabilityTimeLine {
}
private void insert(Interval toBeInserted) {
if (invalids.isEmpty()) {
if ( invalids.isEmpty() ) {
invalids.add(toBeInserted);
return;
}
toBeInserted = coalesceWithAdjacent(toBeInserted);
int insertionPoint = insertBeforeAllAdjacent(toBeInserted);
removeAdjacent(insertionPoint, toBeInserted);
@ -456,12 +463,14 @@ public class AvailabilityTimeLine {
*/
private int findInsertionPosition(Interval interval) {
int binarySearch = Collections.binarySearch(invalids, interval);
return insertionPoint(binarySearch);
}
private int insertBeforeAllAdjacent(Interval toBeInserted) {
int insertionPoint = findInsertionPosition(toBeInserted);
invalids.add(insertionPoint, toBeInserted);
return insertionPoint;
}
@ -471,39 +480,43 @@ public class AvailabilityTimeLine {
for (Interval each : adjacent) {
result = result.coalesce(each);
}
return result;
}
private List<Interval> getAdjacent(Interval toBeInserted) {
final int insertionPoint = findInsertionPosition(toBeInserted);
List<Interval> result = new ArrayList<Interval>();
List<Interval> result = new ArrayList<>();
assert insertionPoint <= invalids.size();
for (int i = insertionPoint - 1; i >= 0 && at(i).overlaps(toBeInserted); i--) {
result.add(at(i));
}
for (int i = insertionPoint; i < invalids.size()
&& at(i).overlaps(toBeInserted); i++) {
for (int i = insertionPoint; i < invalids.size() && at(i).overlaps(toBeInserted); i++) {
result.add(at(i));
}
return result;
}
private List<Interval> intersectWithAdjacent(Interval interval) {
List<Interval> result = new ArrayList<Interval>();
List<Interval> result = new ArrayList<>();
List<Interval> adjacent = getAdjacent(interval);
for (Interval each : adjacent) {
assert interval.overlaps(each);
result.add(interval.intersect(each));
}
return result;
}
private void removeAdjacent(int insertionPoint, Interval inserted) {
ListIterator<Interval> listIterator = invalids
.listIterator(insertionPoint + 1);
ListIterator<Interval> listIterator = invalids.listIterator(insertionPoint + 1);
while (listIterator.hasNext()) {
Interval next = listIterator.next();
if (!next.overlaps(inserted)) {
if ( !next.overlaps(inserted) ) {
break;
}
listIterator.remove();
@ -515,14 +528,12 @@ public class AvailabilityTimeLine {
}
private int insertionPoint(int binarySearchResult) {
return binarySearchResult < 0 ? (-binarySearchResult) - 1
: binarySearchResult;
return binarySearchResult < 0 ? (-binarySearchResult) - 1 : binarySearchResult;
}
public void invalidAt(LocalDate intervalStart, LocalDate intervalEnd) {
if (intervalStart.isAfter(intervalEnd)) {
throw new IllegalArgumentException(
"end must be equal or after start");
if ( intervalStart.isAfter(intervalEnd) ) {
throw new IllegalArgumentException("end must be equal or after start");
}
insert(Interval.create(intervalStart, intervalEnd));
}
@ -540,11 +551,11 @@ public class AvailabilityTimeLine {
inserting(result, invalids);
inserting(result, another.invalids);
result.setVetoer(and(this.vetoer, another.vetoer));
return result;
}
private static IVetoer and(final IVetoer a,
final IVetoer b) {
private static IVetoer and(final IVetoer a, final IVetoer b) {
return new IVetoer() {
@Override
public boolean isValid(LocalDate date) {
@ -556,27 +567,30 @@ public class AvailabilityTimeLine {
public AvailabilityTimeLine or(AvailabilityTimeLine another) {
List<Interval> intersections = doIntersections(this, another);
AvailabilityTimeLine result = AvailabilityTimeLine.allValid();
for (Interval each : intersections) {
boolean fromStartOfTime = each.getStart().equals(
StartOfTime.create());
boolean fromStartOfTime = each.getStart().equals(StartOfTime.create());
boolean untilEndOfTime = each.getEnd().equals(EndOfTime.create());
if (fromStartOfTime && untilEndOfTime) {
if ( fromStartOfTime && untilEndOfTime ) {
result.allInvalid();
} else if (fromStartOfTime) {
} else if ( fromStartOfTime ) {
result.invalidUntil(FixedPoint.tryExtract(each.getEnd()));
} else if (untilEndOfTime) {
} else if ( untilEndOfTime ) {
result.invalidFrom(FixedPoint.tryExtract(each.getStart()));
} else {
result.invalidAt(FixedPoint.tryExtract(each.getStart()),
FixedPoint.tryExtract(each.getEnd()));
result.invalidAt(FixedPoint.tryExtract(each.getStart()), FixedPoint.tryExtract(each.getEnd()));
}
}
result.setVetoer(or(this.vetoer, another.vetoer));
return result;
}
private static IVetoer or(final IVetoer a,
final IVetoer b) {
private static IVetoer or(final IVetoer a, final IVetoer b) {
return new IVetoer() {
@Override
public boolean isValid(LocalDate date) {
@ -585,12 +599,12 @@ public class AvailabilityTimeLine {
};
}
private static List<Interval> doIntersections(AvailabilityTimeLine one,
AvailabilityTimeLine another) {
List<Interval> result = new ArrayList<Interval>();
private static List<Interval> doIntersections(AvailabilityTimeLine one, AvailabilityTimeLine another) {
List<Interval> result = new ArrayList<>();
for (Interval each : one.invalids) {
result.addAll(another.intersectWithAdjacent(each));
}
return result;
}
@ -601,19 +615,22 @@ public class AvailabilityTimeLine {
}
public List<Interval> getValidPeriods() {
List<Interval> result = new ArrayList<Interval>();
List<Interval> result = new ArrayList<>();
DatePoint previous = StartOfTime.create();
for (Interval each : invalids) {
DatePoint invalidStart = each.start;
if (!invalidStart.equals(StartOfTime.create())
&& !invalidStart.equals(EndOfTime.create())) {
if ( !invalidStart.equals(StartOfTime.create()) && !invalidStart.equals(EndOfTime.create()) ) {
result.add(new Interval(previous, invalidStart));
}
previous = each.getEnd();
}
if (!previous.equals(EndOfTime.create())) {
if ( !previous.equals(EndOfTime.create()) ) {
result.add(new Interval(previous, EndOfTime.create()));
}
return result;
}

View file

@ -50,6 +50,7 @@ public class Dependency extends BaseEntity {
return false;
}
},
START_START {
@Override
public boolean modifiesDestinationStart() {
@ -61,6 +62,7 @@ public class Dependency extends BaseEntity {
return false;
}
},
END_END {
@Override
public boolean modifiesDestinationStart() {
@ -72,6 +74,7 @@ public class Dependency extends BaseEntity {
return true;
}
},
START_END {
@Override
public boolean modifiesDestinationStart() {
@ -89,12 +92,12 @@ public class Dependency extends BaseEntity {
public abstract boolean modifiesDestinationEnd();
}
public static Dependency create(TaskElement origin,
TaskElement destination, Type type) {
public static Dependency create(TaskElement origin, TaskElement destination, Type type) {
Dependency dependency = new Dependency(origin, destination, type);
dependency.setNewObject(true);
origin.add(dependency);
destination.add(dependency);
return dependency;
}
@ -117,8 +120,8 @@ public class Dependency extends BaseEntity {
Validate.notNull(origin);
Validate.notNull(destination);
Validate.notNull(type);
Validate.isTrue(!origin.equals(destination),
"a dependency must have a different origin than destination");
Validate.isTrue(!origin.equals(destination), "a dependency must have a different origin than destination");
this.origin = origin;
this.destination = destination;
this.type = type;
@ -145,8 +148,7 @@ public class Dependency extends BaseEntity {
}
public boolean isDependencyBetweenLimitedAllocatedTasks() {
return getOrigin().hasLimitedResourceAllocation() &&
getDestination().hasLimitedResourceAllocation();
return getOrigin().hasLimitedResourceAllocation() && getDestination().hasLimitedResourceAllocation();
}
public boolean hasLimitedQueueDependencyAssociated() {
@ -155,14 +157,18 @@ public class Dependency extends BaseEntity {
public Date getDateFromOrigin() {
switch (type) {
case END_START:
case END_END:
return origin.getEndDate();
case START_END:
case START_START:
return origin.getStartDate();
default:
throw new RuntimeException("unexpected type");
case END_START:
case END_END:
return origin.getEndDate();
case START_END:
case START_START:
return origin.getStartDate();
default:
throw new RuntimeException("unexpected type");
}
}
}

View file

@ -43,7 +43,7 @@ import org.joda.time.LocalDate;
* @author Diego Pino García <dpino@igalia.com>
* @author Manuel Rego Casasnovas <mrego@igalia.com>
*
* Assignment function by stretches.
* Assignment function by stretches.
*
*/
public class StretchesFunction extends AssignmentFunction {
@ -58,48 +58,48 @@ public class StretchesFunction extends AssignmentFunction {
private boolean consolidated = false;
public static Interval create(BigDecimal loadProportion, LocalDate start,
LocalDate end, boolean consolidated) {
public static Interval create(BigDecimal loadProportion, LocalDate start, LocalDate end, boolean consolidated) {
Interval result = create(loadProportion, start, end);
result.consolidated(consolidated);
return result;
}
public static Interval create(BigDecimal loadProportion, LocalDate start,
LocalDate end) {
public static Interval create(BigDecimal loadProportion, LocalDate start, LocalDate end) {
return new Interval(loadProportion, start, end);
}
public Interval(BigDecimal loadProportion, LocalDate start,
LocalDate end) {
public Interval(BigDecimal loadProportion, LocalDate start, LocalDate end) {
Validate.notNull(loadProportion);
Validate.isTrue(loadProportion.signum() >= 0);
Validate.notNull(end);
this.loadProportion = loadProportion.setScale(2,
RoundingMode.HALF_UP);
this.loadProportion = loadProportion.setScale(2, RoundingMode.HALF_UP);
this.start = start;
this.end = end;
}
public static double[] getHoursPointsFor(int totalHours,
List<Interval> intervalsDefinedByStreches) {
public static double[] getHoursPointsFor(int totalHours, List<Interval> intervalsDefinedByStreches) {
double[] result = new double[intervalsDefinedByStreches.size()];
int i = 0;
int accumulated = 0;
for (Interval each : intervalsDefinedByStreches) {
accumulated += each.getHoursFor(totalHours);
result[i++] = accumulated;
}
return result;
}
public static double[] getDayPointsFor(LocalDate start,
List<Interval> intervalsDefinedByStreches) {
public static double[] getDayPointsFor(LocalDate start, List<Interval> intervalsDefinedByStreches) {
double[] result = new double[intervalsDefinedByStreches.size()];
int i = 0;
for (Interval each : intervalsDefinedByStreches) {
result[i++] = Days.daysBetween(start, each.getEnd()).getDays();
}
return result;
}
@ -120,8 +120,7 @@ public class StretchesFunction extends AssignmentFunction {
}
public int getHoursFor(int totalHours) {
return loadProportion.multiply(new BigDecimal(totalHours))
.intValue();
return loadProportion.multiply(new BigDecimal(totalHours)).intValue();
}
public LocalDate getStartFor(LocalDate allocationStart) {
@ -129,41 +128,43 @@ public class StretchesFunction extends AssignmentFunction {
}
private void apply(ResourceAllocation<?> resourceAllocation,
LocalDate startInclusive, LocalDate taskEnd,
int intervalHours) {
LocalDate startInclusive,
int intervalHours) {
Validate.isTrue(!isConsolidated());
resourceAllocation.withPreviousAssociatedResources()
.onInterval(getStartFor(startInclusive), getEnd())
.allocateHours(intervalHours);
.onInterval(getStartFor(startInclusive), getEnd()).allocateHours(intervalHours);
}
public static void apply(ResourceAllocation<?> allocation,
List<Interval> intervalsDefinedByStreches,
LocalDate allocationStart, LocalDate allocationEnd,
int totalHours) {
if (intervalsDefinedByStreches.isEmpty()) {
List<Interval> intervalsDefinedByStreches,
LocalDate allocationStart,
int totalHours) {
if ( intervalsDefinedByStreches.isEmpty() ) {
return;
}
Validate.isTrue(totalHours == allocation.getNonConsolidatedHours());
int[] hoursPerInterval = getHoursPerInterval(
intervalsDefinedByStreches, totalHours);
int[] hoursPerInterval = getHoursPerInterval(intervalsDefinedByStreches, totalHours);
int remainder = totalHours - sum(hoursPerInterval);
hoursPerInterval[0] += remainder;
int i = 0;
for (Interval interval : intervalsDefinedByStreches) {
interval.apply(allocation, allocationStart, allocationEnd,
hoursPerInterval[i++]);
interval.apply(allocation, allocationStart, hoursPerInterval[i++]);
}
}
private static int[] getHoursPerInterval(
List<Interval> intervalsDefinedByStreches, int totalHours) {
private static int[] getHoursPerInterval(List<Interval> intervalsDefinedByStreches, int totalHours) {
int[] hoursPerInterval = new int[intervalsDefinedByStreches.size()];
int i = 0;
for (Interval each : intervalsDefinedByStreches) {
hoursPerInterval[i++] = each.getHoursFor(totalHours);
}
return hoursPerInterval;
}
@ -172,6 +173,7 @@ public class StretchesFunction extends AssignmentFunction {
for (int each : hoursPerInterval) {
result += each;
}
return result;
}
@ -189,7 +191,7 @@ public class StretchesFunction extends AssignmentFunction {
}
private List<Stretch> stretches = new ArrayList<Stretch>();
private List<Stretch> stretches = new ArrayList<>();
private StretchesFunctionTypeEnum type;
@ -203,7 +205,7 @@ public class StretchesFunction extends AssignmentFunction {
private ResourceAllocation<?> resourceAllocation;
public static StretchesFunction create() {
return (StretchesFunction) create(new StretchesFunction());
return create(new StretchesFunction());
}
/**
@ -214,23 +216,28 @@ public class StretchesFunction extends AssignmentFunction {
}
public static List<Interval> intervalsFor(ResourceAllocation<?> allocation,
Collection<? extends Stretch> streches) {
ArrayList<Interval> result = new ArrayList<Interval>();
LocalDate previous = null, stretchDate = null;
BigDecimal sumOfProportions = BigDecimal.ZERO, loadedProportion = BigDecimal.ZERO;
Collection<? extends Stretch> streches) {
ArrayList<Interval> result = new ArrayList<>();
LocalDate previous = null;
LocalDate stretchDate;
BigDecimal sumOfProportions = BigDecimal.ZERO;
BigDecimal loadedProportion;
for (Stretch each : streches) {
stretchDate = each.getDateIn(allocation);
loadedProportion = each.getAmountWorkPercentage().subtract(
sumOfProportions);
if (loadedProportion.signum() < 0) {
loadedProportion = each.getAmountWorkPercentage().subtract(sumOfProportions);
if ( loadedProportion.signum() < 0 ) {
loadedProportion = BigDecimal.ZERO;
}
result.add(Interval.create(loadedProportion, previous,
stretchDate, each.isConsolidated()));
result.add(Interval.create(loadedProportion, previous, stretchDate, each.isConsolidated()));
sumOfProportions = each.getAmountWorkPercentage();
previous = stretchDate;
}
return result;
}
@ -245,6 +252,7 @@ public class StretchesFunction extends AssignmentFunction {
result.desiredType = desiredType;
result.consolidatedStretch = consolidatedStretch;
result.resourceAllocation = resourceAllocation;
return result;
}
@ -257,29 +265,30 @@ public class StretchesFunction extends AssignmentFunction {
}
public List<Stretch> getStretchesDefinedByUser() {
return Collections.unmodifiableList(Stretch
.sortByLengthPercentage(stretches));
return Collections.unmodifiableList(Stretch.sortByLengthPercentage(stretches));
}
@Valid
public List<Stretch> getStretches() {
List<Stretch> result = new ArrayList<Stretch>();
List<Stretch> result = new ArrayList<>();
result.add(getFirstStretch());
result.addAll(stretches);
result.add(getLastStretch());
return Collections.unmodifiableList(Stretch
.sortByLengthPercentage(result));
return Collections.unmodifiableList(Stretch.sortByLengthPercentage(result));
}
private Stretch getLastStretch() {
Stretch result = Stretch.create(BigDecimal.ONE, BigDecimal.ONE);
result.readOnly(true);
return result;
}
private Stretch getFirstStretch() {
Stretch result = Stretch.create(BigDecimal.ZERO, BigDecimal.ZERO);
result.readOnly(true);
return result;
}
@ -313,67 +322,74 @@ public class StretchesFunction extends AssignmentFunction {
return getStretchesPlusConsolidated().size() > 2;
}
@AssertTrue(message = "A stretch has lower or equal values than the "
+ "previous stretch")
@AssertTrue(message = "A stretch has lower or equal values than the previous stretch")
public boolean isStretchesOrderConstraint() {
List<Stretch> stretchesPlusConsolidated = getStretchesPlusConsolidated();
if (stretchesPlusConsolidated.isEmpty()) {
if ( stretchesPlusConsolidated.isEmpty() ) {
return false;
}
Iterator<Stretch> iterator = stretchesPlusConsolidated.iterator();
Stretch previous = iterator.next();
while (iterator.hasNext()) {
Stretch current = iterator.next();
if (current.getLengthPercentage().compareTo(
previous.getLengthPercentage()) <= 0) {
if ( current.getLengthPercentage().compareTo(previous.getLengthPercentage()) <= 0 ) {
return false;
}
if (current.getAmountWorkPercentage().compareTo(
previous.getAmountWorkPercentage()) <= 0) {
if ( current.getAmountWorkPercentage().compareTo(previous.getAmountWorkPercentage()) <= 0 ) {
return false;
}
previous = current;
}
return true;
}
public List<Stretch> getStretchesPlusConsolidated() {
List<Stretch> result = new ArrayList<Stretch>();
List<Stretch> result = new ArrayList<>();
result.addAll(getStretches());
if (consolidatedStretch != null) {
if ( consolidatedStretch != null ) {
result.add(consolidatedStretch);
}
return Collections.unmodifiableList(Stretch
.sortByLengthPercentage(result));
return Collections.unmodifiableList(Stretch.sortByLengthPercentage(result));
}
@AssertTrue(message = "Last stretch should have one hundred percent "
+ "length and one hundred percent of work percentage")
@AssertTrue(message = "Last stretch should have one hundred percent " +
"length and one hundred percent of work percentage")
public boolean isOneHundredPercentConstraint() {
List<Stretch> stretches = getStretchesPlusConsolidated();
if (stretches.isEmpty()) {
if ( stretches.isEmpty() ) {
return false;
}
Stretch lastStretch = stretches.get(stretches.size() - 1);
if (lastStretch.getLengthPercentage().compareTo(BigDecimal.ONE) != 0) {
if ( lastStretch.getLengthPercentage().compareTo(BigDecimal.ONE) != 0 ) {
return false;
}
if (lastStretch.getAmountWorkPercentage().compareTo(BigDecimal.ONE) != 0) {
if ( lastStretch.getAmountWorkPercentage().compareTo(BigDecimal.ONE) != 0 ) {
return false;
}
return true;
}
@Override
public void applyTo(ResourceAllocation<?> resourceAllocation) {
if (!resourceAllocation.hasAssignments()) {
if ( !resourceAllocation.hasAssignments() ) {
return;
}
// Is 100% consolidated
if (resourceAllocation.getFirstNonConsolidatedDate() == null) {
if ( resourceAllocation.getFirstNonConsolidatedDate() == null ) {
return;
}
this.resourceAllocation = resourceAllocation;
getDesiredType().applyTo(resourceAllocation, this);
type = getDesiredType();
@ -381,7 +397,7 @@ public class StretchesFunction extends AssignmentFunction {
@Override
public String getName() {
if (StretchesFunctionTypeEnum.INTERPOLATED.equals(type)) {
if ( StretchesFunctionTypeEnum.INTERPOLATED.equals(type) ) {
return AssignmentFunctionName.INTERPOLATION.toString();
} else {
return AssignmentFunctionName.STRETCHES.toString();
@ -389,25 +405,27 @@ public class StretchesFunction extends AssignmentFunction {
}
public List<Interval> getIntervalsDefinedByStreches() {
List<Stretch> stretches = stretchesFor(type);
if (stretches.isEmpty()) {
List<Stretch> stretches = stretchesFor();
if ( stretches.isEmpty() ) {
return Collections.emptyList();
}
checkStretchesSumOneHundredPercent();
return intervalsFor(resourceAllocation, stretches);
}
private List<Stretch> stretchesFor(StretchesFunctionTypeEnum type) {
return (getDesiredType().equals(StretchesFunctionTypeEnum.INTERPOLATED)) ? getStretchesPlusConsolidated()
: getStretches();
private List<Stretch> stretchesFor() {
boolean condition = (getDesiredType().equals(StretchesFunctionTypeEnum.INTERPOLATED));
return condition ? getStretchesPlusConsolidated() : getStretches();
}
private void checkStretchesSumOneHundredPercent() {
List<Stretch> stretches = getStretchesPlusConsolidated();
BigDecimal sumOfProportions = stretches.isEmpty() ? BigDecimal.ZERO
: last(stretches).getAmountWorkPercentage();
BigDecimal sumOfProportions = stretches.isEmpty() ? BigDecimal.ZERO : last(stretches).getAmountWorkPercentage();
BigDecimal left = calculateLeftFor(sumOfProportions);
if (!left.equals(BigDecimal.ZERO)) {
if ( !left.equals(BigDecimal.ZERO) ) {
throw new IllegalStateException(_("Stretches must sum 100%"));
}
}
@ -415,6 +433,7 @@ public class StretchesFunction extends AssignmentFunction {
private BigDecimal calculateLeftFor(BigDecimal sumOfProportions) {
BigDecimal left = BigDecimal.ONE.subtract(sumOfProportions);
left = left.signum() <= 0 ? BigDecimal.ZERO : left;
return left;
}

View file

@ -50,7 +50,7 @@ public enum StretchesFunctionTypeEnum {
LocalDate startInclusive, LocalDate endExclusive,
int totalHours) {
Interval.apply(allocation, intervalsDefinedByStreches, startInclusive, endExclusive, totalHours);
Interval.apply(allocation, intervalsDefinedByStreches, startInclusive, totalHours);
}
},
INTERPOLATED {

View file

@ -55,11 +55,7 @@ import org.springframework.transaction.annotation.Transactional;
@Repository
@Scope(BeanDefinition.SCOPE_SINGLETON)
@Transactional
public class ResourceDAO extends IntegrationEntityDAO<Resource> implements
IResourceDAO {
@Autowired
private IScenarioManager scenarioManager;
public class ResourceDAO extends IntegrationEntityDAO<Resource> implements IResourceDAO {
@Override
public List<Worker> getWorkers() {
@ -71,10 +67,11 @@ public class ResourceDAO extends IntegrationEntityDAO<Resource> implements
List<Worker> list = getWorkers();
for (Iterator<Worker> iterator = list.iterator(); iterator.hasNext();) {
Worker worker = iterator.next();
if (worker.isReal()) {
if ( worker.isReal() ) {
iterator.remove();
}
}
return list;
}
@ -83,10 +80,11 @@ public class ResourceDAO extends IntegrationEntityDAO<Resource> implements
List<Worker> list = getWorkers();
for (Iterator<Worker> iterator = list.iterator(); iterator.hasNext();) {
Worker worker = iterator.next();
if (worker.isVirtual()) {
if ( worker.isVirtual() ) {
iterator.remove();
}
}
return list;
}
@ -97,15 +95,13 @@ public class ResourceDAO extends IntegrationEntityDAO<Resource> implements
@SuppressWarnings("unchecked")
@Override
public List<Resource> getAllLimitingResources() {
return getSession().createCriteria(Resource.class).add(
Restrictions.eq("limitingResource", true)).list();
return getSession().createCriteria(Resource.class).add(Restrictions.eq("limitingResource", true)).list();
}
@SuppressWarnings("unchecked")
@Override
public List<Resource> getAllNonLimitingResources() {
return getSession().createCriteria(Resource.class).add(
Restrictions.eq("limitingResource", false)).list();
return getSession().createCriteria(Resource.class).add(Restrictions.eq("limitingResource", false)).list();
}
@Override
@ -115,82 +111,95 @@ public class ResourceDAO extends IntegrationEntityDAO<Resource> implements
@Override
public List<Resource> getRealResources() {
List<Resource> list = new ArrayList<Resource>();
List<Resource> list = new ArrayList<>();
list.addAll(getRealWorkers());
list.addAll(getMachines());
return list;
}
@Override
public void save(Resource resource) {
if (resource instanceof Worker || resource instanceof Machine) {
if (resource.isLimitingResource() && resource.getLimitingResourceQueue() == null) {
if ( resource instanceof Worker || resource instanceof Machine ) {
if ( resource.isLimitingResource() && resource.getLimitingResourceQueue() == null ) {
resource.setLimitingResourceQueue(LimitingResourceQueue.create());
}
}
super.save(resource);
}
@Override
@Transactional(readOnly = true)
public List<HoursWorkedPerResourceDTO> getWorkingHoursPerWorker(
List<Resource> resources, List<Label> labels,
LabelFilterType labelFilterType, List<Criterion> criterions,
List<Resource> resources,
List<Label> labels,
LabelFilterType labelFilterType,
List<Criterion> criterions,
Date startingDate,
Date endingDate) {
String strQuery = "SELECT new org.libreplan.business.reports.dtos.HoursWorkedPerResourceDTO(resource, wrl) "
+ "FROM Resource resource, WorkReportLine wrl "
+ "LEFT OUTER JOIN wrl.resource wrlresource "
+ "WHERE wrlresource.id = resource.id ";
String strQuery =
"SELECT new org.libreplan.business.reports.dtos.HoursWorkedPerResourceDTO(resource, wrl) " +
"FROM Resource resource, WorkReportLine wrl " +
"LEFT OUTER JOIN wrl.resource wrlresource " +
"WHERE wrlresource.id = resource.id ";
// Set date range
if (startingDate != null && endingDate != null) {
if ( startingDate != null && endingDate != null ) {
strQuery += "AND wrl.date BETWEEN :startingDate AND :endingDate ";
}
if (startingDate != null && endingDate == null) {
if ( startingDate != null && endingDate == null ) {
strQuery += "AND wrl.date >= :startingDate ";
}
if (startingDate == null && endingDate != null) {
if ( startingDate == null && endingDate != null ) {
strQuery += "AND wrl.date <= :endingDate ";
}
// Set workers
if (resources != null && !resources.isEmpty()) {
if ( resources != null && !resources.isEmpty() ) {
strQuery += "AND resource IN (:resources) ";
}
// Set labels
if (labels != null && !labels.isEmpty()) {
if ( labels != null && !labels.isEmpty() ) {
switch (labelFilterType) {
case ORDER_ELEMENT:
strQuery += " AND ( EXISTS (FROM wrl.orderElement.labels as etq WHERE etq IN (:labels)) "
+ "OR EXISTS (FROM wrl.workReport.orderElement.labels as etqwr WHERE etqwr IN (:labels)) ) ";
break;
case WORK_REPORT:
strQuery += " AND ( EXISTS (FROM wrl.labels as etq WHERE etq IN (:labels)) "
+ "OR EXISTS (FROM wrl.workReport.labels as etqwr WHERE etqwr IN (:labels)) ) ";
break;
case BOTH:
strQuery += " AND ( EXISTS (FROM wrl.labels as etq WHERE etq IN (:labels)) "
+ "OR EXISTS (FROM wrl.workReport.labels as etqwr WHERE etqwr IN (:labels)) ) "
+ "AND ( EXISTS (FROM wrl.orderElement.labels as etq WHERE etq IN (:labels)) "
+ "OR EXISTS (FROM wrl.workReport.orderElement.labels as etqwr WHERE etqwr IN (:labels)) ) ";
break;
case ANY:
default:
strQuery += " AND ( ( EXISTS (FROM wrl.labels as etq WHERE etq IN (:labels)) "
+ "OR EXISTS (FROM wrl.workReport.labels as etqwr WHERE etqwr IN (:labels)) ) "
+ "OR ( EXISTS (FROM wrl.orderElement.labels as etq WHERE etq IN (:labels)) "
+ "OR EXISTS (FROM wrl.workReport.orderElement.labels as etqwr WHERE etqwr IN (:labels)) ) ) ";
break;
case ORDER_ELEMENT:
strQuery += " AND ( EXISTS (FROM wrl.orderElement.labels as etq WHERE etq IN (:labels)) " +
"OR EXISTS (FROM wrl.workReport.orderElement.labels as etqwr WHERE etqwr IN (:labels)) ) ";
break;
case WORK_REPORT:
strQuery += " AND ( EXISTS (FROM wrl.labels as etq WHERE etq IN (:labels)) " +
"OR EXISTS (FROM wrl.workReport.labels as etqwr WHERE etqwr IN (:labels)) ) ";
break;
case BOTH:
strQuery += " AND ( EXISTS (FROM wrl.labels as etq WHERE etq IN (:labels)) " +
"OR EXISTS (FROM wrl.workReport.labels as etqwr WHERE etqwr IN (:labels)) ) " +
"AND ( EXISTS (FROM wrl.orderElement.labels as etq WHERE etq IN (:labels)) " +
"OR EXISTS (FROM wrl.workReport.orderElement.labels as etqwr WHERE etqwr IN (:labels)) ) ";
break;
case ANY:
default:
strQuery += " AND ( ( EXISTS (FROM wrl.labels as etq WHERE etq IN (:labels)) " +
"OR EXISTS (FROM wrl.workReport.labels as etqwr WHERE etqwr IN (:labels)) ) " +
"OR ( EXISTS (FROM wrl.orderElement.labels as etq WHERE etq IN (:labels)) " +
"OR EXISTS (FROM wrl.workReport.orderElement.labels as etqwr WHERE etqwr " +
"IN (:labels)) ) ) ";
break;
}
}
// Set Criterions
if (criterions != null && !criterions.isEmpty()) {
strQuery += " AND EXISTS (FROM resource.criterionSatisfactions as satisfaction "
+ " WHERE satisfaction.criterion IN (:criterions)) ";
if ( criterions != null && !criterions.isEmpty() ) {
strQuery +=
" AND EXISTS (FROM resource.criterionSatisfactions as satisfaction " +
" WHERE satisfaction.criterion IN (:criterions)) ";
}
// Order by
@ -198,22 +207,24 @@ public class ResourceDAO extends IntegrationEntityDAO<Resource> implements
// Set parameters
Query query = getSession().createQuery(strQuery);
if (startingDate != null) {
if ( startingDate != null ) {
query.setParameter("startingDate", startingDate);
}
if (endingDate != null) {
if ( endingDate != null ) {
query.setParameter("endingDate", endingDate);
}
if (resources != null && !resources.isEmpty()) {
if ( resources != null && !resources.isEmpty() ) {
query.setParameterList("resources", resources);
}
if (labels != null && !labels.isEmpty()) {
if ( labels != null && !labels.isEmpty() ) {
query.setParameterList("labels", labels);
}
if (criterions != null && !criterions.isEmpty()) {
query.setParameterList("criterions",
Criterion.withAllDescendants(criterions));
if ( criterions != null && !criterions.isEmpty() ) {
query.setParameterList("criterions", Criterion.withAllDescendants(criterions));
}
// Get result
@ -221,52 +232,55 @@ public class ResourceDAO extends IntegrationEntityDAO<Resource> implements
}
@Override
public List<HoursWorkedPerWorkerInAMonthDTO> getWorkingHoursPerWorker(
Integer year, Integer month) {
public List<HoursWorkedPerWorkerInAMonthDTO> getWorkingHoursPerWorker(Integer year, Integer month) {
String strQuery = "SELECT wrlresource.id, SUM(wrl.effort) "
+ "FROM WorkReportLine wrl "
+ "LEFT OUTER JOIN wrl.resource wrlresource ";
String strQuery =
"SELECT wrlresource.id, SUM(wrl.effort) " +
"FROM WorkReportLine wrl " +
"LEFT OUTER JOIN wrl.resource wrlresource ";
if (year != null) {
if ( year != null ) {
strQuery += "WHERE YEAR(wrl.date) = :year ";
}
if (month != null) {
if ( month != null ) {
strQuery += "AND MONTH(wrl.date) = :month ";
}
strQuery += "GROUP BY wrlresource.id, MONTH(wrl.date) ";
Query query = getSession().createQuery(strQuery);
if (year != null) {
if ( year != null ) {
query.setParameter("year", year);
}
if (month != null) {
if ( month != null ) {
query.setParameter("month", month);
}
List<HoursWorkedPerWorkerInAMonthDTO> result = toDTO(query.list());
return result;
}
@Override
public Number getRowCount() {
return (Number) getSession().createCriteria(Resource.class).setProjection(Projections.rowCount()).uniqueResult();
return (Number) getSession()
.createCriteria(Resource.class).setProjection(Projections.rowCount()).uniqueResult();
}
private List<HoursWorkedPerWorkerInAMonthDTO> toDTO(List<Object> rows) {
List<HoursWorkedPerWorkerInAMonthDTO> result = new ArrayList<HoursWorkedPerWorkerInAMonthDTO>();
List<HoursWorkedPerWorkerInAMonthDTO> result = new ArrayList<>();
for (Object row: rows) {
Object[] columns = (Object[]) row;
Resource resource = (Resource) findExistingEntity((Long) columns[0]);
EffortDuration effort = EffortDuration.seconds(((Long) columns[1])
.intValue());
Resource resource = findExistingEntity((Long) columns[0]);
EffortDuration effort = EffortDuration.seconds(((Long) columns[1]).intValue());
HoursWorkedPerWorkerInAMonthDTO dto = new HoursWorkedPerWorkerInAMonthDTO(
resource, effort);
HoursWorkedPerWorkerInAMonthDTO dto = new HoursWorkedPerWorkerInAMonthDTO(resource, effort);
result.add(dto);
}
return result;
}

View file

@ -31,6 +31,7 @@ import org.joda.time.LocalDate;
* @author Óscar González Fernández <ogonzalez@igalia.com>
*/
public abstract class Interval {
protected final LocalDate start;
protected final LocalDate end;
@ -45,21 +46,24 @@ public abstract class Interval {
public static Interval range(LocalDate start, LocalDate end) {
Validate.notNull(start, "start date must be not null");
if (end == null) {
if ( end == null ) {
return from(start);
}
if (start.equals(end)) {
if ( start.equals(end) ) {
return point(start);
}
return new Range(start, end);
}
protected Interval(LocalDate start, LocalDate end) {
Validate.notNull(start, "start date must be not null");
if (end != null) {
Validate.isTrue(start.compareTo(end) <= 0,
"start date must be equal or before than end date");
if ( end != null ) {
Validate.isTrue(start.compareTo(end) <= 0, "start date must be equal or before than end date");
}
this.start = start;
this.end = end;
}
@ -68,11 +72,12 @@ public abstract class Interval {
@Override
public boolean equals(Object obj) {
if (obj instanceof Interval) {
if ( obj instanceof Interval ) {
Interval interval = (Interval) obj;
return dateEquals(start, interval.start)
&& dateEquals(end, interval.end);
return dateEquals(start, interval.start) && dateEquals(end, interval.end);
}
return false;
}
@ -82,8 +87,7 @@ public abstract class Interval {
}
private boolean dateEquals(LocalDate date1, LocalDate date2) {
return date1 == date2
|| (date1 != null && date2 != null && date1.equals(date2));
return date1 == date2 || (date1 != null && date2 != null && date1.equals(date2));
}
public abstract boolean includes(Interval included);
@ -108,6 +112,7 @@ class Range extends Interval {
Range(LocalDate start, LocalDate end) {
super(start, end);
Validate.notNull(start);
Validate.notNull(end);
}
@ -119,36 +124,39 @@ class Range extends Interval {
@Override
public boolean includes(Interval included) {
if (included instanceof Point) {
if ( included instanceof Point ) {
Point point = (Point) included;
return point.overlapsWith(this);
}
return start.compareTo(included.start) <= 0 && included.end != null
&& end.isAfter(included.end);
return start.compareTo(included.start) <= 0 && included.end != null && end.isAfter(included.end);
}
@Override
public boolean overlapsWith(Interval interval) {
if (interval instanceof Point) {
if ( interval instanceof Point ) {
Point point = (Point) interval;
return point.overlapsWith(this);
}
if (interval instanceof OpenEndedInterval) {
if ( interval instanceof OpenEndedInterval ) {
return interval.overlapsWith(this);
}
return interval.start.compareTo(this.end) < 0
&& this.start.compareTo(interval.end) < 0;
return interval.start.compareTo(this.end) < 0 && this.start.compareTo(interval.end) < 0;
}
@Override
public String toString() {
return new StringBuilder("[").append(start).append(", ").append(end)
.append(")").toString();
return new StringBuilder("[").append(start).append(", ").append(end).append(")").toString();
}
}
class OpenEndedInterval extends Interval {
OpenEndedInterval(LocalDate start) {
super(start, null);
}
@ -165,8 +173,7 @@ class OpenEndedInterval extends Interval {
@Override
public boolean overlapsWith(Interval interval) {
return start.isBefore(interval.start) || interval.end == null
|| start.isBefore(interval.end);
return start.isBefore(interval.start) || interval.end == null || start.isBefore(interval.end);
}
@Override
@ -198,8 +205,7 @@ class Point extends Interval {
@Override
public String toString() {
return new StringBuilder().append("[").append(start).append(")")
.toString();
return new StringBuilder().append("[").append(start).append(")").toString();
}
}

View file

@ -38,19 +38,22 @@ public class Task extends BaseEntity {
public static final String RESOURCE = "resource";
public static final String ORDER_ELEMENT = "orderElement";
public static Task create() {
Task workReportLine = new Task();
workReportLine.setNewObject(true);
return workReportLine;
}
public static Task create(Integer numHours, Resource resource,
OrderElement orderElement, Set<Criterion> criterions) {
Task workReportLine = new Task(numHours, resource,
orderElement, criterions);
public static Task create(
Integer numHours,
Resource resource,
OrderElement orderElement,
Set<Criterion> criterions) {
Task workReportLine = new Task(numHours, resource, orderElement, criterions);
workReportLine.setNewObject(true);
return workReportLine;
}
@ -64,7 +67,7 @@ public class Task extends BaseEntity {
private WorkReport workReport;
private Set<Criterion> criterions = new HashSet<Criterion>();
private Set<Criterion> criterions = new HashSet<>();
/**
* Constructor for hibernate. Do not use!
@ -73,8 +76,7 @@ public class Task extends BaseEntity {
}
private Task(Integer numHours, Resource resource,
OrderElement orderElement, Set<Criterion> criterions) {
private Task(Integer numHours, Resource resource, OrderElement orderElement, Set<Criterion> criterions) {
this.numHours = numHours;
this.resource = resource;
this.orderElement = orderElement;
@ -106,7 +108,7 @@ public class Task extends BaseEntity {
}
public Set<Criterion> getCriterions() {
return new HashSet<Criterion>(criterions);
return new HashSet<>(criterions);
}
public void setCriterions(Set<Criterion> criterions) {

View file

@ -60,7 +60,7 @@ import org.springframework.stereotype.Component;
* @author Diego Pino García <dpino@igalia.com>
* @author Manuel Rego Casasnovas <rego@igalia.com>
*
* Model for UI operations related to Order Dashboard View
* Model for UI operations related to Order Dashboard View
*
*/
@Component
@ -70,43 +70,35 @@ public class DashboardModel implements IDashboardModel {
@Autowired
private IOrderResourceLoadCalculator resourceLoadCalculator;
/* Parameters */
public final static int EA_STRETCHES_PERCENTAGE_STEP = 10;
public final static int EA_STRETCHES_MIN_VALUE = -100;
public final static int EA_STRETCHES_MAX_VALUE = 150;
public final static int LTC_NUMBER_OF_INTERVALS = 10;
/* To be calculated */
public static double LTC_STRETCHES_STEP = 0;
public static double LTC_STRETCHES_MIN_VALUE = 0;
public static double LTC_STRETCHES_MAX_VALUE = 0;
private Order currentOrder;
private List<TaskElement> criticalPath;
private Integer taskCount = null;
private final Map<TaskStatusEnum, BigDecimal> taskStatusStats;
private final Map<TaskDeadlineViolationStatusEnum, BigDecimal> taskDeadlineViolationStatusStats;
private BigDecimal marginWithDeadLine;
private Integer absoluteMarginWithDeadLine;
public DashboardModel() {
taskStatusStats = new EnumMap<TaskStatusEnum, BigDecimal>(
TaskStatusEnum.class);
taskDeadlineViolationStatusStats = new EnumMap<TaskDeadlineViolationStatusEnum, BigDecimal>(
TaskDeadlineViolationStatusEnum.class);
taskStatusStats = new EnumMap<>(TaskStatusEnum.class);
taskDeadlineViolationStatusStats = new EnumMap<>(TaskDeadlineViolationStatusEnum.class);
}
@Override
public void setCurrentOrder(PlanningState planningState, List<TaskElement> criticalPath) {
final Order order = planningState.getOrder();
resourceLoadCalculator.setOrder(order,
planningState.getAssignmentsCalculator());
resourceLoadCalculator.setOrder(order, planningState.getAssignmentsCalculator());
this.currentOrder = order;
this.criticalPath = criticalPath;
this.taskCount = null;
if (tasksAvailable()) {
if ( tasksAvailable() ) {
this.calculateGlobalProgress();
this.calculateTaskStatusStatistics();
this.calculateTaskViolationStatusStatistics();
@ -139,26 +131,23 @@ public class DashboardModel implements IDashboardModel {
/* Progress KPI: "Deadline violation" */
@Override
public BigDecimal getPercentageOfOnScheduleTasks() {
return taskDeadlineViolationStatusStats
.get(TaskDeadlineViolationStatusEnum.ON_SCHEDULE);
return taskDeadlineViolationStatusStats.get(TaskDeadlineViolationStatusEnum.ON_SCHEDULE);
}
@Override
public BigDecimal getPercentageOfTasksWithViolatedDeadline() {
return taskDeadlineViolationStatusStats
.get(TaskDeadlineViolationStatusEnum.DEADLINE_VIOLATED);
return taskDeadlineViolationStatusStats.get(TaskDeadlineViolationStatusEnum.DEADLINE_VIOLATED);
}
@Override
public BigDecimal getPercentageOfTasksWithNoDeadline() {
return taskDeadlineViolationStatusStats
.get(TaskDeadlineViolationStatusEnum.NO_DEADLINE);
return taskDeadlineViolationStatusStats.get(TaskDeadlineViolationStatusEnum.NO_DEADLINE);
}
/* Progress KPI: "Global Progress of the Project" */
private void calculateGlobalProgress() {
TaskGroup rootTask = getRootTask();
if (rootTask == null) {
if ( rootTask == null ) {
throw new RuntimeException("Root task is null");
}
rootTask.updateCriticalPathProgress(criticalPath);
@ -170,8 +159,7 @@ public class DashboardModel implements IDashboardModel {
}
private BigDecimal asPercentage(BigDecimal value) {
return value != null ? value.multiply(BigDecimal.valueOf(100))
: BigDecimal.ZERO;
return value != null ? value.multiply(BigDecimal.valueOf(100)) : BigDecimal.ZERO;
}
@Override
@ -181,8 +169,7 @@ public class DashboardModel implements IDashboardModel {
@Override
public BigDecimal getExpectedAdvancePercentageByHours() {
return asPercentage(getRootTask()
.getTheoreticalProgressByNumHoursForAllTasksUntilNow());
return asPercentage(getRootTask().getTheoreticalProgressByNumHoursForAllTasksUntilNow());
}
@Override
@ -192,8 +179,7 @@ public class DashboardModel implements IDashboardModel {
@Override
public BigDecimal getExpectedCriticalPathProgressByNumHours() {
return asPercentage(getRootTask()
.getTheoreticalProgressByNumHoursForCriticalPathUntilNow());
return asPercentage(getRootTask().getTheoreticalProgressByNumHoursForCriticalPathUntilNow());
}
@Override
@ -203,8 +189,7 @@ public class DashboardModel implements IDashboardModel {
@Override
public BigDecimal getExpectedCriticalPathProgressByDuration() {
return asPercentage(getRootTask()
.getTheoreticalProgressByDurationForCriticalPathUntilNow());
return asPercentage(getRootTask().getTheoreticalProgressByDurationForCriticalPathUntilNow());
}
/* Time KPI: Margin with deadline */
@ -214,29 +199,26 @@ public class DashboardModel implements IDashboardModel {
}
private void calculateMarginWithDeadLine() {
if (this.getRootTask() == null) {
if ( this.getRootTask() == null ) {
throw new RuntimeException("Root task is null");
}
if (this.currentOrder.getDeadline() == null) {
if ( this.currentOrder.getDeadline() == null ) {
this.marginWithDeadLine = null;
return;
}
TaskGroup rootTask = getRootTask();
LocalDate endDate = TaskElement.maxDate(rootTask.getChildren())
.asExclusiveEnd();
Days orderDuration = Days.daysBetween(
TaskElement.minDate(rootTask.getChildren()).getDate(), endDate);
LocalDate endDate = TaskElement.maxDate(rootTask.getChildren()).asExclusiveEnd();
Days orderDuration = Days.daysBetween(TaskElement.minDate(rootTask.getChildren()).getDate(), endDate);
LocalDate deadLineAsLocalDate = LocalDate.fromDateFields(currentOrder
.getDeadline());
Days deadlineOffset = Days.daysBetween(endDate,
deadLineAsLocalDate.plusDays(1));
LocalDate deadLineAsLocalDate = LocalDate.fromDateFields(currentOrder.getDeadline());
Days deadlineOffset = Days.daysBetween(endDate, deadLineAsLocalDate.plusDays(1));
BigDecimal outcome = new BigDecimal(deadlineOffset.getDays(),
MathContext.DECIMAL32);
this.marginWithDeadLine = outcome.divide(
new BigDecimal(orderDuration.getDays()), 8,
BigDecimal.ROUND_HALF_EVEN);
BigDecimal outcome = new BigDecimal(deadlineOffset.getDays(), MathContext.DECIMAL32);
this.marginWithDeadLine =
outcome.divide(new BigDecimal(orderDuration.getDays()), 8, BigDecimal.ROUND_HALF_EVEN);
}
@Override
@ -248,13 +230,15 @@ public class DashboardModel implements IDashboardModel {
TaskElement rootTask = getRootTask();
Date deadline = currentOrder.getDeadline();
if (rootTask == null) {
if ( rootTask == null ) {
throw new RuntimeException("Root task is null");
}
if (deadline == null) {
if ( deadline == null ) {
this.absoluteMarginWithDeadLine = null;
return;
}
absoluteMarginWithDeadLine = daysBetween(
TaskElement.maxDate(rootTask.getChildren()).asExclusiveEnd(),
LocalDate.fromDateFields(deadline).plusDays(1));
@ -277,16 +261,19 @@ public class DashboardModel implements IDashboardModel {
@Override
public Map<Interval, Integer> calculateTaskCompletion() {
List<Double> deviations = getTaskLagDeviations();
return calculateHistogramIntervals(deviations, 6, 1);
}
private List<Double> getTaskLagDeviations() {
if (this.getRootTask() == null) {
if ( this.getRootTask() == null ) {
throw new RuntimeException("Root task is null");
}
CalculateFinishedTasksLagInCompletionVisitor visitor = new CalculateFinishedTasksLagInCompletionVisitor();
TaskElement rootTask = getRootTask();
rootTask.acceptVisitor(visitor);
return visitor.getDeviations();
}
@ -318,18 +305,19 @@ public class DashboardModel implements IDashboardModel {
@Override
public Map<Interval, Integer> calculateEstimationAccuracy() {
List<Double> deviations = getEstimationAccuracyDeviations();
return calculateHistogramIntervals(deviations, 6, 10);
}
private Map<Interval, Integer> calculateHistogramIntervals(
List<Double> values, int intervalsNumber, int intervalMinimumSize) {
Map<Interval, Integer> result = new LinkedHashMap<Interval, Integer>();
private Map<Interval, Integer> calculateHistogramIntervals(List<Double> values, int intervalsNumber,
int intervalMinimumSize) {
Map<Interval, Integer> result = new LinkedHashMap<>();
int totalMinimumSize = intervalsNumber * intervalMinimumSize;
int halfSize = totalMinimumSize / 2;
double maxDouble, minDouble;
if (values.isEmpty()) {
if ( values.isEmpty() ) {
minDouble = -halfSize;
maxDouble = halfSize;
} else {
@ -339,39 +327,34 @@ public class DashboardModel implements IDashboardModel {
// If min and max are between -halfSize and +halfSize, set -halfSize as
// min and +halfSize as max
if (minDouble >= -halfSize && maxDouble <= halfSize) {
if ( minDouble >= -halfSize && maxDouble <= halfSize ) {
minDouble = -halfSize;
maxDouble = halfSize;
}
// If the difference between min and max is less than totalMinimumSize,
// decrease min
// and increase max till get that difference
boolean changeMin = true;
while (maxDouble - minDouble < totalMinimumSize) {
if (changeMin) {
minDouble -= intervalMinimumSize;
} else {
maxDouble += intervalMinimumSize;
}
minDouble -= intervalMinimumSize;
}
// Round min and max properly depending on decimal part or not
int min;
double minDecimalPart = minDouble - (int) minDouble;
if (minDouble >= 0) {
if ( minDouble >= 0 ) {
min = (int) (minDouble - minDecimalPart);
} else {
min = (int) (minDouble - minDecimalPart);
if (minDecimalPart != 0) {
if ( minDecimalPart != 0 ) {
min--;
}
}
int max;
double maxDecimalPart = maxDouble - (int) maxDouble;
if (maxDouble >= 0) {
if ( maxDouble >= 0 ) {
max = (int) (maxDouble - maxDecimalPart);
if (maxDecimalPart != 0) {
if ( maxDecimalPart != 0 ) {
max++;
}
} else {
@ -387,10 +370,11 @@ public class DashboardModel implements IDashboardModel {
for (int i = 0; i < intervalsNumber; i++) {
int to = from + (int) delta;
// Fix to depending on decimal part if it's not the last interval
if (deltaDecimalPart == 0 && i != (intervalsNumber - 1)) {
if ( deltaDecimalPart == 0 && i != (intervalsNumber - 1) ) {
to--;
}
result.put(new Interval(from, to), Integer.valueOf(0));
result.put(new Interval(from, to), 0);
from = to + 1;
}
@ -398,23 +382,25 @@ public class DashboardModel implements IDashboardModel {
// Construct map with number of tasks for each interval
final Set<Interval> intervals = result.keySet();
for (Double each : values) {
Interval interval = Interval.containingValue(
intervals, each);
if (interval != null) {
Interval interval = Interval.containingValue(intervals, each);
if ( interval != null ) {
Integer value = result.get(interval);
result.put(interval, value + 1);
}
}
return result;
}
private List<Double> getEstimationAccuracyDeviations() {
if (this.getRootTask() == null) {
if ( this.getRootTask() == null ) {
throw new RuntimeException("Root task is null");
}
CalculateFinishedTasksEstimationDeviationVisitor visitor = new CalculateFinishedTasksEstimationDeviationVisitor();
TaskElement rootTask = getRootTask();
rootTask.acceptVisitor(visitor);
return visitor.getDeviations();
}
@ -427,13 +413,13 @@ public class DashboardModel implements IDashboardModel {
this.max = max;
}
public static Interval containingValue(
Collection<Interval> intervals, double value) {
public static Interval containingValue(Collection<Interval> intervals, double value) {
for (Interval each : intervals) {
if (each.includes(value)) {
if ( each.includes(value) ) {
return each;
}
}
return null;
}
@ -452,20 +438,25 @@ public class DashboardModel implements IDashboardModel {
public Map<TaskStatusEnum, Integer> calculateTaskStatus() {
AccumulateTasksStatusVisitor visitor = new AccumulateTasksStatusVisitor();
TaskElement rootTask = getRootTask();
if (this.getRootTask() == null) {
if ( this.getRootTask() == null ) {
throw new RuntimeException("Root task is null");
}
resetTasksStatusInGraph();
rootTask.acceptVisitor(visitor);
return visitor.getTaskStatusData();
}
private void calculateTaskStatusStatistics() {
AccumulateTasksStatusVisitor visitor = new AccumulateTasksStatusVisitor();
TaskElement rootTask = getRootTask();
if (this.getRootTask() == null) {
if ( this.getRootTask() == null ) {
throw new RuntimeException("Root task is null");
}
resetTasksStatusInGraph();
rootTask.acceptVisitor(visitor);
Map<TaskStatusEnum, Integer> count = visitor.getTaskStatusData();
@ -475,21 +466,21 @@ public class DashboardModel implements IDashboardModel {
private void calculateTaskViolationStatusStatistics() {
AccumulateTasksDeadlineStatusVisitor visitor = new AccumulateTasksDeadlineStatusVisitor();
TaskElement rootTask = getRootTask();
if (this.getRootTask() == null) {
if ( this.getRootTask() == null ) {
throw new RuntimeException("Root task is null");
}
rootTask.acceptVisitor(visitor);
Map<TaskDeadlineViolationStatusEnum, Integer> count = visitor
.getTaskDeadlineViolationStatusData();
Map<TaskDeadlineViolationStatusEnum, Integer> count = visitor.getTaskDeadlineViolationStatusData();
mapAbsoluteValuesToPercentages(count, taskDeadlineViolationStatusStats);
}
private <T> void mapAbsoluteValuesToPercentages(Map<T, Integer> source,
Map<T, BigDecimal> dest) {
private <T> void mapAbsoluteValuesToPercentages(Map<T, Integer> source, Map<T, BigDecimal> dest) {
int totalTasks = countTasksInAResultMap(source);
for (Map.Entry<T, Integer> entry : source.entrySet()) {
BigDecimal percentage;
if (totalTasks == 0) {
if ( totalTasks == 0 ) {
percentage = BigDecimal.ZERO;
} else {
@ -511,18 +502,18 @@ public class DashboardModel implements IDashboardModel {
}
private int countTasksInAResultMap(Map<? extends Object, Integer> map) {
/*
* It's only needed to count the number of tasks once each time setOrder
* is called.
*/
if (this.taskCount != null) {
// It's only needed to count the number of tasks once each time setOrder is called.
if ( this.taskCount != null ) {
return this.taskCount.intValue();
}
int sum = 0;
for (Object count : map.values()) {
sum += (Integer) count;
}
this.taskCount = new Integer(sum);
this.taskCount = sum;
return sum;
}
@ -534,36 +525,32 @@ public class DashboardModel implements IDashboardModel {
@Override
public BigDecimal getOvertimeRatio() {
EffortDuration totalLoad = sumAll(resourceLoadCalculator.getAllLoad());
EffortDuration overload = sumAll(resourceLoadCalculator
.getAllOverload());
return overload.dividedByAndResultAsBigDecimal(totalLoad).setScale(2,
RoundingMode.HALF_UP);
EffortDuration overload = sumAll(resourceLoadCalculator.getAllOverload());
return overload.dividedByAndResultAsBigDecimal(totalLoad).setScale(2, RoundingMode.HALF_UP);
}
private EffortDuration sumAll(
ContiguousDaysLine<EffortDuration> contiguousDays) {
private EffortDuration sumAll(ContiguousDaysLine<EffortDuration> contiguousDays) {
EffortDuration result = EffortDuration.zero();
Iterator<OnDay<EffortDuration>> iterator = contiguousDays
.iterator();
Iterator<OnDay<EffortDuration>> iterator = contiguousDays.iterator();
while (iterator.hasNext()) {
OnDay<EffortDuration> value = iterator.next();
EffortDuration effort = value.getValue();
result = EffortDuration.sum(result, effort);
}
return result;
}
@Override
public BigDecimal getAvailabilityRatio() {
EffortDuration totalLoad = sumAll(resourceLoadCalculator.getAllLoad());
EffortDuration overload = sumAll(resourceLoadCalculator
.getAllOverload());
EffortDuration overload = sumAll(resourceLoadCalculator.getAllOverload());
EffortDuration load = totalLoad.minus(overload);
EffortDuration capacity = sumAll(resourceLoadCalculator.getMaxCapacityOnResources());
EffortDuration capacity = sumAll(resourceLoadCalculator
.getMaxCapacityOnResources());
return BigDecimal.ONE.setScale(2, RoundingMode.HALF_UP).subtract(
load.dividedByAndResultAsBigDecimal(capacity));
return BigDecimal.ONE.setScale(2, RoundingMode.HALF_UP).subtract(load.dividedByAndResultAsBigDecimal(capacity));
}
}

View file

@ -79,8 +79,7 @@ import org.zkoss.zul.api.Popup;
* @author Manuel Rego Casasnovas <mrego@igalia.com>
*/
@SuppressWarnings("serial")
public class PersonalTimesheetController extends GenericForwardComposer
implements IPersonalTimesheetController {
public class PersonalTimesheetController extends GenericForwardComposer implements IPersonalTimesheetController {
private final static String EFFORT_DURATION_TEXTBOX_WIDTH = "30px";
private final static String TOTAL_DURATION_TEXTBOX_WIDTH = "50px";
@ -142,29 +141,32 @@ public class PersonalTimesheetController extends GenericForwardComposer
initPersonalTimesheetDates();
switch (personalTimesheetRow.getType()) {
case ORDER_ELEMENT:
renderOrderElementRow(row,
personalTimesheetRow.getOrderElemement());
break;
case OTHER:
renderOtherRow(row);
break;
case CAPACITY:
renderCapacityRow(row);
break;
case TOTAL:
renderTotalRow(row);
break;
case EXTRA:
renderExtraRow(row);
case ORDER_ELEMENT:
renderOrderElementRow(row, personalTimesheetRow.getOrderElemement());
break;
// This is the last row so we can load the info in the summary
updateSummary();
break;
default:
throw new IllegalStateException(
"Unknown PersonalTimesheetRow type: "
+ personalTimesheetRow.getType());
case OTHER:
renderOtherRow(row);
break;
case CAPACITY:
renderCapacityRow(row);
break;
case TOTAL:
renderTotalRow(row);
break;
case EXTRA:
renderExtraRow(row);
// This is the last row so we can load the info in the summary
updateSummary();
break;
default:
throw new IllegalStateException(
"Unknown PersonalTimesheetRow type: " + personalTimesheetRow.getType());
}
}
@ -174,81 +176,78 @@ public class PersonalTimesheetController extends GenericForwardComposer
}
private void renderOrderElementRow(Row row, OrderElement orderElement) {
Util.appendLabel(row, personalTimesheetModel.getOrder(orderElement)
.getName());
Util.appendLabel(row, personalTimesheetModel.getOrder(orderElement).getName());
Util.appendLabel(row, orderElement.getName());
appendInputsForDays(row, orderElement);
if (personalTimesheetModel.hasOtherReports()) {
if ( personalTimesheetModel.hasOtherReports() ) {
appendOtherColumn(row, orderElement);
}
appendTotalColumn(row, orderElement);
}
private void appendInputsForDays(Row row,
final OrderElement orderElement) {
for (LocalDate day = first; day.compareTo(last) <= 0; day = day
.plusDays(1)) {
private void appendInputsForDays(Row row, final OrderElement orderElement) {
for (LocalDate day = first; day.compareTo(last) <= 0; day = day.plusDays(1)) {
final LocalDate textboxDate = day;
final Textbox textbox = new Textbox();
textbox.setHflex("true");
Util.bind(textbox, new Util.Getter<String>() {
@Override
public String get() {
EffortDuration effortDuration = personalTimesheetModel
.getEffortDuration(orderElement, textboxDate);
return effortDurationToString(effortDuration);
}
}, new Util.Setter<String>() {
@Override
public void set(String value) {
EffortDuration effortDuration = effortDurationFromString(value);
if (effortDuration == null) {
throw new WrongValueException(textbox,
_("Invalid Effort Duration"));
}
personalTimesheetModel.setEffortDuration(orderElement,
textboxDate, effortDuration);
markAsModified(textbox);
updateTotals(orderElement, textboxDate);
}
Util.bind(
textbox,
new Util.Getter<String>() {
@Override
public String get() {
private void updateTotals(OrderElement orderElement,
LocalDate date) {
updateTotalColumn(orderElement);
updateTotalRow(date);
updateExtraRow(date);
updateTotalColumn();
updateTotalExtraColumn();
updateSummary();
}
EffortDuration effortDuration =
personalTimesheetModel.getEffortDuration(orderElement, textboxDate);
});
return effortDurationToString(effortDuration);
}
},
new Util.Setter<String>() {
@Override
public void set(String value) {
EffortDuration effortDuration = effortDurationFromString(value);
if ( effortDuration == null ) {
throw new WrongValueException(textbox, _("Invalid Effort Duration"));
}
personalTimesheetModel.setEffortDuration(orderElement, textboxDate, effortDuration);
markAsModified(textbox);
updateTotals(orderElement, textboxDate);
}
private void updateTotals(OrderElement orderElement, LocalDate date) {
updateTotalColumn(orderElement);
updateTotalRow(date);
updateExtraRow(date);
updateTotalColumn();
updateTotalExtraColumn();
updateSummary();
}
});
EventListener openPersonalTimesheetPopup = new EventListener() {
@Override
public void onEvent(Event event) throws Exception {
openPersonalTimesheetPopup(textbox,
orderElement, textboxDate);
openPersonalTimesheetPopup(textbox, orderElement, textboxDate);
}
};
textbox.addEventListener(Events.ON_DOUBLE_CLICK,
openPersonalTimesheetPopup);
textbox.addEventListener(Events.ON_OK,
openPersonalTimesheetPopup);
if (personalTimesheetModel
.wasModified(orderElement, textboxDate)) {
textbox.addEventListener(Events.ON_DOUBLE_CLICK, openPersonalTimesheetPopup);
textbox.addEventListener(Events.ON_OK, openPersonalTimesheetPopup);
if ( personalTimesheetModel.wasModified(orderElement, textboxDate) ) {
markAsModified(textbox);
}
Cell cell = getCenteredCell(textbox);
if (personalTimesheetModel.getResourceCapacity(day).isZero()) {
if ( personalTimesheetModel.getResourceCapacity(day).isZero() ) {
setBackgroundNonCapacityCell(cell);
}
row.appendChild(cell);
@ -256,64 +255,71 @@ public class PersonalTimesheetController extends GenericForwardComposer
}
private void openPersonalTimesheetPopup(Textbox textbox,
OrderElement orderElement, LocalDate textboxDate) {
Textbox toFocus = setupPersonalTimesheetPopup(textbox,
orderElement, textboxDate);
private void openPersonalTimesheetPopup(Textbox textbox, OrderElement orderElement, LocalDate textboxDate) {
Textbox toFocus = setupPersonalTimesheetPopup(textbox, orderElement, textboxDate);
personalTimesheetPopup.open(textbox, "after_start");
toFocus.setFocus(true);
}
private Textbox setupPersonalTimesheetPopup(final Textbox textbox,
final OrderElement orderElement, final LocalDate textboxDate) {
private Textbox setupPersonalTimesheetPopup(final Textbox textbox, final OrderElement orderElement,
final LocalDate textboxDate) {
personalTimesheetPopupTask.setValue(orderElement.getName());
personalTimesheetPopupDate.setValue(textboxDate.toString());
personalTimesheetPopupEffort.getChildren().clear();
Textbox effortTextbox = Util.bind(new Textbox(),
Textbox effortTextbox = Util.bind(
new Textbox(),
new Util.Getter<String>() {
@Override
public String get() {
EffortDuration effortDuration = personalTimesheetModel
.getEffortDuration(orderElement, textboxDate);
return effortDurationToString(effortDuration);
}
}, new Util.Setter<String>() {
@Override
public void set(String value) {
EffortDuration effortDuration = effortDurationFromString(value);
if (effortDuration == null) {
throw new WrongValueException(
personalTimesheetPopupEffort,
_("Invalid Effort Duration"));
}
Events.sendEvent(new InputEvent(Events.ON_CHANGE, textbox,
value));
}
});
@Override
public String get() {
EffortDuration effortDuration =
personalTimesheetModel.getEffortDuration(orderElement, textboxDate);
return effortDurationToString(effortDuration);
}
},
new Util.Setter<String>() {
@Override
public void set(String value) {
EffortDuration effortDuration = effortDurationFromString(value);
if ( effortDuration == null ) {
throw new WrongValueException(
personalTimesheetPopupEffort, _("Invalid Effort Duration"));
}
Events.sendEvent(new InputEvent(Events.ON_CHANGE, textbox, value));
}
});
addOnOkEventToClosePopup(effortTextbox);
personalTimesheetPopupEffort.appendChild(effortTextbox);
personalTimesheetPopupFinished.getChildren().clear();
Checkbox finishedCheckbox = Util.bind(new Checkbox(),
Checkbox finishedCheckbox = Util.bind(
new Checkbox(),
new Util.Getter<Boolean>() {
@Override
public Boolean get() {
return personalTimesheetModel.isFinished(
orderElement, textboxDate);
return personalTimesheetModel.isFinished(orderElement, textboxDate);
}
}, new Util.Setter<Boolean>() {
},
new Util.Setter<Boolean>() {
@Override
public void set(Boolean value) {
personalTimesheetModel.setFinished(orderElement,
textboxDate, value);
personalTimesheetModel.setFinished(orderElement, textboxDate, value);
markAsModified(textbox);
}
});
if (!finishedCheckbox.isChecked()) {
finishedCheckbox.setDisabled(personalTimesheetModel
.isFinished(orderElement));
if ( !finishedCheckbox.isChecked() ) {
finishedCheckbox.setDisabled(personalTimesheetModel.isFinished(orderElement));
}
addOnOkEventToClosePopup(finishedCheckbox);
personalTimesheetPopupFinished.appendChild(finishedCheckbox);
@ -321,8 +327,7 @@ public class PersonalTimesheetController extends GenericForwardComposer
}
private boolean addOnOkEventToClosePopup(Component component) {
return component.addEventListener(Events.ON_OK,
new EventListener() {
return component.addEventListener(Events.ON_OK, new EventListener() {
@Override
public void onEvent(Event event) throws Exception {
closePersonalTimesheetPopup();
@ -346,13 +351,10 @@ public class PersonalTimesheetController extends GenericForwardComposer
}
private void updateTotalColumn(OrderElement orderElement) {
EffortDuration effort = personalTimesheetModel
.getEffortDuration(orderElement);
effort = effort.plus(personalTimesheetModel
.getOtherEffortDuration(orderElement));
EffortDuration effort = personalTimesheetModel.getEffortDuration(orderElement);
effort = effort.plus(personalTimesheetModel.getOtherEffortDuration(orderElement));
Textbox textbox = (Textbox) timesheet
.getFellow(getTotalRowTextboxId(orderElement));
Textbox textbox = (Textbox) timesheet.getFellow(getTotalRowTextboxId(orderElement));
textbox.setValue(effortDurationToString(effort));
}
@ -373,12 +375,13 @@ public class PersonalTimesheetController extends GenericForwardComposer
}
private void appendTotalForDays(Row row) {
for (LocalDate day = first; day.compareTo(last) <= 0; day = day
.plusDays(1)) {
for (LocalDate day = first; day.compareTo(last) <= 0; day = day.plusDays(1)) {
Cell cell = getCenteredCell(getDisabledTextbox(getTotalColumnTextboxId(day)));
if (personalTimesheetModel.getResourceCapacity(day).isZero()) {
if ( personalTimesheetModel.getResourceCapacity(day).isZero() ) {
setBackgroundNonCapacityCell(cell);
}
row.appendChild(cell);
updateTotalRow(day);
@ -386,33 +389,29 @@ public class PersonalTimesheetController extends GenericForwardComposer
}
private void updateTotalRow(LocalDate date) {
EffortDuration effort = personalTimesheetModel
.getEffortDuration(date);
effort = effort.plus(personalTimesheetModel
.getOtherEffortDuration(date));
EffortDuration effort = personalTimesheetModel.getEffortDuration(date);
effort = effort.plus(personalTimesheetModel.getOtherEffortDuration(date));
Textbox textbox = (Textbox) timesheet
.getFellow(getTotalColumnTextboxId(date));
Textbox textbox = (Textbox) timesheet.getFellow(getTotalColumnTextboxId(date));
textbox.setValue(effortDurationToString(effort));
}
private void appendTotalColumn(Row row) {
Cell totalCell = getCenteredCell(getDisabledTextbox(getTotalTextboxId()));
if (personalTimesheetModel.hasOtherReports()) {
if ( personalTimesheetModel.hasOtherReports() ) {
totalCell.setColspan(2);
}
row.appendChild(totalCell);
updateTotalColumn();
}
private void updateTotalColumn() {
EffortDuration effort = personalTimesheetModel
.getTotalEffortDuration();
effort = effort.plus(personalTimesheetModel
.getTotalOtherEffortDuration());
EffortDuration effort = personalTimesheetModel.getTotalEffortDuration();
effort = effort.plus(personalTimesheetModel.getTotalOtherEffortDuration());
Textbox textbox = (Textbox) timesheet
.getFellow(getTotalTextboxId());
Textbox textbox = (Textbox) timesheet.getFellow(getTotalTextboxId());
textbox.setValue(effortDurationToString(effort));
}
@ -424,23 +423,21 @@ public class PersonalTimesheetController extends GenericForwardComposer
private void appendOtherForDaysAndTotal(Row row) {
EffortDuration totalOther = EffortDuration.zero();
for (LocalDate day = first; day.compareTo(last) <= 0; day = day
.plusDays(1)) {
EffortDuration other = personalTimesheetModel
.getOtherEffortDuration(day);
for (LocalDate day = first; day.compareTo(last) <= 0; day = day.plusDays(1)) {
EffortDuration other = personalTimesheetModel.getOtherEffortDuration(day);
Cell cell = getCenteredCell(getDisabledTextbox(
getOtherColumnTextboxId(day), other));
if (personalTimesheetModel.getResourceCapacity(day).isZero()) {
Cell cell = getCenteredCell(getDisabledTextbox(getOtherColumnTextboxId(day), other));
if ( personalTimesheetModel.getResourceCapacity(day).isZero() ) {
setBackgroundNonCapacityCell(cell);
}
row.appendChild(cell);
totalOther = totalOther.plus(other);
}
Cell totalOtherCell = getCenteredCell(getDisabledTextbox(
getTotalOtherTextboxId(), totalOther));
Cell totalOtherCell = getCenteredCell(getDisabledTextbox(getTotalOtherTextboxId(), totalOther));
totalOtherCell.setColspan(2);
row.appendChild(totalOtherCell);
}
@ -453,26 +450,26 @@ public class PersonalTimesheetController extends GenericForwardComposer
private void appendCapcityForDaysAndTotal(Row row) {
EffortDuration totalCapacity = EffortDuration.zero();
for (LocalDate day = first; day.compareTo(last) <= 0; day = day
.plusDays(1)) {
EffortDuration capacity = personalTimesheetModel
.getResourceCapacity(day);
for (LocalDate day = first; day.compareTo(last) <= 0; day = day.plusDays(1)) {
EffortDuration capacity = personalTimesheetModel.getResourceCapacity(day);
Cell cell = getCenteredCell(getDisabledTextbox(
getCapcityColumnTextboxId(day), capacity));
if (personalTimesheetModel.getResourceCapacity(day).isZero()) {
Cell cell = getCenteredCell(getDisabledTextbox(getCapcityColumnTextboxId(day), capacity));
if ( personalTimesheetModel.getResourceCapacity(day).isZero() ) {
setBackgroundNonCapacityCell(cell);
}
row.appendChild(cell);
totalCapacity = totalCapacity.plus(capacity);
}
Cell totalCapacityCell = getCenteredCell(getDisabledTextbox(
getTotalCapacityTextboxId(), totalCapacity));
if (personalTimesheetModel.hasOtherReports()) {
Cell totalCapacityCell = getCenteredCell(getDisabledTextbox(getTotalCapacityTextboxId(), totalCapacity));
if ( personalTimesheetModel.hasOtherReports() ) {
totalCapacityCell.setColspan(2);
}
row.appendChild(totalCapacityCell);
}
@ -483,12 +480,13 @@ public class PersonalTimesheetController extends GenericForwardComposer
}
private void appendExtraForDays(Row row) {
for (LocalDate day = first; day.compareTo(last) <= 0; day = day
.plusDays(1)) {
for (LocalDate day = first; day.compareTo(last) <= 0; day = day.plusDays(1)) {
Cell cell = getCenteredCell(getDisabledTextbox(getExtraColumnTextboxId(day)));
if (personalTimesheetModel.getResourceCapacity(day).isZero()) {
if ( personalTimesheetModel.getResourceCapacity(day).isZero() ) {
setBackgroundNonCapacityCell(cell);
}
row.appendChild(cell);
updateExtraRow(day);
@ -501,40 +499,39 @@ public class PersonalTimesheetController extends GenericForwardComposer
EffortDuration capacity = getEffortDuration(getCapcityColumnTextboxId(date));
EffortDuration extra = EffortDuration.zero();
if (total.compareTo(capacity) > 0) {
if ( total.compareTo(capacity) > 0 ) {
extra = total.minus(capacity);
}
Textbox textbox = (Textbox) timesheet
.getFellow(getExtraColumnTextboxId(date));
Textbox textbox = (Textbox) timesheet.getFellow(getExtraColumnTextboxId(date));
textbox.setValue(effortDurationToString(extra));
}
private EffortDuration getEffortDuration(String textboxId) {
String value = ((Textbox) timesheet.getFellow(textboxId))
.getValue();
String value = ((Textbox) timesheet.getFellow(textboxId)).getValue();
return effortDurationFromString(value);
}
private void appendTotalExtra(Row row) {
Cell totalExtraCell = getCenteredCell(getDisabledTextbox(getTotalExtraTextboxId()));
if (personalTimesheetModel.hasOtherReports()) {
if ( personalTimesheetModel.hasOtherReports() ) {
totalExtraCell.setColspan(2);
}
row.appendChild(totalExtraCell);
updateTotalExtraColumn();
}
private void updateTotalExtraColumn() {
EffortDuration totalExtra = EffortDuration.zero();
for (LocalDate day = first; day.compareTo(last) <= 0; day = day
.plusDays(1)) {
for (LocalDate day = first; day.compareTo(last) <= 0; day = day.plusDays(1)) {
EffortDuration extra = getEffortDuration(getExtraColumnTextboxId(day));
totalExtra = totalExtra.plus(extra);
}
Textbox textbox = (Textbox) timesheet
.getFellow(getTotalExtraTextboxId());
Textbox textbox = (Textbox) timesheet.getFellow(getTotalExtraTextboxId());
textbox.setValue(effortDurationToString(totalExtra));
}
@ -543,12 +540,14 @@ public class PersonalTimesheetController extends GenericForwardComposer
textbox.setHflex("true");
textbox.setId(id);
textbox.setDisabled(true);
return textbox;
}
private Textbox getDisabledTextbox(String id, EffortDuration effort) {
Textbox textbox = getDisabledTextbox(id);
textbox.setValue(effortDurationToString(effort));
return textbox;
}
@ -556,6 +555,7 @@ public class PersonalTimesheetController extends GenericForwardComposer
Cell cell = new Cell();
cell.setAlign("center");
cell.appendChild(component);
return cell;
}
@ -563,6 +563,7 @@ public class PersonalTimesheetController extends GenericForwardComposer
Cell cell = new Cell();
cell.setAlign("left");
cell.appendChild(component);
return cell;
}
@ -582,31 +583,31 @@ public class PersonalTimesheetController extends GenericForwardComposer
checkUserComesFromEntryPointsOrSendForbiddenCode();
URLHandlerRegistry.getRedirectorFor(IPersonalTimesheetController.class)
.register(this, page);
URLHandlerRegistry.getRedirectorFor(IPersonalTimesheetController.class).register(this, page);
}
private void adjustFrozenWidth() {
// Hack to reduce frozen scrollarea
// Hack to reduce frozen scroll area
Clients.evalJavaScript("jq('.z-frozen-inner div').width(jq('.totals-column').offset().left);");
}
private void checkUserComesFromEntryPointsOrSendForbiddenCode() {
HttpServletRequest request = (HttpServletRequest) Executions
.getCurrent().getNativeRequest();
HttpServletRequest request = (HttpServletRequest) Executions.getCurrent().getNativeRequest();
Map<String, String> matrixParams = MatrixParameters.extract(request);
// If it doesn't come from a entry point
if (matrixParams.isEmpty()) {
if ( matrixParams.isEmpty() ) {
Util.sendForbiddenStatusCodeInHttpServletResponse();
}
}
private void setBreadcrumbs(Component comp) {
Component breadcrumbs = comp.getPage().getFellow("breadcrumbs");
if (breadcrumbs.getChildren() != null) {
if ( breadcrumbs.getChildren() != null ) {
breadcrumbs.getChildren().clear();
}
breadcrumbs.appendChild(new Image(BREADCRUMBS_SEPARATOR));
breadcrumbs.appendChild(new Label(_("My account")));
breadcrumbs.appendChild(new Image(BREADCRUMBS_SEPARATOR));
@ -617,7 +618,7 @@ public class PersonalTimesheetController extends GenericForwardComposer
@Override
public void goToCreateOrEditForm(LocalDate date) {
if (!SecurityUtils.isUserInRole(UserRole.ROLE_BOUND_USER)) {
if ( !SecurityUtils.isUserInRole(UserRole.ROLE_BOUND_USER) ) {
Util.sendForbiddenStatusCodeInHttpServletResponse();
}
@ -627,8 +628,9 @@ public class PersonalTimesheetController extends GenericForwardComposer
@Override
public void goToCreateOrEditFormForResource(LocalDate date,
org.libreplan.business.resources.entities.Resource resource) {
if (!SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_TIMESHEETS)) {
org.libreplan.business.resources.entities.Resource resource) {
if ( !SecurityUtils.isSuperuserOrUserInRoles(UserRole.ROLE_TIMESHEETS) ) {
Util.sendForbiddenStatusCodeInHttpServletResponse();
}
@ -653,9 +655,11 @@ public class PersonalTimesheetController extends GenericForwardComposer
private void createColumns(LocalDate date) {
createProjectAndTaskColumns();
createColumnsForDays(date);
if (personalTimesheetModel.hasOtherReports()) {
if ( personalTimesheetModel.hasOtherReports() ) {
createOtherColumn();
}
createTotalColumn();
}
@ -672,13 +676,10 @@ public class PersonalTimesheetController extends GenericForwardComposer
}
private void createColumnsForDays(LocalDate date) {
LocalDate start = personalTimesheetModel
.getPersonalTimesheetsPeriodicity().getStart(date);
LocalDate end = personalTimesheetModel
.getPersonalTimesheetsPeriodicity().getEnd(date);
LocalDate start = personalTimesheetModel.getPersonalTimesheetsPeriodicity().getStart(date);
LocalDate end = personalTimesheetModel.getPersonalTimesheetsPeriodicity().getEnd(date);
for (LocalDate day = start; day.compareTo(end) <= 0; day = day
.plusDays(1)) {
for (LocalDate day = start; day.compareTo(end) <= 0; day = day.plusDays(1)) {
Column column = new Column(day.getDayOfMonth() + "");
column.setAlign("center");
column.setWidth(EFFORT_DURATION_TEXTBOX_WIDTH);
@ -711,15 +712,15 @@ public class PersonalTimesheetController extends GenericForwardComposer
}
public List<PersonalTimesheetRow> getRows() {
List<PersonalTimesheetRow> result = PersonalTimesheetRow
.wrap(personalTimesheetModel
.getOrderElements());
if (personalTimesheetModel.hasOtherReports()) {
List<PersonalTimesheetRow> result = PersonalTimesheetRow.wrap(personalTimesheetModel.getOrderElements());
if ( personalTimesheetModel.hasOtherReports() ) {
result.add(PersonalTimesheetRow.createOtherRow());
}
result.add(PersonalTimesheetRow.createTotalRow());
result.add(PersonalTimesheetRow.createCapacityRow());
result.add(PersonalTimesheetRow.createExtraRow());
return result;
}
@ -729,22 +730,24 @@ public class PersonalTimesheetController extends GenericForwardComposer
public void save() {
personalTimesheetModel.save();
String url = IndexController.USER_DASHBOARD_URL
+ "?timesheet_saved=" + personalTimesheetModel.getDate();
if (!personalTimesheetModel.isCurrentUser()) {
String url = IndexController.USER_DASHBOARD_URL + "?timesheet_saved=" + personalTimesheetModel.getDate();
if ( !personalTimesheetModel.isCurrentUser() ) {
url = WORK_REPORTS_URL + "?timesheet_saved=true";
}
Executions.getCurrent().sendRedirect(url);
}
public void saveAndContinue() {
personalTimesheetModel.save();
if (personalTimesheetModel.isCurrentUser()) {
if ( personalTimesheetModel.isCurrentUser() ) {
goToCreateOrEditForm(personalTimesheetModel.getDate());
} else {
goToCreateOrEditFormForResource(personalTimesheetModel.getDate(),
personalTimesheetModel.getWorker());
goToCreateOrEditFormForResource(personalTimesheetModel.getDate(), personalTimesheetModel.getWorker());
}
messagesForUser.showMessage(Level.INFO, _("Personal timesheet saved"));
Util.reloadBindings(timesheet);
}
@ -752,16 +755,17 @@ public class PersonalTimesheetController extends GenericForwardComposer
public void cancel() {
personalTimesheetModel.cancel();
String url = IndexController.USER_DASHBOARD_URL;
if (!personalTimesheetModel.isCurrentUser()) {
if ( !personalTimesheetModel.isCurrentUser() ) {
url = WORK_REPORTS_URL;
}
Executions.getCurrent().sendRedirect(url);
}
public void addOrderElement() {
OrderElement orderElement = (OrderElement) orderElementBandboxSearch
.getSelectedElement();
if (orderElement != null) {
OrderElement orderElement = (OrderElement) orderElementBandboxSearch.getSelectedElement();
if ( orderElement != null ) {
personalTimesheetModel.addOrderElement(orderElement);
orderElementBandboxSearch.setSelectedElement(null);
Util.reloadBindings(timesheet);
@ -778,18 +782,17 @@ public class PersonalTimesheetController extends GenericForwardComposer
}
public void previousPeriod() {
if (personalTimesheetModel.isModified()) {
throw new WrongValueException(
previousPeriod,
if ( personalTimesheetModel.isModified() ) {
throw new WrongValueException(previousPeriod,
_("There are unsaved changes in the current personal timesheet, please save before moving"));
}
sendToPersonalTimesheet(personalTimesheetModel.getPrevious());
}
public void nextPeriod() {
if (personalTimesheetModel.isModified()) {
throw new WrongValueException(
nextPeriod,
if ( personalTimesheetModel.isModified() ) {
throw new WrongValueException(nextPeriod,
_("There are unsaved changes in the current personal timesheet, please save before moving"));
}
@ -803,6 +806,7 @@ public class PersonalTimesheetController extends GenericForwardComposer
personalTimesheetController.goToCreateOrEditForm(date);
}
});
Executions.getCurrent().sendRedirect(capturePath);
}
@ -855,7 +859,7 @@ public class PersonalTimesheetController extends GenericForwardComposer
}
private static String effortDurationToString(EffortDuration effort) {
if (effort == null || effort.isZero()) {
if ( effort == null || effort.isZero() ) {
return "";
}
@ -863,19 +867,19 @@ public class PersonalTimesheetController extends GenericForwardComposer
}
private static EffortDuration effortDurationFromString(String effort) {
if (StringUtils.isBlank(effort)) {
if ( StringUtils.isBlank(effort) ) {
return EffortDuration.zero();
}
String decimalSeparator = ((DecimalFormat) DecimalFormat
.getInstance(Locales.getCurrent()))
.getDecimalFormatSymbols().getDecimalSeparator() + "";
if (effort.contains(decimalSeparator) || effort.contains(".")) {
if ( effort.contains(decimalSeparator) || effort.contains(".") ) {
try {
effort = effort.replace(decimalSeparator, ".");
double hours = Double.parseDouble(effort);
return EffortDuration.fromHoursAsBigDecimal(new BigDecimal(
hours));
return EffortDuration.fromHoursAsBigDecimal(new BigDecimal(hours));
} catch (NumberFormatException e) {
return null;
}
@ -887,21 +891,23 @@ public class PersonalTimesheetController extends GenericForwardComposer
public void updateSummary() {
EffortDuration total = getEffortDurationFromTextbox(getTotalTextboxId());
EffortDuration other = EffortDuration.zero();
if (personalTimesheetModel.hasOtherReports()) {
if ( personalTimesheetModel.hasOtherReports() ) {
other = getEffortDurationFromTextbox(getTotalOtherTextboxId());
}
EffortDuration capacity = getEffortDurationFromTextbox(getTotalCapacityTextboxId());
EffortDuration extraPerDay = getEffortDurationFromTextbox(getTotalExtraTextboxId());
EffortDuration timesheet = total.minus(other);
EffortDuration extra = EffortDuration.zero();
if (total.compareTo(capacity) > 0) {
if ( total.compareTo(capacity) > 0 ) {
extra = total.minus(capacity);
}
if (personalTimesheetModel.hasOtherReports()) {
summaryTotalPersonalTimesheet
.setValue(timesheet.toFormattedString());
if ( personalTimesheetModel.hasOtherReports() ) {
summaryTotalPersonalTimesheet.setValue(timesheet.toFormattedString());
summaryTotalOther.setValue(other.toFormattedString());
}
@ -912,8 +918,7 @@ public class PersonalTimesheetController extends GenericForwardComposer
}
private EffortDuration getEffortDurationFromTextbox(String id) {
return effortDurationFromString(((Textbox) timesheet.getFellow(id))
.getValue());
return effortDurationFromString(((Textbox) timesheet.getFellow(id)).getValue());
}
public boolean hasOtherReports() {
@ -932,19 +937,19 @@ public class PersonalTimesheetController extends GenericForwardComposer
* This is used to mark the special rows like capacity and total.
*/
class PersonalTimesheetRow {
enum PersonalTimesheetRowType {
ORDER_ELEMENT, OTHER, CAPACITY, TOTAL, EXTRA
};
}
private PersonalTimesheetRowType type;
private OrderElement orderElemement;
public static PersonalTimesheetRow createOrderElementRow(
OrderElement orderElemement) {
PersonalTimesheetRow row = new PersonalTimesheetRow(
PersonalTimesheetRowType.ORDER_ELEMENT);
public static PersonalTimesheetRow createOrderElementRow(OrderElement orderElemement) {
PersonalTimesheetRow row = new PersonalTimesheetRow(PersonalTimesheetRowType.ORDER_ELEMENT);
Assert.notNull(orderElemement);
row.orderElemement = orderElemement;
return row;
}
@ -964,12 +969,12 @@ class PersonalTimesheetRow {
return new PersonalTimesheetRow(PersonalTimesheetRowType.EXTRA);
}
public static List<PersonalTimesheetRow> wrap(
List<OrderElement> orderElements) {
List<PersonalTimesheetRow> result = new ArrayList<PersonalTimesheetRow>();
public static List<PersonalTimesheetRow> wrap(List<OrderElement> orderElements) {
List<PersonalTimesheetRow> result = new ArrayList<>();
for (OrderElement each : orderElements) {
result.add(createOrderElementRow(each));
}
return result;
}

View file

@ -390,9 +390,9 @@
<!-- Commons lang -->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.4</version>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
<!-- Commons Math-->