diff --git a/pom.xml b/pom.xml index 686388615..e163f67e5 100644 --- a/pom.xml +++ b/pom.xml @@ -35,7 +35,7 @@ net.sourceforge.plantuml plantuml - 1.2019.14-SNAPSHOT + 1.2020.1-SNAPSHOT jar PlantUML diff --git a/src/gen/lib/dotgen/cluster__c.java b/src/gen/lib/dotgen/cluster__c.java index b13d4c232..33053cd54 100644 --- a/src/gen/lib/dotgen/cluster__c.java +++ b/src/gen/lib/dotgen/cluster__c.java @@ -57,6 +57,7 @@ import static gen.lib.cgraph.obj__c.agroot; import static gen.lib.common.utils__c.UF_setname; import static gen.lib.common.utils__c.UF_singleton; import static gen.lib.dotgen.class2__c.class2; +import static gen.lib.dotgen.class2__c.merge_chain; import static gen.lib.dotgen.class2__c.mergeable; import static gen.lib.dotgen.dotinit__c.dot_root; import static gen.lib.dotgen.fastgr__c.delete_fast_edge; @@ -67,6 +68,7 @@ import static gen.lib.dotgen.fastgr__c.find_flat_edge; import static gen.lib.dotgen.fastgr__c.flat_edge; import static gen.lib.dotgen.fastgr__c.merge_oneway; import static gen.lib.dotgen.fastgr__c.other_edge; +import static gen.lib.dotgen.fastgr__c.safe_other_edge; import static gen.lib.dotgen.fastgr__c.virtual_edge; import static gen.lib.dotgen.fastgr__c.virtual_node; import static gen.lib.dotgen.mincross__c.allocate_ranks; @@ -112,7 +114,6 @@ import h.ST_Agnode_s; import h.ST_Agraph_s; import h.ST_nodequeue; import h.ST_pointf; -import smetana.core.__ptr__; public class cluster__c { //1 2digov3edok6d5srhgtlmrycs @@ -940,9 +941,9 @@ try { ED_to_virt(e, null); if (ED_to_virt(prev) == null) continue; /* internal edge */ -UNSUPPORTED("8d5mw7m9lzlseqbyx8a8mncgs"); // merge_chain(subg, e, ED_to_virt(prev), 0); -UNSUPPORTED("87mmnlsj8quzlzg0vxax15kt2"); // safe_other_edge(e); -UNSUPPORTED("6hyelvzskqfqa07xtgjtvg2is"); // continue; + merge_chain(subg, e, ED_to_virt(prev), false); + safe_other_edge(e); + continue; } /* flat edges */ if (ND_rank(agtail(e)) == ND_rank(aghead(e))) { diff --git a/src/gen/lib/dotgen/fastgr__c.java b/src/gen/lib/dotgen/fastgr__c.java index 68a35d209..a1b520f48 100644 --- a/src/gen/lib/dotgen/fastgr__c.java +++ b/src/gen/lib/dotgen/fastgr__c.java @@ -797,18 +797,17 @@ LEAVING("bf1j97keudu416avridkj9fpb","find_flat_edge"); //3 cttswsffgmw1g710jzvdd3wzn // static void safe_list_append(edge_t * e, elist * L) -public static Object safe_list_append(Object... arg) { -UNSUPPORTED("59dl3yc4jbcy2pb7j1njhlybi"); // static void -UNSUPPORTED("3kdqf9wvozj4zu6wrv6ur2k47"); // safe_list_append(edge_t * e, elist * L) -UNSUPPORTED("erg9i1970wdri39osu8hx2a6e"); // { -UNSUPPORTED("b17di9c7wgtqm51bvsyxz6e2f"); // int i; -UNSUPPORTED("dhvbzrcz6s76mme3x94begmvr"); // for (i = 0; i < L->size; i++) -UNSUPPORTED("c0a4ruccwt5263vw39xrttm0y"); // if (e == L->list[i]) -UNSUPPORTED("6cprbghvenu9ldc0ez1ifc63q"); // return; +public static void safe_list_append(ST_Agedge_s e, ST_elist L) { +ENTERING("cttswsffgmw1g710jzvdd3wzn","safe_list_append"); +try { + int i; + for (i = 0; i < L.size; i++) + if (EQ(e, L.list.get(i))) + return; UNSUPPORTED("cslejjtgepjdwlcykfas4fmvz"); // elist_append(e, (*L)); -UNSUPPORTED("c24nfmv9i7o5eoqaymbibp7m7"); // } - -throw new UnsupportedOperationException(); +} finally { +LEAVING("cttswsffgmw1g710jzvdd3wzn","safe_list_append"); +} } @@ -907,13 +906,13 @@ LEAVING("73oebfcfiescklohgt8mddswc","other_edge"); //3 4zg1fp1b7bhnx2tbeaij8yeel // void safe_other_edge(edge_t * e) -public static Object safe_other_edge(Object... arg) { -UNSUPPORTED("3cc9ux78ad0yjajm0nkpos345"); // void safe_other_edge(edge_t * e) -UNSUPPORTED("erg9i1970wdri39osu8hx2a6e"); // { -UNSUPPORTED("bn816jsdz3qke6htvbwvztrpc"); // safe_list_append(e, &(ND_other(agtail(e)))); -UNSUPPORTED("c24nfmv9i7o5eoqaymbibp7m7"); // } - -throw new UnsupportedOperationException(); +public static void safe_other_edge(ST_Agedge_s e) { +ENTERING("4zg1fp1b7bhnx2tbeaij8yeel","safe_other_edge"); +try { + safe_list_append(e, ND_other(agtail(e))); +} finally { +LEAVING("4zg1fp1b7bhnx2tbeaij8yeel","safe_other_edge"); +} } diff --git a/src/net/sourceforge/plantuml/AFile.java b/src/net/sourceforge/plantuml/AFile.java index b35e08e3b..cca338b96 100644 --- a/src/net/sourceforge/plantuml/AFile.java +++ b/src/net/sourceforge/plantuml/AFile.java @@ -47,8 +47,8 @@ public interface AFile { public AParentFolder getParentFile(); - public String getAbsolutePath(); - public File getUnderlyingFile(); + public File getSystemFolder() throws IOException; + } diff --git a/src/net/sourceforge/plantuml/AFileRegular.java b/src/net/sourceforge/plantuml/AFileRegular.java index 3b31828b7..e910452e1 100644 --- a/src/net/sourceforge/plantuml/AFileRegular.java +++ b/src/net/sourceforge/plantuml/AFileRegular.java @@ -78,12 +78,12 @@ public class AFileRegular implements AFile { return new AParentFolderRegular(file.getParentFile()); } - public String getAbsolutePath() { - return file.getAbsolutePath(); - } - public File getUnderlyingFile() { return file; } + public File getSystemFolder() throws IOException { + return file.getParentFile().getCanonicalFile(); + } + } diff --git a/src/net/sourceforge/plantuml/AFileZipEntry.java b/src/net/sourceforge/plantuml/AFileZipEntry.java index 3269fe1be..fb4dadbc4 100644 --- a/src/net/sourceforge/plantuml/AFileZipEntry.java +++ b/src/net/sourceforge/plantuml/AFileZipEntry.java @@ -113,12 +113,12 @@ public class AFileZipEntry implements AFile { return new AParentFolderZip(zipFile, entry); } - public String getAbsolutePath() { - return zipFile.getAbsolutePath() + "~" + entry; - } - public File getUnderlyingFile() { return zipFile; } + public File getSystemFolder() throws IOException { + return zipFile.getParentFile().getCanonicalFile(); + } + } diff --git a/src/net/sourceforge/plantuml/BlockUml.java b/src/net/sourceforge/plantuml/BlockUml.java index 9daf8de32..4d49c9c7f 100644 --- a/src/net/sourceforge/plantuml/BlockUml.java +++ b/src/net/sourceforge/plantuml/BlockUml.java @@ -49,7 +49,6 @@ import net.sourceforge.plantuml.command.regex.Matcher2; import net.sourceforge.plantuml.core.Diagram; import net.sourceforge.plantuml.error.PSystemErrorPreprocessor; import net.sourceforge.plantuml.preproc.Defines; -import net.sourceforge.plantuml.preproc2.PreprocessorMode; import net.sourceforge.plantuml.preproc2.PreprocessorModeSet; import net.sourceforge.plantuml.tim.TimLoader; import net.sourceforge.plantuml.utils.StartUtils; @@ -98,7 +97,6 @@ public class BlockUml { return result; } - private PreprocessorMode pmode = PreprocessorMode.V1_LEGACY; private boolean preprocessorError; public BlockUml(List strings, Defines defines, ISkinSimple skinParam, PreprocessorModeSet mode) { @@ -108,16 +106,15 @@ public class BlockUml { if (StartUtils.startsWithSymbolAnd("start", s0) == false) { throw new IllegalArgumentException(); } - if (mode != null && mode.getPreprocessorMode() == PreprocessorMode.V2_NEW_TIM) { - this.pmode = mode.getPreprocessorMode(); + if (mode == null) { + this.data = new ArrayList(strings); + } else { final TimLoader timLoader = new TimLoader(mode.getImportedFiles(), defines, mode.getCharset(), (DefinitionsContainer) mode); timLoader.load(strings); this.data = timLoader.getResultList(); this.debug = timLoader.getDebug(); this.preprocessorError = timLoader.isPreprocessorError(); - } else { - this.data = new ArrayList(strings); } } @@ -192,25 +189,14 @@ public class BlockUml { } public List getDefinition(boolean withHeader) { - final List data2 = new ArrayList(); + final List result = new ArrayList(); for (StringLocated s : data) { - data2.add(s.getString()); + result.add(s.getString()); } if (withHeader) { - return Collections.unmodifiableList(data2); + return Collections.unmodifiableList(result); } - return Collections.unmodifiableList(data2.subList(1, data2.size() - 1)); - } - - public List getDefinition2(boolean withHeader) { - final List data2 = new ArrayList(); - for (StringLocated s : debug) { - data2.add(s.getString()); - } - if (withHeader) { - return Collections.unmodifiableList(data2); - } - return Collections.unmodifiableList(data2.subList(1, data2.size() - 1)); + return Collections.unmodifiableList(result.subList(1, result.size() - 1)); } public Defines getLocalDefines() { diff --git a/src/net/sourceforge/plantuml/BlockUmlBuilder.java b/src/net/sourceforge/plantuml/BlockUmlBuilder.java index f199844a9..92319e1ca 100644 --- a/src/net/sourceforge/plantuml/BlockUmlBuilder.java +++ b/src/net/sourceforge/plantuml/BlockUmlBuilder.java @@ -47,42 +47,37 @@ import java.util.Set; import net.sourceforge.plantuml.preproc.Defines; import net.sourceforge.plantuml.preproc.FileWithSuffix; import net.sourceforge.plantuml.preproc.ImportedFiles; -import net.sourceforge.plantuml.preproc.PreprocessorChangeModeReader; import net.sourceforge.plantuml.preproc.ReadLineNumbered; import net.sourceforge.plantuml.preproc.ReadLineReader; import net.sourceforge.plantuml.preproc.UncommentReadLine; import net.sourceforge.plantuml.preproc2.Preprocessor; -import net.sourceforge.plantuml.preproc2.PreprocessorMode; import net.sourceforge.plantuml.utils.StartUtils; public final class BlockUmlBuilder implements DefinitionsContainer { - private PreprocessorMode mode = PreprocessorMode.V2_NEW_TIM; - private final List blocks = new ArrayList(); private Set usedFiles = new HashSet(); - private final UncommentReadLine reader2; + private final UncommentReadLine reader; private final Defines defines; private final ImportedFiles importedFiles; private final String charset; - public BlockUmlBuilder(List config, String charset, Defines defines, Reader reader, File newCurrentDir, + public BlockUmlBuilder(List config, String charset, Defines defines, Reader readerInit, File newCurrentDir, String desc) throws IOException { ReadLineNumbered includer = null; this.defines = defines; this.charset = charset; try { - this.reader2 = new UncommentReadLine(new PreprocessorChangeModeReader(ReadLineReader.create(reader, desc), - this)); + this.reader = new UncommentReadLine(ReadLineReader.create(readerInit, desc)); this.importedFiles = ImportedFiles.createImportedFiles(new AParentFolderRegular(newCurrentDir)); - includer = new Preprocessor(config, reader2, charset, defines, this, importedFiles); + includer = new Preprocessor(config, reader); init(includer); } finally { if (includer != null) { includer.close(); usedFiles = includer.getFilesUsed(); } - reader.close(); + readerInit.close(); } } @@ -102,11 +97,11 @@ public final class BlockUmlBuilder implements DefinitionsContainer { } if (StartUtils.isArobasePauseDiagram(s.getString())) { paused = true; - reader2.setPaused(true); + reader.setPaused(true); } if (StartUtils.isExit(s.getString())) { paused = true; - reader2.setPaused(true); + reader.setPaused(true); } if (current2 != null && paused == false) { current2.add(s); @@ -119,7 +114,7 @@ public final class BlockUmlBuilder implements DefinitionsContainer { if (StartUtils.isArobaseUnpauseDiagram(s.getString())) { paused = false; - reader2.setPaused(false); + reader.setPaused(false); } if (StartUtils.isArobaseEndDiagram(s.getString()) && current2 != null) { if (paused) { @@ -127,7 +122,7 @@ public final class BlockUmlBuilder implements DefinitionsContainer { } blocks.add(new BlockUml(current2, defines.cloneMe(), null, this)); current2 = null; - reader2.setPaused(false); + reader.setPaused(false); } } } @@ -140,33 +135,15 @@ public final class BlockUmlBuilder implements DefinitionsContainer { return Collections.unmodifiableSet(usedFiles); } - public List getDefinition1(String name) { + public List getDefinition(String name) { for (BlockUml block : blocks) { if (block.isStartDef(name)) { - this.defines.importFrom(block.getLocalDefines()); return block.getDefinition(false); } } return Collections.emptyList(); } - public List getDefinition2(String name) { - for (BlockUml block : blocks) { - if (block.isStartDef(name)) { - return block.getDefinition2(false); - } - } - return Collections.emptyList(); - } - - public PreprocessorMode getPreprocessorMode() { - return mode; - } - - public void setPreprocessorMode(PreprocessorMode mode) { - this.mode = mode; - } - public final ImportedFiles getImportedFiles() { return importedFiles; } diff --git a/src/net/sourceforge/plantuml/DefinitionsContainer.java b/src/net/sourceforge/plantuml/DefinitionsContainer.java index 0c9517710..5640191a8 100644 --- a/src/net/sourceforge/plantuml/DefinitionsContainer.java +++ b/src/net/sourceforge/plantuml/DefinitionsContainer.java @@ -41,7 +41,6 @@ import net.sourceforge.plantuml.preproc2.PreprocessorModeSet; public interface DefinitionsContainer extends PreprocessorModeSet { - public List getDefinition1(String name); - public List getDefinition2(String name); + public List getDefinition(String name); } diff --git a/src/net/sourceforge/plantuml/Option.java b/src/net/sourceforge/plantuml/Option.java index 67b5206cc..3e93a3839 100644 --- a/src/net/sourceforge/plantuml/Option.java +++ b/src/net/sourceforge/plantuml/Option.java @@ -470,7 +470,11 @@ public class Option { public Defines getDefaultDefines(File f) { final Defines result = Defines.createWithFileName(f); for (Map.Entry ent : defines.entrySet()) { - result.define(ent.getKey(), Arrays.asList(ent.getValue()), false, null); + String value = ent.getValue(); + if (value == null) { + value = ""; + } + result.define(ent.getKey(), Arrays.asList(value), false, null); } return result; } diff --git a/src/net/sourceforge/plantuml/OptionFlags.java b/src/net/sourceforge/plantuml/OptionFlags.java index 2bd8a100f..4d03d5ef0 100644 --- a/src/net/sourceforge/plantuml/OptionFlags.java +++ b/src/net/sourceforge/plantuml/OptionFlags.java @@ -55,6 +55,10 @@ public class OptionFlags { static public boolean ALLOW_INCLUDE = true; + static public void setAllowIncludeFalse() { + ALLOW_INCLUDE = false; + } + static public void setMaxPixel(int max) { ImageBuilder.setMaxPixel(max); } diff --git a/src/net/sourceforge/plantuml/PSystemBuilder.java b/src/net/sourceforge/plantuml/PSystemBuilder.java index 00a71f953..0ce4e66a5 100644 --- a/src/net/sourceforge/plantuml/PSystemBuilder.java +++ b/src/net/sourceforge/plantuml/PSystemBuilder.java @@ -46,7 +46,6 @@ import net.sourceforge.plantuml.api.PSystemFactory; import net.sourceforge.plantuml.bpm.BpmDiagramFactory; import net.sourceforge.plantuml.classdiagram.ClassDiagramFactory; import net.sourceforge.plantuml.command.regex.RegexConcat; -import net.sourceforge.plantuml.compositediagram.CompositeDiagramFactory; import net.sourceforge.plantuml.core.Diagram; import net.sourceforge.plantuml.core.DiagramType; import net.sourceforge.plantuml.core.UmlSource; diff --git a/src/net/sourceforge/plantuml/SkinParam.java b/src/net/sourceforge/plantuml/SkinParam.java index 4b600278d..f98652eb4 100644 --- a/src/net/sourceforge/plantuml/SkinParam.java +++ b/src/net/sourceforge/plantuml/SkinParam.java @@ -49,7 +49,6 @@ import java.util.Set; import java.util.TreeSet; import net.sourceforge.plantuml.command.BlocLines; -import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.regex.Matcher2; import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.command.regex.Pattern2; diff --git a/src/net/sourceforge/plantuml/StringLocated.java b/src/net/sourceforge/plantuml/StringLocated.java index 76256daa1..26692aa82 100644 --- a/src/net/sourceforge/plantuml/StringLocated.java +++ b/src/net/sourceforge/plantuml/StringLocated.java @@ -56,6 +56,13 @@ final public class StringLocated { return new StringLocated(s + endOfLine, location, preprocessorError); } + public StringLocated mergeEndBackslash(StringLocated next) { + if (StringUtils.endsWithBackslash(s) == false) { + throw new IllegalArgumentException(); + } + return new StringLocated(s.substring(0, s.length() - 1) + next.s, location, preprocessorError); + } + public StringLocated(String s, LineLocation location, String preprocessorError) { if (s == null) { throw new IllegalArgumentException(); diff --git a/src/net/sourceforge/plantuml/activitydiagram/ActivityDiagram.java b/src/net/sourceforge/plantuml/activitydiagram/ActivityDiagram.java index b43ea1915..fbc3b769c 100644 --- a/src/net/sourceforge/plantuml/activitydiagram/ActivityDiagram.java +++ b/src/net/sourceforge/plantuml/activitydiagram/ActivityDiagram.java @@ -40,6 +40,7 @@ import java.util.List; import net.sourceforge.plantuml.Direction; import net.sourceforge.plantuml.ISkinSimple; +import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.UmlDiagramType; import net.sourceforge.plantuml.core.DiagramDescription; import net.sourceforge.plantuml.cucadiagram.Code; @@ -67,7 +68,6 @@ public class ActivityDiagram extends CucaDiagram { public ILeaf getOrCreateLeaf(Ident ident, Code code, LeafType type, USymbol symbol) { checkNotNull(ident); - // final Ident idNewLong = buildLeafIdent(id); return getOrCreateLeafDefault(ident, code, type, symbol); } @@ -77,11 +77,10 @@ public class ActivityDiagram extends CucaDiagram { public IEntity getOrCreate(Ident idNewLong, Code code, Display display, LeafType type) { final IEntity result; - // final Ident idNewLong = buildLeafIdent(id); - if (leafExist(code)) { + final boolean leafExist = this.V1972() ? leafExistSmart(idNewLong) : leafExist(code); + if (leafExist) { result = getOrCreateLeafDefault(idNewLong, code, type, null); if (result.getLeafType() != type) { - // throw new IllegalArgumentException("Already known: " + code + " " + result.getType() + " " + type); return null; } } else { @@ -90,12 +89,20 @@ public class ActivityDiagram extends CucaDiagram { updateLasts(result); return result; } + + @Override + public /*final*/ ILeaf getLeafVerySmart(Ident ident) { + final ILeaf result = super.getLeafVerySmart(ident); + updateLasts(result); + return result; + } + public void startIf(String optionalCodeString) { final String idShort = optionalCodeString == null ? getAutoBranch() : optionalCodeString; final Ident idNewLong = buildLeafIdent(idShort); - final IEntity br = createLeaf(idNewLong, buildCode(idShort), Display.create(""), - LeafType.BRANCH, null); + final Code code = this.V1972() ? idNewLong : buildCode(idShort); + final IEntity br = createLeaf(idNewLong, code, Display.create(""), LeafType.BRANCH, null); currentContext = new ConditionalContext(currentContext, br, Direction.DOWN); } @@ -104,14 +111,16 @@ public class ActivityDiagram extends CucaDiagram { } public ILeaf getStart() { - return (ILeaf) getOrCreate(buildLeafIdent("start"), buildCode("start"), - Display.getWithNewlines("start"), LeafType.CIRCLE_START); + final Ident ident = buildLeafIdent("start"); + final Code code = this.V1972() ? ident : buildCode("start"); + return (ILeaf) getOrCreate(ident, code, Display.getWithNewlines("start"), LeafType.CIRCLE_START); } public ILeaf getEnd(String suppId) { final String tmp = suppId == null ? "end" : "end$" + suppId; - final Code code = buildCode(tmp); - return (ILeaf) getOrCreate(buildLeafIdent(tmp), code, Display.getWithNewlines("end"), LeafType.CIRCLE_END); + final Ident ident = buildLeafIdent(tmp); + final Code code = this.V1972() ? ident : buildCode(tmp); + return (ILeaf) getOrCreate(ident, code, Display.getWithNewlines("end"), LeafType.CIRCLE_END); } private void updateLasts(final IEntity result) { @@ -134,7 +143,6 @@ public class ActivityDiagram extends CucaDiagram { public IEntity createNote(Ident idNewLong, Code code, Display display) { checkNotNull(idNewLong); - // final Ident idNewLong = buildLeafIdent(id); return super.createLeaf(idNewLong, code, display, LeafType.NOTE, null); } @@ -172,8 +180,8 @@ public class ActivityDiagram extends CucaDiagram { public IEntity createInnerActivity() { // Log.println("createInnerActivity A"); final String idShort = "##" + UniqueSequence.getValue(); - final Code code = buildCode(idShort); final Ident idNewLong = buildLeafIdent(idShort); + final Code code = this.V1972() ? idNewLong : buildCode(idShort); gotoGroup(idNewLong, code, Display.getWithNewlines(code), GroupType.INNER_ACTIVITY, getCurrentGroup(), NamespaceStrategy.SINGLE); final IEntity g = getCurrentGroup(); diff --git a/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkActivity.java b/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkActivity.java index ccb477f11..3fdc79122 100644 --- a/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkActivity.java +++ b/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkActivity.java @@ -56,6 +56,7 @@ import net.sourceforge.plantuml.cucadiagram.Code; import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.cucadiagram.GroupType; import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.ILeaf; import net.sourceforge.plantuml.cucadiagram.Ident; import net.sourceforge.plantuml.cucadiagram.LeafType; import net.sourceforge.plantuml.cucadiagram.Link; @@ -206,15 +207,23 @@ public class CommandLinkActivity extends SingleLineCommand2 { } final String idShort = arg.get("CODE" + suf, 0); if (idShort != null) { - final Code code = diagram.buildCode(idShort); if (partition != null) { final Ident idNewLong = diagram.buildLeafIdent(partition); - diagram.gotoGroup(idNewLong, diagram.buildCode(partition), Display.getWithNewlines(partition), - GroupType.PACKAGE, diagram.getRootGroup(), NamespaceStrategy.SINGLE); + final Code codeP = diagram.V1972() ? idNewLong : diagram.buildCode(partition); + diagram.gotoGroup(idNewLong, codeP, Display.getWithNewlines(partition), GroupType.PACKAGE, + diagram.getRootGroup(), NamespaceStrategy.SINGLE); } - final LeafType type = getTypeIfExisting(diagram, code); - final IEntity result = diagram.getOrCreate(diagram.buildLeafIdent(idShort), code, - Display.getWithNewlines(code), type); + final Ident ident = diagram.buildLeafIdent(idShort); + final Code code = diagram.V1972() ? ident : diagram.buildCode(idShort); + final LeafType type = diagram.V1972() ? getTypeIfExistingSmart(diagram, ident) : getTypeIfExisting(diagram, + code); + IEntity result; + if (diagram.V1972()) { + result = diagram.getLeafVerySmart(ident); + if (result == null) + result = diagram.getOrCreate(ident, code, Display.getWithNewlines(code), type); + } else + result = diagram.getOrCreate(ident, code, Display.getWithNewlines(code), type); if (partition != null) { diagram.endGroup(); } @@ -222,21 +231,31 @@ public class CommandLinkActivity extends SingleLineCommand2 { } final String bar = arg.get("BAR" + suf, 0); if (bar != null) { - return diagram.getOrCreate(diagram.buildLeafIdent(bar), diagram.buildCode(bar), - Display.getWithNewlines(bar), LeafType.SYNCHRO_BAR); + final Ident identBar = diagram.buildLeafIdent(bar); + final Code codeBar = diagram.V1972() ? identBar : diagram.buildCode(bar); + if (diagram.V1972()) { + final ILeaf result = diagram.getLeafVerySmart(identBar); + if (result != null) { + return result; + } + } + return diagram.getOrCreate(identBar, codeBar, Display.getWithNewlines(bar), LeafType.SYNCHRO_BAR); } final RegexPartialMatch quoted = arg.get("QUOTED" + suf); if (quoted.get(0) != null) { final String quotedString = quoted.get(1) == null ? quoted.get(0) : quoted.get(1); - final Code quotedCode = diagram.buildCode(quotedString); if (partition != null) { final Ident idNewLong = diagram.buildLeafIdent(partition); - diagram.gotoGroup(idNewLong, diagram.buildCode(partition), Display.getWithNewlines(partition), - GroupType.PACKAGE, diagram.getRootGroup(), NamespaceStrategy.SINGLE); + final Code codeP = diagram.V1972() ? idNewLong : diagram.buildCode(partition); + diagram.gotoGroup(idNewLong, codeP, Display.getWithNewlines(partition), GroupType.PACKAGE, + diagram.getRootGroup(), NamespaceStrategy.SINGLE); } - final LeafType type = getTypeIfExisting(diagram, quotedCode); - final IEntity result = diagram.getOrCreate(diagram.buildLeafIdent(quotedString), quotedCode, - Display.getWithNewlines(quoted.get(0)), type); + final Ident quotedIdent = diagram.buildLeafIdent(quotedString); + final Code quotedCode = diagram.V1972() ? quotedIdent : diagram.buildCode(quotedString); + final LeafType type = diagram.V1972() ? getTypeIfExistingSmart(diagram, quotedIdent) : getTypeIfExisting( + diagram, quotedCode); + final IEntity result = diagram.getOrCreate(quotedIdent, quotedCode, Display.getWithNewlines(quoted.get(0)), + type); if (partition != null) { diagram.endGroup(); } @@ -244,13 +263,15 @@ public class CommandLinkActivity extends SingleLineCommand2 { } final String quoteInvisibleString = arg.get("QUOTED_INVISIBLE" + suf, 0); if (quoteInvisibleString != null) { - final Code quotedInvisible = diagram.buildCode(quoteInvisibleString); if (partition != null) { final Ident idNewLong = diagram.buildLeafIdent(partition); - diagram.gotoGroup(idNewLong, diagram.buildCode(partition), Display.getWithNewlines(partition), - GroupType.PACKAGE, diagram.getRootGroup(), NamespaceStrategy.SINGLE); + final Code codeP = diagram.V1972() ? idNewLong : diagram.buildCode(partition); + diagram.gotoGroup(idNewLong, codeP, Display.getWithNewlines(partition), GroupType.PACKAGE, + diagram.getRootGroup(), NamespaceStrategy.SINGLE); } - final IEntity result = diagram.getOrCreate(diagram.buildLeafIdent(quoteInvisibleString), quotedInvisible, + final Ident identInvisible = diagram.buildLeafIdent(quoteInvisibleString); + final Code quotedInvisible = diagram.V1972() ? identInvisible : diagram.buildCode(quoteInvisibleString); + final IEntity result = diagram.getOrCreate(identInvisible, quotedInvisible, Display.getWithNewlines(quotedInvisible), LeafType.ACTIVITY); if (partition != null) { diagram.endGroup(); @@ -265,9 +286,9 @@ public class CommandLinkActivity extends SingleLineCommand2 { return null; } - private static LeafType getTypeIfExisting(ActivityDiagram system, Ident ident) { - if (system.leafExist(ident)) { - final IEntity ent = system.getLeaf(ident); + private static LeafType getTypeIfExistingSmart(ActivityDiagram system, Ident ident) { + final IEntity ent = system.getLeafSmart(ident); + if (ent != null) { if (ent.getLeafType() == LeafType.BRANCH) { return LeafType.BRANCH; } diff --git a/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkLongActivity.java b/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkLongActivity.java index eb2ecbb15..6b253da61 100644 --- a/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkLongActivity.java +++ b/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkLongActivity.java @@ -168,7 +168,6 @@ public class CommandLinkLongActivity extends CommandMultilines2 final String display = sb.toString(); final String idShort = lineLast.get(1) == null ? display : lineLast.get(1); - final Code code = diagram.buildCode(idShort); String partition = null; if (lineLast.get(3) != null) { @@ -177,11 +176,12 @@ public class CommandLinkLongActivity extends CommandMultilines2 } if (partition != null) { final Ident idNewLong = diagram.buildLeafIdent(partition); - diagram.gotoGroup(idNewLong, diagram.buildCode(partition), - Display.getWithNewlines(partition), GroupType.PACKAGE, null, NamespaceStrategy.SINGLE); + diagram.gotoGroup(idNewLong, diagram.buildCode(partition), Display.getWithNewlines(partition), + GroupType.PACKAGE, null, NamespaceStrategy.SINGLE); } - final IEntity entity2 = diagram.getOrCreate(diagram.buildLeafIdent(idShort), code, - Display.getWithNewlines(display), LeafType.ACTIVITY); + final Ident ident = diagram.buildLeafIdent(idShort); + final Code code = diagram.V1972() ? ident : diagram.buildCode(idShort); + final IEntity entity2 = diagram.getOrCreate(ident, code, Display.getWithNewlines(display), LeafType.ACTIVITY); if (entity2 == null) { return CommandExecutionResult.error("No such entity"); } diff --git a/src/net/sourceforge/plantuml/activitydiagram/command/CommandPartition.java b/src/net/sourceforge/plantuml/activitydiagram/command/CommandPartition.java index 2f8610552..a3b48486a 100644 --- a/src/net/sourceforge/plantuml/activitydiagram/command/CommandPartition.java +++ b/src/net/sourceforge/plantuml/activitydiagram/command/CommandPartition.java @@ -86,10 +86,10 @@ public class CommandPartition extends SingleLineCommand2 { @Override protected CommandExecutionResult executeArg(ActivityDiagram diagram, LineLocation location, RegexResult arg) { final String idShort = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg.get("NAME", 0)); - final Code code = diagram.buildCode(idShort); + final Ident ident = diagram.buildLeafIdent(idShort); + final Code code = diagram.V1972() ? ident : diagram.buildCode(idShort); final IGroup currentPackage = diagram.getCurrentGroup(); - final Ident idNewLong = diagram.buildLeafIdent(idShort); - diagram.gotoGroup(idNewLong, code, Display.getWithNewlines(code), GroupType.PACKAGE, currentPackage, + diagram.gotoGroup(ident, code, Display.getWithNewlines(code), GroupType.PACKAGE, currentPackage, NamespaceStrategy.SINGLE); final IEntity p = diagram.getCurrentGroup(); diff --git a/src/net/sourceforge/plantuml/classdiagram/ClassDiagram.java b/src/net/sourceforge/plantuml/classdiagram/ClassDiagram.java index 2bb260cf3..4e17c1041 100644 --- a/src/net/sourceforge/plantuml/classdiagram/ClassDiagram.java +++ b/src/net/sourceforge/plantuml/classdiagram/ClassDiagram.java @@ -40,6 +40,7 @@ import java.io.OutputStream; import net.sourceforge.plantuml.FileFormatOption; import net.sourceforge.plantuml.ISkinSimple; +import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.UmlDiagramType; import net.sourceforge.plantuml.core.ImageData; import net.sourceforge.plantuml.creole.CreoleMode; @@ -80,6 +81,12 @@ public class ClassDiagram extends AbstractClassOrObjectDiagram { @Override public ILeaf getOrCreateLeaf(Ident ident, Code code, LeafType type, USymbol symbol) { checkNotNull(ident); + if (this.V1972()) { + if (type == null) { + type = LeafType.CLASS; + } + return getOrCreateLeafDefault(ident, code, type, symbol); + } if (type == null) { code = code.eventuallyRemoveStartingAndEndingDoubleQuote("\"([:"); if (getNamespaceSeparator() == null) { @@ -110,6 +117,9 @@ public class ClassDiagram extends AbstractClassOrObjectDiagram { && type != LeafType.LOLLIPOP_HALF && type != LeafType.NOTE) { return super.createLeaf(idNewLong, code, display, type, symbol); } + if (this.V1972()) { + return super.createLeaf(idNewLong, code, display, type, symbol); + } if (getNamespaceSeparator() == null) { return super.createLeaf(idNewLong, code, display, type, symbol); } @@ -121,6 +131,8 @@ public class ClassDiagram extends AbstractClassOrObjectDiagram { } private ILeaf createEntityWithNamespace1972(Ident id, Code fullyCode, Display display, LeafType type, USymbol symbol) { + if (this.V1972()) + throw new UnsupportedOperationException(); checkNotNull(id); final IGroup backupCurrentGroup = getCurrentGroup(); final IGroup group = backupCurrentGroup; diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandAddMethod.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandAddMethod.java index 13710ce9d..663c6c7c0 100644 --- a/src/net/sourceforge/plantuml/classdiagram/command/CommandAddMethod.java +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandAddMethod.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.classdiagram.command; import net.sourceforge.plantuml.LineLocation; +import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.classdiagram.ClassDiagram; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -45,6 +46,7 @@ import net.sourceforge.plantuml.command.regex.RegexLeaf; import net.sourceforge.plantuml.command.regex.RegexResult; import net.sourceforge.plantuml.cucadiagram.Code; import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Ident; import net.sourceforge.plantuml.skin.VisibilityModifier; public class CommandAddMethod extends SingleLineCommand2 { @@ -66,8 +68,17 @@ public class CommandAddMethod extends SingleLineCommand2 { @Override protected CommandExecutionResult executeArg(ClassDiagram diagram, LineLocation location, RegexResult arg) { final String idShort = arg.get("NAME", 0); - final IEntity entity = diagram.getOrCreateLeaf(diagram.buildLeafIdent(idShort), - diagram.buildCode(idShort), null, null); + final Ident ident = diagram.buildLeafIdent(idShort); + final Code code = diagram.V1972() ? ident : diagram.buildCode(idShort); + /* final */IEntity entity; + if (diagram.V1972()) { + entity = diagram.getLeafVerySmart(diagram.cleanIdent(ident)); + if (entity == null) { + entity = diagram.getOrCreateLeaf(ident, code, null, null); + } + } else { + entity = diagram.getOrCreateLeaf(ident, code, null, null); + } final String field = arg.get("DATA", 0); if (field.length() > 0 && VisibilityModifier.isVisibilityCharacter(field)) { diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClass.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClass.java index 464078505..94cd9821a 100644 --- a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClass.java +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClass.java @@ -37,6 +37,7 @@ package net.sourceforge.plantuml.classdiagram.command; import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.LineLocation; +import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.UrlBuilder; @@ -126,22 +127,34 @@ public class CommandCreateClass extends SingleLineCommand2 { @Override protected CommandExecutionResult executeArg(ClassDiagram diagram, LineLocation location, RegexResult arg) { final LeafType type = LeafType.getLeafType(StringUtils.goUpperCase(arg.get("TYPE", 0))); - final String idShort = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg.getLazzy("CODE", 0), "\"([:"); - final Code code = diagram.buildCode(idShort); + final String idShort = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg.getLazzy("CODE", 0), + "\"([:"); final String display = arg.getLazzy("DISPLAY", 0); final String genericOption = arg.getLazzy("DISPLAY", 1); final String generic = genericOption != null ? genericOption : arg.get("GENERIC", 0); final String stereotype = arg.get("STEREO", 0); final ILeaf entity; - if (diagram.leafExist(code)) { - entity = diagram.getOrCreateLeaf(diagram.buildLeafIdent(idShort), code, type, null); - if (entity.muteToType(type, null) == false) { - return CommandExecutionResult.error("Bad name"); + final Ident idNewLong = diagram.buildLeafIdent(idShort); + if (diagram.V1972()) { + if (diagram.leafExistSmart(idNewLong)) { + entity = diagram.getOrCreateLeaf(idNewLong, idNewLong, type, null); + if (entity.muteToType(type, null) == false) { + return CommandExecutionResult.error("Bad name"); + } + } else { + entity = diagram.createLeaf(idNewLong, idNewLong, Display.getWithNewlines(display), type, null); } } else { - final Ident idNewLong = diagram.buildLeafIdent(idShort); - entity = diagram.createLeaf(idNewLong, code, Display.getWithNewlines(display), type, null); + final Code code = diagram.buildCode(idShort); + if (diagram.leafExist(code)) { + entity = diagram.getOrCreateLeaf(idNewLong, code, type, null); + if (entity.muteToType(type, null) == false) { + return CommandExecutionResult.error("Bad name"); + } + } else { + entity = diagram.createLeaf(idNewLong, code, Display.getWithNewlines(display), type, null); + } } if (stereotype != null) { entity.setStereotype(new Stereotype(stereotype, diagram.getSkinParam().getCircledCharacterRadius(), diagram diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClassMultilines.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClassMultilines.java index 99339a498..e34aff45a 100644 --- a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClassMultilines.java +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClassMultilines.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.classdiagram.command; import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.StringLocated; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.Url; @@ -207,8 +208,9 @@ public class CommandCreateClassMultilines extends CommandMultilines2 } final String idShort = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(codeRaw); - final Code code = diagram.buildCode(idShort); + final Ident ident = diagram.buildLeafIdent(idShort); + final Code code = diagram.V1972() ? ident : diagram.buildCode(idShort); String display = displayRaw; if (display == null) { display = code.getName(); } display = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(display); final String stereotype = arg.getLazzy("STEREOTYPE", 0); - final IEntity entity = diagram.getOrCreateLeaf(diagram.buildLeafIdent(idShort), code, type, usymbol); + final IEntity entity = diagram.getOrCreateLeaf(ident, code, type, usymbol); entity.setDisplay(Display.getWithNewlines(display)); entity.setUSymbol(usymbol); if (stereotype != null) { diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandDiamondAssociation.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandDiamondAssociation.java index 771e1ab43..92a52e983 100644 --- a/src/net/sourceforge/plantuml/classdiagram/command/CommandDiamondAssociation.java +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandDiamondAssociation.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.classdiagram.command; import net.sourceforge.plantuml.LineLocation; +import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.classdiagram.ClassDiagram; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -65,12 +66,13 @@ public class CommandDiamondAssociation extends SingleLineCommand2 @Override protected CommandExecutionResult executeArg(ClassDiagram diagram, LineLocation location, RegexResult arg) { final String idShort = arg.get("CODE", 0); - final Code code = diagram.buildCode(idShort); - if (diagram.leafExist(code)) { + final Ident ident = diagram.buildLeafIdent(idShort); + final Code code = diagram.V1972() ? ident : diagram.buildCode(idShort); + final boolean leafExist = diagram.V1972() ? diagram.leafExistSmart(ident) : diagram.leafExist(code); + if (leafExist) { return CommandExecutionResult.error("Already existing : " + code.getName()); } - final Ident idNewLong = diagram.buildLeafIdent(idShort); - diagram.createLeaf(idNewLong, code, Display.NULL, LeafType.ASSOCIATION, null); + diagram.createLeaf(ident, code, Display.NULL, LeafType.ASSOCIATION, null); return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandHideShowByGender.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandHideShowByGender.java index da701fb08..41ae82134 100644 --- a/src/net/sourceforge/plantuml/classdiagram/command/CommandHideShowByGender.java +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandHideShowByGender.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.classdiagram.command; import net.sourceforge.plantuml.LineLocation; +import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.UmlDiagram; import net.sourceforge.plantuml.command.CommandExecutionResult; @@ -51,6 +52,7 @@ import net.sourceforge.plantuml.cucadiagram.EntityGenderUtils; import net.sourceforge.plantuml.cucadiagram.EntityPortion; import net.sourceforge.plantuml.cucadiagram.EntityUtils; import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Ident; import net.sourceforge.plantuml.cucadiagram.LeafType; import net.sourceforge.plantuml.descdiagram.DescriptionDiagram; import net.sourceforge.plantuml.objectdiagram.AbstractClassOrObjectDiagram; @@ -136,8 +138,8 @@ public class CommandHideShowByGender extends SingleLineCommand2 { } else if (arg1.startsWith("<<")) { gender = EntityGenderUtils.byStereotype(arg1); } else { - final IEntity entity = diagram.getOrCreateLeaf(diagram.buildLeafIdent(arg1), - diagram.buildCode(arg1), null, null); + final IEntity entity = diagram.getOrCreateLeaf(diagram.buildLeafIdent(arg1), diagram.buildCode(arg1), null, + null); gender = EntityGenderUtils.byEntityAlone(entity); } @@ -168,8 +170,9 @@ public class CommandHideShowByGender extends SingleLineCommand2 { } else if (arg1.startsWith("<<")) { gender = EntityGenderUtils.byStereotype(arg1); } else { - final IEntity entity = diagram.getOrCreateLeaf(diagram.buildLeafIdent(arg1), - diagram.buildCode(arg1), null, null); + final Ident ident = diagram.buildLeafIdent(arg1); + final Code code = diagram.V1972() ? ident : diagram.buildCode(arg1); + final IEntity entity = diagram.getOrCreateLeaf(ident, code, null, null); gender = EntityGenderUtils.byEntityAlone(entity); } if (gender != null) { diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandLinkClass.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandLinkClass.java index abff86ba5..e3bb06c68 100644 --- a/src/net/sourceforge/plantuml/classdiagram/command/CommandLinkClass.java +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandLinkClass.java @@ -37,6 +37,7 @@ package net.sourceforge.plantuml.classdiagram.command; import net.sourceforge.plantuml.Direction; import net.sourceforge.plantuml.LineLocation; +import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.UmlDiagramType; import net.sourceforge.plantuml.Url; @@ -145,10 +146,12 @@ final public class CommandLinkClass extends SingleLineCommand2 { RegexLeaf.start(), // new RegexLeaf("set"), // RegexLeaf.spaceOneOrMore(), // - new RegexLeaf("namespaceseparator"), // + new RegexOr( // + new RegexLeaf("separator"), // + new RegexLeaf("namespaceseparator")), // RegexLeaf.spaceOneOrMore(), // new RegexLeaf("SEPARATOR", "(\\S+)"), RegexLeaf.end()); // } diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandStereotype.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandStereotype.java index 5064d9c50..1124d3985 100644 --- a/src/net/sourceforge/plantuml/classdiagram/command/CommandStereotype.java +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandStereotype.java @@ -37,6 +37,7 @@ package net.sourceforge.plantuml.classdiagram.command; import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.LineLocation; +import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.classdiagram.ClassDiagram; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -46,6 +47,7 @@ import net.sourceforge.plantuml.command.regex.RegexLeaf; import net.sourceforge.plantuml.command.regex.RegexResult; import net.sourceforge.plantuml.cucadiagram.Code; import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Ident; import net.sourceforge.plantuml.cucadiagram.Stereotype; public class CommandStereotype extends SingleLineCommand2 { @@ -65,9 +67,10 @@ public class CommandStereotype extends SingleLineCommand2 { @Override protected CommandExecutionResult executeArg(ClassDiagram diagram, LineLocation location, RegexResult arg) { final String name = arg.get("NAME", 0); - final Code code = diagram.buildCode(name); + final Ident ident = diagram.buildLeafIdent(name); + final Code code = diagram.V1972() ? ident : diagram.buildCode(name); final String stereotype = arg.get("STEREO", 0); - final IEntity entity = diagram.getOrCreateLeaf(diagram.buildLeafIdent(name), code, null, null); + final IEntity entity = diagram.getOrCreateLeaf(ident, code, null, null); entity.setStereotype(new Stereotype(stereotype, diagram.getSkinParam().getCircledCharacterRadius(), diagram .getSkinParam().getFont(null, false, FontParam.CIRCLED_CHARACTER), diagram.getSkinParam() .getIHtmlColorSet())); diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandUrl.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandUrl.java index f3c3c8449..c753872fb 100644 --- a/src/net/sourceforge/plantuml/classdiagram/command/CommandUrl.java +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandUrl.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.classdiagram.command; import net.sourceforge.plantuml.LineLocation; +import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.UrlBuilder; import net.sourceforge.plantuml.UrlBuilder.ModeUrl; @@ -49,6 +50,7 @@ import net.sourceforge.plantuml.command.regex.RegexOptional; import net.sourceforge.plantuml.command.regex.RegexResult; import net.sourceforge.plantuml.cucadiagram.Code; import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Ident; public class CommandUrl extends SingleLineCommand2 { @@ -73,13 +75,15 @@ public class CommandUrl extends SingleLineCommand2 { @Override protected CommandExecutionResult executeArg(AbstractEntityDiagram diagram, LineLocation location, RegexResult arg) { final String idShort = arg.get("CODE", 0); - final Code code = diagram.buildCode(idShort); + final Ident ident = diagram.buildLeafIdent(idShort); + final Code code = diagram.V1972() ? ident : diagram.buildCode(idShort); final String urlString = arg.get("URL", 0); final IEntity entity; - if (diagram.leafExist(code)) { - entity = diagram.getOrCreateLeaf(diagram.buildLeafIdent(idShort), code, null, null); - } else if (diagram.isGroup(code)) { - entity = diagram.getGroup(code); + final boolean leafExist = diagram.V1972() ? diagram.leafExistSmart(ident) : diagram.leafExist(code); + if (leafExist) { + entity = diagram.getOrCreateLeaf(ident, code, null, null); + } else if (diagram.V1972() ? diagram.isGroupStrict(ident) : diagram.isGroup(code)) { + entity = diagram.V1972() ? diagram.getGroupStrict(ident) : diagram.getGroup(code); } else { return CommandExecutionResult.error(code + " does not exist"); } diff --git a/src/net/sourceforge/plantuml/command/CommandNamespace.java b/src/net/sourceforge/plantuml/command/CommandNamespace.java index c539bf7f2..7054878aa 100644 --- a/src/net/sourceforge/plantuml/command/CommandNamespace.java +++ b/src/net/sourceforge/plantuml/command/CommandNamespace.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.command; import net.sourceforge.plantuml.LineLocation; +import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.UrlBuilder; import net.sourceforge.plantuml.UrlBuilder.ModeUrl; @@ -79,10 +80,19 @@ public class CommandNamespace extends SingleLineCommand2 { @Override protected CommandExecutionResult executeArg(ClassDiagram diagram, LineLocation location, RegexResult arg) { final String idShort = arg.get("NAME", 0); - final Code code = diagram.buildCode(idShort); - final IGroup currentPackage = diagram.getCurrentGroup(); - final Display display = Display.getWithNewlines(code); + final Code code; + final IGroup currentPackage; + final Display display; final Ident idNewLong = diagram.buildLeafIdent(idShort); + if (diagram.V1972()) { + code = null; + currentPackage = null; + display = Display.getWithNewlines(idNewLong.getName()); + } else { + code = diagram.buildCode(idShort); + currentPackage = diagram.getCurrentGroup(); + display = Display.getWithNewlines(code); + } diagram.gotoGroup(idNewLong, code, display, GroupType.PACKAGE, currentPackage, NamespaceStrategy.MULTIPLE); final IEntity p = diagram.getCurrentGroup(); final String stereotype = arg.get("STEREOTYPE", 0); diff --git a/src/net/sourceforge/plantuml/command/CommandNamespace2.java b/src/net/sourceforge/plantuml/command/CommandNamespace2.java index 09724b5c2..7536f7e80 100644 --- a/src/net/sourceforge/plantuml/command/CommandNamespace2.java +++ b/src/net/sourceforge/plantuml/command/CommandNamespace2.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.command; import net.sourceforge.plantuml.LineLocation; +import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.UrlBuilder; import net.sourceforge.plantuml.UrlBuilder.ModeUrl; @@ -87,12 +88,12 @@ public class CommandNamespace2 extends SingleLineCommand2 { @Override protected CommandExecutionResult executeArg(ClassDiagram diagram, LineLocation location, RegexResult arg) { final String idShort = arg.get("NAME", 0); - final Code code = diagram.buildCode(idShort); + final Ident ident = diagram.buildLeafIdent(idShort); + final Code code = diagram.V1972() ? ident : diagram.buildCode(idShort); final IGroup currentPackage = diagram.getCurrentGroup(); final String disp = arg.getLazzy("DISPLAY", 0); final Display display = Display.getWithNewlines(disp); - final Ident idNewLong = diagram.buildLeafIdent(idShort); - diagram.gotoGroup(idNewLong, code, display, GroupType.PACKAGE, currentPackage, NamespaceStrategy.MULTIPLE); + diagram.gotoGroup(ident, code, display, GroupType.PACKAGE, currentPackage, NamespaceStrategy.MULTIPLE); final IEntity p = diagram.getCurrentGroup(); final String stereotype = arg.get("STEREOTYPE", 0); if (stereotype != null) { diff --git a/src/net/sourceforge/plantuml/command/CommandNamespaceEmpty.java b/src/net/sourceforge/plantuml/command/CommandNamespaceEmpty.java index dc3fd99ae..e4c30483e 100644 --- a/src/net/sourceforge/plantuml/command/CommandNamespaceEmpty.java +++ b/src/net/sourceforge/plantuml/command/CommandNamespaceEmpty.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.command; import net.sourceforge.plantuml.LineLocation; +import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.UrlBuilder; import net.sourceforge.plantuml.UrlBuilder.ModeUrl; @@ -82,10 +83,10 @@ public class CommandNamespaceEmpty extends SingleLineCommand2 { @Override protected CommandExecutionResult executeArg(ClassDiagram diagram, LineLocation location, RegexResult arg) { final String idShort = arg.get("NAME", 0); - final Code code = diagram.buildCode(idShort); + final Ident idNewLong = diagram.buildLeafIdent(idShort); + final Code code = diagram.V1972() ? idNewLong : diagram.buildCode(idShort); final IGroup currentPackage = diagram.getCurrentGroup(); final Display display = Display.getWithNewlines(code); - final Ident idNewLong = diagram.buildLeafIdent(idShort); diagram.gotoGroup(idNewLong, code, display, GroupType.PACKAGE, currentPackage, NamespaceStrategy.MULTIPLE); final IEntity p = diagram.getCurrentGroup(); final String stereotype = arg.get("STEREOTYPE", 0); diff --git a/src/net/sourceforge/plantuml/command/CommandPackage.java b/src/net/sourceforge/plantuml/command/CommandPackage.java index ca75d8daa..592dc31fe 100644 --- a/src/net/sourceforge/plantuml/command/CommandPackage.java +++ b/src/net/sourceforge/plantuml/command/CommandPackage.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.command; import net.sourceforge.plantuml.LineLocation; +import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.UrlBuilder; @@ -102,28 +103,30 @@ public class CommandPackage extends SingleLineCommand2 { @Override protected CommandExecutionResult executeArg(AbstractEntityDiagram diagram, LineLocation location, RegexResult arg) { - final Code code; final String idShort; - final String display; + /* final */String display; final String name = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg.get("NAME", 0)); + boolean override1972 = false; if (arg.get("AS", 0) == null) { if (name.length() == 0) { idShort = "##" + UniqueSequence.getValue(); - code = diagram.buildCode(idShort); display = null; } else { idShort = name; - code = diagram.buildCode(idShort); - display = code.getName(); + display = idShort; + override1972 = true; } } else { display = name; idShort = arg.get("AS", 0); - code = diagram.buildCode(idShort); } final IGroup currentPackage = diagram.getCurrentGroup(); - final Ident idNewLong = diagram.buildLeafIdentSpecial(idShort); - diagram.gotoGroup(idNewLong, code, Display.getWithNewlines(display), GroupType.PACKAGE, currentPackage, + // final Ident ident = diagram.buildLeafIdentSpecial(idShort); + final Ident ident = diagram.buildLeafIdent(idShort); + final Code code = diagram.V1972() ? ident : diagram.buildCode(idShort); + if (diagram.V1972() && override1972) + display = ident.getLast(); + diagram.gotoGroup(ident, code, Display.getWithNewlines(display), GroupType.PACKAGE, currentPackage, NamespaceStrategy.SINGLE); final IEntity p = diagram.getCurrentGroup(); final String stereotype = arg.get("STEREOTYPE", 0); diff --git a/src/net/sourceforge/plantuml/command/CommandPackageEmpty.java b/src/net/sourceforge/plantuml/command/CommandPackageEmpty.java index 3e90a4337..cb8dfca99 100644 --- a/src/net/sourceforge/plantuml/command/CommandPackageEmpty.java +++ b/src/net/sourceforge/plantuml/command/CommandPackageEmpty.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.command; import net.sourceforge.plantuml.LineLocation; +import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.classdiagram.AbstractEntityDiagram; import net.sourceforge.plantuml.command.regex.IRegex; @@ -82,27 +83,24 @@ public class CommandPackageEmpty extends SingleLineCommand2 { new RegexLeaf("sprite"), // RegexLeaf.spaceOneOrMore(), // new RegexLeaf("\\$?"), // - new RegexLeaf("NAME", "([\\p{L}0-9_]+)"), // + new RegexLeaf("NAME", "([-\\p{L}0-9_]+)"), // RegexLeaf.spaceOneOrMore(), // new RegexLeaf("FILE", "(.*)"), RegexLeaf.end()); } diff --git a/src/net/sourceforge/plantuml/command/note/FactoryNoteActivityCommand.java b/src/net/sourceforge/plantuml/command/note/FactoryNoteActivityCommand.java index f6a1f098f..ac2e109b9 100644 --- a/src/net/sourceforge/plantuml/command/note/FactoryNoteActivityCommand.java +++ b/src/net/sourceforge/plantuml/command/note/FactoryNoteActivityCommand.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.command.note; import net.sourceforge.plantuml.LineLocation; +import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.UrlBuilder; @@ -118,10 +119,10 @@ public final class FactoryNoteActivityCommand implements SingleMultiFactoryComma // final String s = StringUtils.getMergedLines(strings); - final String code = UniqueSequence.getString("GMN"); - final Ident idNewLong = diagram.buildLeafIdent(code); - final IEntity note = diagram.createLeaf(idNewLong, diagram.buildCode(code), - strings, LeafType.NOTE, null); + final String codeString = UniqueSequence.getString("GMN"); + final Ident ident = diagram.buildLeafIdent(codeString); + final Code code = diagram.V1972() ? ident : diagram.buildCode(codeString); + final IEntity note = diagram.createLeaf(ident, code, strings, LeafType.NOTE, null); if (url != null) { note.addUrl(url); } @@ -137,9 +138,9 @@ public final class FactoryNoteActivityCommand implements SingleMultiFactoryComma protected CommandExecutionResult executeArg(final ActivityDiagram diagram, LineLocation location, RegexResult arg) { final String tmp = UniqueSequence.getString("GN"); - final Ident idNewLong = diagram.buildLeafIdent(tmp); - final IEntity note = diagram.createNote(idNewLong, diagram.buildCode(tmp), - Display.getWithNewlines(arg.get("NOTE", 0))); + final Ident ident = diagram.buildLeafIdent(tmp); + final Code code = diagram.V1972() ? ident : diagram.buildCode(tmp); + final IEntity note = diagram.createNote(ident, code, Display.getWithNewlines(arg.get("NOTE", 0))); return executeInternal(diagram, arg, note); } }; diff --git a/src/net/sourceforge/plantuml/command/note/FactoryNoteCommand.java b/src/net/sourceforge/plantuml/command/note/FactoryNoteCommand.java index 135829d53..1791f0f74 100644 --- a/src/net/sourceforge/plantuml/command/note/FactoryNoteCommand.java +++ b/src/net/sourceforge/plantuml/command/note/FactoryNoteCommand.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.command.note; import net.sourceforge.plantuml.LineLocation; +import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.classdiagram.AbstractEntityDiagram; import net.sourceforge.plantuml.classdiagram.command.CommandCreateClassMultilines; import net.sourceforge.plantuml.command.BlocLines; @@ -127,12 +128,13 @@ public final class FactoryNoteCommand implements SingleMultiFactoryCommand hides2 = new ArrayList(); private final List removed = new ArrayList(); - protected final EntityFactory entityFactory = new EntityFactory(hides2, removed); + protected final EntityFactory entityFactory = new EntityFactory(hides2, removed, this); private IGroup currentGroup = entityFactory.getRootGroup(); private List stacks2 = new ArrayList(); private List stacks = new ArrayList(); @@ -82,6 +87,10 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy, public abstract IEntity getOrCreateLeaf(Ident ident, Code code, LeafType type, USymbol symbol); + public Ident cleanIdent(Ident ident) { + return ident; + } + public CucaDiagram(ISkinSimple orig) { super(orig); this.stacks2.add(Ident.empty()); @@ -131,7 +140,11 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy, if (type == null) { throw new IllegalArgumentException(); } - ILeaf result = entityFactory.getLeaf(code); + ILeaf result; + if (this.V1972()) + result = entityFactory.getLeafStrict(idNewLong); + else + result = entityFactory.getLeaf(code); if (result == null) { result = createLeafInternal(idNewLong, code, Display.getWithNewlines(code), type, symbol); result.setUSymbol(symbol); @@ -147,17 +160,18 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy, public ILeaf createLeaf(Ident idNewLong, Code code, Display display, LeafType type, USymbol symbol) { checkNotNull(idNewLong); - if (entityFactory.getLeaf(idNewLong) != null) { + if (entityFactory.getLeafStrict(idNewLong) != null) { return null; // throw new IllegalArgumentException("Already known: " + code); } return createLeafInternal(idNewLong, code, display, type, symbol); } - final protected ILeaf createLeafInternal(Ident newIdent, Code code, Display display, LeafType type, USymbol symbol) { + final protected ILeaf createLeafInternal(Ident newIdent, Code code, Display display, LeafType type, + USymbol symbol) { checkNotNull(newIdent); if (Display.isNull(display)) { - display = Display.getWithNewlines(code); + display = Display.getWithNewlines(code).withCreoleMode(CreoleMode.SIMPLE_LINE); } final ILeaf leaf = entityFactory.createLeaf(newIdent, code, display, type, getCurrentGroup(), getHides(), getNamespaceSeparator()); @@ -171,17 +185,24 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy, return getLastID().add(id, namespaceSeparator); } - final public Code buildCode(String s) { - return CodeImpl.of(s); + final public Ident buildLeafIdentSpecial(String id) { + return buildFullyQualified(id); + // if (namespaceSeparator != null) { + // if (id.contains(namespaceSeparator)) { + // return Ident.empty().add(id, namespaceSeparator); + // } + // } + // return getLastID().add(id, namespaceSeparator); } - final public Ident buildLeafIdentSpecial(String id) { - if (namespaceSeparator != null) { - if (id.contains(namespaceSeparator)) { - return Ident.empty().add(id, namespaceSeparator); - } - } - return getLastID().add(id, namespaceSeparator); + final public Ident buildFullyQualified(String id) { + return entityFactory.buildFullyQualified(getLastID(), Ident.empty().add(id, namespaceSeparator)); + } + + final public Code buildCode(String s) { + if (this.V1972()) + throw new UnsupportedOperationException(); + return CodeImpl.of(s); } protected final void checkNotNull(Object id) { @@ -191,14 +212,22 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy, } public boolean leafExist(Code code) { + if (this.V1972()) + throw new UnsupportedOperationException(); return entityFactory.getLeaf(code) != null; } - public boolean leafExist(Ident ident) { - return entityFactory.getLeaf(ident) != null; + public boolean leafExistSmart(Ident ident) { + return entityFactory.getLeafSmart(ident) != null; + } + + public boolean leafExistStrict(Ident ident) { + return entityFactory.getLeafStrict(ident) != null; } final public Collection getChildrenGroups(IGroup parent) { + if (this.V1972()) + return getChildrenGroupsIdent1972(parent); final Collection result = new ArrayList(); for (IGroup gg : getGroups(false)) { if (gg.getParentContainer() == parent) { @@ -208,8 +237,23 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy, return Collections.unmodifiableCollection(result); } + private Collection getChildrenGroupsIdent1972(IGroup parent) { + final Collection result = new ArrayList(); + for (IGroup gg : entityFactory.groups2()) { + if (gg.getIdent().parent().equals(parent.getIdent())) { + result.add(gg); + } + } + return Collections.unmodifiableCollection(result); + } + final public void gotoGroup(Ident ident, Code code, Display display, GroupType type, IGroup parent, NamespaceStrategy strategy) { + if (this.V1972()) { + gotoGroupInternalWithNamespace(ident, code, display, code, type, parent); + return; + + } if (strategy == NamespaceStrategy.MULTIPLE) { if (getNamespaceSeparator() != null) { code = getFullyQualifiedCode1972(code); @@ -243,6 +287,11 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy, GroupType type, IGroup parent) { this.stacks.add(currentGroup); this.stacks2.add(idNewLong); + + if (this.V1972()) { + gotoGroupInternal(idNewLong, code, display, namespaceNew, type, parent); + return; + } if (getNamespaceSeparator() == null) { gotoGroupInternal(idNewLong, code, display, namespaceNew, type, parent); return; @@ -285,12 +334,17 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy, private void gotoGroupInternal(Ident idNewLong, final Code code, Display display, final Code namespace, GroupType type, IGroup parent) { + if (this.V1972()) { + gotoGroupInternal1972(idNewLong, code, display, namespace, type, parent); + return; + } + IGroup result = entityFactory.getGroup(code); if (result != null) { currentGroup = result; return; } - if (entityFactory.getLeaf(idNewLong) != null) { + if (entityFactory.getLeafStrict(idNewLong) != null) { result = entityFactory.muteToGroup(code.getName(), namespace, type, parent); result.setDisplay(display); } else { @@ -301,6 +355,30 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy, currentGroup = result; } + private void gotoGroupInternal1972(Ident idNewLong, final Code code, Display display, final Code namespace, + GroupType type, IGroup parent) { + IGroup result = entityFactory.getGroupStrict(idNewLong); + if (result != null) { + currentGroup = result; + return; + } + final boolean mutation; + if (namespaceSeparator == null) + mutation = entityFactory.getLeafVerySmart(idNewLong) != null; + else + mutation = entityFactory.getLeafStrict(idNewLong) != null; + if (mutation) { + result = entityFactory.muteToGroup1972(idNewLong, namespace, type, parent); + result.setDisplay(display); + } else { + result = entityFactory.createGroup(idNewLong, code, display, namespace, type, parent, getHides(), + getNamespaceSeparator()); + } + entityFactory.addGroup(result); + currentGroup = result; + stacks2.set(stacks2.size() - 1, result.getIdent()); + } + final protected void gotoGroupExternal(Ident newIdLong, final Code code, Display display, final Code namespace, GroupType type, IGroup parent) { IGroup result = entityFactory.getGroup(code); @@ -359,12 +437,44 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy, return p; } + public final IGroup getGroupStrict(Ident ident) { + if (!this.V1972()) + throw new UnsupportedOperationException(); + final IGroup p = entityFactory.getGroupStrict(ident); + if (p == null) { + throw new IllegalArgumentException(); + // return null; + } + return p; + } + + public final IGroup getGroupVerySmart(Ident ident) { + if (!this.V1972()) + throw new UnsupportedOperationException(); + final IGroup p = entityFactory.getGroupVerySmart(ident); + if (p == null) { + throw new IllegalArgumentException(); + // return null; + } + return p; + } + public final boolean isGroup(Code code) { + if (this.V1972()) + return isGroupStrict((Ident) code); return leafExist(code) == false && entityFactory.getGroup(code) != null; } - public final boolean isGroup(Ident ident) { - return leafExist(ident) == false && entityFactory.getGroup(ident) != null; + public final boolean isGroupStrict(Ident ident) { + if (!this.V1972()) + throw new UnsupportedOperationException(); + return leafExistStrict(ident) == false && entityFactory.getGroupStrict(ident) != null; + } + + public final boolean isGroupVerySmart(Ident ident) { + if (!this.V1972()) + throw new UnsupportedOperationException(); + return leafExistSmart(ident) == false && entityFactory.getGroupVerySmart(ident) != null; } public final Collection getGroups(boolean withRootGroup) { @@ -393,8 +503,16 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy, return entityFactory.getLeaf(code); } - public final ILeaf getLeaf(Ident ident) { - return entityFactory.getLeaf(ident); + public final ILeaf getLeafStrict(Ident ident) { + return entityFactory.getLeafStrict(ident); + } + + public final ILeaf getLeafSmart(Ident ident) { + return entityFactory.getLeafSmart(ident); + } + + public /* final */ ILeaf getLeafVerySmart(Ident ident) { + return entityFactory.getLeafVerySmart(ident); } final public void addLink(Link link) { @@ -488,8 +606,9 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy, throw new UnsupportedOperationException(); } - final CucaDiagramFileMaker maker = this.isUseJDot() ? new CucaDiagramFileMakerJDot(this, - fileFormatOption.getDefaultStringBounder()) : new CucaDiagramFileMakerSvek(this); + final CucaDiagramFileMaker maker = this.isUseJDot() + ? new CucaDiagramFileMakerJDot(this, fileFormatOption.getDefaultStringBounder()) + : new CucaDiagramFileMakerSvek(this); final ImageData result = maker.createFile(os, getDotStrings(), fileFormatOption); if (result == null) { diff --git a/src/net/sourceforge/plantuml/cucadiagram/Display.java b/src/net/sourceforge/plantuml/cucadiagram/Display.java index 59e723e1e..fb34f9a41 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/Display.java +++ b/src/net/sourceforge/plantuml/cucadiagram/Display.java @@ -66,7 +66,6 @@ import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.HorizontalAlignment; import net.sourceforge.plantuml.graphic.HtmlColor; import net.sourceforge.plantuml.graphic.TextBlock; -import net.sourceforge.plantuml.graphic.TextBlockSimple; import net.sourceforge.plantuml.graphic.TextBlockSprited; import net.sourceforge.plantuml.graphic.TextBlockUtils; import net.sourceforge.plantuml.graphic.VerticalAlignment; @@ -467,45 +466,30 @@ public class Display implements Iterable { if (getNaturalHorizontalAlignment() != null) { horizontalAlignment = getNaturalHorizontalAlignment(); } + final FontConfiguration stereotypeConfiguration = fontConfiguration.forceFont(fontForStereotype, + htmlColorForStereotype); if (size() > 0) { if (get(0) instanceof Stereotype) { return createStereotype(fontConfiguration, horizontalAlignment, spriteContainer, 0, fontForStereotype, - htmlColorForStereotype); + htmlColorForStereotype, maxMessageSize, creoleMode); } if (get(size() - 1) instanceof Stereotype) { return createStereotype(fontConfiguration, horizontalAlignment, spriteContainer, size() - 1, - fontForStereotype, htmlColorForStereotype); + fontForStereotype, htmlColorForStereotype, maxMessageSize, creoleMode); } if (get(0) instanceof MessageNumber) { - return createMessageNumber(fontConfiguration, horizontalAlignment, spriteContainer, maxMessageSize); + return createMessageNumber(fontConfiguration, horizontalAlignment, spriteContainer, maxMessageSize, + stereotypeConfiguration); } } - return getCreole(fontConfiguration, horizontalAlignment, spriteContainer, maxMessageSize, creoleMode); - } - - private TextBlock getCreole(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment, - ISkinSimple spriteContainer, LineBreakStrategy maxMessageSize, CreoleMode creoleMode) { - final Sheet sheet = new CreoleParser(fontConfiguration, horizontalAlignment, spriteContainer, creoleMode) - .createSheet(this); - final SheetBlock1 sheetBlock1 = new SheetBlock1(sheet, maxMessageSize, spriteContainer == null ? 0 - : spriteContainer.getPadding()); - return new SheetBlock2(sheetBlock1, sheetBlock1, new UStroke(1.5)); - } - - private TextBlock createMessageNumber(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment, - ISkinSimple spriteContainer, LineBreakStrategy maxMessageSize) { - TextBlock tb1 = subList(0, 1).getCreole(fontConfiguration, horizontalAlignment, spriteContainer, - maxMessageSize, CreoleMode.FULL); - tb1 = TextBlockUtils.withMargin(tb1, 0, 4, 0, 0); - final TextBlock tb2 = subList(1, size()).getCreole(fontConfiguration, horizontalAlignment, spriteContainer, - maxMessageSize, CreoleMode.FULL); - return TextBlockUtils.mergeLR(tb1, tb2, VerticalAlignment.CENTER); - + return getCreole(fontConfiguration, horizontalAlignment, spriteContainer, maxMessageSize, creoleMode, + stereotypeConfiguration); } private TextBlock createStereotype(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment, - SpriteContainer spriteContainer, int position, UFont fontForStereotype, HtmlColor htmlColorForStereotype) { + SpriteContainer spriteContainer, int position, UFont fontForStereotype, HtmlColor htmlColorForStereotype, + LineBreakStrategy maxMessageSize, CreoleMode creoleMode) { final Stereotype stereotype = (Stereotype) get(position); TextBlock circledCharacter = null; if (stereotype.isSpotted()) { @@ -514,15 +498,35 @@ public class Display implements Iterable { } else { circledCharacter = stereotype.getSprite(spriteContainer); } - if (circledCharacter != null) { - if (stereotype.getLabel(Guillemet.DOUBLE_COMPARATOR) == null) { - return new TextBlockSprited(circledCharacter, this.subList(1, this.size()), fontConfiguration, - horizontalAlignment, spriteContainer); - } - return new TextBlockSprited(circledCharacter, this, fontConfiguration, horizontalAlignment, spriteContainer); - } - return new TextBlockSimple(this, fontConfiguration, horizontalAlignment, spriteContainer, 0, fontForStereotype, + final FontConfiguration stereotypeConfiguration = fontConfiguration.forceFont(fontForStereotype, htmlColorForStereotype); + final TextBlock result = getCreole(fontConfiguration, horizontalAlignment, (ISkinSimple) spriteContainer, + maxMessageSize, creoleMode, stereotypeConfiguration); + if (circledCharacter != null) { + return new TextBlockSprited(circledCharacter, result); + } + return result; + } + + private TextBlock getCreole(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment, + ISkinSimple spriteContainer, LineBreakStrategy maxMessageSize, CreoleMode creoleMode, + FontConfiguration stereotypeConfiguration) { + final Sheet sheet = new CreoleParser(fontConfiguration, horizontalAlignment, spriteContainer, creoleMode, + stereotypeConfiguration).createSheet(this); + final SheetBlock1 sheetBlock1 = new SheetBlock1(sheet, maxMessageSize, spriteContainer == null ? 0 + : spriteContainer.getPadding()); + return new SheetBlock2(sheetBlock1, sheetBlock1, new UStroke(1.5)); + } + + private TextBlock createMessageNumber(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment, + ISkinSimple spriteContainer, LineBreakStrategy maxMessageSize, FontConfiguration stereotypeConfiguration) { + TextBlock tb1 = subList(0, 1).getCreole(fontConfiguration, horizontalAlignment, spriteContainer, + maxMessageSize, CreoleMode.FULL, stereotypeConfiguration); + tb1 = TextBlockUtils.withMargin(tb1, 0, 4, 0, 0); + final TextBlock tb2 = subList(1, size()).getCreole(fontConfiguration, horizontalAlignment, spriteContainer, + maxMessageSize, CreoleMode.FULL, stereotypeConfiguration); + return TextBlockUtils.mergeLR(tb1, tb2, VerticalAlignment.CENTER); + } } diff --git a/src/net/sourceforge/plantuml/cucadiagram/GroupRoot.java b/src/net/sourceforge/plantuml/cucadiagram/GroupRoot.java index a0a6b4873..dd3d93789 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/GroupRoot.java +++ b/src/net/sourceforge/plantuml/cucadiagram/GroupRoot.java @@ -122,7 +122,7 @@ public class GroupRoot implements IGroup { public Code getCode() { return CodeImpl.of("__ROOT__"); } - + public String getCodeGetName() { return getCode().getName(); } @@ -143,9 +143,18 @@ public class GroupRoot implements IGroup { public Collection getChildren() { final List result = new ArrayList(); - for (IGroup ent : entityFactory.groups()) { - if (ent.getParentContainer() == this) { - result.add(ent); + if (entityFactory.namespaceSeparator.V1972()) { + for (IGroup ent : entityFactory.groups()) { + if (ent.getIdent().size() == 1) { + result.add(ent); + } + } + + } else { + for (IGroup ent : entityFactory.groups()) { + if (ent.getParentContainer() == this) { + result.add(ent); + } } } return Collections.unmodifiableCollection(result); diff --git a/src/net/sourceforge/plantuml/cucadiagram/Ident.java b/src/net/sourceforge/plantuml/cucadiagram/Ident.java index 175e42f6b..253b1591e 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/Ident.java +++ b/src/net/sourceforge/plantuml/cucadiagram/Ident.java @@ -55,6 +55,18 @@ public class Ident implements Code { return parts.toString(); } + public boolean startsWith(Ident other) { + if (other.parts.size() > this.parts.size()) { + return false; + } + for (int i = 0; i < other.parts.size(); i++) { + if (other.parts.get(i).equals(this.parts.get(i)) == false) { + return false; + } + } + return true; + } + public String forXmi() { final StringBuilder sb = new StringBuilder(); for (String s : parts) { @@ -66,15 +78,26 @@ public class Ident implements Code { return sb.toString(); } + public Ident add(Ident added) { + final List copy = new ArrayList(parts); + copy.addAll(added.parts); + return new Ident(copy); + } + public static Ident empty() { return new Ident(Collections. emptyList()); } public String getLast() { + if (parts.size() == 0) { + return ""; + } return parts.get(parts.size() - 1); } - public Code toCode() { + public Code toCode(CucaDiagram diagram) { + if (diagram.V1972()) + return this; return CodeImpl.of(getLast()); } @@ -199,7 +222,10 @@ public class Ident implements Code { return sb.toString(); } - public void checkSameAs(Code code, String separator) { + public void checkSameAs(Code code, String separator, CucaDiagram diagram) { + if (diagram.V1972()) { + return; + } final String last = parts.get(parts.size() - 1); if (separator == null) { if (code.getName().equals(last) != true && code.getName().equals(toString(separator)) == false) { @@ -236,4 +262,23 @@ public class Ident implements Code { return getLast(); } + public boolean isRoot() { + return parts.size() == 0; + } + + public Ident move(Ident from, Ident to) { + if (this.startsWith(from) == false) { + throw new IllegalArgumentException(); + } + final List result = new ArrayList(to.parts); + for (int i = from.parts.size(); i < this.parts.size(); i++) { + result.add(this.parts.get(i)); + } + return new Ident(result); + } + + public int size() { + return parts.size(); + } + } diff --git a/src/net/sourceforge/plantuml/cucadiagram/LinkDecor.java b/src/net/sourceforge/plantuml/cucadiagram/LinkDecor.java index d402456b2..617056967 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/LinkDecor.java +++ b/src/net/sourceforge/plantuml/cucadiagram/LinkDecor.java @@ -48,6 +48,7 @@ import net.sourceforge.plantuml.svek.extremity.ExtremityFactoryCircleLine; import net.sourceforge.plantuml.svek.extremity.ExtremityFactoryCrowfoot; import net.sourceforge.plantuml.svek.extremity.ExtremityFactoryDiamond; import net.sourceforge.plantuml.svek.extremity.ExtremityFactoryDoubleLine; +import net.sourceforge.plantuml.svek.extremity.ExtremityFactoryHalfArrow; import net.sourceforge.plantuml.svek.extremity.ExtremityFactoryLineCrowfoot; import net.sourceforge.plantuml.svek.extremity.ExtremityFactoryNotNavigable; import net.sourceforge.plantuml.svek.extremity.ExtremityFactoryParenthesis; @@ -57,18 +58,18 @@ import net.sourceforge.plantuml.svek.extremity.ExtremityFactoryTriangle; public enum LinkDecor { - NONE(2, false, 0), EXTENDS(30, false, 2), COMPOSITION(15, true, 1.3), AGREGATION(15, false, 1.3), NOT_NAVIGABLE(1, - false, 0.5), + NONE(2, false, 0), EXTENDS(30, false, 2), COMPOSITION(15, true, 1.3), AGREGATION(15, false, 1.3), + NOT_NAVIGABLE(1, false, 0.5), + + CROWFOOT(10, true, 0.8), CIRCLE_CROWFOOT(14, false, 0.8), CIRCLE_LINE(10, false, 0.8), DOUBLE_LINE(7, false, 0.7), + LINE_CROWFOOT(10, false, 0.8), - CROWFOOT(10, true, 0.8), CIRCLE_CROWFOOT(14, false, 0.8), CIRCLE_LINE(10, false, 0.8), - DOUBLE_LINE(7, false, 0.7), LINE_CROWFOOT(10, false, 0.8), - ARROW(10, true, 0.5), ARROW_TRIANGLE(10, true, 0.8), ARROW_AND_CIRCLE(10, false, 0.5), - CIRCLE(0, false, 0.5), CIRCLE_FILL(0, false, 0.5), CIRCLE_CONNECT(0, false, 0.5), PARENTHESIS(0, false, OptionFlags.USE_INTERFACE_EYE2 ? 0.5 - : 1.0), SQUARE(0, false, 0.5), + CIRCLE(0, false, 0.5), CIRCLE_FILL(0, false, 0.5), CIRCLE_CONNECT(0, false, 0.5), + PARENTHESIS(0, false, OptionFlags.USE_INTERFACE_EYE2 ? 0.5 : 1.0), SQUARE(0, false, 0.5), - CIRCLE_CROSS(0, false, 0.5), PLUS(0, false, 1.5), SQUARRE_toberemoved(30, false, 0); + CIRCLE_CROSS(0, false, 0.5), PLUS(0, false, 1.5), HALF_ARROW(0, false, 1.5), SQUARRE_toberemoved(30, false, 0); private final double arrowSize; private final int margin; @@ -95,6 +96,8 @@ public enum LinkDecor { public ExtremityFactory getExtremityFactory(HtmlColor backgroundColor) { if (this == LinkDecor.PLUS) { return new ExtremityFactoryPlus(); + } else if (this == LinkDecor.HALF_ARROW) { + return new ExtremityFactoryHalfArrow(); } else if (this == LinkDecor.ARROW_TRIANGLE) { return new ExtremityFactoryTriangle(); } else if (this == LinkDecor.CROWFOOT) { diff --git a/src/net/sourceforge/plantuml/cucadiagram/Namespace.java b/src/net/sourceforge/plantuml/cucadiagram/Namespace.java deleted file mode 100644 index 246ffd69e..000000000 --- a/src/net/sourceforge/plantuml/cucadiagram/Namespace.java +++ /dev/null @@ -1,40 +0,0 @@ -/* ======================================================================== - * PlantUML : a free UML diagram generator - * ======================================================================== - * - * (C) Copyright 2009-2020, 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.cucadiagram; - -public class Namespace { - -} diff --git a/src/net/sourceforge/plantuml/cucadiagram/Stereotype.java b/src/net/sourceforge/plantuml/cucadiagram/Stereotype.java index d8e260e33..b6efbb7ee 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/Stereotype.java +++ b/src/net/sourceforge/plantuml/cucadiagram/Stereotype.java @@ -266,7 +266,7 @@ public class Stereotype implements CharSequence { public List getLabels(Guillemet guillemet) { final String labelLocal = getLabel(Guillemet.DOUBLE_COMPARATOR); if (labelLocal == null) { - return null; + return Collections.emptyList(); } return cutLabels(labelLocal, guillemet); } diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizWindows.java b/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizWindows.java index 341584858..c2681980c 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizWindows.java +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizWindows.java @@ -46,37 +46,54 @@ import net.sourceforge.plantuml.StringUtils; class GraphvizWindows extends AbstractGraphviz { + static private File specificDotExe; + @Override protected File specificDotExe() { - final File result = searchInDir(new File("c:/Program Files")); - if (result != null) { - return result; + synchronized (GraphvizWindows.class) { + if (specificDotExe == null) { + specificDotExe = specificDotExeSlow(); + } + return specificDotExe; } - final File result86 = searchInDir(new File("c:/Program Files (x86)")); - if (result86 != null) { - return result86; - } - final File resultEclipse = searchInDir(new File("c:/eclipse/graphviz")); - if (resultEclipse != null) { - return resultEclipse; + } + + private File specificDotExeSlow() { + for (File tmp : new File("c:/").listFiles(new FileFilter() { + public boolean accept(File pathname) { + return pathname.isDirectory() && pathname.canRead(); + } + })) { + final File result = searchInDir(tmp); + if (result != null) { + return result; + } } return null; } - private static File searchInDir(final File programFile) { - if (programFile.exists() == false || programFile.isDirectory() == false) { + private static File searchInDir(final File dir) { + if (dir.exists() == false || dir.isDirectory() == false) { return null; } final List dots = new ArrayList(); - for (File f : programFile.listFiles(new FileFilter() { + final File[] files = dir.listFiles(new FileFilter() { public boolean accept(File pathname) { return pathname.isDirectory() && StringUtils.goLowerCase(pathname.getName()).startsWith("graphviz"); } - })) { + }); + if (files == null) { + return null; + } + for (File f : files) { final File result = new File(new File(f, "bin"), "dot.exe"); if (result.exists() && result.canRead()) { dots.add(result.getAbsoluteFile()); } + final File result2 = new File(new File(f, "release/bin"), "dot.exe"); + if (result2.exists() && result2.canRead()) { + dots.add(result2.getAbsoluteFile()); + } } return higherVersion(dots); } @@ -92,11 +109,10 @@ class GraphvizWindows extends AbstractGraphviz { GraphvizWindows(ISkinParam skinParam, String dotString, String... type) { super(skinParam, dotString, type); } - + @Override protected String getExeName() { return "dot.exe"; } - } diff --git a/src/net/sourceforge/plantuml/cucadiagram/entity/EntityFactory.java b/src/net/sourceforge/plantuml/cucadiagram/entity/EntityFactory.java index a67035928..4e65ca09b 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/entity/EntityFactory.java +++ b/src/net/sourceforge/plantuml/cucadiagram/entity/EntityFactory.java @@ -41,10 +41,13 @@ import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; +import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.cucadiagram.Bodier; import net.sourceforge.plantuml.cucadiagram.Code; +import net.sourceforge.plantuml.cucadiagram.CucaDiagram; import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.cucadiagram.GroupRoot; import net.sourceforge.plantuml.cucadiagram.GroupType; @@ -59,11 +62,11 @@ import net.sourceforge.plantuml.skin.VisibilityModifier; public final class EntityFactory { - private final Map leafsByCode = new LinkedHashMap(); - private final Map groupsByCode = new LinkedHashMap(); + private final Map leafsByCode; + private final Map groupsByCode; - private final Map leafs2 = new LinkedHashMap(); - private final Map groups2 = new LinkedHashMap(); + /* private */final Map leafs2 = new LinkedHashMap(); + /* private */final Map groups2 = new LinkedHashMap(); private final List links = new ArrayList(); @@ -72,10 +75,20 @@ public final class EntityFactory { private final IGroup rootGroup = new GroupRoot(this); private final List hides2; private final List removed; + /* private */ final public CucaDiagram namespaceSeparator; - public EntityFactory(List hides2, List removed) { + public EntityFactory(List hides2, List removed, CucaDiagram namespaceSeparator) { this.hides2 = hides2; this.removed = removed; + this.namespaceSeparator = namespaceSeparator; + + // if (OptionFlags.V1972(namespaceSeparator)) { + // this.leafsByCode = null; + // this.groupsByCode = null; + // } else { + this.leafsByCode = new LinkedHashMap(); + this.groupsByCode = new LinkedHashMap(); + // } } public boolean isHidden(ILeaf leaf) { @@ -95,17 +108,9 @@ public final class EntityFactory { } public void thisIsGoingToBeALeaf(Ident ident) { - // if (byIdents.containsKey(ident) == false) { - // System.err.println("thisIsGoingToBeALeaf::byIdents=" + byIdents.keySet()); - // System.err.println("thisIsGoingToBeALeaf::ident=" + ident); - // // Thread.dumpStack(); - // // System.exit(0); - // } - // byIdents.remove(ident); } public void thisIsNotArealGroup(Ident ident) { - // byIdents.remove(ident); } public ILeaf createLeaf(Ident ident, Code code, Display display, LeafType entityType, IGroup parentContainer, @@ -113,17 +118,11 @@ public final class EntityFactory { if (entityType == null) { throw new IllegalArgumentException(); } - // if (byIdents.containsKey(ident)) { - // throw new IllegalArgumentException(); - // } final Bodier bodier = new Bodier(entityType, hides); final EntityImpl result = new EntityImpl(ident, code, this, bodier, parentContainer, entityType, namespaceSeparator, rawLayout); bodier.setLeaf(result); result.setDisplay(display); - // System.err.println("adding1 "+ident); - // byIdents.put(ident, result); - // System.err.println("EntityFactory::createLeaf=" + result); return result; } @@ -132,34 +131,40 @@ public final class EntityFactory { if (groupType == null) { throw new IllegalArgumentException(); } - // if (byIdents.containsKey(ident)) { - // throw new IllegalArgumentException(); - // } final Bodier bodier = new Bodier(null, hides); final EntityImpl result = new EntityImpl(ident, code, this, bodier, parentContainer, groupType, namespace, namespaceSeparator, rawLayout); if (Display.isNull(display) == false) { result.setDisplay(display); } - // System.err.println("adding2 "+ident); - // byIdents.put(ident, result); - // System.err.println("EntityFactory::createGroup=" + result); return result; } public void addLeaf(ILeaf entity) { - // System.err.println("EntityFactory::addLeaf=" + entity); - leafsByCode.put(entity.getCodeGetName(), entity); + if (namespaceSeparator.V1972() == false) + leafsByCode.put(entity.getCodeGetName(), entity); leafs2.put(entity.getIdent(), entity); + if (namespaceSeparator.V1972()) + ensureParentIsCreated(entity.getIdent()); } public void addGroup(IGroup group) { - // System.err.println("EntityFactory::addGroup=" + group); - groupsByCode.put(group.getCodeGetName(), group); + if (namespaceSeparator.V1972() == false) + groupsByCode.put(group.getCodeGetName(), group); groups2.put(group.getIdent(), group); + if (namespaceSeparator.V1972()) + ensureParentIsCreated(group.getIdent()); + } + + private void ensureParentIsCreated(Ident ident) { + if (groups2.get(ident.parent()) != null) + return; + getParentContainer(ident, null); } void removeGroup(String name) { + if (namespaceSeparator.V1972()) + throw new UnsupportedOperationException(); final IEntity removed = groupsByCode.remove(name); if (removed == null) { throw new IllegalArgumentException(); @@ -170,13 +175,22 @@ public final class EntityFactory { } } + void removeGroup(Ident ident) { + final IEntity removed = groups2.remove(ident); + if (removed == null) { + throw new IllegalArgumentException(); + } + } + public static void bigError() { - Thread.dumpStack(); + // Thread.dumpStack(); // System.exit(0); // throw new IllegalArgumentException(); } void removeLeaf(String name) { + if (namespaceSeparator.V1972()) + throw new UnsupportedOperationException(); final IEntity removed = leafsByCode.remove(name); if (removed == null) { throw new IllegalArgumentException(); @@ -187,7 +201,25 @@ public final class EntityFactory { } } + void removeLeaf(Ident ident) { + final IEntity removed = leafs2.remove(ident); + if (removed == null) { + System.err.println("leafs2=" + leafs2.keySet()); + throw new IllegalArgumentException(ident.toString()); + } + } + + private void removeLeaf1972(ILeaf leaf) { + final boolean removed = leafs2.values().remove(leaf); + if (removed == false) { + System.err.println("leafs2=" + leafs2.keySet()); + throw new IllegalArgumentException(leaf.toString()); + } + } + public IGroup muteToGroup(String name, Code namespace, GroupType type, IGroup parent) { + if (namespaceSeparator.V1972()) + throw new UnsupportedOperationException(); final ILeaf leaf = leafsByCode.get(name); ((EntityImpl) leaf).muteToGroup(namespace, type, parent); final IGroup result = (IGroup) leaf; @@ -195,15 +227,91 @@ public final class EntityFactory { return result; } + public IGroup muteToGroup1972(Ident ident, Code namespace, GroupType type, IGroup parent) { + if (!namespaceSeparator.V1972()) + throw new UnsupportedOperationException(); + final ILeaf leaf; + if (namespaceSeparator.getNamespaceSeparator() == null) + leaf = getLeafVerySmart(ident); + else + leaf = leafs2.get(ident); + ((EntityImpl) leaf).muteToGroup(namespace, type, parent); + final IGroup result = (IGroup) leaf; + removeLeaf1972(leaf); + return result; + } + public IGroup getRootGroup() { return rootGroup; } - public final ILeaf getLeaf(Ident ident) { + public final ILeaf getLeafStrict(Ident ident) { return leafs2.get(ident); } + public final ILeaf getLeafSmart(Ident ident) { + if (!namespaceSeparator.V1972()) + throw new UnsupportedOperationException(); + final ILeaf result = leafs2.get(ident); + if (result == null && ident.size() == 1) { + for (Entry ent : leafs2.entrySet()) { + if (ent.getKey().getLast().equals(ident.getLast())) { + return ent.getValue(); + } + } + } + return result; + } + + public final ILeaf getLeafVerySmart(Ident ident) { + if (!namespaceSeparator.V1972()) + throw new UnsupportedOperationException(); + final ILeaf result = leafs2.get(ident); + if (result == null) { + for (Entry ent : leafs2.entrySet()) { + if (ent.getKey().getLast().equals(ident.getLast())) { + return ent.getValue(); + } + } + } + return result; + } + + public Ident buildFullyQualified(Ident currentPath, Ident id) { + if (currentPath.equals(id) == false) { + if (leafs2.containsKey(id) || groups2.containsKey(id)) { + return id; + } + } + if (id.size() > 1) { + return id; + } + return currentPath.add(id); + } + + public final IGroup getGroupStrict(Ident ident) { + if (namespaceSeparator.getNamespaceSeparator() == null) { + return getGroupVerySmart(ident); + } + final IGroup result = groups2.get(ident); + return result; + } + + public final IGroup getGroupVerySmart(Ident ident) { + final IGroup result = groups2.get(ident); + if (result == null) { + for (Entry ent : groups2.entrySet()) { + if (ent.getKey().getLast().equals(ident.getLast())) { + return ent.getValue(); + } + } + } + return result; + } + public final ILeaf getLeaf(Code code) { + if (namespaceSeparator.V1972()) + throw new UnsupportedOperationException(); final ILeaf result = leafsByCode.get(code.getName()); if (result != null && result != leafs2.get(result.getIdent())) { bigError(); @@ -212,6 +320,8 @@ public final class EntityFactory { } public final IGroup getGroup(Code code) { + if (namespaceSeparator.V1972()) + throw new UnsupportedOperationException(); final IGroup result = groupsByCode.get(code.getName()); if (result != null && result != groups2.get(result.getIdent())) { bigError(); @@ -219,12 +329,9 @@ public final class EntityFactory { return result; } - public final IGroup getGroup(Ident ident) { - final IGroup result = groups2.get(ident); - return result; - } - public final Collection leafs() { + if (namespaceSeparator.V1972()) + return leafs2(); final Collection result = Collections.unmodifiableCollection(leafsByCode.values()); if (new ArrayList(result).equals(new ArrayList(leafs2())) == false) { bigError(); @@ -233,6 +340,8 @@ public final class EntityFactory { } public final Collection groups() { + if (namespaceSeparator.V1972()) + return groups2(); final Collection result = Collections.unmodifiableCollection(groupsByCode.values()); if (new ArrayList(result).equals(new ArrayList(groups2())) == false) { bigError(); @@ -282,19 +391,24 @@ public final class EntityFactory { } public IGroup getParentContainer(Ident ident, IGroup parentContainer) { + if (namespaceSeparator.V1972()) { + final Ident parent = ident.parent(); + if (parent.isRoot()) { + return this.rootGroup; + } + IGroup result = getGroupStrict(parent); + if (result != null) { + return result; + } + System.err.println("getParentContainer::groups2=" + groups2); + result = createGroup(parent, parent, Display.getWithNewlines(parent.getName()), null, GroupType.PACKAGE, + null, Collections.emptySet(), namespaceSeparator.getNamespaceSeparator()); + addGroup(result); + return result; + } if (parentContainer == null) { throw new IllegalArgumentException(); } - // if (parentContainer == null) { - // } else { - // final Ident identParent = parentContainer.getIdent(); - // if (ident.parent().equals(identParent) == false) { - // System.err.println("ident=" + ident); - // System.err.println("parentContainer=" + identParent); - // Thread.dumpStack(); - // System.exit(0); - // } - // } return parentContainer; } diff --git a/src/net/sourceforge/plantuml/cucadiagram/entity/EntityImpl.java b/src/net/sourceforge/plantuml/cucadiagram/entity/EntityImpl.java index aeb11bb9c..8eb85b7f1 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/entity/EntityImpl.java +++ b/src/net/sourceforge/plantuml/cucadiagram/entity/EntityImpl.java @@ -48,6 +48,7 @@ import java.util.Set; import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.Guillemet; import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.cucadiagram.Bodier; @@ -83,8 +84,8 @@ final class EntityImpl implements ILeaf, IGroup { private final EntityFactory entityFactory; // Entity - private final Code code; - private final Ident ident; + private/* final */Code code; + private/* final */Ident ident; private Url url; @@ -139,6 +140,9 @@ final class EntityImpl implements ILeaf, IGroup { private EntityImpl(Ident ident, EntityFactory entityFactory, Code code, Bodier bodier, IGroup parentContainer, String namespaceSeparator, int rawLayout) { checkNotNull(ident); + if (entityFactory.namespaceSeparator.V1972()) { + code = ident; + } if (code == null) { throw new IllegalArgumentException(); } @@ -164,7 +168,7 @@ final class EntityImpl implements ILeaf, IGroup { this(ident, entityFactory, code, bodier, parentContainer, namespaceSeparator, rawLayout); checkNotNull(ident); // System.err.println("ID for group=" + code + " " + ident); - ident.checkSameAs(code, namespaceSeparator); + ident.checkSameAs(code, namespaceSeparator, entityFactory.namespaceSeparator); this.groupType = groupType; this.namespace = namespace; } @@ -259,6 +263,8 @@ final class EntityImpl implements ILeaf, IGroup { public String toString() { // return super.toString() + code + " " + display + "(" + leafType + ")[" + groupType + "] " + xposition + " " // + getUid(); + if (entityFactory.namespaceSeparator.V1972()) + return getUid() + " " + ident + " " + display + "(" + leafType + ")[" + groupType + "]"; return super.toString() + code + ident + " " + display + "(" + leafType + ")[" + groupType + "] " + getUid(); } @@ -399,6 +405,10 @@ final class EntityImpl implements ILeaf, IGroup { } public void moveEntitiesTo(IGroup dest) { + if (entityFactory.namespaceSeparator.V1972()) { + moveEntitiesTo1972(dest); + return; + } checkGroup(); if (dest.isGroup() == false) { throw new UnsupportedOperationException(); @@ -420,6 +430,65 @@ final class EntityImpl implements ILeaf, IGroup { } + private void moveEntitiesTo1972(IGroup dest) { + checkGroup(); + if (dest.isGroup() == false) { + throw new UnsupportedOperationException(); + } + System.err.println("moveEntitiesTo1972::before1::groups2=" + entityFactory.groups2()); + final Ident firstIdent = getIdent(); + final Ident destIdent = dest.getIdent(); + System.err.println("moveEntitiesTo1972::this=" + firstIdent); + System.err.println("moveEntitiesTo1972::dest=" + destIdent); + if (destIdent.startsWith(firstIdent) == false) { + throw new UnsupportedOperationException(); + } + System.err.println("moveEntitiesTo1972::before2::groups2=" + entityFactory.groups2()); + for (ILeaf ent : new ArrayList(entityFactory.leafs2())) { + Ident ident = ent.getIdent(); + if (ident.equals(firstIdent) == false && ident.startsWith(firstIdent) + && ident.startsWith(destIdent) == false) { + System.err.print("moving leaf ident1=" + ident); + entityFactory.leafs2.remove(ident); + ident = ident.move(firstIdent, destIdent); + System.err.println(" to ident2=" + ident); + ((EntityImpl) ent).ident = ident; + ((EntityImpl) ent).code = ident; + entityFactory.leafs2.put(ident, ent); + } + } + System.err.println("moveEntitiesTo1972::before3::groups2=" + entityFactory.groups2()); + for (IGroup ent : new ArrayList(entityFactory.groups2())) { + Ident ident = ent.getIdent(); + System.err.println("found=" + ident + " " + ident.startsWith(firstIdent) + " " + + ident.startsWith(destIdent)); + if (ident.equals(firstIdent) == false && ident.startsWith(firstIdent) + && ident.startsWith(destIdent) == false) { + System.err.print("moving gr ident1=" + ident); + entityFactory.groups2.remove(ident); + ident = ident.move(firstIdent, destIdent); + System.err.println(" to ident2=" + ident); + ((EntityImpl) ent).ident = ident; + ((EntityImpl) ent).code = ident; + entityFactory.groups2.put(ident, ent); + System.err.println("-->groups2=" + entityFactory.groups2()); + } + } + System.err.println("moveEntitiesTo1972::after::groups2=" + entityFactory.groups2()); + // for (IGroup g : dest.getChildren()) { + // // ((EntityImpl) g).parentContainer = dest; + // throw new IllegalStateException(); + // } + // + // for (IGroup g : getChildren()) { + // if (g == dest) { + // continue; + // } + // ((EntityImpl) g).parentContainer = dest; + // } + + } + public int size() { checkGroup(); return getLeafsDirect().size(); @@ -470,10 +539,19 @@ final class EntityImpl implements ILeaf, IGroup { } } - entityFactory.removeGroup(getCodeGetName()); - for (ILeaf ent : new ArrayList(entityFactory.leafs())) { - if (this != ent && this == ent.getParentContainer()) { - entityFactory.removeLeaf(ent.getCodeGetName()); + if (entityFactory.namespaceSeparator.V1972()) { + entityFactory.removeGroup(getIdent()); + for (ILeaf ent : new ArrayList(entityFactory.leafs())) { + if (this != ent && getIdent().equals(ent.getIdent().parent())) { + entityFactory.removeLeaf(ent.getIdent()); + } + } + } else { + entityFactory.removeGroup(getCodeGetName()); + for (ILeaf ent : new ArrayList(entityFactory.leafs())) { + if (this != ent && this == ent.getParentContainer()) { + entityFactory.removeLeaf(ent.getCodeGetName()); + } } } diff --git a/src/net/sourceforge/plantuml/descdiagram/CommandCreateDomain.java b/src/net/sourceforge/plantuml/descdiagram/CommandCreateDomain.java index a266bd7dc..440cea2d2 100644 --- a/src/net/sourceforge/plantuml/descdiagram/CommandCreateDomain.java +++ b/src/net/sourceforge/plantuml/descdiagram/CommandCreateDomain.java @@ -37,6 +37,7 @@ package net.sourceforge.plantuml.descdiagram; import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.LineLocation; +import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.UrlBuilder; import net.sourceforge.plantuml.UrlBuilder.ModeUrl; @@ -86,17 +87,22 @@ public class CommandCreateDomain extends SingleLineCommand2 protected CommandExecutionResult executeArg(DescriptionDiagram diagram, LineLocation location, RegexResult arg) { String type = arg.get("TYPE", 0); String display = arg.getLazzy("DISPLAY", 0); - String code = arg.getLazzy("CODE", 0); - if (code == null) { - code = display; + String codeString = arg.getLazzy("CODE", 0); + if (codeString == null) { + codeString = display; } - final String genericOption = arg.getLazzy("DISPLAY", 1); - final String generic = genericOption != null ? genericOption : arg.get("GENERIC", 0); + // final String genericOption = arg.getLazzy("DISPLAY", 1); + // final String generic = genericOption != null ? genericOption : arg.get("GENERIC", 0); final String stereotype = arg.get("STEREO", 0); - if (diagram.leafExist(diagram.buildCode(code))) { - return CommandExecutionResult.error("Object already exists : " + code); + final Ident ident = diagram.buildLeafIdent(codeString); + final Code code = diagram.V1972() ? ident : diagram.buildCode(codeString); + if (diagram.V1972() && diagram.leafExistSmart(ident)) { + return CommandExecutionResult.error("Object already exists : " + codeString); + } + if (!diagram.V1972() && diagram.leafExist(code)) { + return CommandExecutionResult.error("Object already exists : " + codeString); } Display d = Display.getWithNewlines(display); final String urlString = arg.get("URL", 0); @@ -104,15 +110,12 @@ public class CommandCreateDomain extends SingleLineCommand2 IEntity entity; if (group != null) { final IGroup currentGroup = diagram.getCurrentGroup(); - final Ident idNewLong = diagram.buildLeafIdent(code); - diagram.gotoGroup(idNewLong, diagram.buildCode(code), d, - type.equalsIgnoreCase("domain") ? GroupType.DOMAIN : GroupType.REQUIREMENT, currentGroup, - NamespaceStrategy.SINGLE); + diagram.gotoGroup(ident, code, d, type.equalsIgnoreCase("domain") ? GroupType.DOMAIN + : GroupType.REQUIREMENT, currentGroup, NamespaceStrategy.SINGLE); entity = diagram.getCurrentGroup(); } else { - final Ident idNewLong = diagram.buildLeafIdent(code); - entity = diagram.createLeaf(idNewLong, diagram.buildCode(code), d, - type.equalsIgnoreCase("domain") ? LeafType.DOMAIN : LeafType.REQUIREMENT, null); + entity = diagram.createLeaf(ident, code, d, type.equalsIgnoreCase("domain") ? LeafType.DOMAIN + : LeafType.REQUIREMENT, null); } if (stereotype != null) { entity.setStereotype(new Stereotype(stereotype, diagram.getSkinParam().getCircledCharacterRadius(), diagram diff --git a/src/net/sourceforge/plantuml/descdiagram/DescriptionDiagram.java b/src/net/sourceforge/plantuml/descdiagram/DescriptionDiagram.java index 240b189c4..7bcba43a6 100644 --- a/src/net/sourceforge/plantuml/descdiagram/DescriptionDiagram.java +++ b/src/net/sourceforge/plantuml/descdiagram/DescriptionDiagram.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.descdiagram; import net.sourceforge.plantuml.ISkinSimple; +import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.UmlDiagramType; import net.sourceforge.plantuml.classdiagram.AbstractEntityDiagram; @@ -51,6 +52,23 @@ public class DescriptionDiagram extends AbstractEntityDiagram { super(skinParam); } + @Override + public Ident cleanIdent(Ident ident) { + String codeString = ident.getName(); + if (codeString.startsWith("[") && codeString.endsWith("]")) { + return ident.eventuallyRemoveStartingAndEndingDoubleQuote("\"([:"); + } + if (codeString.startsWith(":") && codeString.endsWith(":")) { + return ident.eventuallyRemoveStartingAndEndingDoubleQuote("\"([:"); + } + if (codeString.startsWith("()")) { + codeString = StringUtils.trin(codeString.substring(2)); + codeString = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(codeString); + return ident.parent().add(Ident.empty().add(codeString, null)); + } + return ident; + } + @Override public ILeaf getOrCreateLeaf(Ident ident, Code code, LeafType type, USymbol symbol) { checkNotNull(ident); @@ -59,21 +77,23 @@ public class DescriptionDiagram extends AbstractEntityDiagram { if (codeString.startsWith("[") && codeString.endsWith("]")) { final USymbol sym = getSkinParam().useUml2ForComponent() ? USymbol.COMPONENT2 : USymbol.COMPONENT1; final Ident idNewLong = ident.eventuallyRemoveStartingAndEndingDoubleQuote("\"([:"); - return getOrCreateLeafDefault(idNewLong, idNewLong.toCode(), LeafType.DESCRIPTION, sym); + return getOrCreateLeafDefault(idNewLong, idNewLong.toCode(this), LeafType.DESCRIPTION, sym); } if (codeString.startsWith(":") && codeString.endsWith(":")) { final Ident idNewLong = ident.eventuallyRemoveStartingAndEndingDoubleQuote("\"([:"); - return getOrCreateLeafDefault(idNewLong, idNewLong.toCode(), LeafType.DESCRIPTION, getSkinParam().getActorStyle() - .getUSymbol()); + return getOrCreateLeafDefault(idNewLong, idNewLong.toCode(this), LeafType.DESCRIPTION, getSkinParam() + .getActorStyle().getUSymbol()); } if (codeString.startsWith("()")) { codeString = StringUtils.trin(codeString.substring(2)); codeString = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(codeString); final Ident idNewLong = buildLeafIdent(codeString); - return getOrCreateLeafDefault(idNewLong, buildCode(codeString), LeafType.DESCRIPTION, USymbol.INTERFACE); + final Code code99 = this.V1972() ? idNewLong : buildCode(codeString); + return getOrCreateLeafDefault(idNewLong, code99, LeafType.DESCRIPTION, USymbol.INTERFACE); } - code = buildCode(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(code.getName(), "\"([:")); + final String tmp4 = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(code.getName(), "\"([:"); final Ident idNewLong = ident.eventuallyRemoveStartingAndEndingDoubleQuote("\"([:"); + code = this.V1972() ? idNewLong : buildCode(tmp4); return getOrCreateLeafDefault(idNewLong, code, LeafType.STILL_UNKNOWN, symbol); } return getOrCreateLeafDefault(ident, code, type, symbol); diff --git a/src/net/sourceforge/plantuml/descdiagram/command/CommandArchimate.java b/src/net/sourceforge/plantuml/descdiagram/command/CommandArchimate.java index f002f464f..54d5d6144 100644 --- a/src/net/sourceforge/plantuml/descdiagram/command/CommandArchimate.java +++ b/src/net/sourceforge/plantuml/descdiagram/command/CommandArchimate.java @@ -37,6 +37,7 @@ package net.sourceforge.plantuml.descdiagram.command; import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.LineLocation; +import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -49,6 +50,7 @@ import net.sourceforge.plantuml.command.regex.RegexResult; import net.sourceforge.plantuml.cucadiagram.Code; import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Ident; import net.sourceforge.plantuml.cucadiagram.LeafType; import net.sourceforge.plantuml.cucadiagram.Stereotype; import net.sourceforge.plantuml.descdiagram.DescriptionDiagram; @@ -122,10 +124,11 @@ public class CommandArchimate extends SingleLineCommand2 { final String codeRaw = arg.getLazzy("CODE", 0); final String idShort = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(codeRaw); - final Code code = diagram.buildCode(idShort); + final Ident ident = diagram.buildLeafIdent(idShort); + final Code code = diagram.V1972() ? ident : diagram.buildCode(idShort); final String icon = arg.getLazzy("STEREOTYPE", 0); - final IEntity entity = diagram.getOrCreateLeaf(diagram.buildLeafIdent(idShort), code, LeafType.DESCRIPTION, USymbol.ARCHIMATE); + final IEntity entity = diagram.getOrCreateLeaf(ident, code, LeafType.DESCRIPTION, USymbol.ARCHIMATE); final String displayRaw = arg.getLazzy("DISPLAY", 0); diff --git a/src/net/sourceforge/plantuml/descdiagram/command/CommandArchimateMultilines.java b/src/net/sourceforge/plantuml/descdiagram/command/CommandArchimateMultilines.java index a0522bcd5..d0a1891ec 100644 --- a/src/net/sourceforge/plantuml/descdiagram/command/CommandArchimateMultilines.java +++ b/src/net/sourceforge/plantuml/descdiagram/command/CommandArchimateMultilines.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.descdiagram.command; import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.UrlBuilder; import net.sourceforge.plantuml.classdiagram.AbstractEntityDiagram; @@ -51,6 +52,7 @@ import net.sourceforge.plantuml.command.regex.RegexResult; import net.sourceforge.plantuml.cucadiagram.Code; import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Ident; import net.sourceforge.plantuml.cucadiagram.LeafType; import net.sourceforge.plantuml.cucadiagram.Stereotype; import net.sourceforge.plantuml.graphic.USymbol; @@ -103,10 +105,11 @@ public class CommandArchimateMultilines extends CommandMultilines2 { - public static final String ALL_TYPES = "artifact|actor|folder|card|file|package|rectangle|node|frame|cloud|database|queue|stack|storage|agent|usecase|component|boundary|control|entity|interface|circle|collections"; + public static final String ALL_TYPES = "artifact|actor|folder|card|file|package|rectangle|label|node|frame|cloud|database|queue|stack|storage|agent|usecase|component|boundary|control|entity|interface|circle|collections"; public CommandCreateElementFull() { super(getRegexConcat()); @@ -188,20 +190,24 @@ public class CommandCreateElementFull extends SingleLineCommand2 lineLast = StringUtils.getSplit(MyPattern.cmpile(getPatternEnd()), lines.getLast499() .getString()); lines = lines.subExtract(1, 1); @@ -157,11 +157,12 @@ public class CommandCreateElementMultilines extends CommandMultilines2 { new RegexOptional(new RegexLeaf("INSIDE", "(0|\\(0\\)|\\(0|0\\))(?=[-=.~])")), // new RegexLeaf("ARROW_STYLE2", "(?:\\[(" + LINE_STYLE + ")\\])?"), // new RegexLeaf("BODY2", "([-=.~]*)"), // - new RegexLeaf("HEAD1", "(\\(0|>>|[>^*+#0@(]|\\|>|o[%s]+)?"), // + new RegexLeaf("HEAD1", "(\\(0|>>|[>^*+#0@(]|\\|>|\\\\\\\\|o[%s]+)?"), // RegexLeaf.spaceZeroOrMore(), // new RegexOptional(new RegexLeaf("LABEL2", "[%g]([^%g]+)[%g]")), // RegexLeaf.spaceZeroOrMore(), // @@ -130,6 +130,8 @@ public class CommandLinkElement extends SingleLineCommand2 { d1 = LinkDecor.AGREGATION; } else if (head1.equals("+")) { d1 = LinkDecor.PLUS; + } else if (head1.equals("\\\\")) { + d1 = LinkDecor.HALF_ARROW; } else if (head1.equals(">>")) { d1 = LinkDecor.ARROW_TRIANGLE; } else if (head1.equals("^")) { @@ -289,18 +291,12 @@ public class CommandLinkElement extends SingleLineCommand2 { protected CommandExecutionResult executeArg(DescriptionDiagram diagram, LineLocation location, RegexResult arg) { final String ent1String = arg.get("ENT1", 0); final String ent2String = arg.get("ENT2", 0); - final Code code1 = diagram.buildCode(ent1String); - final Code code2 = diagram.buildCode(ent2String); - - if (diagram.isGroup(code1) && diagram.isGroup(code2)) { - return executePackageLink(diagram, arg); - } - - final Ident ident1 = diagram.buildLeafIdent(ent1String); - final Ident ident2 = diagram.buildLeafIdent(ent2String); - - final IEntity cl1 = getFoo1(diagram, code1, ident1); - final IEntity cl2 = getFoo1(diagram, code2, ident2); + final Ident ident1 = diagram.buildFullyQualified(ent1String); + final Ident ident2 = diagram.buildFullyQualified(ent2String); + Ident ident1pure = Ident.empty().add(ent1String, diagram.getNamespaceSeparator()); + Ident ident2pure = Ident.empty().add(ent2String, diagram.getNamespaceSeparator()); + final Code code1 = diagram.V1972() ? ident1 : diagram.buildCode(ent1String); + final Code code2 = diagram.V1972() ? ident2 : diagram.buildCode(ent2String); final LinkType linkType = getLinkType(arg); final Direction dir = getDirection(arg); @@ -310,9 +306,19 @@ public class CommandLinkElement extends SingleLineCommand2 { } else { queue = getQueue(arg); } - final Labels labels = new Labels(arg); + final IEntity cl1; + final IEntity cl2; + if (diagram.isGroup(code1) && diagram.isGroup(code2)) { + cl1 = diagram.V1972() ? diagram.getGroupStrict(diagram.buildLeafIdent(ent1String)) : diagram + .getGroup(diagram.buildCode(ent1String)); + cl2 = diagram.V1972() ? diagram.getGroupStrict(diagram.buildLeafIdent(ent2String)) : diagram + .getGroup(diagram.buildCode(ent2String)); + } else { + cl1 = getFoo1(diagram, code1, ident1, ident1pure); + cl2 = getFoo1(diagram, code2, ident2, ident2pure); + } Link link = new Link(cl1, cl2, linkType, Display.getWithNewlines(labels.labelLink), queue.length(), labels.firstLabel, labels.secondLabel, diagram.getLabeldistance(), diagram.getLabelangle(), diagram .getSkinParam().getCurrentStyleBuilder()); @@ -330,58 +336,46 @@ public class CommandLinkElement extends SingleLineCommand2 { return CommandExecutionResult.ok(); } - private IEntity getFoo1(DescriptionDiagram diagram, Code code, Ident ident) { - if (diagram.isGroup(code)) { + private IEntity getFoo1(DescriptionDiagram diagram, Code code, Ident ident, Ident pure) { + if (!diagram.V1972() && diagram.isGroup(code)) { return diagram.getGroup(code); } - return getOrCreateLeafInternal(diagram, code, ident); - } - - private ILeaf getOrCreateLeafInternal(DescriptionDiagram diagram, Code code, Ident ident) { + if (diagram.V1972() && diagram.isGroupStrict(ident)) { + return diagram.getGroupStrict(ident); + } final String codeString = code.getName(); if (ident.getLast().startsWith("()")) { ident = ident.removeStartingParenthesis(); - return diagram.getOrCreateLeaf(ident, ident.toCode(), LeafType.DESCRIPTION, USymbol.INTERFACE); + return getOrCreateLeaf1972(diagram, ident, ident.toCode(diagram), LeafType.DESCRIPTION, USymbol.INTERFACE, + pure); } final char codeChar = codeString.length() > 2 ? codeString.charAt(0) : 0; - final Code code3 = diagram.buildCode(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(codeString, "\"([:")); - final Ident ident3 = diagram.buildLeafIdent(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote( - codeString, "\"([:")); + final String tmp3 = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(codeString, "\"([:"); + final Ident ident3 = diagram.buildFullyQualified(tmp3); + final Code code3 = diagram.V1972() ? ident3 : diagram.buildCode(tmp3); if (codeChar == '(') { - return diagram.getOrCreateLeaf(ident3, code3, LeafType.USECASE, USymbol.USECASE); + return getOrCreateLeaf1972(diagram, ident3, code3, LeafType.USECASE, USymbol.USECASE, pure); } else if (codeChar == ':') { - return diagram.getOrCreateLeaf(ident3, code3, LeafType.DESCRIPTION, diagram.getSkinParam().getActorStyle() - .getUSymbol()); + return getOrCreateLeaf1972(diagram, ident3, code3, LeafType.DESCRIPTION, diagram.getSkinParam() + .getActorStyle().getUSymbol(), pure); } else if (codeChar == '[') { final USymbol sym = diagram.getSkinParam().useUml2ForComponent() ? USymbol.COMPONENT2 : USymbol.COMPONENT1; - return diagram.getOrCreateLeaf(ident3, code3, LeafType.DESCRIPTION, sym); + return getOrCreateLeaf1972(diagram, ident3, code3, LeafType.DESCRIPTION, sym, pure); } - return diagram.getOrCreateLeaf(ident, code, null, null); + return getOrCreateLeaf1972(diagram, ident, code, null, null, pure); } - private CommandExecutionResult executePackageLink(DescriptionDiagram diagram, RegexResult arg) { - final IEntity cl1 = diagram.getGroup(diagram.buildCode(arg.get("ENT1", 0))); - final IEntity cl2 = diagram.getGroup(diagram.buildCode(arg.get("ENT2", 0))); - - final LinkType linkType = getLinkType(arg); - final Direction dir = getDirection(arg); - final String queue; - if (dir == Direction.LEFT || dir == Direction.RIGHT) { - queue = "-"; - } else { - queue = getQueue(arg); + private ILeaf getOrCreateLeaf1972(DescriptionDiagram diagram, Ident ident, Code code, LeafType type, + USymbol symbol, Ident pure) { + if (diagram.V1972()) { + final ILeaf result = pure.size() == 1 ? diagram.getLeafVerySmart(ident) : diagram.getLeafStrict(ident); + // final ILeaf result = diagram.getLeafSmart(ident); + if (result != null) { + return result; + } } - - final Labels labels = new Labels(arg); - Link link = new Link(cl1, cl2, linkType, Display.getWithNewlines(labels.labelLink), queue.length(), diagram - .getSkinParam().getCurrentStyleBuilder()); - if (dir == Direction.LEFT || dir == Direction.UP) { - link = link.getInv(); - } - link.applyStyle(arg.getLazzy("ARROW_STYLE", 0)); - diagram.addLink(link); - return CommandExecutionResult.ok(); + return diagram.getOrCreateLeaf(ident, code, type, symbol); } } diff --git a/src/net/sourceforge/plantuml/descdiagram/command/CommandPackageWithUSymbol.java b/src/net/sourceforge/plantuml/descdiagram/command/CommandPackageWithUSymbol.java index 75fd674bf..8473e5dac 100644 --- a/src/net/sourceforge/plantuml/descdiagram/command/CommandPackageWithUSymbol.java +++ b/src/net/sourceforge/plantuml/descdiagram/command/CommandPackageWithUSymbol.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.descdiagram.command; import net.sourceforge.plantuml.LineLocation; +import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.UrlBuilder; @@ -138,26 +139,24 @@ public class CommandPackageWithUSymbol extends SingleLineCommand2 lines2; + private List lines; private final Display texts; private final FontConfiguration fontConfiguration; - private final UFont fontForStereotype; private final HorizontalAlignment horizontalAlignment; private final SpriteContainer spriteContainer; private final double maxMessageSize; - private final HtmlColor htmlColorForStereotype; - - protected TextBlockSimple(Display texts, FontConfiguration fontConfiguration, - HorizontalAlignment horizontalAlignment, SpriteContainer spriteContainer, double maxMessageSize) { - this(texts, fontConfiguration, horizontalAlignment, spriteContainer, maxMessageSize, null, null); - } public TextBlockSimple(Display texts, FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment, - SpriteContainer spriteContainer, double maxMessageSize, UFont fontForStereotype, - HtmlColor htmlColorForStereotype) { + SpriteContainer spriteContainer, double maxMessageSize) { this.texts = texts; this.fontConfiguration = fontConfiguration; this.horizontalAlignment = horizontalAlignment; this.spriteContainer = spriteContainer; this.maxMessageSize = maxMessageSize; - this.fontForStereotype = fontForStereotype; - this.htmlColorForStereotype = htmlColorForStereotype; } private List getLines(StringBounder stringBounder) { - if (lines2 == null) { + if (lines == null) { if (stringBounder == null) { throw new IllegalStateException(); } - this.lines2 = new ArrayList(); + this.lines = new ArrayList(); for (CharSequence s : texts) { - if (s instanceof Stereotype) { - lines2.addAll(createLinesForStereotype( - fontConfiguration.forceFont(fontForStereotype, htmlColorForStereotype), (Stereotype) s, - horizontalAlignment, spriteContainer)); - } else if (s instanceof EmbeddedDiagram) { - lines2.add(((EmbeddedDiagram) s).asDraw(null)); + if (s instanceof EmbeddedDiagram) { + lines.add(((EmbeddedDiagram) s).asDraw(null)); } else { addInLines(stringBounder, s.toString()); } } } - return lines2; + return lines; } private void addInLines(StringBounder stringBounder, String s) { @@ -145,11 +127,11 @@ public class TextBlockSimple extends AbstractTextBlock implements TextBlock { if (s.length() == 0 || MyPattern.mtches(s, "^[%s]*$ ")) { return; } - lines2.add(SingleLine.withSomeHtmlTag(s, fontConfiguration, horizontalAlignment, spriteContainer)); + lines.add(SingleLine.withSomeHtmlTag(s, fontConfiguration, horizontalAlignment, spriteContainer)); } private void addSingleLine(String s) { - lines2.add(SingleLine.withSomeHtmlTag(s, fontConfiguration, horizontalAlignment, spriteContainer)); + lines.add(SingleLine.withSomeHtmlTag(s, fontConfiguration, horizontalAlignment, spriteContainer)); } private double getTextWidth(StringBounder stringBounder, String s) { @@ -157,16 +139,6 @@ public class TextBlockSimple extends AbstractTextBlock implements TextBlock { return line.calculateDimension(stringBounder).getWidth(); } - private List createLinesForStereotype(FontConfiguration fontConfiguration, Stereotype s, - HorizontalAlignment horizontalAlignment, SpriteContainer spriteContainer) { - assert s.getLabel(Guillemet.DOUBLE_COMPARATOR) != null; - final List result = new ArrayList(); - for (String st : s.getLabels(spriteContainer.guillemet())) { - result.add(SingleLine.withSomeHtmlTag(st, fontConfiguration, horizontalAlignment, spriteContainer)); - } - return Collections.unmodifiableList(result); - } - public Dimension2D calculateDimension(StringBounder stringBounder) { return getTextDimension(stringBounder); } diff --git a/src/net/sourceforge/plantuml/graphic/TextBlockSprited.java b/src/net/sourceforge/plantuml/graphic/TextBlockSprited.java index ad22f7425..13b17c208 100644 --- a/src/net/sourceforge/plantuml/graphic/TextBlockSprited.java +++ b/src/net/sourceforge/plantuml/graphic/TextBlockSprited.java @@ -38,27 +38,24 @@ package net.sourceforge.plantuml.graphic; import java.awt.geom.Dimension2D; import net.sourceforge.plantuml.Dimension2DDouble; -import net.sourceforge.plantuml.SpriteContainer; -import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UTranslate; -public class TextBlockSprited extends TextBlockSimple { +public class TextBlockSprited extends AbstractTextBlock { + private final TextBlock parent; private final TextBlock sprite; - public TextBlockSprited(TextBlock sprite, Display texts, FontConfiguration fontConfiguration, - HorizontalAlignment horizontalAlignment, SpriteContainer spriteContainer) { - super(texts, fontConfiguration, horizontalAlignment, spriteContainer, 0); + public TextBlockSprited(TextBlock sprite, TextBlock parent) { this.sprite = sprite; + this.parent = parent; } - @Override public Dimension2D calculateDimension(StringBounder stringBounder) { final double widthCircledCharacter = getCircledCharacterWithAndMargin(stringBounder); final double heightCircledCharacter = sprite.calculateDimension(stringBounder).getHeight(); - final Dimension2D dim = super.calculateDimension(stringBounder); + final Dimension2D dim = parent.calculateDimension(stringBounder); return new Dimension2DDouble(dim.getWidth() + widthCircledCharacter, Math.max(heightCircledCharacter, dim.getHeight())); } @@ -67,7 +64,6 @@ public class TextBlockSprited extends TextBlockSimple { return sprite.calculateDimension(stringBounder).getWidth() + 6.0; } - @Override public void drawU(UGraphic ug) { final StringBounder stringBounder = ug.getStringBounder(); @@ -75,7 +71,7 @@ public class TextBlockSprited extends TextBlockSimple { final double widthCircledCharacter = getCircledCharacterWithAndMargin(stringBounder); - super.drawU(ug.apply(new UTranslate(widthCircledCharacter, 0))); + parent.drawU(ug.apply(new UTranslate(widthCircledCharacter, 0))); } } diff --git a/src/net/sourceforge/plantuml/graphic/USymbol.java b/src/net/sourceforge/plantuml/graphic/USymbol.java index 412bceb54..d24f89812 100644 --- a/src/net/sourceforge/plantuml/graphic/USymbol.java +++ b/src/net/sourceforge/plantuml/graphic/USymbol.java @@ -65,6 +65,8 @@ public abstract class USymbol { public final static USymbol FILE = record("FILE", SkinParameter.FILE, new USymbolFile()); public final static USymbol RECTANGLE = record("RECTANGLE", SkinParameter.RECTANGLE, new USymbolRect( SkinParameter.RECTANGLE)); + public final static USymbol LABEL = record("LABEL", SkinParameter.RECTANGLE, new USymbolLabel( + SkinParameter.RECTANGLE)); public final static USymbol ARCHIMATE = record("ARCHIMATE", SkinParameter.ARCHIMATE, new USymbolRect( SkinParameter.ARCHIMATE)); public final static USymbol COLLECTIONS = record("COLLECTIONS", SkinParameter.COLLECTIONS, new USymbolCollections( @@ -210,6 +212,8 @@ public abstract class USymbol { usymbol = USymbol.PACKAGE; } else if (symbol.equalsIgnoreCase("rectangle")) { usymbol = USymbol.RECTANGLE; + } else if (symbol.equalsIgnoreCase("label")) { + usymbol = USymbol.LABEL; } else if (symbol.equalsIgnoreCase("collections")) { usymbol = USymbol.COLLECTIONS; } else if (symbol.equalsIgnoreCase("node")) { diff --git a/src/net/sourceforge/plantuml/graphic/USymbolLabel.java b/src/net/sourceforge/plantuml/graphic/USymbolLabel.java new file mode 100644 index 000000000..5a315acdd --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/USymbolLabel.java @@ -0,0 +1,129 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2020, 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.graphic; + +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.ugraphic.Shadowable; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.UGraphicStencil; +import net.sourceforge.plantuml.ugraphic.UPath; +import net.sourceforge.plantuml.ugraphic.URectangle; +import net.sourceforge.plantuml.ugraphic.UStroke; +import net.sourceforge.plantuml.ugraphic.UTranslate; + +class USymbolLabel extends USymbol { + + private final SkinParameter skinParameter; + + public USymbolLabel(SkinParameter skinParameter) { + this.skinParameter = skinParameter; + } + + @Override + public SkinParameter getSkinParameter() { + return skinParameter; + } + + private Margin getMargin() { + return new Margin(10, 10, 10, 10); + } + + @Override + public TextBlock asSmall(TextBlock name, final TextBlock label, final TextBlock stereotype, + final SymbolContext symbolContext, final HorizontalAlignment stereoAlignment) { + return new AbstractTextBlock() { + + public void drawU(UGraphic ug) { + final Dimension2D dim = calculateDimension(ug.getStringBounder()); + ug = UGraphicStencil.create(ug, getRectangleStencil(dim), new UStroke()); + ug = symbolContext.apply(ug); + final Margin margin = getMargin(); + final TextBlock tb = TextBlockUtils.mergeTB(stereotype, label, stereoAlignment); + tb.drawU(ug.apply(new UTranslate(margin.getX1(), margin.getY1()))); + } + + public Dimension2D calculateDimension(StringBounder stringBounder) { + final Dimension2D dimLabel = label.calculateDimension(stringBounder); + final Dimension2D dimStereo = stereotype.calculateDimension(stringBounder); + return getMargin().addDimension(Dimension2DDouble.mergeTB(dimStereo, dimLabel)); + } + }; + } + + @Override + public TextBlock asBig(final TextBlock title, final HorizontalAlignment labelAlignment, final TextBlock stereotype, + final double width, final double height, final SymbolContext symbolContext, + final HorizontalAlignment stereoAlignment) { + return new AbstractTextBlock() { + public void drawU(UGraphic ug) { + ug = symbolContext.apply(ug); + final Dimension2D dimStereo = stereotype.calculateDimension(ug.getStringBounder()); + final double posStereoX; + final double posStereoY; + if (stereoAlignment == HorizontalAlignment.RIGHT) { + posStereoX = width - dimStereo.getWidth() - getMargin().getX1() / 2; + posStereoY = getMargin().getY1() / 2; + } else { + posStereoX = (width - dimStereo.getWidth()) / 2; + posStereoY = 2; + } + stereotype.drawU(ug.apply(new UTranslate(posStereoX, posStereoY))); + final Dimension2D dimTitle = title.calculateDimension(ug.getStringBounder()); + final double posTitle; + if (labelAlignment == HorizontalAlignment.LEFT) { + posTitle = 3; + } else if (labelAlignment == HorizontalAlignment.RIGHT) { + posTitle = width - dimTitle.getWidth() - 3; + } else { + posTitle = (width - dimTitle.getWidth()) / 2; + } + title.drawU(ug.apply(new UTranslate(posTitle, 2 + dimStereo.getHeight()))); + } + + public Dimension2D calculateDimension(StringBounder stringBounder) { + return new Dimension2DDouble(width, height); + } + }; + } + + @Override + public boolean manageHorizontalLine() { + return true; + } + +} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/graphic/USymbolRect.java b/src/net/sourceforge/plantuml/graphic/USymbolRect.java index 3daae2265..4b72f0a55 100644 --- a/src/net/sourceforge/plantuml/graphic/USymbolRect.java +++ b/src/net/sourceforge/plantuml/graphic/USymbolRect.java @@ -49,18 +49,11 @@ import net.sourceforge.plantuml.ugraphic.UTranslate; class USymbolRect extends USymbol { private final SkinParameter skinParameter; - // private final HorizontalAlignment stereotypeAlignement; public USymbolRect(SkinParameter skinParameter) { this.skinParameter = skinParameter; -// this.stereotypeAlignement = stereotypeAlignement; } -// @Override -// public USymbol withStereoAlignment(HorizontalAlignment alignment) { -// return new USymbolRect(skinParameter, alignment); -// } - @Override public SkinParameter getSkinParameter() { return skinParameter; diff --git a/src/net/sourceforge/plantuml/objectdiagram/AbstractClassOrObjectDiagram.java b/src/net/sourceforge/plantuml/objectdiagram/AbstractClassOrObjectDiagram.java index 9cf5f3fc0..b36bbb290 100644 --- a/src/net/sourceforge/plantuml/objectdiagram/AbstractClassOrObjectDiagram.java +++ b/src/net/sourceforge/plantuml/objectdiagram/AbstractClassOrObjectDiagram.java @@ -39,6 +39,8 @@ import java.util.ArrayList; import java.util.List; import net.sourceforge.plantuml.ISkinSimple; +import net.sourceforge.plantuml.OptionFlags; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.classdiagram.AbstractEntityDiagram; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.cucadiagram.Code; @@ -47,6 +49,7 @@ import net.sourceforge.plantuml.cucadiagram.DisplayPositionned; import net.sourceforge.plantuml.cucadiagram.GroupRoot; import net.sourceforge.plantuml.cucadiagram.IEntity; import net.sourceforge.plantuml.cucadiagram.IGroup; +import net.sourceforge.plantuml.cucadiagram.Ident; import net.sourceforge.plantuml.cucadiagram.LeafType; import net.sourceforge.plantuml.cucadiagram.Link; import net.sourceforge.plantuml.cucadiagram.LinkDecor; @@ -59,6 +62,16 @@ public abstract class AbstractClassOrObjectDiagram extends AbstractEntityDiagram public AbstractClassOrObjectDiagram(ISkinSimple orig) { super(orig); } + + @Override + public Ident cleanIdent(Ident ident) { + String codeString = ident.getName(); + if (codeString.startsWith("\"") && codeString.endsWith("\"")) { + return ident.eventuallyRemoveStartingAndEndingDoubleQuote("\""); + } + return ident; + } + final public boolean insertBetween(IEntity entity1, IEntity entity2, IEntity node) { final Link link = foundLink(entity1, entity2); @@ -107,24 +120,29 @@ public abstract class AbstractClassOrObjectDiagram extends AbstractEntityDiagram public CommandExecutionResult associationClass(String name1A, String name1B, String name2A, String name2B, LinkType linkType, Display label) { - final IEntity entity1A = getOrCreateLeaf(buildLeafIdent(name1A), buildCode(name1A), - null, null); - final IEntity entity1B = getOrCreateLeaf(buildLeafIdent(name1B), buildCode(name1B), - null, null); - final IEntity entity2A = getOrCreateLeaf(buildLeafIdent(name2A), buildCode(name2A), - null, null); - final IEntity entity2B = getOrCreateLeaf(buildLeafIdent(name2B), buildCode(name2B), - null, null); + final Ident ident1A = buildLeafIdent(name1A); + final Ident ident1B = buildLeafIdent(name1B); + final Ident ident2A = buildLeafIdent(name2A); + final Ident ident2B = buildLeafIdent(name2B); + final Code code1A = this.V1972() ? ident1A : buildCode(name1A); + final Code code1B = this.V1972() ? ident1B : buildCode(name1B); + final Code code2A = this.V1972() ? ident2A : buildCode(name2A); + final Code code2B = this.V1972() ? ident2B : buildCode(name2B); + final IEntity entity1A = getOrCreateLeaf(ident1A, code1A, null, null); + final IEntity entity1B = getOrCreateLeaf(ident1B, code1B, null, null); + final IEntity entity2A = getOrCreateLeaf(ident2A, code2A, null, null); + final IEntity entity2B = getOrCreateLeaf(ident2B, code2B, null, null); final List same1 = getExistingAssociatedPoints(entity1A, entity1B); final List same2 = getExistingAssociatedPoints(entity2A, entity2B); if (same1.size() == 0 && same2.size() == 0) { - final String tmp1 = UniqueSequence.getString("apoint"); - final IEntity point1 = getOrCreateLeaf(buildLeafIdent(tmp1), buildCode(tmp1), - LeafType.POINT_FOR_ASSOCIATION, null); final String tmp2 = UniqueSequence.getString("apoint"); - final IEntity point2 = getOrCreateLeaf(buildLeafIdent(tmp2), buildCode(tmp2), - LeafType.POINT_FOR_ASSOCIATION, null); + final Ident ident1 = buildLeafIdent(tmp1); + final Ident ident2 = buildLeafIdent(tmp2); + final Code code1 = this.V1972() ? ident1 : buildCode(tmp1); + final Code code2 = this.V1972() ? ident2 : buildCode(tmp2); + final IEntity point1 = getOrCreateLeaf(ident1, code1, LeafType.POINT_FOR_ASSOCIATION, null); + final IEntity point2 = getOrCreateLeaf(ident2, code2, LeafType.POINT_FOR_ASSOCIATION, null); insertPointBetween(entity1A, entity1B, point1); insertPointBetween(entity2A, entity2B, point2); @@ -176,10 +194,12 @@ public abstract class AbstractClassOrObjectDiagram extends AbstractEntityDiagram public boolean associationClass(int mode, String name1, String name2, IEntity associed, LinkType linkType, Display label) { - final IEntity entity1 = getOrCreateLeaf(buildLeafIdent(name1), buildCode(name1), null, - null); - final IEntity entity2 = getOrCreateLeaf(buildLeafIdent(name2), buildCode(name2), null, - null); + final Ident ident1 = buildLeafIdent(name1); + final Ident ident2 = buildLeafIdent(name2); + final Code code1 = this.V1972() ? ident1 : buildCode(name1); + final Code code2 = this.V1972() ? ident2 : buildCode(name2); + final IEntity entity1 = getOrCreateLeaf(ident1, code1, null, null); + final IEntity entity2 = getOrCreateLeaf(ident2, code2, null, null); final List same = getExistingAssociatedPoints(entity1, entity2); if (same.size() > 1) { return false; @@ -227,8 +247,9 @@ public abstract class AbstractClassOrObjectDiagram extends AbstractEntityDiagram this.entity2 = entity2; this.associed = associed; final String idShort = UniqueSequence.getString("apoint"); - point = getOrCreateLeaf(buildLeafIdent(idShort), buildCode(idShort), - LeafType.POINT_FOR_ASSOCIATION, null); + final Ident ident = buildLeafIdent(idShort); + final Code code = AbstractClassOrObjectDiagram.this.V1972() ? ident : buildCode(idShort); + point = getOrCreateLeaf(ident, code, LeafType.POINT_FOR_ASSOCIATION, null); } diff --git a/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObject.java b/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObject.java index 4599c0b39..152f43e72 100644 --- a/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObject.java +++ b/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObject.java @@ -37,6 +37,7 @@ package net.sourceforge.plantuml.objectdiagram.command; import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.LineLocation; +import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.UrlBuilder; import net.sourceforge.plantuml.UrlBuilder.ModeUrl; @@ -79,15 +80,15 @@ public class CommandCreateEntityObject extends SingleLineCommand2 environment = new LinkedHashMap(); private final Map values = new LinkedHashMap(); - private final Map savedState = new LinkedHashMap(); @Deprecated @ApiWarning(willBeRemoved = "in next major release") @@ -75,6 +78,15 @@ public class Defines implements Truth { return new Defines(); } + public void copyTo(TMemory memory) throws EaterException { + for (Entry ent : values.entrySet()) { + final String name = ent.getKey(); + final Define def = ent.getValue(); + memory.putVariable(name, def.asTVariable(), TVariableScope.GLOBAL); + } + + } + public void overrideFilename(String filename) { if (filename != null) { environment.put("filename", filename); @@ -244,15 +256,4 @@ public class Defines implements Truth { return line; } - public void saveState1() { - this.savedState.putAll(values); - - } - - public void restoreState1() { - this.values.clear(); - this.values.putAll(savedState); - magic = null; - } - } diff --git a/src/net/sourceforge/plantuml/preproc/DefinesGet.java b/src/net/sourceforge/plantuml/preproc/DefinesGet.java deleted file mode 100644 index 2d5432f99..000000000 --- a/src/net/sourceforge/plantuml/preproc/DefinesGet.java +++ /dev/null @@ -1,58 +0,0 @@ -/* ======================================================================== - * PlantUML : a free UML diagram generator - * ======================================================================== - * - * (C) Copyright 2009-2020, 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.preproc; - -public class DefinesGet { - - private final Defines defines; - - public DefinesGet(Defines defines) { - this.defines = defines; - } - - public final Defines get() { - return defines; - } - - public void saveState() { - this.defines.saveState1(); - } - - public void restoreState() { - this.defines.restoreState1(); - } - -} diff --git a/src/net/sourceforge/plantuml/preproc/FileWithSuffix.java b/src/net/sourceforge/plantuml/preproc/FileWithSuffix.java index 8e897f06d..b0fe17e9a 100644 --- a/src/net/sourceforge/plantuml/preproc/FileWithSuffix.java +++ b/src/net/sourceforge/plantuml/preproc/FileWithSuffix.java @@ -60,9 +60,16 @@ public class FileWithSuffix { @Override public String toString() { + if (file == null) { + return super.toString(); + } return file.toString(); } + public Reader getReader(String charset) throws IOException { + if (file == null) { + return null; + } if (entry == null) { if (charset == null) { Log.info("Using default charset"); @@ -108,45 +115,33 @@ public class FileWithSuffix { this.file = new AFileRegular(file); this.suffix = suffix; this.entry = null; - // this.description = file.getAbsolutePath(); this.description = getFileName(file); } - public static String getFileName(File file) { - return file.getName(); - } - - public static String getAbsolutePath(File file) { - return file.getAbsolutePath(); - } - - public FileWithSuffix(ImportedFiles importedFiles, String fileName, String suffix) throws IOException { - final int idx = fileName.indexOf('~'); + FileWithSuffix(String description, String suffix, AFile file, String entry) { + this.description = description; this.suffix = suffix; - if (idx == -1) { - this.file = importedFiles.getAFile(fileName); - this.entry = null; - } else { - this.file = importedFiles.getAFile(fileName.substring(0, idx)); - this.entry = fileName.substring(idx + 1); - } - - if (file == null) { - this.description = fileName; - } else if (entry == null) { - // this.description = file.getAbsolutePath(); - this.description = fileName; - } else { - // this.description = file.getAbsolutePath() + "~" + entry; - this.description = fileName; - } + this.file = file; + this.entry = entry; + } + static FileWithSuffix none() { + return new FileWithSuffix("NONE", null, null, null); } @Override public int hashCode() { - return (file == null ? 0 : file.hashCode()) + (suffix == null ? 0 : suffix.hashCode() * 43) - + (entry == null ? 0 : entry.hashCode()); + int v = 0; + if (file != null) { + v += file.hashCode(); + } + if (suffix != null) { + v += suffix.hashCode() * 43; + } + if (entry != null) { + v += entry.hashCode(); + } + return v; } @Override @@ -165,6 +160,23 @@ public class FileWithSuffix { return false; } + public AParentFolder getParentFile() { + if (file == null) { + return null; + } + Log.info("Getting parent of " + file); + Log.info("-->The parent is " + file.getParentFile()); + return file.getParentFile(); + } + + public String getDescription() { + return description; + } + + public final String getSuffix() { + return suffix; + } + private static boolean equals(String s1, String s2) { if (s1 == null && s2 == null) { return true; @@ -184,22 +196,8 @@ public class FileWithSuffix { return result; } - public AParentFolder getParentFile() { - Log.info("Getting parent of " + file); - Log.info("-->The parent is " + file.getParentFile()); - return file.getParentFile(); - } - - public String getDescription() { - return description; - } - - public final String getSuffix() { - return suffix; - } - - public String toStringDebug() { - return file.getAbsolutePath(); + public static String getFileName(File file) { + return file.getName(); } } diff --git a/src/net/sourceforge/plantuml/preproc/IfManager.java b/src/net/sourceforge/plantuml/preproc/IfManager.java deleted file mode 100644 index d5a396f60..000000000 --- a/src/net/sourceforge/plantuml/preproc/IfManager.java +++ /dev/null @@ -1,126 +0,0 @@ -/* ======================================================================== - * PlantUML : a free UML diagram generator - * ======================================================================== - * - * (C) Copyright 2009-2020, 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.preproc; - -import java.io.IOException; - -import net.sourceforge.plantuml.StringLocated; -import net.sourceforge.plantuml.command.regex.Matcher2; -import net.sourceforge.plantuml.command.regex.MyPattern; -import net.sourceforge.plantuml.command.regex.Pattern2; -import net.sourceforge.plantuml.version.Version; - -public class IfManager extends ReadLineInstrumented implements ReadLine { - - protected static final Pattern2 ifdefPattern = MyPattern.cmpile("^[%s]*!if(n)?def[%s]+(.+)$"); - protected static final Pattern2 ifcomparePattern = MyPattern - .cmpile("^[%s]*!if[%s]+\\%(\\w+)\\%[%s]*(\\<|\\<=|\\>|\\>=|=|==|!=|\\<\\>)[%s]*(\\d+)$"); - protected static final Pattern2 elsePattern = MyPattern.cmpile("^[%s]*!else[%s]*$"); - protected static final Pattern2 endifPattern = MyPattern.cmpile("^[%s]*!endif[%s]*$"); - - private final DefinesGet defines; - private final ReadLine source; - - private IfManager child; - - public IfManager(ReadLine source, DefinesGet defines) { - this.defines = defines; - this.source = source; - } - - @Override - final StringLocated readLineInst() throws IOException { - if (child != null) { - final StringLocated s = child.readLine(); - if (s != null) { - return s; - } - child = null; - } - - return readLineInternal(); - } - - protected StringLocated readLineInternal() throws IOException { - final StringLocated s = source.readLine(); - if (s == null) { - return null; - } - - Matcher2 m = ifcomparePattern.matcher(s.getString()); - if (m.find()) { - final int value1 = getValue(m.group(1)); - final String operator = m.group(2); - final int value2 = Integer.parseInt(m.group(3)); - final boolean ok = new NumericCompare(operator).isCompareOk(value1, value2); - if (ok) { - child = new IfManagerPositif(source, defines); - } else { - child = new IfManagerNegatif(source, defines); - } - return this.readLine(); - } - - m = ifdefPattern.matcher(s.getString()); - if (m.find()) { - boolean ok = defines.get().isDefine(m.group(2)); - if (m.group(1) != null) { - ok = !ok; - } - if (ok) { - child = new IfManagerPositif(source, defines); - } else { - child = new IfManagerNegatif(source, defines); - } - return this.readLine(); - } - - return s; - } - - private int getValue(final String arg) { - if (arg.equalsIgnoreCase("PLANTUML_VERSION")) { - return Version.versionPatched(); - } - return 0; - } - - @Override - void closeInst() throws IOException { - source.close(); - } - -} diff --git a/src/net/sourceforge/plantuml/preproc/IfManagerNegatif.java b/src/net/sourceforge/plantuml/preproc/IfManagerNegatif.java deleted file mode 100644 index 730df803f..000000000 --- a/src/net/sourceforge/plantuml/preproc/IfManagerNegatif.java +++ /dev/null @@ -1,83 +0,0 @@ -/* ======================================================================== - * PlantUML : a free UML diagram generator - * ======================================================================== - * - * (C) Copyright 2009-2020, 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.preproc; - -import java.io.IOException; - -import net.sourceforge.plantuml.StringLocated; -import net.sourceforge.plantuml.command.regex.Matcher2; - -class IfManagerNegatif extends IfManager { - - private boolean skippingDone = false; - - public IfManagerNegatif(ReadLine source, DefinesGet defines) { - super(source, defines); - } - - @Override - protected StringLocated readLineInternal() throws IOException { - if (skippingDone == false) { - skippingDone = true; - do { - final StringLocated s = readLine(); - if (s == null) { - return null; - } - Matcher2 m = endifPattern.matcher(s.getString()); - if (m.find()) { - return null; - } - m = elsePattern.matcher(s.getString()); - if (m.find()) { - break; - } - } while (true); - } - - final StringLocated s = super.readLineInternal(); - if (s == null) { - return null; - } - final Matcher2 m = endifPattern.matcher(s.getString()); - if (m.find()) { - return null; - } - return s; - - } - -} diff --git a/src/net/sourceforge/plantuml/preproc/IfManagerPositif.java b/src/net/sourceforge/plantuml/preproc/IfManagerPositif.java deleted file mode 100644 index eef7e6a41..000000000 --- a/src/net/sourceforge/plantuml/preproc/IfManagerPositif.java +++ /dev/null @@ -1,75 +0,0 @@ -/* ======================================================================== - * PlantUML : a free UML diagram generator - * ======================================================================== - * - * (C) Copyright 2009-2020, 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.preproc; - -import java.io.IOException; - -import net.sourceforge.plantuml.StringLocated; -import net.sourceforge.plantuml.command.regex.Matcher2; - -class IfManagerPositif extends IfManager { - - public IfManagerPositif(ReadLine source, DefinesGet defines) { - super(source, defines); - } - - @Override - protected StringLocated readLineInternal() throws IOException { - StringLocated s = super.readLineInternal(); - if (s == null) { - return null; - } - Matcher2 m = endifPattern.matcher(s.getString()); - if (m.find()) { - return null; - } - m = elsePattern.matcher(s.getString()); - if (m.find()) { - do { - s = readLine(); - if (s == null) { - return null; - } - m = endifPattern.matcher(s.getString()); - if (m.find()) { - return null; - } - } while (true); - } - return s; - } - -} diff --git a/src/net/sourceforge/plantuml/preproc/ImportedFiles.java b/src/net/sourceforge/plantuml/preproc/ImportedFiles.java index 24634aa64..cfe99179c 100644 --- a/src/net/sourceforge/plantuml/preproc/ImportedFiles.java +++ b/src/net/sourceforge/plantuml/preproc/ImportedFiles.java @@ -47,9 +47,11 @@ import net.sourceforge.plantuml.AFileZipEntry; import net.sourceforge.plantuml.AParentFolder; import net.sourceforge.plantuml.FileSystem; import net.sourceforge.plantuml.Log; +import net.sourceforge.plantuml.OptionFlags; public class ImportedFiles { + private static final List INCLUDE_PATH = FileSystem.getPath("plantuml.include.path", true); private final List imported; private final AParentFolder currentDir; @@ -75,8 +77,8 @@ public class ImportedFiles { } public AFile getAFile(String nameOrPath) throws IOException { - Log.info("ImportedFiles::getAFile nameOrPath = " + nameOrPath); - Log.info("ImportedFiles::getAFile currentDir = " + currentDir); + // Log.info("ImportedFiles::getAFile nameOrPath = " + nameOrPath); + // Log.info("ImportedFiles::getAFile currentDir = " + currentDir); final AParentFolder dir = currentDir; if (dir == null || isAbsolute(nameOrPath)) { return new AFileRegular(new File(nameOrPath).getCanonicalFile()); @@ -105,7 +107,7 @@ public class ImportedFiles { public List getPath() { final List result = new ArrayList(imported); - result.addAll(FileSystem.getPath("plantuml.include.path", true)); + result.addAll(INCLUDE_PATH); result.addAll(FileSystem.getPath("java.class.path", true)); return result; } @@ -123,4 +125,35 @@ public class ImportedFiles { return currentDir; } + public FileWithSuffix getFile(String filename, String suffix) throws IOException { + final int idx = filename.indexOf('~'); + final AFile file; + final String entry; + if (idx == -1) { + file = getAFile(filename); + entry = null; + } else { + file = getAFile(filename.substring(0, idx)); + entry = filename.substring(idx + 1); + } + if (isAllowed(file) == false) { + return FileWithSuffix.none(); + } + return new FileWithSuffix(filename, suffix, file, entry); + } + + private boolean isAllowed(AFile file) throws IOException { + if (OptionFlags.ALLOW_INCLUDE) { + return true; + } + if (file != null) { + final File folder = file.getSystemFolder(); + // System.err.println("canonicalPath=" + path + " " + folder + " " + INCLUDE_PATH); + if (INCLUDE_PATH.contains(folder)) { + return true; + } + } + return false; + } + } diff --git a/src/net/sourceforge/plantuml/preproc/PreprocessorChangeModeReader.java b/src/net/sourceforge/plantuml/preproc/PreprocessorChangeModeReader.java deleted file mode 100644 index 76911c8d4..000000000 --- a/src/net/sourceforge/plantuml/preproc/PreprocessorChangeModeReader.java +++ /dev/null @@ -1,67 +0,0 @@ -/* ======================================================================== - * PlantUML : a free UML diagram generator - * ======================================================================== - * - * (C) Copyright 2009-2020, 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.preproc; - -import java.io.IOException; - -import net.sourceforge.plantuml.StringLocated; -import net.sourceforge.plantuml.preproc2.PreprocessorMode; -import net.sourceforge.plantuml.preproc2.PreprocessorModeSet; - -public class PreprocessorChangeModeReader implements ReadLine { - - private final ReadLine raw; - private final PreprocessorModeSet mode; - - public PreprocessorChangeModeReader(ReadLine source, PreprocessorModeSet mode) { - this.raw = source; - this.mode = mode; - } - - public void close() throws IOException { - raw.close(); - } - - public StringLocated readLine() throws IOException { - final StringLocated line = raw.readLine(); - if (line != null && line.getTrimmed().getString().endsWith("!preprocessorV2")) { - this.mode.setPreprocessorMode(PreprocessorMode.V2_NEW_TIM); - return new StringLocated("", line.getLocation()); - } - return line; - } - -} diff --git a/src/net/sourceforge/plantuml/preproc/ReadLineEmpty.java b/src/net/sourceforge/plantuml/preproc/ReadLineEmpty.java deleted file mode 100644 index 6fe00acf0..000000000 --- a/src/net/sourceforge/plantuml/preproc/ReadLineEmpty.java +++ /dev/null @@ -1,49 +0,0 @@ -/* ======================================================================== - * PlantUML : a free UML diagram generator - * ======================================================================== - * - * (C) Copyright 2009-2020, 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.preproc; - -import net.sourceforge.plantuml.StringLocated; - -public class ReadLineEmpty implements ReadLine { - - public void close() { - } - - public StringLocated readLine() { - return null; - } - -} diff --git a/src/net/sourceforge/plantuml/preproc/ReadLineInstrumented.java b/src/net/sourceforge/plantuml/preproc/ReadLineInstrumented.java deleted file mode 100644 index 790c66695..000000000 --- a/src/net/sourceforge/plantuml/preproc/ReadLineInstrumented.java +++ /dev/null @@ -1,98 +0,0 @@ -/* ======================================================================== - * PlantUML : a free UML diagram generator - * ======================================================================== - * - * (C) Copyright 2009-2020, 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.preproc; - -import java.io.IOException; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.atomic.AtomicLong; - -import net.sourceforge.plantuml.Log; -import net.sourceforge.plantuml.StringLocated; - -public abstract class ReadLineInstrumented implements ReadLine { - - private static final boolean TRACE = false; - - private static ConcurrentMap durations = new ConcurrentHashMap(); - private static ConcurrentMap maxes = new ConcurrentHashMap(); - - private long current = 0; - - private AtomicLong get(ConcurrentMap source) { - AtomicLong result = source.get(getClass()); - if (result == null) { - result = new AtomicLong(); - source.put(getClass(), result); - } - return result; - } - - public final StringLocated readLine() throws IOException { - if (TRACE == false) { - return readLineInst(); - } - final long now = System.currentTimeMillis(); - try { - return readLineInst(); - } finally { - final long time = System.currentTimeMillis() - now; - current += time; - get(durations).addAndGet(time); - } - } - - @Override - public String toString() { - return super.toString() + " current=" + current; - } - - abstract StringLocated readLineInst() throws IOException; - - public final void close() throws IOException { - if (TRACE) { - if (current > get(maxes).get()) { - get(maxes).set(current); - } - Log.info("DURATION::" + getClass() + " duration= " + get(durations).get() + " current=" + current + " max=" - + get(maxes).get()); - } - closeInst(); - } - - abstract void closeInst() throws IOException; - -} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/preproc/ReadLineReader.java b/src/net/sourceforge/plantuml/preproc/ReadLineReader.java index 547816a97..a7f5b68fb 100644 --- a/src/net/sourceforge/plantuml/preproc/ReadLineReader.java +++ b/src/net/sourceforge/plantuml/preproc/ReadLineReader.java @@ -44,9 +44,8 @@ import net.sourceforge.plantuml.LineLocationImpl; import net.sourceforge.plantuml.Log; import net.sourceforge.plantuml.StringLocated; -public class ReadLineReader extends ReadLineInstrumented implements ReadLine { +public class ReadLineReader implements ReadLine { - // private static final int LIMIT = 850; private final BufferedReader br; private LineLocationImpl location; private final String description; @@ -78,8 +77,7 @@ public class ReadLineReader extends ReadLineInstrumented implements ReadLine { return new ReadLineReader(reader, description, parent); } - @Override - StringLocated readLineInst() throws IOException { + public StringLocated readLine() throws IOException { String s = br.readLine(); location = location.oneLineRead(); if (s == null) { @@ -108,8 +106,7 @@ public class ReadLineReader extends ReadLineInstrumented implements ReadLine { return new StringLocated(s, location); } - @Override - void closeInst() throws IOException { + public void close() throws IOException { br.close(); } diff --git a/src/net/sourceforge/plantuml/preproc/Sub.java b/src/net/sourceforge/plantuml/preproc/Sub.java index a29040195..91f09e6ca 100644 --- a/src/net/sourceforge/plantuml/preproc/Sub.java +++ b/src/net/sourceforge/plantuml/preproc/Sub.java @@ -35,27 +35,64 @@ */ package net.sourceforge.plantuml.preproc; +import java.io.IOException; import java.util.ArrayList; +import java.util.Collections; import java.util.List; -import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.StringLocated; +import net.sourceforge.plantuml.tim.EaterException; +import net.sourceforge.plantuml.tim.EaterStartsub; +import net.sourceforge.plantuml.tim.TContext; +import net.sourceforge.plantuml.tim.TLineType; +import net.sourceforge.plantuml.tim.TMemory; public class Sub { private final String name; - private final List lines = new ArrayList(); + private final List lines = new ArrayList(); public Sub(String name) { this.name = name; } - public void add(StringLocated s) { - this.lines.add(s.getString()); + @Override + public String toString() { + return super.toString() + " " + name; } - public ReadLine getReadLine(LineLocation lineLocation) { - return new ReadLineList(lines, lineLocation); + public void add(StringLocated s) { + this.lines.add(s); + } + + public final List lines() { + return Collections.unmodifiableList(lines); + } + + public static Sub fromFile(ReadLine reader, String blocname, TContext context, TMemory memory) throws IOException, + EaterException { + Sub result = null; + StringLocated s = null; + while ((s = reader.readLine()) != null) { + final TLineType type = TLineType.getFromLine(s.getTrimmed().getString()); + if (type == TLineType.STARTSUB) { + final EaterStartsub eater = new EaterStartsub(s.getTrimmed().getString()); + eater.execute(context, memory); + if (eater.getSubname().equals(blocname)) { + result = new Sub(blocname); + } + continue; + } + if (type == TLineType.ENDSUB && result != null) { + reader.close(); + return result; + } + if (result != null) { + result.add(s); + } + } + reader.close(); + return null; } } \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/preproc/Sub2.java b/src/net/sourceforge/plantuml/preproc/Sub2.java deleted file mode 100644 index 3c9c148c2..000000000 --- a/src/net/sourceforge/plantuml/preproc/Sub2.java +++ /dev/null @@ -1,93 +0,0 @@ -/* ======================================================================== - * PlantUML : a free UML diagram generator - * ======================================================================== - * - * (C) Copyright 2009-2020, 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.preproc; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import net.sourceforge.plantuml.StringLocated; -import net.sourceforge.plantuml.tim.EaterException; -import net.sourceforge.plantuml.tim.EaterStartsub; -import net.sourceforge.plantuml.tim.TContext; -import net.sourceforge.plantuml.tim.TLineType; -import net.sourceforge.plantuml.tim.TMemory; - -public class Sub2 { - - private final String name; - private final List lines = new ArrayList(); - - public Sub2(String name) { - this.name = name; - } - - public void add(StringLocated s) { - this.lines.add(s); - } - - public final List lines() { - return Collections.unmodifiableList(lines); - } - - public static Sub2 fromFile(ReadLine reader, String blocname, TContext context, TMemory memory) throws IOException, - EaterException { - Sub2 result = null; - StringLocated s = null; - while ((s = reader.readLine()) != null) { - final TLineType type = TLineType.getFromLine(s.getTrimmed().getString()); - if (type == TLineType.STARTSUB) { - final EaterStartsub eater = new EaterStartsub(s.getTrimmed().getString()); - eater.execute(context, memory); - if (eater.getSubname().equals(blocname)) { - result = new Sub2(blocname); - } - continue; - } - if (type == TLineType.ENDSUB && result != null) { - reader.close(); - return result; - } - if (result != null) { - result.add(s); - } - } - reader.close(); - return null; - } - -} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/preproc/UncommentReadLine.java b/src/net/sourceforge/plantuml/preproc/UncommentReadLine.java index 95cf5cfae..1a19d5ebb 100644 --- a/src/net/sourceforge/plantuml/preproc/UncommentReadLine.java +++ b/src/net/sourceforge/plantuml/preproc/UncommentReadLine.java @@ -43,7 +43,7 @@ import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.command.regex.Pattern2; import net.sourceforge.plantuml.utils.StartUtils; -public class UncommentReadLine extends ReadLineInstrumented implements ReadLine { +public class UncommentReadLine implements ReadLine { private static final Pattern2 unpause = MyPattern.cmpile(StartUtils.PAUSE_PATTERN); @@ -55,13 +55,7 @@ public class UncommentReadLine extends ReadLineInstrumented implements ReadLine this.raw = source; } - @Override - public String toString() { - return "UncommentReadLine of " + raw; - } - - @Override - StringLocated readLineInst() throws IOException { + public StringLocated readLine() throws IOException { final StringLocated result = raw.readLine(); if (result == null) { @@ -87,8 +81,7 @@ public class UncommentReadLine extends ReadLineInstrumented implements ReadLine return result; } - @Override - void closeInst() throws IOException { + public void close() throws IOException { this.raw.close(); } diff --git a/src/net/sourceforge/plantuml/preproc2/Preprocessor.java b/src/net/sourceforge/plantuml/preproc2/Preprocessor.java index 329408bcd..cc8b30a34 100644 --- a/src/net/sourceforge/plantuml/preproc2/Preprocessor.java +++ b/src/net/sourceforge/plantuml/preproc2/Preprocessor.java @@ -37,67 +37,27 @@ package net.sourceforge.plantuml.preproc2; import java.io.IOException; import java.util.Collections; -import java.util.HashSet; import java.util.List; import java.util.Set; -import net.sourceforge.plantuml.DefinitionsContainer; import net.sourceforge.plantuml.StringLocated; -import net.sourceforge.plantuml.preproc.Defines; -import net.sourceforge.plantuml.preproc.DefinesGet; import net.sourceforge.plantuml.preproc.FileWithSuffix; -import net.sourceforge.plantuml.preproc.IfManagerFilter; -import net.sourceforge.plantuml.preproc.ImportedFiles; import net.sourceforge.plantuml.preproc.ReadLine; import net.sourceforge.plantuml.preproc.ReadLineNumbered; public class Preprocessor implements ReadLineNumbered { private final ReadLine source; - private final PreprocessorInclude include; - private final PreprocessorModeSet mode; - private final ReadLine sourceV2; - - public Preprocessor(List config, ReadLine reader, String charset, Defines defines, - DefinitionsContainer definitionsContainer, ImportedFiles importedFiles) throws IOException { - this(config, reader, charset, new DefinesGet(defines), definitionsContainer, new HashSet(), - importedFiles, true); - } - - Preprocessor(List config, ReadLine reader, String charset, DefinesGet defines, - DefinitionsContainer definitionsContainer, Set filesUsedGlobal, - ImportedFiles importedFiles, boolean doSaveState) throws IOException { - this.mode = definitionsContainer; - if (doSaveState) { - defines.saveState(); - } - final ReadFilterAnd filtersV2 = new ReadFilterAnd(); - filtersV2.add(new ReadLineQuoteComment(true)); - filtersV2.add(new ReadLineAddConfig(config)); - this.sourceV2 = filtersV2.applyFilter(reader); + public Preprocessor(List config, ReadLine reader) throws IOException { final ReadFilterAnd filters = new ReadFilterAnd(); - filters.add(new ReadLineQuoteComment(false)); - include = new PreprocessorInclude(config, charset, defines, definitionsContainer, importedFiles, - filesUsedGlobal); - filters.add(new ReadLineAddConfig(config)); - filters.add(new IfManagerFilter(defines)); - filters.add(new PreprocessorDefineApply(defines)); - filters.add(new SubPreprocessor(charset, definitionsContainer)); - filters.add(new PreprocessorDefineLearner(defines, importedFiles.getCurrentDir())); - filters.add(include); - + // filters.add(new ReadLineQuoteComment(true)); + filters.add(new ReadFilterAddConfig(config)); + filters.add(new ReadFilterMergeLines()); this.source = filters.applyFilter(reader); } - private boolean isV2() { - return mode != null && mode.getPreprocessorMode() == PreprocessorMode.V2_NEW_TIM; - } - public StringLocated readLine() throws IOException { - if (isV2()) { - return sourceV2.readLine(); - } return source.readLine(); } @@ -107,7 +67,7 @@ public class Preprocessor implements ReadLineNumbered { public Set getFilesUsed() { // System.err.println("************************** WARNING **************************"); - // return Collections.emptySet(); - return Collections.unmodifiableSet(include.getFilesUsedGlobal()); + return Collections.emptySet(); + // return Collections.unmodifiableSet(include.getFilesUsedGlobal()); } } \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/preproc2/PreprocessorDefineApply.java b/src/net/sourceforge/plantuml/preproc2/PreprocessorDefineApply.java deleted file mode 100644 index 825bbc93d..000000000 --- a/src/net/sourceforge/plantuml/preproc2/PreprocessorDefineApply.java +++ /dev/null @@ -1,91 +0,0 @@ -/* ======================================================================== - * PlantUML : a free UML diagram generator - * ======================================================================== - * - * (C) Copyright 2009-2020, 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.preproc2; - -import java.io.IOException; -import java.util.List; - -import net.sourceforge.plantuml.StringLocated; -import net.sourceforge.plantuml.preproc.DefinesGet; -import net.sourceforge.plantuml.preproc.ReadLine; -import net.sourceforge.plantuml.preproc.ReadLineList; - -public class PreprocessorDefineApply implements ReadFilter { - - private final DefinesGet defines; - - public PreprocessorDefineApply(DefinesGet defines) throws IOException { - this.defines = defines; - } - - public ReadLine applyFilter(final ReadLine source) { - return new Inner(source); - } - - class Inner extends ReadLineInsertable { - - final ReadLine source; - - Inner(ReadLine source) { - this.source = source; - } - - @Override - void closeInternal() throws IOException { - source.close(); - } - - @Override - StringLocated readLineInternal() throws IOException { - final StringLocated s = this.source.readLine(); - if (s == null || s.getPreprocessorError() != null) { - return s; - } - if (PreprocessorDefineLearner.isLearningLine(s)) { - return s; - } - final List result = defines.get().applyDefines(s.getString()); - if (result.size() > 1) { - insert(new ReadLineList(result, s.getLocation())); - return readLine(); - } - String tmp = result.get(0); - return new StringLocated(tmp, s.getLocation(), s.getPreprocessorError()); - } - - } - -} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/preproc2/PreprocessorDefineLearner.java b/src/net/sourceforge/plantuml/preproc2/PreprocessorDefineLearner.java deleted file mode 100644 index fa9dbec4b..000000000 --- a/src/net/sourceforge/plantuml/preproc2/PreprocessorDefineLearner.java +++ /dev/null @@ -1,182 +0,0 @@ -/* ======================================================================== - * PlantUML : a free UML diagram generator - * ======================================================================== - * - * (C) Copyright 2009-2020, 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.preproc2; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import net.sourceforge.plantuml.AParentFolder; -import net.sourceforge.plantuml.StringLocated; -import net.sourceforge.plantuml.StringUtils; -import net.sourceforge.plantuml.command.regex.Matcher2; -import net.sourceforge.plantuml.command.regex.MyPattern; -import net.sourceforge.plantuml.command.regex.Pattern2; -import net.sourceforge.plantuml.preproc.DefinesGet; -import net.sourceforge.plantuml.preproc.ReadLine; -import net.sourceforge.plantuml.utils.StartUtils; - -public class PreprocessorDefineLearner implements ReadFilter { - - private static final String END_DEFINE_LONG = "!enddefinelong"; - private static final String ID = "[A-Za-z_][A-Za-z_0-9]*"; - private static final String ID_ARG = "\\s*[A-Za-z_][A-Za-z_0-9]*\\s*(?:=\\s*(?:\"[^\"]*\"|'[^']*')\\s*)?"; - private static final String ARG = "(?:\\(" + ID_ARG + "(?:," + ID_ARG + ")*?\\))?"; - private static final Pattern2 defineShortPattern = MyPattern.cmpile("^[%s]*!define[%s]+(" + ID + ARG + ")" - + "(?:[%s]+(.*))?$"); - private static final Pattern2 filenamePattern = MyPattern.cmpile("^[%s]*!filename[%s]+(.+)$"); - private static final Pattern2 undefPattern = MyPattern.cmpile("^[%s]*!undef[%s]+(" + ID + ")$"); - private static final Pattern2 definelongPattern = MyPattern.cmpile("^[%s]*!definelong[%s]+(" + ID + ARG + ")"); - private static final Pattern2 enddefinelongPattern = MyPattern.cmpile("^[%s]*" + END_DEFINE_LONG + "[%s]*$"); - - private final DefinesGet defines; - private final AParentFolder currentDir; - - public PreprocessorDefineLearner(DefinesGet defines, AParentFolder currentDir) { - this.defines = defines; - this.currentDir = currentDir; - } - - public static boolean isLearningLine(StringLocated s) { - Matcher2 m = defineShortPattern.matcher(s.getString()); - if (m.find()) { - return true; - } - m = definelongPattern.matcher(s.getString()); - if (m.find()) { - return true; - } - m = undefPattern.matcher(s.getString()); - if (m.find()) { - return true; - } - return false; - } - - public ReadLine applyFilter(final ReadLine source) { - return new ReadLine() { - - public void close() throws IOException { - source.close(); - } - - public StringLocated readLine() throws IOException { - while (true) { - final StringLocated s = source.readLine(); - if (s == null || s.getPreprocessorError() != null) { - return s; - } - if (StartUtils.isArobaseStartDiagram(s.getString())) { - defines.restoreState(); - return s; - } - - Matcher2 m = filenamePattern.matcher(s.getString()); - if (m.find()) { - manageFilename(m); - continue; - } - m = defineShortPattern.matcher(s.getString()); - if (m.find()) { - manageDefineShort(source, m, s.getString().trim().endsWith("()")); - continue; - } - m = definelongPattern.matcher(s.getString()); - if (m.find()) { - manageDefineLong(source, m, s.getString().trim().endsWith("()")); - continue; - } - - m = undefPattern.matcher(s.getString()); - if (m.find()) { - manageUndef(m); - continue; - } - return s; - } - } - }; - } - - private void manageUndef(Matcher2 m) throws IOException { - defines.get().undefine(m.group(1)); - } - - private void manageDefineLong(ReadLine source, Matcher2 m, boolean emptyParentheses) throws IOException { - final String group1 = m.group(1); - final List def = new ArrayList(); - while (true) { - final StringLocated read = source.readLine(); - if (read == null) { - return; - } - if (enddefinelongPattern.matcher(read.getString()).find()) { - defines.get().define(group1, def, emptyParentheses, currentDir); - return; - } - def.add(read.getString()); - } - } - - private void manageFilename(Matcher2 m) { - final String group1 = m.group(1); - this.defines.get().overrideFilename(group1); - } - - private void manageDefineShort(ReadLine source, Matcher2 m, boolean emptyParentheses) throws IOException { - final String group1 = m.group(1); - final String group2 = m.group(2); - if (group2 == null) { - defines.get().define(group1, null, emptyParentheses, null); - } else { - final List strings = defines.get().applyDefines(group2); - if (strings.size() > 1) { - defines.get().define(group1, strings, emptyParentheses, null); - } else { - final StringBuilder value = new StringBuilder(strings.get(0)); - while (StringUtils.endsWithBackslash(value.toString())) { - value.setLength(value.length() - 1); - final StringLocated read = source.readLine(); - value.append(read.getString()); - } - final List li = new ArrayList(); - li.add(value.toString()); - defines.get().define(group1, li, emptyParentheses, null); - } - } - } - -} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/preproc2/PreprocessorInclude.java b/src/net/sourceforge/plantuml/preproc2/PreprocessorInclude.java deleted file mode 100644 index a448fba2a..000000000 --- a/src/net/sourceforge/plantuml/preproc2/PreprocessorInclude.java +++ /dev/null @@ -1,382 +0,0 @@ -/* ======================================================================== - * PlantUML : a free UML diagram generator - * ======================================================================== - * - * (C) Copyright 2009-2020, 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 - * Modified by: Nicolas Jouanin - * - * - */ -package net.sourceforge.plantuml.preproc2; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import net.sourceforge.plantuml.DefinitionsContainer; -import net.sourceforge.plantuml.FileSystem; -import net.sourceforge.plantuml.Log; -import net.sourceforge.plantuml.OptionFlags; -import net.sourceforge.plantuml.StringLocated; -import net.sourceforge.plantuml.StringUtils; -import net.sourceforge.plantuml.command.regex.Matcher2; -import net.sourceforge.plantuml.command.regex.MyPattern; -import net.sourceforge.plantuml.command.regex.Pattern2; -import net.sourceforge.plantuml.preproc.DefinesGet; -import net.sourceforge.plantuml.preproc.FileWithSuffix; -import net.sourceforge.plantuml.preproc.ImportedFiles; -import net.sourceforge.plantuml.preproc.ReadLine; -import net.sourceforge.plantuml.preproc.ReadLineEmpty; -import net.sourceforge.plantuml.preproc.ReadLineList; -import net.sourceforge.plantuml.preproc.ReadLineReader; -import net.sourceforge.plantuml.preproc.ReadLineSimple; -import net.sourceforge.plantuml.preproc.ReadLineSingle; -import net.sourceforge.plantuml.preproc.StartDiagramExtractReader; -import net.sourceforge.plantuml.preproc.Stdlib; -import net.sourceforge.plantuml.tim.EaterException; -import net.sourceforge.plantuml.utils.StartUtils; - -public class PreprocessorInclude implements ReadFilter { - - private static final Pattern2 includeDefPattern = MyPattern.cmpile("^[%s]*!includedef[%s]+[%g]?([^%g]+)[%g]?$"); - - private static final Pattern2 includeDefaultStrategy = MyPattern.cmpile("^[%s]*!default_include[%s]+(once|many)$"); - - private static final Pattern2 includePattern = MyPattern.cmpile("^[%s]*!include[%s]+[%g]?([^%g]+)[%g]?$"); - private static final Pattern2 includeManyPattern = MyPattern.cmpile("^[%s]*!include_many[%s]+[%g]?([^%g]+)[%g]?$"); - private static final Pattern2 includeOncePattern = MyPattern.cmpile("^[%s]*!include_once[%s]+[%g]?([^%g]+)[%g]?$"); - - private static final Pattern2 importPattern = MyPattern.cmpile("^[%s]*!import[%s]+[%g]?([^%g]+)[%g]?$"); - private static final Pattern2 includePatternStdlib = MyPattern.cmpile("^[%s]*!include[%s]+(\\<[^%g]+\\>)$"); - private static final Pattern2 includeURLPattern = MyPattern.cmpile("^[%s]*!includeurl[%s]+[%g]?([^%g]+)[%g]?$"); - - private final String charset; - private final DefinesGet defines; - private final List config; - private final DefinitionsContainer definitionsContainer; - private final ImportedFiles importedFiles; - - private final Set filesUsedCurrent = new HashSet(); - private final Set filesUsedGlobal; - private PreprocessorIncludeStrategy strategy = PreprocessorIncludeStrategy.ONCE; - - public PreprocessorInclude(List config, String charset, DefinesGet defines, - DefinitionsContainer definitionsContainer, ImportedFiles importedFiles, Set filesUsedGlobal) { - this.charset = charset; - this.config = config; - this.defines = defines; - this.definitionsContainer = definitionsContainer; - this.importedFiles = importedFiles; - this.filesUsedGlobal = filesUsedGlobal; - } - - public ReadLine applyFilter(ReadLine source) { - return new Inner(source); - } - - class Inner extends ReadLineInsertable { - - final ReadLine source; - - Inner(ReadLine source) { - this.source = source; - } - - @Override - void closeInternal() throws IOException { - source.close(); - } - - @Override - StringLocated readLineInternal() throws IOException { - final StringLocated s = source.readLine(); - if (s == null || s.getPreprocessorError() != null) { - return s; - } - if (s != null && StartUtils.startOrEnd(s)) { - // http://plantuml.sourceforge.net/qa/?qa=3389/error-generating-when-same-file-included-different-diagram - filesUsedCurrent.clear(); - strategy = PreprocessorIncludeStrategy.ONCE; - return s; - } - if (s.getPreprocessorError() == null && OptionFlags.ALLOW_INCLUDE) { - final Matcher2 m0 = importPattern.matcher(s.getString()); - if (m0.find()) { - final StringLocated err = manageFileImport(s, m0); - if (err != null) { - insert(new ReadLineSingle(err)); - } - return readLine(); - } - final Matcher2 m1 = includePattern.matcher(s.getString()); - if (m1.find()) { - insert(manageFileInclude(s, m1, strategy)); - return readLine(); - } - final Matcher2 m2 = includeManyPattern.matcher(s.getString()); - if (m2.find()) { - insert(manageFileInclude(s, m2, PreprocessorIncludeStrategy.MANY)); - return readLine(); - } - final Matcher2 m3 = includeOncePattern.matcher(s.getString()); - if (m3.find()) { - insert(manageFileInclude(s, m3, PreprocessorIncludeStrategy.ONCE)); - return readLine(); - } - final Matcher2 m4 = includeDefPattern.matcher(s.getString()); - if (m4.find()) { - insert(manageDefinitionInclude(s, m4)); - return readLine(); - } - } else { - final Matcher2 m1 = includePatternStdlib.matcher(s.getString()); - if (m1.find()) { - insert(manageFileInclude(s, m1, PreprocessorIncludeStrategy.ONCE)); - return readLine(); - } - } - final Matcher2 mUrl = includeURLPattern.matcher(s.getString()); - if (s.getPreprocessorError() == null && mUrl.find()) { - insert(manageUrlInclude(s, mUrl)); - return readLine(); - } - final Matcher2 m2 = includeDefaultStrategy.matcher(s.getString()); - if (m2.find()) { - strategy = PreprocessorIncludeStrategy.fromString(m2.group(1)); - return readLine(); - } - - return s; - } - - } - - private StringLocated manageFileImport(StringLocated s, Matcher2 m) throws IOException { - final String fileName = m.group(1); - final File file = FileSystem.getInstance().getFile(withEnvironmentVariable(fileName)); - if (file.exists() && file.isDirectory() == false) { - importedFiles.add(file); - return null; - } - return s.withErrorPreprocessor("Cannot import " + FileWithSuffix.getFileName(file)); - - } - - private ReadLine manageUrlInclude(StringLocated s, Matcher2 m) throws IOException { - String urlString = m.group(1); - urlString = defines.get().applyDefines(urlString).get(0); - - final int idx = urlString.lastIndexOf('!'); - String suf = null; - if (idx != -1) { - suf = urlString.substring(idx + 1); - urlString = urlString.substring(0, idx); - } - try { - if (urlString.toLowerCase().startsWith("https://") == false - && urlString.toLowerCase().startsWith("http://") == false) { - return new ReadLineSingle(s.withErrorPreprocessor("Cannot include url " + urlString)); - } - final URL url = new URL(urlString); - return new Preprocessor(config, getReaderIncludeUrl(url, s, suf, charset), charset, defines, definitionsContainer, - filesUsedGlobal, importedFiles, false); - - } catch (MalformedURLException e) { - return new ReadLineSingle(s.withErrorPreprocessor("Cannot include url " + urlString)); - } - } - - private ReadLine manageDefinitionInclude(StringLocated s, Matcher2 matcher) throws IOException { - final String definitionName = matcher.group(1); - final List definition = definitionsContainer.getDefinition1(definitionName); - return new Preprocessor(config, new ReadLineList(definition, s.getLocation()), charset, defines, - definitionsContainer, filesUsedGlobal, importedFiles, false); - } - - private ReadLine manageFileInclude(StringLocated s, Matcher2 matcher, PreprocessorIncludeStrategy allowMany) - throws IOException { - String fileName = matcher.group(1); - fileName = defines.get().applyDefines(fileName).get(0); - if (fileName.startsWith("<") && fileName.endsWith(">")) { - final ReadLine strlibReader = getReaderStdlibInclude(s, fileName.substring(1, fileName.length() - 1)); - if (strlibReader == null) { - return new ReadLineSingle(s.withErrorPreprocessor("Cannot include " + fileName)); - } - return new Preprocessor(config, strlibReader, charset, defines, definitionsContainer, filesUsedGlobal, - importedFiles, false); - } - final int idx = fileName.lastIndexOf('!'); - String suf = null; - if (idx != -1) { - suf = fileName.substring(idx + 1); - fileName = fileName.substring(0, idx); - } - final FileWithSuffix f2 = new FileWithSuffix(importedFiles, withEnvironmentVariable(fileName), suf); - if (f2.fileOk() == false) { - Log.error("Current path is " + FileWithSuffix.getAbsolutePath(new File("."))); - Log.error("Cannot include " + f2.getDescription()); - return new ReadLineSingle(s.withErrorPreprocessor("Cannot include " + f2.getDescription())); - } else if (allowMany == PreprocessorIncludeStrategy.ONCE && filesUsedCurrent.contains(f2)) { - // return new ReadLineSimple(s, "File already included " + f2.getDescription()); - return new ReadLineEmpty(); - } - filesUsedCurrent.add(f2); - filesUsedGlobal.add(f2); - - return new Preprocessor(config, getReaderInclude(f2, s), charset, defines, definitionsContainer, - filesUsedGlobal, importedFiles.withCurrentDir(f2.getParentFile()), false); - } - - public static String withEnvironmentVariable(String s) { - final Pattern p = Pattern.compile("%(\\w+)%"); - - final Matcher m = p.matcher(s); - final StringBuffer sb = new StringBuffer(); - while (m.find()) { - final String var = m.group(1); - final String value = getenv(var); - if (value != null) { - m.appendReplacement(sb, Matcher.quoteReplacement(value)); - } - } - m.appendTail(sb); - s = sb.toString(); - return s; - } - - public static String getenv(String var) { - final String env = System.getProperty(var); - if (StringUtils.isNotEmpty(env)) { - return StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(env); - } - final String getenv = System.getenv(var); - if (StringUtils.isNotEmpty(getenv)) { - return StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(getenv); - } - return null; - } - - private static InputStream getStdlibInputStream(String filename) { - final InputStream result = Stdlib.getResourceAsStream(filename); - // Log.info("Loading sdlib " + filename + " ok"); - return result; - } - - public static ReadLine getReaderStdlibInclude(StringLocated s, String filename) { - Log.info("Loading sdlib " + filename); - InputStream is = getStdlibInputStream(filename); - if (is == null) { - return null; - } - final String description = "<" + filename + ">"; - try { - if (StartDiagramExtractReader.containsStartDiagram(is, s, description)) { - is = getStdlibInputStream(filename); - return StartDiagramExtractReader.build(is, s, description); - } - is = getStdlibInputStream(filename); - if (is == null) { - return null; - } - return ReadLineReader.create(new InputStreamReader(is), description); - } catch (IOException e) { - e.printStackTrace(); - return new ReadLineSimple(s, e.toString()); - } - } - - private ReadLine getReaderInclude(FileWithSuffix f2, StringLocated s) { - try { - if (StartDiagramExtractReader.containsStartDiagram(f2, s, charset)) { - return StartDiagramExtractReader.build(f2, s, charset); - } - final Reader reader = f2.getReader(charset); - if (reader == null) { - return new ReadLineSimple(s, "Cannot open " + f2.getDescription()); - } - return ReadLineReader.create(reader, f2.getDescription(), s.getLocation()); - } catch (IOException e) { - e.printStackTrace(); - return new ReadLineSimple(s, e.toString()); - } - } - - private static ReadLine getReaderIncludeUrl(final URL url, StringLocated s, String suf, String charset) { - try { - if (StartDiagramExtractReader.containsStartDiagram(url, s, charset)) { - return StartDiagramExtractReader.build(url, s, suf, charset); - } - final InputStream is = url.openStream(); - if (charset == null) { - Log.info("Using default charset"); - return ReadLineReader.create(new InputStreamReader(is), url.toString(), s.getLocation()); - } - Log.info("Using charset " + charset); - return ReadLineReader.create(new InputStreamReader(is, charset), url.toString(), s.getLocation()); - } catch (IOException e) { - e.printStackTrace(); - return new ReadLineSimple(s, e.toString()); - } - - } - - public static ReadLine getReaderIncludeUrl2(final URL url, StringLocated s, String suf, String charset) throws EaterException { - try { - if (StartDiagramExtractReader.containsStartDiagram(url, s, charset)) { - return StartDiagramExtractReader.build(url, s, suf, charset); - } - final InputStream is = url.openStream(); - if (charset == null) { - Log.info("Using default charset"); - return ReadLineReader.create(new InputStreamReader(is), url.toString(), s.getLocation()); - } - Log.info("Using charset " + charset); - return ReadLineReader.create(new InputStreamReader(is, charset), url.toString(), s.getLocation()); - } catch (IOException e) { - e.printStackTrace(); - throw new EaterException("Cannot open URL"); - } - - } - - public Set getFilesUsedGlobal() { - return filesUsedGlobal; - } - -} diff --git a/src/net/sourceforge/plantuml/preproc2/PreprocessorMode.java b/src/net/sourceforge/plantuml/preproc2/PreprocessorMode.java deleted file mode 100644 index 8ecf41c05..000000000 --- a/src/net/sourceforge/plantuml/preproc2/PreprocessorMode.java +++ /dev/null @@ -1,42 +0,0 @@ -/* ======================================================================== - * PlantUML : a free UML diagram generator - * ======================================================================== - * - * (C) Copyright 2009-2020, 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.preproc2; - -public enum PreprocessorMode { - - V1_LEGACY, V2_NEW_TIM - -} diff --git a/src/net/sourceforge/plantuml/preproc2/PreprocessorModeSet.java b/src/net/sourceforge/plantuml/preproc2/PreprocessorModeSet.java index 41b07a954..7b835b768 100644 --- a/src/net/sourceforge/plantuml/preproc2/PreprocessorModeSet.java +++ b/src/net/sourceforge/plantuml/preproc2/PreprocessorModeSet.java @@ -39,10 +39,6 @@ import net.sourceforge.plantuml.preproc.ImportedFiles; public interface PreprocessorModeSet { - public PreprocessorMode getPreprocessorMode(); - - public void setPreprocessorMode(PreprocessorMode mode); - public ImportedFiles getImportedFiles(); public String getCharset(); diff --git a/src/net/sourceforge/plantuml/preproc2/PreprocessorUtils.java b/src/net/sourceforge/plantuml/preproc2/PreprocessorUtils.java new file mode 100644 index 000000000..fa3d10b97 --- /dev/null +++ b/src/net/sourceforge/plantuml/preproc2/PreprocessorUtils.java @@ -0,0 +1,136 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2020, 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 + * Modified by: Nicolas Jouanin + * + * + */ +package net.sourceforge.plantuml.preproc2; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import net.sourceforge.plantuml.Log; +import net.sourceforge.plantuml.StringLocated; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.preproc.ReadLine; +import net.sourceforge.plantuml.preproc.ReadLineReader; +import net.sourceforge.plantuml.preproc.ReadLineSimple; +import net.sourceforge.plantuml.preproc.StartDiagramExtractReader; +import net.sourceforge.plantuml.preproc.Stdlib; +import net.sourceforge.plantuml.tim.EaterException; + +public class PreprocessorUtils { + + public static String withEnvironmentVariable(String s) { + final Pattern p = Pattern.compile("%(\\w+)%"); + + final Matcher m = p.matcher(s); + final StringBuffer sb = new StringBuffer(); + while (m.find()) { + final String var = m.group(1); + final String value = getenv(var); + if (value != null) { + m.appendReplacement(sb, Matcher.quoteReplacement(value)); + } + } + m.appendTail(sb); + s = sb.toString(); + return s; + } + + public static String getenv(String var) { + final String env = System.getProperty(var); + if (StringUtils.isNotEmpty(env)) { + return StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(env); + } + final String getenv = System.getenv(var); + if (StringUtils.isNotEmpty(getenv)) { + return StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(getenv); + } + return null; + } + + private static InputStream getStdlibInputStream(String filename) { + final InputStream result = Stdlib.getResourceAsStream(filename); + // Log.info("Loading sdlib " + filename + " ok"); + return result; + } + + public static ReadLine getReaderStdlibInclude(StringLocated s, String filename) { + Log.info("Loading sdlib " + filename); + InputStream is = getStdlibInputStream(filename); + if (is == null) { + return null; + } + final String description = "<" + filename + ">"; + try { + if (StartDiagramExtractReader.containsStartDiagram(is, s, description)) { + is = getStdlibInputStream(filename); + return StartDiagramExtractReader.build(is, s, description); + } + is = getStdlibInputStream(filename); + if (is == null) { + return null; + } + return ReadLineReader.create(new InputStreamReader(is), description); + } catch (IOException e) { + e.printStackTrace(); + return new ReadLineSimple(s, e.toString()); + } + } + + public static ReadLine getReaderIncludeUrl2(final URL url, StringLocated s, String suf, String charset) + throws EaterException { + try { + if (StartDiagramExtractReader.containsStartDiagram(url, s, charset)) { + return StartDiagramExtractReader.build(url, s, suf, charset); + } + final InputStream is = url.openStream(); + if (charset == null) { + Log.info("Using default charset"); + return ReadLineReader.create(new InputStreamReader(is), url.toString(), s.getLocation()); + } + Log.info("Using charset " + charset); + return ReadLineReader.create(new InputStreamReader(is, charset), url.toString(), s.getLocation()); + } catch (IOException e) { + e.printStackTrace(); + throw new EaterException("Cannot open URL"); + } + + } + +} diff --git a/src/net/sourceforge/plantuml/preproc2/ReadLineAddConfig.java b/src/net/sourceforge/plantuml/preproc2/ReadFilterAddConfig.java similarity index 91% rename from src/net/sourceforge/plantuml/preproc2/ReadLineAddConfig.java rename to src/net/sourceforge/plantuml/preproc2/ReadFilterAddConfig.java index 41c7b670f..fa274305f 100644 --- a/src/net/sourceforge/plantuml/preproc2/ReadLineAddConfig.java +++ b/src/net/sourceforge/plantuml/preproc2/ReadFilterAddConfig.java @@ -43,11 +43,11 @@ import net.sourceforge.plantuml.preproc.ReadLine; import net.sourceforge.plantuml.preproc.ReadLineList; import net.sourceforge.plantuml.utils.StartUtils; -public class ReadLineAddConfig implements ReadFilter { +public class ReadFilterAddConfig implements ReadFilter { private final List config; - public ReadLineAddConfig(List config) { + public ReadFilterAddConfig(List config) { this.config = config; } @@ -74,7 +74,7 @@ public class ReadLineAddConfig implements ReadFilter { } result = raw.readLine(); if (result != null && StartUtils.isArobaseStartDiagram(result.getString()) && config.size() > 0) { - inserted = new ReadLineQuoteComment(false).applyFilter(new ReadLineList(config, result.getLocation())); + inserted = new ReadFilterQuoteComment().applyFilter(new ReadLineList(config, result.getLocation())); } return result; } diff --git a/src/net/sourceforge/plantuml/preproc/IfManagerFilter.java b/src/net/sourceforge/plantuml/preproc2/ReadFilterMergeLines.java similarity index 75% rename from src/net/sourceforge/plantuml/preproc/IfManagerFilter.java rename to src/net/sourceforge/plantuml/preproc2/ReadFilterMergeLines.java index 3e4f4a690..d8c1e65c4 100644 --- a/src/net/sourceforge/plantuml/preproc/IfManagerFilter.java +++ b/src/net/sourceforge/plantuml/preproc2/ReadFilterMergeLines.java @@ -33,32 +33,33 @@ * * */ -package net.sourceforge.plantuml.preproc; +package net.sourceforge.plantuml.preproc2; import java.io.IOException; import net.sourceforge.plantuml.StringLocated; -import net.sourceforge.plantuml.preproc2.ReadFilter; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.preproc.ReadLine; -public class IfManagerFilter implements ReadFilter { - - private final DefinesGet defines; - - public IfManagerFilter(DefinesGet defines) { - this.defines = defines; - } +public class ReadFilterMergeLines implements ReadFilter { public ReadLine applyFilter(final ReadLine source) { return new ReadLine() { - - final IfManager ifManager = new IfManager(source, defines); - public void close() throws IOException { source.close(); } public StringLocated readLine() throws IOException { - return ifManager.readLine(); + StringLocated result = source.readLine(); + while (result != null && StringUtils.endsWithBackslash(result.getString())) { + final StringLocated next = source.readLine(); + if (next == null) { + break; + } else { + result = result.mergeEndBackslash(next); + } + } + return result; } }; } diff --git a/src/net/sourceforge/plantuml/preproc2/ReadLineQuoteComment.java b/src/net/sourceforge/plantuml/preproc2/ReadFilterQuoteComment.java similarity index 91% rename from src/net/sourceforge/plantuml/preproc2/ReadLineQuoteComment.java rename to src/net/sourceforge/plantuml/preproc2/ReadFilterQuoteComment.java index c4b7ab5f4..95ff4c9bb 100644 --- a/src/net/sourceforge/plantuml/preproc2/ReadLineQuoteComment.java +++ b/src/net/sourceforge/plantuml/preproc2/ReadFilterQuoteComment.java @@ -40,21 +40,10 @@ import java.io.IOException; import net.sourceforge.plantuml.StringLocated; import net.sourceforge.plantuml.preproc.ReadLine; -public class ReadLineQuoteComment implements ReadFilter { - - private final boolean ignoreMe; - - public ReadLineQuoteComment(boolean ignoreMe) { - this.ignoreMe = ignoreMe; - } +public class ReadFilterQuoteComment implements ReadFilter { public ReadLine applyFilter(final ReadLine source) { - if (ignoreMe) { - return source; - } - return new ReadLine() { - public void close() throws IOException { source.close(); } diff --git a/src/net/sourceforge/plantuml/preproc2/ReadLineInsertable.java b/src/net/sourceforge/plantuml/preproc2/ReadLineInsertable.java deleted file mode 100644 index 3d2513cb0..000000000 --- a/src/net/sourceforge/plantuml/preproc2/ReadLineInsertable.java +++ /dev/null @@ -1,77 +0,0 @@ -/* ======================================================================== - * PlantUML : a free UML diagram generator - * ======================================================================== - * - * (C) Copyright 2009-2020, 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.preproc2; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import net.sourceforge.plantuml.StringLocated; -import net.sourceforge.plantuml.preproc.ReadLine; - -public abstract class ReadLineInsertable implements ReadLine { - - private final List sources = new ArrayList(); - - final protected void insert(ReadLine inserted) throws IOException { - sources.add(0, inserted); - } - - abstract StringLocated readLineInternal() throws IOException; - - final public StringLocated readLine() throws IOException { - while (sources.size() > 0) { - final ReadLine tmp = sources.get(0); - final StringLocated result = tmp.readLine(); - if (result != null) { - return result; - } - tmp.close(); - sources.remove(0); - } - return readLineInternal(); - } - - abstract void closeInternal() throws IOException; - - final public void close() throws IOException { - for (ReadLine s : sources) { - s.close(); - } - closeInternal(); - } - -} diff --git a/src/net/sourceforge/plantuml/preproc2/SubPreprocessor.java b/src/net/sourceforge/plantuml/preproc2/SubPreprocessor.java deleted file mode 100644 index 2e89353cf..000000000 --- a/src/net/sourceforge/plantuml/preproc2/SubPreprocessor.java +++ /dev/null @@ -1,199 +0,0 @@ -/* ======================================================================== - * PlantUML : a free UML diagram generator - * ======================================================================== - * - * (C) Copyright 2009-2020, 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.preproc2; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.HashMap; -import java.util.Map; - -import net.sourceforge.plantuml.DefinitionsContainer; -import net.sourceforge.plantuml.FileSystem; -import net.sourceforge.plantuml.Log; -import net.sourceforge.plantuml.StringLocated; -import net.sourceforge.plantuml.command.regex.Matcher2; -import net.sourceforge.plantuml.command.regex.MyPattern; -import net.sourceforge.plantuml.command.regex.Pattern2; -import net.sourceforge.plantuml.preproc.FileWithSuffix; -import net.sourceforge.plantuml.preproc.ReadLine; -import net.sourceforge.plantuml.preproc.ReadLineReader; -import net.sourceforge.plantuml.preproc.ReadLineSimple; -import net.sourceforge.plantuml.preproc.Sub; - -public class SubPreprocessor implements ReadFilter { - - private static final String ID = "[A-Za-z_][A-Za-z_0-9]*"; - - private static final Pattern2 includeSubPattern = MyPattern.cmpile("^[%s]*!includesub[%s]+[%g]?([^%g]+)[%g]?$"); - - private static final Pattern2 startsub = MyPattern.cmpile("^[%s]*!startsub[%s]+(" + ID + ")"); - private static final Pattern2 endsub = MyPattern.cmpile("^[%s]*!endsub[%s]*"); - - private final DefinitionsContainer definitionsContainer; - private final String charset; - - public SubPreprocessor(String charset, DefinitionsContainer definitionsContainer) { - this.charset = charset; - this.definitionsContainer = definitionsContainer; - } - - private final Map subs = new HashMap(); - private Sub learningSub; - private ReadLine includedSub; - - public ReadLine applyFilter(ReadLine source) { - return new InnerReadLine(source); - } - - class InnerReadLine implements ReadLine { - final ReadLine source; - - public InnerReadLine(ReadLine source) { - this.source = source; - } - - private StringLocated manageStartsub(Matcher2 m) throws IOException { - final String name = m.group(1); - learningSub = getSub(name); - return this.readLine(); - } - - private StringLocated manageEndsub(Matcher2 m) throws IOException { - learningSub = null; - return this.readLine(); - } - - public void close() throws IOException { - source.close(); - } - - private StringLocated manageIncludeSub(StringLocated s, Matcher2 m) throws IOException { - final String name = m.group(1); - final int idx = name.indexOf('!'); - if (idx != -1) { - final String filename = name.substring(0, idx); - final String blocname = name.substring(idx + 1); - final File f = FileSystem.getInstance().getFile(PreprocessorInclude.withEnvironmentVariable(filename)); - if (f.exists() == false || f.isDirectory()) { - Log.error("Cannot include " + FileWithSuffix.getAbsolutePath(f)); - return s.withErrorPreprocessor("Cannot include " + FileWithSuffix.getFileName(f)); - } - final SubPreprocessor data = new SubPreprocessor(charset, definitionsContainer); - InnerReadLine tmp = (InnerReadLine) data.applyFilter(getReaderIncludeWithoutComment(s, f)); - while (tmp.readLine() != null) { - // Read file - } - tmp.close(); - includedSub = tmp.getSub(blocname).getReadLine(s.getLocation()); - } else { - includedSub = getSub(name).getReadLine(s.getLocation()); - } - return this.readLine(); - } - - public StringLocated readLine() throws IOException { - if (includedSub != null) { - final StringLocated s = includedSub.readLine(); - if (s != null) { - eventuallyLearn(s); - return s; - } - includedSub = null; - } - - final StringLocated s = source.readLine(); - if (s == null) { - return null; - } - - final Matcher2 m1 = includeSubPattern.matcher(s.getString()); - if (m1.find()) { - return manageIncludeSub(s, m1); - } - - Matcher2 m = startsub.matcher(s.getString()); - if (m.find()) { - return manageStartsub(m); - } - - m = endsub.matcher(s.getString()); - if (m.find()) { - return manageEndsub(m); - } - eventuallyLearn(s); - return s; - } - - private void eventuallyLearn(final StringLocated s) { - if (learningSub != null) { - learningSub.add(s); - } - } - - Sub getSub(String name) { - Sub result = subs.get(name); - if (result == null) { - result = new Sub(name); - subs.put(name, result); - } - return result; - } - - } - - private ReadLine getReaderIncludeWithoutComment(StringLocated s, final File f) { - return new ReadLineQuoteComment(false).applyFilter(getReaderIncludeRaw(s, f)); - } - - private ReadLine getReaderIncludeRaw(StringLocated s, final File f) { - try { - if (charset == null) { - Log.info("Using default charset"); - return ReadLineReader.create(new FileReader(f), FileWithSuffix.getFileName(f), s.getLocation()); - } - Log.info("Using charset " + charset); - return ReadLineReader.create(new InputStreamReader(new FileInputStream(f), charset), FileWithSuffix.getFileName(f), - s.getLocation()); - } catch (IOException e) { - return new ReadLineSimple(s, e.toString()); - } - - } - -} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/project3/Resource.java b/src/net/sourceforge/plantuml/project3/Resource.java index 668c89d50..54eb1d9b5 100644 --- a/src/net/sourceforge/plantuml/project3/Resource.java +++ b/src/net/sourceforge/plantuml/project3/Resource.java @@ -37,7 +37,6 @@ package net.sourceforge.plantuml.project3; import java.util.Collection; import java.util.EnumSet; -import java.util.HashSet; import java.util.Set; import java.util.TreeSet; diff --git a/src/net/sourceforge/plantuml/project3/VerbProjectStarts.java b/src/net/sourceforge/plantuml/project3/VerbProjectStarts.java index 74350ec20..d9bceb122 100644 --- a/src/net/sourceforge/plantuml/project3/VerbProjectStarts.java +++ b/src/net/sourceforge/plantuml/project3/VerbProjectStarts.java @@ -45,7 +45,6 @@ import net.sourceforge.plantuml.command.regex.RegexLeaf; import net.sourceforge.plantuml.command.regex.RegexOptional; import net.sourceforge.plantuml.command.regex.RegexOr; import net.sourceforge.plantuml.command.regex.RegexResult; -import net.sourceforge.plantuml.descdiagram.command.CommandLinkElement; public class VerbProjectStarts implements VerbPattern { diff --git a/src/net/sourceforge/plantuml/sequencediagram/AbstractMessage.java b/src/net/sourceforge/plantuml/sequencediagram/AbstractMessage.java index 748a5f545..5044ff8d4 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/AbstractMessage.java +++ b/src/net/sourceforge/plantuml/sequencediagram/AbstractMessage.java @@ -255,4 +255,7 @@ public abstract class AbstractMessage implements EventWithDeactivate, WithStyle return this.anchor2; } + public abstract Participant getParticipant1(); + + public abstract Participant getParticipant2(); } diff --git a/src/net/sourceforge/plantuml/sequencediagram/Message.java b/src/net/sourceforge/plantuml/sequencediagram/Message.java index 332459af2..05305ace9 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/Message.java +++ b/src/net/sourceforge/plantuml/sequencediagram/Message.java @@ -56,10 +56,12 @@ public final class Message extends AbstractMessage { return super.toString() + " " + p1 + "->" + p2 + " " + getLabel(); } + @Override public Participant getParticipant1() { return p1; } + @Override public Participant getParticipant2() { return p2; } diff --git a/src/net/sourceforge/plantuml/sequencediagram/MessageExo.java b/src/net/sourceforge/plantuml/sequencediagram/MessageExo.java index 4e2292654..a057f984f 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/MessageExo.java +++ b/src/net/sourceforge/plantuml/sequencediagram/MessageExo.java @@ -68,6 +68,16 @@ public class MessageExo extends AbstractMessage { throw new IllegalStateException(); } + @Override + public Participant getParticipant1() { + return participant; + } + + @Override + public Participant getParticipant2() { + return participant; + } + public Participant getParticipant() { return participant; } diff --git a/src/net/sourceforge/plantuml/sequencediagram/MessageExoType.java b/src/net/sourceforge/plantuml/sequencediagram/MessageExoType.java index d3207b6ae..49aef40cf 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/MessageExoType.java +++ b/src/net/sourceforge/plantuml/sequencediagram/MessageExoType.java @@ -39,16 +39,14 @@ public enum MessageExoType { FROM_LEFT, TO_LEFT, FROM_RIGHT, TO_RIGHT; public int getDirection() { - if (this == MessageExoType.FROM_LEFT) { + switch (this) { + case FROM_LEFT: return 1; - } - if (this == MessageExoType.TO_LEFT) { + case TO_LEFT: return -1; - } - if (this == MessageExoType.TO_RIGHT) { + case TO_RIGHT: return 1; - } - if (this == MessageExoType.FROM_RIGHT) { + case FROM_RIGHT: return -1; } throw new IllegalStateException(); @@ -62,4 +60,18 @@ public enum MessageExoType { return this == MessageExoType.FROM_RIGHT || this == MessageExoType.TO_RIGHT; } + public MessageExoType reverse() { + switch (this) { + case FROM_LEFT: + return TO_LEFT; + case TO_RIGHT: + return FROM_RIGHT; + case FROM_RIGHT: + return TO_RIGHT; + case TO_LEFT: + return FROM_LEFT; + } + throw new IllegalStateException(); + } + } diff --git a/src/net/sourceforge/plantuml/sequencediagram/SequenceDiagram.java b/src/net/sourceforge/plantuml/sequencediagram/SequenceDiagram.java index 281079d93..691550309 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/SequenceDiagram.java +++ b/src/net/sourceforge/plantuml/sequencediagram/SequenceDiagram.java @@ -253,9 +253,9 @@ public class SequenceDiagram extends UmlDiagram { } // support for CommandReturn - private final Stack activationState = new Stack(); + private final Stack activationState = new Stack(); - public Message getActivatingMessage() { + public AbstractMessage getActivatingMessage() { if (activationState.empty()) { return null; } @@ -288,8 +288,8 @@ public class SequenceDiagram extends UmlDiagram { } return null; } - if (lifeEventType == LifeEventType.ACTIVATE && lastEventWithDeactivate instanceof Message) { - activationState.push((Message) lastEventWithDeactivate); + if (lifeEventType == LifeEventType.ACTIVATE && lastEventWithDeactivate instanceof AbstractMessage) { + activationState.push((AbstractMessage) lastEventWithDeactivate); } else if (lifeEventType == LifeEventType.DEACTIVATE && activationState.empty() == false) { activationState.pop(); } diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandDeactivateShort.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandDeactivateShort.java index cbb6bcc14..057544117 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandDeactivateShort.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandDeactivateShort.java @@ -61,7 +61,7 @@ public class CommandDeactivateShort extends SingleLineCommand2 @Override protected CommandExecutionResult executeArg(SequenceDiagram sequenceDiagram, LineLocation location, RegexResult arg2) { - Message message = sequenceDiagram.getActivatingMessage(); + Message message = (Message) sequenceDiagram.getActivatingMessage(); if (message == null) { return CommandExecutionResult.error("Nothing to deactivate."); } diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowAny.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowAny.java index bebd603d1..1863de347 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowAny.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowAny.java @@ -92,6 +92,13 @@ abstract class CommandExoArrowAny extends SingleLineCommand2 { } config = config.withPart(getArrowPart(dressing)); config = CommandArrow.applyStyle(arg.getLazzy("ARROW_STYLE", 0), config); + + final String activationSpec = arg.get("ACTIVATION", 0); + + if (activationSpec != null && activationSpec.charAt(0) == '*') { + diagram.activate(p, LifeEventType.CREATE, null); + } + final MessageExoType messageExoType = getMessageExoType(arg); if (messageExoType == MessageExoType.TO_RIGHT || messageExoType == MessageExoType.TO_LEFT) { @@ -144,7 +151,22 @@ abstract class CommandExoArrowAny extends SingleLineCommand2 { final HtmlColor activationColor = diagram.getSkinParam().getIHtmlColorSet() .getColorIfValid(arg.get("LIFECOLOR", 0)); - if (diagram.isAutoactivate() && (config.getHead() == ArrowHead.NORMAL || config.getHead() == ArrowHead.ASYNC)) { + if (activationSpec != null) { + switch (activationSpec.charAt(0)) { + case '+': + diagram.activate(p, LifeEventType.ACTIVATE, activationColor); + break; + case '-': + diagram.activate(p, LifeEventType.DEACTIVATE, null); + break; + case '!': + diagram.activate(p, LifeEventType.DESTROY, null); + break; + default: + break; + } + } else if (diagram.isAutoactivate() + && (config.getHead() == ArrowHead.NORMAL || config.getHead() == ArrowHead.ASYNC)) { if (config.isDotted()) { diagram.activate(p, LifeEventType.DEACTIVATE, null); } else { diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowLeft.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowLeft.java index 64fe88056..1de4230ec 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowLeft.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowLeft.java @@ -70,6 +70,10 @@ public class CommandExoArrowLeft extends CommandExoArrowAny { RegexLeaf.spaceZeroOrMore(), // new RegexLeaf("PARTICIPANT", "([\\p{L}0-9_.@]+|[%g][^%g]+[%g])"), // RegexLeaf.spaceZeroOrMore(), // + new RegexLeaf("ACTIVATION", "(?:([+*!-]+)?)"), // + RegexLeaf.spaceZeroOrMore(), // + new RegexLeaf("LIFECOLOR", "(?:(#\\w+)?)"), // + RegexLeaf.spaceZeroOrMore(), // new RegexLeaf("URL", "(" + UrlBuilder.getRegexp() + ")?"), // RegexLeaf.spaceZeroOrMore(), // new RegexOptional( // diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowRight.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowRight.java index 5ed063716..791936e82 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowRight.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowRight.java @@ -70,6 +70,10 @@ public class CommandExoArrowRight extends CommandExoArrowAny { new RegexLeaf("ARROW_BODYA2", "(-+)"))), // new RegexLeaf("SHORT", "([ox]?[?\\]\\[])?"), // RegexLeaf.spaceZeroOrMore(), // + new RegexLeaf("ACTIVATION", "(?:([+*!-]+)?)"), // + RegexLeaf.spaceZeroOrMore(), // + new RegexLeaf("LIFECOLOR", "(?:(#\\w+)?)"), // + RegexLeaf.spaceZeroOrMore(), // new RegexLeaf("URL", "(" + UrlBuilder.getRegexp() + ")?"), // RegexLeaf.spaceZeroOrMore(), // new RegexOptional( // diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandReturn.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandReturn.java index 868d348b5..1f81d45c2 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandReturn.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandReturn.java @@ -45,9 +45,12 @@ import net.sourceforge.plantuml.command.regex.RegexOptional; import net.sourceforge.plantuml.command.regex.RegexResult; import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.graphic.HtmlColorSet; +import net.sourceforge.plantuml.sequencediagram.AbstractMessage; import net.sourceforge.plantuml.sequencediagram.EventWithDeactivate; import net.sourceforge.plantuml.sequencediagram.LifeEventType; import net.sourceforge.plantuml.sequencediagram.Message; +import net.sourceforge.plantuml.sequencediagram.MessageExo; +import net.sourceforge.plantuml.sequencediagram.MessageExoType; import net.sourceforge.plantuml.sequencediagram.SequenceDiagram; import net.sourceforge.plantuml.skin.ArrowBody; import net.sourceforge.plantuml.skin.ArrowConfiguration; @@ -75,7 +78,7 @@ public class CommandReturn extends SingleLineCommand2 { @Override protected CommandExecutionResult executeArg(SequenceDiagram diagram, LineLocation location, RegexResult arg) { - Message message1 = diagram.getActivatingMessage(); + AbstractMessage message1 = diagram.getActivatingMessage(); boolean doDeactivation = true; if (message1 == null) { final EventWithDeactivate last = diagram.getLastEventWithDeactivate(); @@ -93,12 +96,18 @@ public class CommandReturn extends SingleLineCommand2 { } final Display display = Display.getWithNewlines(arg.get("MESSAGE", 0)); - final Message message2 = new Message(diagram.getSkinParam().getCurrentStyleBuilder(), - message1.getParticipant2(), message1.getParticipant1(), display, arrow, - diagram.getNextMessageNumber()); - final boolean parallel = arg.get("PARALLEL", 0) != null; - if (parallel) { - message2.goParallel(); + final AbstractMessage message2; + if (message1 instanceof MessageExo) { + final MessageExo exo1 = (MessageExo) message1; + message2 = new MessageExo(diagram.getSkinParam().getCurrentStyleBuilder(), exo1.getParticipant(), exo1 + .getType().reverse(), display, arrow, diagram.getNextMessageNumber(), false); + } else { + message2 = new Message(diagram.getSkinParam().getCurrentStyleBuilder(), message1.getParticipant2(), + message1.getParticipant1(), display, arrow, diagram.getNextMessageNumber()); + final boolean parallel = arg.get("PARALLEL", 0) != null; + if (parallel) { + message2.goParallel(); + } } diagram.addMessage(message2); @@ -111,5 +120,4 @@ public class CommandReturn extends SingleLineCommand2 { return CommandExecutionResult.ok(); } - } diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/ArrowAndParticipant.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/ArrowAndParticipant.java index 5fda5fdc6..836382bf3 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/ArrowAndParticipant.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/ArrowAndParticipant.java @@ -107,7 +107,10 @@ class ArrowAndParticipant extends Arrow implements InGroupable { if (arrowHeight > boxHeight) { diff = arrowHeight - boxHeight; } - participantBox.drawParticipantHead(ug.apply(new UTranslate(participantBoxStartingX, getStartingY() + diff))); + if (context.isBackground() == false) { + participantBox + .drawParticipantHead(ug.apply(new UTranslate(participantBoxStartingX, getStartingY() + diff))); + } } private double getDiff(UGraphic ug) { diff --git a/src/net/sourceforge/plantuml/statediagram/StateDiagram.java b/src/net/sourceforge/plantuml/statediagram/StateDiagram.java index decbdbff8..d8e437ec7 100644 --- a/src/net/sourceforge/plantuml/statediagram/StateDiagram.java +++ b/src/net/sourceforge/plantuml/statediagram/StateDiagram.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.statediagram; import net.sourceforge.plantuml.ISkinSimple; +import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.UmlDiagramType; import net.sourceforge.plantuml.classdiagram.AbstractEntityDiagram; import net.sourceforge.plantuml.cucadiagram.Code; @@ -44,6 +45,7 @@ import net.sourceforge.plantuml.cucadiagram.EntityUtils; import net.sourceforge.plantuml.cucadiagram.GroupType; import net.sourceforge.plantuml.cucadiagram.IEntity; import net.sourceforge.plantuml.cucadiagram.IGroup; +import net.sourceforge.plantuml.cucadiagram.ILeaf; import net.sourceforge.plantuml.cucadiagram.Ident; import net.sourceforge.plantuml.cucadiagram.LeafType; import net.sourceforge.plantuml.cucadiagram.Link; @@ -61,6 +63,9 @@ public class StateDiagram extends AbstractEntityDiagram { } public boolean checkConcurrentStateOk(Ident ident, Code code) { + if (this.V1972()) { + return checkConcurrentStateOkInternal1972(ident); + } final boolean result = checkConcurrentStateOkInternal(code); // System.err.println("checkConcurrentStateOk " + code + " " + ident + " " + result); return result; @@ -82,14 +87,29 @@ public class StateDiagram extends AbstractEntityDiagram { return true; } + private boolean checkConcurrentStateOkInternal1972(Ident ident) { + if (leafExistSmart(ident) == false) { + return true; + } + final IEntity existing = this.getLeafSmart(ident); + if (getCurrentGroup().getGroupType() == GroupType.CONCURRENT_STATE + && getCurrentGroup() != existing.getParentContainer()) { + return false; + } + if (existing.getParentContainer().getGroupType() == GroupType.CONCURRENT_STATE + && getCurrentGroup() != existing.getParentContainer()) { + return false; + } + return true; + } + @Override public IEntity getOrCreateLeaf(Ident ident, Code code, LeafType type, USymbol symbol) { checkNotNull(ident); if (checkConcurrentStateOk(ident, code) == false) { throw new IllegalStateException("Concurrent State " + code); } - // final Ident idNewLong = buildLeafIdent(id); - if (type == null) { + if (!this.V1972() && type == null) { if (code.getName().startsWith("[*]")) { throw new IllegalArgumentException(); } @@ -98,51 +118,74 @@ public class StateDiagram extends AbstractEntityDiagram { } return getOrCreateLeafDefault(ident, code, LeafType.STATE, null); } + if (this.V1972() && type == null) { + if (ident.getName().startsWith("[*]")) { + throw new IllegalArgumentException(); + } + if (isGroupVerySmart(ident)) { + return getGroupVerySmart(ident); + } + if (getNamespaceSeparator() == null) { + final ILeaf result = getLeafVerySmart(ident); + if (result != null) { + return result; + } + + } + return getOrCreateLeafDefault(ident, code, LeafType.STATE, null); + } return getOrCreateLeafDefault(ident, code, type, symbol); } public IEntity getStart() { final IGroup g = getCurrentGroup(); if (EntityUtils.groupRoot(g)) { - return getOrCreateLeaf(buildLeafIdent("*start"), buildCode("*start"), - LeafType.CIRCLE_START, null); + final Ident ident = buildLeafIdent("*start"); + final Code code = this.V1972() ? ident : buildCode("*start"); + return getOrCreateLeaf(ident, code, LeafType.CIRCLE_START, null); } final String idShort = "*start*" + g.getCodeGetName(); - return getOrCreateLeaf(buildLeafIdent(idShort), buildCode(idShort), - LeafType.CIRCLE_START, null); + final Ident ident = buildLeafIdent(idShort); + final Code code = this.V1972() ? ident : buildCode(idShort); + return getOrCreateLeaf(ident, code, LeafType.CIRCLE_START, null); } public IEntity getEnd() { final IGroup p = getCurrentGroup(); if (EntityUtils.groupRoot(p)) { - return getOrCreateLeaf(buildLeafIdent("*end"), buildCode("*end"), - LeafType.CIRCLE_END, null); + final Ident ident = buildLeafIdent("*end"); + final Code code = this.V1972() ? ident : buildCode("*end"); + return getOrCreateLeaf(ident, code, LeafType.CIRCLE_END, null); } final String idShort = "*end*" + p.getCodeGetName(); - return getOrCreateLeaf(buildLeafIdent(idShort), buildCode(idShort), LeafType.CIRCLE_END, - null); + final Ident ident = buildLeafIdent(idShort); + final Code code = this.V1972() ? ident : buildCode(idShort); + return getOrCreateLeaf(ident, code, LeafType.CIRCLE_END, null); } public IEntity getHistorical() { final IGroup g = getCurrentGroup(); if (EntityUtils.groupRoot(g)) { - return getOrCreateLeaf(buildLeafIdent("*historical"), buildCode("*historical"), - LeafType.PSEUDO_STATE, null); + final Ident ident = buildLeafIdent("*historical"); + final Code code = buildCode("*historical"); + return getOrCreateLeaf(ident, code, LeafType.PSEUDO_STATE, null); } final String idShort = "*historical*" + g.getCodeGetName(); - return getOrCreateLeaf(buildLeafIdent(idShort), buildCode(idShort), - LeafType.PSEUDO_STATE, null); + final Ident ident = buildLeafIdent(idShort); + final Code code = this.V1972() ? ident : buildCode(idShort); + return getOrCreateLeaf(ident, code, LeafType.PSEUDO_STATE, null); } public IEntity getHistorical(String idShort) { - final Code codeGroup = buildCode(idShort); final Ident idNewLong = buildLeafIdent(idShort); + final Code codeGroup = this.V1972() ? idNewLong : buildCode(idShort); gotoGroup(idNewLong, codeGroup, Display.getWithNewlines(codeGroup), GroupType.STATE, getRootGroup(), NamespaceStrategy.SINGLE); final IEntity g = getCurrentGroup(); final String tmp = "*historical*" + g.getCodeGetName(); - final IEntity result = getOrCreateLeaf(buildLeafIdent(tmp), buildCode(tmp), - LeafType.PSEUDO_STATE, null); + final Ident ident = buildLeafIdent(tmp); + final Code code = this.V1972() ? ident : buildCode(tmp); + final IEntity result = getOrCreateLeaf(ident, code, LeafType.PSEUDO_STATE, null); endGroup(); return result; } @@ -155,17 +198,19 @@ public class StateDiagram extends AbstractEntityDiagram { } getCurrentGroup().setConcurrentSeparator(direction); final String tmp1 = UniqueSequence.getString(CONCURRENT_PREFIX); - final Ident idNewLong1 = buildLeafIdent(tmp1); - gotoGroup(idNewLong1, buildCode(tmp1), Display.create(""), GroupType.CONCURRENT_STATE, - getCurrentGroup(), NamespaceStrategy.SINGLE); + final Ident ident1 = buildLeafIdent(tmp1); + final Code code1 = this.V1972() ? ident1 : buildCode(tmp1); + gotoGroup(ident1, code1, Display.create(""), GroupType.CONCURRENT_STATE, getCurrentGroup(), + NamespaceStrategy.SINGLE); final IGroup conc1 = getCurrentGroup(); if (EntityUtils.groupRoot(cur) == false && cur.getGroupType() == GroupType.STATE) { cur.moveEntitiesTo(conc1); super.endGroup(); final String tmp2 = UniqueSequence.getString(CONCURRENT_PREFIX); - final Ident idNewLong2 = buildLeafIdent(tmp2); - gotoGroup(idNewLong2, buildCode(tmp2), Display.create(""), - GroupType.CONCURRENT_STATE, getCurrentGroup(), NamespaceStrategy.SINGLE); + final Ident ident2 = buildLeafIdent(tmp2); + final Code code2 = this.V1972() ? ident2 : buildCode(tmp2); + gotoGroup(ident2, code2, Display.create(""), GroupType.CONCURRENT_STATE, getCurrentGroup(), + NamespaceStrategy.SINGLE); } // printlink("AFTER"); return true; @@ -210,8 +255,7 @@ public class StateDiagram extends AbstractEntityDiagram { final IGroup parent2 = getGroupParentIfItIsConcurrentState(link.getEntity2()); if (isCompatible(parent1, parent2) == false) { return "State within concurrent state cannot be linked out of this concurrent state (between " - + link.getEntity1().getCodeGetName() + " and " - + link.getEntity2().getCodeGetName() + ")"; + + link.getEntity1().getCodeGetName() + " and " + link.getEntity2().getCodeGetName() + ")"; } } return super.checkFinalError(); diff --git a/src/net/sourceforge/plantuml/statediagram/StateDiagramFactory.java b/src/net/sourceforge/plantuml/statediagram/StateDiagramFactory.java index a0c07ba65..654c05526 100644 --- a/src/net/sourceforge/plantuml/statediagram/StateDiagramFactory.java +++ b/src/net/sourceforge/plantuml/statediagram/StateDiagramFactory.java @@ -40,6 +40,7 @@ import java.util.List; import net.sourceforge.plantuml.ISkinSimple; import net.sourceforge.plantuml.classdiagram.command.CommandHideShow2; +import net.sourceforge.plantuml.classdiagram.command.CommandNamespaceSeparator; import net.sourceforge.plantuml.classdiagram.command.CommandRemoveRestore; import net.sourceforge.plantuml.classdiagram.command.CommandUrl; import net.sourceforge.plantuml.command.Command; @@ -76,10 +77,8 @@ public class StateDiagramFactory extends UmlDiagramFactory { final List cmds = new ArrayList(); cmds.add(new CommandFootboxIgnored()); cmds.add(new CommandRankDir()); - // cmds.add(new CommandHideEmptyDescription()); cmds.add(new CommandRemoveRestore()); cmds.add(new CommandCreateState()); - // addCommand(new CommandLinkState()); cmds.add(new CommandLinkState()); cmds.add(new CommandCreatePackageState()); cmds.add(new CommandEndState()); @@ -105,6 +104,7 @@ public class StateDiagramFactory extends UmlDiagramFactory { addCommonCommands1(cmds); cmds.add(new CommandHideShow2()); + cmds.add(new CommandNamespaceSeparator()); return cmds; } diff --git a/src/net/sourceforge/plantuml/statediagram/command/CommandAddField.java b/src/net/sourceforge/plantuml/statediagram/command/CommandAddField.java index c24202d3f..435880721 100644 --- a/src/net/sourceforge/plantuml/statediagram/command/CommandAddField.java +++ b/src/net/sourceforge/plantuml/statediagram/command/CommandAddField.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.statediagram.command; import net.sourceforge.plantuml.LineLocation; +import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.regex.IRegex; @@ -45,6 +46,7 @@ import net.sourceforge.plantuml.command.regex.RegexOr; import net.sourceforge.plantuml.command.regex.RegexResult; import net.sourceforge.plantuml.cucadiagram.Code; import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Ident; import net.sourceforge.plantuml.statediagram.StateDiagram; public class CommandAddField extends SingleLineCommand2 { @@ -66,11 +68,18 @@ public class CommandAddField extends SingleLineCommand2 { @Override protected CommandExecutionResult executeArg(StateDiagram diagram, LineLocation location, RegexResult arg) { - final String code = arg.getLazzy("CODE", 0); + final String codeString = arg.getLazzy("CODE", 0); final String field = arg.get("FIELD", 0); - final IEntity entity = diagram.getOrCreateLeaf(diagram.buildLeafIdent(code), - diagram.buildCode(code), null, null); + Ident ident = diagram.buildLeafIdent(codeString); + if (diagram.V1972()) { + // This is very bad. xi04 xc06 + if (ident.parent().getLast().equals(codeString)) { + ident = ident.parent(); + } + } + final Code code = diagram.V1972() ? ident : diagram.buildCode(codeString); + final IEntity entity = diagram.getOrCreateLeaf(ident, code, null, null); entity.getBodier().addFieldOrMethod(field, entity); return CommandExecutionResult.ok(); diff --git a/src/net/sourceforge/plantuml/statediagram/command/CommandCreatePackageState.java b/src/net/sourceforge/plantuml/statediagram/command/CommandCreatePackageState.java index 9433bc0e0..db318bf25 100644 --- a/src/net/sourceforge/plantuml/statediagram/command/CommandCreatePackageState.java +++ b/src/net/sourceforge/plantuml/statediagram/command/CommandCreatePackageState.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.statediagram.command; import net.sourceforge.plantuml.LineLocation; +import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.UrlBuilder; import net.sourceforge.plantuml.UrlBuilder.ModeUrl; @@ -111,12 +112,12 @@ public class CommandCreatePackageState extends SingleLineCommand2 protected CommandExecutionResult executeArg(StateDiagram diagram, LineLocation location, RegexResult arg) { final IGroup currentPackage = diagram.getCurrentGroup(); final String idShort = getNotNull(arg, "CODE1", "CODE2"); - final Code code = diagram.buildCode(idShort); + final Ident idNewLong = diagram.buildLeafIdentSpecial(idShort); + final Code code = diagram.V1972() ? idNewLong : diagram.buildCode(idShort); String display = getNotNull(arg, "DISPLAY1", "DISPLAY2"); if (display == null) { display = code.getName(); } - final Ident idNewLong = diagram.buildLeafIdentSpecial(idShort); diagram.gotoGroup(idNewLong, code, Display.getWithNewlines(display), GroupType.STATE, currentPackage, NamespaceStrategy.SINGLE); final IEntity p = diagram.getCurrentGroup(); diff --git a/src/net/sourceforge/plantuml/statediagram/command/CommandCreateState.java b/src/net/sourceforge/plantuml/statediagram/command/CommandCreateState.java index 112612d12..2eab0b6fb 100644 --- a/src/net/sourceforge/plantuml/statediagram/command/CommandCreateState.java +++ b/src/net/sourceforge/plantuml/statediagram/command/CommandCreateState.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.statediagram.command; import net.sourceforge.plantuml.LineLocation; +import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.UrlBuilder; import net.sourceforge.plantuml.UrlBuilder.ModeUrl; @@ -50,6 +51,7 @@ import net.sourceforge.plantuml.command.regex.RegexResult; import net.sourceforge.plantuml.cucadiagram.Code; import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Ident; import net.sourceforge.plantuml.cucadiagram.LeafType; import net.sourceforge.plantuml.cucadiagram.Stereotype; import net.sourceforge.plantuml.graphic.HtmlColor; @@ -104,14 +106,15 @@ public class CommandCreateState extends SingleLineCommand2 { @Override protected CommandExecutionResult executeArg(StateDiagram diagram, LineLocation location, RegexResult arg) { final String idShort = arg.getLazzy("CODE", 0); - final Code code = diagram.buildCode(idShort); + final Ident ident = diagram.buildLeafIdent(idShort); + final Code code = diagram.V1972() ? ident : diagram.buildCode(idShort); String display = arg.getLazzy("DISPLAY", 0); if (display == null) { display = code.getName(); } final String stereotype = arg.get("STEREOTYPE", 0); final LeafType type = getTypeFromStereotype(stereotype); - if (diagram.checkConcurrentStateOk(diagram.buildLeafIdent(idShort), code) == false) { + if (diagram.checkConcurrentStateOk(ident, code) == false) { return CommandExecutionResult.error("The state " + code.getName() + " has been created in a concurrent state : it cannot be used here."); } diff --git a/src/net/sourceforge/plantuml/statediagram/command/CommandLinkState.java b/src/net/sourceforge/plantuml/statediagram/command/CommandLinkState.java index c70f75c84..2f512c32a 100644 --- a/src/net/sourceforge/plantuml/statediagram/command/CommandLinkState.java +++ b/src/net/sourceforge/plantuml/statediagram/command/CommandLinkState.java @@ -37,6 +37,7 @@ package net.sourceforge.plantuml.statediagram.command; import net.sourceforge.plantuml.Direction; import net.sourceforge.plantuml.LineLocation; +import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.UmlDiagramType; import net.sourceforge.plantuml.command.CommandExecutionResult; @@ -48,6 +49,7 @@ import net.sourceforge.plantuml.command.regex.RegexResult; import net.sourceforge.plantuml.cucadiagram.Code; import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Ident; import net.sourceforge.plantuml.cucadiagram.LeafType; import net.sourceforge.plantuml.cucadiagram.Link; import net.sourceforge.plantuml.cucadiagram.LinkDecor; @@ -151,27 +153,6 @@ public class CommandLinkState extends SingleLineCommand2 { return CommandExecutionResult.ok(); } - // public static void applyStyle(String arrowStyle, Link link) { - // if (arrowStyle == null) { - // return; - // } - // final StringTokenizer st = new StringTokenizer(arrowStyle, ","); - // while (st.hasMoreTokens()) { - // final String s = st.nextToken(); - // if (s.equalsIgnoreCase("dashed")) { - // link.goDashed(); - // } else if (s.equalsIgnoreCase("bold")) { - // link.goBold(); - // } else if (s.equalsIgnoreCase("dotted")) { - // link.goDotted(); - // } else if (s.equalsIgnoreCase("hidden")) { - // link.goHidden(); - // } else { - // link.setSpecificColor(s); - // } - // } - // } - private Direction getDirection(RegexResult arg) { final String arrowDirection = arg.get("ARROW_DIRECTION", 0); if (arrowDirection != null) { @@ -180,24 +161,39 @@ public class CommandLinkState extends SingleLineCommand2 { return null; } - private IEntity getEntityStart(StateDiagram diagram, String code) { - if (code.startsWith("[*]")) { + private IEntity getEntityStart(StateDiagram diagram, final String codeString) { + if (codeString.startsWith("[*]")) { return diagram.getStart(); } - if (code.equalsIgnoreCase("[H]")) { + return getFoo1(diagram, codeString); + } + + private IEntity getEntityEnd(StateDiagram diagram, final String codeString) { + if (codeString.startsWith("[*]")) { + return diagram.getEnd(); + } + return getFoo1(diagram, codeString); + } + + private IEntity getFoo1(StateDiagram diagram, final String codeString) { + if (codeString.equalsIgnoreCase("[H]")) { return diagram.getHistorical(); } - if (code.endsWith("[H]")) { - return diagram.getHistorical(code.substring(0, code.length() - 3)); + if (codeString.endsWith("[H]")) { + return diagram.getHistorical(codeString.substring(0, codeString.length() - 3)); } - if (code.startsWith("=") && code.endsWith("=")) { - code = removeEquals(code); - return diagram.getOrCreateLeaf(diagram.buildLeafIdent(code), diagram.buildCode(code), LeafType.SYNCHRO_BAR, null); + if (codeString.startsWith("=") && codeString.endsWith("=")) { + final String codeString1 = removeEquals(codeString); + final Ident ident1 = diagram.buildLeafIdent(codeString1); + final Code code1 = diagram.V1972() ? ident1 : diagram.buildCode(codeString1); + return diagram.getOrCreateLeaf(ident1, code1, LeafType.SYNCHRO_BAR, null); } - if (diagram.checkConcurrentStateOk(diagram.buildLeafIdent(code), diagram.buildCode(code)) == false) { + final Ident ident = diagram.buildLeafIdent(codeString); + final Code code = diagram.V1972() ? ident : diagram.buildCode(codeString); + if (diagram.checkConcurrentStateOk(ident, code) == false) { return null; } - return diagram.getOrCreateLeaf(diagram.buildLeafIdent(code), diagram.buildCode(code), null, null); + return diagram.getOrCreateLeaf(ident, code, null, null); } private String removeEquals(String code) { @@ -210,21 +206,4 @@ public class CommandLinkState extends SingleLineCommand2 { return code; } - private IEntity getEntityEnd(StateDiagram diagram, String code) { - if (code.startsWith("[*]")) { - return diagram.getEnd(); - } - if (code.endsWith("[H]")) { - return diagram.getHistorical(code.substring(0, code.length() - 3)); - } - if (code.startsWith("=") && code.endsWith("=")) { - code = removeEquals(code); - return diagram.getOrCreateLeaf(diagram.buildLeafIdent(code), diagram.buildCode(code), LeafType.SYNCHRO_BAR, null); - } - if (diagram.checkConcurrentStateOk(diagram.buildLeafIdent(code), diagram.buildCode(code)) == false) { - return null; - } - return diagram.getOrCreateLeaf(diagram.buildLeafIdent(code), diagram.buildCode(code), null, null); - } - } diff --git a/src/net/sourceforge/plantuml/svek/extremity/ExtremityCircle.java b/src/net/sourceforge/plantuml/svek/extremity/ExtremityCircle.java index 814a319cb..5b6cf33ad 100644 --- a/src/net/sourceforge/plantuml/svek/extremity/ExtremityCircle.java +++ b/src/net/sourceforge/plantuml/svek/extremity/ExtremityCircle.java @@ -56,13 +56,16 @@ class ExtremityCircle extends Extremity { return dest; } - public static UDrawable create(Point2D center, boolean fill) { - return new ExtremityCircle(center.getX(), center.getY(), fill); + public static UDrawable create(Point2D center, boolean fill, double angle) { + return new ExtremityCircle(center.getX(), center.getY(), fill, angle); } - private ExtremityCircle(double x, double y, boolean fill) { - this.dest = new Point2D.Double(x, y); + private ExtremityCircle(double x, double y, boolean fill, double angle) { + this.dest = new Point2D.Double(x - radius * Math.cos(angle + Math.PI / 2), y - radius + * Math.sin(angle + Math.PI / 2)); this.fill = fill; + // contact = new Point2D.Double(p1.getX() - xContact * Math.cos(angle + Math.PI / 2), p1.getY() - xContact + // * Math.sin(angle + Math.PI / 2)); } public void drawU(UGraphic ug) { diff --git a/src/net/sourceforge/plantuml/svek/extremity/ExtremityFactoryCircle.java b/src/net/sourceforge/plantuml/svek/extremity/ExtremityFactoryCircle.java index d42496059..569b3d646 100644 --- a/src/net/sourceforge/plantuml/svek/extremity/ExtremityFactoryCircle.java +++ b/src/net/sourceforge/plantuml/svek/extremity/ExtremityFactoryCircle.java @@ -51,11 +51,13 @@ public class ExtremityFactoryCircle extends AbstractExtremityFactory implements @Override public UDrawable createUDrawable(Point2D center, double angle, Side side) { - return ExtremityCircle.create(center, fill); + angle -= Math.PI / 2; + return ExtremityCircle.create(center, fill, angle); } public UDrawable createUDrawable(Point2D p0, Point2D p1, Point2D p2, Side side) { - return ExtremityCircle.create(p1, fill); + final double ortho = atan2(p0, p2); + return ExtremityCircle.create(p1, fill, ortho); } } diff --git a/src/net/sourceforge/plantuml/preproc/ReadLineSingle.java b/src/net/sourceforge/plantuml/svek/extremity/ExtremityFactoryHalfArrow.java similarity index 63% rename from src/net/sourceforge/plantuml/preproc/ReadLineSingle.java rename to src/net/sourceforge/plantuml/svek/extremity/ExtremityFactoryHalfArrow.java index 2e2e553ba..0c1638450 100644 --- a/src/net/sourceforge/plantuml/preproc/ReadLineSingle.java +++ b/src/net/sourceforge/plantuml/svek/extremity/ExtremityFactoryHalfArrow.java @@ -30,31 +30,28 @@ * * * Original Author: Arnaud Roques - * * + * */ -package net.sourceforge.plantuml.preproc; +package net.sourceforge.plantuml.svek.extremity; -import net.sourceforge.plantuml.StringLocated; +import java.awt.geom.Point2D; -public class ReadLineSingle implements ReadLine { +import net.sourceforge.plantuml.graphic.UDrawable; +import net.sourceforge.plantuml.svek.AbstractExtremityFactory; +import net.sourceforge.plantuml.svek.Side; - private final StringLocated data; - private int current = 0; +public class ExtremityFactoryHalfArrow extends AbstractExtremityFactory implements ExtremityFactory { - public ReadLineSingle(StringLocated s2) { - this.data = s2; + @Override + public UDrawable createUDrawable(Point2D p0, double angle, Side side) { + return new ExtremityHalfArrow(p0, angle); } - public void close() { - } - - public StringLocated readLine() { - if (current > 0) { - return null; - } - current++; - return data; + public UDrawable createUDrawable(Point2D p0, Point2D p1, Point2D p2, Side side) { + final double ortho = atan2(p0, p2); + final Point2D center = new Point2D.Double((p0.getX() + p2.getX()) / 2, (p0.getY() + p2.getY()) / 2); + return new ExtremityHalfArrow(p1, ortho, center); } } diff --git a/src/net/sourceforge/plantuml/svek/extremity/ExtremityHalfArrow.java b/src/net/sourceforge/plantuml/svek/extremity/ExtremityHalfArrow.java new file mode 100644 index 000000000..3068b181b --- /dev/null +++ b/src/net/sourceforge/plantuml/svek/extremity/ExtremityHalfArrow.java @@ -0,0 +1,81 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2020, 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.svek.extremity; + +import java.awt.geom.AffineTransform; +import java.awt.geom.Point2D; + +import net.sourceforge.plantuml.ugraphic.UChangeBackColor; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.UTranslate; + +class ExtremityHalfArrow extends Extremity { + + private final ULine line; + private final ULine otherLine; + private final Point2D contact; + + @Override + public Point2D somePoint() { + return contact; + } + + public ExtremityHalfArrow(Point2D p1, double angle, Point2D center) { + angle = manageround(angle); + final AffineTransform rotate = AffineTransform.getRotateInstance(angle + Math.PI / 2); + final int xWing = 9; + final int yAperture = 4; + final Point2D other = new Point2D.Double(-xWing, -yAperture); + rotate.transform(other, other); + this.contact = p1; + this.line = new ULine(center.getX() - contact.getX(), center.getY() - contact.getY()); + this.otherLine = new ULine(other.getX(), other.getY()); + } + + public ExtremityHalfArrow(Point2D p0, double angle) { + throw new UnsupportedOperationException(); + } + + public void drawU(UGraphic ug) { + ug = ug.apply(new UChangeBackColor(ug.getParam().getColor())); + if (line != null && line.getLength() > 2) { + ug.apply(new UTranslate(contact.getX(), contact.getY())).draw(line); + ug.apply(new UTranslate(contact.getX(), contact.getY())).draw(otherLine); + } + } + +} diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageUseCase.java b/src/net/sourceforge/plantuml/svek/image/EntityImageUseCase.java index e1a8bd092..f62b3dd84 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageUseCase.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageUseCase.java @@ -88,9 +88,14 @@ public class EntityImageUseCase extends AbstractEntityImage { || portionShower.showPortion(EntityPortion.STEREOTYPE, entity) == false) { this.desc = tmp; } else { - final TextBlock stereo = Display.getWithNewlines(stereotype.getLabel(getSkinParam().guillemet())) - .create(new FontConfiguration(getSkinParam(), FontParam.USECASE_STEREOTYPE, stereotype), - HorizontalAlignment.CENTER, skinParam); + final TextBlock stereo; + if (stereotype.getSprite(getSkinParam()) != null) { + stereo = stereotype.getSprite(getSkinParam()); + } else { + stereo = Display.getWithNewlines(stereotype.getLabel(getSkinParam().guillemet())).create( + new FontConfiguration(getSkinParam(), FontParam.USECASE_STEREOTYPE, stereotype), + HorizontalAlignment.CENTER, skinParam); + } this.desc = TextBlockUtils.mergeTB(stereo, tmp, HorizontalAlignment.CENTER); } this.url = entity.getUrl99(); diff --git a/src/net/sourceforge/plantuml/tim/TContext.java b/src/net/sourceforge/plantuml/tim/TContext.java index 2a3ddfd40..22f5b0cc7 100644 --- a/src/net/sourceforge/plantuml/tim/TContext.java +++ b/src/net/sourceforge/plantuml/tim/TContext.java @@ -47,7 +47,6 @@ import java.util.Set; import net.sourceforge.plantuml.DefinitionsContainer; import net.sourceforge.plantuml.FileSystem; -import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.StringLocated; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.json.JsonObject; @@ -59,11 +58,10 @@ import net.sourceforge.plantuml.preproc.ReadLine; import net.sourceforge.plantuml.preproc.ReadLineList; import net.sourceforge.plantuml.preproc.ReadLineReader; import net.sourceforge.plantuml.preproc.StartDiagramExtractReader; -import net.sourceforge.plantuml.preproc.Sub2; +import net.sourceforge.plantuml.preproc.Sub; import net.sourceforge.plantuml.preproc.UncommentReadLine; -import net.sourceforge.plantuml.preproc2.PreprocessorInclude; import net.sourceforge.plantuml.preproc2.PreprocessorIncludeStrategy; -import net.sourceforge.plantuml.preproc2.ReadLineQuoteComment; +import net.sourceforge.plantuml.preproc2.PreprocessorUtils; import net.sourceforge.plantuml.tim.expression.Knowledge; import net.sourceforge.plantuml.tim.expression.TValue; import net.sourceforge.plantuml.tim.stdlib.AlwaysFalse; @@ -98,9 +96,9 @@ public class TContext { private final String charset; private TFunctionImpl pendingFunction; - private Sub2 pendingSub; + private Sub pendingSub; private boolean inLongComment; - private final Map subs = new HashMap(); + private final Map subs = new HashMap(); private final DefinitionsContainer definitionsContainer; // private final Set usedFiles = new HashSet(); @@ -187,7 +185,7 @@ public class TContext { } final EaterStartsub eater = new EaterStartsub(s.getTrimmed().getString()); eater.execute(this, memory); - this.pendingSub = new Sub2(eater.getSubname()); + this.pendingSub = new Sub(eater.getSubname()); this.subs.put(eater.getSubname(), this.pendingSub); return; } @@ -195,15 +193,15 @@ public class TContext { if (pendingSub == null) { throw new EaterException("No corresponding !startsub"); } - final Sub2 newly = this.pendingSub; + final Sub newly = this.pendingSub; this.pendingSub = null; this.runSub(memory, newly); return; } - if (this.inLongComment == false && type == TLineType.INCLUDESUB) { - this.executeIncludesub(memory, s); - return; - } + // if (this.inLongComment == false && type == TLineType.INCLUDESUB) { + // this.executeIncludesub(memory, s); + // return; + // } if (pendingSub != null) { pendingSub.add(s); @@ -260,6 +258,10 @@ public class TContext { if (conditionalContext != null && memory.areAllIfOk() == false) { return; } + if (this.inLongComment == false && type == TLineType.INCLUDESUB) { + this.executeIncludesub(memory, s); + return; + } if (type == TLineType.DUMP_MEMORY) { this.executeDumpMemory(memory, s.getTrimmed().getString()); @@ -585,26 +587,27 @@ public class TContext { include.execute(this, memory); final String location = include.getLocation(); final int idx = location.indexOf('!'); - Sub2 sub = null; - if (OptionFlags.ALLOW_INCLUDE && idx != -1) { + Sub sub = null; + if (idx != -1) { final String filename = location.substring(0, idx); final String blocname = location.substring(idx + 1); try { - final FileWithSuffix f2 = new FileWithSuffix(importedFiles, filename, null); + final FileWithSuffix f2 = importedFiles.getFile(filename, null); if (f2.fileOk()) { saveImportedFiles = this.importedFiles; this.importedFiles = this.importedFiles.withCurrentDir(f2.getParentFile()); final Reader reader = f2.getReader(charset); ReadLine readerline = ReadLineReader.create(reader, location, s.getLocation()); readerline = new UncommentReadLine(readerline); - readerline = new ReadLineQuoteComment(true).applyFilter(readerline); - sub = Sub2.fromFile(readerline, blocname, this, memory); + // readerline = new ReadLineQuoteComment(true).applyFilter(readerline); + sub = Sub.fromFile(readerline, blocname, this, memory); } } catch (IOException e) { e.printStackTrace(); throw new EaterException("cannot include " + e); } - } else { + } + if (sub == null) { sub = subs.get(location); } if (sub == null) { @@ -618,7 +621,7 @@ public class TContext { } } - private void runSub(TMemory memory, final Sub2 sub) throws EaterException { + private void runSub(TMemory memory, final Sub sub) throws EaterException { for (StringLocated sl : sub.lines()) { executeOneLine(memory, TLineType.getFromLine(sl.getString()), sl, null); } @@ -628,11 +631,11 @@ public class TContext { final EaterIncludeDef include = new EaterIncludeDef(s.getTrimmed().getString()); include.execute(this, memory); final String definitionName = include.getLocation(); - final List definition = definitionsContainer.getDefinition2(definitionName); + final List definition = definitionsContainer.getDefinition(definitionName); ReadLine reader2 = new ReadLineList(definition, s.getLocation()); try { - reader2 = new ReadLineQuoteComment(true).applyFilter(reader2); + // reader2 = new ReadLineQuoteComment(true).applyFilter(reader2); do { final StringLocated sl = reader2.readLine(); if (sl == null) { @@ -663,13 +666,13 @@ public class TContext { try { if (location.startsWith("http://") || location.startsWith("https://")) { final URL url = new URL(location); - reader2 = PreprocessorInclude.getReaderIncludeUrl2(url, s, suf, charset); + reader2 = PreprocessorUtils.getReaderIncludeUrl2(url, s, suf, charset); } if (location.startsWith("<") && location.endsWith(">")) { - reader2 = PreprocessorInclude.getReaderStdlibInclude(s, location.substring(1, location.length() - 1)); - } else if (OptionFlags.ALLOW_INCLUDE) { - final FileWithSuffix f2 = new FileWithSuffix(importedFiles, location, suf); + reader2 = PreprocessorUtils.getReaderStdlibInclude(s, location.substring(1, location.length() - 1)); + } else { + final FileWithSuffix f2 = importedFiles.getFile(location, suf); if (f2.fileOk()) { if (strategy == PreprocessorIncludeStrategy.DEFAULT && filesUsedCurrent.contains(f2)) { return; @@ -695,7 +698,7 @@ public class TContext { } } if (reader2 != null) { - reader2 = new ReadLineQuoteComment(true).applyFilter(reader2); + // reader2 = new ReadLineQuoteComment(true).applyFilter(reader2); try { do { final StringLocated sl = reader2.readLine(); diff --git a/src/net/sourceforge/plantuml/tim/TimLoader.java b/src/net/sourceforge/plantuml/tim/TimLoader.java index ffb14fc69..abcdddab3 100644 --- a/src/net/sourceforge/plantuml/tim/TimLoader.java +++ b/src/net/sourceforge/plantuml/tim/TimLoader.java @@ -48,8 +48,14 @@ public class TimLoader { private boolean preprocessorError; private List resultList; - public TimLoader(ImportedFiles importedFiles, Defines defines, String charset, DefinitionsContainer definitionsContainer) { + public TimLoader(ImportedFiles importedFiles, Defines defines, String charset, + DefinitionsContainer definitionsContainer) { this.context = new TContext(importedFiles, defines, charset, definitionsContainer); + try { + defines.copyTo(global); + } catch (EaterException e) { + e.printStackTrace(); + } } public void load(List input) { diff --git a/src/net/sourceforge/plantuml/ugraphic/AbstractCommonUGraphic.java b/src/net/sourceforge/plantuml/ugraphic/AbstractCommonUGraphic.java index f8492243c..ef6771ab3 100644 --- a/src/net/sourceforge/plantuml/ugraphic/AbstractCommonUGraphic.java +++ b/src/net/sourceforge/plantuml/ugraphic/AbstractCommonUGraphic.java @@ -44,6 +44,7 @@ public abstract class AbstractCommonUGraphic implements UGraphic { private boolean hidden = false; private HtmlColor backColor = null; private HtmlColor color = null; + private boolean enlargeClip = false; private UTranslate translate = new UTranslate(); @@ -80,14 +81,22 @@ public abstract class AbstractCommonUGraphic implements UGraphic { } final public UClip getClip() { + if (enlargeClip && clip != null) { + return clip.enlarge(1); + } return clip; } + final public void enlargeClip() { + this.enlargeClip = true; + } + public AbstractCommonUGraphic(ColorMapper colorMapper) { this.colorMapper = colorMapper; } protected AbstractCommonUGraphic(AbstractCommonUGraphic other) { + this.enlargeClip = other.enlargeClip; this.colorMapper = other.colorMapper; this.translate = other.translate; this.clip = other.clip; diff --git a/src/net/sourceforge/plantuml/ugraphic/UClip.java b/src/net/sourceforge/plantuml/ugraphic/UClip.java index 3fc87bada..18f2ca985 100644 --- a/src/net/sourceforge/plantuml/ugraphic/UClip.java +++ b/src/net/sourceforge/plantuml/ugraphic/UClip.java @@ -52,6 +52,10 @@ public class UClip implements UChange { this.height = height; } + public UClip enlarge(double delta) { + return new UClip(x - delta, y - delta, width + 2 * delta, height + 2 * delta); + } + @Override public String toString() { return "CLIP x=" + x + " y=" + y + " w=" + width + " h=" + height; diff --git a/src/net/sourceforge/plantuml/ugraphic/hand/UGraphicHandwritten.java b/src/net/sourceforge/plantuml/ugraphic/hand/UGraphicHandwritten.java index 02ef3b52b..98355cc6b 100644 --- a/src/net/sourceforge/plantuml/ugraphic/hand/UGraphicHandwritten.java +++ b/src/net/sourceforge/plantuml/ugraphic/hand/UGraphicHandwritten.java @@ -49,6 +49,7 @@ import net.sourceforge.plantuml.ugraphic.UPath; import net.sourceforge.plantuml.ugraphic.UPolygon; import net.sourceforge.plantuml.ugraphic.URectangle; import net.sourceforge.plantuml.ugraphic.UShape; +import net.sourceforge.plantuml.ugraphic.svg.UGraphicSvg; public class UGraphicHandwritten implements UGraphic { @@ -57,6 +58,9 @@ public class UGraphicHandwritten implements UGraphic { public UGraphicHandwritten(UGraphic ug) { this.ug = ug; + if (ug instanceof UGraphicSvg) { + ((UGraphicSvg) ug).enlargeClip(); + } } public StringBounder getStringBounder() { diff --git a/src/net/sourceforge/plantuml/version/PSystemVersion.java b/src/net/sourceforge/plantuml/version/PSystemVersion.java index 1d0f69632..26abb5df8 100644 --- a/src/net/sourceforge/plantuml/version/PSystemVersion.java +++ b/src/net/sourceforge/plantuml/version/PSystemVersion.java @@ -65,7 +65,7 @@ import net.sourceforge.plantuml.graphic.GraphicPosition; import net.sourceforge.plantuml.graphic.GraphicStrings; import net.sourceforge.plantuml.preproc.ImportedFiles; import net.sourceforge.plantuml.preproc.Stdlib; -import net.sourceforge.plantuml.preproc2.PreprocessorInclude; +import net.sourceforge.plantuml.preproc2.PreprocessorUtils; import net.sourceforge.plantuml.svek.TextBlockBackcolored; import net.sourceforge.plantuml.ugraphic.ColorMapperIdentity; import net.sourceforge.plantuml.ugraphic.ImageBuilder; @@ -182,7 +182,7 @@ public class PSystemVersion extends AbstractPSystem { strings.add("Word Mode"); strings.add("Command Line: " + Run.getCommandLine()); strings.add("Current Dir: " + new File(".").getAbsolutePath()); - strings.add("plantuml.include.path: " + PreprocessorInclude.getenv("plantuml.include.path")); + strings.add("plantuml.include.path: " + PreprocessorUtils.getenv("plantuml.include.path")); } } strings.add(" "); diff --git a/src/net/sourceforge/plantuml/version/Version.java b/src/net/sourceforge/plantuml/version/Version.java index e1bf5a32b..f56c78261 100644 --- a/src/net/sourceforge/plantuml/version/Version.java +++ b/src/net/sourceforge/plantuml/version/Version.java @@ -43,7 +43,7 @@ public class Version { private static final int MAJOR_SEPARATOR = 1000000; public static int version() { - return 1201913; + return 1202000; } public static int versionPatched() { @@ -93,7 +93,7 @@ public class Version { } public static long compileTime() { - return 1575998309706L; + return 1578745853861L; } public static String compileTimeString() { diff --git a/src/sprites/archimate/assignment.png b/src/sprites/archimate/assignment.png index 4dc80e67b..ff5bffba6 100644 Binary files a/src/sprites/archimate/assignment.png and b/src/sprites/archimate/assignment.png differ diff --git a/src/sprites/archimate/association-unidirect.png b/src/sprites/archimate/association-unidirect.png new file mode 100644 index 000000000..70774b1cb Binary files /dev/null and b/src/sprites/archimate/association-unidirect.png differ diff --git a/src/sprites/archimate/motivation-value.png b/src/sprites/archimate/motivation-value.png new file mode 100644 index 000000000..fe7ecc633 Binary files /dev/null and b/src/sprites/archimate/motivation-value.png differ diff --git a/src/sprites/archimate/serving.png b/src/sprites/archimate/serving.png new file mode 100644 index 000000000..ddf59056f Binary files /dev/null and b/src/sprites/archimate/serving.png differ diff --git a/src/sprites/archimate/specialization.png b/src/sprites/archimate/specialization.png new file mode 100644 index 000000000..d3449a3a7 Binary files /dev/null and b/src/sprites/archimate/specialization.png differ diff --git a/src/sprites/archimate/strategy-value-stream.png b/src/sprites/archimate/strategy-value-stream.png new file mode 100644 index 000000000..24fe565ec Binary files /dev/null and b/src/sprites/archimate/strategy-value-stream.png differ diff --git a/src/sprites/archimate/technology-communication-network.png b/src/sprites/archimate/technology-communication-network.png new file mode 100644 index 000000000..95ec28b2d Binary files /dev/null and b/src/sprites/archimate/technology-communication-network.png differ diff --git a/src/sprites/archimate/technology-interface.png b/src/sprites/archimate/technology-interface.png new file mode 100644 index 000000000..ac1e4d038 Binary files /dev/null and b/src/sprites/archimate/technology-interface.png differ diff --git a/src/sprites/archimate/technology-path.png b/src/sprites/archimate/technology-path.png new file mode 100644 index 000000000..3d45c937d Binary files /dev/null and b/src/sprites/archimate/technology-path.png differ diff --git a/src/sprites/archimate/technology-service.png b/src/sprites/archimate/technology-service.png new file mode 100644 index 000000000..bc398eac3 Binary files /dev/null and b/src/sprites/archimate/technology-service.png differ