diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/CompanyPlanningModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/CompanyPlanningModel.java index 9c44e56ce..daf952f8c 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/CompanyPlanningModel.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/CompanyPlanningModel.java @@ -20,8 +20,6 @@ package org.navalplanner.web.planner; -import java.io.IOException; -import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -31,10 +29,6 @@ import java.util.List; import java.util.SortedMap; import java.util.TreeMap; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - import org.joda.time.LocalDate; import org.navalplanner.business.calendars.entities.ResourceCalendar; import org.navalplanner.business.calendars.entities.SameWorkHoursEveryDay; @@ -50,8 +44,6 @@ import org.navalplanner.business.planner.entities.TaskGroup; import org.navalplanner.business.planner.entities.TaskMilestone; import org.navalplanner.business.resources.daos.IResourceDAO; import org.navalplanner.business.resources.entities.Resource; -import org.navalplanner.web.servlets.CallbackServlet; -import org.navalplanner.web.servlets.CallbackServlet.IServletRequestHandler; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Scope; @@ -82,12 +74,6 @@ import org.zkoss.zul.Div; @Scope(BeanDefinition.SCOPE_SINGLETON) public abstract class CompanyPlanningModel implements ICompanyPlanningModel { - /** - * Number of days to Thursday since the beginning of the week. In order to - * calculate the middle of a week. - */ - private final static int DAYS_TO_THURSDAY = 3; - @Autowired private IOrderDAO orderDAO; @@ -100,11 +86,9 @@ public abstract class CompanyPlanningModel implements ICompanyPlanningModel { @Autowired private IAdHocTransactionService transactionService; - private Integer maximunValueForChart = 0; - private IZoomLevelChangedListener zoomListener; - private ZoomLevel zoomLevel = ZoomLevel.DETAIL_ONE; + private ILoadChartFiller loadChartFiller = new CompanyLoadChartFiller(); private final class TaskElementNavigator implements IStructureNavigator { @@ -154,7 +138,8 @@ public abstract class CompanyPlanningModel implements ICompanyPlanningModel { } private void setupChart(Timeplot chartComponent, TimeTracker timeTracker) { - fillChart(chartComponent, timeTracker.getRealInterval(), timeTracker + loadChartFiller.fillChart(chartComponent, + timeTracker.getRealInterval(), timeTracker .getHorizontalSize()); fillChartOnZoomChange(chartComponent, timeTracker); } @@ -166,15 +151,15 @@ public abstract class CompanyPlanningModel implements ICompanyPlanningModel { @Override public void zoomLevelChanged(final ZoomLevel detailLevel) { - zoomLevel = detailLevel; + loadChartFiller.setZoomLevel(detailLevel); transactionService .runOnReadOnlyTransaction(new IOnTransaction() { @Override public Void execute() { - fillChart(chartComponent, - timeTracker.getRealInterval(), timeTracker - .getHorizontalSize()); + loadChartFiller.fillChart(chartComponent, + timeTracker.getRealInterval(), + timeTracker.getHorizontalSize()); return null; } }); @@ -262,165 +247,6 @@ public abstract class CompanyPlanningModel implements ICompanyPlanningModel { // spring method injection protected abstract ITaskElementAdapter getTaskElementAdapter(); - private void fillChart(Timeplot chart, Interval interval, Integer size) { - chart.getChildren().clear(); - chart.invalidate(); - maximunValueForChart = 0; - - Plotinfo plotInfoLoad = getLoadPlotInfo(interval.getStart(), interval - .getFinish()); - plotInfoLoad.setFillColor("0000FF"); - - Plotinfo plotInfoMax = getCalendarMaximumAvailabilityPlotInfo(interval - .getStart(), interval.getFinish()); - plotInfoMax.setLineColor("FF0000"); - - ValueGeometry valueGeometry = new DefaultValueGeometry(); - valueGeometry.setMin(0); - valueGeometry.setMax(maximunValueForChart); - valueGeometry.setGridColor("#000000"); - valueGeometry.setAxisLabelsPlacement("left"); - - plotInfoLoad.setValueGeometry(valueGeometry); - plotInfoMax.setValueGeometry(valueGeometry); - - chart.appendChild(plotInfoMax); - chart.appendChild(plotInfoLoad); - - size = size + (16 * 2); - chart.setWidth(size + "px"); - chart.setHeight("100px"); - } - - private Plotinfo getLoadPlotInfo(Date start, Date finish) { - List dayAssignments = dayAssignmentDAO.list(DayAssignment.class); - SortedMap mapDayAssignments = calculateHoursAdditionByDay(dayAssignments); - - String uri = getServletUri(mapDayAssignments, start, finish); - - PlotDataSource pds = new PlotDataSource(); - pds.setDataSourceUri(uri); - pds.setSeparator(" "); - - Plotinfo plotInfo = new Plotinfo(); - plotInfo.setPlotDataSource(pds); - - return plotInfo; - } - - private void printLine(PrintWriter writer, LocalDate day, Integer hours) { - writer.println(day.toString("yyyyMMdd") + " " + hours); - } - - private void fillZeroValueFromStart(PrintWriter writer, Date start, - SortedMap mapDayAssignments) { - LocalDate day = new LocalDate(start); - if (mapDayAssignments.isEmpty()) { - printLine(writer, day, 0); - } else if (day.compareTo(mapDayAssignments.firstKey()) < 0) { - printLine(writer, day, 0); - if (!day.equals(mapDayAssignments.firstKey().minusDays(1))) { - printLine(writer, mapDayAssignments.firstKey().minusDays(1), 0); - } - } - } - - private void fillZeroValueToFinish(PrintWriter writer, Date finish, - SortedMap mapDayAssignments) { - LocalDate day = new LocalDate(finish); - if (mapDayAssignments.isEmpty()) { - printLine(writer, day, 0); - } else if (day.compareTo(mapDayAssignments.lastKey()) > 0) { - if (!day.equals(mapDayAssignments.lastKey().plusDays(1))) { - printLine(writer, mapDayAssignments.lastKey().plusDays(1), 0); - } - printLine(writer, day, 0); - } - } - - private Plotinfo getCalendarMaximumAvailabilityPlotInfo(Date start, - Date finish) { - SortedMap mapDayAssignments = calculateHoursAdditionByDay( - resourceDAO.list(Resource.class), start, finish); - - String uri = getServletUri(mapDayAssignments, start, finish); - - PlotDataSource pds = new PlotDataSource(); - pds.setDataSourceUri(uri); - pds.setSeparator(" "); - - Plotinfo plotInfo = new Plotinfo(); - plotInfo.setPlotDataSource(pds); - - return plotInfo; - } - - private String getServletUri( - final SortedMap mapDayAssignments, - final Date start, final Date finish) { - if (mapDayAssignments.isEmpty()) { - return ""; - } - - setMaximunValueForChartIfGreater(Collections.max(mapDayAssignments.values())); - - String uri = CallbackServlet - .registerAndCreateURLFor(new IServletRequestHandler() { - - @Override - public void handle(HttpServletRequest request, - HttpServletResponse response) - throws ServletException, IOException { - PrintWriter writer = response.getWriter(); - - fillZeroValueFromStart(writer, start, mapDayAssignments); - - LocalDate firstDay = firstDay(mapDayAssignments); - LocalDate lastDay = lastDay(mapDayAssignments); - - for (LocalDate day = firstDay; day.compareTo(lastDay) <= 0; day = nextDay(day)) { - Integer hours = mapDayAssignments.get(day) != null ? mapDayAssignments - .get(day) - : 0; - printLine(writer, day, hours); - } - - fillZeroValueToFinish(writer, finish, mapDayAssignments); - - writer.close(); - } - }); - return uri; - } - - private LocalDate firstDay(SortedMap mapDayAssignments) { - LocalDate date = mapDayAssignments.firstKey(); - if (zoomByDay()) { - return date; - } else { - return date.dayOfWeek().withMinimumValue().plusDays( - DAYS_TO_THURSDAY); - } - } - - private LocalDate lastDay(SortedMap mapDayAssignments) { - LocalDate date = mapDayAssignments.lastKey(); - if (zoomByDay()) { - return date; - } else { - return date.dayOfWeek().withMinimumValue().plusDays( - DAYS_TO_THURSDAY); - } - } - - private LocalDate nextDay(LocalDate date) { - if (zoomByDay()) { - return date; - } else { - return date.plusWeeks(1); - } - } - /** * Calculate the hours by day for all the {@link DayAssignment} in the list. * @@ -456,7 +282,7 @@ public abstract class CompanyPlanningModel implements ICompanyPlanningModel { } } - if (zoomLevel.equals(ZoomLevel.DETAIL_FIVE)) { + if (loadChartFiller.zoomByDay()) { return map; } else { return groupByWeek(map); @@ -485,7 +311,7 @@ public abstract class CompanyPlanningModel implements ICompanyPlanningModel { map.put(date, hours); } - if (zoomLevel.equals(ZoomLevel.DETAIL_FIVE)) { + if (loadChartFiller.zoomByDay()) { return map; } else { return groupByWeek(map); @@ -497,7 +323,7 @@ public abstract class CompanyPlanningModel implements ICompanyPlanningModel { SortedMap result = new TreeMap(); for (LocalDate day : map.keySet()) { - LocalDate key = getKey(day); + LocalDate key = loadChartFiller.getThursdayOfThisWeek(day); if (result.get(key) == null) { result.put(key, map.get(day)); @@ -513,16 +339,6 @@ public abstract class CompanyPlanningModel implements ICompanyPlanningModel { return result; } - private LocalDate getKey(LocalDate date) { - return date.dayOfWeek().withMinimumValue().plusDays(3); - } - - private void setMaximunValueForChartIfGreater(Integer max) { - if (maximunValueForChart < max) { - maximunValueForChart = max; - } - } - private org.zkoss.zk.ui.Component getChartLegend() { Div div = new Div(); @@ -532,8 +348,75 @@ public abstract class CompanyPlanningModel implements ICompanyPlanningModel { return div; } - private boolean zoomByDay() { - return zoomLevel.equals(ZoomLevel.DETAIL_FIVE); + private class CompanyLoadChartFiller extends LoadChartFiller { + + @Override + public void fillChart(Timeplot chart, Interval interval, Integer size) { + chart.getChildren().clear(); + chart.invalidate(); + resetMaximunValueForChart(); + + Plotinfo plotInfoLoad = getLoadPlotInfo(interval.getStart(), + interval.getFinish()); + plotInfoLoad.setFillColor("0000FF"); + + Plotinfo plotInfoMax = getCalendarMaximumAvailabilityPlotInfo( + interval.getStart(), interval.getFinish()); + plotInfoMax.setLineColor("FF0000"); + + ValueGeometry valueGeometry = new DefaultValueGeometry(); + valueGeometry.setMin(0); + valueGeometry.setMax(getMaximunValueForChart()); + valueGeometry.setGridColor("#000000"); + valueGeometry.setAxisLabelsPlacement("left"); + + plotInfoLoad.setValueGeometry(valueGeometry); + plotInfoMax.setValueGeometry(valueGeometry); + + chart.appendChild(plotInfoMax); + chart.appendChild(plotInfoLoad); + + size = size + (16 * 2); + chart.setWidth(size + "px"); + chart.setHeight("100px"); + } + + private Plotinfo getLoadPlotInfo(Date start, Date finish) { + List dayAssignments = dayAssignmentDAO + .list(DayAssignment.class); + SortedMap mapDayAssignments = calculateHoursAdditionByDay(dayAssignments); + + String uri = getServletUri(mapDayAssignments, + start, finish); + + PlotDataSource pds = new PlotDataSource(); + pds.setDataSourceUri(uri); + pds.setSeparator(" "); + + Plotinfo plotInfo = new Plotinfo(); + plotInfo.setPlotDataSource(pds); + + return plotInfo; + } + + private Plotinfo getCalendarMaximumAvailabilityPlotInfo(Date start, + Date finish) { + SortedMap mapDayAssignments = calculateHoursAdditionByDay( + resourceDAO.list(Resource.class), start, finish); + + String uri = getServletUri(mapDayAssignments, + start, finish); + + PlotDataSource pds = new PlotDataSource(); + pds.setDataSourceUri(uri); + pds.setSeparator(" "); + + Plotinfo plotInfo = new Plotinfo(); + plotInfo.setPlotDataSource(pds); + + return plotInfo; + } + } } diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/ILoadChartFiller.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/ILoadChartFiller.java new file mode 100644 index 000000000..865de2a0b --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/ILoadChartFiller.java @@ -0,0 +1,53 @@ +/* + * This file is part of ###PROJECT_NAME### + * + * Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e + * Desenvolvemento Tecnolóxico de Galicia + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.navalplanner.web.planner; + +import java.util.Date; +import java.util.SortedMap; + +import org.joda.time.LocalDate; +import org.zkforge.timeplot.Timeplot; +import org.zkoss.ganttz.timetracker.zoom.ZoomLevel; +import org.zkoss.ganttz.util.Interval; + +/** + * Contract for {@link LoadChartFiller}. + * + * @author Manuel Rego Casasnovas + */ +public interface ILoadChartFiller { + + void fillChart(Timeplot chart, Interval interval, Integer size); + + String getServletUri(final SortedMap mapDayAssignments, + final Date start, final Date finish); + + void setZoomLevel(ZoomLevel zoomLevel); + + void resetMaximunValueForChart(); + + Integer getMaximunValueForChart(); + + boolean zoomByDay(); + + LocalDate getThursdayOfThisWeek(LocalDate date); + +} diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/LoadChartFiller.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/LoadChartFiller.java new file mode 100644 index 000000000..9782d7253 --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/LoadChartFiller.java @@ -0,0 +1,188 @@ +/* + * This file is part of ###PROJECT_NAME### + * + * Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e + * Desenvolvemento Tecnolóxico de Galicia + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.navalplanner.web.planner; + +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Collections; +import java.util.Date; +import java.util.SortedMap; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.joda.time.LocalDate; +import org.navalplanner.web.servlets.CallbackServlet; +import org.navalplanner.web.servlets.CallbackServlet.IServletRequestHandler; +import org.zkforge.timeplot.Timeplot; +import org.zkoss.ganttz.timetracker.zoom.ZoomLevel; +import org.zkoss.ganttz.util.Interval; + +/** + * Abstract class with the basic functionality to fill the chart. + * + * @author Manuel Rego Casasnovas + */ +public abstract class LoadChartFiller implements ILoadChartFiller { + + /** + * Number of days to Thursday since the beginning of the week. In order to + * calculate the middle of a week. + */ + private final static int DAYS_TO_THURSDAY = 3; + + private ZoomLevel zoomLevel = ZoomLevel.DETAIL_ONE; + + private Integer maximunValueForChart = 0; + + @Override + public abstract void fillChart(Timeplot chart, Interval interval, + Integer size); + + @Override + public String getServletUri( + final SortedMap mapDayAssignments, + final Date start, final Date finish) { + if (mapDayAssignments.isEmpty()) { + return ""; + } + + setMaximunValueForChartIfGreater(Collections.max(mapDayAssignments + .values())); + + String uri = CallbackServlet + .registerAndCreateURLFor(new IServletRequestHandler() { + + @Override + public void handle(HttpServletRequest request, + HttpServletResponse response) + throws ServletException, IOException { + PrintWriter writer = response.getWriter(); + + fillZeroValueFromStart(writer, start, mapDayAssignments); + + LocalDate firstDay = firstDay(mapDayAssignments); + LocalDate lastDay = lastDay(mapDayAssignments); + + for (LocalDate day = firstDay; day.compareTo(lastDay) <= 0; day = nextDay(day)) { + Integer hours = mapDayAssignments.get(day) != null ? mapDayAssignments + .get(day) + : 0; + printLine(writer, day, hours); + } + + fillZeroValueToFinish(writer, finish, mapDayAssignments); + + writer.close(); + } + }); + return uri; + } + + private void setMaximunValueForChartIfGreater(Integer max) { + if (maximunValueForChart < max) { + maximunValueForChart = max; + } + } + + private LocalDate firstDay(SortedMap mapDayAssignments) { + LocalDate date = mapDayAssignments.firstKey(); + if (zoomByDay()) { + return date; + } else { + return getThursdayOfThisWeek(date); + } + } + + private LocalDate lastDay(SortedMap mapDayAssignments) { + LocalDate date = mapDayAssignments.lastKey(); + if (zoomByDay()) { + return date; + } else { + return getThursdayOfThisWeek(date); + } + } + + @Override + public LocalDate getThursdayOfThisWeek(LocalDate date) { + return date.dayOfWeek().withMinimumValue().plusDays(DAYS_TO_THURSDAY); + } + + private LocalDate nextDay(LocalDate date) { + if (zoomByDay()) { + return date; + } else { + return date.plusWeeks(1); + } + } + + @Override + public boolean zoomByDay() { + return zoomLevel.equals(ZoomLevel.DETAIL_FIVE); + } + + private void fillZeroValueFromStart(PrintWriter writer, Date start, + SortedMap mapDayAssignments) { + LocalDate day = new LocalDate(start); + if (mapDayAssignments.isEmpty()) { + printLine(writer, day, 0); + } else if (day.compareTo(mapDayAssignments.firstKey()) < 0) { + printLine(writer, day, 0); + if (!day.equals(mapDayAssignments.firstKey().minusDays(1))) { + printLine(writer, mapDayAssignments.firstKey().minusDays(1), 0); + } + } + } + + private void fillZeroValueToFinish(PrintWriter writer, Date finish, + SortedMap mapDayAssignments) { + LocalDate day = new LocalDate(finish); + if (mapDayAssignments.isEmpty()) { + printLine(writer, day, 0); + } else if (day.compareTo(mapDayAssignments.lastKey()) > 0) { + if (!day.equals(mapDayAssignments.lastKey().plusDays(1))) { + printLine(writer, mapDayAssignments.lastKey().plusDays(1), 0); + } + printLine(writer, day, 0); + } + } + + private void printLine(PrintWriter writer, LocalDate day, Integer hours) { + writer.println(day.toString("yyyyMMdd") + " " + hours); + } + + @Override + public void setZoomLevel(ZoomLevel zoomLevel) { + this.zoomLevel = zoomLevel; + } + + @Override + public void resetMaximunValueForChart() { + this.maximunValueForChart = 0; + } + + @Override + public Integer getMaximunValueForChart() { + return maximunValueForChart; + } + +}