diff options
Diffstat (limited to 'src/net/sourceforge/plantuml/project3')
55 files changed, 2718 insertions, 241 deletions
diff --git a/src/net/sourceforge/plantuml/project3/CommandGanttArrow.java b/src/net/sourceforge/plantuml/project3/CommandGanttArrow.java new file mode 100644 index 0000000..5cd0757 --- /dev/null +++ b/src/net/sourceforge/plantuml/project3/CommandGanttArrow.java @@ -0,0 +1,83 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML 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 General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.project3; + +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand2; +import net.sourceforge.plantuml.command.regex.RegexConcat; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexResult; + +public class CommandGanttArrow extends SingleLineCommand2<GanttDiagram> { + + public CommandGanttArrow() { + super(getRegexConcat()); + } + + static RegexConcat getRegexConcat() { + return new RegexConcat(new RegexLeaf("^"), // + new RegexLeaf("CODE1", "([\\p{L}0-9_.]+)"), // + new RegexLeaf("[%s]*"), // + new RegexLeaf("ARROW", "(-+)\\>"), // + new RegexLeaf("[%s]*"), // + new RegexLeaf("CODE2", "([\\p{L}0-9_.]+)"), // + new RegexLeaf("[%s]*"), // + new RegexLeaf("$")); + } + + @Override + protected CommandExecutionResult executeArg(GanttDiagram diagram, RegexResult arg) { + + final String code1 = arg.get("CODE1", 0); + final String code2 = arg.get("CODE2", 0); + final Task task1 = diagram.getExistingTask(code1); + if (task1 == null) { + return CommandExecutionResult.error("No such task " + code1); + } + final Task task2 = diagram.getExistingTask(code2); + if (task2 == null) { + return CommandExecutionResult.error("No such task " + code2); + } + + final TaskInstant end1 = new TaskInstant(task1, TaskAttribute.END); + + task2.setStart(end1.getInstantPrecise()); + diagram.addContraint(new GanttConstraint(end1, new TaskInstant(task2, TaskAttribute.START))); + + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/project3/CommandGanttArrow2.java b/src/net/sourceforge/plantuml/project3/CommandGanttArrow2.java new file mode 100644 index 0000000..af29b66 --- /dev/null +++ b/src/net/sourceforge/plantuml/project3/CommandGanttArrow2.java @@ -0,0 +1,74 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML 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 General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.project3; + +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand2; +import net.sourceforge.plantuml.command.regex.RegexConcat; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexResult; + +public class CommandGanttArrow2 extends SingleLineCommand2<GanttDiagram> { + + public CommandGanttArrow2() { + super(getRegexConcat()); + } + + static RegexConcat getRegexConcat() { + return new RegexConcat(new RegexLeaf("^"), // + new RegexLeaf("TASK1", "\\[([^\\[\\]]+?)\\]"), // + new RegexLeaf("[%s]*"), // + new RegexLeaf("ARROW", "(-+)\\>"), // + new RegexLeaf("[%s]*"), // + new RegexLeaf("TASK2", "\\[([^\\[\\]]+?)\\]"), // + new RegexLeaf("[%s]*"), // + new RegexLeaf("$")); + } + + @Override + protected CommandExecutionResult executeArg(GanttDiagram diagram, RegexResult arg) { + + final String name1 = arg.get("TASK1", 0); + final String name2 = arg.get("TASK2", 0); + final Task task1 = diagram.getOrCreateTask(name1, null, false); + final Task task2 = diagram.getOrCreateTask(name2, null, false); + + diagram.setTaskOrder(task1, task2); + + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/project3/CommandPage.java b/src/net/sourceforge/plantuml/project3/CommandPage.java new file mode 100644 index 0000000..eaf7e1d --- /dev/null +++ b/src/net/sourceforge/plantuml/project3/CommandPage.java @@ -0,0 +1,63 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML 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 General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.project3; + +import java.util.List; + +import net.sourceforge.plantuml.classdiagram.AbstractEntityDiagram; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand; + +public class CommandPage extends SingleLineCommand<GanttDiagram> { + + public CommandPage() { + super("(?i)^page[%s]+(\\d+)[%s]*x[%s]*(\\d+)$"); + } + + @Override + protected CommandExecutionResult executeArg(GanttDiagram diagram, List<String> arg) { + + final int horizontal = Integer.parseInt(arg.get(0)); + final int vertical = Integer.parseInt(arg.get(1)); + if (horizontal <= 0 || vertical <= 0) { + return CommandExecutionResult.error("Argument must be positive"); + } + diagram.setHorizontalPages(horizontal); + diagram.setVerticalPages(vertical); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/project3/CommandSeparator.java b/src/net/sourceforge/plantuml/project3/CommandSeparator.java new file mode 100644 index 0000000..d4a5cd0 --- /dev/null +++ b/src/net/sourceforge/plantuml/project3/CommandSeparator.java @@ -0,0 +1,65 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML 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 General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.project3; + +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand2; +import net.sourceforge.plantuml.command.regex.RegexConcat; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexResult; + +public class CommandSeparator extends SingleLineCommand2<GanttDiagram> { + + public CommandSeparator() { + super(getRegexConcat()); + } + + static RegexConcat getRegexConcat() { + return new RegexConcat(new RegexLeaf("^"), // + new RegexLeaf("--"), // + new RegexLeaf("[%s]*"), // + new RegexLeaf("COMMENT", "((.+?)[%s]*--)?"), // + new RegexLeaf("$")); + } + + @Override + protected CommandExecutionResult executeArg(GanttDiagram diagram, RegexResult arg) { + final String comment = arg.get("COMMENT", 1); + diagram.addSeparator(comment); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/project3/ComplementClose.java b/src/net/sourceforge/plantuml/project3/ComplementClose.java index 113adff..1467246 100644 --- a/src/net/sourceforge/plantuml/project3/ComplementClose.java +++ b/src/net/sourceforge/plantuml/project3/ComplementClose.java @@ -42,7 +42,7 @@ import net.sourceforge.plantuml.command.regex.RegexResult; public class ComplementClose implements ComplementPattern { public IRegex toRegex(String suffix) { - return new RegexLeaf("ADAY" + suffix, "(closed?)"); + return new RegexLeaf("CLOSED" + suffix, "(closed?)"); } public Failable<Complement> getComplement(GanttDiagram system, RegexResult arg, String suffix) { diff --git a/src/net/sourceforge/plantuml/project3/ComplementColors.java b/src/net/sourceforge/plantuml/project3/ComplementColors.java index 6859c91..13e3ea3 100644 --- a/src/net/sourceforge/plantuml/project3/ComplementColors.java +++ b/src/net/sourceforge/plantuml/project3/ComplementColors.java @@ -66,4 +66,8 @@ public class ComplementColors implements Complement { public boolean isOk() { return center != null; } + + public HtmlColor getCenter() { + return center; + } } diff --git a/src/net/sourceforge/plantuml/project3/ComplementDates.java b/src/net/sourceforge/plantuml/project3/ComplementDates.java new file mode 100644 index 0000000..9785f8f --- /dev/null +++ b/src/net/sourceforge/plantuml/project3/ComplementDates.java @@ -0,0 +1,91 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML 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 General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.project3; + +import net.sourceforge.plantuml.command.regex.IRegex; +import net.sourceforge.plantuml.command.regex.RegexConcat; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexOr; +import net.sourceforge.plantuml.command.regex.RegexResult; + +public class ComplementDates implements ComplementPattern { + + public IRegex toRegex(String suffix) { + return new RegexConcat( // + new RegexLeaf("YEAR1" + suffix, "([\\d]{4})"), // + new RegexLeaf("\\D"), // + new RegexLeaf("MONTH1" + suffix, "([\\d]{1,2})"), // + new RegexLeaf("\\D"), // + new RegexLeaf("DAY1" + suffix, "([\\d]{1,2})"), // + new RegexLeaf("[%s]+to[%s]+"), // + new RegexLeaf("YEAR2" + suffix, "([\\d]{4})"), // + new RegexLeaf("\\D"), // + new RegexLeaf("MONTH2" + suffix, "([\\d]{1,2})"), // + new RegexLeaf("\\D"), // + new RegexLeaf("DAY2" + suffix, "([\\d]{1,2})") // + + ); + } + + public Subject getSubject(GanttDiagram project, RegexResult arg) { + final DayAsDate date1 = getDate(arg, "1"); + final DayAsDate date2 = getDate(arg, "2"); + return new DaysAsDates(date1, date2); + } + + private DayAsDate getDate(RegexResult arg, String suffix) { + final int day = Integer.parseInt(arg.get("DAY" + suffix, 0)); + final int month = Integer.parseInt(arg.get("MONTH" + suffix, 0)); + final int year = Integer.parseInt(arg.get("YEAR" + suffix, 0)); + return DayAsDate.create(year, month, day); + } + + public Failable<Complement> getComplement(GanttDiagram system, RegexResult arg, String suffix) { + + final int day1 = Integer.parseInt(arg.get("DAY1" + suffix, 0)); + final int month1 = Integer.parseInt(arg.get("MONTH1" + suffix, 0)); + final int year1 = Integer.parseInt(arg.get("YEAR1" + suffix, 0)); + final DayAsDate date1 = DayAsDate.create(year1, month1, day1); + + final int day2 = Integer.parseInt(arg.get("DAY2" + suffix, 0)); + final int month2 = Integer.parseInt(arg.get("MONTH2" + suffix, 0)); + final int year2 = Integer.parseInt(arg.get("YEAR2" + suffix, 0)); + final DayAsDate date2 = DayAsDate.create(year2, month2, day2); + + return Failable.<Complement> ok(new DaysAsDates(date1, date2)); + } + +} diff --git a/src/net/sourceforge/plantuml/project3/ComplementInColors2.java b/src/net/sourceforge/plantuml/project3/ComplementInColors2.java new file mode 100644 index 0000000..28cfe41 --- /dev/null +++ b/src/net/sourceforge/plantuml/project3/ComplementInColors2.java @@ -0,0 +1,56 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML 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 General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.project3; + +import net.sourceforge.plantuml.command.regex.IRegex; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexResult; +import net.sourceforge.plantuml.graphic.HtmlColor; + +public class ComplementInColors2 implements ComplementPattern { + + public IRegex toRegex(String suffix) { + return new RegexLeaf("COMPLEMENT" + suffix, "colou?red[%s]+(?:in[%s+])?(#?\\w+)(?:/(#?\\w+))?"); + } + + public Failable<Complement> getComplement(GanttDiagram system, RegexResult arg, String suffix) { + final String color1 = arg.get("COMPLEMENT" + suffix, 0); + final String color2 = arg.get("COMPLEMENT" + suffix, 1); + final HtmlColor col1 = system.getIHtmlColorSet().getColorIfValid(color1); + final HtmlColor col2 = system.getIHtmlColorSet().getColorIfValid(color2); + return Failable.<Complement> ok(new ComplementColors(col1, col2)); + } +} diff --git a/src/net/sourceforge/plantuml/project3/DurationDay.java b/src/net/sourceforge/plantuml/project3/ComplementName.java index efd53c4..a3d09f1 100644 --- a/src/net/sourceforge/plantuml/project3/DurationDay.java +++ b/src/net/sourceforge/plantuml/project3/ComplementName.java @@ -35,21 +35,16 @@ */ package net.sourceforge.plantuml.project3; -public class DurationDay implements Duration { +public class ComplementName implements Complement { - private final int days; + private final String name; - public DurationDay(int days) { - this.days = days; + public ComplementName(String name) { + this.name = name; } - public int getDays() { - return days; - } - - @Override - public String toString() { - return "{" + days + " days}"; + public final String getName() { + return name; } } diff --git a/src/net/sourceforge/plantuml/project3/ComplementNamed.java b/src/net/sourceforge/plantuml/project3/ComplementNamed.java new file mode 100644 index 0000000..70b5725 --- /dev/null +++ b/src/net/sourceforge/plantuml/project3/ComplementNamed.java @@ -0,0 +1,52 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML 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 General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.project3; + +import net.sourceforge.plantuml.command.regex.IRegex; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexResult; + +public class ComplementNamed implements ComplementPattern { + + public IRegex toRegex(String suffix) { + return new RegexLeaf("COMPLEMENT" + suffix, "\\[([^\\[\\]]+)\\]"); + } + + public Failable<Complement> getComplement(GanttDiagram system, RegexResult arg, String suffix) { + final String name = arg.get("COMPLEMENT" + suffix, 0); + return Failable.<Complement> ok(new ComplementName(name)); + } +} diff --git a/src/net/sourceforge/plantuml/project3/ComplementSeveralDays.java b/src/net/sourceforge/plantuml/project3/ComplementSeveralDays.java index 09226cd..fd6e20c 100644 --- a/src/net/sourceforge/plantuml/project3/ComplementSeveralDays.java +++ b/src/net/sourceforge/plantuml/project3/ComplementSeveralDays.java @@ -36,17 +36,24 @@ package net.sourceforge.plantuml.project3; import net.sourceforge.plantuml.command.regex.IRegex; +import net.sourceforge.plantuml.command.regex.RegexConcat; import net.sourceforge.plantuml.command.regex.RegexLeaf; import net.sourceforge.plantuml.command.regex.RegexResult; public class ComplementSeveralDays implements ComplementPattern { public IRegex toRegex(String suffix) { - return new RegexLeaf("COMPLEMENT" + suffix, "(\\d+)[%s]+days?"); + return new RegexConcat( // + new RegexLeaf("COMPLEMENT" + suffix, "(\\d+)[%s]+days?"), // + new RegexLeaf("LOAD" + suffix, "([%s]+at[%s]+(\\d+)%)?")); } public Failable<Complement> getComplement(GanttDiagram system, RegexResult arg, String suffix) { final String days = arg.get("COMPLEMENT" + suffix, 0); - return Failable.<Complement> ok(new DurationDay(Integer.parseInt(days))); + final String load = arg.get("LOAD" + suffix, 1); + if (load == null) { + return Failable.<Complement> ok(LoadInDays.inDay(Integer.parseInt(days))); + } + return Failable.<Complement> ok(LoadInDays.inDayWithLoad(Integer.parseInt(days), Integer.parseInt(load))); } } diff --git a/src/net/sourceforge/plantuml/project3/ConstantPlan.java b/src/net/sourceforge/plantuml/project3/ConstantPlan.java new file mode 100644 index 0000000..ee5cfe4 --- /dev/null +++ b/src/net/sourceforge/plantuml/project3/ConstantPlan.java @@ -0,0 +1,58 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML 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 General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.project3; + +public class ConstantPlan implements LoadPlanable { + + private final int loadPerInstant; + + private ConstantPlan(int loadPerInstant) { + this.loadPerInstant = loadPerInstant; + } + + public static LoadPlanable normal() { + return new ConstantPlan(100); + } + + public static LoadPlanable partial(int load) { + return new ConstantPlan(load); + } + + public int getLoadAt(Instant instant) { + return loadPerInstant; + + } +} diff --git a/src/net/sourceforge/plantuml/project3/DayAsDate.java b/src/net/sourceforge/plantuml/project3/DayAsDate.java index c8d5e6c..43068f8 100644 --- a/src/net/sourceforge/plantuml/project3/DayAsDate.java +++ b/src/net/sourceforge/plantuml/project3/DayAsDate.java @@ -35,7 +35,7 @@ */ package net.sourceforge.plantuml.project3; -public class DayAsDate implements Complement { +public class DayAsDate implements Complement, Comparable<DayAsDate>, Subject { private final int year; private final int dayOfMonth; @@ -55,11 +55,26 @@ public class DayAsDate implements Complement { this.month = month; } + private int internalNumber() { + return year * 100 * 100 + month.ordinal() * 100 + dayOfMonth; + } + @Override public String toString() { return "" + year + "/" + month + "/" + dayOfMonth; } + @Override + public int hashCode() { + return year * 113 + dayOfMonth * 17 + month.hashCode(); + } + + @Override + public boolean equals(Object obj) { + final DayAsDate other = (DayAsDate) obj; + return other.internalNumber() == this.internalNumber(); + } + public final int getDayOfMonth() { return dayOfMonth; } @@ -94,4 +109,21 @@ public class DayAsDate implements Complement { final int h = ((q + 13 * (m + 1) / 5) + k + k / 4 + j / 4 + 5 * j) % 7; return DayOfWeek.fromH(h); } + + public InstantDay asInstantDay(DayAsDate reference) { + // if (this.compareTo(reference) < 0) { + // throw new IllegalArgumentException(); + // } + int cmp = 0; + DayAsDate current = reference; + while (current.compareTo(this) < 0) { + current = current.next(); + cmp++; + } + return new InstantDay(cmp); + } + + public int compareTo(DayAsDate other) { + return this.internalNumber() - other.internalNumber(); + } } diff --git a/src/net/sourceforge/plantuml/project3/DaysAsDates.java b/src/net/sourceforge/plantuml/project3/DaysAsDates.java new file mode 100644 index 0000000..ecf51cb --- /dev/null +++ b/src/net/sourceforge/plantuml/project3/DaysAsDates.java @@ -0,0 +1,90 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML 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 General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.project3; + +import java.util.Iterator; + +public class DaysAsDates implements Subject, Complement, Iterable<DayAsDate> { + + private final DayAsDate date1; + private final DayAsDate date2; + + public DaysAsDates(DayAsDate date1, DayAsDate date2) { + this.date1 = date1; + this.date2 = date2; + } + + public DaysAsDates(GanttDiagram gantt, DayAsDate date1, int count) { + this.date1 = date1; + DayAsDate tmp = date1; + while (count > 0) { + if (gantt.isOpen(tmp)) { + count--; + } + tmp = tmp.next(); + } + this.date2 = tmp; + } + + class MyIterator implements Iterator<DayAsDate> { + + private DayAsDate current; + + public MyIterator(DayAsDate current) { + this.current = current; + } + + public boolean hasNext() { + return current.compareTo(date2) <= 0; + } + + public DayAsDate next() { + final DayAsDate result = current; + current = current.next(); + return result; + } + + public void remove() { + throw new UnsupportedOperationException(); + } + + } + + public Iterator<DayAsDate> iterator() { + return new MyIterator(date1); + } + +} diff --git a/src/net/sourceforge/plantuml/project3/GCalendar.java b/src/net/sourceforge/plantuml/project3/GCalendar.java index a7277b3..73c25e5 100644 --- a/src/net/sourceforge/plantuml/project3/GCalendar.java +++ b/src/net/sourceforge/plantuml/project3/GCalendar.java @@ -37,8 +37,10 @@ package net.sourceforge.plantuml.project3; public interface GCalendar { - // public DayAsDate next(DayAsDate day); - public DayAsDate toDayAsDate(InstantDay day); + public DayAsDate getStartingDate(); + + public InstantDay fromDayAsDate(DayAsDate day); + } diff --git a/src/net/sourceforge/plantuml/project3/GCalendarSimple.java b/src/net/sourceforge/plantuml/project3/GCalendarSimple.java index 5200b52..a257ddc 100644 --- a/src/net/sourceforge/plantuml/project3/GCalendarSimple.java +++ b/src/net/sourceforge/plantuml/project3/GCalendarSimple.java @@ -45,10 +45,28 @@ public class GCalendarSimple implements GCalendar { public DayAsDate toDayAsDate(InstantDay day) { DayAsDate result = start; - for (int i = 0; i < day.getNumDay(); i++) { + final int target = day.getNumDay(); + int work = 0; + while (work < target) { result = result.next(); + work++; } return result; } + public InstantDay fromDayAsDate(DayAsDate day) { + if (day.compareTo(start) < 0) { + throw new IllegalArgumentException(); + } + InstantDay result = new InstantDay(0); + while (toDayAsDate(result).equals(day) == false) { + result = result.increment(); + } + return result; + } + + public DayAsDate getStartingDate() { + return start; + } + } diff --git a/src/net/sourceforge/plantuml/project3/GanttArrow.java b/src/net/sourceforge/plantuml/project3/GanttArrow.java index 0758159..d48659c 100644 --- a/src/net/sourceforge/plantuml/project3/GanttArrow.java +++ b/src/net/sourceforge/plantuml/project3/GanttArrow.java @@ -125,7 +125,7 @@ public class GanttArrow implements UDrawable { private double getX(TaskInstant when, Direction direction) { final double x1 = timeScale.getStartingPosition(when.getInstantTheorical()); - final double x2 = timeScale.getStartingPosition(when.getInstantTheorical().increment()); + final double x2 = timeScale.getEndingPosition(when.getInstantTheorical()); if (direction == Direction.LEFT) { return x1; } diff --git a/src/net/sourceforge/plantuml/project3/GanttDiagram.java b/src/net/sourceforge/plantuml/project3/GanttDiagram.java index 6ca4226..3308389 100644 --- a/src/net/sourceforge/plantuml/project3/GanttDiagram.java +++ b/src/net/sourceforge/plantuml/project3/GanttDiagram.java @@ -35,25 +35,29 @@ */ package net.sourceforge.plantuml.project3; -import java.awt.Font; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.Comparator; +import java.util.EnumSet; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import net.sourceforge.plantuml.AbstractPSystem; import net.sourceforge.plantuml.FileFormatOption; +import net.sourceforge.plantuml.Scale; import net.sourceforge.plantuml.SpriteContainerEmpty; import net.sourceforge.plantuml.core.DiagramDescription; import net.sourceforge.plantuml.core.ImageData; import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.HorizontalAlignment; +import net.sourceforge.plantuml.graphic.HtmlColor; import net.sourceforge.plantuml.graphic.HtmlColorSetSimple; import net.sourceforge.plantuml.graphic.HtmlColorUtils; import net.sourceforge.plantuml.graphic.IHtmlColorSet; @@ -61,10 +65,12 @@ import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.UDrawable; import net.sourceforge.plantuml.ugraphic.ColorMapperIdentity; import net.sourceforge.plantuml.ugraphic.ImageBuilder; +import net.sourceforge.plantuml.ugraphic.UChangeBackColor; import net.sourceforge.plantuml.ugraphic.UChangeColor; import net.sourceforge.plantuml.ugraphic.UFont; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.URectangle; import net.sourceforge.plantuml.ugraphic.UTranslate; public class GanttDiagram extends AbstractPSystem implements Subject { @@ -73,29 +79,58 @@ public class GanttDiagram extends AbstractPSystem implements Subject { private final Map<String, Task> byShortName = new HashMap<String, Task>(); private final List<GanttConstraint> constraints = new ArrayList<GanttConstraint>(); private final IHtmlColorSet colorSet = new HtmlColorSetSimple(); + private final Collection<DayOfWeek> closedDayOfWeek = EnumSet.noneOf(DayOfWeek.class); + private final Collection<DayAsDate> closedDayAsDate = new HashSet<DayAsDate>(); private GCalendar calendar; - private Instant min; + private final Instant min = new InstantDay(0); private Instant max; public DiagramDescription getDescription() { return new DiagramDescription("(Project)"); } + private int horizontalPages = 1; + private int verticalPages = 1; + + final public int getHorizontalPages() { + return horizontalPages; + } + + final public void setHorizontalPages(int horizontalPages) { + this.horizontalPages = horizontalPages; + } + + final public int getVerticalPages() { + return verticalPages; + } + + final public void setVerticalPages(int verticalPages) { + this.verticalPages = verticalPages; + } + + @Override + public int getNbImages() { + return this.horizontalPages * this.verticalPages; + } + + public final int getDpi(FileFormatOption fileFormatOption) { + return 96; + } + @Override protected ImageData exportDiagramNow(OutputStream os, int index, FileFormatOption fileFormatOption, long seed) throws IOException { - final double dpiFactor = 1; final double margin = 10; - // public ImageBuilder(ColorMapper colorMapper, double dpiFactor, HtmlColor mybackcolor, String metadata, - // String warningOrError, double margin1, double margin2, Animation animation, boolean useHandwritten) { - sortTasks(); + final Scale scale = getScale(); - final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1, null, "", "", 0, 0, null, - false); - imageBuilder.setUDrawable(getUDrawable()); + final double dpiFactor = scale == null ? 1 : scale.getScale(100, 100); + final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), dpiFactor, null, "", "", 0, 0, + null, false); + final UDrawable result = getUDrawable(); + imageBuilder.setUDrawable(result); return imageBuilder.writeImageTOBEMOVED(fileFormatOption, seed, os); } @@ -127,10 +162,33 @@ public class GanttDiagram extends AbstractPSystem implements Subject { } private TimeScale getTimeScale() { - return new TimeScaleBasic(); + if (calendar == null) { + return new TimeScaleBasic(); + } + return new TimeScaleBasic2(getCalendarSimple()); // return new TimeScaleWithoutWeekEnd(calendar); } + private GCalendarSimple getCalendarSimple() { + return (GCalendarSimple) calendar; + } + + public final LoadPlanable getDefaultPlan() { + return new LoadPlanable() { + public int getLoadAt(Instant instant) { + if (calendar == null) { + return 100; + } + final DayAsDate day = getCalendarSimple().toDayAsDate((InstantDay) instant); + final DayOfWeek dayOfWeek = day.getDayOfWeek(); + if (closedDayOfWeek.contains(dayOfWeek) || closedDayAsDate.contains(day)) { + return 0; + } + return 100; + } + }; + } + private void drawConstraints(final UGraphic ug, TimeScale timeScale) { for (GanttConstraint constraint : constraints) { constraint.getUDrawable(timeScale).drawU(ug); @@ -140,54 +198,114 @@ public class GanttDiagram extends AbstractPSystem implements Subject { private void drawTimeHeader(final UGraphic ug, TimeScale timeScale) { - final double yTotal = initTaskDraws(timeScale); + final double yTotal = initTaskAndResourceDraws(timeScale); final double xmin = timeScale.getStartingPosition(min); - final double xmax = timeScale.getStartingPosition(max.increment()); - ug.apply(new UChangeColor(HtmlColorUtils.LIGHT_GRAY)).draw(new ULine(xmax - xmin, 0)); - ug.apply(new UChangeColor(HtmlColorUtils.LIGHT_GRAY)).apply(new UTranslate(0, getHeaderHeight() - 3)) - .draw(new ULine(xmax - xmin, 0)); + final double xmax = timeScale.getEndingPosition(max); if (calendar == null) { drawSimpleDayCounter(ug, timeScale, yTotal); } else { drawCalendar(ug, timeScale, yTotal); } + ug.apply(new UChangeColor(HtmlColorUtils.LIGHT_GRAY)).draw(new ULine(xmax - xmin, 0)); + ug.apply(new UChangeColor(HtmlColorUtils.LIGHT_GRAY)).apply(new UTranslate(0, getHeaderHeight() - 3)) + .draw(new ULine(xmax - xmin, 0)); + + } + + private final HtmlColor veryLightGray = new HtmlColorSetSimple().getColorIfValid("#E0E8E8"); + + private double getHeaderHeight() { + return getTimeHeaderHeight() + getHeaderNameDayHeight(); + } + + private double getTimeHeaderHeight() { + if (calendar != null) { + return Y_WEEKDAY + Y_NUMDAY; + } + return 16; + } + private double getHeaderNameDayHeight() { + if (calendar != null && nameDays.size() > 0) { + return 16; + } + return 0; } + private static final int Y_WEEKDAY = 16; + private static final int Y_NUMDAY = 28; + private void drawCalendar(final UGraphic ug, TimeScale timeScale, final double yTotal) { - final int magic = 12; - final ULine vbar = new ULine(0, yTotal - magic); + timeScale = new TimeScaleBasic(); + final ULine vbar = new ULine(0, yTotal - Y_WEEKDAY); Month lastMonth = null; - for (Instant i = min; i.compareTo(max.increment()) <= 0; i = i.increment()) { - final DayAsDate day = calendar.toDayAsDate((InstantDay) i); + final GCalendarSimple calendarAll = getCalendarSimple(); + final Instant max2 = calendarAll.fromDayAsDate(calendar.toDayAsDate((InstantDay) max)); + for (Instant i = min; i.compareTo(max2.increment()) <= 0; i = i.increment()) { + final DayAsDate day = calendarAll.toDayAsDate((InstantDay) i); + final DayOfWeek dayOfWeek = day.getDayOfWeek(); + final boolean isWorkingDay = getDefaultPlan().getLoadAt(i) > 0; final String d1 = "" + day.getDayOfMonth(); - final TextBlock num = Display.getWithNewlines(d1).create(getFontConfiguration(), HorizontalAlignment.LEFT, - new SpriteContainerEmpty()); + final TextBlock num = getTextBlock(d1, 10, false); final double x1 = timeScale.getStartingPosition(i); - final double x2 = timeScale.getStartingPosition(i.increment()); - if (i.compareTo(max.increment()) < 0) { - final TextBlock weekDay = Display.getWithNewlines(day.getDayOfWeek().shortName()).create( - getFontConfiguration(), HorizontalAlignment.LEFT, new SpriteContainerEmpty()); - - drawCenter(ug.apply(new UTranslate(0, magic * 2)), num, x1, x2); - drawCenter(ug.apply(new UTranslate(0, magic)), weekDay, x1, x2); + final double x2 = timeScale.getEndingPosition(i); + if (i.compareTo(max2.increment()) < 0) { + final TextBlock weekDay = getTextBlock(dayOfWeek.shortName(), 10, false); + + final URectangle rect = new URectangle(x2 - x1 - 1, yTotal - Y_WEEKDAY); + if (isWorkingDay) { + final HtmlColor back = colorDays.get(day); + if (back != null) { + ug.apply(new UChangeColor(null)).apply(new UChangeBackColor(back)) + .apply(new UTranslate(x1 + 1, Y_WEEKDAY)).draw(rect); + } + drawCenter(ug.apply(new UTranslate(0, Y_NUMDAY)), num, x1, x2); + drawCenter(ug.apply(new UTranslate(0, Y_WEEKDAY)), weekDay, x1, x2); + } else { + ug.apply(new UChangeColor(null)).apply(new UChangeBackColor(veryLightGray)) + .apply(new UTranslate(x1 + 1, Y_WEEKDAY)).draw(rect); + } if (lastMonth != day.getMonth()) { - final TextBlock month = Display.getWithNewlines(day.getMonth().name()).create( - getFontConfiguration(), HorizontalAlignment.LEFT, new SpriteContainerEmpty()); - month.drawU(ug.apply(new UTranslate(x1, 0))); + final int delta = 5; + if (lastMonth != null) { + final TextBlock lastMonthBlock = getTextBlock(lastMonth.name(), 12, true); + lastMonthBlock.drawU(ug.apply(new UTranslate(x1 + - lastMonthBlock.calculateDimension(ug.getStringBounder()).getWidth() - delta, 0))); + } + final TextBlock month = getTextBlock(day.getMonth().name(), 12, true); + month.drawU(ug.apply(new UTranslate(x1 + delta, 0))); + ug.apply(new UChangeColor(HtmlColorUtils.LIGHT_GRAY)).apply(new UTranslate(x1, 0)) + .draw(new ULine(0, Y_WEEKDAY)); } lastMonth = day.getMonth(); } - ug.apply(new UChangeColor(HtmlColorUtils.LIGHT_GRAY)).apply(new UTranslate(x1, magic)).draw(vbar); + ug.apply(new UChangeColor(HtmlColorUtils.LIGHT_GRAY)).apply(new UTranslate(x1, Y_WEEKDAY)).draw(vbar); } - } - private double getHeaderHeight() { - if (calendar != null) { - return 40; + if (nameDays.size() > 0) { + String last = null; + for (Instant i = min; i.compareTo(max2.increment()) <= 0; i = i.increment()) { + final DayAsDate day = calendarAll.toDayAsDate((InstantDay) i); + final String name = nameDays.get(day); + if (name != null && name.equals(last) == false) { + final double x1 = timeScale.getStartingPosition(i); + final double x2 = timeScale.getEndingPosition(i); + final TextBlock label = getTextBlock(name, 12, false); + final double h = label.calculateDimension(ug.getStringBounder()).getHeight(); + double y1 = getTimeHeaderHeight(); + double y2 = getHeaderHeight(); + label.drawU(ug.apply(new UTranslate(x1, Y_NUMDAY + 11))); + } + last = name; + } + } - return 16; + } + + private TextBlock getTextBlock(final String text, int size, boolean bold) { + return Display.getWithNewlines(text).create(getFontConfiguration(size, bold), HorizontalAlignment.LEFT, + new SpriteContainerEmpty()); } private void drawCenter(final UGraphic ug, final TextBlock text, final double x1, final double x2) { @@ -202,10 +320,10 @@ public class GanttDiagram extends AbstractPSystem implements Subject { private void drawSimpleDayCounter(final UGraphic ug, TimeScale timeScale, final double yTotal) { final ULine vbar = new ULine(0, yTotal); for (Instant i = min; i.compareTo(max.increment()) <= 0; i = i.increment()) { - final TextBlock num = Display.getWithNewlines(i.toShortString()).create(getFontConfiguration(), + final TextBlock num = Display.getWithNewlines(i.toShortString()).create(getFontConfiguration(10, false), HorizontalAlignment.LEFT, new SpriteContainerEmpty()); final double x1 = timeScale.getStartingPosition(i); - final double x2 = timeScale.getStartingPosition(i.increment()); + final double x2 = timeScale.getEndingPosition(i); final double width = num.calculateDimension(ug.getStringBounder()).getWidth(); final double delta = (x2 - x1) - width; if (i.compareTo(max.increment()) < 0) { @@ -215,25 +333,40 @@ public class GanttDiagram extends AbstractPSystem implements Subject { } } - private double initTaskDraws(TimeScale timeScale) { + private double initTaskAndResourceDraws(TimeScale timeScale) { double y = getHeaderHeight(); for (Task task : tasks.values()) { - final TaskDraw draw = new TaskDraw(task, timeScale, y); + final TaskDraw draw; + if (task instanceof TaskSeparator) { + draw = new TaskDrawSeparator((TaskSeparator) task, timeScale, y, min, max); + } else { + draw = new TaskDrawRegular((TaskImpl) task, timeScale, y); + } task.setTaskDraw(draw); y += draw.getHeight(); + + } + for (Resource res : resources.values()) { + final ResourceDraw draw = new ResourceDraw(this, res, timeScale, y, min, max); + res.setTaskDraw(draw); + y += draw.getHeight(); + } return y; } private void initMinMax() { - min = tasks.values().iterator().next().getStart(); + // min = tasks.values().iterator().next().getStart(); max = tasks.values().iterator().next().getEnd(); for (Task task : tasks.values()) { + if (task instanceof TaskSeparator) { + continue; + } final Instant start = task.getStart(); final Instant end = task.getEnd(); - if (min.compareTo(start) > 0) { - min = start; - } + // if (min.compareTo(start) > 0) { + // min = start; + // } if (max.compareTo(end) < 0) { max = end; } @@ -244,14 +377,20 @@ public class GanttDiagram extends AbstractPSystem implements Subject { for (Task task : tasks.values()) { final TaskDraw draw = task.getTaskDraw(); draw.drawU(ug.apply(new UTranslate(0, draw.getY()))); - draw.getTitle().drawU( - ug.apply(new UTranslate(timeScale.getStartingPosition(task.getStart().increment()), draw.getY()))); + draw.drawTitle(ug.apply(new UTranslate(0, draw.getY()))); + } + for (Resource res : resources.values()) { + final ResourceDraw draw = res.getResourceDraw(); + draw.drawU(ug.apply(new UTranslate(0, draw.getY()))); } } - private FontConfiguration getFontConfiguration() { - final UFont font = UFont.serif(10); - return new FontConfiguration(font, HtmlColorUtils.LIGHT_GRAY, HtmlColorUtils.LIGHT_GRAY, false); + private FontConfiguration getFontConfiguration(int size, boolean bold) { + UFont font = UFont.serif(size); + if (bold) { + font = font.bold(); + } + return new FontConfiguration(font, HtmlColorUtils.BLACK, HtmlColorUtils.BLACK, false); } public Task getExistingTask(String id) { @@ -266,7 +405,13 @@ public class GanttDiagram extends AbstractPSystem implements Subject { return tasks.get(code); } - public Task getOrCreateTask(String codeOrShortName, String shortName) { + public void setTaskOrder(final Task task1, final Task task2) { + final TaskInstant end1 = new TaskInstant(task1, TaskAttribute.END); + task2.setStart(end1.getInstantPrecise()); + addContraint(new GanttConstraint(end1, new TaskInstant(task2, TaskAttribute.START))); + } + + public Task getOrCreateTask(String codeOrShortName, String shortName, boolean linkedToPrevious) { if (codeOrShortName == null) { throw new IllegalArgumentException(); } @@ -281,15 +426,37 @@ public class GanttDiagram extends AbstractPSystem implements Subject { final TaskCode code = new TaskCode(codeOrShortName); result = tasks.get(code); if (result == null) { - result = new TaskImpl(code); + Task previous = null; + if (linkedToPrevious) { + previous = getLastCreatedTask(); + } + result = new TaskImpl(code, getDefaultPlan()); tasks.put(code, result); if (byShortName != null) { byShortName.put(shortName, result); } + if (previous != null) { + setTaskOrder(previous, result); + } } return result; } + private Task getLastCreatedTask() { + final List<Task> all = new ArrayList<Task>(tasks.values()); + for (int i = all.size() - 1; i >= 0; i--) { + if (all.get(i) instanceof TaskImpl) { + return all.get(i); + } + } + return null; + } + + public void addSeparator(String comment) { + TaskSeparator separator = new TaskSeparator(comment, tasks.size()); + tasks.put(separator.getCode(), separator); + } + private TaskCodeSimpleOrder getCanonicalOrder(int hierarchyHeader) { final List<TaskCode> codes = new ArrayList<TaskCode>(); for (TaskCode code : tasks.keySet()) { @@ -320,4 +487,66 @@ public class GanttDiagram extends AbstractPSystem implements Subject { this.calendar = new GCalendarSimple(start); } + public DayAsDate getStartingDate() { + if (this.calendar == null) { + return null; + } + return this.calendar.getStartingDate(); + } + + public void closeDayOfWeek(DayOfWeek day) { + closedDayOfWeek.add(day); + } + + public void closeDayAsDate(DayAsDate day) { + closedDayAsDate.add(day); + } + + public Instant convert(DayAsDate day) { + return calendar.fromDayAsDate(day); + } + + public boolean isOpen(DayAsDate day) { + return getDefaultPlan().getLoadAt(convert(day)) > 0; + } + + private final Map<String, Resource> resources = new LinkedHashMap<String, Resource>(); + + public void affectResource(Task result, String resourceName) { + Resource resource = getResource(resourceName); + result.addResource(resource); + } + + public Resource getResource(String resourceName) { + Resource resource = resources.get(resourceName); + if (resource == null) { + resource = new Resource(resourceName, getDefaultPlan()); + } + resources.put(resourceName, resource); + return resource; + } + + public int getLoadForResource(Resource res, Instant i) { + int result = 0; + for (Task task : tasks.values()) { + if (task instanceof TaskSeparator) { + continue; + } + final TaskImpl task2 = (TaskImpl) task; + result += task2.loadForResource(res, i); + } + return result; + } + + private final Map<DayAsDate, HtmlColor> colorDays = new HashMap<DayAsDate, HtmlColor>(); + private final Map<DayAsDate, String> nameDays = new HashMap<DayAsDate, String>(); + + public void colorDay(DayAsDate day, HtmlColor color) { + colorDays.put(day, color); + } + + public void nameDay(DayAsDate day, String name) { + nameDays.put(day, name); + } + } diff --git a/src/net/sourceforge/plantuml/project3/GanttDiagramFactory.java b/src/net/sourceforge/plantuml/project3/GanttDiagramFactory.java index 68d8603..1b4a870 100644 --- a/src/net/sourceforge/plantuml/project3/GanttDiagramFactory.java +++ b/src/net/sourceforge/plantuml/project3/GanttDiagramFactory.java @@ -42,32 +42,44 @@ import java.util.Collections; import java.util.List; import net.sourceforge.plantuml.command.Command; -import net.sourceforge.plantuml.command.CommandComment; -import net.sourceforge.plantuml.command.CommandMultilinesComment; import net.sourceforge.plantuml.command.CommandNope; +import net.sourceforge.plantuml.command.CommandScale; import net.sourceforge.plantuml.command.UmlDiagramFactory; import net.sourceforge.plantuml.core.DiagramType; public class GanttDiagramFactory extends UmlDiagramFactory { private List<SubjectPattern> subjects() { - return Arrays.<SubjectPattern> asList(new SubjectTask(), new SubjectProject(), new SubjectDayOfWeek()); + return Arrays.<SubjectPattern> asList(new SubjectTask(), new SubjectProject(), new SubjectDayOfWeek(), + new SubjectDayAsDate(), new SubjectDaysAsDates(), new SubjectResource()); } - public GanttDiagramFactory() { - super(DiagramType.UML); + public GanttDiagramFactory(DiagramType type) { + super(type); } @Override protected List<Command> createCommands() { final List<Command> cmds = new ArrayList<Command>(); + // addCommonCommands(cmds); cmds.add(new CommandNope()); - cmds.add(new CommandComment()); - cmds.add(new CommandMultilinesComment()); - + // cmds.add(new CommandComment()); + // cmds.add(new CommandMultilinesComment()); for (Command cmd : getLanguageCommands()) { cmds.add(cmd); } + cmds.add(new CommandGanttArrow()); + cmds.add(new CommandGanttArrow2()); + cmds.add(new CommandSeparator()); + + cmds.add(new CommandScale()); + cmds.add(new CommandPage()); + // cmds.add(new CommandScaleWidthAndHeight()); + // cmds.add(new CommandScaleWidthOrHeight()); + // cmds.add(new CommandScaleMaxWidth()); + // cmds.add(new CommandScaleMaxHeight()); + // cmds.add(new CommandScaleMaxWidthAndHeight()); + return cmds; } diff --git a/src/net/sourceforge/plantuml/project3/Instant.java b/src/net/sourceforge/plantuml/project3/Instant.java index f9d0567..458a24d 100644 --- a/src/net/sourceforge/plantuml/project3/Instant.java +++ b/src/net/sourceforge/plantuml/project3/Instant.java @@ -37,10 +37,6 @@ package net.sourceforge.plantuml.project3; public interface Instant extends Value, Comparable<Instant> { - public Instant add(Duration duration); - - public Instant sub(Duration duration); - public Instant increment(); public Instant decrement(); diff --git a/src/net/sourceforge/plantuml/project3/InstantDay.java b/src/net/sourceforge/plantuml/project3/InstantDay.java index 95cf49d..8ea1e2c 100644 --- a/src/net/sourceforge/plantuml/project3/InstantDay.java +++ b/src/net/sourceforge/plantuml/project3/InstantDay.java @@ -48,16 +48,6 @@ public class InstantDay implements Instant { return "(day +" + numDay + ")"; } - public InstantDay add(Duration duration) { - final int nbdays = ((DurationDay) duration).getDays(); - return new InstantDay(numDay + nbdays); - } - - public InstantDay sub(Duration duration) { - final int nbdays = ((DurationDay) duration).getDays(); - return new InstantDay(numDay - nbdays); - } - public InstantDay increment() { return new InstantDay(numDay + 1); } diff --git a/src/net/sourceforge/plantuml/project3/Load.java b/src/net/sourceforge/plantuml/project3/Load.java new file mode 100644 index 0000000..bc95e10 --- /dev/null +++ b/src/net/sourceforge/plantuml/project3/Load.java @@ -0,0 +1,42 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML 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 General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.project3; + +public interface Load extends Value, Complement, LoadPlanable { + + int getFullLoad(); + +} diff --git a/src/net/sourceforge/plantuml/project3/LoadInDays.java b/src/net/sourceforge/plantuml/project3/LoadInDays.java new file mode 100644 index 0000000..5d13f75 --- /dev/null +++ b/src/net/sourceforge/plantuml/project3/LoadInDays.java @@ -0,0 +1,65 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML 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 General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.project3; + +public class LoadInDays implements Load { + + private final int days; + private final int loadPerDay; + + private LoadInDays(int days, int loadPerDay) { + this.days = days; + this.loadPerDay = loadPerDay; + } + + public static LoadInDays inDay(int days) { + return new LoadInDays(days, 100); + } + + public static Complement inDayWithLoad(int days, int loadPerDay) { + final int tmp = (int) Math.ceil(days * 100.0 / loadPerDay); + return new LoadInDays(tmp, loadPerDay); + } + + public int getFullLoad() { + return days * loadPerDay; + } + + public int getLoadAt(Instant instant) { + return loadPerDay; + } + +} diff --git a/src/net/sourceforge/plantuml/project3/Duration.java b/src/net/sourceforge/plantuml/project3/LoadPlanable.java index 2dfa10c..1d04c06 100644 --- a/src/net/sourceforge/plantuml/project3/Duration.java +++ b/src/net/sourceforge/plantuml/project3/LoadPlanable.java @@ -35,6 +35,7 @@ */ package net.sourceforge.plantuml.project3; -public interface Duration extends Value, Complement { +public interface LoadPlanable { + public int getLoadAt(Instant instant); } diff --git a/src/net/sourceforge/plantuml/project3/NaturalCommand.java b/src/net/sourceforge/plantuml/project3/NaturalCommand.java index 213e54a..2d2ace9 100644 --- a/src/net/sourceforge/plantuml/project3/NaturalCommand.java +++ b/src/net/sourceforge/plantuml/project3/NaturalCommand.java @@ -72,13 +72,15 @@ public class NaturalCommand extends SingleLineCommand2<GanttDiagram> { } public static Command create(SubjectPattern subject, VerbPattern verb, ComplementPattern complement) { - return new NaturalCommand(new RegexConcat(// + final RegexConcat pattern = new RegexConcat(// new RegexLeaf("^"), // subject.toRegex(), // new RegexLeaf("[%s]+"), // verb.toRegex(), // new RegexLeaf("[%s]+"), // complement.toRegex("0"), // - new RegexLeaf("$")), subject, verb, complement); + new RegexLeaf("$")); + // System.err.println("NaturalCommand="+pattern.getPattern()); + return new NaturalCommand(pattern, subject, verb, complement); } } diff --git a/src/net/sourceforge/plantuml/project3/PlanUtils.java b/src/net/sourceforge/plantuml/project3/PlanUtils.java new file mode 100644 index 0000000..e89aae7 --- /dev/null +++ b/src/net/sourceforge/plantuml/project3/PlanUtils.java @@ -0,0 +1,52 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML 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 General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.project3; + +public class PlanUtils { + + private PlanUtils() { + + } + + public static LoadPlanable minOf(final LoadPlanable p1, final LoadPlanable p2) { + return new LoadPlanable() { + public int getLoadAt(Instant instant) { + return Math.min(p1.getLoadAt(instant), p2.getLoadAt(instant)); + } + }; + } + +} diff --git a/src/net/sourceforge/plantuml/project3/Resource.java b/src/net/sourceforge/plantuml/project3/Resource.java new file mode 100644 index 0000000..6bfdbca --- /dev/null +++ b/src/net/sourceforge/plantuml/project3/Resource.java @@ -0,0 +1,91 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML 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 General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.project3; + +import java.util.Set; +import java.util.TreeSet; + +public class Resource implements Subject, LoadPlanable { + + private final String name; + private ResourceDraw draw; + private final LoadPlanable loadPlanable; + private Set<Instant> closed = new TreeSet<Instant>(); + + public Resource(String name, LoadPlanable loadPlanable) { + this.name = name; + this.loadPlanable = loadPlanable; + } + + @Override + public int hashCode() { + return name.hashCode(); + } + + @Override + public boolean equals(Object obj) { + final Resource other = (Resource) obj; + return this.name.equals(other.name); + } + + @Override + public String toString() { + return name; + } + + public String getName() { + return name; + } + + public ResourceDraw getResourceDraw() { + return draw; + } + + public void setTaskDraw(ResourceDraw draw) { + this.draw = draw; + } + + public int getLoadAt(Instant instant) { + if (this.closed.contains(instant)) { + return 0; + } + return loadPlanable.getLoadAt(instant); + } + + public void addCloseDay(Instant instant) { + this.closed.add(instant); + } +} diff --git a/src/net/sourceforge/plantuml/project3/ResourceDraw.java b/src/net/sourceforge/plantuml/project3/ResourceDraw.java new file mode 100644 index 0000000..8b5f258 --- /dev/null +++ b/src/net/sourceforge/plantuml/project3/ResourceDraw.java @@ -0,0 +1,118 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML 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 General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.project3; + +import net.sourceforge.plantuml.SpriteContainerEmpty; +import net.sourceforge.plantuml.cucadiagram.Display; +import net.sourceforge.plantuml.graphic.FontConfiguration; +import net.sourceforge.plantuml.graphic.HorizontalAlignment; +import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.graphic.HtmlColorUtils; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.graphic.UDrawable; +import net.sourceforge.plantuml.ugraphic.UChangeColor; +import net.sourceforge.plantuml.ugraphic.UFont; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.UTranslate; + +public class ResourceDraw implements UDrawable { + + private final Resource res; + private final TimeScale timeScale; + private final double y; + private final Instant min; + private final Instant max; + private final GanttDiagram gantt; + + public ResourceDraw(GanttDiagram gantt, Resource res, TimeScale timeScale, double y, Instant min, Instant max) { + this.res = res; + this.timeScale = timeScale; + this.y = y; + this.min = min; + this.max = max; + this.gantt = gantt; + } + + public void drawU(UGraphic ug) { + final TextBlock title = Display.getWithNewlines(res.getName()).create(getFontConfiguration(13), + HorizontalAlignment.LEFT, new SpriteContainerEmpty()); + title.drawU(ug); + final ULine line = new ULine(timeScale.getEndingPosition(max) - timeScale.getStartingPosition(min), 0); + ug.apply(new UChangeColor(HtmlColorUtils.BLACK)) + .apply(new UTranslate(0, title.calculateDimension(ug.getStringBounder()).getHeight())).draw(line); + for (Instant i = min; i.compareTo(max) <= 0; i = i.increment()) { + final int load = gantt.getLoadForResource(res, i); + if (load > 0) { + final FontConfiguration fontConfiguration = getFontConfiguration(9, load > 100 ? HtmlColorUtils.RED + : HtmlColorUtils.BLACK); + final TextBlock value = Display.getWithNewlines("" + load).create(fontConfiguration, + HorizontalAlignment.LEFT, new SpriteContainerEmpty()); + final double start = (timeScale.getStartingPosition(i) + timeScale.getEndingPosition(i)) / 2 + - value.calculateDimension(ug.getStringBounder()).getWidth() / 2; + value.drawU(ug.apply(new UTranslate(start, 16))); + } + + } + + } + + private FontConfiguration getFontConfiguration(int size) { + return getFontConfiguration(size, HtmlColorUtils.BLACK); + } + + private FontConfiguration getFontConfiguration(int size, HtmlColor color) { + final UFont font = UFont.serif(size); + return new FontConfiguration(font, color, color, false); + } + + // public void setColors(ComplementColors colors); + // + // public double getY(); + // + // public double getY(Direction direction); + // + // public void drawTitle(UGraphic ug); + + public double getHeight() { + return 16 * 2; + } + + public double getY() { + return y; + } + +} diff --git a/src/net/sourceforge/plantuml/project3/Resources.java b/src/net/sourceforge/plantuml/project3/Resources.java new file mode 100644 index 0000000..7880a9f --- /dev/null +++ b/src/net/sourceforge/plantuml/project3/Resources.java @@ -0,0 +1,53 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML 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 General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.project3; + +import java.util.LinkedHashSet; +import java.util.Set; + +public class Resources implements LoadPlanable { + + private final Set<Resource> all = new LinkedHashSet<Resource>(); + + public int getLoadAt(Instant instant) { + int result = 0; + for (Resource res : all) { + result += res.getLoadAt(instant); + } + return result; + } + +} diff --git a/src/net/sourceforge/plantuml/project3/Solver.java b/src/net/sourceforge/plantuml/project3/Solver3.java index d18f6e2..70da380 100644 --- a/src/net/sourceforge/plantuml/project3/Solver.java +++ b/src/net/sourceforge/plantuml/project3/Solver3.java @@ -40,12 +40,24 @@ import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; -public class Solver { +public class Solver3 { private final Map<TaskAttribute, Value> values = new LinkedHashMap<TaskAttribute, Value>(); + private final LoadPlanable loadPlanable; + + public Solver3(LoadPlanable loadPlanable) { + this.loadPlanable = loadPlanable; + } + public void setData(TaskAttribute attribute, Value value) { - values.remove(attribute); + final Value previous = values.remove(attribute); + if (previous != null && attribute == TaskAttribute.START) { + final Instant previousInstant = (Instant) previous; + if (previousInstant.compareTo((Instant) value) > 0) { + value = previous; + } + } values.put(attribute, value); if (values.size() > 2) { removeFirstElement(); @@ -69,23 +81,30 @@ public class Solver { if (attribute == TaskAttribute.START) { return computeStart(); } - throw new UnsupportedOperationException(attribute.toString()); + return LoadInDays.inDay(1); + // throw new UnsupportedOperationException(attribute.toString()); } return result; } - private Instant computeStart() { - final Instant end = (Instant) values.get(TaskAttribute.END); - final Duration duration = (Duration) values.get(TaskAttribute.DURATION); - assert end != null && duration != null; - return end.sub(duration).increment(); + private Instant computeEnd() { + Instant current = (Instant) values.get(TaskAttribute.START); + int fullLoad = ((Load) values.get(TaskAttribute.LOAD)).getFullLoad(); + while (fullLoad > 0) { + fullLoad -= loadPlanable.getLoadAt(current); + current = current.increment(); + } + return current.decrement(); } - private Instant computeEnd() { - final Instant start = (Instant) values.get(TaskAttribute.START); - final Duration duration = (Duration) values.get(TaskAttribute.DURATION); - assert start != null && duration != null; - return start.add(duration).decrement(); + private Instant computeStart() { + Instant current = (Instant) values.get(TaskAttribute.END); + int fullLoad = ((Load) values.get(TaskAttribute.LOAD)).getFullLoad(); + while (fullLoad > 0) { + fullLoad -= loadPlanable.getLoadAt(current); + current = current.decrement(); + } + return current.increment(); } } diff --git a/src/net/sourceforge/plantuml/project3/SubjectDayAsDate.java b/src/net/sourceforge/plantuml/project3/SubjectDayAsDate.java new file mode 100644 index 0000000..01fc742 --- /dev/null +++ b/src/net/sourceforge/plantuml/project3/SubjectDayAsDate.java @@ -0,0 +1,68 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML 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 General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.project3; + +import java.util.Arrays; +import java.util.Collection; + +import net.sourceforge.plantuml.command.regex.IRegex; +import net.sourceforge.plantuml.command.regex.RegexConcat; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexResult; + +public class SubjectDayAsDate implements SubjectPattern { + + public Collection<VerbPattern> getVerbs() { + return Arrays.<VerbPattern> asList(new VerbIsOrAre()); + } + + public IRegex toRegex() { + return new RegexConcat( // + new RegexLeaf("YEAR", "([\\d]{4})"), // + new RegexLeaf("\\D"), // + new RegexLeaf("MONTH", "([\\d]{1,2})"), // + new RegexLeaf("\\D"), // + new RegexLeaf("DAY", "([\\d]{1,2})")); + } + + public Subject getSubject(GanttDiagram project, RegexResult arg) { + final int day = Integer.parseInt(arg.get("DAY", 0)); + final int month = Integer.parseInt(arg.get("MONTH", 0)); + final int year = Integer.parseInt(arg.get("YEAR", 0)); + return DayAsDate.create(year, month, day); + } + +} diff --git a/src/net/sourceforge/plantuml/project3/SubjectDaysAsDates.java b/src/net/sourceforge/plantuml/project3/SubjectDaysAsDates.java new file mode 100644 index 0000000..5a9d63f --- /dev/null +++ b/src/net/sourceforge/plantuml/project3/SubjectDaysAsDates.java @@ -0,0 +1,107 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML 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 General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.project3; + +import java.util.Arrays; +import java.util.Collection; + +import net.sourceforge.plantuml.command.regex.IRegex; +import net.sourceforge.plantuml.command.regex.RegexConcat; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexOr; +import net.sourceforge.plantuml.command.regex.RegexResult; + +public class SubjectDaysAsDates implements SubjectPattern { + + public Collection<VerbPattern> getVerbs() { + return Arrays.<VerbPattern> asList(new VerbIsOrAre(), new VerbIsOrAreNamed()); + } + + public IRegex toRegex() { + return new RegexOr(regexTo(), regexAnd()); + + } + + private IRegex regexTo() { + return new RegexConcat( // + new RegexLeaf("YEAR1", "([\\d]{4})"), // + new RegexLeaf("\\D"), // + new RegexLeaf("MONTH1", "([\\d]{1,2})"), // + new RegexLeaf("\\D"), // + new RegexLeaf("DAY1", "([\\d]{1,2})"), // + new RegexLeaf("[%s]+to[%s]+"), // + new RegexLeaf("YEAR2", "([\\d]{4})"), // + new RegexLeaf("\\D"), // + new RegexLeaf("MONTH2", "([\\d]{1,2})"), // + new RegexLeaf("\\D"), // + new RegexLeaf("DAY2", "([\\d]{1,2})") // + ); + } + + private IRegex regexAnd() { + return new RegexConcat( // + new RegexLeaf("YEAR3", "([\\d]{4})"), // + new RegexLeaf("\\D"), // + new RegexLeaf("MONTH3", "([\\d]{1,2})"), // + new RegexLeaf("\\D"), // + new RegexLeaf("DAY3", "([\\d]{1,2})"), // + new RegexLeaf("[%s]+and[%s]+"), // + new RegexLeaf("COUNT", "([\\d]+)"), // + new RegexLeaf("[%s]+days?") // + + ); + } + + public Subject getSubject(GanttDiagram project, RegexResult arg) { + final String count = arg.get("COUNT", 0); + if (count == null) { + final DayAsDate date1 = getDate(arg, "1"); + final DayAsDate date2 = getDate(arg, "2"); + return new DaysAsDates(date1, date2); + } + final DayAsDate date3 = getDate(arg, "3"); + final int nb = Integer.parseInt(count); + return new DaysAsDates(project, date3, nb); + } + + private DayAsDate getDate(RegexResult arg, String suffix) { + final int day = Integer.parseInt(arg.get("DAY" + suffix, 0)); + final int month = Integer.parseInt(arg.get("MONTH" + suffix, 0)); + final int year = Integer.parseInt(arg.get("YEAR" + suffix, 0)); + return DayAsDate.create(year, month, day); + } + +} diff --git a/src/net/sourceforge/plantuml/project3/SubjectResource.java b/src/net/sourceforge/plantuml/project3/SubjectResource.java new file mode 100644 index 0000000..cd6d701 --- /dev/null +++ b/src/net/sourceforge/plantuml/project3/SubjectResource.java @@ -0,0 +1,63 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML 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 General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.project3; + +import java.util.Arrays; +import java.util.Collection; +import java.util.StringTokenizer; + +import net.sourceforge.plantuml.command.regex.IRegex; +import net.sourceforge.plantuml.command.regex.RegexConcat; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexResult; + +public class SubjectResource implements SubjectPattern { + + public Collection<VerbPattern> getVerbs() { + return Arrays.<VerbPattern> asList(new VerbIsOff()); + } + + public IRegex toRegex() { + return new RegexConcat( // + new RegexLeaf("RESOURCE", "\\{([^{}]+)\\}") // + ); + } + + public Subject getSubject(GanttDiagram project, RegexResult arg) { + final String s = arg.get("RESOURCE", 0); + return project.getResource(s); + } +} diff --git a/src/net/sourceforge/plantuml/project3/SubjectTask.java b/src/net/sourceforge/plantuml/project3/SubjectTask.java index 17ac263..21632df 100644 --- a/src/net/sourceforge/plantuml/project3/SubjectTask.java +++ b/src/net/sourceforge/plantuml/project3/SubjectTask.java @@ -37,30 +37,46 @@ package net.sourceforge.plantuml.project3; import java.util.Arrays; import java.util.Collection; +import java.util.StringTokenizer; import net.sourceforge.plantuml.command.regex.IRegex; +import net.sourceforge.plantuml.command.regex.RegexConcat; import net.sourceforge.plantuml.command.regex.RegexLeaf; import net.sourceforge.plantuml.command.regex.RegexResult; public class SubjectTask implements SubjectPattern { public Collection<VerbPattern> getVerbs() { - return Arrays.<VerbPattern> asList(new VerbLasts(), new VerbStarts(), new VerbHappens(), new VerbEnds(), - new VerbIsColored()); + return Arrays.<VerbPattern> asList(new VerbLasts(), new VerbTaskStarts(), new VerbTaskStartsAbsolute(), + new VerbHappens(), new VerbEnds(), new VerbTaskEndsAbsolute(), new VerbIsColored()); } public IRegex toRegex() { - return new RegexLeaf("SUBJECT", "\\[([^\\[\\]]+?)\\](?:[%s]+as[%s]+\\[([^\\[\\]]+?)\\])?"); + return new RegexConcat( // + new RegexLeaf("THEN", "(then[%s]+)?"), // + new RegexLeaf("SUBJECT", "\\[([^\\[\\]]+?)\\](?:[%s]+as[%s]+\\[([^\\[\\]]+?)\\])?"), // + new RegexLeaf("RESOURCE", "(?:[%s]+on[%s]+((?:\\{[^{}]+\\}[%s]*)+))?") // + ); } public Subject getSubject(GanttDiagram project, RegexResult arg) { final String s = arg.get("SUBJECT", 0); final String shortName = arg.get("SUBJECT", 1); - final Task result = project.getOrCreateTask(s, shortName); + final String then = arg.get("THEN", 0); + final String resource = arg.get("RESOURCE", 0); + final Task result = project.getOrCreateTask(s, shortName, then != null); if (result == null) { throw new IllegalStateException(); } + if (resource != null) { + for (final StringTokenizer st = new StringTokenizer(resource, "{}"); st.hasMoreTokens();) { + final String part = st.nextToken().trim(); + if (part.length() > 0) { + project.affectResource(result, part); + } + } + + } return result; } - } diff --git a/src/net/sourceforge/plantuml/project3/Task.java b/src/net/sourceforge/plantuml/project3/Task.java index fb7ee8c..770eb09 100644 --- a/src/net/sourceforge/plantuml/project3/Task.java +++ b/src/net/sourceforge/plantuml/project3/Task.java @@ -43,18 +43,20 @@ public interface Task extends Subject { public Instant getEnd(); - public Duration getDuration(); + public Load getLoad(); + + public void setLoad(Load load); public void setStart(Instant start); public void setEnd(Instant end); - public void setDuration(Duration duration); - public void setTaskDraw(TaskDraw taskDraw); public TaskDraw getTaskDraw(); public void setColors(ComplementColors colors); + public void addResource(Resource resource); + } diff --git a/src/net/sourceforge/plantuml/project3/TaskAttribute.java b/src/net/sourceforge/plantuml/project3/TaskAttribute.java index 54d40eb..5a42a6f 100644 --- a/src/net/sourceforge/plantuml/project3/TaskAttribute.java +++ b/src/net/sourceforge/plantuml/project3/TaskAttribute.java @@ -36,7 +36,7 @@ package net.sourceforge.plantuml.project3; public enum TaskAttribute { - START, END, DURATION; + START, END, LOAD; public static TaskAttribute fromString(String value) { return valueOf(value.toUpperCase()); diff --git a/src/net/sourceforge/plantuml/project3/TaskCode.java b/src/net/sourceforge/plantuml/project3/TaskCode.java index 234c833..ad715c3 100644 --- a/src/net/sourceforge/plantuml/project3/TaskCode.java +++ b/src/net/sourceforge/plantuml/project3/TaskCode.java @@ -81,9 +81,8 @@ public class TaskCode { return hierarchy.toString(); } - public Display getSimpleDisplay() { - final String last = hierarchy.get(hierarchy.size() - 1); - return Display.getWithNewlines(last); + public String getSimpleDisplay() { + return hierarchy.get(hierarchy.size() - 1); } public int getHierarchySize() { diff --git a/src/net/sourceforge/plantuml/project3/TaskDraw.java b/src/net/sourceforge/plantuml/project3/TaskDraw.java index 4246352..722b2b7 100644 --- a/src/net/sourceforge/plantuml/project3/TaskDraw.java +++ b/src/net/sourceforge/plantuml/project3/TaskDraw.java @@ -36,111 +36,19 @@ package net.sourceforge.plantuml.project3; import net.sourceforge.plantuml.Direction; -import net.sourceforge.plantuml.SpriteContainerEmpty; -import net.sourceforge.plantuml.graphic.FontConfiguration; -import net.sourceforge.plantuml.graphic.HorizontalAlignment; -import net.sourceforge.plantuml.graphic.HtmlColorUtils; -import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.UDrawable; -import net.sourceforge.plantuml.ugraphic.UChangeBackColor; -import net.sourceforge.plantuml.ugraphic.UChangeColor; -import net.sourceforge.plantuml.ugraphic.UFont; import net.sourceforge.plantuml.ugraphic.UGraphic; -import net.sourceforge.plantuml.ugraphic.UPolygon; -import net.sourceforge.plantuml.ugraphic.URectangle; -import net.sourceforge.plantuml.ugraphic.UShape; -import net.sourceforge.plantuml.ugraphic.UTranslate; -public class TaskDraw implements UDrawable { +public interface TaskDraw extends UDrawable { - private final Task task; - private final TimeScale timeScale; - private final double y; - private ComplementColors colors; + public void setColors(ComplementColors colors); - private final double margin = 2; + public double getY(); - public TaskDraw(Task task, TimeScale timeScale, double y) { - this.y = y; - this.task = task; - this.timeScale = timeScale; - } + public double getY(Direction direction); - public TextBlock getTitle() { - return task.getCode().getSimpleDisplay() - .create(getFontConfiguration(), HorizontalAlignment.LEFT, new SpriteContainerEmpty()); - } + public void drawTitle(UGraphic ug); - private FontConfiguration getFontConfiguration() { - final UFont font = UFont.serif(11); - return new FontConfiguration(font, HtmlColorUtils.BLACK, HtmlColorUtils.BLACK, false); - } + public double getHeight(); - public void drawU(UGraphic ug) { - final double start = timeScale.getStartingPosition(task.getStart()); - final UShape rect = getShape(); - - ug = applyColors(ug); - ug.apply(new UTranslate(start + margin, margin)).draw(rect); - } - - private UGraphic applyColors(UGraphic ug) { - if (colors != null && colors.isOk()) { - return colors.apply(ug); - } - if (isDiamond()) { - return ug.apply(new UChangeColor(HtmlColorUtils.BLACK)).apply(new UChangeBackColor(HtmlColorUtils.BLACK)); - } - return ug.apply(new UChangeColor(HtmlColorUtils.BLUE)).apply(new UChangeBackColor(HtmlColorUtils.COL_84BE84)); - } - - private UShape getShape() { - if (isDiamond()) { - return getDiamond(); - } - final Instant instantStart = task.getStart(); - final Instant instantEnd = task.getEnd(); - final double start = timeScale.getStartingPosition(instantStart); - final double end = timeScale.getStartingPosition(instantEnd.increment()); - return new URectangle(end - start - 2 * margin, getHeight() - 2 * margin, 8, 8); - } - - private boolean isDiamond() { - final Instant instantStart = task.getStart(); - final Instant instantEnd = task.getEnd(); - return instantStart.compareTo(instantEnd) == 0; - } - - private UShape getDiamond() { - final double h = getHeight() - 2 * margin; - final UPolygon result = new UPolygon(); - result.addPoint(h / 2, 0); - result.addPoint(h, h / 2); - result.addPoint(h / 2, h); - result.addPoint(0, h / 2); - return result; - // return result.translate(2, 2); - } - - public double getHeight() { - return 16; - } - - public double getY() { - return y; - } - - public double getY(Direction direction) { - if (direction == Direction.UP) { - return y; - } - if (direction == Direction.DOWN) { - return y + getHeight(); - } - return y + getHeight() / 2; - } - - public void setColors(ComplementColors colors) { - this.colors = colors; - } } diff --git a/src/net/sourceforge/plantuml/project3/TaskDrawRegular.java b/src/net/sourceforge/plantuml/project3/TaskDrawRegular.java new file mode 100644 index 0000000..0a47344 --- /dev/null +++ b/src/net/sourceforge/plantuml/project3/TaskDrawRegular.java @@ -0,0 +1,174 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML 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 General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.project3; + +import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.SpriteContainerEmpty; +import net.sourceforge.plantuml.cucadiagram.Display; +import net.sourceforge.plantuml.graphic.FontConfiguration; +import net.sourceforge.plantuml.graphic.HorizontalAlignment; +import net.sourceforge.plantuml.graphic.HtmlColorUtils; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.ugraphic.UChangeBackColor; +import net.sourceforge.plantuml.ugraphic.UChangeColor; +import net.sourceforge.plantuml.ugraphic.UFont; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.UPolygon; +import net.sourceforge.plantuml.ugraphic.URectangle; +import net.sourceforge.plantuml.ugraphic.UShape; +import net.sourceforge.plantuml.ugraphic.UTranslate; + +public class TaskDrawRegular implements TaskDraw { + + private final TaskImpl task; + private final TimeScale timeScale; + private final double y; + private ComplementColors colors; + + private final double margin = 2; + + public TaskDrawRegular(TaskImpl task, TimeScale timeScale, double y) { + this.y = y; + this.task = task; + this.timeScale = timeScale; + } + + public void drawTitle(UGraphic ug) { + final TextBlock title = Display.getWithNewlines(task.getPrettyDisplay()).create(getFontConfiguration(), + HorizontalAlignment.LEFT, new SpriteContainerEmpty()); + title.drawU(ug.apply(new UTranslate(timeScale.getEndingPosition(task.getStart()), 0))); + } + + private FontConfiguration getFontConfiguration() { + final UFont font = UFont.serif(11); + return new FontConfiguration(font, HtmlColorUtils.BLACK, HtmlColorUtils.BLACK, false); + } + + public void drawU(UGraphic ug1) { + final double start = timeScale.getStartingPosition(task.getStart()); + ug1 = applyColors(ug1); + UGraphic ug2 = ug1.apply(new UTranslate(start + margin, margin)); + // final int load = 42; // task.getLoad(); + final UShape shapeFull = getShape(100); + if (shapeFull instanceof UPolygon) { + ug2.draw(shapeFull); + } else { + final double fullHeight = ((URectangle) shapeFull).getHeight(); + ug2.apply(new UChangeBackColor(HtmlColorUtils.WHITE)).apply(new UChangeColor(HtmlColorUtils.WHITE)) + .draw(shapeFull); + drawInside(ug1, fullHeight); + ug2.apply(new UChangeBackColor(null)).draw(shapeFull); + } + } + + private void drawInside(UGraphic ug, double fullHeight) { + for (Instant i = task.getStart(); i.compareTo(task.getEnd()) <= 0; i = i.increment()) { + final int load = task.getLoadAt(i); + final URectangle shapeLoad = getShapeInside(load, i); + final double diffHeight = fullHeight - shapeLoad.getHeight(); + final double start = timeScale.getStartingPosition(i); + ug.apply(new UChangeColor(null)).apply(new UTranslate(start, diffHeight + margin)).draw(shapeLoad); + } + } + + private UGraphic applyColors(UGraphic ug) { + if (colors != null && colors.isOk()) { + return colors.apply(ug); + } + if (isDiamond()) { + return ug.apply(new UChangeColor(HtmlColorUtils.BLACK)).apply(new UChangeBackColor(HtmlColorUtils.BLACK)); + } + return ug.apply(new UChangeColor(HtmlColorUtils.BLUE)).apply(new UChangeBackColor(HtmlColorUtils.COL_84BE84)); + } + + private URectangle getShapeInside(int load, Instant instant) { + final double start = timeScale.getStartingPosition(instant); + final double end = timeScale.getEndingPosition(instant); + final double height = (getHeight() - 2 * margin) * load / 100.0; + return new URectangle(end - start, height); + } + + private UShape getShape(int load) { + if (isDiamond()) { + return getDiamond(); + } + final Instant instantStart = task.getStart(); + final Instant instantEnd = task.getEnd(); + final double start = timeScale.getStartingPosition(instantStart); + final double end = timeScale.getEndingPosition(instantEnd); + final double height = (getHeight() - 2 * margin) * load / 100.0; + return new URectangle(end - start - 2 * margin, height, 8, 8); + } + + private boolean isDiamond() { + final Instant instantStart = task.getStart(); + final Instant instantEnd = task.getEnd(); + return instantStart.compareTo(instantEnd) == 0; + } + + private UShape getDiamond() { + final double h = getHeight() - 2 * margin; + final UPolygon result = new UPolygon(); + result.addPoint(h / 2, 0); + result.addPoint(h, h / 2); + result.addPoint(h / 2, h); + result.addPoint(0, h / 2); + return result; + // return result.translate(2, 2); + } + + public double getHeight() { + return 16; + } + + public double getY() { + return y; + } + + public double getY(Direction direction) { + if (direction == Direction.UP) { + return y; + } + if (direction == Direction.DOWN) { + return y + getHeight(); + } + return y + getHeight() / 2; + } + + public void setColors(ComplementColors colors) { + this.colors = colors; + } +} diff --git a/src/net/sourceforge/plantuml/project3/TaskDrawSeparator.java b/src/net/sourceforge/plantuml/project3/TaskDrawSeparator.java new file mode 100644 index 0000000..e0cb984 --- /dev/null +++ b/src/net/sourceforge/plantuml/project3/TaskDrawSeparator.java @@ -0,0 +1,128 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML 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 General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.project3; + +import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.SpriteContainerEmpty; +import net.sourceforge.plantuml.cucadiagram.Display; +import net.sourceforge.plantuml.graphic.FontConfiguration; +import net.sourceforge.plantuml.graphic.HorizontalAlignment; +import net.sourceforge.plantuml.graphic.HtmlColorUtils; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.graphic.TextBlockUtils; +import net.sourceforge.plantuml.ugraphic.UChangeColor; +import net.sourceforge.plantuml.ugraphic.UFont; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.UTranslate; + +public class TaskDrawSeparator implements TaskDraw { + + private final TimeScale timeScale; + private final double y; + private final Instant min; + private final Instant max; + private final String name; + + public TaskDrawSeparator(TaskSeparator task, TimeScale timeScale, double y, Instant min, Instant max) { + this.name = task.getName(); + this.y = y; + this.timeScale = timeScale; + this.min = min; + this.max = max; + } + + public void drawTitle(UGraphic ug) { + getTitle().drawU(ug.apply(new UTranslate(MARGIN1, 0))); + } + + private TextBlock getTitle() { + if (name == null) { + return TextBlockUtils.empty(0, 0); + } + return Display.getWithNewlines(this.name).create(getFontConfiguration(), HorizontalAlignment.LEFT, + new SpriteContainerEmpty()); + } + + private FontConfiguration getFontConfiguration() { + final UFont font = UFont.serif(11); + return new FontConfiguration(font, HtmlColorUtils.BLACK, HtmlColorUtils.BLACK, false); + } + + private final static double MARGIN1 = 10; + private final static double MARGIN2 = 2; + + public void drawU(UGraphic ug) { + final double widthTitle = getTitle().calculateDimension(ug.getStringBounder()).getWidth(); + final double start = timeScale.getStartingPosition(min) + widthTitle; + final double end = timeScale.getEndingPosition(max); + + ug = ug.apply(new UChangeColor(HtmlColorUtils.BLACK)); + ug = ug.apply(new UTranslate(0, getHeight() / 2)); + + if (widthTitle == 0) { + final ULine line = new ULine(end - start, 0); + ug.draw(line); + } else { + final ULine line1 = new ULine(MARGIN1 - MARGIN2, 0); + final ULine line2 = new ULine(end - start - MARGIN1 - MARGIN2, 0); + ug.draw(line1); + ug.apply(new UTranslate(widthTitle + MARGIN1 + MARGIN2, 0)).draw(line2); + } + } + + public double getHeight() { + return 16; + } + + public double getY() { + return y; + } + + public double getY(Direction direction) { + if (direction == Direction.UP) { + return y; + } + if (direction == Direction.DOWN) { + return y + getHeight(); + } + return y + getHeight() / 2; + } + + public void setColors(ComplementColors colors) { + } + +} diff --git a/src/net/sourceforge/plantuml/project3/TaskImpl.java b/src/net/sourceforge/plantuml/project3/TaskImpl.java index ef44446..68e77b9 100644 --- a/src/net/sourceforge/plantuml/project3/TaskImpl.java +++ b/src/net/sourceforge/plantuml/project3/TaskImpl.java @@ -35,15 +35,80 @@ */ package net.sourceforge.plantuml.project3; -public class TaskImpl implements Task { +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.Set; + +public class TaskImpl implements Task, LoadPlanable { private final TaskCode code; - private final Solver solver = new Solver(); + private final Solver3 solver; + private final Set<Resource> resources = new LinkedHashSet<Resource>(); + private final LoadPlanable defaultPlan; - public TaskImpl(TaskCode code) { + public TaskImpl(TaskCode code, LoadPlanable defaultPlan) { this.code = code; + this.defaultPlan = defaultPlan; + this.solver = new Solver3(this); setStart(new InstantDay(0)); - setDuration(new DurationDay(1)); + setLoad(LoadInDays.inDay(1)); + } + + public int getLoadAt(Instant instant) { + LoadPlanable plan1 = defaultPlan; + if (resources.size() > 0) { + plan1 = PlanUtils.minOf(plan1, getRessourcePlan()); + } + return PlanUtils.minOf(getLoad(), plan1).getLoadAt(instant); + } + + public int loadForResource(Resource res, Instant i) { + if (resources.contains(res) && i.compareTo(getStart()) >= 0 && i.compareTo(getEnd()) <= 0) { + if (res.getLoadAt(i) == 0) { + return 0; + } + int size = 0; + for (Resource r : resources) { + if (r.getLoadAt(i) > 0) { + size++; + } + } + return getLoadAt(i) / size; + } + return 0; + } + + private LoadPlanable getRessourcePlan() { + if (resources.size() == 0) { + throw new IllegalStateException(); + } + return new LoadPlanable() { + + public int getLoadAt(Instant instant) { + int result = 0; + for (Resource res : resources) { + result += res.getLoadAt(instant); + } + return result; + } + }; + } + + public String getPrettyDisplay() { + if (resources.size() > 0) { + final StringBuilder result = new StringBuilder(code.getSimpleDisplay()); + result.append(" "); + for (Iterator<Resource> it = resources.iterator(); it.hasNext();) { + result.append("{"); + result.append(it.next().getName()); + result.append("}"); + if (it.hasNext()) { + result.append(" "); + } + } + return result.toString(); + } + return code.getSimpleDisplay(); } @Override @@ -52,7 +117,7 @@ public class TaskImpl implements Task { } public String debug() { - return "" + getStart() + " ---> " + getEnd() + " [" + getDuration() + "]"; + return "" + getStart() + " ---> " + getEnd() + " [" + getLoad() + "]"; } public TaskCode getCode() { @@ -60,15 +125,23 @@ public class TaskImpl implements Task { } public Instant getStart() { - return (Instant) solver.getData(TaskAttribute.START); + Instant result = (Instant) solver.getData(TaskAttribute.START); + while (getLoadAt(result) == 0) { + result = result.increment(); + } + return result; } public Instant getEnd() { return (Instant) solver.getData(TaskAttribute.END); } - public Duration getDuration() { - return (Duration) solver.getData(TaskAttribute.DURATION); + public Load getLoad() { + return (Load) solver.getData(TaskAttribute.LOAD); + } + + public void setLoad(Load load) { + solver.setData(TaskAttribute.LOAD, load); } public void setStart(Instant start) { @@ -79,10 +152,6 @@ public class TaskImpl implements Task { solver.setData(TaskAttribute.END, end); } - public void setDuration(Duration duration) { - solver.setData(TaskAttribute.DURATION, duration); - } - private TaskDraw taskDraw; private ComplementColors colors; @@ -99,4 +168,8 @@ public class TaskImpl implements Task { this.colors = colors; } + public void addResource(Resource resource) { + this.resources.add(resource); + } + } diff --git a/src/net/sourceforge/plantuml/project3/TaskSeparator.java b/src/net/sourceforge/plantuml/project3/TaskSeparator.java new file mode 100644 index 0000000..71822f4 --- /dev/null +++ b/src/net/sourceforge/plantuml/project3/TaskSeparator.java @@ -0,0 +1,99 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML 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 General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.project3; + +public class TaskSeparator implements Task { + // public static final double SPACE = 15; + + private final TaskCode code; + private final String comment; + private TaskDraw taskDraw; + + public TaskSeparator(String comment, int id) { + this.code = new TaskCode("##" + id); + this.comment = comment; + } + + public TaskCode getCode() { + return code; + } + + public Instant getStart() { + throw new UnsupportedOperationException(); + } + + public Instant getEnd() { + throw new UnsupportedOperationException(); + } + + public void setStart(Instant start) { + throw new UnsupportedOperationException(); + } + + public void setEnd(Instant end) { + throw new UnsupportedOperationException(); + + } + + public void setTaskDraw(TaskDraw taskDraw) { + this.taskDraw = taskDraw; + } + + public TaskDraw getTaskDraw() { + return taskDraw; + } + + public void setColors(ComplementColors colors) { + throw new UnsupportedOperationException(); + } + + public String getName() { + return comment; + } + + public void addResource(Resource resource) { + throw new UnsupportedOperationException(); + } + + public Load getLoad() { + throw new UnsupportedOperationException(); + } + + public void setLoad(Load load) { + throw new UnsupportedOperationException(); + } + +} diff --git a/src/net/sourceforge/plantuml/project3/TimeScale.java b/src/net/sourceforge/plantuml/project3/TimeScale.java index 7edfde0..222853e 100644 --- a/src/net/sourceforge/plantuml/project3/TimeScale.java +++ b/src/net/sourceforge/plantuml/project3/TimeScale.java @@ -39,6 +39,8 @@ public interface TimeScale { public double getStartingPosition(Instant instant); + public double getEndingPosition(Instant instant); + public double getWidth(Instant instant); } diff --git a/src/net/sourceforge/plantuml/project3/TimeScaleBasic.java b/src/net/sourceforge/plantuml/project3/TimeScaleBasic.java index 023051d..3909aee 100644 --- a/src/net/sourceforge/plantuml/project3/TimeScaleBasic.java +++ b/src/net/sourceforge/plantuml/project3/TimeScaleBasic.java @@ -44,6 +44,10 @@ public class TimeScaleBasic implements TimeScale { return day * scale; } + public double getEndingPosition(Instant instant) { + return getStartingPosition(instant) + getWidth(instant); + } + public double getWidth(Instant instant) { return scale; } diff --git a/src/net/sourceforge/plantuml/project3/TimeScaleBasic2.java b/src/net/sourceforge/plantuml/project3/TimeScaleBasic2.java new file mode 100644 index 0000000..caf0f87 --- /dev/null +++ b/src/net/sourceforge/plantuml/project3/TimeScaleBasic2.java @@ -0,0 +1,79 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML 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 General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.project3; + +import java.util.Map; +import java.util.TreeMap; + +public class TimeScaleBasic2 implements TimeScale { + + private final GCalendar calendar; + private final GCalendar calendarAllOpen; + private final TimeScaleBasic basic = new TimeScaleBasic(); + private final Map<Instant, Instant> cache = new TreeMap<Instant, Instant>(); + + public TimeScaleBasic2(GCalendarSimple calendar) { + this.calendar = calendar; + this.calendarAllOpen = calendar; + } + + private Instant changeInstantSlow(Instant instant) { + final DayAsDate day = calendar.toDayAsDate((InstantDay) instant); + return calendarAllOpen.fromDayAsDate(day); + } + + private Instant changeInstant(Instant instant) { + Instant result = cache.get(instant); + if (result == null) { + result = changeInstantSlow(instant); + cache.put(instant, result); + } + return result; + } + + public double getStartingPosition(Instant instant) { + return basic.getStartingPosition(changeInstant(instant)); + } + + public double getEndingPosition(Instant instant) { + return basic.getEndingPosition(changeInstant(instant)); + } + + public double getWidth(Instant instant) { + return basic.getWidth(changeInstant(instant)); + } + +} diff --git a/src/net/sourceforge/plantuml/project3/TimeScaleWithoutWeekEnd.java b/src/net/sourceforge/plantuml/project3/TimeScaleWithoutWeekEnd.java index a8e525e..5312cc7 100644 --- a/src/net/sourceforge/plantuml/project3/TimeScaleWithoutWeekEnd.java +++ b/src/net/sourceforge/plantuml/project3/TimeScaleWithoutWeekEnd.java @@ -66,4 +66,8 @@ public class TimeScaleWithoutWeekEnd implements TimeScale { return scale; } + public double getEndingPosition(Instant instant) { + throw new UnsupportedOperationException(); + } + } diff --git a/src/net/sourceforge/plantuml/project3/VerbAre.java b/src/net/sourceforge/plantuml/project3/VerbAre.java index 2c4cdb2..d3e1560 100644 --- a/src/net/sourceforge/plantuml/project3/VerbAre.java +++ b/src/net/sourceforge/plantuml/project3/VerbAre.java @@ -57,9 +57,9 @@ public class VerbAre implements VerbPattern { return new Verb() { public CommandExecutionResult execute(Subject subject, Complement complement) { final DayOfWeek day = (DayOfWeek) subject; + project.closeDayOfWeek(day); return CommandExecutionResult.ok(); } - }; } } diff --git a/src/net/sourceforge/plantuml/project3/VerbHappens.java b/src/net/sourceforge/plantuml/project3/VerbHappens.java index 20bea96..58a3deb 100644 --- a/src/net/sourceforge/plantuml/project3/VerbHappens.java +++ b/src/net/sourceforge/plantuml/project3/VerbHappens.java @@ -46,20 +46,29 @@ import net.sourceforge.plantuml.command.regex.RegexResult; public class VerbHappens implements VerbPattern { public Collection<ComplementPattern> getComplements() { - return Arrays.<ComplementPattern> asList(new ComplementBeforeOrAfterOrAtTaskStartOrEnd()); + return Arrays.<ComplementPattern> asList(new ComplementBeforeOrAfterOrAtTaskStartOrEnd(), new ComplementDate()); } public IRegex toRegex() { - return new RegexLeaf("happens"); + return new RegexLeaf("happens[%s]*(at[%s]*|the[%s]*|on[%s]*)*"); } - public Verb getVerb(GanttDiagram project, RegexResult arg) { + public Verb getVerb(final GanttDiagram project, RegexResult arg) { return new Verb() { public CommandExecutionResult execute(Subject subject, Complement complement) { final Task task = (Task) subject; - final TaskInstant when = (TaskInstant) complement; - task.setDuration(new DurationDay(1)); - task.setStart(when.getInstantTheorical()); + task.setLoad(LoadInDays.inDay(1)); + if (complement instanceof DayAsDate) { + final DayAsDate start = (DayAsDate) complement; + final DayAsDate startingDate = project.getStartingDate(); + if (startingDate == null) { + return CommandExecutionResult.error("No starting date for the project"); + } + task.setStart(start.asInstantDay(startingDate)); + } else { + final TaskInstant when = (TaskInstant) complement; + task.setStart(when.getInstantTheorical()); + } return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/project3/VerbIsOff.java b/src/net/sourceforge/plantuml/project3/VerbIsOff.java new file mode 100644 index 0000000..bc2308d --- /dev/null +++ b/src/net/sourceforge/plantuml/project3/VerbIsOff.java @@ -0,0 +1,74 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML 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 General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.project3; + +import java.util.Arrays; +import java.util.Collection; + +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.regex.IRegex; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexResult; + +public class VerbIsOff implements VerbPattern { + + public Collection<ComplementPattern> getComplements() { + return Arrays.<ComplementPattern> asList(new ComplementDate(), new ComplementDates()); + } + + public IRegex toRegex() { + return new RegexLeaf("is off on"); + } + + public Verb getVerb(final GanttDiagram project, RegexResult arg) { + return new Verb() { + public CommandExecutionResult execute(Subject subject, Complement complement) { + final Resource resource = (Resource) subject; + if (complement instanceof DaysAsDates) { + for (DayAsDate when : (DaysAsDates) complement) { + resource.addCloseDay(project.convert(when)); + } + } else { + final DayAsDate when = (DayAsDate) complement; + resource.addCloseDay(project.convert(when)); + } + return CommandExecutionResult.ok(); + } + + }; + } + +} diff --git a/src/net/sourceforge/plantuml/project3/VerbIsOrAre.java b/src/net/sourceforge/plantuml/project3/VerbIsOrAre.java new file mode 100644 index 0000000..4e1248e --- /dev/null +++ b/src/net/sourceforge/plantuml/project3/VerbIsOrAre.java @@ -0,0 +1,96 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML 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 General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.project3; + +import java.util.Arrays; +import java.util.Collection; + +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.regex.IRegex; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexResult; +import net.sourceforge.plantuml.graphic.HtmlColor; + +public class VerbIsOrAre implements VerbPattern { + + public Collection<ComplementPattern> getComplements() { + return Arrays.<ComplementPattern> asList(new ComplementClose(), new ComplementInColors2()); + } + + public IRegex toRegex() { + return new RegexLeaf("(is|are)"); + } + + public Verb getVerb(final GanttDiagram project, final RegexResult arg) { + return new Verb() { + public CommandExecutionResult execute(Subject subject, Complement complement) { + if (complement instanceof ComplementColors) { + final HtmlColor color = ((ComplementColors) complement).getCenter(); + return manageColor(project, subject, color); + } + return manageClose(project, subject); + } + }; + } + + private CommandExecutionResult manageColor(final GanttDiagram project, Subject subject, HtmlColor color) { + if (subject instanceof DayAsDate) { + final DayAsDate day = (DayAsDate) subject; + project.colorDay(day, color); + } + if (subject instanceof DaysAsDates) { + final DaysAsDates days = (DaysAsDates) subject; + for (DayAsDate d : days) { + project.colorDay(d, color); + } + } + return CommandExecutionResult.ok(); + } + + private CommandExecutionResult manageClose(final GanttDiagram project, Subject subject) { + if (subject instanceof DayAsDate) { + final DayAsDate day = (DayAsDate) subject; + project.closeDayAsDate(day); + } + if (subject instanceof DaysAsDates) { + final DaysAsDates days = (DaysAsDates) subject; + for (DayAsDate d : days) { + project.closeDayAsDate(d); + } + } + return CommandExecutionResult.ok(); + } +} diff --git a/src/net/sourceforge/plantuml/project3/VerbIsOrAreNamed.java b/src/net/sourceforge/plantuml/project3/VerbIsOrAreNamed.java new file mode 100644 index 0000000..c291ce1 --- /dev/null +++ b/src/net/sourceforge/plantuml/project3/VerbIsOrAreNamed.java @@ -0,0 +1,70 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML 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 General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.project3; + +import java.util.Arrays; +import java.util.Collection; + +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.regex.IRegex; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexResult; + +public class VerbIsOrAreNamed implements VerbPattern { + + public Collection<ComplementPattern> getComplements() { + return Arrays.<ComplementPattern> asList(new ComplementNamed()); + } + + public IRegex toRegex() { + return new RegexLeaf("(is|are)[%s]+named"); + } + + public Verb getVerb(final GanttDiagram project, final RegexResult arg) { + return new Verb() { + public CommandExecutionResult execute(Subject subject, Complement complement) { + final ComplementName named = (ComplementName) complement; + final String name = named.getName(); + final DaysAsDates days = (DaysAsDates) subject; + for (DayAsDate d : days) { + project.nameDay(d, name); + } + return CommandExecutionResult.ok(); + } + }; + } + +} diff --git a/src/net/sourceforge/plantuml/project3/VerbLasts.java b/src/net/sourceforge/plantuml/project3/VerbLasts.java index 48b5d97..8dc2213 100644 --- a/src/net/sourceforge/plantuml/project3/VerbLasts.java +++ b/src/net/sourceforge/plantuml/project3/VerbLasts.java @@ -57,8 +57,8 @@ public class VerbLasts implements VerbPattern { return new Verb() { public CommandExecutionResult execute(Subject subject, Complement complement) { final Task task = (Task) subject; - final Duration duration = (Duration) complement; - task.setDuration(duration); + final Load duration = (Load) complement; + task.setLoad(duration); return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/project3/VerbTaskEndsAbsolute.java b/src/net/sourceforge/plantuml/project3/VerbTaskEndsAbsolute.java new file mode 100644 index 0000000..b0f7cf4 --- /dev/null +++ b/src/net/sourceforge/plantuml/project3/VerbTaskEndsAbsolute.java @@ -0,0 +1,71 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML 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 General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.project3; + +import java.util.Arrays; +import java.util.Collection; + +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.regex.IRegex; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexResult; + +public class VerbTaskEndsAbsolute implements VerbPattern { + + public Collection<ComplementPattern> getComplements() { + return Arrays.<ComplementPattern> asList(new ComplementDate()); + } + + public IRegex toRegex() { + return new RegexLeaf("ends[%s]*(the[%s]*|on[%s]*|at[%s]*)*"); + } + + public Verb getVerb(final GanttDiagram project, RegexResult arg) { + return new Verb() { + public CommandExecutionResult execute(Subject subject, Complement complement) { + final Task task = (Task) subject; + final DayAsDate end = (DayAsDate) complement; + final DayAsDate startingDate = project.getStartingDate(); + if (startingDate == null) { + return CommandExecutionResult.error("No starting date for the project"); + } + task.setEnd(end.asInstantDay(startingDate)); + return CommandExecutionResult.ok(); + } + + }; + } +} diff --git a/src/net/sourceforge/plantuml/project3/VerbStarts.java b/src/net/sourceforge/plantuml/project3/VerbTaskStarts.java index 89550d9..3cec23a 100644 --- a/src/net/sourceforge/plantuml/project3/VerbStarts.java +++ b/src/net/sourceforge/plantuml/project3/VerbTaskStarts.java @@ -43,7 +43,7 @@ import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.RegexLeaf; import net.sourceforge.plantuml.command.regex.RegexResult; -public class VerbStarts implements VerbPattern { +public class VerbTaskStarts implements VerbPattern { public Collection<ComplementPattern> getComplements() { return Arrays.<ComplementPattern> asList(new ComplementBeforeOrAfterOrAtTaskStartOrEnd()); diff --git a/src/net/sourceforge/plantuml/project3/VerbTaskStartsAbsolute.java b/src/net/sourceforge/plantuml/project3/VerbTaskStartsAbsolute.java new file mode 100644 index 0000000..d011301 --- /dev/null +++ b/src/net/sourceforge/plantuml/project3/VerbTaskStartsAbsolute.java @@ -0,0 +1,71 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2017, Arnaud Roques + * + * Project Info: http://plantuml.com + * + * If you like this project or if you find it useful, you can support us at: + * + * http://plantuml.com/patreon (only 1$ per month!) + * http://plantuml.com/paypal + * + * This file is part of PlantUML. + * + * PlantUML is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PlantUML 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 General Public + * License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * Original Author: Arnaud Roques + * + * + */ +package net.sourceforge.plantuml.project3; + +import java.util.Arrays; +import java.util.Collection; + +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.regex.IRegex; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexResult; + +public class VerbTaskStartsAbsolute implements VerbPattern { + + public Collection<ComplementPattern> getComplements() { + return Arrays.<ComplementPattern> asList(new ComplementDate()); + } + + public IRegex toRegex() { + return new RegexLeaf("starts[%s]*(the[%s]*|on[%s]*|at[%s]*)*"); + } + + public Verb getVerb(final GanttDiagram project, RegexResult arg) { + return new Verb() { + public CommandExecutionResult execute(Subject subject, Complement complement) { + final Task task = (Task) subject; + final DayAsDate start = (DayAsDate) complement; + final DayAsDate startingDate = project.getStartingDate(); + if (startingDate == null) { + return CommandExecutionResult.error("No starting date for the project"); + } + task.setStart(start.asInstantDay(startingDate)); + return CommandExecutionResult.ok(); + } + + }; + } +} |