feat: improve gantt language

This commit is contained in:
Arnaud Roques 2023-11-26 18:57:11 +01:00
parent bcb3b92dbc
commit f0b3e6900c
28 changed files with 475 additions and 219 deletions

View File

@ -86,7 +86,7 @@ import net.sourceforge.plantuml.project.core.TaskInstant;
import net.sourceforge.plantuml.project.core.TaskSeparator;
import net.sourceforge.plantuml.project.draw.FingerPrint;
import net.sourceforge.plantuml.project.draw.ResourceDraw;
import net.sourceforge.plantuml.project.draw.ResourceDrawVersion2;
import net.sourceforge.plantuml.project.draw.ResourceDrawBasic;
import net.sourceforge.plantuml.project.draw.TaskDraw;
import net.sourceforge.plantuml.project.draw.TaskDrawDiamond;
import net.sourceforge.plantuml.project.draw.TaskDrawGroup;
@ -153,6 +153,9 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
private int defaultCompletion = 100;
private Task it;
private Resource they;
public CommandExecutionResult changeLanguage(String lang) {
this.locale = new Locale(lang);
return CommandExecutionResult.ok();
@ -487,7 +490,8 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
private ResourceDraw buildResourceDraw(GanttDiagram gantt, Resource res, TimeScale timeScale, double y, Day min,
Day max) {
return new ResourceDrawVersion2(gantt, res, timeScale, y, min, max);
return new ResourceDrawBasic(gantt, res, timeScale, y, min, max);
// return new ResourceDrawVersion2(gantt, res, timeScale, y, min, max);
}
private Collection<GanttConstraint> getConstraints(Task task) {
@ -906,4 +910,20 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
return Collections.unmodifiableList(result);
}
public void setIt(Task result) {
this.it = result;
}
public Task getIt() {
return it;
}
public final Resource getThey() {
return they;
}
public final void setThey(Resource they) {
this.they = they;
}
}

View File

@ -52,7 +52,7 @@ import net.sourceforge.plantuml.project.core.Resource;
import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.timescale.TimeScale;
public class ResourceDrawBasicImpl implements ResourceDraw {
public class ResourceDrawBasic implements ResourceDraw {
private final Resource res;
private final TimeScale timeScale;
@ -61,7 +61,7 @@ public class ResourceDrawBasicImpl implements ResourceDraw {
private final Day max;
private final GanttDiagram gantt;
public ResourceDrawBasicImpl(GanttDiagram gantt, Resource res, TimeScale timeScale, double y, Day min, Day max) {
public ResourceDrawBasic(GanttDiagram gantt, Resource res, TimeScale timeScale, double y, Day min, Day max) {
this.res = res;
this.timeScale = timeScale;
this.y = y;

View File

@ -0,0 +1,44 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2024, Arnaud Roques
*
* Project Info: https://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* https://plantuml.com/patreon (only 1$ per month!)
* https://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.project.lang;
import net.sourceforge.plantuml.regex.IRegex;
public interface Adverbial {
public IRegex toRegex();
}

View File

@ -58,8 +58,8 @@ public class ComplementDates implements Something {
new RegexLeaf("BMONTH1" + suffix, "([\\d]{1,2})"), //
new RegexLeaf("\\D"), //
new RegexLeaf("BDAY1" + suffix, "([\\d]{1,2})"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("to"), //
Words.exactly(Words.TO), //
Words.zeroOrMore(Words.THE), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("BYEAR2" + suffix, "([\\d]{4})"), //
new RegexLeaf("\\D"), //
@ -73,8 +73,8 @@ public class ComplementDates implements Something {
return new RegexConcat( //
new RegexLeaf("[dD]\\+"), //
new RegexLeaf("ECOUNT1" + suffix, "([\\d]+)"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("to"), //
Words.exactly(Words.TO), //
Words.zeroOrMore(Words.THE), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("[dD]\\+"), //
new RegexLeaf("ECOUNT2" + suffix, "([\\d]+)") //

View File

@ -0,0 +1,58 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2024, Arnaud Roques
*
* Project Info: https://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* https://plantuml.com/patreon (only 1$ per month!)
* https://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.project.lang;
import net.sourceforge.plantuml.project.Failable;
import net.sourceforge.plantuml.project.GanttDiagram;
import net.sourceforge.plantuml.project.core.Task;
import net.sourceforge.plantuml.regex.IRegex;
import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexResult;
public class ComplementTask implements Something {
public IRegex toRegex(String suffix) {
return new RegexLeaf("COMPLEMENT" + suffix, "\\[([^\\[\\]]+?)\\]");
}
public Failable<Task> getMe(GanttDiagram gantt, RegexResult arg, String suffix) {
final String code = arg.get("COMPLEMENT" + suffix, 0);
final Task task = gantt.getExistingTask(code);
if (task == null)
return Failable.error("No such task " + code);
return Failable.ok(task);
}
}

View File

@ -38,9 +38,14 @@ package net.sourceforge.plantuml.project.lang;
import net.sourceforge.plantuml.command.CommandExecutionResult;
import net.sourceforge.plantuml.project.GanttDiagram;
import net.sourceforge.plantuml.regex.IRegex;
import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexResult;
public interface Sentence {
public final RegexLeaf OPTIONAL_FINAL_DOT = new RegexLeaf("\\s*[.]?\\s*$");
public final RegexLeaf SENTENCE_SEPARATOR = new RegexLeaf("\\s*(,|\\sand\\s)\\s*");
public IRegex toRegex();

View File

@ -56,37 +56,37 @@ public class SentenceAnd implements Sentence {
public IRegex toRegex() {
return new RegexConcat(//
RegexLeaf.start(), //
sentence1.subjectii.toRegex(), //
sentence1.getSubject().toRegex(), //
RegexLeaf.spaceOneOrMore(), //
sentence1.getVerbRegex(), //
sentence1.getAdverbialOrPropositon(), //
RegexLeaf.spaceOneOrMore(), //
sentence1.complementii.toRegex("1"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("and"), //
RegexLeaf.spaceOneOrMore(), //
sentence1.getComplement().toRegex("1"), //
SENTENCE_SEPARATOR, //
sentence2.getVerbRegex(), //
sentence2.getAdverbialOrPropositon(), //
RegexLeaf.spaceOneOrMore(), //
sentence2.complementii.toRegex("2"), //
RegexLeaf.end());
sentence2.getComplement().toRegex("2"), //
OPTIONAL_FINAL_DOT);
}
public final CommandExecutionResult execute(GanttDiagram project, RegexResult arg) {
final Failable<? extends Object> subject = sentence1.subjectii.getMe(project, arg);
if (subject.isFail()) {
final Failable<? extends Object> subject = sentence1.getSubject().getMe(project, arg);
if (subject.isFail())
return CommandExecutionResult.error(subject.getError());
}
final Failable<? extends Object> complement1 = sentence1.complementii.getMe(project, arg, "1");
if (complement1.isFail()) {
final Failable<? extends Object> complement1 = sentence1.getComplement().getMe(project, arg, "1");
if (complement1.isFail())
return CommandExecutionResult.error(complement1.getError());
}
final CommandExecutionResult result1 = sentence1.execute(project, subject.get(), complement1.get());
if (result1.isOk() == false) {
if (result1.isOk() == false)
return result1;
}
final Failable<? extends Object> complement2 = sentence2.complementii.getMe(project, arg, "2");
if (complement2.isFail()) {
final Failable<? extends Object> complement2 = sentence2.getComplement().getMe(project, arg, "2");
if (complement2.isFail())
return CommandExecutionResult.error(complement2.getError());
}
return sentence2.execute(project, subject.get(), complement2.get());
}

View File

@ -58,51 +58,50 @@ public class SentenceAndAnd implements Sentence {
public IRegex toRegex() {
return new RegexConcat(//
RegexLeaf.start(), //
sentence1.subjectii.toRegex(), //
sentence1.getSubject().toRegex(), //
RegexLeaf.spaceOneOrMore(), //
sentence1.getVerbRegex(), //
sentence1.getAdverbialOrPropositon(), //
RegexLeaf.spaceOneOrMore(), //
sentence1.complementii.toRegex("1"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("and"), //
RegexLeaf.spaceOneOrMore(), //
sentence1.getComplement().toRegex("1"), //
SENTENCE_SEPARATOR, //
sentence2.getVerbRegex(), //
sentence2.getAdverbialOrPropositon(), //
RegexLeaf.spaceOneOrMore(), //
sentence2.complementii.toRegex("2"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("and"), //
RegexLeaf.spaceOneOrMore(), //
sentence2.getComplement().toRegex("2"), //
SENTENCE_SEPARATOR, //
sentence3.getVerbRegex(), //
sentence3.getAdverbialOrPropositon(), //
RegexLeaf.spaceOneOrMore(), //
sentence3.complementii.toRegex("3"), //
RegexLeaf.end());
sentence3.getComplement().toRegex("3"), //
OPTIONAL_FINAL_DOT);
}
public final CommandExecutionResult execute(GanttDiagram project, RegexResult arg) {
final Failable<? extends Object> subject = sentence1.subjectii.getMe(project, arg);
if (subject.isFail()) {
final Failable<? extends Object> subject = sentence1.getSubject().getMe(project, arg);
if (subject.isFail())
return CommandExecutionResult.error(subject.getError());
}
final Failable<? extends Object> complement1 = sentence1.complementii.getMe(project, arg, "1");
if (complement1.isFail()) {
final Failable<? extends Object> complement1 = sentence1.getComplement().getMe(project, arg, "1");
if (complement1.isFail())
return CommandExecutionResult.error(complement1.getError());
}
final CommandExecutionResult result1 = sentence1.execute(project, subject.get(), complement1.get());
if (result1.isOk() == false) {
if (result1.isOk() == false)
return result1;
}
final Failable<? extends Object> complement2 = sentence2.complementii.getMe(project, arg, "2");
if (complement2.isFail()) {
final Failable<? extends Object> complement2 = sentence2.getComplement().getMe(project, arg, "2");
if (complement2.isFail())
return CommandExecutionResult.error(complement2.getError());
}
final CommandExecutionResult result2 = sentence2.execute(project, subject.get(), complement2.get());
if (result2.isOk() == false) {
if (result2.isOk() == false)
return result2;
}
final Failable<? extends Object> complement3 = sentence3.complementii.getMe(project, arg, "3");
if (complement3.isFail()) {
final Failable<? extends Object> complement3 = sentence3.getComplement().getMe(project, arg, "3");
if (complement3.isFail())
return CommandExecutionResult.error(complement3.getError());
}
final CommandExecutionResult result3 = sentence3.execute(project, subject.get(), complement3.get());
return result3;

View File

@ -44,7 +44,8 @@ import net.sourceforge.plantuml.project.core.TaskInstant;
public class SentenceHappens extends SentenceSimple {
public SentenceHappens() {
super(SubjectTask.ME, Verbs.happens, new ComplementBeforeOrAfterOrAtTaskStartOrEnd());
super(SubjectTask.ME, Verbs.happens, Words.zeroOrMore(Words.THE, Words.ON, Words.AT),
new ComplementBeforeOrAfterOrAtTaskStartOrEnd());
}
@Override

View File

@ -44,7 +44,7 @@ import net.sourceforge.plantuml.project.time.Day;
public class SentenceHappensDate extends SentenceSimple {
public SentenceHappensDate() {
super(SubjectTask.ME, Verbs.happens, ComplementDate.any());
super(SubjectTask.ME, Verbs.happens, Words.zeroOrMore(Words.THE, Words.ON, Words.AT), ComplementDate.any());
}
@Override

View File

@ -42,7 +42,8 @@ import net.sourceforge.plantuml.project.core.Task;
public class SentenceIsColoredForCompletion extends SentenceSimple {
public SentenceIsColoredForCompletion() {
super(SubjectTask.ME, Verbs.isColoredForCompletion, new ComplementInColorsFromTo());
super(SubjectTask.ME, Verbs.isColored, Words.exactly(Words.FOR, Words.COMPLETION),
new ComplementInColorsFromTo());
}
@Override

View File

@ -43,7 +43,8 @@ import net.sourceforge.plantuml.project.time.Day;
public class SentencePausesDate extends SentenceSimple {
public SentencePausesDate() {
super(SubjectTask.ME, Verbs.pauses, ComplementDate.any());
super(SubjectTask.ME, Verbs.pauses, Words.zeroOrMore(Words.THE, Words.ON, Words.AT, Words.FROM),
ComplementDate.any());
}
@Override

View File

@ -44,20 +44,17 @@ import net.sourceforge.plantuml.project.time.Day;
public class SentencePausesDates extends SentenceSimple {
public SentencePausesDates() {
super(SubjectTask.ME, Verbs.pauses, new ComplementDates());
super(SubjectTask.ME, Verbs.pauses, Words.zeroOrMore(Words.THE, Words.ON, Words.AT, Words.FROM),
new ComplementDates());
}
@Override
public CommandExecutionResult execute(GanttDiagram project, Object subject, Object complement) {
final Task task = (Task) subject;
final DaysAsDates pauses = (DaysAsDates) complement;
// final Day startingDate = project.getStartingDate();
// if (startingDate == null) {
// return CommandExecutionResult.error("No starting date for the project");
// }
for (Day day : pauses) {
for (Day day : pauses)
task.addPause(day);
}
return CommandExecutionResult.ok();
}

View File

@ -43,7 +43,8 @@ import net.sourceforge.plantuml.project.time.DayOfWeek;
public class SentencePausesDayOfWeek extends SentenceSimple {
public SentencePausesDayOfWeek() {
super(SubjectTask.ME, Verbs.pauses, new ComplementDayOfWeek());
super(SubjectTask.ME, Verbs.pauses, Words.zeroOrMore(Words.THE, Words.ON, Words.AT, Words.FROM),
new ComplementDayOfWeek());
}
@Override

View File

@ -45,49 +45,57 @@ import net.sourceforge.plantuml.regex.RegexResult;
public abstract class SentenceSimple implements Sentence {
protected final Subject subjectii;
private final Subject subject;
private final IRegex verb;
protected final Something complementii;
private final IRegex adverbialOrPropositon;
private final Something complement;
public SentenceSimple(Subject subject, IRegex verb, Something complement) {
this.subjectii = subject;
this(subject, verb, new RegexLeaf(""), complement);
}
public SentenceSimple(Subject subject, IRegex verb, IRegex adverbialOrPropositon, Something complement) {
this.subject = subject;
this.verb = verb;
this.complementii = complement;
this.adverbialOrPropositon = adverbialOrPropositon;
this.complement = complement;
}
public String getSignature() {
return subjectii.getClass() + "/" + verb.getPattern() + "/" + complementii.getClass();
return subject.getClass() + "/" + verb.getPattern() + "/" + complement.getClass();
}
public final IRegex toRegex() {
if (complementii instanceof ComplementEmpty)
if (complement instanceof ComplementEmpty)
return new RegexConcat(//
RegexLeaf.start(), //
subjectii.toRegex(), //
subject.toRegex(), //
RegexLeaf.spaceOneOrMore(), //
verb, //
RegexLeaf.end());
adverbialOrPropositon, //
OPTIONAL_FINAL_DOT);
return new RegexConcat(//
RegexLeaf.start(), //
subjectii.toRegex(), //
subject.toRegex(), //
RegexLeaf.spaceOneOrMore(), //
verb, //
adverbialOrPropositon, //
RegexLeaf.spaceOneOrMore(), //
complementii.toRegex("0"), //
RegexLeaf.end());
complement.toRegex("0"), //
OPTIONAL_FINAL_DOT);
}
public final CommandExecutionResult execute(GanttDiagram project, RegexResult arg) {
final Failable<? extends Object> subject = subjectii.getMe(project, arg);
if (subject.isFail())
return CommandExecutionResult.error(subject.getError());
final Failable<? extends Object> currentSubject = subject.getMe(project, arg);
if (currentSubject.isFail())
return CommandExecutionResult.error(currentSubject.getError());
final Failable<? extends Object> complement = complementii.getMe(project, arg, "0");
if (complement.isFail())
return CommandExecutionResult.error(complement.getError());
final Failable<? extends Object> currentComplement = complement.getMe(project, arg, "0");
if (currentComplement.isFail())
return CommandExecutionResult.error(currentComplement.getError());
return execute(project, subject.get(), complement.get());
return execute(project, currentSubject.get(), currentComplement.get());
}
@ -97,4 +105,18 @@ public abstract class SentenceSimple implements Sentence {
return verb;
}
protected final IRegex getAdverbialOrPropositon() {
return adverbialOrPropositon;
}
protected final Subject getSubject() {
return subject;
}
protected final Something getComplement() {
return complement;
}
}

View File

@ -43,9 +43,10 @@ import net.sourceforge.plantuml.project.time.Day;
public class SentenceTaskEndsAbsolute extends SentenceSimple {
public SentenceTaskEndsAbsolute() {
super(SubjectTask.ME, Verbs.ends2, ComplementDate.any());
super(SubjectTask.ME, Verbs.ends, Words.zeroOrMore(Words.THE, Words.ON, Words.AT), ComplementDate.any());
}
@Override
public CommandExecutionResult execute(GanttDiagram project, Object subject, Object complement) {
final Task task = (Task) subject;

View File

@ -43,7 +43,8 @@ import net.sourceforge.plantuml.project.time.Day;
public class SentenceTaskEndsOnlyRelative extends SentenceSimple {
public SentenceTaskEndsOnlyRelative() {
super(SubjectTask.ME, Verbs.ends2, ComplementDate.onlyRelative());
super(SubjectTask.ME, Verbs.ends, Words.zeroOrMore(Words.THE, Words.ON, Words.AT),
ComplementDate.onlyRelative());
}
@Override

View File

@ -46,7 +46,7 @@ import net.sourceforge.plantuml.project.core.TaskInstant;
public class SentenceTaskStarts extends SentenceSimple {
public SentenceTaskStarts() {
super(SubjectTask.ME, Verbs.starts2, new ComplementBeforeOrAfterOrAtTaskStartOrEnd());
super(SubjectTask.ME, Verbs.starts, new ComplementBeforeOrAfterOrAtTaskStartOrEnd());
}
@Override

View File

@ -43,7 +43,7 @@ import net.sourceforge.plantuml.project.time.Day;
public class SentenceTaskStartsAbsolute extends SentenceSimple {
public SentenceTaskStartsAbsolute() {
super(SubjectTask.ME, Verbs.starts3, ComplementDate.any());
super(SubjectTask.ME, Verbs.starts, Words.zeroOrMore(Words.THE, Words.ON, Words.AT), ComplementDate.any());
}
@Override

View File

@ -43,7 +43,8 @@ import net.sourceforge.plantuml.project.time.Day;
public class SentenceTaskStartsOnlyRelative extends SentenceSimple {
public SentenceTaskStartsOnlyRelative() {
super(SubjectTask.ME, Verbs.starts3, ComplementDate.onlyRelative());
super(SubjectTask.ME, Verbs.starts, Words.zeroOrMore(Words.THE, Words.ON, Words.AT),
ComplementDate.onlyRelative());
}
@Override

View File

@ -46,7 +46,7 @@ import net.sourceforge.plantuml.project.core.TaskInstant;
public class SentenceTaskStartsWithColor extends SentenceSimple {
public SentenceTaskStartsWithColor() {
super(SubjectTask.ME, Verbs.starts2,
super(SubjectTask.ME, Verbs.starts,
new PairOfSomething(new ComplementBeforeOrAfterOrAtTaskStartOrEnd(), new ComplementWithColorLink()));
}

View File

@ -68,7 +68,8 @@ public class SubjectProject implements Subject {
class Starts extends SentenceSimple {
public Starts() {
super(SubjectProject.this, Verbs.starts, ComplementDate.onlyAbsolute());
super(SubjectProject.this, Verbs.starts, Words.zeroOrMore(Words.ON, Words.FOR, Words.THE, Words.AT),
ComplementDate.onlyAbsolute());
}
@Override

View File

@ -43,11 +43,12 @@ import net.sourceforge.plantuml.project.DaysAsDates;
import net.sourceforge.plantuml.project.Failable;
import net.sourceforge.plantuml.project.GanttDiagram;
import net.sourceforge.plantuml.project.core.Resource;
import net.sourceforge.plantuml.project.core.Task;
import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.time.DayOfWeek;
import net.sourceforge.plantuml.regex.IRegex;
import net.sourceforge.plantuml.regex.RegexConcat;
import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexOr;
import net.sourceforge.plantuml.regex.RegexResult;
public class SubjectResource implements Subject {
@ -57,30 +58,56 @@ public class SubjectResource implements Subject {
private SubjectResource() {
}
public Failable<Resource> getMe(GanttDiagram project, RegexResult arg) {
final String s = arg.get("RESOURCE", 0);
return Failable.ok(project.getResource(s));
public Failable<Resource> getMe(GanttDiagram gantt, RegexResult arg) {
if (arg.get("THEY", 0) != null) {
final Resource they = gantt.getThey();
if (they == null)
return Failable.error("Not sure who are you refering to?");
return Failable.ok(they);
}
final String resource = arg.get("RESOURCE", 0);
final Resource result = gantt.getResource(resource);
gantt.setThey(result);
return Failable.ok(result);
}
public Collection<? extends SentenceSimple> getSentences() {
return Arrays.asList(new IsOffDate(), new IsOffDates(), new IsOffDayOfWeek(), new IsOnDate(), new IsOnDates(),
new IsOffBeforeDate(), new IsOffAfterDate());
new IsOffBeforeDate(), new IsOffAfterDate(), new WorksOn());
}
public IRegex toRegex() {
return new RegexConcat( //
return new RegexOr( //
new RegexLeaf("THEY", "(she|he|they)"), //
new RegexLeaf("RESOURCE", "\\{([^{}]+)\\}") //
);
}
public class WorksOn extends SentenceSimple {
public WorksOn() {
super(SubjectResource.this, Verbs.worksOn, new ComplementTask());
}
@Override
public CommandExecutionResult execute(GanttDiagram gantt, Object subject, Object complement) {
final Resource resource = (Resource) subject;
final Task task = (Task) complement;
task.addResource(resource, 100);
return CommandExecutionResult.ok();
}
}
public class IsOffBeforeDate extends SentenceSimple {
public IsOffBeforeDate() {
super(SubjectResource.this, Verbs.isOffBefore, ComplementDate.any());
super(SubjectResource.this, Verbs.isOff,
Words.concat(Words.exactly(Words.BEFORE), Words.zeroOrMore(Words.THE)), ComplementDate.any());
}
@Override
public CommandExecutionResult execute(GanttDiagram project, Object subject, Object complement) {
public CommandExecutionResult execute(GanttDiagram gantt, Object subject, Object complement) {
final Resource resource = (Resource) subject;
final Day when = (Day) complement;
resource.setOffBeforeDate(when);
@ -92,11 +119,12 @@ public class SubjectResource implements Subject {
public class IsOffAfterDate extends SentenceSimple {
public IsOffAfterDate() {
super(SubjectResource.this, Verbs.isOffAfter, ComplementDate.any());
super(SubjectResource.this, Verbs.isOff,
Words.concat(Words.exactly(Words.AFTER), Words.zeroOrMore(Words.THE)), ComplementDate.any());
}
@Override
public CommandExecutionResult execute(GanttDiagram project, Object subject, Object complement) {
public CommandExecutionResult execute(GanttDiagram gantt, Object subject, Object complement) {
final Resource resource = (Resource) subject;
final Day when = (Day) complement;
resource.setOffAfterDate(when);
@ -108,11 +136,12 @@ public class SubjectResource implements Subject {
public class IsOffDate extends SentenceSimple {
public IsOffDate() {
super(SubjectResource.this, Verbs.isOff, ComplementDate.any());
super(SubjectResource.this, Verbs.isOff,
Words.zeroOrMore(Words.FROM, Words.ON, Words.FOR, Words.THE, Words.AT), ComplementDate.any());
}
@Override
public CommandExecutionResult execute(GanttDiagram project, Object subject, Object complement) {
public CommandExecutionResult execute(GanttDiagram gantt, Object subject, Object complement) {
final Resource resource = (Resource) subject;
final Day when = (Day) complement;
resource.addCloseDay(when);
@ -124,11 +153,12 @@ public class SubjectResource implements Subject {
public class IsOffDates extends SentenceSimple {
public IsOffDates() {
super(SubjectResource.this, Verbs.isOff, new ComplementDates());
super(SubjectResource.this, Verbs.isOff,
Words.zeroOrMore(Words.FROM, Words.ON, Words.FOR, Words.THE, Words.AT), new ComplementDates());
}
@Override
public CommandExecutionResult execute(GanttDiagram project, Object subject, Object complement) {
public CommandExecutionResult execute(GanttDiagram gantt, Object subject, Object complement) {
final Resource resource = (Resource) subject;
for (Day when : (DaysAsDates) complement) {
resource.addCloseDay(when);
@ -141,11 +171,12 @@ public class SubjectResource implements Subject {
public class IsOffDayOfWeek extends SentenceSimple {
public IsOffDayOfWeek() {
super(SubjectResource.this, Verbs.isOff, new ComplementDayOfWeek());
super(SubjectResource.this, Verbs.isOff,
Words.zeroOrMore(Words.FROM, Words.ON, Words.FOR, Words.THE, Words.AT), new ComplementDayOfWeek());
}
@Override
public CommandExecutionResult execute(GanttDiagram project, Object subject, Object complement) {
public CommandExecutionResult execute(GanttDiagram gantt, Object subject, Object complement) {
final Resource resource = (Resource) subject;
resource.addCloseDay(((DayOfWeek) complement));
return CommandExecutionResult.ok();
@ -156,11 +187,12 @@ public class SubjectResource implements Subject {
public class IsOnDate extends SentenceSimple {
public IsOnDate() {
super(SubjectResource.this, Verbs.isOn, ComplementDate.any());
super(SubjectResource.this, Verbs.isOn,
Words.zeroOrMore(Words.FROM, Words.ON, Words.FOR, Words.THE, Words.AT), ComplementDate.any());
}
@Override
public CommandExecutionResult execute(GanttDiagram project, Object subject, Object complement) {
public CommandExecutionResult execute(GanttDiagram gantt, Object subject, Object complement) {
final Resource resource = (Resource) subject;
final Day when = (Day) complement;
resource.addForceOnDay(when);
@ -172,11 +204,12 @@ public class SubjectResource implements Subject {
public class IsOnDates extends SentenceSimple {
public IsOnDates() {
super(SubjectResource.this, Verbs.isOn, new ComplementDates());
super(SubjectResource.this, Verbs.isOn,
Words.zeroOrMore(Words.FROM, Words.ON, Words.FOR, Words.THE, Words.AT), new ComplementDates());
}
@Override
public CommandExecutionResult execute(GanttDiagram project, Object subject, Object complement) {
public CommandExecutionResult execute(GanttDiagram gantt, Object subject, Object complement) {
final Resource resource = (Resource) subject;
for (Day when : (DaysAsDates) complement) {
resource.addForceOnDay(when);

View File

@ -69,7 +69,7 @@ public class SubjectSeparator implements Subject {
class JustBefore extends SentenceSimple {
public JustBefore() {
super(SubjectSeparator.this, Verbs.justBefore, ComplementDate.any());
super(SubjectSeparator.this, Verbs.just, Words.exactly(Words.BEFORE), ComplementDate.any());
}
@Override
@ -85,7 +85,7 @@ public class SubjectSeparator implements Subject {
class JustAfter extends SentenceSimple {
public JustAfter() {
super(SubjectSeparator.this, Verbs.justAfter, ComplementDate.any());
super(SubjectSeparator.this, Verbs.just, Words.exactly(Words.AFTER), ComplementDate.any());
}
@Override

View File

@ -46,6 +46,7 @@ import net.sourceforge.plantuml.regex.IRegex;
import net.sourceforge.plantuml.regex.RegexConcat;
import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexOptional;
import net.sourceforge.plantuml.regex.RegexOr;
import net.sourceforge.plantuml.regex.RegexResult;
public class SubjectTask implements Subject {
@ -55,23 +56,32 @@ public class SubjectTask implements Subject {
private SubjectTask() {
}
public Failable<Task> getMe(GanttDiagram project, RegexResult arg) {
final String s = arg.get("SUBJECT", 0);
final String shortName = arg.get("SUBJECT", 1);
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();
public Failable<Task> getMe(GanttDiagram gantt, RegexResult arg) {
final Task result;
if (arg.get("IT", 0) != null) {
result = gantt.getIt();
if (result == null)
return Failable.error("Not sure what are you refering to?");
} else {
final String subject = arg.get("SUBJECT", 0);
final String shortName = arg.get("SUBJECT", 1);
final String then = arg.get("THEN", 0);
result = gantt.getOrCreateTask(subject, shortName, then != null);
gantt.setIt(result);
}
if (result == null)
throw new IllegalStateException();
final String resource = arg.get("RESOURCE", 0);
if (resource != null) {
for (final StringTokenizer st = new StringTokenizer(resource, "{}"); st.hasMoreTokens();) {
final String part = st.nextToken().trim();
if (part.length() > 0) {
final boolean ok = project.affectResource(result, part);
if (ok == false) {
final boolean ok = gantt.affectResource(result, part);
if (ok == false)
return Failable.error("Bad argument for resource");
}
}
}
@ -90,17 +100,17 @@ public class SubjectTask implements Subject {
}
public IRegex toRegex() {
return new RegexConcat( //
new RegexLeaf("THEN", "(then[%s]+)?"), //
new RegexLeaf("SUBJECT", "\\[([^\\[\\]]+?)\\](?:[%s]+as[%s]+\\[([^\\[\\]]+?)\\])?"), //
new RegexOptional( //
new RegexConcat( //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("on"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("RESOURCE", "((?:\\{[^{}]+\\}[%s]*)+)") //
)) //
);
return new RegexOr( //
new RegexLeaf("IT", "(it)"), //
new RegexConcat(new RegexLeaf("THEN", "(then[%s]+)?"), //
new RegexLeaf("SUBJECT", "\\[([^\\[\\]]+?)\\](?:[%s]+as[%s]+\\[([^\\[\\]]+?)\\])?"), //
new RegexOptional( //
new RegexConcat( //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("on"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("RESOURCE", "((?:\\{[^{}]+\\}[%s]*)+)") //
))));
}
}

View File

@ -36,103 +36,28 @@
package net.sourceforge.plantuml.project.lang;
import net.sourceforge.plantuml.regex.IRegex;
import net.sourceforge.plantuml.regex.RegexConcat;
import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexOptional;
import net.sourceforge.plantuml.regex.RegexOr;
public class Verbs {
public static IRegex are = new RegexLeaf("are");
public static IRegex areColored = new RegexLeaf("are[%s]+colou?red");
public static IRegex displayOnSameRowAs = new RegexLeaf("displays?[%s]+on[%s]+same[%s]+row[%s]+as");
public static IRegex ends = new RegexLeaf("ends");
public static IRegex ends2 = new RegexLeaf("ends[%s]*(the[%s]*|on[%s]*|at[%s]*)*");
public static IRegex happens = new RegexLeaf("happens?[%s]*(at[%s]*|the[%s]*|on[%s]*)*");
public static IRegex pauses = new RegexLeaf("pauses?[%s]*(at[%s]*|the[%s]*|on[%s]*|from[%s]*)*");
public static IRegex isDeleted = new RegexLeaf("is[%s]+deleted");
public static IRegex happens = new RegexLeaf("happens");
public static IRegex is = new RegexLeaf("is");
public static IRegex isColored = new RegexLeaf("is[%s]+colou?red");
public static IRegex isColoredForCompletion = new RegexLeaf("is[%s]+colou?red[%s]+for[%s]+completion");
public static IRegex isOff = new RegexConcat(new RegexLeaf("is"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("off"), //
RegexLeaf.spaceOneOrMore(), //
new RegexOr(//
new RegexLeaf("from"), //
new RegexLeaf("on"), //
new RegexLeaf("for"), //
new RegexLeaf("the"), //
new RegexLeaf("at") //
));
public static IRegex isOffBefore = new RegexConcat(new RegexLeaf("is"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("off"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("before") //
);
public static IRegex isOffAfter = new RegexConcat(new RegexLeaf("is"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("off"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("after") //
);
public static IRegex isOn = new RegexConcat(new RegexLeaf("is"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("on"), //
RegexLeaf.spaceOneOrMore(), //
new RegexOr(//
new RegexLeaf("from"), //
new RegexLeaf("on"), //
new RegexLeaf("for"), //
new RegexLeaf("the"), //
new RegexLeaf("at") //
) //
);
public static IRegex isDeleted = new RegexLeaf("is[%s]+deleted");
public static IRegex isOff = new RegexLeaf("is[%s]+off");
public static IRegex isOn = new RegexLeaf("is[%s]+on");
public static IRegex isOrAre = new RegexLeaf("(is|are)");
public static IRegex isOrAreNamed = new RegexLeaf("(is|are)[%s]+named");
public static IRegex requires = new RegexLeaf("(lasts|requires?)");
public static IRegex linksTo = new RegexLeaf("links to");
public static IRegex occurs = new RegexLeaf("occurs?");
public static IRegex starts3 = new RegexLeaf("starts[%s]*(the[%s]*|on[%s]*|at[%s]*)*");
public static IRegex starts2 = new RegexLeaf("starts");
public static IRegex starts = new RegexConcat(new RegexLeaf("start"), //
new RegexOptional(new RegexLeaf("s")), //
RegexLeaf.spaceZeroOrMore(), //
new RegexOptional(new RegexOr(//
new RegexLeaf("on"), //
new RegexLeaf("for"), //
new RegexLeaf("the"), //
new RegexLeaf("at") //
)) //
);
public static IRegex just = new RegexLeaf("just");
public static IRegex justBefore = new RegexLeaf("just[%s]*before");
public static IRegex justAfter = new RegexLeaf("just[%s]*after");
public static IRegex linksTo = new RegexLeaf("links[%s]+to");
public static IRegex occurs = new RegexLeaf("occurs");
public static IRegex pauses = new RegexLeaf("pauses");
public static IRegex requires = new RegexLeaf("(lasts|requires)");
public static IRegex starts = new RegexLeaf("starts");
public static IRegex worksOn = new RegexLeaf("works[%s]+on");
}

View File

@ -0,0 +1,77 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2024, Arnaud Roques
*
* Project Info: https://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* https://plantuml.com/patreon (only 1$ per month!)
* https://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.project.lang;
import net.sourceforge.plantuml.regex.IRegex;
import net.sourceforge.plantuml.regex.RegexConcat;
import net.sourceforge.plantuml.regex.RegexLeaf;
import net.sourceforge.plantuml.regex.RegexOr;
import net.sourceforge.plantuml.regex.RegexRepeatedZeroOrMore;
public class Words {
public final static String AFTER = "after";
public final static String AT = "at";
public final static String BEFORE = "before";
public final static String COMPLETION = "completion";
public final static String FOR = "for";
public final static String FROM = "from";
public final static String ON = "on";
public final static String THE = "the";
public final static String TO = "to";
public static IRegex zeroOrMore(String... words) {
final IRegex tmp[] = new IRegex[words.length];
for (int i = 0; i < words.length; i++)
tmp[i] = new RegexLeaf(words[i]);
final RegexOr or = new RegexOr(tmp);
return new RegexRepeatedZeroOrMore(new RegexConcat(RegexLeaf.spaceOneOrMore(), or));
}
public static IRegex exactly(String... words) {
final IRegex tmp[] = new IRegex[words.length];
for (int i = 0; i < words.length; i++)
tmp[i] = new RegexConcat(RegexLeaf.spaceOneOrMore(), new RegexLeaf(words[i]));
return new RegexConcat(tmp);
}
public static IRegex concat(IRegex... expressions) {
return new RegexConcat(expressions);
}
}

View File

@ -0,0 +1,58 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2024, Arnaud Roques
*
* Project Info: https://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* https://plantuml.com/patreon (only 1$ per month!)
* https://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.regex;
import net.sourceforge.plantuml.text.StringLocated;
public class RegexRepeatedZeroOrMore extends RegexComposed implements IRegex {
public RegexRepeatedZeroOrMore(IRegex partial) {
super(partial);
}
@Override
protected String getFullSlow() {
final StringBuilder sb = new StringBuilder("(?:");
sb.append(partials().get(0).getPattern());
sb.append(")*");
return sb.toString();
}
public boolean match(StringLocated full) {
throw new UnsupportedOperationException();
}
}