diff --git a/src/net/sourceforge/plantuml/BlockUml.java b/src/net/sourceforge/plantuml/BlockUml.java index ec0a9634d..204927c18 100644 --- a/src/net/sourceforge/plantuml/BlockUml.java +++ b/src/net/sourceforge/plantuml/BlockUml.java @@ -56,7 +56,7 @@ public class BlockUml { public BlockUml(List strings, int startLine) { this.startLine = startLine; - final String s0 = strings.get(0).toString().trim(); + final String s0 = StringUtils.trin(strings.get(0).toString()); if (s0.startsWith("@start") == false) { throw new IllegalArgumentException(); } @@ -67,7 +67,7 @@ public class BlockUml { if (OptionFlags.getInstance().isWord()) { return null; } - final Matcher m = patternFilename.matcher(data.get(0).toString().trim()); + final Matcher m = patternFilename.matcher(StringUtils.trin(data.get(0).toString())); final boolean ok = m.find(); if (ok == false) { return null; diff --git a/src/net/sourceforge/plantuml/FileFormatOption.java b/src/net/sourceforge/plantuml/FileFormatOption.java index 6309f8280..a645a8903 100644 --- a/src/net/sourceforge/plantuml/FileFormatOption.java +++ b/src/net/sourceforge/plantuml/FileFormatOption.java @@ -70,9 +70,14 @@ public class FileFormatOption { private final AffineTransform affineTransform; private final boolean withMetadata; private final boolean useRedForError; + private final String svgLinkTarget; public FileFormatOption(FileFormat fileFormat) { - this(fileFormat, null, true, false); + this(fileFormat, null, true, false, "_top"); + } + + public String getSvgLinkTarget() { + return svgLinkTarget; } public final boolean isWithMetadata() { @@ -80,18 +85,23 @@ public class FileFormatOption { } public FileFormatOption(FileFormat fileFormat, boolean withMetadata) { - this(fileFormat, null, false, false); + this(fileFormat, null, false, false, "_top"); } - private FileFormatOption(FileFormat fileFormat, AffineTransform at, boolean withMetadata, boolean useRedForError) { + private FileFormatOption(FileFormat fileFormat, AffineTransform at, boolean withMetadata, boolean useRedForError, String svgLinkTarget) { this.fileFormat = fileFormat; this.affineTransform = at; this.withMetadata = withMetadata; this.useRedForError = useRedForError; + this.svgLinkTarget = svgLinkTarget; } public FileFormatOption withUseRedForError() { - return new FileFormatOption(fileFormat, affineTransform, withMetadata, true); + return new FileFormatOption(fileFormat, affineTransform, withMetadata, true, svgLinkTarget); + } + + public FileFormatOption withSvgLinkTarget(String target) { + return new FileFormatOption(fileFormat, affineTransform, withMetadata, useRedForError, target); } @Override @@ -152,11 +162,11 @@ public class FileFormatOption { } final UGraphicSvg ug; if (mybackcolor instanceof HtmlColorGradient) { - ug = new UGraphicSvg(colorMapper, (HtmlColorGradient) mybackcolor, false, scale); + ug = new UGraphicSvg(colorMapper, (HtmlColorGradient) mybackcolor, false, scale, getSvgLinkTarget()); } else if (backColor == null || backColor.equals(Color.WHITE)) { - ug = new UGraphicSvg(colorMapper, false, scale); + ug = new UGraphicSvg(colorMapper, false, scale, getSvgLinkTarget()); } else { - ug = new UGraphicSvg(colorMapper, StringUtils.getAsHtml(backColor), false, scale); + ug = new UGraphicSvg(colorMapper, StringUtils.getAsHtml(backColor), false, scale, getSvgLinkTarget()); } return ug; diff --git a/src/net/sourceforge/plantuml/FontParam.java b/src/net/sourceforge/plantuml/FontParam.java index 8ecb96320..46ac9b8bc 100644 --- a/src/net/sourceforge/plantuml/FontParam.java +++ b/src/net/sourceforge/plantuml/FontParam.java @@ -28,13 +28,18 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 15877 $ + * Revision $Revision: 16206 $ * */ package net.sourceforge.plantuml; import java.awt.Font; +import net.sourceforge.plantuml.graphic.FontConfiguration; +import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.skin.rose.Rose; +import net.sourceforge.plantuml.ugraphic.UFont; + interface FontParamConstant { String FAMILY = "SansSerif"; String COLOR = "black"; @@ -146,4 +151,12 @@ public enum FontParam { return defaultFamily; } + public FontConfiguration getFontConfiguration(ISkinParam skinParam) { + final UFont font = skinParam.getFont(this, null, false); + final HtmlColor color = new Rose().getFontColor(skinParam, this); + final HtmlColor hyperlinkColor = skinParam.getHyperlinkColor(); + final boolean useUnderlineForHyperlink = skinParam.useUnderlineForHyperlink(); + return new FontConfiguration(font, color, hyperlinkColor, useUnderlineForHyperlink); + } + } diff --git a/src/net/sourceforge/plantuml/ISkinParam.java b/src/net/sourceforge/plantuml/ISkinParam.java index d70356759..b0dc15224 100644 --- a/src/net/sourceforge/plantuml/ISkinParam.java +++ b/src/net/sourceforge/plantuml/ISkinParam.java @@ -121,4 +121,6 @@ public interface ISkinParam extends ISkinSimple { public boolean handwritten(); + public String getSvgLinkTarget(); + } \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/OptionFlags.java b/src/net/sourceforge/plantuml/OptionFlags.java index ceae6ebfc..50b47e33f 100644 --- a/src/net/sourceforge/plantuml/OptionFlags.java +++ b/src/net/sourceforge/plantuml/OptionFlags.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 15892 $ + * Revision $Revision: 16158 $ * */ package net.sourceforge.plantuml; diff --git a/src/net/sourceforge/plantuml/PSystemBuilder.java b/src/net/sourceforge/plantuml/PSystemBuilder.java index 589ac49df..ddc25ed5f 100644 --- a/src/net/sourceforge/plantuml/PSystemBuilder.java +++ b/src/net/sourceforge/plantuml/PSystemBuilder.java @@ -103,7 +103,7 @@ public class PSystemBuilder { errors.add((PSystemError) sys); } - final PSystemError err = merge(errors); + final PSystemError err = PSystemError.merge(errors); // if (OptionFlags.getInstance().isQuiet() == false) { // err.print(System.err); // } @@ -160,21 +160,6 @@ public class PSystemBuilder { return factories; } - private PSystemError merge(Collection ps) { - UmlSource source = null; - final List errors = new ArrayList(); - for (PSystemError system : ps) { - if (system.getSource() != null && source == null) { - source = system.getSource(); - } - errors.addAll(system.getErrorsUml()); - } - if (source == null) { - throw new IllegalStateException(); - } - return new PSystemError(source, errors); - } - private boolean isOk(Diagram ps) { if (ps == null || ps instanceof PSystemError) { return false; diff --git a/src/net/sourceforge/plantuml/PSystemError.java b/src/net/sourceforge/plantuml/PSystemError.java index caddb7498..5aa49d07d 100644 --- a/src/net/sourceforge/plantuml/PSystemError.java +++ b/src/net/sourceforge/plantuml/PSystemError.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 15848 $ + * Revision $Revision: 16158 $ */ package net.sourceforge.plantuml; @@ -54,24 +54,15 @@ import net.sourceforge.plantuml.ugraphic.txt.UGraphicTxt; public class PSystemError extends AbstractPSystem { - private String getSuggestColor(boolean useRed) { - if (useRed) { - return "black"; - } - return "white"; - } - - private String getRed(boolean useRed) { - if (useRed) { - return "#CD0A0A"; - } - return "red"; - } - private final int higherErrorPosition; private final List printedErrors; + private final List debugLines = new ArrayList(); - public PSystemError(UmlSource source, List all) { + public PSystemError(UmlSource source, ErrorUml singleError, List debugLines) { + this(source, Collections.singletonList(singleError), debugLines); + } + + private PSystemError(UmlSource source, List all, List debugLines) { this.setSource(source); final int higherErrorPositionExecution = getHigherErrorPosition(ErrorUmlType.EXECUTION_ERROR, all); @@ -90,10 +81,24 @@ public class PSystemError extends AbstractPSystem { printedErrors = getErrorsAt(higherErrorPositionSyntax, ErrorUmlType.SYNTAX_ERROR, all); } + if (debugLines != null) { + this.debugLines.addAll(debugLines); + } + } - public PSystemError(UmlSource source, ErrorUml singleError) { - this(source, Collections.singletonList(singleError)); + private String getSuggestColor(boolean useRed) { + if (useRed) { + return "black"; + } + return "white"; + } + + private String getRed(boolean useRed) { + if (useRed) { + return "#CD0A0A"; + } + return "red"; } public ImageData exportDiagram(OutputStream os, int num, FileFormatOption fileFormat) throws IOException { @@ -110,7 +115,7 @@ public class PSystemError extends AbstractPSystem { final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, result.getBackcolor(), getMetadata(), null, 0, 0, null, false); imageBuilder.addUDrawable(result); - return imageBuilder.writeImageTOBEMOVED(fileFormat.getFileFormat(), os); + return imageBuilder.writeImageTOBEMOVED(fileFormat, os); } private List getTextStrings() { @@ -158,6 +163,7 @@ public class PSystemError extends AbstractPSystem { } first = false; } + result.addAll(this.debugLines); return result; } @@ -186,10 +192,10 @@ public class PSystemError extends AbstractPSystem { if (StringUtils.isNotEmpty(err)) { htmlStrings.add("" + err + ""); } -// final StringBuilder underscore = new StringBuilder(); -// for (int i = 0; i < errorLine.length(); i++) { -// underscore.append("^"); -// } + // final StringBuilder underscore = new StringBuilder(); + // for (int i = 0; i < errorLine.length(); i++) { + // underscore.append("^"); + // } final Collection textErrors = new LinkedHashSet(); for (ErrorUml er : printedErrors) { textErrors.add(er.getError()); @@ -207,6 +213,7 @@ public class PSystemError extends AbstractPSystem { } first = false; } + htmlStrings.addAll(this.debugLines); return htmlStrings; } @@ -293,4 +300,25 @@ public class PSystemError extends AbstractPSystem { } return sb.toString(); } + + public static PSystemError merge(Collection ps) { + UmlSource source = null; + final List errors = new ArrayList(); + final List debugs = new ArrayList(); + for (PSystemError system : ps) { + if (system.getSource() != null && source == null) { + source = system.getSource(); + } + errors.addAll(system.getErrorsUml()); + debugs.addAll(system.debugLines); + if (system.debugLines.size() > 0) { + debugs.add("-"); + } + } + if (source == null) { + throw new IllegalStateException(); + } + return new PSystemError(source, errors, debugs); + } + } diff --git a/src/net/sourceforge/plantuml/PSystemUtils.java b/src/net/sourceforge/plantuml/PSystemUtils.java index cd80278b7..1425642f8 100644 --- a/src/net/sourceforge/plantuml/PSystemUtils.java +++ b/src/net/sourceforge/plantuml/PSystemUtils.java @@ -55,6 +55,10 @@ public class PSystemUtils { public static List exportDiagrams(Diagram system, File suggestedFile, FileFormatOption fileFormatOption) throws IOException { + if (system instanceof UmlDiagram) { + final ISkinParam skinParam = ((UmlDiagram) system).getSkinParam(); + fileFormatOption = fileFormatOption.withSvgLinkTarget(skinParam.getSvgLinkTarget()); + } if (system instanceof NewpagedDiagram) { return exportDiagramsNewpaged((NewpagedDiagram) system, suggestedFile, fileFormatOption); } diff --git a/src/net/sourceforge/plantuml/SkinParam.java b/src/net/sourceforge/plantuml/SkinParam.java index 3b0650178..369ad4c69 100644 --- a/src/net/sourceforge/plantuml/SkinParam.java +++ b/src/net/sourceforge/plantuml/SkinParam.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 15982 $ + * Revision $Revision: 16196 $ * */ package net.sourceforge.plantuml; @@ -70,7 +70,7 @@ public class SkinParam implements ISkinParam { private Rankdir rankdir = Rankdir.TOP_TO_BOTTOM; public void setParam(String key, String value) { - params.put(cleanForKey(key), value.trim()); + params.put(cleanForKey(key), StringUtils.trin(value)); } private static final String stereoPatternString = "\\<\\<(.*?)\\>\\>"; @@ -93,7 +93,7 @@ public class SkinParam implements ISkinParam { // } static String cleanForKey(String key) { - key = StringUtils.goLowerCase(key).trim(); + key = StringUtils.trin(StringUtils.goLowerCase(key)); key = key.replaceAll("_|\\.|\\s", ""); key = replaceSmart(key, "partition", "package"); key = replaceSmart(key, "sequenceparticipant", "participant"); @@ -664,4 +664,12 @@ public class SkinParam implements ISkinParam { return false; } + public String getSvgLinkTarget() { + final String value = getValue("svglinktarget"); + if (value == null) { + return "_top"; + } + return value; + } + } diff --git a/src/net/sourceforge/plantuml/SkinParamDelegator.java b/src/net/sourceforge/plantuml/SkinParamDelegator.java index f171e1bda..826bcb662 100644 --- a/src/net/sourceforge/plantuml/SkinParamDelegator.java +++ b/src/net/sourceforge/plantuml/SkinParamDelegator.java @@ -212,5 +212,9 @@ public class SkinParamDelegator implements ISkinParam { return skinParam.handwritten(); } + public String getSvgLinkTarget() { + return skinParam.getSvgLinkTarget(); + } + } diff --git a/src/net/sourceforge/plantuml/SourceStringReader.java b/src/net/sourceforge/plantuml/SourceStringReader.java index ea9649f99..dc25ed671 100644 --- a/src/net/sourceforge/plantuml/SourceStringReader.java +++ b/src/net/sourceforge/plantuml/SourceStringReader.java @@ -130,7 +130,7 @@ public class SourceStringReader { final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, error.getBackcolor(), null, null, 0, 0, null, false); imageBuilder.addUDrawable(error); - imageBuilder.writeImageTOBEMOVED(fileFormatOption.getFileFormat(), os); + imageBuilder.writeImageTOBEMOVED(fileFormatOption, os); } public DiagramDescription generateDiagramDescription(OutputStream os) throws IOException { diff --git a/src/net/sourceforge/plantuml/StringUtils.java b/src/net/sourceforge/plantuml/StringUtils.java index 132c538df..c7a7c1141 100644 --- a/src/net/sourceforge/plantuml/StringUtils.java +++ b/src/net/sourceforge/plantuml/StringUtils.java @@ -117,7 +117,7 @@ public class StringUtils { } public static boolean isNotEmpty(String input) { - return input != null && input.trim().length() > 0; + return input != null && trin(input).length() > 0; } public static boolean isNotEmpty(List input) { @@ -125,7 +125,7 @@ public class StringUtils { } public static boolean isEmpty(String input) { - return input == null || input.trim().length() == 0; + return input == null || trin(input).length() == 0; } public static String manageHtml(String s) { @@ -179,7 +179,7 @@ public class StringUtils { public static String capitalize(String s) { return s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase(); } - + public static String goUpperCase(String s) { return s.toUpperCase(Locale.ENGLISH); } @@ -312,6 +312,10 @@ public class StringUtils { public static char hiddenBiggerThan() { return '\u0006'; } + + public static char hiddenNewLine() { + return '\u0009'; + } public static String hideComparatorCharacters(String s) { s = s.replace('<', hiddenLesserThan()); @@ -388,10 +392,44 @@ public class StringUtils { return result; } + public static void trimSmart(List data, int referenceLine) { + if (data.size() <= referenceLine) { + return; + } + final int nbStartingSpace = nbStartingSpace(data.get(referenceLine)); + for (int i = referenceLine; i < data.size(); i++) { + final String s = data.get(i); + data.set(i, removeStartingSpaces(s, nbStartingSpace)); + } + } + + public static String removeStartingSpaces(String s, int nbStartingSpace) { + for (int i = 0; i < nbStartingSpace; i++) { + if (s.length() > 0 && isSpaceOrTab(s.charAt(0))) { + s = s.substring(1); + } else { + return s; + } + } + return s; + } + + private static boolean isSpaceOrTab(char c) { + return c == ' ' || c == '\t'; + } + + private static int nbStartingSpace(String s) { + int nb = 0; + while (nb < s.length() && isSpaceOrTab(s.charAt(nb))) { + nb++; + } + return nb; + } + public static void trim(List data, boolean removeEmptyLines) { for (int i = 0; i < data.size(); i++) { final String s = data.get(i); - data.set(i, s.trim()); + data.set(i, trin(s)); } if (removeEmptyLines) { for (final Iterator it = data.iterator(); it.hasNext();) { @@ -439,7 +477,7 @@ public class StringUtils { } public static List splitComma(String s) { - s = s.trim(); + s = trin(s); // if (s.matches("([\\p{L}0-9_.]+|[%g][^%g]+[%g])(\\s*,\\s*([\\p{L}0-9_.]+|[%g][^%g]+[%g]))*") == false) { // throw new IllegalArgumentException(); // } @@ -494,5 +532,35 @@ public class StringUtils { return s.endsWith("\\") && s.endsWith("\\\\") == false; } + public static String manageGuillemetStrict(String st) { + if (st.startsWith("<< ")) { + st = "\u00AB" + st.substring(3); + } else if (st.startsWith("<<")) { + st = "\u00AB" + st.substring(2); + } + if (st.endsWith(" >>")) { + st = st.substring(0, st.length() - 3) + "\u00BB"; + } else if (st.endsWith(">>")) { + st = st.substring(0, st.length() - 2) + "\u00BB"; + } + return st; + } + + public static String manageGuillemet(String st) { + return st.replaceAll("\\<\\<([^<>]+)\\>\\>", "\u00AB$1\u00BB"); + } + + public static String trinNoTrace(String s) { + return s.trim(); + } + + public static String trin(String s) { + final String result = s.trim(); + // if (result.equals(s) == false && s.contains("prop")) { + // System.err.println("TRIMING " + s); + // } + return result; + } + // http://docs.oracle.com/javase/tutorial/i18n/format/dateFormat.html } diff --git a/src/net/sourceforge/plantuml/UmlDiagram.java b/src/net/sourceforge/plantuml/UmlDiagram.java index 2cb000514..4950e759a 100644 --- a/src/net/sourceforge/plantuml/UmlDiagram.java +++ b/src/net/sourceforge/plantuml/UmlDiagram.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 15848 $ + * Revision $Revision: 16158 $ * */ package net.sourceforge.plantuml; @@ -55,6 +55,7 @@ import javax.script.ScriptException; import net.sourceforge.plantuml.anim.Animation; import net.sourceforge.plantuml.anim.AnimationDecoder; import net.sourceforge.plantuml.api.ImageDataSimple; +import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.core.Diagram; import net.sourceforge.plantuml.core.ImageData; import net.sourceforge.plantuml.core.UmlSource; @@ -166,6 +167,26 @@ public abstract class UmlDiagram extends AbstractPSystem implements Diagram { return footerAlignment; } + public final HorizontalAlignment getAlignmentTeoz(FontParam param) { + if (param == FontParam.FOOTER) { + return getFooterAlignment(); + } + if (param == FontParam.HEADER) { + return getHeaderAlignment(); + } + throw new IllegalArgumentException(); + } + + public final Display getFooterOrHeaderTeoz(FontParam param) { + if (param == FontParam.FOOTER) { + return getFooter(); + } + if (param == FontParam.HEADER) { + return getHeader(); + } + throw new IllegalArgumentException(); + } + public final void setFooterAlignment(HorizontalAlignment footerAlignment) { this.footerAlignment = footerAlignment; } @@ -236,7 +257,6 @@ public abstract class UmlDiagram extends AbstractPSystem implements Diagram { exportDiagramError(os, e, fileFormatOption, null, null); } return new ImageDataSimple(); - } private void exportDiagramError(OutputStream os, Throwable exception, FileFormatOption fileFormat, @@ -245,18 +265,7 @@ public abstract class UmlDiagram extends AbstractPSystem implements Diagram { final List strings = getFailureText(exception, graphvizVersion); final String flash = getFlashData(); - for (StackTraceElement ste : exception.getStackTrace()) { - strings.add(" " + ste.toString()); - } - if (exception.getCause() != null) { - final Throwable cause = exception.getCause(); - strings.add(" "); - strings.add("Caused by " + cause.toString()); - for (StackTraceElement ste : cause.getStackTrace()) { - strings.add(" " + ste.toString()); - } - - } + strings.addAll(CommandExecutionResult.getStackTrace(exception)); final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, HtmlColorUtils.WHITE, getMetadata(), null, 0, 0, null, getSkinParam().handwritten()); @@ -283,7 +292,7 @@ public abstract class UmlDiagram extends AbstractPSystem implements Diagram { } }); } - imageBuilder.writeImageTOBEMOVED(fileFormat.getFileFormat(), os); + imageBuilder.writeImageTOBEMOVED(fileFormat, os); } private String getFlashData() { @@ -320,7 +329,6 @@ public abstract class UmlDiagram extends AbstractPSystem implements Diagram { strings.add("You should send this diagram and this image to plantuml@gmail.com to solve this issue."); strings.add("You can try to turn arround this issue by simplifing your diagram."); strings.add(" "); - strings.add(exception.toString()); return strings; } diff --git a/src/net/sourceforge/plantuml/UrlBuilder.java b/src/net/sourceforge/plantuml/UrlBuilder.java index 2f5539fc6..e9f2b1a85 100644 --- a/src/net/sourceforge/plantuml/UrlBuilder.java +++ b/src/net/sourceforge/plantuml/UrlBuilder.java @@ -67,7 +67,7 @@ public class UrlBuilder { } else { throw new IllegalStateException(); } - final Matcher m = p.matcher(s.trim()); + final Matcher m = p.matcher(StringUtils.trinNoTrace(s)); if (m.matches() == false) { return null; } diff --git a/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkLongActivity.java b/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkLongActivity.java index 5fbe9d4d0..c68c15309 100644 --- a/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkLongActivity.java +++ b/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkLongActivity.java @@ -96,7 +96,7 @@ public class CommandLinkLongActivity extends CommandMultilines2 public CommandExecutionResult executeNow(final ActivityDiagram diagram, List lines) { StringUtils.trim(lines, false); - final RegexResult line0 = getStartingPattern().matcher(lines.get(0).trim()); + final RegexResult line0 = getStartingPattern().matcher(StringUtils.trin(lines.get(0))); final IEntity entity1 = CommandLinkActivity.getEntity(diagram, line0, true); diff --git a/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkLongActivity2.java b/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkLongActivity2.java index c9397efdc..13c9f50d1 100644 --- a/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkLongActivity2.java +++ b/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkLongActivity2.java @@ -107,7 +107,7 @@ public class CommandLinkLongActivity2 extends CommandMultilines2 lines) { StringUtils.trim(lines, false); - final RegexResult line0 = getStartingPattern().matcher(lines.get(0).trim()); + final RegexResult line0 = getStartingPattern().matcher(StringUtils.trin(lines.get(0))); final IEntity entity1 = CommandLinkActivity.getEntity(diagram, line0, true); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagram3.java b/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagram3.java index 2702f1da4..a47ff6391 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagram3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagram3.java @@ -187,7 +187,7 @@ public class ActivityDiagram3 extends UmlDiagram { margin, margin, getAnimation(), getSkinParam().handwritten()); imageBuilder.addUDrawable(result); - return imageBuilder.writeImageTOBEMOVED(fileFormatOption.getFileFormat(), os); + return imageBuilder.writeImageTOBEMOVED(fileFormatOption, os); } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagramFactory3.java b/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagramFactory3.java index 2abe641f0..f2a87a75b 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagramFactory3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ActivityDiagramFactory3.java @@ -53,7 +53,6 @@ import net.sourceforge.plantuml.activitydiagram3.command.CommandGoto; import net.sourceforge.plantuml.activitydiagram3.command.CommandGroup3; import net.sourceforge.plantuml.activitydiagram3.command.CommandGroupEnd3; import net.sourceforge.plantuml.activitydiagram3.command.CommandIf2; -import net.sourceforge.plantuml.activitydiagram3.command.CommandIf2Multilines; import net.sourceforge.plantuml.activitydiagram3.command.CommandIf4; import net.sourceforge.plantuml.activitydiagram3.command.CommandIfLegacy1; import net.sourceforge.plantuml.activitydiagram3.command.CommandKill3; @@ -64,6 +63,7 @@ import net.sourceforge.plantuml.activitydiagram3.command.CommandNoteLong3; import net.sourceforge.plantuml.activitydiagram3.command.CommandPartition3; import net.sourceforge.plantuml.activitydiagram3.command.CommandRepeat3; import net.sourceforge.plantuml.activitydiagram3.command.CommandRepeatWhile3; +import net.sourceforge.plantuml.activitydiagram3.command.CommandRepeatWhile3Multilines; import net.sourceforge.plantuml.activitydiagram3.command.CommandSplit3; import net.sourceforge.plantuml.activitydiagram3.command.CommandSplitAgain3; import net.sourceforge.plantuml.activitydiagram3.command.CommandSplitEnd3; @@ -75,6 +75,7 @@ import net.sourceforge.plantuml.activitydiagram3.command.CommandSwimlane2; import net.sourceforge.plantuml.activitydiagram3.command.CommandWhile3; import net.sourceforge.plantuml.activitydiagram3.command.CommandWhileEnd3; import net.sourceforge.plantuml.command.Command; +import net.sourceforge.plantuml.command.CommandDecoratorMultine; import net.sourceforge.plantuml.command.CommandFootboxIgnored; import net.sourceforge.plantuml.command.UmlDiagramFactory; @@ -98,14 +99,17 @@ public class ActivityDiagramFactory3 extends UmlDiagramFactory { cmds.add(new CommandActivity3()); cmds.add(new CommandIf4()); cmds.add(new CommandIf2()); - cmds.add(new CommandIf2Multilines()); + cmds.add(new CommandDecoratorMultine(new CommandIf2())); // UmlDiagramFactory + // cmds.add(new CommandIf2Multilines()); cmds.add(new CommandIfLegacy1()); cmds.add(new CommandElseIf2()); cmds.add(new CommandElse3()); + cmds.add(new CommandDecoratorMultine(new CommandElse3())); cmds.add(new CommandElseLegacy1()); cmds.add(new CommandEndif3()); cmds.add(new CommandRepeat3()); cmds.add(new CommandRepeatWhile3()); + cmds.add(new CommandRepeatWhile3Multilines()); cmds.add(new CommandWhile3()); cmds.add(new CommandWhileEnd3()); cmds.add(new CommandFork3()); @@ -114,8 +118,8 @@ public class ActivityDiagramFactory3 extends UmlDiagramFactory { cmds.add(new CommandSplit3()); cmds.add(new CommandSplitAgain3()); cmds.add(new CommandSplitEnd3()); -// cmds.add(new CommandGroup3()); -// cmds.add(new CommandGroupEnd3()); + // cmds.add(new CommandGroup3()); + // cmds.add(new CommandGroupEnd3()); cmds.add(new CommandStart3()); cmds.add(new CommandStop3()); cmds.add(new CommandStopLegacy1()); @@ -130,7 +134,6 @@ public class ActivityDiagramFactory3 extends UmlDiagramFactory { cmds.add(new CommandLabel()); cmds.add(new CommandGoto()); - return cmds; } diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandActivityLong3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandActivityLong3.java index ed90f1297..740359aa0 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandActivityLong3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandActivityLong3.java @@ -69,7 +69,7 @@ public class CommandActivityLong3 extends CommandMultilines2 { public CommandExecutionResult executeNow(ActivityDiagram3 diagram, List lines) { lines = StringUtils.removeEmptyColumns(lines); - final RegexResult line0 = getStartingPattern().matcher(lines.get(0).trim()); + final RegexResult line0 = getStartingPattern().matcher(StringUtils.trin(lines.get(0))); final HtmlColor color = diagram.getSkinParam().getIHtmlColorSet().getColorIfValid(line0.get("COLOR", 0)); final BoxStyle style = BoxStyle.fromChar(getLastChar(lines)); removeStarting(lines, line0.get("DATA", 0)); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandArrowLong3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandArrowLong3.java index 2a6b9fa20..d05cc1e2b 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandArrowLong3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandArrowLong3.java @@ -70,7 +70,7 @@ public class CommandArrowLong3 extends CommandMultilines2 { public CommandExecutionResult executeNow(ActivityDiagram3 diagram, List lines) { lines = StringUtils.removeEmptyColumns(lines); - final RegexResult line0 = getStartingPattern().matcher(lines.get(0).trim()); + final RegexResult line0 = getStartingPattern().matcher(StringUtils.trin(lines.get(0))); final HtmlColor color = diagram.getSkinParam().getIHtmlColorSet().getColorIfValid(line0.get("COLOR", 0)); diagram.setColorNextArrow(color); removeStarting(lines, line0.get("LABEL", 0)); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandIf2Multilines.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandIf2Multilines.java index 19545c128..0a7df20be 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandIf2Multilines.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandIf2Multilines.java @@ -71,7 +71,7 @@ public class CommandIf2Multilines extends CommandMultilines2 { @Override public CommandExecutionResult executeNow(ActivityDiagram3 diagram, List lines) { StringUtils.trim(lines, false); - final RegexResult line0 = getStartingPattern().matcher(lines.get(0).trim()); + final RegexResult line0 = getStartingPattern().matcher(StringUtils.trin(lines.get(0))); final List lineLast = StringUtils.getSplit(MyPattern.cmpile(getPatternEnd()), lines.get(lines.size() - 1)); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandNoteLong3.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandNoteLong3.java index 5f343fbf3..17b023faa 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandNoteLong3.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandNoteLong3.java @@ -57,9 +57,8 @@ public class CommandNoteLong3 extends CommandMultilines2 { } public CommandExecutionResult executeNow(final ActivityDiagram3 diagram, List lines) { - // final RegexResult line0 = getStartingPattern().matcher(lines.get(0).trim()); final List in = StringUtils.removeEmptyColumns(lines.subList(1, lines.size() - 1)); - final RegexResult line0 = getStartingPattern().matcher(lines.get(0).trim()); + final RegexResult line0 = getStartingPattern().matcher(StringUtils.trin(lines.get(0))); final NotePosition position = getPosition(line0.get("POSITION", 0)); final Display note = Display.create(in); return diagram.addNote(note, position); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/command/CommandRepeatWhile3Multilines.java b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandRepeatWhile3Multilines.java new file mode 100644 index 000000000..b27184406 --- /dev/null +++ b/src/net/sourceforge/plantuml/activitydiagram3/command/CommandRepeatWhile3Multilines.java @@ -0,0 +1,111 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2014, Arnaud Roques + * + * Project Info: http://plantuml.sourceforge.net + * + * 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. + * + * [Java is a trademark or registered trademark of Sun Microsystems, Inc. + * in the United States and other countries.] + * + * Original Author: Arnaud Roques + * + * Revision $Revision: 4762 $ + * + */ +package net.sourceforge.plantuml.activitydiagram3.command; + +import java.util.List; +import java.util.regex.Pattern; + +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.activitydiagram3.ActivityDiagram3; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.CommandMultilines3; +import net.sourceforge.plantuml.command.MultilinesStrategy; +import net.sourceforge.plantuml.command.regex.MyPattern; +import net.sourceforge.plantuml.command.regex.RegexConcat; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexResult; +import net.sourceforge.plantuml.cucadiagram.Display; +import net.sourceforge.plantuml.graphic.HtmlColor; + +public class CommandRepeatWhile3Multilines extends CommandMultilines3 { + + public CommandRepeatWhile3Multilines() { + super(getRegexConcat(), MultilinesStrategy.REMOVE_STARTING_QUOTE); + } + + @Override + public RegexConcat getPatternEnd2() { + return new RegexConcat(// + new RegexLeaf("TEST1", "([^)]*)"), new RegexLeaf("\\)"), // + new RegexLeaf(";?$")); + } + + static RegexConcat getRegexConcat() { + return new RegexConcat(// + new RegexLeaf("^"), // + new RegexLeaf("repeat[%s]?while"), // + new RegexLeaf("[%s]*"), // + new RegexLeaf("\\("), // + new RegexLeaf("TEST1", "([^)]*)$")); + } + + @Override + public CommandExecutionResult executeNow(ActivityDiagram3 diagram, List lines) { + StringUtils.trim(lines, false); + final RegexResult line0 = getStartingPattern().matcher(StringUtils.trin(lines.get(0))); + final RegexResult lineLast = getPatternEnd2().matcher(lines.get(lines.size() - 1)); + + // System.err.println("line0=" + line0); + // System.err.println("linesLast=" + lineLast); + + // + // final HtmlColor color = diagram.getSkinParam().getIHtmlColorSet().getColorIfValid(line0.get("COLOR", 0)); + + final String test = line0.get("TEST1", 0); + Display testDisplay = Display.getWithNewlines(test); + for (int i = 1; i < lines.size() - 1; i++) { + testDisplay = testDisplay.add(lines.get(i)); + } + final String trailTest = lineLast.get("TEST1", 0); + if (StringUtils.isEmpty(trailTest) == false) { + testDisplay = testDisplay.add(trailTest); + } + + Display yes = null;// Display.getWithNewlines("arg.getLazzy(\"WHEN\", 0)"); + final Display out = null; // Display.getWithNewlines("arg.getLazzy(\"OUT\", 0)"); + final HtmlColor linkColor = null; // diagram.getSkinParam().getIHtmlColorSet().getColorIfValid(arg.get("COLOR", + // 0)); + final Display linkLabel = null; // Display.getWithNewlines("arg.get(\"LABEL\", 0)"); + final List splitted = testDisplay.splitMultiline(MyPattern.cmpile("\\)[%s]*(is|equals?)[%s]*\\(", + Pattern.CASE_INSENSITIVE)); + if (splitted.size() == 2) { + testDisplay = splitted.get(0); + yes = splitted.get(1); + + } + + return diagram.repeatWhile(testDisplay, yes, out, linkLabel, linkColor); + } + +} diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/Swimlanes.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/Swimlanes.java index fc7b0cb20..41f60987e 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/Swimlanes.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/Swimlanes.java @@ -85,7 +85,6 @@ public class Swimlanes implements TextBlock { private final ISkinParam skinParam;; private final List swimlanes = new ArrayList(); - private final FontConfiguration fontConfiguration; private Swimlane currentSwimlane = null; private final Instruction root = new InstructionList(); @@ -95,10 +94,12 @@ public class Swimlanes implements TextBlock { public Swimlanes(ISkinParam skinParam) { this.skinParam = skinParam; - final UFont font = skinParam.getFont(FontParam.TITLE, null, false); - this.fontConfiguration = new FontConfiguration(font, HtmlColorUtils.BLACK, skinParam.getHyperlinkColor(), - skinParam.useUnderlineForHyperlink()); + } + private FontConfiguration getFontConfiguration() { + final UFont font = skinParam.getFont(FontParam.TITLE, null, false); + return new FontConfiguration(font, HtmlColorUtils.BLACK, skinParam.getHyperlinkColor(), + skinParam.useUnderlineForHyperlink()); } private FtileFactory getFtileFactory() { @@ -248,7 +249,7 @@ public class Swimlanes implements TextBlock { } if (OptionFlags.SWI2 == false) { - final TextBlock swTitle = TextBlockUtils.create(swimlane.getDisplay(), fontConfiguration, + final TextBlock swTitle = TextBlockUtils.create(swimlane.getDisplay(), getFontConfiguration(), HorizontalAlignment.LEFT, skinParam); final double titleWidth = swTitle.calculateDimension(stringBounder).getWidth(); final double posTitle = x2 + (swimlane.getTotalWidth() - titleWidth) / 2; @@ -281,7 +282,7 @@ public class Swimlanes implements TextBlock { final MinMax minMax = limitFinder.getMinMax(); final double drawingWidth = minMax.getWidth() + 2 * separationMargin; - final TextBlock swTitle = TextBlockUtils.create(swimlane.getDisplay(), fontConfiguration, + final TextBlock swTitle = TextBlockUtils.create(swimlane.getDisplay(), getFontConfiguration(), HorizontalAlignment.LEFT, skinParam); final double titleWidth = swTitle.calculateDimension(stringBounder).getWidth(); final double totalWidth = Math.max(drawingWidth, titleWidth + 2 * separationMargin); @@ -297,7 +298,7 @@ public class Swimlanes implements TextBlock { private UTranslate getTitleHeightTranslate(final StringBounder stringBounder) { double titlesHeight = 0; for (Swimlane swimlane : swimlanes) { - final TextBlock swTitle = TextBlockUtils.create(swimlane.getDisplay(), fontConfiguration, + final TextBlock swTitle = TextBlockUtils.create(swimlane.getDisplay(), getFontConfiguration(), HorizontalAlignment.LEFT, skinParam); titlesHeight = Math.max(titlesHeight, swTitle.calculateDimension(stringBounder).getHeight()); diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileRepeat.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileRepeat.java index b2b34d0b1..30b0224de 100644 --- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileRepeat.java +++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileRepeat.java @@ -66,8 +66,6 @@ import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlockUtils; import net.sourceforge.plantuml.svek.ConditionStyle; -import net.sourceforge.plantuml.ugraphic.UChangeBackColor; -import net.sourceforge.plantuml.ugraphic.UChangeColor; import net.sourceforge.plantuml.ugraphic.UFont; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UTranslate; @@ -106,7 +104,8 @@ class FtileRepeat extends AbstractFtile { final FontConfiguration fc = new FontConfiguration(fontTest, HtmlColorUtils.BLACK, hyperlinkColor, useUnderlineForHyperlink); - final TextBlock tbTest = TextBlockUtils.create(test, fc, HorizontalAlignment.LEFT, spriteContainer); + final TextBlock tbTest = (test == null || test.isWhite()) ? TextBlockUtils.empty(0, 0) : TextBlockUtils.create( + test, fc, HorizontalAlignment.LEFT, spriteContainer); final TextBlock yesTb = TextBlockUtils.create(yes, fc, HorizontalAlignment.LEFT, spriteContainer); final TextBlock outTb = TextBlockUtils.create(out, fc, HorizontalAlignment.LEFT, spriteContainer); @@ -137,7 +136,7 @@ class FtileRepeat extends AbstractFtile { final TextBlock tbbackLink1 = backLink1 == null ? null : TextBlockUtils.create(backLink1, fc, HorizontalAlignment.LEFT, spriteContainer, true); conns.add(result.new ConnectionBack(LinkRendering.getColor(backRepeatLinkRendering, arrowColor), tbbackLink1)); - + final Display out1 = LinkRendering.getDisplay(repeat.getOutLinkRendering()); final TextBlock tbout1 = out1 == null ? null : TextBlockUtils.create(out1, fc, HorizontalAlignment.LEFT, spriteContainer, true); diff --git a/src/net/sourceforge/plantuml/anim/AffineTransformation.java b/src/net/sourceforge/plantuml/anim/AffineTransformation.java index a5b327d3b..5e426a169 100644 --- a/src/net/sourceforge/plantuml/anim/AffineTransformation.java +++ b/src/net/sourceforge/plantuml/anim/AffineTransformation.java @@ -40,6 +40,7 @@ import java.util.StringTokenizer; import java.util.regex.Matcher; import java.util.regex.Pattern; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.ugraphic.MinMax; public class AffineTransformation { @@ -88,7 +89,7 @@ public class AffineTransformation { } private static AffineTransformation createSimple(String value) { - Matcher m = rotate.matcher(value.trim()); + Matcher m = rotate.matcher(StringUtils.trin(value)); if (m.find()) { final double angle = Double.parseDouble(m.group(1)); return new AffineTransformation(AffineTransform.getRotateInstance(angle * Math.PI / 180.0)); diff --git a/src/net/sourceforge/plantuml/classdiagram/ClassDiagram.java b/src/net/sourceforge/plantuml/classdiagram/ClassDiagram.java index 0fcfcf190..4ebb4c7f3 100644 --- a/src/net/sourceforge/plantuml/classdiagram/ClassDiagram.java +++ b/src/net/sourceforge/plantuml/classdiagram/ClassDiagram.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 15848 $ + * Revision $Revision: 16021 $ * */ package net.sourceforge.plantuml.classdiagram; @@ -213,7 +213,7 @@ public class ClassDiagram extends AbstractClassOrObjectDiagram { final ImageBuilder imageBuilder = new ImageBuilder(getSkinParam().getColorMapper(), 1, HtmlColorUtils.WHITE, null, null, 0, 10, null, getSkinParam().handwritten()); imageBuilder.addUDrawable(fullLayout); - return imageBuilder.writeImageTOBEMOVED(fileFormatOption.getFileFormat(), os); + return imageBuilder.writeImageTOBEMOVED(fileFormatOption, os); } private RowLayout getRawLayout(int raw) { diff --git a/src/net/sourceforge/plantuml/classdiagram/ClassDiagramFactory.java b/src/net/sourceforge/plantuml/classdiagram/ClassDiagramFactory.java index 7f0d180a0..50ebf29f4 100644 --- a/src/net/sourceforge/plantuml/classdiagram/ClassDiagramFactory.java +++ b/src/net/sourceforge/plantuml/classdiagram/ClassDiagramFactory.java @@ -66,6 +66,7 @@ import net.sourceforge.plantuml.command.UmlDiagramFactory; import net.sourceforge.plantuml.command.note.FactoryNoteCommand; import net.sourceforge.plantuml.command.note.FactoryNoteOnEntityCommand; import net.sourceforge.plantuml.command.note.FactoryNoteOnLinkCommand; +import net.sourceforge.plantuml.command.note.FactoryTipOnEntityCommand; import net.sourceforge.plantuml.command.regex.RegexLeaf; import net.sourceforge.plantuml.cucadiagram.Link; @@ -107,6 +108,11 @@ public class ClassDiagramFactory extends UmlDiagramFactory { cmds.add(new CommandLinkLollipop(UmlDiagramType.CLASS)); cmds.add(new CommandImport()); + + final FactoryTipOnEntityCommand factoryTipOnEntityCommand = new FactoryTipOnEntityCommand(new RegexLeaf( + "ENTITY", "(" + CommandCreateClass.CODE_NO_DOTDOT + "|[%g][^%g]+[%g])::([^%s]+)")); + cmds.add(factoryTipOnEntityCommand.createMultiLine()); + final FactoryNoteOnEntityCommand factoryNoteOnEntityCommand = new FactoryNoteOnEntityCommand(new RegexLeaf( "ENTITY", "(" + CommandCreateClass.CODE + "|[%g][^%g]+[%g])")); cmds.add(factoryNoteOnEntityCommand.createSingleLine()); @@ -114,6 +120,7 @@ public class ClassDiagramFactory extends UmlDiagramFactory { cmds.add(factoryNoteOnEntityCommand.createMultiLine()); cmds.add(factoryNoteCommand.createMultiLine()); + cmds.add(new CommandCreateClassMultilines()); final FactoryNoteOnLinkCommand factoryNoteOnLinkCommand = new FactoryNoteOnLinkCommand(); diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClass.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClass.java index 3d0a84ab8..f3294c390 100644 --- a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClass.java +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClass.java @@ -57,6 +57,7 @@ import net.sourceforge.plantuml.graphic.HtmlColorUtils; public class CommandCreateClass extends SingleLineCommand2 { public static final String CODE = "[^%s{}%g<>]+"; + public static final String CODE_NO_DOTDOT = "[^%s{}%g<>:]+"; enum Mode { EXTENDS, IMPLEMENTS diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClassMultilines.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClassMultilines.java index 7f431bbce..6d3ee957a 100644 --- a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClassMultilines.java +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateClassMultilines.java @@ -110,8 +110,8 @@ public class CommandCreateClassMultilines extends CommandMultilines2 lines) { - StringUtils.trim(lines, false); - final RegexResult line0 = getStartingPattern().matcher(lines.get(0).trim()); + StringUtils.trimSmart(lines, 1); + final RegexResult line0 = getStartingPattern().matcher(StringUtils.trin(lines.get(0))); final IEntity entity = executeArg0(diagram, line0); if (entity == null) { return CommandExecutionResult.error("No such entity"); @@ -155,7 +155,7 @@ public class CommandCreateClassMultilines extends CommandMultilines2 final String symbol; if (codeRaw.startsWith("()")) { symbol = "interface"; - codeRaw = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(codeRaw.substring(2).trim()); + codeRaw = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(StringUtils.trin(codeRaw.substring(2))); } else if (codeChar == '(' || codeDisplay == '(') { symbol = "usecase"; } else if (codeChar == ':' || codeDisplay == ':') { diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandLinkClass.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandLinkClass.java index 6c366b67c..d8ccfda38 100644 --- a/src/net/sourceforge/plantuml/classdiagram/command/CommandLinkClass.java +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandLinkClass.java @@ -39,6 +39,7 @@ import java.util.regex.Pattern; import net.sourceforge.plantuml.Direction; import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.UmlDiagramType; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand2; @@ -58,7 +59,6 @@ import net.sourceforge.plantuml.cucadiagram.LinkDecor; import net.sourceforge.plantuml.cucadiagram.LinkType; import net.sourceforge.plantuml.cucadiagram.Stereotype; import net.sourceforge.plantuml.objectdiagram.AbstractClassOrObjectDiagram; -import net.sourceforge.plantuml.StringUtils; final public class CommandLinkClass extends SingleLineCommand2 { @@ -190,24 +190,24 @@ final public class CommandLinkClass extends SingleLineCommand2 ")) { linkArrow = LinkArrow.DIRECT_NORMAL; - labelLink = labelLink.substring(2).trim(); + labelLink = StringUtils.trin(labelLink.substring(2)); } else if (labelLink != null && labelLink.endsWith(" >")) { linkArrow = LinkArrow.DIRECT_NORMAL; - labelLink = labelLink.substring(0, labelLink.length() - 2).trim(); + labelLink = StringUtils.trin(labelLink.substring(0, labelLink.length() - 2)); } else if (labelLink != null && labelLink.endsWith(" <")) { linkArrow = LinkArrow.BACKWARD; - labelLink = labelLink.substring(0, labelLink.length() - 2).trim(); + labelLink = StringUtils.trin(labelLink.substring(0, labelLink.length() - 2)); } Link link = new Link(cl1, cl2, linkType, Display.getWithNewlines(labelLink), queue, firstLabel, secondLabel, @@ -295,6 +295,7 @@ final public class CommandLinkClass extends SingleLineCommand2".equals(s)) { return LinkDecor.EXTENDS; } diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandLinkLollipop.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandLinkLollipop.java index 661b13af8..9b857e193 100644 --- a/src/net/sourceforge/plantuml/classdiagram/command/CommandLinkLollipop.java +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandLinkLollipop.java @@ -104,11 +104,13 @@ final public class CommandLinkLollipop extends SingleLineCommand2 { public CommandExecutionResult executeNow(ClassDiagram system, List lines) { StringUtils.trim(lines, false); - final RegexResult line0 = getStartingPattern().matcher(lines.get(0).trim()); + final RegexResult line0 = getStartingPattern().matcher(StringUtils.trin(lines.get(0))); Code code = Code.of(line0.get("NAME1", 0)); if (code == null) { code = Code.of(line0.get("NAME3", 0)); diff --git a/src/net/sourceforge/plantuml/classdiagram/command/JavaClass.java b/src/net/sourceforge/plantuml/classdiagram/command/JavaClass.java index f9dec0194..de5acbee0 100644 --- a/src/net/sourceforge/plantuml/classdiagram/command/JavaClass.java +++ b/src/net/sourceforge/plantuml/classdiagram/command/JavaClass.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 12235 $ + * Revision $Revision: 16197 $ * */ package net.sourceforge.plantuml.classdiagram.command; @@ -38,6 +38,7 @@ import java.util.Collections; import java.util.List; import java.util.StringTokenizer; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.cucadiagram.LeafType; class JavaClass { @@ -54,9 +55,9 @@ class JavaClass { if (p == null) { p = ""; } - final StringTokenizer st = new StringTokenizer(p.trim(), ","); + final StringTokenizer st = new StringTokenizer(StringUtils.trin(p), ","); while (st.hasMoreTokens()) { - this.parents.add(st.nextToken().trim().replaceAll("\\<.*", "")); + this.parents.add(StringUtils.trin(st.nextToken()).replaceAll("\\<.*", "")); } this.type = type; this.parentType = parentType; diff --git a/src/net/sourceforge/plantuml/classdiagram/command/JavaFile.java b/src/net/sourceforge/plantuml/classdiagram/command/JavaFile.java index 3164c7362..05865a1b2 100644 --- a/src/net/sourceforge/plantuml/classdiagram/command/JavaFile.java +++ b/src/net/sourceforge/plantuml/classdiagram/command/JavaFile.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 14726 $ + * Revision $Revision: 16194 $ * */ package net.sourceforge.plantuml.classdiagram.command; @@ -72,7 +72,7 @@ class JavaFile { String javaPackage = null; String s; while ((s = br.readLine()) != null) { - s = s.trim(); + s = StringUtils.trin(s); final Matcher matchPackage = packageDefinition.matcher(s); if (matchPackage.find()) { javaPackage = matchPackage.group(1); diff --git a/src/net/sourceforge/plantuml/code/ArobaseStringCompressor.java b/src/net/sourceforge/plantuml/code/ArobaseStringCompressor.java index 97d08e5c2..6c3f8aa30 100644 --- a/src/net/sourceforge/plantuml/code/ArobaseStringCompressor.java +++ b/src/net/sourceforge/plantuml/code/ArobaseStringCompressor.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 12235 $ + * Revision $Revision: 16194 $ * */ package net.sourceforge.plantuml.code; @@ -38,6 +38,7 @@ import java.io.StringReader; import java.util.regex.Matcher; import java.util.regex.Pattern; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.preproc.ReadLine; import net.sourceforge.plantuml.preproc.ReadLineReader; @@ -98,11 +99,11 @@ public class ArobaseStringCompressor implements StringCompressor { } private String clean(String s) { - s = s.trim(); + s = StringUtils.trin(s); s = clean1(s); s = s.replaceAll("@enduml[^\\n\\r]*", ""); s = s.replaceAll("@startuml[^\\n\\r]*", ""); - s = s.trim(); + s = StringUtils.trin(s); return s; } diff --git a/src/net/sourceforge/plantuml/command/CommandDecoratorMultine.java b/src/net/sourceforge/plantuml/command/CommandDecoratorMultine.java new file mode 100644 index 000000000..ba1258cfb --- /dev/null +++ b/src/net/sourceforge/plantuml/command/CommandDecoratorMultine.java @@ -0,0 +1,86 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2014, Arnaud Roques + * + * Project Info: http://plantuml.sourceforge.net + * + * 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. + * + * [Java is a trademark or registered trademark of Sun Microsystems, Inc. + * in the United States and other countries.] + * + * Original Author: Arnaud Roques + * + * Revision $Revision: 12235 $ + * + */ +package net.sourceforge.plantuml.command; + +import java.util.Collections; +import java.util.List; + +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.core.Diagram; + +public class CommandDecoratorMultine implements Command { + + private final SingleLineCommand2 cmd; + + public CommandDecoratorMultine(SingleLineCommand2 cmd) { + this.cmd = cmd; + } + + public CommandExecutionResult execute(D diagram, List lines) { + final String concat = concat(lines); + return cmd.execute(diagram, Collections.singletonList(concat)); + } + + public CommandControl isValid(List lines) { + if (cmd.isCommandForbidden()) { + return CommandControl.NOT_OK; + } + final String concat = concat(lines); + if (cmd.isForbidden(concat)) { + return CommandControl.NOT_OK; + } + final CommandControl tmp = cmd.isValid(Collections.singletonList(concat)); + if (tmp == CommandControl.OK_PARTIAL) { + throw new IllegalStateException(); + } + if (tmp == CommandControl.OK) { + return tmp; + } + return CommandControl.OK_PARTIAL; + } + + private String concat(List lines) { + final StringBuilder sb = new StringBuilder(); + for (String line : lines) { + sb.append(line); + sb.append(StringUtils.hiddenNewLine()); + } + return sb.substring(0, sb.length() - 1); + } + + public String[] getDescription() { + return cmd.getDescription(); + } + +} diff --git a/src/net/sourceforge/plantuml/command/CommandExecutionResult.java b/src/net/sourceforge/plantuml/command/CommandExecutionResult.java index db472549c..dc851bfca 100644 --- a/src/net/sourceforge/plantuml/command/CommandExecutionResult.java +++ b/src/net/sourceforge/plantuml/command/CommandExecutionResult.java @@ -33,20 +33,25 @@ */ package net.sourceforge.plantuml.command; +import java.util.ArrayList; +import java.util.List; + import net.sourceforge.plantuml.AbstractPSystem; public class CommandExecutionResult { private final String error; private final AbstractPSystem newDiagram; + private final List debugLines; - private CommandExecutionResult(String error, AbstractPSystem newDiagram) { + private CommandExecutionResult(String error, AbstractPSystem newDiagram, List debugLines) { this.error = error; this.newDiagram = newDiagram; + this.debugLines = debugLines; } public CommandExecutionResult withDiagram(AbstractPSystem newDiagram) { - return new CommandExecutionResult(error, newDiagram); + return new CommandExecutionResult(error, newDiagram, null); } @Override @@ -55,15 +60,37 @@ public class CommandExecutionResult { } public static CommandExecutionResult newDiagram(AbstractPSystem result) { - return new CommandExecutionResult(null, result); + return new CommandExecutionResult(null, result, null); } public static CommandExecutionResult ok() { - return new CommandExecutionResult(null, null); + return new CommandExecutionResult(null, null, null); } public static CommandExecutionResult error(String error) { - return new CommandExecutionResult(error, null); + return new CommandExecutionResult(error, null, null); + } + + public static CommandExecutionResult error(String error, Throwable t) { + return new CommandExecutionResult(error, null, getStackTrace(t)); + } + + public static List getStackTrace(Throwable exception) { + final List result = new ArrayList(); + result.add(exception.toString()); + for (StackTraceElement ste : exception.getStackTrace()) { + result.add(" " + ste.toString()); + } + if (exception.getCause() != null) { + final Throwable cause = exception.getCause(); + result.add(" "); + result.add("Caused by " + cause.toString()); + for (StackTraceElement ste : cause.getStackTrace()) { + result.add(" " + ste.toString()); + } + + } + return result; } public boolean isOk() { @@ -81,4 +108,8 @@ public class CommandExecutionResult { return newDiagram; } + public List getDebugLines() { + return debugLines; + } + } diff --git a/src/net/sourceforge/plantuml/command/CommandMultilines.java b/src/net/sourceforge/plantuml/command/CommandMultilines.java index b66aca6a3..c0da9365c 100644 --- a/src/net/sourceforge/plantuml/command/CommandMultilines.java +++ b/src/net/sourceforge/plantuml/command/CommandMultilines.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 12235 $ + * Revision $Revision: 16196 $ * */ package net.sourceforge.plantuml.command; @@ -37,6 +37,7 @@ import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.core.Diagram; @@ -61,7 +62,7 @@ public abstract class CommandMultilines implements Command if (isCommandForbidden()) { return CommandControl.NOT_OK; } - Matcher m1 = starting.matcher(lines.get(0).trim()); + Matcher m1 = starting.matcher(StringUtils.trin(lines.get(0))); if (m1.matches() == false) { return CommandControl.NOT_OK; } @@ -69,7 +70,7 @@ public abstract class CommandMultilines implements Command return CommandControl.OK_PARTIAL; } - m1 = MyPattern.cmpile(getPatternEnd()).matcher(lines.get(lines.size() - 1).trim()); + m1 = MyPattern.cmpile(getPatternEnd()).matcher(StringUtils.trin(lines.get(lines.size() - 1))); if (m1.matches() == false) { return CommandControl.OK_PARTIAL; } diff --git a/src/net/sourceforge/plantuml/command/CommandMultilines2.java b/src/net/sourceforge/plantuml/command/CommandMultilines2.java index 25ac2bc6f..9b6a17fe6 100644 --- a/src/net/sourceforge/plantuml/command/CommandMultilines2.java +++ b/src/net/sourceforge/plantuml/command/CommandMultilines2.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.command; import java.util.List; import java.util.regex.Matcher; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.command.regex.RegexConcat; import net.sourceforge.plantuml.core.Diagram; @@ -65,7 +66,7 @@ public abstract class CommandMultilines2 implements Command implements Command implements Command { + + private final RegexConcat starting; + + private final MultilinesStrategy strategy; + + public CommandMultilines3(RegexConcat patternStart, MultilinesStrategy strategy) { + if (patternStart.getPattern().startsWith("^") == false || patternStart.getPattern().endsWith("$") == false) { + throw new IllegalArgumentException("Bad pattern " + patternStart.getPattern()); + } + this.strategy = strategy; + this.starting = patternStart; + } + + public abstract RegexConcat getPatternEnd2(); + + public String[] getDescription() { + return new String[] { "START: " + starting.getPattern(), "END: " + getPatternEnd2().getPattern() }; + } + + final public CommandControl isValid(List lines) { + lines = strategy.filter(lines); + if (isCommandForbidden()) { + return CommandControl.NOT_OK; + } + final boolean result1 = starting.match(StringUtils.trin(lines.get(0))); + if (result1 == false) { + return CommandControl.NOT_OK; + } + if (lines.size() == 1) { + return CommandControl.OK_PARTIAL; + } + + final String potentialLast = StringUtils.trinNoTrace(lines.get(lines.size() - 1)); + final boolean m1 = getPatternEnd2().match(potentialLast); + if (m1 == false) { + return CommandControl.OK_PARTIAL; + } + + actionIfCommandValid(); + return CommandControl.OK; + } + + public final CommandExecutionResult execute(S system, List lines) { + return executeNow(system, strategy.filter(lines)); + } + + public abstract CommandExecutionResult executeNow(S system, List lines); + + protected boolean isCommandForbidden() { + return false; + } + + protected void actionIfCommandValid() { + } + + protected final RegexConcat getStartingPattern() { + return starting; + } + +} diff --git a/src/net/sourceforge/plantuml/command/CommandMultilinesBracket.java b/src/net/sourceforge/plantuml/command/CommandMultilinesBracket.java index 4a62d72f3..8770af9fb 100644 --- a/src/net/sourceforge/plantuml/command/CommandMultilinesBracket.java +++ b/src/net/sourceforge/plantuml/command/CommandMultilinesBracket.java @@ -37,6 +37,7 @@ import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.core.Diagram; @@ -70,7 +71,7 @@ public abstract class CommandMultilinesBracket implements Com if (isCommandForbidden()) { return CommandControl.NOT_OK; } - final Matcher m1 = starting.matcher(lines.get(0).trim()); + final Matcher m1 = starting.matcher(StringUtils.trin(lines.get(0))); if (m1.matches() == false) { return CommandControl.NOT_OK; } @@ -80,7 +81,7 @@ public abstract class CommandMultilinesBracket implements Com int level = 1; for (int i = 1; i < lines.size(); i++) { - final String s = lines.get(i).trim(); + final String s = StringUtils.trin(lines.get(i)); if (isLineConsistent(s, level) == false) { return CommandControl.NOT_OK; } diff --git a/src/net/sourceforge/plantuml/command/CommandMultilinesFooter.java b/src/net/sourceforge/plantuml/command/CommandMultilinesFooter.java index 249991241..8c15b7634 100644 --- a/src/net/sourceforge/plantuml/command/CommandMultilinesFooter.java +++ b/src/net/sourceforge/plantuml/command/CommandMultilinesFooter.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 14726 $ + * Revision $Revision: 16195 $ * */ package net.sourceforge.plantuml.command; @@ -54,7 +54,7 @@ public class CommandMultilinesFooter extends CommandMultilines { public CommandExecutionResult execute(final UmlDiagram diagram, List lines) { StringUtils.trim(lines, false); - final Matcher m = getStartingPattern().matcher(lines.get(0).trim()); + final Matcher m = getStartingPattern().matcher(StringUtils.trin(lines.get(0))); if (m.find() == false) { throw new IllegalStateException(); } diff --git a/src/net/sourceforge/plantuml/command/CommandMultilinesHeader.java b/src/net/sourceforge/plantuml/command/CommandMultilinesHeader.java index 6fe698a83..2104384d0 100644 --- a/src/net/sourceforge/plantuml/command/CommandMultilinesHeader.java +++ b/src/net/sourceforge/plantuml/command/CommandMultilinesHeader.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 14726 $ + * Revision $Revision: 16195 $ * */ package net.sourceforge.plantuml.command; @@ -55,7 +55,7 @@ public class CommandMultilinesHeader extends CommandMultilines { public CommandExecutionResult execute(final UmlDiagram diagram, List lines) { StringUtils.trim(lines, false); - final Matcher m = getStartingPattern().matcher(lines.get(0).trim()); + final Matcher m = getStartingPattern().matcher(StringUtils.trin(lines.get(0))); if (m.find() == false) { throw new IllegalStateException(); } diff --git a/src/net/sourceforge/plantuml/command/CommandMultilinesLegend.java b/src/net/sourceforge/plantuml/command/CommandMultilinesLegend.java index 4d50e493b..05a4af902 100644 --- a/src/net/sourceforge/plantuml/command/CommandMultilinesLegend.java +++ b/src/net/sourceforge/plantuml/command/CommandMultilinesLegend.java @@ -65,8 +65,8 @@ public class CommandMultilinesLegend extends CommandMultilines2 { @Override public CommandExecutionResult executeNow(UmlDiagram diagram, List lines) { - StringUtils.trim(lines, false); - final RegexResult line0 = getStartingPattern().matcher(lines.get(0).trim()); + StringUtils.trimSmart(lines, 1); + final RegexResult line0 = getStartingPattern().matcher(StringUtils.trin(lines.get(0))); final String align = line0.get("ALIGN", 0); final String valign = line0.get("VALIGN", 0); final Display strings = Display.create(lines.subList(1, lines.size() - 1)).removeEmptyColumns(); diff --git a/src/net/sourceforge/plantuml/command/CommandSkinParamMultilines.java b/src/net/sourceforge/plantuml/command/CommandSkinParamMultilines.java index 0702f3d2a..a9b0276c8 100644 --- a/src/net/sourceforge/plantuml/command/CommandSkinParamMultilines.java +++ b/src/net/sourceforge/plantuml/command/CommandSkinParamMultilines.java @@ -72,13 +72,13 @@ public class CommandSkinParamMultilines extends CommandMultilinesBracket lines) { final Context context = new Context(); - final Matcher mStart = getStartingPattern().matcher(lines.get(0).trim()); + final Matcher mStart = getStartingPattern().matcher(StringUtils.trin(lines.get(0))); if (mStart.find() == false) { throw new IllegalStateException(); } diff --git a/src/net/sourceforge/plantuml/command/FactorySpriteCommand.java b/src/net/sourceforge/plantuml/command/FactorySpriteCommand.java index 9d4ff1d1a..4a53eb64d 100644 --- a/src/net/sourceforge/plantuml/command/FactorySpriteCommand.java +++ b/src/net/sourceforge/plantuml/command/FactorySpriteCommand.java @@ -88,7 +88,7 @@ public final class FactorySpriteCommand implements SingleMultiFactoryCommand lines) { StringUtils.trim(lines, true); - final RegexResult line0 = getStartingPattern().matcher(lines.get(0).trim()); + final RegexResult line0 = getStartingPattern().matcher(StringUtils.trin(lines.get(0))); final List strings = StringUtils.removeEmptyColumns(lines.subList(1, lines.size() - 1)); if (strings.size() == 0) { @@ -130,7 +130,7 @@ public final class FactorySpriteCommand implements SingleMultiFactoryCommand strings) { final StringBuilder sb = new StringBuilder(); for (String s : strings) { - sb.append(s.trim()); + sb.append(StringUtils.trin(s)); } return sb.toString(); } diff --git a/src/net/sourceforge/plantuml/command/MultilinesStrategy.java b/src/net/sourceforge/plantuml/command/MultilinesStrategy.java index 2c0689c1d..87aca0d00 100644 --- a/src/net/sourceforge/plantuml/command/MultilinesStrategy.java +++ b/src/net/sourceforge/plantuml/command/MultilinesStrategy.java @@ -36,6 +36,8 @@ package net.sourceforge.plantuml.command; import java.util.Iterator; import java.util.List; +import net.sourceforge.plantuml.StringUtils; + public enum MultilinesStrategy { REMOVE_STARTING_QUOTE, KEEP_STARTING_QUOTE; @@ -56,6 +58,6 @@ public enum MultilinesStrategy { } private boolean hasStartingQuote(String s) { - return s.trim().startsWith("\'"); + return StringUtils.trinNoTrace(s).startsWith("\'"); } } diff --git a/src/net/sourceforge/plantuml/command/PSystemAbstractFactory.java b/src/net/sourceforge/plantuml/command/PSystemAbstractFactory.java index eac19472d..9c40f587a 100644 --- a/src/net/sourceforge/plantuml/command/PSystemAbstractFactory.java +++ b/src/net/sourceforge/plantuml/command/PSystemAbstractFactory.java @@ -51,13 +51,13 @@ public abstract class PSystemAbstractFactory implements PSystemFactory { final protected AbstractPSystem buildEmptyError(UmlSource source) { final PSystemError result = new PSystemError(source, new ErrorUml(ErrorUmlType.SYNTAX_ERROR, - "Empty description", 1)); + "Empty description", 1), null); result.setSource(source); return result; } final protected PSystemError buildEmptyError(UmlSource source, String err) { - final PSystemError result = new PSystemError(source, new ErrorUml(ErrorUmlType.EXECUTION_ERROR, err, 1)); + final PSystemError result = new PSystemError(source, new ErrorUml(ErrorUmlType.EXECUTION_ERROR, err, 1), null); result.setSource(source); return result; } diff --git a/src/net/sourceforge/plantuml/command/PSystemBasicFactory.java b/src/net/sourceforge/plantuml/command/PSystemBasicFactory.java index 962dd26d9..6b876a90f 100644 --- a/src/net/sourceforge/plantuml/command/PSystemBasicFactory.java +++ b/src/net/sourceforge/plantuml/command/PSystemBasicFactory.java @@ -78,7 +78,7 @@ public abstract class PSystemBasicFactory

extends PSy system = executeLine(system, s); if (system == null) { return new PSystemError(source, new ErrorUml(ErrorUmlType.SYNTAX_ERROR, "Syntax Error?", - it.currentNum() - 1)); + it.currentNum() - 1), null); } } if (system != null) { diff --git a/src/net/sourceforge/plantuml/command/PSystemSingleLineFactory.java b/src/net/sourceforge/plantuml/command/PSystemSingleLineFactory.java index 58446da63..6307b1c16 100644 --- a/src/net/sourceforge/plantuml/command/PSystemSingleLineFactory.java +++ b/src/net/sourceforge/plantuml/command/PSystemSingleLineFactory.java @@ -73,7 +73,7 @@ public abstract class PSystemSingleLineFactory extends PSystemAbstractFactory { final AbstractPSystem sys = executeLine(s); if (sys == null) { return new PSystemError(source, new ErrorUml(ErrorUmlType.SYNTAX_ERROR, "Syntax Error?", - it.currentNum() - 1)); + it.currentNum() - 1), null); } sys.setSource(source); return sys; diff --git a/src/net/sourceforge/plantuml/command/ProtectedCommand.java b/src/net/sourceforge/plantuml/command/ProtectedCommand.java index ec4d3c8c5..e40f88934 100644 --- a/src/net/sourceforge/plantuml/command/ProtectedCommand.java +++ b/src/net/sourceforge/plantuml/command/ProtectedCommand.java @@ -33,8 +33,6 @@ */ package net.sourceforge.plantuml.command; -import java.io.ByteArrayOutputStream; -import java.io.PrintWriter; import java.util.List; import net.sourceforge.plantuml.Log; @@ -52,22 +50,18 @@ public class ProtectedCommand implements Command { public CommandExecutionResult execute(S system, List lines) { try { final CommandExecutionResult result = cmd.execute(system, lines); -// if (result.isOk()) { -// // TRACECOMMAND -// System.err.println("CMD = " + cmd.getClass()); -// } + // if (result.isOk()) { + // // TRACECOMMAND + // System.err.println("CMD = " + cmd.getClass()); + // } return result; } catch (Throwable t) { - t.printStackTrace(); - final ByteArrayOutputStream baos = new ByteArrayOutputStream(); - final PrintWriter pw = new PrintWriter(baos); - t.printStackTrace(pw); Log.error("Error " + t); String msg = "You should send a mail to plantuml@gmail.com with this log (V" + Version.versionString() + ")"; Log.error(msg); - msg += " " + new String(baos.toByteArray()); - return CommandExecutionResult.error(msg); + msg += " " + t.toString(); + return CommandExecutionResult.error(msg, t); } } diff --git a/src/net/sourceforge/plantuml/command/SingleLineCommand.java b/src/net/sourceforge/plantuml/command/SingleLineCommand.java index 22eada7bc..abf6f1a91 100644 --- a/src/net/sourceforge/plantuml/command/SingleLineCommand.java +++ b/src/net/sourceforge/plantuml/command/SingleLineCommand.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 14321 $ + * Revision $Revision: 16195 $ * */ package net.sourceforge.plantuml.command; @@ -67,7 +67,7 @@ public abstract class SingleLineCommand implements Command if (isCommandForbidden()) { return CommandControl.NOT_OK; } - final String line = lines.get(0).trim(); + final String line = StringUtils.trin(lines.get(0)); final Matcher m = pattern.matcher(line); final boolean result = m.find(); if (result) { @@ -87,7 +87,7 @@ public abstract class SingleLineCommand implements Command if (lines.size() != 1) { throw new IllegalArgumentException(); } - final String line = lines.get(0).trim(); + final String line = StringUtils.trin(lines.get(0)); if (isForbidden(line)) { return CommandExecutionResult.error("Forbidden line " + line); } diff --git a/src/net/sourceforge/plantuml/command/SingleLineCommand2.java b/src/net/sourceforge/plantuml/command/SingleLineCommand2.java index 2bc47d696..a503e4360 100644 --- a/src/net/sourceforge/plantuml/command/SingleLineCommand2.java +++ b/src/net/sourceforge/plantuml/command/SingleLineCommand2.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.command; import java.util.List; import net.sourceforge.plantuml.PSystemError; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.command.regex.RegexConcat; import net.sourceforge.plantuml.command.regex.RegexResult; import net.sourceforge.plantuml.core.Diagram; @@ -66,7 +67,7 @@ public abstract class SingleLineCommand2 implements Command implements Command lines = new ArrayList(); - addOneSingleLineManageEmbedded(lines, init, it); - while (it.hasNext()) { - final String s = it.next(); - if (StartUtils.isArobaseEndDiagram(s)) { - return false; + public CommandControl isValid2(final IteratorCounter it) { + final List asList = Arrays.asList(it.peek()); + for (Command cmd : cmds) { + final CommandControl result = cmd.isValid(asList); + if (result == CommandControl.OK) { + return result; } - addOneSingleLineManageEmbedded(lines, s, it); - final CommandControl commandControl = isValid(lines); - if (commandControl == CommandControl.NOT_OK) { - // throw new IllegalStateException(); - return false; + if (result == CommandControl.OK_PARTIAL && isMultilineCommandOk(it.cloneMe(), cmd) != null) { + return result; } - if (commandControl == CommandControl.OK) { - final Command cmd = createCommand(lines); - final CommandExecutionResult result = system.executeCommand(cmd, lines); - return result.isOk(); + } + return CommandControl.NOT_OK; + } + + public CommandControl goForwardMultiline(final IteratorCounter it) { + final List asList = Arrays.asList(it.peek()); + for (Command cmd : cmds) { + final CommandControl result = cmd.isValid(asList); + if (result == CommandControl.OK) { + throw new IllegalStateException(); + } + if (result == CommandControl.OK_PARTIAL && isMultilineCommandOk(it, cmd) != null) { + return result; + } + } + throw new IllegalStateException(); + } + + private boolean manageMultiline(IteratorCounter it, AbstractPSystem system) { + for (Command cmd : cmds) { + if (isMultilineCommandOk(it.cloneMe(), cmd) != null) { + final List lines = isMultilineCommandOk(it, cmd); + return cmd.execute(system, lines).isOk(); } } return false; - } - private void addOneSingleLineManageEmbedded(final List lines, final String linetoBeAdded, IteratorCounter it) { + private List isMultilineCommandOk(IteratorCounter it, Command cmd) { + final List lines = new ArrayList(); + while (it.hasNext()) { + addOneSingleLineManageEmbedded(it, lines); + final CommandControl result = cmd.isValid(lines); + if (result == CommandControl.NOT_OK) { + return null; + } + if (result == CommandControl.OK) { + return lines; + } + } + return null; + } + + private void addOneSingleLineManageEmbedded(IteratorCounter it, final List lines) { + final String linetoBeAdded = it.next(); lines.add(linetoBeAdded); - if (linetoBeAdded.trim().equals("{{")) { + if (StringUtils.trinNoTrace(linetoBeAdded).equals("{{")) { while (it.hasNext()) { final String s = it.next(); lines.add(s); - if (s.trim().equals("}}")) { + if (StringUtils.trinNoTrace(s).equals("}}")) { return; } } @@ -187,11 +217,15 @@ public abstract class UmlDiagramFactory extends PSystemAbstractFactory { public String checkFinalError(AbstractPSystem system) { return null; } + final public CommandControl isValid(List lines) { for (Command cmd : cmds) { final CommandControl result = cmd.isValid(lines); - if (result == CommandControl.OK || result == CommandControl.OK_PARTIAL) { + if (result == CommandControl.OK) { + return result; + } + if (result == CommandControl.OK_PARTIAL) { return result; } } @@ -199,13 +233,11 @@ public abstract class UmlDiagramFactory extends PSystemAbstractFactory { } - final public Command createCommand(List lines) { + private Command getFirstCommandOkForLines(List lines) { for (Command cmd : cmds) { final CommandControl result = cmd.isValid(lines); if (result == CommandControl.OK) { return cmd; - } else if (result == CommandControl.OK_PARTIAL) { - throw new IllegalArgumentException(); } } throw new IllegalArgumentException(); @@ -244,11 +276,10 @@ public abstract class UmlDiagramFactory extends PSystemAbstractFactory { cmds.add(factorySpriteCommand.createMultiLine()); cmds.add(factorySpriteCommand.createSingleLine()); cmds.add(new CommandSpriteFile()); - + cmds.add(new CommandHideShow3()); cmds.add(new CommandHideShow()); - } final public List getDescription() { diff --git a/src/net/sourceforge/plantuml/command/note/FactoryNoteActivityCommand.java b/src/net/sourceforge/plantuml/command/note/FactoryNoteActivityCommand.java index f49a3e23c..0ca7a2933 100644 --- a/src/net/sourceforge/plantuml/command/note/FactoryNoteActivityCommand.java +++ b/src/net/sourceforge/plantuml/command/note/FactoryNoteActivityCommand.java @@ -88,7 +88,7 @@ public final class FactoryNoteActivityCommand implements SingleMultiFactoryComma public final CommandExecutionResult executeNow(final ActivityDiagram system, List lines) { // StringUtils.trim(lines, true); - final RegexResult arg = getStartingPattern().matcher(lines.get(0).trim()); + final RegexResult arg = getStartingPattern().matcher(StringUtils.trin(lines.get(0))); Display strings = Display.create(StringUtils.removeEmptyColumns(lines.subList(1, lines.size() - 1))); Url url = null; diff --git a/src/net/sourceforge/plantuml/command/note/FactoryNoteCommand.java b/src/net/sourceforge/plantuml/command/note/FactoryNoteCommand.java index eb15da6b0..c14c7caac 100644 --- a/src/net/sourceforge/plantuml/command/note/FactoryNoteCommand.java +++ b/src/net/sourceforge/plantuml/command/note/FactoryNoteCommand.java @@ -96,7 +96,7 @@ public final class FactoryNoteCommand implements SingleMultiFactoryCommand lines) { // StringUtils.trim(lines, false); - final RegexResult line0 = getStartingPattern().matcher(lines.get(0).trim()); + final RegexResult line0 = getStartingPattern().matcher(StringUtils.trin(lines.get(0))); final List strings = StringUtils.removeEmptyColumns(lines.subList(1, lines.size() - 1)); diff --git a/src/net/sourceforge/plantuml/command/note/FactoryNoteOnEntityCommand.java b/src/net/sourceforge/plantuml/command/note/FactoryNoteOnEntityCommand.java index 9b88b9bd7..9f842189c 100644 --- a/src/net/sourceforge/plantuml/command/note/FactoryNoteOnEntityCommand.java +++ b/src/net/sourceforge/plantuml/command/note/FactoryNoteOnEntityCommand.java @@ -118,7 +118,7 @@ public final class FactoryNoteOnEntityCommand implements SingleMultiFactoryComma public CommandExecutionResult executeNow(final AbstractEntityDiagram system, List lines) { // StringUtils.trim(lines, false); - final RegexResult line0 = getStartingPattern().matcher(lines.get(0).trim()); + final RegexResult line0 = getStartingPattern().matcher(StringUtils.trin(lines.get(0))); List strings = StringUtils.removeEmptyColumns(lines.subList(1, lines.size() - 1)); Url url = null; diff --git a/src/net/sourceforge/plantuml/command/note/FactoryTipOnEntityCommand.java b/src/net/sourceforge/plantuml/command/note/FactoryTipOnEntityCommand.java new file mode 100644 index 000000000..c58cef1e6 --- /dev/null +++ b/src/net/sourceforge/plantuml/command/note/FactoryTipOnEntityCommand.java @@ -0,0 +1,163 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2014, Arnaud Roques + * + * Project Info: http://plantuml.sourceforge.net + * + * 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. + * + * [Java is a trademark or registered trademark of Sun Microsystems, Inc. + * in the United States and other countries.] + * + * Original Author: Arnaud Roques + * + * Revision $Revision: 7558 $ + * + */ +package net.sourceforge.plantuml.command.note; + +import java.util.List; + +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.Url; +import net.sourceforge.plantuml.UrlBuilder; +import net.sourceforge.plantuml.UrlBuilder.ModeUrl; +import net.sourceforge.plantuml.classdiagram.AbstractEntityDiagram; +import net.sourceforge.plantuml.command.Command; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.CommandMultilines2; +import net.sourceforge.plantuml.command.MultilinesStrategy; +import net.sourceforge.plantuml.command.regex.IRegex; +import net.sourceforge.plantuml.command.regex.RegexConcat; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexResult; +import net.sourceforge.plantuml.cucadiagram.Code; +import net.sourceforge.plantuml.cucadiagram.Display; +import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.LeafType; +import net.sourceforge.plantuml.cucadiagram.Link; +import net.sourceforge.plantuml.cucadiagram.LinkDecor; +import net.sourceforge.plantuml.cucadiagram.LinkType; +import net.sourceforge.plantuml.graphic.HtmlColorUtils; + +public final class FactoryTipOnEntityCommand implements SingleMultiFactoryCommand { + + private final IRegex partialPattern; + + public FactoryTipOnEntityCommand(IRegex partialPattern) { + this.partialPattern = partialPattern; + } + + private RegexConcat getRegexConcatMultiLine(IRegex partialPattern) { + return new RegexConcat(new RegexLeaf("^note[%s]+"), // + new RegexLeaf("POSITION", "(right|left)"), // + new RegexLeaf("[%s]+of[%s]+"), partialPattern, // + new RegexLeaf("[%s]*"), // + new RegexLeaf("COLOR", "(" + HtmlColorUtils.COLOR_REGEXP + ")?"), // + new RegexLeaf("[%s]*\\{?"), // + new RegexLeaf("$") // + ); + } + + public Command createSingleLine() { + throw new UnsupportedOperationException(); + } + + public Command createMultiLine() { + return new CommandMultilines2(getRegexConcatMultiLine(partialPattern), + MultilinesStrategy.KEEP_STARTING_QUOTE) { + + @Override + public String getPatternEnd() { + return "(?i)^(end[%s]?note|\\})$"; + } + + public CommandExecutionResult executeNow(final AbstractEntityDiagram system, List lines) { + // StringUtils.trim(lines, false); + final RegexResult line0 = getStartingPattern().matcher(StringUtils.trin(lines.get(0))); + + List strings = StringUtils.removeEmptyColumns(lines.subList(1, lines.size() - 1)); + Url url = null; + if (strings.size() > 0) { + final UrlBuilder urlBuilder = new UrlBuilder(system.getSkinParam().getValue("topurl"), + ModeUrl.STRICT); + url = urlBuilder.getUrl(strings.get(0)); + } + if (url != null) { + strings = strings.subList(1, strings.size()); + } + + return executeInternal(line0, system, url, strings); + } + }; + } + + private CommandExecutionResult executeInternal(RegexResult line0, AbstractEntityDiagram diagram, Url url, + List s) { + + final String pos = line0.get("POSITION", 0); + + final Code code = Code.of(line0.get("ENTITY", 0)); + final String member = line0.get("ENTITY", 1); + if (code == null) { + return CommandExecutionResult.error("Nothing to note to"); + } + final IEntity cl1 = diagram.getOrCreateLeaf(code, null, null); + + final Code codeTip = code.addSuffix("$$$right"); + IEntity tips = diagram.getLeafsget(codeTip); + if (tips == null) { + tips = diagram.getOrCreateLeaf(codeTip, LeafType.TIPS, null); + final LinkType type = new LinkType(LinkDecor.NONE, LinkDecor.NONE).getInvisible(); + final Link link = new Link(cl1, (IEntity) tips, type, null, 1); + diagram.addLink(link); + } + tips.putTip(member, Display.create(s)); + + // final IEntity note = diagram.createLeaf(UniqueSequence.getCode("GMN"), Display.create(s), LeafType.NOTE, + // null); + // note.setSpecificBackcolor(diagram.getSkinParam().getIHtmlColorSet().getColorIfValid(line0.get("COLOR", 0))); + // if (url != null) { + // note.addUrl(url); + // } + // + // final Position position = Position.valueOf(StringUtils.goUpperCase(pos)).withRankdir( + // diagram.getSkinParam().getRankdir()); + // final Link link; + // + // final LinkType type = new LinkType(LinkDecor.NONE, LinkDecor.NONE).getDashed(); + // if (position == Position.RIGHT) { + // link = new Link(cl1, note, type, null, 1); + // link.setHorizontalSolitary(true); + // } else if (position == Position.LEFT) { + // link = new Link(note, cl1, type, null, 1); + // link.setHorizontalSolitary(true); + // } else if (position == Position.BOTTOM) { + // link = new Link(cl1, note, type, null, 2); + // } else if (position == Position.TOP) { + // link = new Link(note, cl1, type, null, 2); + // } else { + // throw new IllegalArgumentException(); + // } + // diagram.addLink(link); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteCommand.java b/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteCommand.java index a715f148a..bb028b122 100644 --- a/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteCommand.java +++ b/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteCommand.java @@ -90,7 +90,7 @@ public final class FactorySequenceNoteCommand implements SingleMultiFactoryComma } public CommandExecutionResult executeNow(final SequenceDiagram system, List lines) { - final RegexResult line0 = getStartingPattern().matcher(lines.get(0).trim()); + final RegexResult line0 = getStartingPattern().matcher(StringUtils.trin(lines.get(0))); final List strings = StringUtils.removeEmptyColumns(lines.subList(1, lines.size() - 1)); return executeInternal(system, line0, strings); } diff --git a/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteOnArrowCommand.java b/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteOnArrowCommand.java index f58c1671a..0c634dc6c 100644 --- a/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteOnArrowCommand.java +++ b/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteOnArrowCommand.java @@ -95,7 +95,7 @@ public final class FactorySequenceNoteOnArrowCommand implements SingleMultiFacto } public CommandExecutionResult executeNow(final SequenceDiagram system, List lines) { - final RegexResult line0 = getStartingPattern().matcher(lines.get(0).trim()); + final RegexResult line0 = getStartingPattern().matcher(StringUtils.trin(lines.get(0))); final List in = StringUtils.removeEmptyColumns(lines.subList(1, lines.size() - 1)); return executeInternal(system, line0, in); diff --git a/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteOverSeveralCommand.java b/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteOverSeveralCommand.java index f04a8fe19..70f70f1b7 100644 --- a/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteOverSeveralCommand.java +++ b/src/net/sourceforge/plantuml/command/note/sequence/FactorySequenceNoteOverSeveralCommand.java @@ -102,7 +102,7 @@ public final class FactorySequenceNoteOverSeveralCommand implements SingleMultiF } public CommandExecutionResult executeNow(final SequenceDiagram system, List lines) { - final RegexResult line0 = getStartingPattern().matcher(lines.get(0).trim()); + final RegexResult line0 = getStartingPattern().matcher(StringUtils.trin(lines.get(0))); final List strings = StringUtils.removeEmptyColumns(lines.subList(1, lines.size() - 1)); return executeInternal(system, line0, strings); diff --git a/src/net/sourceforge/plantuml/core/UmlSource.java b/src/net/sourceforge/plantuml/core/UmlSource.java index 093ef263b..07b995029 100644 --- a/src/net/sourceforge/plantuml/core/UmlSource.java +++ b/src/net/sourceforge/plantuml/core/UmlSource.java @@ -107,7 +107,7 @@ final public class UmlSource { * @return a iterator that allow counting line number. */ public IteratorCounter iterator() { - return new IteratorCounterImpl(source.iterator()); + return new IteratorCounterImpl(source); } /** @@ -161,7 +161,7 @@ final public class UmlSource { if (s.matches("\\s*'.*")) { continue; } - if (s.trim().length() != 0) { + if (StringUtils.trin(s).length() != 0) { return false; } } diff --git a/src/net/sourceforge/plantuml/creole/AtomTree.java b/src/net/sourceforge/plantuml/creole/AtomTree.java new file mode 100644 index 000000000..80970bcde --- /dev/null +++ b/src/net/sourceforge/plantuml/creole/AtomTree.java @@ -0,0 +1,102 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2014, Arnaud Roques + * + * Project Info: http://plantuml.sourceforge.net + * + * 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. + * + * [Java is a trademark or registered trademark of Sun Microsystems, Inc. + * in the United States and other countries.] + * + * Original Author: Arnaud Roques + * + * Revision $Revision: 11025 $ + * + */ +package net.sourceforge.plantuml.creole; + +import java.awt.geom.Dimension2D; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.salt.element.Skeleton2; +import net.sourceforge.plantuml.ugraphic.UChangeColor; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.UTranslate; + +public class AtomTree implements Atom { + + private final HtmlColor lineColor; + private final List cells = new ArrayList(); + private final Map levels = new HashMap(); + private final double margin = 2; + + public AtomTree(HtmlColor lineColor) { + this.lineColor = lineColor; + } + + public Dimension2D calculateDimension(StringBounder stringBounder) { + final Skeleton2 skeleton = new Skeleton2(); + double width = 0; + double height = 0; + for (Atom cell : cells) { + final Dimension2D dim = cell.calculateDimension(stringBounder); + height += dim.getHeight(); + final int level = getLevel(cell); + width = Math.max(width, skeleton.getXEndForLevel(level) + margin + dim.getWidth()); + } + return new Dimension2DDouble(width, height); + } + + public double getStartingAltitude(StringBounder stringBounder) { + return 0; + } + + public void drawU(final UGraphic ugInit) { + final Skeleton2 skeleton = new Skeleton2(); + double y = 0; + UGraphic ug = ugInit; + for (Atom cell : cells) { + final int level = getLevel(cell); + cell.drawU(ug.apply(new UTranslate(margin + skeleton.getXEndForLevel(level), 0))); + final Dimension2D dim = cell.calculateDimension(ug.getStringBounder()); + skeleton.add(level, y + dim.getHeight() / 2); + ug = ug.apply(new UTranslate(0, dim.getHeight())); + y += dim.getHeight(); + } + skeleton.draw(ugInit.apply(new UChangeColor(this.lineColor))); + } + + private int getLevel(Atom atom) { + return levels.get(atom); + } + + public void addCell(Atom cell, int level) { + this.cells.add(cell); + this.levels.put(cell, level); + } + +} diff --git a/src/net/sourceforge/plantuml/creole/CreoleParser.java b/src/net/sourceforge/plantuml/creole/CreoleParser.java index 46cc75afd..e52a1233c 100644 --- a/src/net/sourceforge/plantuml/creole/CreoleParser.java +++ b/src/net/sourceforge/plantuml/creole/CreoleParser.java @@ -38,6 +38,7 @@ import java.util.List; import net.sourceforge.plantuml.EmbededDiagram; import net.sourceforge.plantuml.ISkinSimple; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.HorizontalAlignment; @@ -62,10 +63,22 @@ public class CreoleParser { final StripeTable table = (StripeTable) lastStripe; table.analyzeAndAddNormal(line); return null; + } else if (lastStripe instanceof StripeTree && isTreeStart(StringUtils.trinNoTrace(line))) { + final StripeTree tree = (StripeTree) lastStripe; + tree.analyzeAndAdd(line); + return null; } else if (line.startsWith("|=") && line.endsWith("|")) { return new StripeTable(fontConfiguration, skinParam, line); + } else if (isTreeStart(line)) { + return new StripeTree(fontConfiguration, skinParam, line); } - return new CreoleStripeSimpleParser(line, context, fontConfiguration, skinParam, modeSimpleLine).createStripe(context); + return new CreoleStripeSimpleParser(line, context, fontConfiguration, skinParam, modeSimpleLine) + .createStripe(context); + } + + public static boolean isTreeStart(String line) { + // return false; + return line.startsWith("|_"); } public Sheet createSheet(Display display) { diff --git a/src/net/sourceforge/plantuml/creole/CreoleStripeSimpleParser.java b/src/net/sourceforge/plantuml/creole/CreoleStripeSimpleParser.java index aee8b0c3f..850e424e5 100644 --- a/src/net/sourceforge/plantuml/creole/CreoleStripeSimpleParser.java +++ b/src/net/sourceforge/plantuml/creole/CreoleStripeSimpleParser.java @@ -37,6 +37,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import net.sourceforge.plantuml.ISkinSimple; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.utils.CharHidder; @@ -101,7 +102,7 @@ public class CreoleStripeSimpleParser { final Pattern p1 = MyPattern.cmpile("^(\\*+)([^*]+(?:[^*]|\\*\\*[^*]+\\*\\*)*)$"); final Matcher m1 = p1.matcher(line); if (m1.find()) { - this.line = m1.group(2).trim(); + this.line = StringUtils.trin(m1.group(2)); final int order = m1.group(1).length() - 1; this.style = new StripeStyle(StripeStyleType.LIST_WITHOUT_NUMBER, order, '\0'); return; @@ -112,7 +113,7 @@ public class CreoleStripeSimpleParser { final Pattern p2 = MyPattern.cmpile("^(#+)(.+)$"); final Matcher m2 = p2.matcher(CharHidder.hide(line)); if (m2.find()) { - this.line = CharHidder.unhide(m2.group(2)).trim(); + this.line = StringUtils.trin(CharHidder.unhide(m2.group(2))); final int order = CharHidder.unhide(m2.group(1)).length() - 1; this.style = new StripeStyle(StripeStyleType.LIST_WITH_NUMBER, order, '\0'); return; @@ -122,7 +123,7 @@ public class CreoleStripeSimpleParser { final Pattern p3 = MyPattern.cmpile("^(=+)(.+)$"); final Matcher m3 = p3.matcher(line); if (m3.find()) { - this.line = m3.group(2).trim(); + this.line = StringUtils.trin(m3.group(2)); final int order = m3.group(1).length() - 1; this.style = new StripeStyle(StripeStyleType.HEADING, order, '\0'); return; diff --git a/src/net/sourceforge/plantuml/creole/PSystemCreole.java b/src/net/sourceforge/plantuml/creole/PSystemCreole.java index e8c45cfa3..f40639ba0 100644 --- a/src/net/sourceforge/plantuml/creole/PSystemCreole.java +++ b/src/net/sourceforge/plantuml/creole/PSystemCreole.java @@ -78,7 +78,7 @@ public class PSystemCreole extends AbstractPSystem { final ImageBuilder builder = new ImageBuilder(new ColorMapperIdentity(), 1.0, null, null, null, 0, 0, null, false); builder.addUDrawable(sheetBlock); - return builder.writeImageTOBEMOVED(fileFormat.getFileFormat(), os); + return builder.writeImageTOBEMOVED(fileFormat, os); // final Dimension2D dim = TextBlockUtils.getDimension(sheetBlock); // final UGraphic2 ug = fileFormat.createUGraphic(new ColorMapperIdentity(), 1, dim, null, false); diff --git a/src/net/sourceforge/plantuml/creole/StripeStyleType.java b/src/net/sourceforge/plantuml/creole/StripeStyleType.java index a1aeba55b..3bec5662f 100644 --- a/src/net/sourceforge/plantuml/creole/StripeStyleType.java +++ b/src/net/sourceforge/plantuml/creole/StripeStyleType.java @@ -34,5 +34,5 @@ package net.sourceforge.plantuml.creole; public enum StripeStyleType { - NORMAL, HEADING, LIST_WITHOUT_NUMBER, LIST_WITH_NUMBER, HORIZONTAL_LINE + NORMAL, HEADING, LIST_WITHOUT_NUMBER, LIST_WITH_NUMBER, HORIZONTAL_LINE, TREE } diff --git a/src/net/sourceforge/plantuml/creole/StripeTable.java b/src/net/sourceforge/plantuml/creole/StripeTable.java index f20f83244..776f5581a 100644 --- a/src/net/sourceforge/plantuml/creole/StripeTable.java +++ b/src/net/sourceforge/plantuml/creole/StripeTable.java @@ -66,7 +66,7 @@ public class StripeTable implements Stripe { return Collections. singletonList(marged); } - private static Atom asAtom(List cells, double padding) { + static Atom asAtom(List cells, double padding) { final Sheet sheet = new Sheet(HorizontalAlignment.LEFT); for (StripeSimple cell : cells) { sheet.add(cell); @@ -93,7 +93,7 @@ public class StripeTable implements Stripe { } } - private static List getWithNewlinesInternal(String s) { + static List getWithNewlinesInternal(String s) { final List result = new ArrayList(); final StringBuilder current = new StringBuilder(); for (int i = 0; i < s.length(); i++) { diff --git a/src/net/sourceforge/plantuml/creole/StripeTree.java b/src/net/sourceforge/plantuml/creole/StripeTree.java new file mode 100644 index 000000000..a843649d8 --- /dev/null +++ b/src/net/sourceforge/plantuml/creole/StripeTree.java @@ -0,0 +1,76 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2014, Arnaud Roques + * + * Project Info: http://plantuml.sourceforge.net + * + * 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. + * + * [Java is a trademark or registered trademark of Sun Microsystems, Inc. + * in the United States and other countries.] + * + * Original Author: Arnaud Roques + * + * Revision $Revision: 11025 $ + * + */ +package net.sourceforge.plantuml.creole; + +import java.util.Collections; +import java.util.List; + +import net.sourceforge.plantuml.ISkinSimple; +import net.sourceforge.plantuml.graphic.FontConfiguration; + +public class StripeTree implements Stripe { + + private FontConfiguration fontConfiguration; + final private ISkinSimple skinParam; + final private AtomTree tree; + final private Atom marged; + final private StripeStyle stripeStyle = new StripeStyle(StripeStyleType.TREE, 0, '\0'); + + public StripeTree(FontConfiguration fontConfiguration, ISkinSimple skinParam, String line) { + this.fontConfiguration = fontConfiguration; + this.skinParam = skinParam; + this.tree = new AtomTree(fontConfiguration.getColor()); + this.marged = new AtomWithMargin(tree, 2, 2); + analyzeAndAdd(line); + } + + public List getAtoms() { + return Collections. singletonList(marged); + } + + public void analyzeAndAdd(String line) { + final List lines = StripeTable.getWithNewlinesInternal(line); + for (String s : lines) { + final StripeSimple cell = new StripeSimple(fontConfiguration, stripeStyle, new CreoleContext(), skinParam, + false); + // EMTEC + final String text = s.replaceFirst("^\\s*\\|_", ""); + final int level = (s.length() - text.length()) / 2; + cell.analyzeAndAdd(text); + this.tree.addCell(StripeTable.asAtom(Collections.singletonList(cell), 0), level); + } + + } + +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/BlockMember.java b/src/net/sourceforge/plantuml/cucadiagram/BlockMember.java index f966a164e..8acdb11b0 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/BlockMember.java +++ b/src/net/sourceforge/plantuml/cucadiagram/BlockMember.java @@ -33,12 +33,17 @@ */ package net.sourceforge.plantuml.cucadiagram; +import java.awt.geom.Rectangle2D; + import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.TextBlock; public interface BlockMember { public TextBlock asTextBlock(FontParam fontParam, ISkinParam skinParam); + + public Rectangle2D getPosition(String member, StringBounder stringBounder, FontParam fontParam, ISkinParam skinParam); } diff --git a/src/net/sourceforge/plantuml/cucadiagram/BlockMemberImpl.java b/src/net/sourceforge/plantuml/cucadiagram/BlockMemberImpl.java index 7d757b54b..eb69cdd0e 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/BlockMemberImpl.java +++ b/src/net/sourceforge/plantuml/cucadiagram/BlockMemberImpl.java @@ -33,12 +33,14 @@ */ package net.sourceforge.plantuml.cucadiagram; +import java.awt.geom.Rectangle2D; import java.util.ArrayList; import java.util.Collections; import java.util.List; import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlockLineBefore; import net.sourceforge.plantuml.graphic.TextBlockUtils; @@ -56,8 +58,18 @@ public class BlockMemberImpl implements BlockMember { } public TextBlock asTextBlock(FontParam fontParam, ISkinParam skinParam) { - return new TextBlockLineBefore(TextBlockUtils.withMargin((TextBlock) new MethodsOrFieldsArea(members, - fontParam, skinParam), 6, 4)); + final MethodsOrFieldsArea methodsOrFieldsArea = new MethodsOrFieldsArea(members, fontParam, skinParam); + return new TextBlockLineBefore(TextBlockUtils.withMargin((TextBlock) methodsOrFieldsArea, 6, 4)); + } + + public Rectangle2D getPosition(String member, StringBounder stringBounder, FontParam fontParam, ISkinParam skinParam) { + final MethodsOrFieldsArea methodsOrFieldsArea = new MethodsOrFieldsArea(members, fontParam, skinParam); + return methodsOrFieldsArea.getPosition(member, stringBounder); + } + + public boolean contains(String member, FontParam fontParam, ISkinParam skinParam) { + final MethodsOrFieldsArea methodsOrFieldsArea = new MethodsOrFieldsArea(members, fontParam, skinParam); + return methodsOrFieldsArea.contains(member); } } diff --git a/src/net/sourceforge/plantuml/cucadiagram/Bodier.java b/src/net/sourceforge/plantuml/cucadiagram/Bodier.java index b080f8f7f..50f0ef47f 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/Bodier.java +++ b/src/net/sourceforge/plantuml/cucadiagram/Bodier.java @@ -33,6 +33,7 @@ */ package net.sourceforge.plantuml.cucadiagram; +import java.awt.geom.Rectangle2D; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -40,9 +41,10 @@ import java.util.Set; import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.skin.VisibilityModifier; -import net.sourceforge.plantuml.StringUtils; public class Bodier { @@ -81,6 +83,9 @@ public class Bodier { final BodyEnhanced result = new BodyEnhanced(rawBody, fontParam, skinParam, manageModifier); return result; } + public Rectangle2D getPosition(String member, StringBounder stringBounder, FontParam fontParam, ISkinParam skinParam) { + throw new UnsupportedOperationException(); + } }; } @@ -108,7 +113,7 @@ public class Bodier { if (s.length() == 0 && methodsToDisplay.size() == 0) { continue; } - final Member m = new Member(s, true, manageModifier); + final Member m = new MemberImpl(s, true, manageModifier, true); if (hides == null || hides.contains(m.getVisibilityModifier()) == false) { methodsToDisplay.add(m); } @@ -136,7 +141,7 @@ public class Bodier { if (s.length() == 0 && fieldsToDisplay.size() == 0) { continue; } - final Member m = new Member(s, false, manageModifier); + final Member m = new MemberImpl(s, false, manageModifier, true); if (hides == null || hides.contains(m.getVisibilityModifier()) == false) { fieldsToDisplay.add(m); } @@ -147,7 +152,7 @@ public class Bodier { } private void removeFinalEmptyMembers(List result) { - while (result.size() > 0 && result.get(result.size() - 1).getDisplay(false).trim().length() == 0) { + while (result.size() > 0 && StringUtils.trin(result.get(result.size() - 1).getDisplay(false)).length() == 0) { result.remove(result.size() - 1); } } diff --git a/src/net/sourceforge/plantuml/cucadiagram/BodyEnhanced.java b/src/net/sourceforge/plantuml/cucadiagram/BodyEnhanced.java index ab23879d9..9042c0abd 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/BodyEnhanced.java +++ b/src/net/sourceforge/plantuml/cucadiagram/BodyEnhanced.java @@ -37,11 +37,14 @@ import java.awt.geom.Dimension2D; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.ListIterator; import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.ISkinSimple; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.Url; +import net.sourceforge.plantuml.creole.CreoleParser; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.HorizontalAlignment; import net.sourceforge.plantuml.graphic.StringBounder; @@ -51,7 +54,6 @@ import net.sourceforge.plantuml.graphic.TextBlockUtils; import net.sourceforge.plantuml.graphic.TextBlockVertical2; import net.sourceforge.plantuml.skin.rose.Rose; import net.sourceforge.plantuml.ugraphic.UGraphic; -import net.sourceforge.plantuml.StringUtils; public class BodyEnhanced implements TextBlock { @@ -65,14 +67,16 @@ public class BodyEnhanced implements TextBlock { private final boolean manageHorizontalLine; private final boolean manageModifier; private final List urls = new ArrayList(); + private final boolean manageUrl; public BodyEnhanced(List rawBody, FontParam fontParam, ISkinParam skinParam, boolean manageModifier) { this.rawBody = new ArrayList(rawBody); this.fontParam = fontParam; this.skinParam = skinParam; + this.manageUrl = true; - this.titleConfig = new FontConfiguration(skinParam.getFont(fontParam, null, false), new Rose().getFontColor(skinParam, - fontParam), skinParam.getHyperlinkColor(), skinParam.useUnderlineForHyperlink()); + this.titleConfig = new FontConfiguration(skinParam.getFont(fontParam, null, false), new Rose().getFontColor( + skinParam, fontParam), skinParam.getHyperlinkColor(), skinParam.useUnderlineForHyperlink()); this.lineFirst = true; this.align = HorizontalAlignment.LEFT; this.manageHorizontalLine = true; @@ -80,7 +84,8 @@ public class BodyEnhanced implements TextBlock { } public BodyEnhanced(Display display, FontParam fontParam, ISkinParam skinParam, HorizontalAlignment align, - Stereotype stereotype, boolean manageHorizontalLine, boolean manageModifier) { + Stereotype stereotype, boolean manageHorizontalLine, boolean manageModifier, boolean manageUrl) { + this.manageUrl = manageUrl; this.rawBody = new ArrayList(); for (CharSequence s : display) { this.rawBody.add(s.toString()); @@ -123,15 +128,26 @@ public class BodyEnhanced implements TextBlock { char separator = lineFirst ? '_' : 0; TextBlock title = null; List members = new ArrayList(); - for (String s : rawBody) { + for (ListIterator it = rawBody.listIterator(); it.hasNext();) { + final String s = it.next(); if (manageHorizontalLine && isBlockSeparator(s)) { blocks.add(decorate(stringBounder, new MethodsOrFieldsArea(members, fontParam, skinParam, align), separator, title)); separator = s.charAt(0); title = getTitle(s, skinParam); members = new ArrayList(); + } else if (CreoleParser.isTreeStart(s)) { + if (members.size() > 0) { + blocks.add(decorate(stringBounder, new MethodsOrFieldsArea(members, fontParam, skinParam, align), + separator, title)); + } + members = new ArrayList(); + final List allTree = buildAllTree(s, it); + final TextBlock bloc = TextBlockUtils.create(Display.create(allTree), + fontParam.getFontConfiguration(skinParam), align, skinParam, false); + blocks.add(bloc); } else { - final Member m = new Member(s, StringUtils.isMethod(s), manageModifier); + final Member m = new MemberImpl(s, StringUtils.isMethod(s), manageModifier, manageUrl); members.add(m); if (m.getUrl() != null) { urls.add(m.getUrl()); @@ -150,6 +166,22 @@ public class BodyEnhanced implements TextBlock { return area2; } + private static List buildAllTree(String init, ListIterator it) { + final List result = new ArrayList(); + result.add(init); + while (it.hasNext()) { + final String s = it.next(); + if (CreoleParser.isTreeStart(StringUtils.trinNoTrace(s))) { + result.add(s); + } else { + it.previous(); + return result; + } + + } + return result; + } + public static boolean isBlockSeparator(String s) { if (s.startsWith("--") && s.endsWith("--")) { return true; @@ -170,7 +202,7 @@ public class BodyEnhanced implements TextBlock { if (s.length() <= 4) { return null; } - s = s.substring(2, s.length() - 2).trim(); + s = StringUtils.trin(s.substring(2, s.length() - 2)); return TextBlockUtils .create(Display.getWithNewlines(s), titleConfig, HorizontalAlignment.LEFT, spriteContainer); } diff --git a/src/net/sourceforge/plantuml/cucadiagram/BodyEnhanced2.java b/src/net/sourceforge/plantuml/cucadiagram/BodyEnhanced2.java index 46e28d7c4..570833287 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/BodyEnhanced2.java +++ b/src/net/sourceforge/plantuml/cucadiagram/BodyEnhanced2.java @@ -39,6 +39,7 @@ import java.util.List; import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.ISkinSimple; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.HorizontalAlignment; import net.sourceforge.plantuml.graphic.HtmlColor; @@ -143,7 +144,7 @@ public class BodyEnhanced2 implements TextBlock { if (s.length() <= 4) { return null; } - s = s.substring(2, s.length() - 2).trim(); + s = StringUtils.trin(s.substring(2, s.length() - 2)); return TextBlockUtils .create(Display.getWithNewlines(s), titleConfig, HorizontalAlignment.LEFT, spriteContainer); } diff --git a/src/net/sourceforge/plantuml/cucadiagram/Display.java b/src/net/sourceforge/plantuml/cucadiagram/Display.java index 671d13a92..d01e604a8 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/Display.java +++ b/src/net/sourceforge/plantuml/cucadiagram/Display.java @@ -38,8 +38,11 @@ import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import net.sourceforge.plantuml.EmbededDiagram; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.UrlBuilder; import net.sourceforge.plantuml.UrlBuilder.ModeUrl; @@ -98,6 +101,9 @@ public class Display implements Iterable { current.append(c); current.append(c2); } + } else if (c == StringUtils.hiddenNewLine()) { + result.add(current.toString()); + current.setLength(0); } else { current.append(c); } @@ -125,12 +131,12 @@ public class Display implements Iterable { final Iterator it = strings.iterator(); while (it.hasNext()) { CharSequence s = it.next(); - if (s != null && s.toString().trim().equals("{{")) { + if (s != null && StringUtils.trin(s.toString()).equals("{{")) { final List other = new ArrayList(); other.add("@startuml"); while (it.hasNext()) { final CharSequence s2 = it.next(); - if (s2 != null && s2.toString().trim().equals("}}")) { + if (s2 != null && StringUtils.trin(s2.toString()).equals("}}")) { break; } other.add(s2); @@ -240,7 +246,7 @@ public class Display implements Iterable { return null; } final UrlBuilder urlBuilder = new UrlBuilder(null, ModeUrl.AT_START); - return urlBuilder.getUrl(this.get(0).toString().trim()); + return urlBuilder.getUrl(StringUtils.trin(this.get(0).toString())); } public Display removeUrl(Url url) { @@ -267,4 +273,24 @@ public class Display implements Iterable { return naturalHorizontalAlignment; } + public List splitMultiline(Pattern separator) { + final List result = new ArrayList(); + Display pending = new Display(this.naturalHorizontalAlignment); + result.add(pending); + for (CharSequence line : display) { + final Matcher m = separator.matcher(line); + if (m.find()) { + final CharSequence s1 = line.subSequence(0, m.start()); + pending.display.add(s1); + final CharSequence s2 = line.subSequence(m.end(), line.length()); + pending = new Display(this.naturalHorizontalAlignment); + result.add(pending); + pending.display.add(s2); + } else { + pending.display.add(line); + } + } + return Collections.unmodifiableList(result); + } + } diff --git a/src/net/sourceforge/plantuml/cucadiagram/Display2.java b/src/net/sourceforge/plantuml/cucadiagram/Display2.java index 11a608729..5f6e1c230 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/Display2.java +++ b/src/net/sourceforge/plantuml/cucadiagram/Display2.java @@ -39,6 +39,7 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.UrlBuilder; import net.sourceforge.plantuml.UrlBuilder.ModeUrl; @@ -214,7 +215,7 @@ public class Display2 implements Iterable { return null; } final UrlBuilder urlBuilder = new UrlBuilder(null, ModeUrl.AT_START); - return urlBuilder.getUrl(this.get(0).toString().trim()); + return urlBuilder.getUrl(StringUtils.trin(this.get(0).toString())); } public Display2 removeUrl(Url url) { diff --git a/src/net/sourceforge/plantuml/cucadiagram/GroupRoot.java b/src/net/sourceforge/plantuml/cucadiagram/GroupRoot.java index 66f628513..07998f49c 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/GroupRoot.java +++ b/src/net/sourceforge/plantuml/cucadiagram/GroupRoot.java @@ -37,6 +37,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Map; import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.Url; @@ -277,4 +278,12 @@ public class GroupRoot implements IGroup { throw new UnsupportedOperationException(); } + public void putTip(String member, Display display) { + throw new UnsupportedOperationException(); + } + + public Map getTips() { + throw new UnsupportedOperationException(); + } + } diff --git a/src/net/sourceforge/plantuml/cucadiagram/IEntity.java b/src/net/sourceforge/plantuml/cucadiagram/IEntity.java index 47a23ea9a..ddd57ce13 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/IEntity.java +++ b/src/net/sourceforge/plantuml/cucadiagram/IEntity.java @@ -34,6 +34,7 @@ package net.sourceforge.plantuml.cucadiagram; import java.util.List; +import java.util.Map; import net.sourceforge.plantuml.Hideable; import net.sourceforge.plantuml.LineConfigurable; @@ -92,4 +93,8 @@ public interface IEntity extends SpecificBackcolorable, Hideable, Removeable, Li public int getRawLayout(); + public void putTip(String member, Display display); + + public Map getTips(); + } diff --git a/src/net/sourceforge/plantuml/cucadiagram/LeafType.java b/src/net/sourceforge/plantuml/cucadiagram/LeafType.java index b8e7afb0e..91353b439 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/LeafType.java +++ b/src/net/sourceforge/plantuml/cucadiagram/LeafType.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 14727 $ + * Revision $Revision: 16249 $ * */ package net.sourceforge.plantuml.cucadiagram; @@ -39,7 +39,7 @@ public enum LeafType { EMPTY_PACKAGE, - ABSTRACT_CLASS, CLASS, INTERFACE, ANNOTATION, LOLLIPOP, NOTE, OBJECT, ASSOCIATION, ENUM, + ABSTRACT_CLASS, CLASS, INTERFACE, ANNOTATION, LOLLIPOP, NOTE, TIPS, OBJECT, ASSOCIATION, ENUM, USECASE, diff --git a/src/net/sourceforge/plantuml/cucadiagram/Member.java b/src/net/sourceforge/plantuml/cucadiagram/Member.java index 2502cb022..a67d293e3 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/Member.java +++ b/src/net/sourceforge/plantuml/cucadiagram/Member.java @@ -33,159 +33,20 @@ */ package net.sourceforge.plantuml.cucadiagram; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.Url; -import net.sourceforge.plantuml.UrlBuilder; -import net.sourceforge.plantuml.UrlBuilder.ModeUrl; -import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.skin.VisibilityModifier; -public class Member { +public interface Member { - private final String display; - private final boolean staticModifier; - private final boolean abstractModifier; - private final Url url; - private final boolean hasUrl; + public Url getUrl(); - private final VisibilityModifier visibilityModifier; + public String getDisplay(boolean withVisibilityChar); - public Member(String display, boolean isMethod, boolean manageModifier) { - this.hasUrl = new UrlBuilder(null, ModeUrl.ANYWHERE).getUrl(display) != null; - final Pattern pstart = MyPattern.cmpile("^(" + UrlBuilder.getRegexp() + ")([^\\[\\]]+)$"); - final Matcher mstart = pstart.matcher(display); + public boolean hasUrl(); - if (mstart.matches()) { - if (mstart.groupCount() != 5) { - throw new IllegalStateException(); - } - final UrlBuilder urlBuilder = new UrlBuilder(null, ModeUrl.AT_START); - url = urlBuilder.getUrl(mstart.group(1)); - url.setMember(true); - display = /* mstart.group(1).trim() + */mstart.group(mstart.groupCount()).trim(); - } else { - final Pattern pend = MyPattern.cmpile("^((?:[^\\[\\]]|\\[[^\\[\\]]*\\])+)(" + UrlBuilder.getRegexp() + ")$"); - final Matcher mend = pend.matcher(display); + public VisibilityModifier getVisibilityModifier(); - if (mend.matches()) { - if (mend.groupCount() != 5) { - throw new IllegalStateException(); - } - final UrlBuilder urlBuilder = new UrlBuilder(null, ModeUrl.AT_END); - url = urlBuilder.getUrl(mend.group(2)); - url.setMember(true); - display = mend.group(1).trim(); - } else { - url = null; - } - } - - final String lower = StringUtils.goLowerCase(display); - - if (manageModifier) { - this.staticModifier = lower.contains("{static}") || lower.contains("{classifier}"); - this.abstractModifier = lower.contains("{abstract}"); - String displayClean = display.replaceAll("(?i)\\{(static|classifier|abstract)\\}", "").trim(); - if (displayClean.length() == 0) { - displayClean = " "; - } - - if (VisibilityModifier.isVisibilityCharacter(displayClean.charAt(0))) { - visibilityModifier = VisibilityModifier.getVisibilityModifier(display.charAt(0), isMethod == false); - this.display = displayClean.substring(1).trim(); - } else { - this.display = displayClean; - visibilityModifier = null; - } - } else { - this.staticModifier = false; - this.visibilityModifier = null; - this.abstractModifier = false; - display = display.trim(); - this.display = display.length() == 0 ? " " : display.trim(); - } - } - - public String getDisplay(boolean withVisibilityChar) { - if (withVisibilityChar) { - return getDisplayWithVisibilityChar(); - } - return getDisplayWithoutVisibilityChar(); - } - - public String getDisplayWithoutVisibilityChar() { - // assert display.length() == 0 || VisibilityModifier.isVisibilityCharacter(display.charAt(0)) == false; - return display; - } - - public String getDisplayWithVisibilityChar() { - if (isPrivate()) { - return "-" + display; - } - if (isPublic()) { - return "+" + display; - } - if (isPackagePrivate()) { - return "~" + display; - } - if (isProtected()) { - return "#" + display; - } - return display; - } - - @Override - public boolean equals(Object obj) { - final Member other = (Member) obj; - return this.display.equals(other.display); - } - - @Override - public int hashCode() { - return display.hashCode(); - } - - public final boolean isStatic() { - return staticModifier; - } - - public final boolean isAbstract() { - return abstractModifier; - } - - private boolean isPrivate() { - return visibilityModifier == VisibilityModifier.PRIVATE_FIELD - || visibilityModifier == VisibilityModifier.PRIVATE_METHOD; - } - - private boolean isProtected() { - return visibilityModifier == VisibilityModifier.PROTECTED_FIELD - || visibilityModifier == VisibilityModifier.PROTECTED_METHOD; - } - - private boolean isPublic() { - return visibilityModifier == VisibilityModifier.PUBLIC_FIELD - || visibilityModifier == VisibilityModifier.PUBLIC_METHOD; - } - - private boolean isPackagePrivate() { - return visibilityModifier == VisibilityModifier.PACKAGE_PRIVATE_FIELD - || visibilityModifier == VisibilityModifier.PACKAGE_PRIVATE_METHOD; - } - - public final VisibilityModifier getVisibilityModifier() { - return visibilityModifier; - } - - public final Url getUrl() { - return url; - } - - public boolean hasUrl() { - return hasUrl; - } + public boolean isStatic(); + public boolean isAbstract(); } diff --git a/src/net/sourceforge/plantuml/cucadiagram/MemberImpl.java b/src/net/sourceforge/plantuml/cucadiagram/MemberImpl.java new file mode 100644 index 000000000..b83a36788 --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/MemberImpl.java @@ -0,0 +1,197 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2014, Arnaud Roques + * + * Project Info: http://plantuml.sourceforge.net + * + * 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. + * + * [Java is a trademark or registered trademark of Sun Microsystems, Inc. + * in the United States and other countries.] + * + * Original Author: Arnaud Roques + * + * Revision $Revision: 4749 $ + * + */ +package net.sourceforge.plantuml.cucadiagram; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.Url; +import net.sourceforge.plantuml.UrlBuilder; +import net.sourceforge.plantuml.UrlBuilder.ModeUrl; +import net.sourceforge.plantuml.command.regex.MyPattern; +import net.sourceforge.plantuml.skin.VisibilityModifier; + +public class MemberImpl implements Member { + + private final String display; + private final boolean staticModifier; + private final boolean abstractModifier; + private final Url url; + private final boolean hasUrl; + + private final VisibilityModifier visibilityModifier; + + public MemberImpl(String tmpDisplay, boolean isMethod, boolean manageModifier, boolean manageUrl) { + if (manageModifier) { + this.hasUrl = new UrlBuilder(null, ModeUrl.ANYWHERE).getUrl(tmpDisplay) != null; + final Pattern pstart = MyPattern.cmpile("^(" + UrlBuilder.getRegexp() + ")([^\\[\\]]+)$"); + final Matcher mstart = pstart.matcher(tmpDisplay); + + if (mstart.matches()) { + if (mstart.groupCount() != 5) { + throw new IllegalStateException(); + } + final UrlBuilder urlBuilder = new UrlBuilder(null, ModeUrl.AT_START); + this.url = urlBuilder.getUrl(mstart.group(1)); + this.url.setMember(true); + tmpDisplay = /* mstart.group(1).trim() + */StringUtils.trin(mstart.group(mstart.groupCount())); + } else { + final Pattern pend = MyPattern.cmpile("^((?:[^\\[\\]]|\\[[^\\[\\]]*\\])+)(" + UrlBuilder.getRegexp() + + ")$"); + final Matcher mend = pend.matcher(tmpDisplay); + + if (mend.matches()) { + if (mend.groupCount() != 5) { + throw new IllegalStateException(); + } + final UrlBuilder urlBuilder = new UrlBuilder(null, ModeUrl.AT_END); + this.url = urlBuilder.getUrl(mend.group(2)); + this.url.setMember(true); + tmpDisplay = StringUtils.trin(mend.group(1)); + } else { + this.url = null; + } + } + } else { + this.url = null; + this.hasUrl = false; + } + + final String lower = StringUtils.goLowerCase(tmpDisplay); + + if (manageModifier) { + this.staticModifier = lower.contains("{static}") || lower.contains("{classifier}"); + this.abstractModifier = lower.contains("{abstract}"); + String displayClean = tmpDisplay.replaceAll("(?i)\\{(static|classifier|abstract)\\}\\s*", ""); + if (displayClean.length() == 0) { + displayClean = " "; + } + + if (VisibilityModifier.isVisibilityCharacter(displayClean.charAt(0))) { + visibilityModifier = VisibilityModifier.getVisibilityModifier(displayClean.charAt(0), isMethod == false); + this.display = StringUtils.trin(StringUtils.manageGuillemet(displayClean.substring(1))); + } else { + this.display = StringUtils.manageGuillemet(displayClean); + visibilityModifier = null; + } + } else { + this.staticModifier = false; + this.visibilityModifier = null; + this.abstractModifier = false; + tmpDisplay = StringUtils.trin(tmpDisplay); + this.display = tmpDisplay.length() == 0 ? " " : StringUtils.manageGuillemet(StringUtils.trin(tmpDisplay)); + } + } + + public String getDisplay(boolean withVisibilityChar) { + if (withVisibilityChar) { + return getDisplayWithVisibilityChar(); + } + return getDisplayWithoutVisibilityChar(); + } + + public String getDisplayWithoutVisibilityChar() { + // assert display.length() == 0 || VisibilityModifier.isVisibilityCharacter(display.charAt(0)) == false; + return display; + } + + public String getDisplayWithVisibilityChar() { + if (isPrivate()) { + return "-" + display; + } + if (isPublic()) { + return "+" + display; + } + if (isPackagePrivate()) { + return "~" + display; + } + if (isProtected()) { + return "#" + display; + } + return display; + } + + @Override + public boolean equals(Object obj) { + final MemberImpl other = (MemberImpl) obj; + return this.display.equals(other.display); + } + + @Override + public int hashCode() { + return display.hashCode(); + } + + public final boolean isStatic() { + return staticModifier; + } + + public final boolean isAbstract() { + return abstractModifier; + } + + private boolean isPrivate() { + return visibilityModifier == VisibilityModifier.PRIVATE_FIELD + || visibilityModifier == VisibilityModifier.PRIVATE_METHOD; + } + + private boolean isProtected() { + return visibilityModifier == VisibilityModifier.PROTECTED_FIELD + || visibilityModifier == VisibilityModifier.PROTECTED_METHOD; + } + + private boolean isPublic() { + return visibilityModifier == VisibilityModifier.PUBLIC_FIELD + || visibilityModifier == VisibilityModifier.PUBLIC_METHOD; + } + + private boolean isPackagePrivate() { + return visibilityModifier == VisibilityModifier.PACKAGE_PRIVATE_FIELD + || visibilityModifier == VisibilityModifier.PACKAGE_PRIVATE_METHOD; + } + + public final VisibilityModifier getVisibilityModifier() { + return visibilityModifier; + } + + public final Url getUrl() { + return url; + } + + public boolean hasUrl() { + return hasUrl; + } + +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/MethodsOrFieldsArea.java b/src/net/sourceforge/plantuml/cucadiagram/MethodsOrFieldsArea.java index 6ae1a3ea8..1ce6ccf81 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/MethodsOrFieldsArea.java +++ b/src/net/sourceforge/plantuml/cucadiagram/MethodsOrFieldsArea.java @@ -34,6 +34,7 @@ package net.sourceforge.plantuml.cucadiagram; import java.awt.geom.Dimension2D; +import java.awt.geom.Rectangle2D; import java.util.ArrayList; import java.util.List; @@ -191,6 +192,29 @@ public class MethodsOrFieldsArea implements TextBlockWidth, TextBlock { }; } + public Rectangle2D getPosition(String member, StringBounder stringBounder) { + double x = 0; + double y = 0; + for (Member att : members) { + final TextBlock bloc = createTextBlock(att); + final Dimension2D dim = bloc.calculateDimension(stringBounder); + if (att.getDisplay(false).startsWith(member)) { + return new Rectangle2D.Double(x, y, dim.getWidth(), dim.getHeight()); + } + y += dim.getHeight(); + } + throw new IllegalArgumentException(); + } + + public boolean contains(String member) { + for (Member att : members) { + if (att.getDisplay(false).startsWith(member)) { + return true; + } + } + return false; + } + public void drawU(UGraphic ug) { final Dimension2D dim = calculateDimension(ug.getStringBounder()); final ULayoutGroup group; @@ -220,4 +244,5 @@ public class MethodsOrFieldsArea implements TextBlockWidth, TextBlock { } group.drawU(ug, 0, 0, dim.getWidth(), dim.getHeight()); } + } diff --git a/src/net/sourceforge/plantuml/cucadiagram/Stereotype.java b/src/net/sourceforge/plantuml/cucadiagram/Stereotype.java index 9e1e7c50b..bdc719230 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/Stereotype.java +++ b/src/net/sourceforge/plantuml/cucadiagram/Stereotype.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 15849 $ + * Revision $Revision: 16159 $ * */ package net.sourceforge.plantuml.cucadiagram; @@ -145,7 +145,7 @@ public class Stereotype implements CharSequence, Hideable { return null; } if (withGuillement) { - return manageGuillemet(label); + return StringUtils.manageGuillemetStrict(label); } return label; } @@ -194,7 +194,7 @@ public class Stereotype implements CharSequence, Hideable { final Matcher m = p.matcher(getLabel(false)); while (m.find()) { if (useGuillemet) { - result.add(manageGuillemet(m.group())); + result.add(StringUtils.manageGuillemetStrict(m.group())); } else { result.add(m.group()); } @@ -202,20 +202,6 @@ public class Stereotype implements CharSequence, Hideable { return Collections.unmodifiableList(result); } - private static String manageGuillemet(String st) { - if (st.startsWith("<< ")) { - st = "\u00AB" + st.substring(3); - } else if (st.startsWith("<<")) { - st = "\u00AB" + st.substring(2); - } - if (st.endsWith(" >>")) { - st = st.substring(0, st.length() - 3) + "\u00BB"; - } else if (st.endsWith(">>")) { - st = st.substring(0, st.length() - 2) + "\u00BB"; - } - return st; - } - public PackageStyle getPackageStyle() { if (automaticPackageStyle == false) { return null; diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/AbstractGraphviz.java b/src/net/sourceforge/plantuml/cucadiagram/dot/AbstractGraphviz.java index 360560ad9..717fb7880 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/dot/AbstractGraphviz.java +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/AbstractGraphviz.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 15599 $ + * Revision $Revision: 16196 $ * */ package net.sourceforge.plantuml.cucadiagram.dot; @@ -147,7 +147,7 @@ abstract class AbstractGraphviz implements Graphviz { } sb.append(p.getError()); } - return sb.toString().replace('\n', ' ').trim(); + return StringUtils.trin(sb.toString().replace('\n', ' ')); } final String[] getCommandLine() { diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizVersionFinder.java b/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizVersionFinder.java index 64e06bad0..773954458 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizVersionFinder.java +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/GraphvizVersionFinder.java @@ -97,7 +97,7 @@ public class GraphvizVersionFinder { } sb.append(p.getError()); } - return sb.toString().replace('\n', ' ').trim(); + return StringUtils.trin(sb.toString().replace('\n', ' ')); } private String[] getCommandLine() { diff --git a/src/net/sourceforge/plantuml/cucadiagram/entity/EntityImpl.java b/src/net/sourceforge/plantuml/cucadiagram/entity/EntityImpl.java index 4bdd725cc..bed8f8114 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/entity/EntityImpl.java +++ b/src/net/sourceforge/plantuml/cucadiagram/entity/EntityImpl.java @@ -33,10 +33,13 @@ */ package net.sourceforge.plantuml.cucadiagram.entity; +import java.awt.geom.Rectangle2D; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.ISkinParam; @@ -64,6 +67,7 @@ import net.sourceforge.plantuml.cucadiagram.Stereotype; import net.sourceforge.plantuml.cucadiagram.dot.Neighborhood; import net.sourceforge.plantuml.graphic.HorizontalAlignment; import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlockVertical2; import net.sourceforge.plantuml.graphic.USymbol; @@ -299,6 +303,11 @@ final class EntityImpl implements ILeaf, IGroup { public TextBlock asTextBlock(FontParam fontParam, ISkinParam skinParam) { return null; } + + public Rectangle2D getPosition(String member, StringBounder stringBounder, FontParam fontParam, + ISkinParam skinParam) { + throw new UnsupportedOperationException(); + } }; } return new BlockMember() { @@ -306,10 +315,11 @@ final class EntityImpl implements ILeaf, IGroup { if (getEntityType().isLikeClass()) { if (showFields && showMethods) { - return new TextBlockVertical2(new BlockMemberImpl(getFieldsToDisplay()).asTextBlock(fontParam, - skinParam), - new BlockMemberImpl(getMethodsToDisplay()).asTextBlock(fontParam, skinParam), - HorizontalAlignment.LEFT); + final BlockMemberImpl bb1 = new BlockMemberImpl(getFieldsToDisplay()); + final BlockMemberImpl bb2 = new BlockMemberImpl(getMethodsToDisplay()); + final TextBlock b1 = bb1.asTextBlock(fontParam, skinParam); + final TextBlock b2 = bb2.asTextBlock(fontParam, skinParam); + return new TextBlockVertical2(b1, b2, HorizontalAlignment.LEFT); } else if (showFields) { return new BlockMemberImpl(getFieldsToDisplay()).asTextBlock(fontParam, skinParam); } else if (showMethods) { @@ -322,6 +332,25 @@ final class EntityImpl implements ILeaf, IGroup { } throw new UnsupportedOperationException(); } + + public Rectangle2D getPosition(String member, StringBounder stringBounder, FontParam fontParam, + ISkinParam skinParam) { + if (getEntityType().isLikeClass()) { + + if (showFields && showMethods) { + final BlockMemberImpl bb1 = new BlockMemberImpl(getFieldsToDisplay()); + final BlockMemberImpl bb2 = new BlockMemberImpl(getMethodsToDisplay()); + if (bb1.contains(member, fontParam, skinParam)) { + return bb1.getPosition(member, stringBounder, fontParam, skinParam); + } + if (bb2.contains(member, fontParam, skinParam)) { + return bb2.getPosition(member, stringBounder, fontParam, skinParam); + } + } + return null; + } + throw new UnsupportedOperationException(); + } }; } @@ -333,6 +362,11 @@ final class EntityImpl implements ILeaf, IGroup { public TextBlock asTextBlock(FontParam fontParam, ISkinParam skinParam) { return new BodyEnhanced(mouseOver, fontParam, skinParam, leafType.manageModifier()); } + + public Rectangle2D getPosition(String member, StringBounder stringBounder, FontParam fontParam, + ISkinParam skinParam) { + throw new UnsupportedOperationException(); + } }; } @@ -648,4 +682,14 @@ final class EntityImpl implements ILeaf, IGroup { return neighborhood; } + private final Map tips = new LinkedHashMap(); + + public void putTip(String member, Display display) { + tips.put(member, display); + } + + public Map getTips() { + return Collections.unmodifiableMap(tips); + } + } diff --git a/src/net/sourceforge/plantuml/cute/CuteShapeFactory.java b/src/net/sourceforge/plantuml/cute/CuteShapeFactory.java index a75d927ab..93ecbda7e 100644 --- a/src/net/sourceforge/plantuml/cute/CuteShapeFactory.java +++ b/src/net/sourceforge/plantuml/cute/CuteShapeFactory.java @@ -35,6 +35,8 @@ package net.sourceforge.plantuml.cute; import java.util.Map; +import net.sourceforge.plantuml.StringUtils; + public class CuteShapeFactory { private final Map groups; @@ -50,7 +52,7 @@ public class CuteShapeFactory { } private CuteShape createCuteShape(String data) { - data = data.toLowerCase().trim(); + data = StringUtils.trin(data.toLowerCase()); final VarArgs varArgs = new VarArgs(data); if (data.startsWith("circle ")) { return new Circle(varArgs); diff --git a/src/net/sourceforge/plantuml/cute/PSystemCute.java b/src/net/sourceforge/plantuml/cute/PSystemCute.java index 677d58080..ec20da360 100644 --- a/src/net/sourceforge/plantuml/cute/PSystemCute.java +++ b/src/net/sourceforge/plantuml/cute/PSystemCute.java @@ -35,14 +35,11 @@ package net.sourceforge.plantuml.cute; import java.io.IOException; import java.io.OutputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; import java.util.StringTokenizer; import net.sourceforge.plantuml.AbstractPSystem; import net.sourceforge.plantuml.FileFormatOption; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.core.DiagramDescription; import net.sourceforge.plantuml.core.DiagramDescriptionImpl; import net.sourceforge.plantuml.core.ImageData; @@ -64,7 +61,7 @@ public class PSystemCute extends AbstractPSystem { } public void doCommandLine(String line) { - line = line.trim(); + line = StringUtils.trin(line); if (line.length()==0 || line.startsWith("'")) { return; } @@ -88,6 +85,6 @@ public class PSystemCute extends AbstractPSystem { public ImageData exportDiagram(OutputStream os, int num, FileFormatOption fileFormat) throws IOException { final ImageBuilder builder = new ImageBuilder(new ColorMapperIdentity(), 1.0, null, null, null, 10, 10, null, false); builder.addUDrawable(root); - return builder.writeImageTOBEMOVED(fileFormat.getFileFormat(), os); + return builder.writeImageTOBEMOVED(fileFormat, os); } } diff --git a/src/net/sourceforge/plantuml/descdiagram/DescriptionDiagram.java b/src/net/sourceforge/plantuml/descdiagram/DescriptionDiagram.java index a7cb711cd..0b44a0493 100644 --- a/src/net/sourceforge/plantuml/descdiagram/DescriptionDiagram.java +++ b/src/net/sourceforge/plantuml/descdiagram/DescriptionDiagram.java @@ -68,7 +68,7 @@ public class DescriptionDiagram extends AbstractEntityDiagram { LeafType.DESCRIPTION, USymbol.ACTOR); } if (code2.startsWith("()")) { - code2 = code2.substring(2).trim(); + code2 = StringUtils.trin(code2.substring(2)); code2 = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(code2); return getOrCreateLeafDefault(Code.of(code2), LeafType.DESCRIPTION, USymbol.INTERFACE); } diff --git a/src/net/sourceforge/plantuml/descdiagram/command/CommandCreateElementFull.java b/src/net/sourceforge/plantuml/descdiagram/command/CommandCreateElementFull.java index 5bb8e9fd0..6b7416a44 100644 --- a/src/net/sourceforge/plantuml/descdiagram/command/CommandCreateElementFull.java +++ b/src/net/sourceforge/plantuml/descdiagram/command/CommandCreateElementFull.java @@ -116,7 +116,7 @@ public class CommandCreateElementFull extends SingleLineCommand2 lines) { StringUtils.trim(lines, false); - final RegexResult line0 = getStartingPattern().matcher(lines.get(0).trim()); + final RegexResult line0 = getStartingPattern().matcher(StringUtils.trin(lines.get(0))); final String symbol = StringUtils.goUpperCase(line0.get("TYPE", 0)); final LeafType type; final USymbol usymbol; diff --git a/src/net/sourceforge/plantuml/descdiagram/command/CommandLinkElement.java b/src/net/sourceforge/plantuml/descdiagram/command/CommandLinkElement.java index dfa8885b7..d1237d2df 100644 --- a/src/net/sourceforge/plantuml/descdiagram/command/CommandLinkElement.java +++ b/src/net/sourceforge/plantuml/descdiagram/command/CommandLinkElement.java @@ -167,7 +167,7 @@ public class CommandLinkElement extends SingleLineCommand2 { if (s == null) { return ""; } - return StringUtils.goLowerCase(s.trim()); + return StringUtils.goLowerCase(StringUtils.trin(s)); } private Direction getDirection(RegexResult arg) { @@ -213,7 +213,7 @@ public class CommandLinkElement extends SingleLineCommand2 { final Matcher m1 = p1.matcher(labelLink); if (m1.matches()) { firstLabel = m1.group(1); - labelLink = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(m1.group(2).trim()).trim(); + labelLink = StringUtils.trin(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(StringUtils.trin(m1.group(2)))); secondLabel = m1.group(3); return; } @@ -221,7 +221,7 @@ public class CommandLinkElement extends SingleLineCommand2 { final Matcher m2 = p2.matcher(labelLink); if (m2.matches()) { firstLabel = m2.group(1); - labelLink = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(m2.group(2).trim()).trim(); + labelLink = StringUtils.trin(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(StringUtils.trin(m2.group(2)))); secondLabel = null; return; } @@ -229,7 +229,7 @@ public class CommandLinkElement extends SingleLineCommand2 { final Matcher m3 = p3.matcher(labelLink); if (m3.matches()) { firstLabel = null; - labelLink = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(m3.group(1).trim()).trim(); + labelLink = StringUtils.trin(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(StringUtils.trin(m3.group(1)))); secondLabel = m3.group(2); } } @@ -286,7 +286,7 @@ public class CommandLinkElement extends SingleLineCommand2 { final String code = code2.getFullName(); if (code.startsWith("()")) { return diagram.getOrCreateLeaf( - Code.of(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(code.substring(2).trim())), + Code.of(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(StringUtils.trin(code.substring(2)))), LeafType.DESCRIPTION, USymbol.INTERFACE); } final char codeChar = code.length() > 2 ? code.charAt(0) : 0; diff --git a/src/net/sourceforge/plantuml/donors/PSystemDonors.java b/src/net/sourceforge/plantuml/donors/PSystemDonors.java index 9de967620..852796e78 100644 --- a/src/net/sourceforge/plantuml/donors/PSystemDonors.java +++ b/src/net/sourceforge/plantuml/donors/PSystemDonors.java @@ -58,19 +58,14 @@ import net.sourceforge.plantuml.version.PSystemVersion; public class PSystemDonors extends AbstractPSystem { - public static final String DONORS = "UDfTaikosZ0CXlTw2gypquT8IOTEu5pcqEcYEv7e41sCH6s7DddwYhR11gsiqUtx9TU--cyKu9KI1LTBKc7iu1jLsVG4MyrkY50lfRY7TSWXcc17Uuo9KTop3WArz1hSMYdDT7s-lrl6aeu2Mom6IOA65uSzrBcrNc0tPeG9rbpTcoYq2-KOOPVeF92ubUhPz3NB78gmEJsKQe2LUXRtfcCaQCU7UFMX9cHnpWnF1JMUIjT6rPv-e_IspjN0rlM0OJAbRpVPSe3daZxDyEBvOWKDTqSZlqLOu4kyjPO2eg8BDFE9KvZS5WVj4ThhqdyCQEsBl8fyFfVPSR8r2IRBCpxZQl_1q_5EbVHtxjzAjaRUobv2uXc-vd2lyCJTGDvzHlPJgS3F9KoCZsWjeNngiVivKdJDk0zef_LP_dVzIDGDRXCmOaOwaFtOue2_hX_DKjn6Bmn_0C5QlDy0"; - - // public ImageData exportDiagram(OutputStream os, int num, FileFormatOption - // fileFormat) throws IOException { - // return getGraphicStrings().exportDiagram(os, fileFormat); - // } + public static final String DONORS = "UDfTaisIsZ0Cn-zw2fypquT8IOTEO7SxIwU7taIY9LgCH6s7DddwYcs33JfPew_VNrRjg_z60RvHek1gIIgC7NodAfkUOAlP3H7gfHJti0uvH1FiQ8ynCOfxra6Wbbw3MokbcQxFjpVBMD9HO8l584dGyEAmXpgtrWlinemmmPghUnE5Tg4S8-mIdGSIjr8zcxvccKCHDgU7KWsmKi_YNdMC1Etu4A_UrOGipfdXgQ36K-dQgDhJ7vJUrhaQsBeUC4oczFKcMmxmNDAd6LuyNwoWuUvevBS82to9jzPIG5HqWMO-SGgJs-AWFK9xNVhF0QrzaLUHpzzbTfniJOB9yepFkDf_y7IyKoNzdVjHoTR8MzbBI3p3rnpk5Pwu6yYxpyX-AXNukOI9yH6j9PHFBNQ_Hegk6VS1xMjzblz3tnDrWzi4Z9YH3cGNMtpWx-kXMOhRw8NBk_cudB-jFS1F"; public ImageData exportDiagram(OutputStream os, int num, FileFormatOption fileFormat) throws IOException { final GraphicStrings result = getGraphicStrings(); final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, result.getBackcolor(), getMetadata(), null, 0, 0, null, false); imageBuilder.addUDrawable(result); - return imageBuilder.writeImageTOBEMOVED(fileFormat.getFileFormat(), os); + return imageBuilder.writeImageTOBEMOVED(fileFormat, os); } private GraphicStrings getGraphicStrings() throws IOException { diff --git a/src/net/sourceforge/plantuml/eggs/PSystemAppleTwo.java b/src/net/sourceforge/plantuml/eggs/PSystemAppleTwo.java index b12cb4614..3efcbc21f 100644 --- a/src/net/sourceforge/plantuml/eggs/PSystemAppleTwo.java +++ b/src/net/sourceforge/plantuml/eggs/PSystemAppleTwo.java @@ -76,7 +76,7 @@ public class PSystemAppleTwo extends AbstractPSystem { final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, result.getBackcolor(), getMetadata(), null, 0, 0, null, false); imageBuilder.addUDrawable(result); - return imageBuilder.writeImageTOBEMOVED(fileFormat.getFileFormat(), os); + return imageBuilder.writeImageTOBEMOVED(fileFormat, os); } private GraphicStrings getGraphicStrings() throws IOException { diff --git a/src/net/sourceforge/plantuml/eggs/PSystemCharlie.java b/src/net/sourceforge/plantuml/eggs/PSystemCharlie.java index 45c978154..fff24c295 100644 --- a/src/net/sourceforge/plantuml/eggs/PSystemCharlie.java +++ b/src/net/sourceforge/plantuml/eggs/PSystemCharlie.java @@ -66,7 +66,7 @@ public class PSystemCharlie extends AbstractPSystem { ug.draw(im); } }); - return imageBuilder.writeImageTOBEMOVED(fileFormat.getFileFormat(), os); + return imageBuilder.writeImageTOBEMOVED(fileFormat, os); } public DiagramDescription getDescription() { diff --git a/src/net/sourceforge/plantuml/eggs/PSystemEgg.java b/src/net/sourceforge/plantuml/eggs/PSystemEgg.java index 5b8c8e4b6..1b02ade54 100644 --- a/src/net/sourceforge/plantuml/eggs/PSystemEgg.java +++ b/src/net/sourceforge/plantuml/eggs/PSystemEgg.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 15848 $ + * Revision $Revision: 16021 $ * */ package net.sourceforge.plantuml.eggs; @@ -68,7 +68,7 @@ public class PSystemEgg extends AbstractPSystem { final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, result.getBackcolor(), getMetadata(), null, 0, 0, null, false); imageBuilder.addUDrawable(result); - return imageBuilder.writeImageTOBEMOVED(fileFormat.getFileFormat(), os); + return imageBuilder.writeImageTOBEMOVED(fileFormat, os); } private GraphicStrings getGraphicStrings() throws IOException { diff --git a/src/net/sourceforge/plantuml/eggs/PSystemLost.java b/src/net/sourceforge/plantuml/eggs/PSystemLost.java index f6e8dbaae..c8afd0c8e 100644 --- a/src/net/sourceforge/plantuml/eggs/PSystemLost.java +++ b/src/net/sourceforge/plantuml/eggs/PSystemLost.java @@ -64,7 +64,7 @@ public class PSystemLost extends AbstractPSystem { final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, result.getBackcolor(), getMetadata(), null, 0, 0, null, false); imageBuilder.addUDrawable(result); - return imageBuilder.writeImageTOBEMOVED(fileFormat.getFileFormat(), os); + return imageBuilder.writeImageTOBEMOVED(fileFormat, os); } private GraphicStrings getGraphicStrings() throws IOException { diff --git a/src/net/sourceforge/plantuml/eggs/PSystemRIP.java b/src/net/sourceforge/plantuml/eggs/PSystemRIP.java index 5f45d36d6..8d1e7ece7 100644 --- a/src/net/sourceforge/plantuml/eggs/PSystemRIP.java +++ b/src/net/sourceforge/plantuml/eggs/PSystemRIP.java @@ -85,7 +85,7 @@ public class PSystemRIP extends AbstractPSystem { final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, result.getBackcolor(), getMetadata(), null, 0, 0, null, false); imageBuilder.addUDrawable(result); - return imageBuilder.writeImageTOBEMOVED(fileFormat.getFileFormat(), os); + return imageBuilder.writeImageTOBEMOVED(fileFormat, os); } diff --git a/src/net/sourceforge/plantuml/font/PSystemListFonts.java b/src/net/sourceforge/plantuml/font/PSystemListFonts.java index e94dd0a80..5dbf5c6ae 100644 --- a/src/net/sourceforge/plantuml/font/PSystemListFonts.java +++ b/src/net/sourceforge/plantuml/font/PSystemListFonts.java @@ -76,7 +76,7 @@ public class PSystemListFonts extends AbstractPSystem { final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, result.getBackcolor(), getMetadata(), null, 0, 0, null, false); imageBuilder.addUDrawable(result); - return imageBuilder.writeImageTOBEMOVED(fileFormat.getFileFormat(), os); + return imageBuilder.writeImageTOBEMOVED(fileFormat, os); } private GraphicStrings getGraphicStrings() throws IOException { diff --git a/src/net/sourceforge/plantuml/font/PSystemListFontsFactory.java b/src/net/sourceforge/plantuml/font/PSystemListFontsFactory.java index dbc12be2f..8c8e92b53 100644 --- a/src/net/sourceforge/plantuml/font/PSystemListFontsFactory.java +++ b/src/net/sourceforge/plantuml/font/PSystemListFontsFactory.java @@ -45,7 +45,7 @@ public class PSystemListFontsFactory extends PSystemSingleLineFactory { if (lineLower.equals("listfont") || lineLower.equals("listfonts") || lineLower.startsWith("listfont ") || lineLower.startsWith("listfonts ")) { final int idx = line.indexOf(' '); - return new PSystemListFonts(idx == -1 ? "This is a test" : line.substring(idx).trim()); + return new PSystemListFonts(idx == -1 ? "This is a test" : StringUtils.trin(line.substring(idx))); } return null; } diff --git a/src/net/sourceforge/plantuml/graphic/FontFamilyChange.java b/src/net/sourceforge/plantuml/graphic/FontFamilyChange.java index 668b27ecd..8a6ca2fe4 100644 --- a/src/net/sourceforge/plantuml/graphic/FontFamilyChange.java +++ b/src/net/sourceforge/plantuml/graphic/FontFamilyChange.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.graphic; import java.util.regex.Matcher; import java.util.regex.Pattern; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.command.regex.MyPattern; class FontFamilyChange implements FontChange { @@ -49,7 +50,7 @@ class FontFamilyChange implements FontChange { if (matcherColor.find() == false) { throw new IllegalArgumentException(); } - this.family = matcherColor.group(1).trim(); + this.family = StringUtils.trin(matcherColor.group(1)); } public FontConfiguration apply(FontConfiguration initial) { diff --git a/src/net/sourceforge/plantuml/graphic/QuoteUtils.java b/src/net/sourceforge/plantuml/graphic/QuoteUtils.java index f1df1c826..69bcf0790 100644 --- a/src/net/sourceforge/plantuml/graphic/QuoteUtils.java +++ b/src/net/sourceforge/plantuml/graphic/QuoteUtils.java @@ -145,9 +145,20 @@ public class QuoteUtils { "If you are a friend, you speak the password, and the doors will open.", // "You Shall Not Pass", // "73.6% Of All Statistics Are Made Up", // - "We can neither confirm nor deny that this is crashing" - // When the beating of your heart echoes the beating of the drums - // Never trust a computer you can't throw out a window + "We can neither confirm nor deny that this is crashing", // + "When the beating of your heart echoes the beating of the drums", // + "Never trust a computer you can't throw out a window", // + "Yeah, I'm calm. I'm a calm person. Is there some reason I shouldn't be calm?", // + "Everybody just stay calm. The situation is under control.", // + "Hippy, you think everything is a conspiracy.", // + "These guys are about as much fun as a tax audit.", // + "There is something down there! Something not us.", // + "I saw a glimpse of my future and everything's changed for me now.", // + "In space no one can hear you scream", // + "I can't lie to you about your chances, but... you have my sympathies.", // + "There is an explanation for this, you know.", // + "Bishop: I'm afraid I have some bad news.", // + "Do me a favour. Disconnect me. I could be reworked, but I'll never be top of the line again." ); private QuoteUtils() { } diff --git a/src/net/sourceforge/plantuml/graphic/SpriteCommand.java b/src/net/sourceforge/plantuml/graphic/SpriteCommand.java index ce96e8a70..eb117aac8 100644 --- a/src/net/sourceforge/plantuml/graphic/SpriteCommand.java +++ b/src/net/sourceforge/plantuml/graphic/SpriteCommand.java @@ -33,6 +33,8 @@ */ package net.sourceforge.plantuml.graphic; +import net.sourceforge.plantuml.StringUtils; + public class SpriteCommand implements HtmlCommand { private final String sprite; @@ -47,7 +49,7 @@ public class SpriteCommand implements HtmlCommand { if (sprite.endsWith(">") == false) { throw new IllegalArgumentException(); } - this.sprite = sprite.substring(2, sprite.length() - 1).trim(); + this.sprite = StringUtils.trin(sprite.substring(2, sprite.length() - 1)); } public String getSprite() { diff --git a/src/net/sourceforge/plantuml/jcckit/PSystemJcckitFactory.java b/src/net/sourceforge/plantuml/jcckit/PSystemJcckitFactory.java index 0bcf72c60..dcd00c21d 100644 --- a/src/net/sourceforge/plantuml/jcckit/PSystemJcckitFactory.java +++ b/src/net/sourceforge/plantuml/jcckit/PSystemJcckitFactory.java @@ -40,6 +40,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import net.sourceforge.plantuml.Log; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.command.PSystemBasicFactory; import net.sourceforge.plantuml.command.regex.MyPattern; import net.sourceforge.plantuml.core.DiagramType; @@ -108,7 +109,7 @@ public class PSystemJcckitFactory extends PSystemBasicFactory { if (data == null) { return null; } - data.append(line.trim()); + data.append(StringUtils.trin(line)); data.append("\n"); return createSystem(); } diff --git a/src/net/sourceforge/plantuml/jungle/PSystemTree.java b/src/net/sourceforge/plantuml/jungle/PSystemTree.java index 8f9bfe5a0..4dc251eb4 100644 --- a/src/net/sourceforge/plantuml/jungle/PSystemTree.java +++ b/src/net/sourceforge/plantuml/jungle/PSystemTree.java @@ -73,7 +73,7 @@ public class PSystemTree extends AbstractPSystem { } else { builder.addUDrawable(new GTileOneLevelFactory().createGTile(root)); } - return builder.writeImageTOBEMOVED(fileFormat.getFileFormat(), os); + return builder.writeImageTOBEMOVED(fileFormat, os); } public CommandExecutionResult addParagraph(int level, String label) { diff --git a/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObjectMultilines.java b/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObjectMultilines.java index a28817aeb..bbae5c7c6 100644 --- a/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObjectMultilines.java +++ b/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObjectMultilines.java @@ -79,7 +79,7 @@ public class CommandCreateEntityObjectMultilines extends CommandMultilines2 lines) { StringUtils.trim(lines, true); - final RegexResult line0 = getStartingPattern().matcher(lines.get(0).trim()); + final RegexResult line0 = getStartingPattern().matcher(StringUtils.trin(lines.get(0))); final IEntity entity = executeArg0(diagram, line0); if (entity == null) { return CommandExecutionResult.error("No such entity"); diff --git a/src/net/sourceforge/plantuml/openiconic/PSystemListOpenIconic.java b/src/net/sourceforge/plantuml/openiconic/PSystemListOpenIconic.java index 8e8c19ec9..705d15b21 100644 --- a/src/net/sourceforge/plantuml/openiconic/PSystemListOpenIconic.java +++ b/src/net/sourceforge/plantuml/openiconic/PSystemListOpenIconic.java @@ -62,7 +62,7 @@ public class PSystemListOpenIconic extends AbstractPSystem { final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, result.getBackcolor(), getMetadata(), null, 0, 0, null, false); imageBuilder.addUDrawable(result); - return imageBuilder.writeImageTOBEMOVED(fileFormat.getFileFormat(), os); + return imageBuilder.writeImageTOBEMOVED(fileFormat, os); } private GraphicStrings getGraphicStrings() throws IOException { diff --git a/src/net/sourceforge/plantuml/openiconic/PSystemOpenIconic.java b/src/net/sourceforge/plantuml/openiconic/PSystemOpenIconic.java index fef4c1ee9..9ee896bea 100644 --- a/src/net/sourceforge/plantuml/openiconic/PSystemOpenIconic.java +++ b/src/net/sourceforge/plantuml/openiconic/PSystemOpenIconic.java @@ -62,7 +62,7 @@ public class PSystemOpenIconic extends AbstractPSystem { final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, null, null, null, 5, 5, null, false); imageBuilder.addUDrawable(icon.asTextBlock(HtmlColorUtils.BLACK, factor)); - return imageBuilder.writeImageTOBEMOVED(fileFormat.getFileFormat(), os); + return imageBuilder.writeImageTOBEMOVED(fileFormat, os); // UGraphic2 ug = fileFormat.createUGraphic(dim); // ug = (UGraphic2) ug.apply(new UTranslate(10, 10)); diff --git a/src/net/sourceforge/plantuml/oregon/PSystemOregon.java b/src/net/sourceforge/plantuml/oregon/PSystemOregon.java index fafcbb995..ba2abac3d 100644 --- a/src/net/sourceforge/plantuml/oregon/PSystemOregon.java +++ b/src/net/sourceforge/plantuml/oregon/PSystemOregon.java @@ -101,7 +101,7 @@ public class PSystemOregon extends AbstractPSystem { final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, result.getBackcolor(), getMetadata(), null, 0, 0, null, false); imageBuilder.addUDrawable(result); - return imageBuilder.writeImageTOBEMOVED(fileFormat.getFileFormat(), os); + return imageBuilder.writeImageTOBEMOVED(fileFormat, os); } private GraphicStrings getGraphicStrings() throws IOException { diff --git a/src/net/sourceforge/plantuml/project/PSystemProject.java b/src/net/sourceforge/plantuml/project/PSystemProject.java index 6555e3267..ff2b3cc0e 100644 --- a/src/net/sourceforge/plantuml/project/PSystemProject.java +++ b/src/net/sourceforge/plantuml/project/PSystemProject.java @@ -78,7 +78,7 @@ public class PSystemProject extends AbstractPSystem { final BufferedImage im = createImage(diagram); PngIO.write(im, os, fileFormatOption.isWithMetadata() ? getMetadata() : null, 96); } else if (fileFormat == FileFormat.SVG) { - final UGraphicSvg svg = new UGraphicSvg(colorMapper, StringUtils.getAsHtml(background), false, 1.0); + final UGraphicSvg svg = new UGraphicSvg(colorMapper, StringUtils.getAsHtml(background), false, 1.0, fileFormatOption.getSvgLinkTarget()); diagram.draw(svg, 0, 0); svg.createXml(os); } else if (fileFormat == FileFormat.EPS) { diff --git a/src/net/sourceforge/plantuml/project/Project.java b/src/net/sourceforge/plantuml/project/Project.java index ba0a16c42..d5441bb62 100644 --- a/src/net/sourceforge/plantuml/project/Project.java +++ b/src/net/sourceforge/plantuml/project/Project.java @@ -84,7 +84,7 @@ public class Project { } public Expression getExpression(String desc) { - desc = desc.trim(); + desc = StringUtils.trin(desc); final int plus = desc.indexOf('+'); if (plus != -1) { diff --git a/src/net/sourceforge/plantuml/project/command/CommandAffectation.java b/src/net/sourceforge/plantuml/project/command/CommandAffectation.java index 70c8b4126..9510f1b6f 100644 --- a/src/net/sourceforge/plantuml/project/command/CommandAffectation.java +++ b/src/net/sourceforge/plantuml/project/command/CommandAffectation.java @@ -35,6 +35,7 @@ package net.sourceforge.plantuml.project.command; import java.util.List; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand; import net.sourceforge.plantuml.project.Expression; @@ -48,8 +49,8 @@ public class CommandAffectation extends SingleLineCommand { @Override protected CommandExecutionResult executeArg(PSystemProject diagram, List arg) { - final Expression exp = diagram.getProject().getExpression(arg.get(1).trim()); - final boolean ok = diagram.getProject().affectation(arg.get(0).trim(), exp); + final Expression exp = diagram.getProject().getExpression(StringUtils.trin(arg.get(1))); + final boolean ok = diagram.getProject().affectation(StringUtils.trin(arg.get(0)), exp); if (ok) { return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/project2/Knowledge.java b/src/net/sourceforge/plantuml/project2/Knowledge.java index 6ee8fc452..c0359c6ff 100644 --- a/src/net/sourceforge/plantuml/project2/Knowledge.java +++ b/src/net/sourceforge/plantuml/project2/Knowledge.java @@ -36,6 +36,8 @@ package net.sourceforge.plantuml.project2; import java.util.HashMap; import java.util.Map; +import net.sourceforge.plantuml.StringUtils; + public class Knowledge { private final TaskContainer taskContainer; @@ -48,7 +50,7 @@ public class Knowledge { } public Value evaluate(String exp) { - exp = exp.trim(); + exp = StringUtils.trin(exp); int idx = exp.indexOf('$'); if (idx != -1) { return evaluate(exp.substring(0, idx), exp.substring(idx + 1)); diff --git a/src/net/sourceforge/plantuml/project2/PSystemProject2.java b/src/net/sourceforge/plantuml/project2/PSystemProject2.java index 848d8a43d..e498eb954 100644 --- a/src/net/sourceforge/plantuml/project2/PSystemProject2.java +++ b/src/net/sourceforge/plantuml/project2/PSystemProject2.java @@ -77,7 +77,7 @@ public class PSystemProject2 extends AbstractPSystem { final BufferedImage im = createImage(diagram); PngIO.write(im, os, fileFormatOption.isWithMetadata() ? getMetadata() : null, 96); } else if (fileFormat == FileFormat.SVG) { - final UGraphicSvg svg = new UGraphicSvg(colorMapper, StringUtils.getAsHtml(background), false, 1.0); + final UGraphicSvg svg = new UGraphicSvg(colorMapper, StringUtils.getAsHtml(background), false, 1.0, fileFormatOption.getSvgLinkTarget()); diagram.draw(svg, 0, 0); svg.createXml(os); } else if (fileFormat == FileFormat.EPS) { diff --git a/src/net/sourceforge/plantuml/project2/command/CommandAffectation.java b/src/net/sourceforge/plantuml/project2/command/CommandAffectation.java index 563a95dec..2fd3b40c2 100644 --- a/src/net/sourceforge/plantuml/project2/command/CommandAffectation.java +++ b/src/net/sourceforge/plantuml/project2/command/CommandAffectation.java @@ -35,6 +35,7 @@ package net.sourceforge.plantuml.project2.command; import java.util.List; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand; import net.sourceforge.plantuml.project2.PSystemProject2; @@ -48,8 +49,8 @@ public class CommandAffectation extends SingleLineCommand { @Override protected CommandExecutionResult executeArg(PSystemProject2 diagram, List arg) { - final Value exp = diagram.getProject().getExpression(arg.get(1).trim()); - final boolean ok = diagram.getProject().affectation(arg.get(0).trim(), exp); + final Value exp = diagram.getProject().getExpression(StringUtils.trin(arg.get(1))); + final boolean ok = diagram.getProject().affectation(StringUtils.trin(arg.get(0)), exp); if (ok) { return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/real/AbstractReal.java b/src/net/sourceforge/plantuml/real/AbstractReal.java new file mode 100644 index 000000000..b6a380d93 --- /dev/null +++ b/src/net/sourceforge/plantuml/real/AbstractReal.java @@ -0,0 +1,65 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2014, Arnaud Roques + * + * Project Info: http://plantuml.sourceforge.net + * + * 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. + * + * [Java is a trademark or registered trademark of Sun Microsystems, Inc. + * in the United States and other countries.] + * + * Original Author: Arnaud Roques + * + * Revision $Revision: 4636 $ + * + */ +package net.sourceforge.plantuml.real; + + +abstract class AbstractReal implements Real { + + private final RealLine line; + + AbstractReal(RealLine line) { + this.line = line; + } + + final RealLine getLine() { + return line; + } + + abstract double getCurrentValueInternal(); + + final public double getCurrentValue() { + final double result = getCurrentValueInternal(); + line.register(result); + return result; + } + + public Real getMaxAbsolute() { + return line.asMaxAbsolute(); + } + + public Real getMinAbsolute() { + return line.asMinAbsolute(); + } + +} diff --git a/src/net/sourceforge/plantuml/real/PositiveForce.java b/src/net/sourceforge/plantuml/real/PositiveForce.java index 795115e38..24622d57a 100644 --- a/src/net/sourceforge/plantuml/real/PositiveForce.java +++ b/src/net/sourceforge/plantuml/real/PositiveForce.java @@ -38,6 +38,8 @@ class PositiveForce { private final Real fixedPoint; private final RealMoveable movingPoint; private final double minimunDistance; + private final boolean trace = false; + private final Throwable creationPoint; public PositiveForce(Real fixedPoint, RealMoveable movingPoint, double minimunDistance) { if (fixedPoint == movingPoint) { @@ -46,6 +48,8 @@ class PositiveForce { this.fixedPoint = fixedPoint; this.movingPoint = movingPoint; this.minimunDistance = minimunDistance; + this.creationPoint = new Throwable(); + this.creationPoint.fillInStackTrace(); } @Override @@ -54,12 +58,32 @@ class PositiveForce { } public boolean apply() { - final double distance = movingPoint.getCurrentValue() - fixedPoint.getCurrentValue(); + if (trace) { + System.err.println("apply " + this); + } + final double movingPointValue = movingPoint.getCurrentValue(); + final double fixedPointValue; + try { + fixedPointValue = fixedPoint.getCurrentValue(); + } catch (IllegalStateException e) { + System.err.println("Pb with force " + this); + System.err.println("This force has been created here:"); + creationPoint.printStackTrace(); + System.err.println("The fixed point has been created here: " + fixedPoint); + fixedPoint.printCreationStackTrace(); + throw e; + } + final double distance = movingPointValue - fixedPointValue; final double diff = distance - minimunDistance; if (diff >= 0) { + if (trace) { + System.err.println("Not using "); + } return false; } - // System.err.println("moving " + (-diff) + " " + movingPoint); + if (trace) { + System.err.println("moving " + (-diff) + " " + movingPoint); + } movingPoint.move(-diff); return true; } diff --git a/src/net/sourceforge/plantuml/real/Real.java b/src/net/sourceforge/plantuml/real/Real.java index e9db15aa8..3cea6f384 100644 --- a/src/net/sourceforge/plantuml/real/Real.java +++ b/src/net/sourceforge/plantuml/real/Real.java @@ -35,6 +35,8 @@ package net.sourceforge.plantuml.real; public interface Real { + public void printCreationStackTrace(); + public String getName(); public double getCurrentValue(); @@ -45,6 +47,8 @@ public interface Real { public void ensureBiggerThan(Real other); - public void compile(); + public Real getMaxAbsolute(); + + public Real getMinAbsolute(); } diff --git a/src/net/sourceforge/plantuml/real/RealDelta.java b/src/net/sourceforge/plantuml/real/RealDelta.java index a675226a7..90dd45a45 100644 --- a/src/net/sourceforge/plantuml/real/RealDelta.java +++ b/src/net/sourceforge/plantuml/real/RealDelta.java @@ -39,12 +39,13 @@ class RealDelta extends RealMoveable { private final double diff; RealDelta(Real delegated, double diff) { - super("[Delegated {" + delegated.getName() + "} d=" + diff + "]"); + super(((AbstractReal) delegated).getLine(), "[Delegated {" + delegated.getName() + "} d=" + diff + "]"); this.delegated = delegated; this.diff = diff; } - public double getCurrentValue() { + @Override + double getCurrentValueInternal() { return delegated.getCurrentValue() + diff; } @@ -54,19 +55,10 @@ class RealDelta extends RealMoveable { public void ensureBiggerThan(Real other) { delegated.ensureBiggerThan(new RealDelta(other, -diff)); - - } - - public void compile() { - delegated.compile(); } void move(double delta) { ((RealMoveable) delegated).move(delta); } - RealLine getLine() { - return ((RealMoveable) delegated).getLine(); - } - } diff --git a/src/net/sourceforge/plantuml/real/RealImpl.java b/src/net/sourceforge/plantuml/real/RealImpl.java index a8acbebd7..f23a4a765 100644 --- a/src/net/sourceforge/plantuml/real/RealImpl.java +++ b/src/net/sourceforge/plantuml/real/RealImpl.java @@ -33,14 +33,12 @@ */ package net.sourceforge.plantuml.real; -class RealImpl extends RealMoveable { +class RealImpl extends RealMoveable implements RealOrigin { - private final RealLine line; private double currentValue; public RealImpl(String name, RealLine line, double currentValue) { - super(name); - this.line = line; + super(line, name); this.currentValue = currentValue; } @@ -48,26 +46,22 @@ class RealImpl extends RealMoveable { this.currentValue += delta; } - public double getCurrentValue() { + @Override + double getCurrentValueInternal() { return currentValue; } public Real addAtLeast(double delta) { - final RealImpl result = new RealImpl(getName() + ".addAtLeast" + delta, line, this.currentValue + delta); - line.addForce(new PositiveForce(this, result, delta)); + final RealImpl result = new RealImpl(getName() + ".addAtLeast" + delta, getLine(), this.currentValue + delta); + getLine().addForce(new PositiveForce(this, result, delta)); return result; } public void ensureBiggerThan(Real other) { - line.addForce(new PositiveForce(other, this, 0)); + getLine().addForce(new PositiveForce(other, this, 0)); } - public void compile() { - line.compile(); + public void compileNow() { + getLine().compile(); } - - RealLine getLine() { - return line; - } - } diff --git a/src/net/sourceforge/plantuml/real/RealLine.java b/src/net/sourceforge/plantuml/real/RealLine.java index 88c45a236..8a3547dc2 100644 --- a/src/net/sourceforge/plantuml/real/RealLine.java +++ b/src/net/sourceforge/plantuml/real/RealLine.java @@ -34,12 +34,30 @@ package net.sourceforge.plantuml.real; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; class RealLine { private final List forces = new ArrayList(); + private double min; + private double max; + + void register(double v) { + min = Math.min(min, v); + max = Math.max(max, v); + } + + public double getAbsoluteMin() { + return min; + } + + public double getAbsoluteMax() { + return max; + } + public void addForce(PositiveForce force) { this.forces.add(force); } @@ -48,12 +66,14 @@ class RealLine { public void compile() { int cpt = 0; + final Map counter = new HashMap(); do { boolean done = true; for (PositiveForce f : forces) { // System.err.println("force=" + f); final boolean change = f.apply(); if (change) { + incCounter(counter, f); // System.err.println("changed! " + f); done = false; } @@ -66,10 +86,73 @@ class RealLine { } cpt++; if (cpt > 99999) { + printCounter(counter); throw new IllegalStateException("Inifinite Loop?"); } } while (true); } + private void printCounter(Map counter) { + for (Map.Entry ent : counter.entrySet()) { + System.err.println("count=" + ent.getValue() + " for " + ent.getKey()); + } + } + + private static void incCounter(Map counter, PositiveForce f) { + final Integer v = counter.get(f); + counter.put(f, v == null ? 1 : v + 1); + } + + Real asMaxAbsolute() { + return new MaxAbsolute(); + } + + Real asMinAbsolute() { + return new MinAbsolute(); + } + + class MaxAbsolute extends AbstractAbsolute { + public double getCurrentValue() { + return max; + } + } + + class MinAbsolute extends AbstractAbsolute { + public double getCurrentValue() { + return min; + } + } + + abstract class AbstractAbsolute implements Real { + + public void printCreationStackTrace() { + } + + public String getName() { + return getClass().getName(); + } + + public Real addFixed(double delta) { + throw new UnsupportedOperationException(); + } + + public Real addAtLeast(double delta) { + throw new UnsupportedOperationException(); + } + + public void ensureBiggerThan(Real other) { + throw new UnsupportedOperationException(); + } + + public Real getMaxAbsolute() { + return asMaxAbsolute(); + } + + public Real getMinAbsolute() { + return asMinAbsolute(); + } + + } + } diff --git a/src/net/sourceforge/plantuml/real/RealMax.java b/src/net/sourceforge/plantuml/real/RealMax.java index 0a39bde43..94b039c0c 100644 --- a/src/net/sourceforge/plantuml/real/RealMax.java +++ b/src/net/sourceforge/plantuml/real/RealMax.java @@ -34,29 +34,42 @@ package net.sourceforge.plantuml.real; import java.util.ArrayList; +import java.util.Collection; import java.util.List; -public class RealMax implements Real { +class RealMax extends AbstractReal implements Real { private final List all = new ArrayList(); + private final Throwable creationPoint; - public void put(Real real) { - if (real == null) { - throw new IllegalArgumentException(); - } - if (real == this) { - return; - } - all.add(real); + RealMax(Collection reals) { + super(line(reals)); + this.all.addAll(reals); + this.creationPoint = new Throwable(); + this.creationPoint.fillInStackTrace(); + } + + static RealLine line(Collection reals) { + return ((AbstractReal) reals.iterator().next()).getLine(); } public String getName() { return "max " + all; } - public double getCurrentValue() { + @Override + double getCurrentValueInternal() { double result = all.get(0).getCurrentValue(); for (int i = 1; i < all.size(); i++) { + Throwable t = new Throwable(); + t.fillInStackTrace(); + final int stackLength = t.getStackTrace().length; + if (stackLength > 1000) { + System.err.println("The faulty RealMax " + getName()); + System.err.println("has been created here:"); + printCreationStackTrace(); + throw new IllegalStateException("Infinite recursion?"); + } final double v = all.get(i).getCurrentValue(); if (v > result) { result = v; @@ -74,11 +87,11 @@ public class RealMax implements Real { } public void ensureBiggerThan(Real other) { - all.add(other); + throw new UnsupportedOperationException(); } - public void compile() { - all.get(0).compile(); + public void printCreationStackTrace() { + creationPoint.printStackTrace(); } } diff --git a/src/net/sourceforge/plantuml/real/RealMiddle.java b/src/net/sourceforge/plantuml/real/RealMiddle.java index 5e5941d6b..5b49c2461 100644 --- a/src/net/sourceforge/plantuml/real/RealMiddle.java +++ b/src/net/sourceforge/plantuml/real/RealMiddle.java @@ -33,13 +33,14 @@ */ package net.sourceforge.plantuml.real; -class RealMiddle implements Real { +class RealMiddle extends AbstractReal implements Real { private final RealMoveable p1; private final RealMoveable p2; private final double delta; private RealMiddle(RealMoveable p1, RealMoveable p2, double delta) { + super(p1.getLine()); this.p1 = p1; this.p2 = p2; this.delta = delta; @@ -49,7 +50,8 @@ class RealMiddle implements Real { this(p1, p2, 0); } - public double getCurrentValue() { + @Override + double getCurrentValueInternal() { return (p1.getCurrentValue() + p2.getCurrentValue()) / 2 + delta; } @@ -65,12 +67,12 @@ class RealMiddle implements Real { throw new UnsupportedOperationException(); } - public void compile() { - p1.compile(); - } - public String getName() { return "[Middle " + p1.getName() + " and " + p2.getName() + "]"; } + public void printCreationStackTrace() { + throw new UnsupportedOperationException(); + } + } diff --git a/src/net/sourceforge/plantuml/sequencediagram/ParticipantEngloberContexted.java b/src/net/sourceforge/plantuml/real/RealMiddle2.java similarity index 54% rename from src/net/sourceforge/plantuml/sequencediagram/ParticipantEngloberContexted.java rename to src/net/sourceforge/plantuml/real/RealMiddle2.java index 5878064b8..285d1df74 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/ParticipantEngloberContexted.java +++ b/src/net/sourceforge/plantuml/real/RealMiddle2.java @@ -28,50 +28,44 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 4836 $ + * Revision $Revision: 4636 $ * */ -package net.sourceforge.plantuml.sequencediagram; +package net.sourceforge.plantuml.real; -import java.util.ArrayList; -import java.util.List; +class RealMiddle2 extends RealMoveable { -public class ParticipantEngloberContexted { + private final RealMoveable p1; + private final RealMoveable p2; - final private ParticipantEnglober participantEnglober; - final private List participants = new ArrayList(); - - public ParticipantEngloberContexted(ParticipantEnglober participantEnglober, Participant first) { - this.participantEnglober = participantEnglober; - this.participants.add(first); + RealMiddle2(RealMoveable p1, RealMoveable p2) { + super(p1.getLine(), "middle"); + assert p1.getLine() == p2.getLine(); + this.p1 = p1; + this.p2 = p2; } - public final ParticipantEnglober getParticipantEnglober() { - return participantEnglober; - } - - public boolean contains(Participant p) { - return participants.contains(p); - } - - public void add(Participant p) { - if (participants.contains(p)) { - throw new IllegalArgumentException(); - } - participants.add(p); - } - - public final Participant getFirst2() { - return participants.get(0); - } - - public final Participant getLast2() { - return participants.get(participants.size() - 1); - } - @Override - public String toString() { - return super.toString()+" "+participants; + double getCurrentValueInternal() { + return (p1.getCurrentValue() + p2.getCurrentValue()) / 2; + } + + // public Real addFixed(double diff) { + // return new RealMiddle2(p1, p2, delta + diff); + // } + + public Real addAtLeast(double delta) { + throw new UnsupportedOperationException(); + } + + public void ensureBiggerThan(Real other) { + getLine().addForce(new PositiveForce(other, this, 0)); + } + + @Override + void move(double delta) { + p1.move(delta / 2); + p2.move(delta / 2); } } diff --git a/src/net/sourceforge/plantuml/real/RealMin.java b/src/net/sourceforge/plantuml/real/RealMin.java index 3e1b77f33..d6e15762a 100644 --- a/src/net/sourceforge/plantuml/real/RealMin.java +++ b/src/net/sourceforge/plantuml/real/RealMin.java @@ -34,27 +34,24 @@ package net.sourceforge.plantuml.real; import java.util.ArrayList; +import java.util.Collection; import java.util.List; -public class RealMin implements Real { +class RealMin extends AbstractReal implements Real { private final List all = new ArrayList(); - public void put(Real real) { - if (real == null) { - throw new IllegalArgumentException(); - } - if (real == this) { - return; - } - all.add(real); + RealMin(Collection reals) { + super(RealMax.line(reals)); + this.all.addAll(reals); } public String getName() { return "min " + all; } - public double getCurrentValue() { + @Override + double getCurrentValueInternal() { double result = all.get(0).getCurrentValue(); for (int i = 1; i < all.size(); i++) { final double v = all.get(i).getCurrentValue(); @@ -74,15 +71,17 @@ public class RealMin implements Real { } public void ensureBiggerThan(Real other) { - throw new UnsupportedOperationException(); - } - - public void compile() { - all.get(0).compile(); + for (Real r : all) { + r.ensureBiggerThan(other); + } } public int size() { return all.size(); } + public void printCreationStackTrace() { + throw new UnsupportedOperationException(); + } + } diff --git a/src/net/sourceforge/plantuml/real/RealMoveable.java b/src/net/sourceforge/plantuml/real/RealMoveable.java index 7c8a0613e..4d3218abb 100644 --- a/src/net/sourceforge/plantuml/real/RealMoveable.java +++ b/src/net/sourceforge/plantuml/real/RealMoveable.java @@ -33,29 +33,38 @@ */ package net.sourceforge.plantuml.real; -abstract class RealMoveable implements Real { +import java.util.concurrent.atomic.AtomicInteger; +abstract class RealMoveable extends AbstractReal implements Real { + + public static final AtomicInteger CPT = new AtomicInteger(); + private final int cpt = CPT.getAndIncrement(); private final String name; + private final Throwable creationPoint; - RealMoveable(String name) { + RealMoveable(RealLine line, String name) { + super(line); this.name = name; + this.creationPoint = new Throwable(); + this.creationPoint.fillInStackTrace(); } abstract void move(double delta); - abstract RealLine getLine(); + final public void printCreationStackTrace() { + creationPoint.printStackTrace(); + } final public Real addFixed(double delta) { return new RealDelta(this, delta); } @Override - public String toString() { - return name; + public final String toString() { + return "#" + cpt + "_" + name; } final public String getName() { return name; } - } diff --git a/src/net/sourceforge/plantuml/real/RealOrigin.java b/src/net/sourceforge/plantuml/real/RealOrigin.java new file mode 100644 index 000000000..509d69f5e --- /dev/null +++ b/src/net/sourceforge/plantuml/real/RealOrigin.java @@ -0,0 +1,39 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2014, Arnaud Roques + * + * Project Info: http://plantuml.sourceforge.net + * + * 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. + * + * [Java is a trademark or registered trademark of Sun Microsystems, Inc. + * in the United States and other countries.] + * + * Original Author: Arnaud Roques + * + * Revision $Revision: 4636 $ + * + */ +package net.sourceforge.plantuml.real; + +public interface RealOrigin extends Real { + + public void compileNow(); +} diff --git a/src/net/sourceforge/plantuml/real/RealUtils.java b/src/net/sourceforge/plantuml/real/RealUtils.java index 51753221d..7e67145cc 100644 --- a/src/net/sourceforge/plantuml/real/RealUtils.java +++ b/src/net/sourceforge/plantuml/real/RealUtils.java @@ -33,26 +33,34 @@ */ package net.sourceforge.plantuml.real; -import java.util.List; +import java.util.Arrays; +import java.util.Collection; public class RealUtils { - public static Real createOrigin() { + public static RealOrigin createOrigin() { final RealLine line = new RealLine(); final RealImpl result = new RealImpl("O", line, 0); return result; } public static Real middle(Real r1, Real r2) { - return new RealMiddle((RealMoveable) r1, (RealMoveable) r2); + return new RealMiddle2((RealMoveable) r1, (RealMoveable) r2); } - // public static Real max(List all) { - // return new RealMax(all); - // } - // - // public static Real min(List all) { - // return new RealMin(all); - // } + public static Real max(Real... reals) { + return new RealMax(Arrays.asList(reals)); + } + public static Real max(Collection reals) { + return new RealMax(reals); + } + + public static Real min(Real... reals) { + return new RealMin(Arrays.asList(reals)); + } + + public static Real min(Collection reals) { + return new RealMin(reals); + } } diff --git a/src/net/sourceforge/plantuml/salt/DataSourceImpl.java b/src/net/sourceforge/plantuml/salt/DataSourceImpl.java index 8a8ab4eaa..8f55aa9cb 100644 --- a/src/net/sourceforge/plantuml/salt/DataSourceImpl.java +++ b/src/net/sourceforge/plantuml/salt/DataSourceImpl.java @@ -39,6 +39,7 @@ import java.util.StringTokenizer; import java.util.regex.Matcher; import java.util.regex.Pattern; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.command.regex.MyPattern; public class DataSourceImpl implements DataSource { @@ -51,7 +52,7 @@ public class DataSourceImpl implements DataSource { for (String s : data) { final StringTokenizer st = new StringTokenizer(s, "|}", true); while (st.hasMoreTokens()) { - final String token = st.nextToken().trim(); + final String token = StringUtils.trin(st.nextToken()); if (token.equals("|")) { continue; } @@ -82,7 +83,7 @@ public class DataSourceImpl implements DataSource { } private void addInternal(String s, Terminator t) { - s = s.trim(); + s = StringUtils.trin(s); if (s.length() > 0) { data.add(new Terminated(s, t)); } diff --git a/src/net/sourceforge/plantuml/salt/PSystemSalt.java b/src/net/sourceforge/plantuml/salt/PSystemSalt.java index f65afef88..6d55fc6ec 100644 --- a/src/net/sourceforge/plantuml/salt/PSystemSalt.java +++ b/src/net/sourceforge/plantuml/salt/PSystemSalt.java @@ -94,7 +94,7 @@ public class PSystemSalt extends AbstractPSystem { salt.drawU(ug, 1, new Dimension2DDouble(size.getWidth(), size.getHeight())); } }); - return builder.writeImageTOBEMOVED(fileFormat.getFileFormat(), os); + return builder.writeImageTOBEMOVED(fileFormat, os); } private ImageData exportDiagramOld(OutputStream os, int num, FileFormatOption fileFormat) throws IOException { diff --git a/src/net/sourceforge/plantuml/salt/PSystemSaltFactory.java b/src/net/sourceforge/plantuml/salt/PSystemSaltFactory.java index d32729466..046ed1aee 100644 --- a/src/net/sourceforge/plantuml/salt/PSystemSaltFactory.java +++ b/src/net/sourceforge/plantuml/salt/PSystemSaltFactory.java @@ -33,6 +33,7 @@ */ package net.sourceforge.plantuml.salt; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.command.PSystemBasicFactory; import net.sourceforge.plantuml.core.DiagramType; @@ -61,7 +62,7 @@ public class PSystemSaltFactory extends PSystemBasicFactory { if (system == null) { return null; } - system.add(line.trim()); + system.add(StringUtils.trin(line)); return system; } diff --git a/src/net/sourceforge/plantuml/salt/element/AbstractElementText.java b/src/net/sourceforge/plantuml/salt/element/AbstractElementText.java index 36d5f0ed3..a50ff4bc7 100644 --- a/src/net/sourceforge/plantuml/salt/element/AbstractElementText.java +++ b/src/net/sourceforge/plantuml/salt/element/AbstractElementText.java @@ -37,6 +37,7 @@ import java.awt.geom.Dimension2D; import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.ISkinSimple; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.HorizontalAlignment; @@ -58,7 +59,7 @@ abstract class AbstractElementText extends AbstractElement { config = new FontConfiguration(font, HtmlColorUtils.BLACK, HtmlColorUtils.BLUE, true); if (manageLength) { this.charLength = getCharNumber(text); - text = text.trim(); + text = StringUtils.trin(text); } else { this.charLength = 0; } diff --git a/src/net/sourceforge/plantuml/salt/element/ElementTree.java b/src/net/sourceforge/plantuml/salt/element/ElementTree.java index df674432d..d12a61fe6 100644 --- a/src/net/sourceforge/plantuml/salt/element/ElementTree.java +++ b/src/net/sourceforge/plantuml/salt/element/ElementTree.java @@ -41,14 +41,12 @@ import java.util.List; import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.ISkinSimple; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.graphic.HtmlColorSet; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.ugraphic.UChangeColor; import net.sourceforge.plantuml.ugraphic.UFont; import net.sourceforge.plantuml.ugraphic.UGraphic; -import net.sourceforge.plantuml.ugraphic.ULine; -import net.sourceforge.plantuml.ugraphic.URectangle; -import net.sourceforge.plantuml.ugraphic.UTranslate; public class ElementTree extends AbstractElement { @@ -70,14 +68,14 @@ public class ElementTree extends AbstractElement { level++; s = s.substring(1); } - final Element elmt = new ElementText(Arrays.asList(s.trim()), font, spriteContainer); + final Element elmt = new ElementText(Arrays.asList(StringUtils.trin(s)), font, spriteContainer); entries.add(new ElementTreeEntry(level, elmt)); } public void addCellToEntry(String s) { final int size = entries.size(); if (size > 0) { - final Element elmt = new ElementText(Arrays.asList(s.trim()), font, spriteContainer); + final Element elmt = new ElementText(Arrays.asList(StringUtils.trin(s)), font, spriteContainer); entries.get(size - 1).addCell(elmt); } } @@ -153,56 +151,4 @@ public class ElementTree extends AbstractElement { } } - static class Skeleton { - - private final List entries = new ArrayList(); - - static class Entry { - private final double xpos; - private final double ypos; - - public Entry(double x, double y) { - this.xpos = x; - this.ypos = y; - } - - public void drawRectangle(UGraphic ug) { - ug.apply(new UTranslate(xpos, ypos)).draw(new URectangle(2, 2)); - } - } - - public void add(double x, double y) { - entries.add(new Entry(x, y)); - } - - public void draw(UGraphic ug, double x, double y) { - for (int i = 0; i < entries.size(); i++) { - final Entry en = entries.get(i); - if (i + 1 < entries.size() && entries.get(i + 1).xpos > en.xpos) { - en.drawRectangle(ug); - } - Entry parent = null; - for (int j = 0; j < i; j++) { - final Entry en0 = entries.get(j); - if (en0.xpos < en.xpos) { - parent = en0; - } - } - if (parent != null) { - drawChild(ug, parent, en); - } - } - } - - private void drawChild(UGraphic ug, Entry parent, Entry child) { - final double dy = child.ypos - parent.ypos - 2; - ug.apply(new UTranslate(parent.xpos + 1, parent.ypos + 3)).draw(new ULine(0, dy)); - - final double dx = child.xpos - parent.xpos - 2; - ug.apply(new UTranslate(parent.xpos + 1, child.ypos + 1)).draw(new ULine(dx, 0)); - - } - - } - } diff --git a/src/net/sourceforge/plantuml/salt/element/Skeleton.java b/src/net/sourceforge/plantuml/salt/element/Skeleton.java new file mode 100644 index 000000000..bc1e6db4b --- /dev/null +++ b/src/net/sourceforge/plantuml/salt/element/Skeleton.java @@ -0,0 +1,94 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2014, Arnaud Roques + * + * Project Info: http://plantuml.sourceforge.net + * + * 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. + * + * [Java is a trademark or registered trademark of Sun Microsystems, Inc. + * in the United States and other countries.] + * + * Original Author: Arnaud Roques + * + * Revision $Revision: 3835 $ + * + */ +package net.sourceforge.plantuml.salt.element; + +import java.util.ArrayList; +import java.util.List; + +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.URectangle; +import net.sourceforge.plantuml.ugraphic.UTranslate; + +public class Skeleton { + + private final List entries = new ArrayList(); + + static class Entry { + private final double xpos; + private final double ypos; + + public Entry(double x, double y) { + this.xpos = x; + this.ypos = y; + } + + public void drawRectangle(UGraphic ug) { + ug.apply(new UTranslate(xpos, ypos)).draw(new URectangle(2, 2)); + } + } + + public void add(double x, double y) { + entries.add(new Entry(x, y)); + } + + public void draw(UGraphic ug, double x, double y) { + for (int i = 0; i < entries.size(); i++) { + final Entry en = entries.get(i); + if (i + 1 < entries.size() && entries.get(i + 1).xpos > en.xpos) { + en.drawRectangle(ug); + } + Entry parent = null; + for (int j = 0; j < i; j++) { + final Entry en0 = entries.get(j); + if (en0.xpos < en.xpos) { + parent = en0; + } + } + if (parent != null) { + drawChild(ug, parent, en); + } + } + } + + private void drawChild(UGraphic ug, Entry parent, Entry child) { + final double dy = child.ypos - parent.ypos - 2; + ug.apply(new UTranslate(parent.xpos + 1, parent.ypos + 3)).draw(new ULine(0, dy)); + + final double dx = child.xpos - parent.xpos - 2; + ug.apply(new UTranslate(parent.xpos + 1, child.ypos + 1)).draw(new ULine(dx, 0)); + + } + +} diff --git a/src/net/sourceforge/plantuml/salt/element/Skeleton2.java b/src/net/sourceforge/plantuml/salt/element/Skeleton2.java new file mode 100644 index 000000000..de04a0ecf --- /dev/null +++ b/src/net/sourceforge/plantuml/salt/element/Skeleton2.java @@ -0,0 +1,132 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2014, Arnaud Roques + * + * Project Info: http://plantuml.sourceforge.net + * + * 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. + * + * [Java is a trademark or registered trademark of Sun Microsystems, Inc. + * in the United States and other countries.] + * + * Original Author: Arnaud Roques + * + * Revision $Revision: 3835 $ + * + */ +package net.sourceforge.plantuml.salt.element; + +import java.util.ArrayList; +import java.util.List; + +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.ULine; +import net.sourceforge.plantuml.ugraphic.URectangle; +import net.sourceforge.plantuml.ugraphic.UTranslate; + +public class Skeleton2 { + + private final List entries = new ArrayList(); + private static final double sizeX = 8; + + static class Entry { + private final int level; + private final double ypos; + + Entry(int level, double y) { + System.err.println("level=" + level); + this.level = level; + this.ypos = y; + } + + void drawHline(UGraphic ug) { + final double xpos = getXStartForLevel(level); + ug.apply(new UTranslate(xpos + sizeX - 1, ypos - 1)).draw(new URectangle(2, 2)); + ug.apply(new UTranslate(xpos, ypos)).draw(new ULine(sizeX, 0)); + } + + public void drawVline(UGraphic ug, double lastY) { + System.err.println("ypos=" + ypos); + final double xpos = getXStartForLevel(level); + ug.apply(new UTranslate(xpos, lastY)).draw(new ULine(0, ypos - lastY)); + } + } + + public void add(int level, double y) { + entries.add(new Entry(level, y)); + } + + public void draw(UGraphic ug) { + for (int i = 0; i < entries.size(); i++) { + final Entry en = entries.get(i); + en.drawHline(ug); + final Entry up = getMotherOrSister(i); + en.drawVline(ug, up == null ? 0 : up.ypos); + } + } + + private Entry getMotherOrSister(int idx) { + final int currentLevel = entries.get(idx).level; + for (int i = idx - 1; i >= 0; i--) { + final int otherLevel = entries.get(i).level; + if (otherLevel == currentLevel || otherLevel == currentLevel - 1) { + return entries.get(i); + } + } + return null; + } + + private static double getXStartForLevel(int level) { + return level * sizeX; + } + + public double getXEndForLevel(int level) { + return getXStartForLevel(level) + sizeX; + } + + // public void drawOld(UGraphic ug, double x, double y) { + // for (int i = 0; i < entries.size(); i++) { + // final Entry en = entries.get(i); + // if (i + 1 < entries.size() && entries.get(i + 1).xpos > en.xpos) { + // en.drawRectangle(ug); + // } + // Entry parent = null; + // for (int j = 0; j < i; j++) { + // final Entry en0 = entries.get(j); + // if (en0.xpos < en.xpos) { + // parent = en0; + // } + // } + // if (parent != null) { + // drawChild(ug, parent, en); + // } + // } + // } + // + // private void drawChild(UGraphic ug, Entry parent, Entry child) { + // final double dy = child.ypos - parent.ypos - 2; + // ug.apply(new UTranslate(parent.xpos + 1, parent.ypos + 3)).draw(new ULine(0, dy)); + // + // final double dx = child.xpos - parent.xpos - 2; + // ug.apply(new UTranslate(parent.xpos + 1, child.ypos + 1)).draw(new ULine(dx, 0)); + // + // } + +} diff --git a/src/net/sourceforge/plantuml/salt/factory/ElementFactoryCheckboxOff.java b/src/net/sourceforge/plantuml/salt/factory/ElementFactoryCheckboxOff.java index 578574325..bb18560bb 100644 --- a/src/net/sourceforge/plantuml/salt/factory/ElementFactoryCheckboxOff.java +++ b/src/net/sourceforge/plantuml/salt/factory/ElementFactoryCheckboxOff.java @@ -38,6 +38,7 @@ import java.util.Arrays; import java.util.List; import net.sourceforge.plantuml.ISkinSimple; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.salt.DataSource; import net.sourceforge.plantuml.salt.Terminated; import net.sourceforge.plantuml.salt.element.Element; @@ -67,7 +68,7 @@ public class ElementFactoryCheckboxOff implements ElementFactory { private List extracted(final String text) { final int x = text.indexOf(']'); - return Arrays.asList(text.substring(x + 1).trim()); + return Arrays.asList(StringUtils.trin(text.substring(x + 1))); } public boolean ready() { diff --git a/src/net/sourceforge/plantuml/salt/factory/ElementFactoryCheckboxOn.java b/src/net/sourceforge/plantuml/salt/factory/ElementFactoryCheckboxOn.java index bb211fb2c..b6f8815a9 100644 --- a/src/net/sourceforge/plantuml/salt/factory/ElementFactoryCheckboxOn.java +++ b/src/net/sourceforge/plantuml/salt/factory/ElementFactoryCheckboxOn.java @@ -38,6 +38,7 @@ import java.util.Arrays; import java.util.List; import net.sourceforge.plantuml.ISkinSimple; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.salt.DataSource; import net.sourceforge.plantuml.salt.Terminated; import net.sourceforge.plantuml.salt.element.Element; @@ -67,7 +68,7 @@ public class ElementFactoryCheckboxOn implements ElementFactory { private List extracted(final String text) { final int x = text.indexOf(']'); - return Arrays.asList(text.substring(x + 1).trim()); + return Arrays.asList(StringUtils.trin(text.substring(x + 1))); } public boolean ready() { diff --git a/src/net/sourceforge/plantuml/salt/factory/ElementFactoryRadioOff.java b/src/net/sourceforge/plantuml/salt/factory/ElementFactoryRadioOff.java index a4a5d6534..f5a10cd24 100644 --- a/src/net/sourceforge/plantuml/salt/factory/ElementFactoryRadioOff.java +++ b/src/net/sourceforge/plantuml/salt/factory/ElementFactoryRadioOff.java @@ -38,6 +38,7 @@ import java.util.Arrays; import java.util.List; import net.sourceforge.plantuml.ISkinSimple; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.salt.DataSource; import net.sourceforge.plantuml.salt.Terminated; import net.sourceforge.plantuml.salt.element.Element; @@ -67,7 +68,7 @@ public class ElementFactoryRadioOff implements ElementFactory { private List extracted(final String text) { final int x = text.indexOf(')'); - return Arrays.asList(text.substring(x + 1).trim()); + return Arrays.asList(StringUtils.trin(text.substring(x + 1))); } public boolean ready() { diff --git a/src/net/sourceforge/plantuml/salt/factory/ElementFactoryRadioOn.java b/src/net/sourceforge/plantuml/salt/factory/ElementFactoryRadioOn.java index 82ebc2b3a..e91091c9c 100644 --- a/src/net/sourceforge/plantuml/salt/factory/ElementFactoryRadioOn.java +++ b/src/net/sourceforge/plantuml/salt/factory/ElementFactoryRadioOn.java @@ -38,6 +38,7 @@ import java.util.Arrays; import java.util.List; import net.sourceforge.plantuml.ISkinSimple; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.salt.DataSource; import net.sourceforge.plantuml.salt.Terminated; import net.sourceforge.plantuml.salt.element.Element; @@ -67,7 +68,7 @@ public class ElementFactoryRadioOn implements ElementFactory { private List extracted(final String text) { final int x = text.indexOf(')'); - return Arrays.asList(text.substring(x + 1).trim()); + return Arrays.asList(StringUtils.trin(text.substring(x + 1))); } public boolean ready() { diff --git a/src/net/sourceforge/plantuml/salt/factory/ElementFactoryText.java b/src/net/sourceforge/plantuml/salt/factory/ElementFactoryText.java index 615dc16d6..f3c2d9bb1 100644 --- a/src/net/sourceforge/plantuml/salt/factory/ElementFactoryText.java +++ b/src/net/sourceforge/plantuml/salt/factory/ElementFactoryText.java @@ -37,7 +37,7 @@ import java.awt.Font; import java.util.Arrays; import net.sourceforge.plantuml.ISkinSimple; -import net.sourceforge.plantuml.SpriteContainer; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.salt.DataSource; import net.sourceforge.plantuml.salt.Terminated; import net.sourceforge.plantuml.salt.element.Element; @@ -71,7 +71,7 @@ public class ElementFactoryText implements ElementFactory { if (text.startsWith("{") || text.startsWith("}")) { return false; } - return text.trim().length() > 0; + return StringUtils.trin(text).length() > 0; } } diff --git a/src/net/sourceforge/plantuml/sequencediagram/AbstractMessage.java b/src/net/sourceforge/plantuml/sequencediagram/AbstractMessage.java index 0ba2005a7..9a7bf4fa8 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/AbstractMessage.java +++ b/src/net/sourceforge/plantuml/sequencediagram/AbstractMessage.java @@ -137,6 +137,17 @@ public abstract class AbstractMessage implements EventWithDeactivate { public final Display getLabel() { return label; } + + public final Display getLabelNumbered() { + if (getMessageNumber() == null) { + return getLabel(); + } + Display result = Display.empty(); + result = result.add(new MessageNumber(getMessageNumber())); + result = result.addAll(getLabel()); + return result; + } + public final ArrowConfiguration getArrowConfiguration() { return arrowConfiguration; diff --git a/src/net/sourceforge/plantuml/sequencediagram/Englober.java b/src/net/sourceforge/plantuml/sequencediagram/Englober.java new file mode 100644 index 000000000..666529728 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/Englober.java @@ -0,0 +1,197 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2014, Arnaud Roques + * + * Project Info: http://plantuml.sourceforge.net + * + * 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. + * + * [Java is a trademark or registered trademark of Sun Microsystems, Inc. + * in the United States and other countries.] + * + * Original Author: Arnaud Roques + * + * Revision $Revision: 4836 $ + * + */ +package net.sourceforge.plantuml.sequencediagram; + +import java.util.ArrayList; +import java.util.List; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.SkinParamBackcolored; +import net.sourceforge.plantuml.graphic.TextBlockUtils; +import net.sourceforge.plantuml.real.Real; +import net.sourceforge.plantuml.real.RealUtils; +import net.sourceforge.plantuml.sequencediagram.teoz.LivingSpace; +import net.sourceforge.plantuml.sequencediagram.teoz.TileArguments; +import net.sourceforge.plantuml.skin.Area; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.ComponentType; +import net.sourceforge.plantuml.skin.Context2D; +import net.sourceforge.plantuml.skin.Skin; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.UTranslate; + +public class Englober { + + final private ParticipantEnglober participantEnglober; + final private List participants = new ArrayList(); + final private TileArguments tileArguments; + final private Real core1; + final private Real core2; + + @Deprecated + public Englober(ParticipantEnglober participantEnglober, Participant first, ISkinParam skinParam, Skin skin) { + this(participantEnglober, first, convertFunctionToBeRemoved(skinParam, skin)); + } + + private static TileArguments convertFunctionToBeRemoved(ISkinParam skinParam, Skin skin) { + final TileArguments result = new TileArguments(TextBlockUtils.getDummyStringBounder(), null, null, skin, + skinParam, null); + return result; + } + + public Englober(ParticipantEnglober participantEnglober, Participant first, TileArguments tileArguments) { + if (tileArguments == null) { + throw new IllegalArgumentException(); + } + this.participantEnglober = participantEnglober; + this.participants.add(first); + this.tileArguments = tileArguments; + final double preferredWidth = getPreferredWidth(); + if (tileArguments.getLivingSpaces() == null) { + this.core1 = null; + this.core2 = null; + } else { + this.core1 = getMiddle().addFixed(-preferredWidth / 2); + this.core2 = getMiddle().addFixed(preferredWidth / 2); + } + } + + public final Participant getFirst2TOBEPRIVATE() { + return participants.get(0); + } + + public final Participant getLast2TOBEPRIVATE() { + return participants.get(participants.size() - 1); + } + + private Real getMiddle() { + return RealUtils.middle(getPosB(), getPosD()); + } + + private Real getPosB() { + return getFirstLivingSpace().getPosB(); + } + + private Real getPosD() { + return getLastLivingSpace().getPosD(tileArguments.getStringBounder()); + } + + private Real getPosAA() { + final LivingSpace previous = tileArguments.getLivingSpaces().previous(getFirstLivingSpace()); + if (previous == null) { + return tileArguments.getOrigin(); + } + return previous.getPosD(tileArguments.getStringBounder()); + } + + private Real getPosZZ() { + final LivingSpace next = tileArguments.getLivingSpaces().next(getLastLivingSpace()); + if (next == null) { + return tileArguments.getOmega(); + } + return next.getPosB(); + } + + private LivingSpace getFirstLivingSpace() { + return tileArguments.getLivingSpace(getFirst2TOBEPRIVATE()); + } + + private LivingSpace getLastLivingSpace() { + return tileArguments.getLivingSpace(getLast2TOBEPRIVATE()); + } + + private Component getComponent() { + final ParticipantEnglober englober = getParticipantEnglober(); + final ISkinParam s = englober.getBoxColor() == null ? tileArguments.getSkinParam() : new SkinParamBackcolored( + tileArguments.getSkinParam(), englober.getBoxColor()); + return tileArguments.getSkin().createComponent(ComponentType.ENGLOBER, null, s, englober.getTitle()); + } + + public final ParticipantEnglober getParticipantEnglober() { + return participantEnglober; + } + + public boolean contains(Participant p) { + return participants.contains(p); + } + + public void add(Participant p) { + if (participants.contains(p)) { + throw new IllegalArgumentException(); + } + participants.add(p); + } + + @Override + public String toString() { + return "ParticipantEngloberContexted:" + participantEnglober.getTitle().toString() + " " + participants; + } + + private double getPreferredWidth() { + return getComponent().getPreferredWidth(tileArguments.getStringBounder()); + } + + public double getPreferredHeight() { + final Component comp = tileArguments.getSkin().createComponent(ComponentType.ENGLOBER, null, + tileArguments.getSkinParam(), getParticipantEnglober().getTitle()); + return comp.getPreferredHeight(tileArguments.getStringBounder()); + } + + public void drawEnglober(UGraphic ug, double height, Context2D context) { + final double x1 = getX1().getCurrentValue() - 4; + final double x2 = getX2().getCurrentValue() + 4; + + final Dimension2DDouble dim = new Dimension2DDouble(x2 - x1, height); + getComponent().drawU(ug.apply(new UTranslate(x1, 1)), new Area(dim), context); + } + + private Real getX2() { + return RealUtils.max(getPosD(), core2); + } + + private Real getX1() { + return RealUtils.min(getPosB(), core1); + } + + public void addInternalConstraints() { + getX1().ensureBiggerThan(getPosAA().addFixed(10)); + getPosZZ().ensureBiggerThan(getX2().addFixed(10)); + } + + public void addConstraintAfter(Englober current) { + current.getX1().ensureBiggerThan(getX2().addFixed(10)); + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/SequenceDiagram.java b/src/net/sourceforge/plantuml/sequencediagram/SequenceDiagram.java index f2abe7cc0..d8a7b2cea 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/SequenceDiagram.java +++ b/src/net/sourceforge/plantuml/sequencediagram/SequenceDiagram.java @@ -69,7 +69,8 @@ public class SequenceDiagram extends UmlDiagram { private final Map participantEnglobers2 = new HashMap(); - private Skin skin = new ProtectedSkin(new Rose()); + private final Skin skinInitial = new ProtectedSkin(new Rose()); + private Skin skin2 = new ProtectedSkin(new Rose()); @Deprecated public Participant getOrCreateParticipant(String code) { @@ -195,11 +196,15 @@ public class SequenceDiagram extends UmlDiagram { return new SequenceDiagramTxtMaker(this, fileFormat); } - if (OptionFlags.FORCE_TEOZ || getPragma().useTeozLayout()) { - return new SequenceDiagramFileMakerTeoz(this, skin, fileFormatOption); + if (modeTeoz()) { + return new SequenceDiagramFileMakerTeoz(this, getSkin2(), fileFormatOption); } - return new SequenceDiagramFileMakerPuma2(this, skin, fileFormatOption); + return new SequenceDiagramFileMakerPuma2(this, getSkin2(), fileFormatOption); + } + + private boolean modeTeoz() { + return OptionFlags.FORCE_TEOZ || getPragma().useTeozLayout(); } @Override @@ -286,14 +291,17 @@ public class SequenceDiagram extends UmlDiagram { final Skin s = SkinUtils.loadSkin(className); final Integer expected = new Integer(1); if (s != null && expected.equals(s.getProtocolVersion())) { - this.skin = new ProtectedSkin(s); + this.skin2 = new ProtectedSkin(s); return true; } return false; } - public Skin getSkin() { - return skin; + private Skin getSkin2() { + if (modeTeoz()) { + return skinInitial; + } + return skin2; } private Integer messageNumber = null; @@ -364,7 +372,12 @@ public class SequenceDiagram extends UmlDiagram { @Override public int getNbImages() { - return getSequenceDiagramPngMaker(new FileFormatOption(FileFormat.PNG)).getNbPages(); + try { + return getSequenceDiagramPngMaker(new FileFormatOption(FileFormat.PNG)).getNbPages(); + } catch (Throwable t) { + t.printStackTrace(); + return 1; + } } public void removeHiddenParticipants() { diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandReferenceMultilinesOverSeveral.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandReferenceMultilinesOverSeveral.java index 531bc0150..2bc84763c 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandReferenceMultilinesOverSeveral.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandReferenceMultilinesOverSeveral.java @@ -61,7 +61,7 @@ public class CommandReferenceMultilinesOverSeveral extends CommandMultilines lines) { - final List line0 = StringUtils.getSplit(getStartingPattern(), lines.get(0).trim()); + final List line0 = StringUtils.getSplit(getStartingPattern(), StringUtils.trin(lines.get(0))); final HtmlColor backColorElement = diagram.getSkinParam().getIHtmlColorSet().getColorIfValid(line0.get(0)); // final HtmlColor backColorGeneral = HtmlColorSet.getInstance().getColorIfValid(line0.get(1)); diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandReferenceOverSeveral.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandReferenceOverSeveral.java index e0fb6c7d9..cfe126eea 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandReferenceOverSeveral.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandReferenceOverSeveral.java @@ -74,7 +74,7 @@ public class CommandReferenceOverSeveral extends SingleLineCommand2 participants = StringUtils.splitComma(arg.get("PARTS", 0)); final String url = arg.get("URL", 0); final String title = arg.get("URL", 1); - final String text = arg.get("TEXT", 0).trim(); + final String text = StringUtils.trin(arg.get("TEXT", 0)); final List p = new ArrayList(); for (String s : participants) { diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/DrawableSet.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/DrawableSet.java index 140f9b419..2aa2fe70b 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/DrawableSet.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/DrawableSet.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 15886 $ + * Revision $Revision: 16175 $ * */ package net.sourceforge.plantuml.sequencediagram.graphic; @@ -52,7 +52,7 @@ import net.sourceforge.plantuml.sequencediagram.Event; import net.sourceforge.plantuml.sequencediagram.Newpage; import net.sourceforge.plantuml.sequencediagram.Participant; import net.sourceforge.plantuml.sequencediagram.ParticipantEnglober; -import net.sourceforge.plantuml.sequencediagram.ParticipantEngloberContexted; +import net.sourceforge.plantuml.sequencediagram.Englober; import net.sourceforge.plantuml.skin.Area; import net.sourceforge.plantuml.skin.Component; import net.sourceforge.plantuml.skin.ComponentType; @@ -138,7 +138,7 @@ public class DrawableSet { public double getHeadAndEngloberHeight(Participant p, StringBounder stringBounder) { final LivingParticipantBox box = participants.get(p); final double height = box.getParticipantBox().getHeadHeight(stringBounder); - final ParticipantEngloberContexted englober = getParticipantEnglober(p); + final Englober englober = getParticipantEnglober(p); if (englober == null) { return height; } @@ -148,9 +148,9 @@ public class DrawableSet { return height + heightEnglober; } - public List getExistingParticipantEnglober() { - final List result = new ArrayList(); - ParticipantEngloberContexted pending = null; + public List getExistingParticipantEnglober() { + final List result = new ArrayList(); + Englober pending = null; for (Map.Entry ent : participantEnglobers2.entrySet()) { final ParticipantEnglober englober = ent.getValue(); if (englober == null) { @@ -162,7 +162,7 @@ public class DrawableSet { pending.add(ent.getKey()); continue; } - pending = new ParticipantEngloberContexted(englober, ent.getKey()); + pending = new Englober(englober, ent.getKey(), getSkinParam(), skin); result.add(pending); } return Collections.unmodifiableList(result); @@ -170,7 +170,7 @@ public class DrawableSet { public double getOffsetForEnglobers(StringBounder stringBounder) { double result = 0; - for (ParticipantEngloberContexted englober : getExistingParticipantEnglober()) { + for (Englober englober : getExistingParticipantEnglober()) { final Component comp = skin.createComponent(ComponentType.ENGLOBER, null, skinParam, englober .getParticipantEnglober().getTitle()); final double height = comp.getPreferredHeight(stringBounder); @@ -238,26 +238,6 @@ public class DrawableSet { return dimension; } - void drawU_REMOVEDME_4243(UGraphic ug, final double delta, double width, Page page, boolean showTail) { - - final UGraphic ugOrig = ug; - - final int height = (int) page.getHeight(); - - ug = clipAndTranslate2(delta, width, page, ug); - final SimpleContext2D context = new SimpleContext2D(true); - this.drawPlaygroundU(ug, context); - ug = ugOrig; - - this.drawEnglobers(ug, height - MARGIN_FOR_ENGLOBERS1, context); - - this.drawLineU_REMOVEDME_4243(ug, showTail, page); - this.drawHeadTailU(ug, page, showTail ? height - getTailHeight(ug.getStringBounder(), true) : 0); - - ug = clipAndTranslate2(delta, width, page, ug); - this.drawPlaygroundU(ug, new SimpleContext2D(false)); - } - void drawU22(final UGraphic ug, final double delta, double width, Page page, boolean showTail) { // final UGraphic ugOrig = ug; final double height = page.getHeight(); @@ -303,26 +283,6 @@ public class DrawableSet { } } - private void drawLineU_REMOVEDME_4243(UGraphic ug, boolean showTail, Page page) { - for (LivingParticipantBox box : getAllLivingParticipantBox()) { - final double create = box.getCreate(); - final double startMin = page.getBodyRelativePosition() - box.magicMargin(ug.getStringBounder()); - // final double endMax = page.getHeight() - 1; - final double endMax = startMin + page.getBodyHeight() + 2 * box.magicMargin(ug.getStringBounder()); - double start = startMin; - if (create > 0) { - if (create > page.getNewpage2()) { - continue; - } - if (create >= page.getNewpage1() && create < page.getNewpage2()) { - start += create - page.getNewpage1() + 2 * box.magicMargin(ug.getStringBounder()); - } - } - final double myDelta = page.getNewpage1() - page.getHeaderHeight(); - box.drawLineUTOBEREMOVED_4243(ug, start, endMax, showTail, myDelta); - } - } - private void drawHeadTailU(UGraphic ug, Page page, double positionTail) { for (Map.Entry ent : participants.entrySet()) { final Participant p = ent.getKey(); @@ -367,7 +327,7 @@ public class DrawableSet { } private void drawEnglobers(UGraphic ug, double height, Context2D context) { - for (ParticipantEngloberContexted englober : getExistingParticipantEnglober()) { + for (Englober englober : getExistingParticipantEnglober()) { double x1 = getX1(englober); final double x2 = getX2(ug.getStringBounder(), englober); @@ -399,14 +359,14 @@ public class DrawableSet { return skin.createComponent(ComponentType.ENGLOBER, null, s, englober.getTitle()); } - public double getX1(ParticipantEngloberContexted englober) { - final Participant first = englober.getFirst2(); + public double getX1(Englober englober) { + final Participant first = englober.getFirst2TOBEPRIVATE(); final ParticipantBox firstBox = participants.get(first).getParticipantBox(); return firstBox.getStartingX() + 1; } - public double getX2(StringBounder stringBounder, ParticipantEngloberContexted englober) { - final Participant last = englober.getLast2(); + public double getX2(StringBounder stringBounder, Englober englober) { + final Participant last = englober.getLast2TOBEPRIVATE(); final ParticipantBox lastBox = participants.get(last).getParticipantBox(); return lastBox.getMaxX(stringBounder) - 1; } @@ -418,8 +378,8 @@ public class DrawableSet { line.drawU(ug, getSkin(), skinParam); } - private ParticipantEngloberContexted getParticipantEnglober(Participant p) { - for (ParticipantEngloberContexted pe : getExistingParticipantEnglober()) { + private Englober getParticipantEnglober(Participant p) { + for (Englober pe : getExistingParticipantEnglober()) { if (pe.contains(p)) { return pe; } diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/DrawableSetInitializer.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/DrawableSetInitializer.java index aa876542c..bcb3fa4f3 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/DrawableSetInitializer.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/DrawableSetInitializer.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 16005 $ + * Revision $Revision: 16156 $ * */ package net.sourceforge.plantuml.sequencediagram.graphic; @@ -62,7 +62,7 @@ import net.sourceforge.plantuml.sequencediagram.NoteStyle; import net.sourceforge.plantuml.sequencediagram.Notes; import net.sourceforge.plantuml.sequencediagram.Participant; import net.sourceforge.plantuml.sequencediagram.ParticipantEnglober; -import net.sourceforge.plantuml.sequencediagram.ParticipantEngloberContexted; +import net.sourceforge.plantuml.sequencediagram.Englober; import net.sourceforge.plantuml.sequencediagram.ParticipantType; import net.sourceforge.plantuml.sequencediagram.Reference; import net.sourceforge.plantuml.skin.Component; @@ -206,11 +206,11 @@ class DrawableSetInitializer { } private void takeParticipantEngloberTitleWidth3(StringBounder stringBounder) { - for (ParticipantEngloberContexted pe : drawableSet.getExistingParticipantEnglober()) { + for (Englober pe : drawableSet.getExistingParticipantEnglober()) { final double preferredWidth = drawableSet.getEngloberPreferedWidth(stringBounder, pe.getParticipantEnglober()); - final ParticipantBox first = drawableSet.getLivingParticipantBox(pe.getFirst2()).getParticipantBox(); - final ParticipantBox last = drawableSet.getLivingParticipantBox(pe.getLast2()).getParticipantBox(); + final ParticipantBox first = drawableSet.getLivingParticipantBox(pe.getFirst2TOBEPRIVATE()).getParticipantBox(); + final ParticipantBox last = drawableSet.getLivingParticipantBox(pe.getLast2TOBEPRIVATE()).getParticipantBox(); final double x1 = drawableSet.getX1(pe); final double x2 = drawableSet.getX2(stringBounder, pe); final double missing = preferredWidth - (x2 - x1); diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/LivingParticipantBox.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/LivingParticipantBox.java index 97e8b1192..fec51d6b1 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/LivingParticipantBox.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/LivingParticipantBox.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 15886 $ + * Revision $Revision: 16028 $ * */ package net.sourceforge.plantuml.sequencediagram.graphic; @@ -72,17 +72,6 @@ public class LivingParticipantBox implements InGroupable { return new SegmentColored(centerX - left, centerX + right, null, lifeLine.shadowing()); } - public void drawLineUTOBEREMOVED_4243(UGraphic ug, double startingY, double endingY, boolean showTail, double myDelta) { - if (endingY <= startingY) { - return; - } - final double destroy = lifeLine.getDestroy(); - if (destroy != 0 && destroy > startingY && destroy < endingY) { - endingY = destroy; - } - participantBox.drawLineUTOBEREMOVED_4243(ug, startingY, endingY, showTail, myDelta); - } - public void drawLineU22(UGraphic ug, double startingY, double endingY, boolean showTail, double myDelta) { if (endingY <= startingY) { return; diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/Segment.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/Segment.java index d3afc6fe1..49394797e 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/Segment.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/Segment.java @@ -44,7 +44,7 @@ public class Segment { final private double pos1; final private double pos2; - Segment(double pos1, double pos2) { + public Segment(double pos1, double pos2) { this.pos1 = pos1; this.pos2 = pos2; if (pos2 < pos1) { diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/SequenceDiagramFileMakerPuma2.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/SequenceDiagramFileMakerPuma2.java index 554da2ab1..9fc6a4596 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/SequenceDiagramFileMakerPuma2.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/SequenceDiagramFileMakerPuma2.java @@ -227,7 +227,7 @@ public class SequenceDiagramFileMakerPuma2 implements FileMaker { } }); - return imageBuilder.writeImageTOBEMOVED(fileFormatOption.getFileFormat(), os); + return imageBuilder.writeImageTOBEMOVED(fileFormatOption, os); } private double oneOf(double a, double b) { diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1Abstract.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1Abstract.java index 9e1086556..dc9bae3ac 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1Abstract.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1Abstract.java @@ -81,17 +81,6 @@ abstract class Step1Abstract { abstract Frontier prepareMessage(ConstraintSet constraintSet, InGroupablesStack groupingStructures); - protected final Display getLabelOfMessage(AbstractMessage message) { - if (message.getMessageNumber() == null) { - return message.getLabel(); - } - Display result = Display.empty(); - result = result.add(new MessageNumber(message.getMessageNumber())); - result = result.addAll(message.getLabel()); - return result; - } - - protected final ArrowConfiguration getConfig() { return config; } diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1Message.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1Message.java index 7f9829314..ea64f684b 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1Message.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1Message.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 16005 $ + * Revision $Revision: 16018 $ * */ package net.sourceforge.plantuml.sequencediagram.graphic; @@ -63,7 +63,7 @@ class Step1Message extends Step1Abstract { this.messageArrow = null; } else { final Component comp = drawingSet.getSkin().createComponent(ComponentType.ARROW, getConfig(), - drawingSet.getSkinParam(), getLabelOfMessage(message)); + drawingSet.getSkinParam(), message.getLabelNumbered()); final Component compAliveBox = drawingSet.getSkin().createComponent(ComponentType.ALIVE_BOX_OPEN_OPEN, null, drawingSet.getSkinParam(), null); @@ -189,7 +189,7 @@ class Step1Message extends Step1Abstract { } return new MessageSelfArrow(posY, getDrawingSet().getSkin(), getDrawingSet().getSkin().createComponent( - ComponentType.ARROW, getConfig(), getDrawingSet().getSkinParam(), getLabelOfMessage(getMessage())), + ComponentType.ARROW, getConfig(), getDrawingSet().getSkinParam(), getMessage().getLabelNumbered()), getLivingParticipantBox1(), deltaY, getMessage().getUrl(), deltaX); } diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1MessageExo.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1MessageExo.java index 1604e1883..15eafb468 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1MessageExo.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/Step1MessageExo.java @@ -56,7 +56,7 @@ class Step1MessageExo extends Step1Abstract { this.messageArrow = new MessageExoArrow(freeY.getFreeY(range), drawingSet.getSkin(), drawingSet.getSkin() .createComponent(ComponentType.ARROW, getConfig(), drawingSet.getSkinParam(), - getLabelOfMessage(message)), getLivingParticipantBox(), message.getType(), message.getUrl(), + message.getLabelNumbered()), getLivingParticipantBox(), message.getType(), message.getUrl(), message.isShortArrow(), message.getArrowConfiguration()); if (message.getNote() != null) { @@ -108,16 +108,6 @@ class Step1MessageExo extends Step1Abstract { return getDrawingSet().getLivingParticipantBox(((MessageExo) getMessage()).getParticipant()); } - private Display getLabelOfMessage(MessageExo message) { - if (message.getMessageNumber() == null) { - return message.getLabel(); - } - Display result = Display.empty(); - result = result.add(new MessageNumber(message.getMessageNumber())); - result = result.addAll(message.getLabel()); - return result; - } - private Arrow createArrow() { if (getMessage().getNote() == null) { return messageArrow; diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationExoTile.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationExoTile.java index afb80c87b..6e327350b 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationExoTile.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationExoTile.java @@ -56,21 +56,19 @@ public class CommunicationExoTile implements TileWithUpdateStairs { private final MessageExo message; private final Skin skin; private final ISkinParam skinParam; - private final Real alpha; - private final Real omega; + private final TileArguments tileArguments; public Event getEvent() { return message; } public CommunicationExoTile(LivingSpace livingSpace, MessageExo message, Skin skin, ISkinParam skinParam, - Real alpha, Real omega) { + TileArguments tileArguments) { + this.tileArguments = tileArguments; this.livingSpace = livingSpace; this.message = message; this.skin = skin; this.skinParam = skinParam; - this.alpha = alpha; - this.omega = omega; } private Component getComponent(StringBounder stringBounder) { @@ -87,8 +85,16 @@ public class CommunicationExoTile implements TileWithUpdateStairs { final StringBounder stringBounder = ug.getStringBounder(); final Component comp = getComponent(stringBounder); final Dimension2D dim = comp.getPreferredDimension(stringBounder); - final double x1 = getPoint1(stringBounder).getCurrentValue(); - final double x2 = getPoint2(stringBounder).getCurrentValue(); + double x1 = getPoint1Value(stringBounder); + double x2 = getPoint2(stringBounder).getCurrentValue(); + final int level = livingSpace.getLevelAt(this, EventsHistoryMode.IGNORE_FUTURE_DEACTIVATE); + if (level > 0) { + if (message.getType().isRightBorder()) { + x1 += CommunicationTile.LIVE_DELTA_SIZE * level; + } else { + x2 -= CommunicationTile.LIVE_DELTA_SIZE * level; + } + } final Area area = new Area(x2 - x1, dim.getHeight()); ug = ug.apply(new UTranslate(x1, 0)); comp.drawU(ug, area, (Context2D) ug); @@ -127,12 +133,19 @@ public class CommunicationExoTile implements TileWithUpdateStairs { if (message.getType().isRightBorder()) { return livingSpace.getPosC(stringBounder); } - return alpha; + return tileArguments.getOrigin(); + } + + private double getPoint1Value(final StringBounder stringBounder) { + if (message.getType().isRightBorder()) { + return livingSpace.getPosC(stringBounder).getCurrentValue(); + } + return tileArguments.getOrigin().getMinAbsolute().getCurrentValue(); } private Real getPoint2(final StringBounder stringBounder) { if (message.getType().isRightBorder()) { - return omega; + return tileArguments.getOmega(); } return livingSpace.getPosC(stringBounder); } diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTile.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTile.java index 5603a01eb..92ced14f8 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTile.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTile.java @@ -36,7 +36,9 @@ package net.sourceforge.plantuml.sequencediagram.teoz; import java.awt.geom.Dimension2D; import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.graphic.HorizontalAlignment; import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.VerticalAlignment; import net.sourceforge.plantuml.real.Real; import net.sourceforge.plantuml.sequencediagram.Event; import net.sourceforge.plantuml.sequencediagram.Message; @@ -50,7 +52,7 @@ import net.sourceforge.plantuml.skin.Skin; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UTranslate; -public class CommunicationTile implements TileWithUpdateStairs { +public class CommunicationTile implements TileWithUpdateStairs, TileWithCallbackY { private final LivingSpace livingSpace1; private final LivingSpace livingSpace2; @@ -72,6 +74,10 @@ public class CommunicationTile implements TileWithUpdateStairs { this.message = message; this.skin = skin; this.skinParam = skinParam; + + if (message.isCreate()) { + livingSpace2.goCreate(); + } // for (LifeEvent lifeEvent : message.getLiveEvents()) { // System.err.println("lifeEvent = " + lifeEvent); // // livingSpace1.addLifeEvent(this, lifeEvent); @@ -86,7 +92,10 @@ public class CommunicationTile implements TileWithUpdateStairs { return true; } return false; + } + private boolean isCreate() { + return message.isCreate(); } private Component getComponent(StringBounder stringBounder) { @@ -98,7 +107,7 @@ public class CommunicationTile implements TileWithUpdateStairs { arrowConfiguration = arrowConfiguration.reverse(); } final Component comp = skin.createComponent(ComponentType.ARROW, arrowConfiguration, skinParam, - message.getLabel()); + message.getLabelNumbered()); return comp; } @@ -124,25 +133,37 @@ public class CommunicationTile implements TileWithUpdateStairs { double x1 = getPoint1(stringBounder).getCurrentValue(); double x2 = getPoint2(stringBounder).getCurrentValue(); - final int level1 = livingSpace1.getLevelAt(this, EventsHistoryMode.IGNORE_FUTURE_DEACTIVATE); - final int level2 = livingSpace2.getLevelAt(this, EventsHistoryMode.IGNORE_FUTURE_DEACTIVATE); - // System.err.println("CommunicationTile::draw msg=" + message + " level1=" + level1 + " level2=" + level2); - final Area area; if (isReverse(stringBounder)) { - System.err.println("isreverse!"); - // x1 -= LIVE_DELTA_SIZE * level1; + final int level1 = livingSpace1.getLevelAt(this, EventsHistoryMode.IGNORE_FUTURE_DEACTIVATE); + final int level2 = livingSpace2.getLevelAt(this, EventsHistoryMode.IGNORE_FUTURE_DEACTIVATE); + if (level1 > 0) { + x1 -= LIVE_DELTA_SIZE; + } x2 += LIVE_DELTA_SIZE * level2; area = new Area(x1 - x2, dim.getHeight()); ug = ug.apply(new UTranslate(x2, 0)); + if (isCreate()) { + livingSpace2.drawHead(ug, (Context2D) ug, VerticalAlignment.CENTER, HorizontalAlignment.RIGHT); + } } else { + final int level1 = livingSpace1.getLevelAt(this, EventsHistoryMode.IGNORE_FUTURE_DEACTIVATE); + int level2 = livingSpace2.getLevelAt(this, EventsHistoryMode.IGNORE_FUTURE_DEACTIVATE); + if (level2 > 0) { + level2 = level2 - 2; + } x1 += LIVE_DELTA_SIZE * level1; - x2 -= LIVE_DELTA_SIZE * level2; + x2 += LIVE_DELTA_SIZE * level2; area = new Area(x2 - x1, dim.getHeight()); ug = ug.apply(new UTranslate(x1, 0)); + if (isCreate()) { + livingSpace2.drawHead(ug.apply(new UTranslate(area.getDimensionToUse().getWidth(), 0)), (Context2D) ug, + VerticalAlignment.CENTER, HorizontalAlignment.LEFT); + } } comp.drawU(ug, area, (Context2D) ug); // ug.draw(new ULine(x2 - x1, 0)); + } public double getPreferredHeight(StringBounder stringBounder) { @@ -210,4 +231,10 @@ public class CommunicationTile implements TileWithUpdateStairs { return getPoint2(stringBounder); } + public void callbackY(double y) { + if (message.isCreate()) { + livingSpace2.goCreate(y); + } + } + } diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileNoteLeft.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileNoteLeft.java index ea70fb72c..2ac3feb17 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileNoteLeft.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileNoteLeft.java @@ -49,7 +49,7 @@ import net.sourceforge.plantuml.skin.Skin; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UTranslate; -public class CommunicationTileNoteLeft implements TileWithUpdateStairs { +public class CommunicationTileNoteLeft implements TileWithUpdateStairs, TileWithCallbackY { private final TileWithUpdateStairs tile; private final AbstractMessage message; @@ -58,14 +58,13 @@ public class CommunicationTileNoteLeft implements TileWithUpdateStairs { private final Display notes; // private final NotePosition notePosition; private final LivingSpace livingSpace; - + public Event getEvent() { return message; } - - public CommunicationTileNoteLeft(TileWithUpdateStairs tile, AbstractMessage message, Skin skin, ISkinParam skinParam, - LivingSpace livingSpace) { + public CommunicationTileNoteLeft(TileWithUpdateStairs tile, AbstractMessage message, Skin skin, + ISkinParam skinParam, LivingSpace livingSpace) { this.tile = tile; this.message = message; this.skin = skin; @@ -74,14 +73,14 @@ public class CommunicationTileNoteLeft implements TileWithUpdateStairs { // this.notePosition = message.getNotePosition(); this.livingSpace = livingSpace; } - + public void updateStairs(StringBounder stringBounder, double y) { tile.updateStairs(stringBounder, y); } - private Component getComponent(StringBounder stringBounder) { - final Component comp = skin.createComponent(ComponentType.NOTE, null, message.getSkinParamNoteBackcolored(skinParam), notes); + final Component comp = skin.createComponent(ComponentType.NOTE, null, + message.getSkinParamNoteBackcolored(skinParam), notes); return comp; } @@ -120,4 +119,10 @@ public class CommunicationTileNoteLeft implements TileWithUpdateStairs { return tile.getMaxX(stringBounder); } + public void callbackY(double y) { + if (tile instanceof TileWithCallbackY) { + ((TileWithCallbackY) tile).callbackY(y); + } + } + } diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileNoteRight.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileNoteRight.java index b49b28f0c..25f9075b7 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileNoteRight.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileNoteRight.java @@ -49,7 +49,7 @@ import net.sourceforge.plantuml.skin.Skin; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UTranslate; -public class CommunicationTileNoteRight implements TileWithUpdateStairs { +public class CommunicationTileNoteRight implements TileWithUpdateStairs, TileWithCallbackY { private final TileWithUpdateStairs tile; private final AbstractMessage message; @@ -62,6 +62,10 @@ public class CommunicationTileNoteRight implements TileWithUpdateStairs { public Event getEvent() { return message; } + + private boolean isCreate() { + return message.isCreate(); + } public CommunicationTileNoteRight(TileWithUpdateStairs tile, AbstractMessage message, Skin skin, ISkinParam skinParam, LivingSpace livingSpace) { @@ -87,6 +91,9 @@ public class CommunicationTileNoteRight implements TileWithUpdateStairs { private Real getNotePosition(StringBounder stringBounder) { final Component comp = getComponent(stringBounder); final Dimension2D dim = comp.getPreferredDimension(stringBounder); + if (isCreate()) { + return livingSpace.getPosD(stringBounder); + } return livingSpace.getPosC(stringBounder); } @@ -121,4 +128,10 @@ public class CommunicationTileNoteRight implements TileWithUpdateStairs { return getNotePosition(stringBounder).addFixed(dim.getWidth()); } + public void callbackY(double y) { + if (tile instanceof TileWithCallbackY) { + ((TileWithCallbackY) tile).callbackY(y); + } + } + } diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileSelf.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileSelf.java index 5492535d7..a2fa57946 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileSelf.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/CommunicationTileSelf.java @@ -88,7 +88,7 @@ public class CommunicationTileSelf implements TileWithUpdateStairs { ArrowConfiguration arrowConfiguration = message.getArrowConfiguration(); arrowConfiguration = arrowConfiguration.self(); final Component comp = skin.createComponent(ComponentType.ARROW, arrowConfiguration, skinParam, - message.getLabel()); + message.getLabelNumbered()); return comp; } diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/ComponentAdapter.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/ComponentAdapter.java new file mode 100644 index 000000000..8379290e0 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/ComponentAdapter.java @@ -0,0 +1,71 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2014, Arnaud Roques + * + * Project Info: http://plantuml.sourceforge.net + * + * 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. + * + * [Java is a trademark or registered trademark of Sun Microsystems, Inc. + * in the United States and other countries.] + * + * Original Author: Arnaud Roques + * + * Revision $Revision: 9591 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.teoz; + +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.skin.Area; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.SimpleContext2D; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +public class ComponentAdapter implements TextBlock { + + private final Component component; + + public ComponentAdapter(Component component) { + this.component = component; + } + + public void drawU(UGraphic ug) { + if (component == null) { + return; + } + component.drawU(ug, new Area(calculateDimension(ug.getStringBounder())), new SimpleContext2D(false)); + + } + + public Dimension2D calculateDimension(StringBounder stringBounder) { + if (component == null) { + return new Dimension2DDouble(0, 0); + } + final double width = component.getPreferredWidth(stringBounder); + final double height = component.getPreferredHeight(stringBounder); + return new Dimension2DDouble(width, height); + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/DelayTile.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/DelayTile.java index 539a025e1..e43f43196 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/DelayTile.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/DelayTile.java @@ -43,21 +43,24 @@ import net.sourceforge.plantuml.skin.Area; import net.sourceforge.plantuml.skin.Component; import net.sourceforge.plantuml.skin.ComponentType; import net.sourceforge.plantuml.skin.Context2D; -import net.sourceforge.plantuml.skin.SimpleContext2D; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UTranslate; -public class DelayTile implements Tile { +public class DelayTile implements Tile, TileWithCallbackY { private final Delay delay; private final TileArguments tileArguments; private Real first; private Real last; - + private double y; + public Event getEvent() { return delay; } + public void callbackY(double y) { + this.y = y; + } public DelayTile(Delay delay, TileArguments tileArguments) { this.delay = delay; @@ -88,6 +91,7 @@ public class DelayTile implements Tile { final Component comp = getComponent(stringBounder); final Dimension2D dim = comp.getPreferredDimension(stringBounder); final Area area = new Area(last.getCurrentValue() - first.getCurrentValue(), dim.getHeight()); + tileArguments.getLivingSpaces().delayOn(y, dim.getHeight()); ug = ug.apply(new UTranslate(first.getCurrentValue(), 0)); comp.drawU(ug, area, (Context2D) ug); @@ -112,14 +116,14 @@ public class DelayTile implements Tile { return this.last; } -// private double startingY; -// -// public void setStartingY(double startingY) { -// this.startingY = startingY; -// } -// -// public double getStartingY() { -// return startingY; -// } + // private double startingY; + // + // public void setStartingY(double startingY) { + // this.startingY = startingY; + // } + // + // public double getStartingY() { + // return startingY; + // } } diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/ElseTile.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/ElseTile.java index 27d0154c8..02a9b5606 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/ElseTile.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/ElseTile.java @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.sequencediagram.teoz; import java.awt.geom.Dimension2D; import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.SkinParamBackcolored; import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.real.Real; @@ -45,23 +46,21 @@ import net.sourceforge.plantuml.skin.Area; import net.sourceforge.plantuml.skin.Component; import net.sourceforge.plantuml.skin.ComponentType; import net.sourceforge.plantuml.skin.Context2D; -import net.sourceforge.plantuml.skin.SimpleContext2D; import net.sourceforge.plantuml.skin.Skin; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UTranslate; -public class ElseTile implements Tile { +public class ElseTile implements TileWithCallbackY { private final Skin skin; private final ISkinParam skinParam; private final GroupingLeaf anElse; private final Tile parent; - + public Event getEvent() { return anElse; } - public ElseTile(GroupingLeaf anElse, Skin skin, ISkinParam skinParam, Tile parent) { this.anElse = anElse; this.skin = skin; @@ -70,8 +69,12 @@ public class ElseTile implements Tile { } private Component getComponent(StringBounder stringBounder) { - final Display display = Display.create(anElse.getTitle()); - final Component comp = skin.createComponent(ComponentType.GROUPING_ELSE, null, skinParam, display); + // final Display display = Display.create(anElse.getTitle()); + final ISkinParam tmp = new SkinParamBackcolored(skinParam, anElse.getBackColorElement(), + anElse.getBackColorGeneral()); + + final Display display = Display.create(anElse.getComment()); + final Component comp = skin.createComponent(ComponentType.GROUPING_ELSE, null, tmp, display); return comp; } @@ -81,10 +84,16 @@ public class ElseTile implements Tile { final Dimension2D dim = comp.getPreferredDimension(stringBounder); final Real min = getMinX(stringBounder); final Real max = getMaxX(stringBounder); - final Area area = new Area(max.getCurrentValue() - min.getCurrentValue(), dim.getHeight()); + final Context2D context = (Context2D) ug; + double height = dim.getHeight(); + if (context.isBackground() && parent instanceof GroupingTile) { + final double startingY = ((GroupingTile) parent).getStartY(); + final double totalParentHeight = parent.getPreferredHeight(stringBounder); + height = totalParentHeight - (startingY - y); + } + final Area area = new Area(max.getCurrentValue() - min.getCurrentValue(), height); ug = ug.apply(new UTranslate(min.getCurrentValue(), 0)); - // ug = ug.apply(new UTranslate(x, 0)); - comp.drawU(ug, area, (Context2D) ug); + comp.drawU(ug, area, context); } public double getPreferredHeight(StringBounder stringBounder) { @@ -107,4 +116,10 @@ public class ElseTile implements Tile { return parent.getMaxX(stringBounder); } + private double y; + + public void callbackY(double y) { + this.y = y; + } + } diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/Englobers.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/Englobers.java new file mode 100644 index 000000000..3ae85f471 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/Englobers.java @@ -0,0 +1,97 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2014, Arnaud Roques + * + * Project Info: http://plantuml.sourceforge.net + * + * 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. + * + * [Java is a trademark or registered trademark of Sun Microsystems, Inc. + * in the United States and other countries.] + * + * Original Author: Arnaud Roques + * + * Revision $Revision: 4636 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.teoz; + +import java.util.ArrayList; +import java.util.List; + +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.sequencediagram.Englober; +import net.sourceforge.plantuml.sequencediagram.Participant; +import net.sourceforge.plantuml.sequencediagram.ParticipantEnglober; +import net.sourceforge.plantuml.skin.Context2D; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +public class Englobers { + + private final List englobers = new ArrayList(); + + public Englobers(TileArguments tileArguments) { + Englober pending = null; + for (Participant p : tileArguments.getLivingSpaces().participants()) { + final ParticipantEnglober englober = tileArguments.getLivingSpaces().get(p).getEnglober(); + if (englober == null) { + pending = null; + continue; + } + assert englober != null; + if (pending != null && englober == pending.getParticipantEnglober()) { + pending.add(p); + continue; + } + pending = new Englober(englober, p, tileArguments); + englobers.add(pending); + } + } + + public double getOffsetForEnglobers(StringBounder stringBounder) { + double result = 0; + for (Englober englober : englobers) { + final double height = englober.getPreferredHeight(); + if (height > result) { + result = height; + } + } + return result; + } + + public void addConstraints(StringBounder stringBounder) { + Englober last = null; + for (Englober current : englobers) { + current.addInternalConstraints(); + + if (last != null) { + last.addConstraintAfter(current); + } + last = current; + } + } + + public void drawEnglobers(UGraphic ug, double height, Context2D context) { + for (Englober englober : englobers) { + englober.drawEnglober(ug, height, context); + } + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/EventsHistory.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/EventsHistory.java index 4d1017ff5..ab2726c44 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/EventsHistory.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/EventsHistory.java @@ -164,19 +164,19 @@ public class EventsHistory { } public Stairs2 getStairs(double totalHeight) { - System.err.println("EventsHistory::getStairs totalHeight=" + totalHeight); + // System.err.println("EventsHistory::getStairs totalHeight=" + totalHeight); final Stairs2 result = new Stairs2(); int value = 0; for (Event event : events) { final Double position = ys3.get(event); - System.err.println("EventsHistory::getStairs event=" + event + " position=" + position); + // System.err.println("EventsHistory::getStairs event=" + event + " position=" + position); if (position != null) { assert position <= totalHeight : "position=" + position + " totalHeight=" + totalHeight; value = getLevelAt(event, EventsHistoryMode.CONSIDERE_FUTURE_DEACTIVATE); result.addStep(new StairsPosition(position, isNextEventADestroy(event)), value, getActivateColor(event)); } } - System.err.println("EventsHistory::getStairs finishing totalHeight=" + totalHeight); + // System.err.println("EventsHistory::getStairs finishing totalHeight=" + totalHeight); result.addStep(new StairsPosition(totalHeight, false), value, null); // System.err.println("EventsHistory::getStairs " + p + " result=" + result); return result; diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/GroupingTile.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/GroupingTile.java index 87f4cdd08..289034dac 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/GroupingTile.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/GroupingTile.java @@ -42,8 +42,7 @@ import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.real.Real; -import net.sourceforge.plantuml.real.RealMax; -import net.sourceforge.plantuml.real.RealMin; +import net.sourceforge.plantuml.real.RealUtils; import net.sourceforge.plantuml.sequencediagram.Event; import net.sourceforge.plantuml.sequencediagram.Grouping; import net.sourceforge.plantuml.sequencediagram.GroupingLeaf; @@ -57,13 +56,13 @@ import net.sourceforge.plantuml.skin.Skin; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UTranslate; -public class GroupingTile implements Tile { +public class GroupingTile implements TileWithCallbackY { private static final int MARGINX = 16; private static final int MARGINY = 10; private final List tiles = new ArrayList(); - private final RealMin min = new RealMin(); - private final RealMax max = new RealMax(); + private final Real min; + private final Real max; private final GroupingStart start; // private final double marginX = 20; @@ -88,6 +87,9 @@ public class GroupingTile implements Tile { this.skinParam = tileArgumentsBachColorChanged.getSkinParam(); // this.max = min.addAtLeast(dim1.getWidth()); + final List min2 = new ArrayList(); + final List max2 = new ArrayList(); + while (it.hasNext()) { final Event ev = it.next(); System.err.println("GroupingTile::ev=" + ev); @@ -97,21 +99,24 @@ public class GroupingTile implements Tile { final Tile tile = TileBuilder.buildOne(it, tileArgumentsOriginal, ev, this); if (tile != null) { tiles.add(tile); - min.put(tile.getMinX(stringBounder).addFixed(-MARGINX)); - final Real m = tile.getMaxX(stringBounder); - max.put(m == tileArgumentsOriginal.getOmega() ? m : m.addFixed(MARGINX)); bodyHeight += tile.getPreferredHeight(stringBounder); + if (ev instanceof GroupingLeaf && ((Grouping) ev).getType() == GroupingType.ELSE) { + continue; + } + min2.add(tile.getMinX(stringBounder).addFixed(-MARGINX)); + final Real m = tile.getMaxX(stringBounder); + max2.add(m == tileArgumentsOriginal.getOmega() ? m : m.addFixed(MARGINX)); } } final Dimension2D dim1 = getPreferredDimensionIfEmpty(stringBounder); final double width = dim1.getWidth(); - System.err.println("width=" + width); - if (min.size() == 0) { - min.put(tileArgumentsOriginal.getOrigin()); - max.put(tileArgumentsOriginal.getOmega()); + if (min2.size() == 0) { + min2.add(tileArgumentsOriginal.getOrigin()); } - // max.ensureBiggerThan(min.addFixed(width)); - this.max.ensureBiggerThan(getMinX(stringBounder).addFixed(width + 16)); + this.min = RealUtils.min(min2); + max2.add(this.min.addFixed(width + 16)); + this.max = RealUtils.max(max2); + } private Component getComponent(StringBounder stringBounder) { @@ -162,4 +167,14 @@ public class GroupingTile implements Tile { public Real getMaxX(StringBounder stringBounder) { return max; } + + private double y; + + public void callbackY(double y) { + this.y = y; + } + + public double getStartY() { + return y + MARGINY; + } } diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/LiveBoxes.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/LiveBoxes.java index 2a2ffe2ac..329907a1d 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/LiveBoxes.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/LiveBoxes.java @@ -33,87 +33,69 @@ */ package net.sourceforge.plantuml.sequencediagram.teoz; -import java.awt.geom.Dimension2D; import java.util.Iterator; +import java.util.Map; +import java.util.TreeMap; import net.sourceforge.plantuml.ISkinParam; -import net.sourceforge.plantuml.SkinParamBackcolored; -import net.sourceforge.plantuml.graphic.HtmlColor; -import net.sourceforge.plantuml.graphic.UDrawable; -import net.sourceforge.plantuml.skin.Area; -import net.sourceforge.plantuml.skin.Component; -import net.sourceforge.plantuml.skin.ComponentType; import net.sourceforge.plantuml.skin.Context2D; import net.sourceforge.plantuml.skin.Skin; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UTranslate; -public class LiveBoxes implements UDrawable { +public class LiveBoxes { private final EventsHistory eventsHistory; private final Skin skin; private final ISkinParam skinParam; - private final double totalHeight; - private final Context2D context; + private final Map delays = new TreeMap(); - public LiveBoxes(EventsHistory eventsHistory, Skin skin, ISkinParam skinParam, double totalHeight, Context2D context) { + public LiveBoxes(EventsHistory eventsHistory, Skin skin, ISkinParam skinParam) { this.eventsHistory = eventsHistory; this.skin = skin; this.skinParam = skinParam; - this.totalHeight = totalHeight; - this.context = context; } - public void drawU(UGraphic ug) { + public void drawBoxes(UGraphic ug, double totalHeight, Context2D context) { final Stairs2 stairs = eventsHistory.getStairs(totalHeight); final int max = stairs.getMaxValue(); + if (max == 0) { + drawDestroys(ug, stairs, context); + } for (int i = 1; i <= max; i++) { drawOneLevel(ug, i, stairs, context); } } - private void drawOneLevel(UGraphic ug, int levelToDraw, Stairs2 stairs, Context2D context) { - final Component comp1 = skin.createComponent(ComponentType.ALIVE_BOX_CLOSE_CLOSE, null, skinParam, null); - final Component cross = skin.createComponent(ComponentType.DESTROY, null, skinParam, null); - final Dimension2D dimCross = cross.getPreferredDimension(ug.getStringBounder()); - final double width = comp1.getPreferredWidth(ug.getStringBounder()); - ug = ug.apply(new UTranslate((levelToDraw - 1) * width / 2.0, 0)); + private void drawDestroys(UGraphic ug, Stairs2 stairs, Context2D context) { + final LiveBoxesDrawer drawer = new LiveBoxesDrawer(context, skin, skinParam, delays); + for (StairsPosition yposition : stairs.getYs()) { + drawer.drawDestroyIfNeeded(ug, yposition); + } + } - double y1 = Double.MAX_VALUE; - HtmlColor color = null; + private void drawOneLevel(UGraphic ug, int levelToDraw, Stairs2 stairs, Context2D context) { + final LiveBoxesDrawer drawer = new LiveBoxesDrawer(context, skin, skinParam, delays); + ug = ug.apply(new UTranslate((levelToDraw - 1) * drawer.getWidth(ug.getStringBounder()) / 2.0, 0)); + + boolean pending = true; for (Iterator it = stairs.getYs().iterator(); it.hasNext();) { final StairsPosition yposition = it.next(); - System.err.println("LiveBoxes::drawOneLevel " + levelToDraw + " " + yposition); final IntegerColored integerColored = stairs.getValue(yposition.getValue()); - System.err.println("integerColored=" + integerColored); final int level = integerColored.getValue(); - if (y1 == Double.MAX_VALUE && level == levelToDraw) { - y1 = yposition.getValue(); - color = integerColored.getColor(); - } else if (y1 != Double.MAX_VALUE && (it.hasNext() == false || level < levelToDraw)) { - final double y2 = yposition.getValue(); - final Area area = new Area(width, y2 - y1); - - final ISkinParam skinParam2 = new SkinParamBackcolored(skinParam, color); - final Component comp = skin - .createComponent(ComponentType.ALIVE_BOX_CLOSE_CLOSE, null, skinParam2, null); - - comp.drawU(ug.apply(new UTranslate(-width / 2, y1)), area, context); - System.err.println("LiveBoxes::drawOneLevel one block " + y1 + " " + y2); - if (yposition.isDestroy()) { - System.err.println("LiveBoxes::drawOneLevel DESTROY " + yposition); - cross.drawU(ug.apply(new UTranslate(-dimCross.getWidth() / 2, y2 - dimCross.getHeight() / 2)), - null, context); - } else { - System.err.println("LiveBoxes::drawOneLevel NOTDESTROY " + yposition); - } - y1 = Double.MAX_VALUE; + if (pending && level == levelToDraw) { + drawer.addStart(yposition.getValue(), integerColored.getColor()); + pending = false; + } else if (pending == false && (it.hasNext() == false || level < levelToDraw)) { + drawer.doDrawing(ug, yposition); + drawer.drawDestroyIfNeeded(ug, yposition); + pending = true; } } } - private UGraphic withColor(UGraphic ug) { - return ug; + public void delayOn(double y, double height) { + delays.put(y, height); } } diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/LiveBoxesDrawer.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/LiveBoxesDrawer.java new file mode 100644 index 000000000..485ff78c0 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/LiveBoxesDrawer.java @@ -0,0 +1,123 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2014, Arnaud Roques + * + * Project Info: http://plantuml.sourceforge.net + * + * 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. + * + * [Java is a trademark or registered trademark of Sun Microsystems, Inc. + * in the United States and other countries.] + * + * Original Author: Arnaud Roques + * + * Revision $Revision: 5183 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.teoz; + +import java.awt.geom.Dimension2D; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; + +import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.SkinParamBackcolored; +import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.sequencediagram.graphic.Segment; +import net.sourceforge.plantuml.skin.Area; +import net.sourceforge.plantuml.skin.Component; +import net.sourceforge.plantuml.skin.ComponentType; +import net.sourceforge.plantuml.skin.Context2D; +import net.sourceforge.plantuml.skin.Skin; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.UTranslate; + +public class LiveBoxesDrawer { + + private double y1; + private HtmlColor color; + + private final Component cross; + private final Context2D context; + private final Skin skin; + private final ISkinParam skinParam; + private final Component compForWidth; + private final Collection delays; + + public LiveBoxesDrawer(Context2D context, Skin skin, ISkinParam skinParam, Map delays) { + this.cross = skin.createComponent(ComponentType.DESTROY, null, skinParam, null); + this.compForWidth = skin.createComponent(ComponentType.ALIVE_BOX_CLOSE_CLOSE, null, skinParam, null); + this.context = context; + this.skin = skin; + this.skinParam = skinParam; + this.delays = new HashSet(); + for (Map.Entry ent : delays.entrySet()) { + this.delays.add(new Segment(ent.getKey(), ent.getKey() + ent.getValue())); + } + } + + public double getWidth(StringBounder stringBounder) { + return compForWidth.getPreferredWidth(stringBounder); + } + + public void addStart(double y1, HtmlColor color) { + this.y1 = y1; + this.color = color; + } + + public void doDrawing(UGraphic ug, StairsPosition yposition) { + final Segment full = new Segment(y1, yposition.getValue()); + final Collection segments = full.cutSegmentIfNeed(delays); + ComponentType type = ComponentType.ALIVE_BOX_CLOSE_CLOSE; + if (segments.size() > 1) { + type = ComponentType.ALIVE_BOX_CLOSE_OPEN; + } + for (Iterator it = segments.iterator(); it.hasNext();) { + final Segment seg = it.next(); + if (it.hasNext() == false && type != ComponentType.ALIVE_BOX_CLOSE_CLOSE) { + type = ComponentType.ALIVE_BOX_OPEN_CLOSE; + } + drawInternal(ug, yposition, seg.getPos1(), seg.getPos2(), type); + type = ComponentType.ALIVE_BOX_OPEN_OPEN; + } + y1 = Double.MAX_VALUE; + } + + public void drawDestroyIfNeeded(UGraphic ug, StairsPosition yposition) { + if (yposition.isDestroy()) { + final Dimension2D dimCross = cross.getPreferredDimension(ug.getStringBounder()); + cross.drawU( + ug.apply(new UTranslate(-dimCross.getWidth() / 2, yposition.getValue() - dimCross.getHeight() / 2)), + null, context); + } + } + + private void drawInternal(UGraphic ug, StairsPosition yposition, double ya, double yb, ComponentType type) { + final double width = getWidth(ug.getStringBounder()); + final Area area = new Area(width, yb - ya); + final ISkinParam skinParam2 = new SkinParamBackcolored(skinParam, color); + final Component comp = skin.createComponent(type, null, skinParam2, null); + comp.drawU(ug.apply(new UTranslate(-width / 2, ya)), area, context); + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/LivingSpace.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/LivingSpace.java index a77948273..7a1c1b40c 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/LivingSpace.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/LivingSpace.java @@ -37,7 +37,9 @@ import java.awt.geom.Dimension2D; import java.util.List; import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.graphic.HorizontalAlignment; import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.VerticalAlignment; import net.sourceforge.plantuml.real.Real; import net.sourceforge.plantuml.sequencediagram.Delay; import net.sourceforge.plantuml.sequencediagram.Event; @@ -51,6 +53,7 @@ import net.sourceforge.plantuml.skin.Context2D; import net.sourceforge.plantuml.skin.Skin; import net.sourceforge.plantuml.skin.rose.Rose; import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.UTranslate; public class LivingSpace { @@ -62,6 +65,7 @@ public class LivingSpace { private final boolean useContinueLineBecauseOfDelay; private final MutingLine mutingLine; private final Rose rose = new Rose(); + private final LiveBoxes liveBoxes; // private final LivingSpaceImpl previous; // private LivingSpace next; @@ -71,6 +75,10 @@ public class LivingSpace { private Real posD; private final EventsHistory eventsHistory; + private boolean create = false; + private double createY = 0; + + private final ParticipantEnglober englober; public int getLevelAt(Tile tile, EventsHistoryMode mode) { // assert mode == EventsHistoryMode.IGNORE_FUTURE_DEACTIVATE; @@ -99,6 +107,7 @@ public class LivingSpace { this.p = p; this.skin = skin; this.skinParam = skinParam; + this.englober = englober; this.posB = position; if (p.getType() == ParticipantType.PARTICIPANT) { headType = ComponentType.PARTICIPANT_HEAD; @@ -125,7 +134,7 @@ public class LivingSpace { // this.stairs2.addStep2(0, 0); this.useContinueLineBecauseOfDelay = useContinueLineBecauseOfDelay(events); this.mutingLine = new MutingLine(skin, skinParam, events); - + this.liveBoxes = new LiveBoxes(eventsHistory, skin, skinParam); } private boolean useContinueLineBecauseOfDelay(List events) { @@ -143,27 +152,28 @@ public class LivingSpace { public void drawLineAndLiveBoxes(UGraphic ug, double height, Context2D context) { - mutingLine.drawLine(ug, height, context); - // final ComponentType defaultLineType = useContinueLineBecauseOfDelay ? ComponentType.CONTINUE_LINE - // : ComponentType.PARTICIPANT_LINE; - // final Component comp = skin.createComponent(defaultLineType, null, skinParam, p.getDisplay(false)); - // final Dimension2D dim = comp.getPreferredDimension(ug.getStringBounder()); - // final Area area = new Area(dim.getWidth(), height); - // comp.drawU(ug, area, new SimpleContext2D(false)); - - final LiveBoxes liveBoxes = new LiveBoxes(eventsHistory, skin, skinParam, height, context); - liveBoxes.drawU(ug); + mutingLine.drawLine(ug, context, createY, height); + liveBoxes.drawBoxes(ug, height, context); } // public void addDelayTile(DelayTile tile) { // System.err.println("addDelayTile " + this + " " + tile); // } - public void drawHead(UGraphic ug, Context2D context) { - // final Component comp = skin.createComponent(headType, null, skinParam, p.getDisplay(false)); + public void drawHead(UGraphic ug, Context2D context, VerticalAlignment verticalAlignment, + HorizontalAlignment horizontalAlignment) { + if (create && verticalAlignment == VerticalAlignment.BOTTOM) { + return; + } final Component comp = rose.createComponent(headType, null, p.getSkinParamBackcolored(skinParam), p.getDisplay(false)); final Dimension2D dim = comp.getPreferredDimension(ug.getStringBounder()); + if (horizontalAlignment == HorizontalAlignment.RIGHT) { + ug = ug.apply(new UTranslate(-dim.getWidth(), 0)); + } + if (verticalAlignment == VerticalAlignment.CENTER) { + ug = ug.apply(new UTranslate(0, -dim.getHeight() / 2)); + } final Area area = new Area(dim); comp.drawU(ug, area, context); } @@ -201,4 +211,23 @@ public class LivingSpace { return p; } + public void goCreate(double y) { + System.err.println("LivingSpace::goCreate"); + this.createY = y; + this.create = true; + } + + public void goCreate() { + this.create = true; + } + + public void delayOn(double y, double height) { + mutingLine.delayOn(y, height); + liveBoxes.delayOn(y, height); + } + + public ParticipantEnglober getEnglober() { + return englober; + } + } diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/LivingSpaces.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/LivingSpaces.java index 3ea19797b..b36d925e4 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/LivingSpaces.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/LivingSpaces.java @@ -35,9 +35,11 @@ package net.sourceforge.plantuml.sequencediagram.teoz; import java.awt.geom.Dimension2D; import java.util.Collection; +import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; +import net.sourceforge.plantuml.graphic.HorizontalAlignment; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.VerticalAlignment; import net.sourceforge.plantuml.sequencediagram.Participant; @@ -53,6 +55,32 @@ public class LivingSpaces { return all.values(); } + public LivingSpace previous(LivingSpace element) { + LivingSpace previous = null; + for (LivingSpace current : all.values()) { + if (current == element) { + return previous; + } + previous = current; + } + return null; + } + + public LivingSpace next(LivingSpace element) { + for (Iterator it = all.values().iterator(); it.hasNext();) { + final LivingSpace current = it.next(); + if (current == element && it.hasNext()) { + return it.next(); + } + } + return null; + + } + + public Collection participants() { + return all.keySet(); + } + public void put(Participant participant, LivingSpace livingSpace) { all.put(participant, livingSpace); } @@ -71,7 +99,7 @@ public class LivingSpaces { final Dimension2D dimHead = livingSpace.getHeadPreferredDimension(stringBounder); y = headHeight - dimHead.getHeight(); } - livingSpace.drawHead(ug.apply(new UTranslate(x, y)), context); + livingSpace.drawHead(ug.apply(new UTranslate(x, y)), context, verticalAlignment, HorizontalAlignment.LEFT); } } @@ -97,4 +125,14 @@ public class LivingSpaces { } } + public void delayOn(double y, double height) { + for (LivingSpace livingSpace : values()) { + livingSpace.delayOn(y, height); + } + } + + public int size() { + return all.size(); + } + } diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/MainTile.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/MainTile.java index ade1457bd..9971ea31e 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/MainTile.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/MainTile.java @@ -36,44 +36,45 @@ package net.sourceforge.plantuml.sequencediagram.teoz; import java.util.ArrayList; import java.util.List; -import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.graphic.StringBounder; -import net.sourceforge.plantuml.graphic.TextBlockUtils; import net.sourceforge.plantuml.real.Real; -import net.sourceforge.plantuml.real.RealMax; -import net.sourceforge.plantuml.real.RealMin; +import net.sourceforge.plantuml.real.RealUtils; import net.sourceforge.plantuml.sequencediagram.Event; import net.sourceforge.plantuml.sequencediagram.SequenceDiagram; -import net.sourceforge.plantuml.skin.Skin; import net.sourceforge.plantuml.ugraphic.LimitFinder; import net.sourceforge.plantuml.ugraphic.UGraphic; public class MainTile implements Tile { - private final RealMin min = new RealMin(); - private final RealMax max = new RealMax(); - // private double height; + private final Real min; + private final Real max; + private final boolean isShowFootbox; private final List tiles = new ArrayList(); + private final LivingSpaces livingSpaces; - public MainTile(SequenceDiagram diagram, Skin skin, Real omega, LivingSpaces livingSpaces, Real origin) { + public MainTile(SequenceDiagram diagram, TileArguments tileArguments) { - min.put(origin); - max.put(omega); + this.livingSpaces = tileArguments.getLivingSpaces(); - final ISkinParam skinParam = diagram.getSkinParam(); - final StringBounder stringBounder = TextBlockUtils.getDummyStringBounder(); + final List min2 = new ArrayList(); + final List max2 = new ArrayList(); - final TileArguments tileArguments = new TileArguments(stringBounder, omega, livingSpaces, skin, skinParam, - origin); + min2.add(tileArguments.getOrigin()); + max2.add(tileArguments.getOmega()); tiles.addAll(TileBuilder.buildSeveral(diagram.events().iterator(), tileArguments, null)); for (Tile tile : tiles) { // height += tile.getPreferredHeight(stringBounder); - min.put(tile.getMinX(stringBounder)); - max.put(tile.getMaxX(stringBounder)); + min2.add(tile.getMinX(tileArguments.getStringBounder())); + max2.add(tile.getMaxX(tileArguments.getStringBounder())); } + + this.min = RealUtils.min(min2); + this.max = RealUtils.max(max2); + + this.isShowFootbox = diagram.isShowFootbox(); } public void drawU(UGraphic ug) { @@ -109,16 +110,16 @@ public class MainTile implements Tile { for (YPositionedTile tile : positionedTiles) { tile.drawU(ug); } - System.err.println("MainTile::drawUInternal finalY=" + y); + // System.err.println("MainTile::drawUInternal finalY=" + y); return y; } public double getPreferredHeight(StringBounder stringBounder) { final LimitFinder limitFinder = new LimitFinder(stringBounder, true); final UGraphicInterceptorTile interceptor = new UGraphicInterceptorTile(limitFinder, false); - final double finalY = drawUInternal(interceptor, true); + final double finalY = drawUInternal(interceptor, false); final double result = Math.max(limitFinder.getMinMax().getDimension().getHeight(), finalY) + 10; - System.err.println("MainTile::getPreferredHeight=" + result); + // System.err.println("MainTile::getPreferredHeight=" + result); return result; } @@ -140,4 +141,12 @@ public class MainTile implements Tile { return null; } + public boolean isShowFootbox() { + return isShowFootbox; + } + + public LivingSpaces getLivingSpaces() { + return livingSpaces; + } + } diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/MainTileAdapter.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/MainTileAdapter.java new file mode 100644 index 000000000..6caec335a --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/MainTileAdapter.java @@ -0,0 +1,96 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2014, Arnaud Roques + * + * Project Info: http://plantuml.sourceforge.net + * + * 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. + * + * [Java is a trademark or registered trademark of Sun Microsystems, Inc. + * in the United States and other countries.] + * + * Original Author: Arnaud Roques + * + * Revision $Revision: 9591 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.teoz; + +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.graphic.VerticalAlignment; +import net.sourceforge.plantuml.real.Real; +import net.sourceforge.plantuml.skin.Context2D; +import net.sourceforge.plantuml.skin.SimpleContext2D; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.UTranslate; + +public class MainTileAdapter implements TextBlock { + + private final MainTile mainTile; + private Dimension2D cacheDimension; + + public MainTileAdapter(MainTile mainTile) { + if (mainTile == null) { + throw new IllegalArgumentException(); + } + this.mainTile = mainTile; + } + + public Dimension2D calculateDimension(StringBounder stringBounder) { + if (cacheDimension == null) { + final double width = mainTile.getMaxX(stringBounder).getCurrentValue() + - mainTile.getMinX(stringBounder).getCurrentValue(); + + final int factor = mainTile.isShowFootbox() ? 2 : 1; + final double height = mainTile.getPreferredHeight(stringBounder) + factor + * mainTile.getLivingSpaces().getHeadHeight(stringBounder); + + cacheDimension = new Dimension2DDouble(width, height); + } + return cacheDimension; + } + + public void drawU(UGraphic ug) { + final StringBounder stringBounder = ug.getStringBounder(); + + final Context2D context = new SimpleContext2D(false); + final double height = mainTile.getPreferredHeight(stringBounder); + final LivingSpaces livingSpaces = mainTile.getLivingSpaces(); + + final double headHeight = livingSpaces.getHeadHeight(stringBounder); + + mainTile.drawU(ug.apply(new UTranslate(0, headHeight))); + livingSpaces.drawLifeLines(ug.apply(new UTranslate(0, headHeight)), height, context); + livingSpaces.drawHeads(ug, context, VerticalAlignment.BOTTOM); + if (mainTile.isShowFootbox()) { + livingSpaces.drawHeads(ug.apply(new UTranslate(0, height + headHeight)), context, VerticalAlignment.TOP); + } + mainTile.drawForeground(ug.apply(new UTranslate(0, headHeight))); + } + + public Real getMinX(StringBounder stringBounder) { + return mainTile.getMinX(stringBounder); + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/MutingLine.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/MutingLine.java index 6773985af..8d923008c 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/MutingLine.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/MutingLine.java @@ -35,6 +35,8 @@ package net.sourceforge.plantuml.sequencediagram.teoz; import java.awt.geom.Dimension2D; import java.util.List; +import java.util.Map; +import java.util.TreeMap; import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.sequencediagram.Delay; @@ -45,12 +47,14 @@ import net.sourceforge.plantuml.skin.ComponentType; import net.sourceforge.plantuml.skin.Context2D; import net.sourceforge.plantuml.skin.Skin; import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.UTranslate; public class MutingLine { private final Skin skin; private final ISkinParam skinParam; private final boolean useContinueLineBecauseOfDelay; + private final Map delays = new TreeMap(); public MutingLine(Skin skin, ISkinParam skinParam, List events) { this.skin = skin; @@ -71,13 +75,39 @@ public class MutingLine { return false; } - public void drawLine(UGraphic ug, double height, Context2D context) { + public void drawLine(UGraphic ug, Context2D context, double createY, double endY) { final ComponentType defaultLineType = useContinueLineBecauseOfDelay ? ComponentType.CONTINUE_LINE : ComponentType.PARTICIPANT_LINE; + if (delays.size() > 0) { + double y = createY; + for (Map.Entry ent : delays.entrySet()) { + if (ent.getKey() >= createY) { + drawInternal(ug, context, y, ent.getKey(), defaultLineType); + drawInternal(ug, context, ent.getKey(), ent.getKey() + ent.getValue(), ComponentType.DELAY_LINE); + y = ent.getKey() + ent.getValue(); + } + } + drawInternal(ug, context, y, endY, defaultLineType); + } else { + drawInternal(ug, context, createY, endY, defaultLineType); + } + } + + private void drawInternal(UGraphic ug, Context2D context, double y1, double y2, final ComponentType defaultLineType) { + if (y2 == y1) { + return; + } + if (y2 < y1) { + throw new IllegalArgumentException(); + } final Component comp = skin.createComponent(defaultLineType, null, skinParam, null); final Dimension2D dim = comp.getPreferredDimension(ug.getStringBounder()); - final Area area = new Area(dim.getWidth(), height); - comp.drawU(ug, area, context); + final Area area = new Area(dim.getWidth(), y2 - y1); + comp.drawU(ug.apply(new UTranslate(0, y1)), area, context); + } + + public void delayOn(double y, double height) { + delays.put(y, height); } } diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/NoteTile.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/NoteTile.java index e93aac3ce..17fa8be08 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/NoteTile.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/NoteTile.java @@ -42,11 +42,11 @@ import net.sourceforge.plantuml.real.RealUtils; import net.sourceforge.plantuml.sequencediagram.Event; import net.sourceforge.plantuml.sequencediagram.Note; import net.sourceforge.plantuml.sequencediagram.NotePosition; +import net.sourceforge.plantuml.sequencediagram.NoteStyle; import net.sourceforge.plantuml.skin.Area; import net.sourceforge.plantuml.skin.Component; import net.sourceforge.plantuml.skin.ComponentType; import net.sourceforge.plantuml.skin.Context2D; -import net.sourceforge.plantuml.skin.SimpleContext2D; import net.sourceforge.plantuml.skin.Skin; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UTranslate; @@ -72,11 +72,21 @@ public class NoteTile implements Tile { } private Component getComponent(StringBounder stringBounder) { - final Component comp = skin.createComponent(ComponentType.NOTE, null, note.getSkinParamBackcolored(skinParam), - note.getStrings()); + final Component comp = skin.createComponent(getNoteComponentType(note.getStyle()), null, + note.getSkinParamBackcolored(skinParam), note.getStrings()); return comp; } + private ComponentType getNoteComponentType(NoteStyle noteStyle) { + if (noteStyle == NoteStyle.HEXAGONAL) { + return ComponentType.NOTE_HEXAGONAL; + } + if (noteStyle == NoteStyle.BOX) { + return ComponentType.NOTE_BOX; + } + return ComponentType.NOTE; + } + public void drawU(UGraphic ug) { final StringBounder stringBounder = ug.getStringBounder(); final Component comp = getComponent(stringBounder); diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/SequenceDiagramFileMakerTeoz.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/SequenceDiagramFileMakerTeoz.java index 921ef67cb..74bea2c4f 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/SequenceDiagramFileMakerTeoz.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/SequenceDiagramFileMakerTeoz.java @@ -41,24 +41,25 @@ import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.FileFormatOption; import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.activitydiagram3.ftile.EntityImageLegend; import net.sourceforge.plantuml.api.ImageDataSimple; import net.sourceforge.plantuml.core.ImageData; import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.graphic.HorizontalAlignment; import net.sourceforge.plantuml.graphic.HtmlColor; import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlockUtils; import net.sourceforge.plantuml.graphic.VerticalAlignment; import net.sourceforge.plantuml.png.PngTitler; import net.sourceforge.plantuml.real.Real; +import net.sourceforge.plantuml.real.RealOrigin; import net.sourceforge.plantuml.real.RealUtils; import net.sourceforge.plantuml.sequencediagram.Participant; import net.sourceforge.plantuml.sequencediagram.SequenceDiagram; import net.sourceforge.plantuml.sequencediagram.graphic.FileMaker; -import net.sourceforge.plantuml.skin.Area; import net.sourceforge.plantuml.skin.Component; import net.sourceforge.plantuml.skin.ComponentType; -import net.sourceforge.plantuml.skin.Context2D; import net.sourceforge.plantuml.skin.SimpleContext2D; import net.sourceforge.plantuml.skin.Skin; import net.sourceforge.plantuml.ugraphic.UGraphic; @@ -77,162 +78,163 @@ public class SequenceDiagramFileMakerTeoz implements FileMaker { this.diagram = sequenceDiagram; this.fileFormatOption = fileFormatOption; this.skin = skin; + this.footer = getFooterOrHeader(FontParam.FOOTER); + this.header = getFooterOrHeader(FontParam.HEADER); + + this.main = new MainTileAdapter(createMainTile()); + this.min1 = ((MainTileAdapter) main).getMinX(stringBounder); + + this.title = getTitle(); + this.legend = getLegend(); + + this.heightEnglober1 = englobers.getOffsetForEnglobers(stringBounder); + this.heightEnglober2 = heightEnglober1 == 0 ? 0 : 10; + + final double totalWidth = MathUtils.max(main.calculateDimension(stringBounder).getWidth(), title + .calculateDimension(stringBounder).getWidth(), footer.calculateDimension(stringBounder).getWidth(), + header.calculateDimension(stringBounder).getWidth(), legend.calculateDimension(stringBounder) + .getWidth()); + final double totalHeight = main.calculateDimension(stringBounder).getHeight() + heightEnglober1 + + heightEnglober2 + title.calculateDimension(stringBounder).getHeight() + + header.calculateDimension(stringBounder).getHeight() + + legend.calculateDimension(stringBounder).getHeight() + + footer.calculateDimension(stringBounder).getHeight(); + this.dimTotal = new Dimension2DDouble(totalWidth, totalHeight); } + private Englobers englobers; + private final StringBounder stringBounder = TextBlockUtils.getDummyStringBounder(); + + private final TextBlock footer; + private final TextBlock header; + + private final TextBlock main; + + private final TextBlock title; + private final TextBlock legend; + private final Dimension2D dimTotal; + private final Real min1; + + private final LivingSpaces livingSpaces = new LivingSpaces(); + private final double heightEnglober1; + private final double heightEnglober2; + public ImageData createOne(OutputStream os, int index, boolean isWithMetadata) throws IOException { - StringBounder stringBounder = TextBlockUtils.getDummyStringBounder(); + final UTranslate min1translate = new UTranslate(-min1.getCurrentValue(), 0); + final UGraphic2 ug2 = (UGraphic2) fileFormatOption.createUGraphic(getSkinParam().getColorMapper(), + diagram.getDpiFactor(fileFormatOption), dimTotal, getSkinParam().getBackgroundColor(), false).apply( + min1translate); - final ISkinParam skinParam = diagram.getSkinParam(); + UGraphic ug = getSkinParam().handwritten() ? new UGraphicHandwritten(ug2) : ug2; + englobers.drawEnglobers(goDownForEnglobers(ug), main.calculateDimension(stringBounder).getHeight() + + this.heightEnglober1 + this.heightEnglober2 / 2, new SimpleContext2D(true)); - final Real origin = RealUtils.createOrigin(); + printAligned(ug, diagram.getAlignmentTeoz(FontParam.HEADER), header); + ug = goDown(ug, header); + + printAligned(ug, HorizontalAlignment.CENTER, title); + ug = goDown(ug, title); + + if (diagram.getLegendVerticalAlignment() == VerticalAlignment.TOP) { + printAligned(ug, diagram.getLegendAlignment(), legend); + ug = goDown(ug, legend); + } + + ug = ug.apply(new UTranslate(0, this.heightEnglober1)); + printAligned(ug, HorizontalAlignment.CENTER, main); + ug = goDown(ug, main); + ug = ug.apply(new UTranslate(0, this.heightEnglober2)); + + if (diagram.getLegendVerticalAlignment() == VerticalAlignment.BOTTOM) { + printAligned(ug, diagram.getLegendAlignment(), legend); + ug = goDown(ug, legend); + } + + printAligned(ug, diagram.getAlignmentTeoz(FontParam.FOOTER), footer); + + ug2.writeImageTOBEMOVED(os, isWithMetadata ? diagram.getMetadata() : null, diagram.getDpi(fileFormatOption)); + + return new ImageDataSimple(dimTotal); + } + + private UGraphic goDownForEnglobers(UGraphic ug) { + ug = goDown(ug, title); + ug = goDown(ug, header); + if (diagram.getLegendVerticalAlignment() == VerticalAlignment.TOP) { + ug = goDown(ug, legend); + } + return ug; + } + + private UGraphic goDown(UGraphic ug, TextBlock size) { + return ug.apply(new UTranslate(0, size.calculateDimension(stringBounder).getHeight())); + } + + public void printAligned(UGraphic ug, HorizontalAlignment align, final TextBlock layer) { + double dx = 0; + if (align == HorizontalAlignment.RIGHT) { + dx = dimTotal.getWidth() - layer.calculateDimension(stringBounder).getWidth(); + } else if (align == HorizontalAlignment.CENTER) { + dx = (dimTotal.getWidth() - layer.calculateDimension(stringBounder).getWidth()) / 2; + } + layer.drawU(ug.apply(new UTranslate(dx, 0))); + } + + private MainTile createMainTile() { + final RealOrigin origin = RealUtils.createOrigin(); Real currentPos = origin.addAtLeast(0); - LivingSpace last = null; - LivingSpaces livingSpaces = new LivingSpaces(); for (Participant p : diagram.participants().values()) { - final LivingSpace livingSpace = new LivingSpace(p, diagram.getEnglober(p), skin, skinParam, currentPos, - diagram.events()); - last = livingSpace; - ((LivingSpaces) livingSpaces).put(p, livingSpace); + final LivingSpace livingSpace = new LivingSpace(p, diagram.getEnglober(p), skin, getSkinParam(), + currentPos, diagram.events()); + livingSpaces.put(p, livingSpace); currentPos = livingSpace.getPosD(stringBounder).addAtLeast(0); } - final MainTile mainTile = new MainTile(diagram, skin, last.getPosD(stringBounder).addAtLeast(0), livingSpaces, - origin); + final TileArguments tileArguments = new TileArguments(stringBounder, currentPos, livingSpaces, skin, + diagram.getSkinParam(), origin); + + this.englobers = new Englobers(tileArguments); + final MainTile mainTile = new MainTile(diagram, tileArguments); mainTile.addConstraints(stringBounder); - origin.compile(); - - final double mainHeight = mainTile.getPreferredHeight(stringBounder) + 2 - * livingSpaces.getHeadHeight(stringBounder); - - final Real min1 = mainTile.getMinX(stringBounder); - final Real max1 = mainTile.getMaxX(stringBounder); - // System.err.println("min1=" + min1.getCurrentValue()); - // System.err.println("max1=" + max1.getCurrentValue()); - - final Component compTitle = getCompTitle(); - - final double mainWidth = max1.getCurrentValue() - min1.getCurrentValue(); - - Dimension2D dimTitle = new Dimension2DDouble(0, 0); - if (compTitle != null) { - dimTitle = compTitle.getPreferredDimension(stringBounder); - } - - final PngTitler footer = getFooter(); - Dimension2D dimFooter = new Dimension2DDouble(0, 0); - if (footer != null && footer.getTextBlock() != null) { - dimFooter = footer.getTextBlock().calculateDimension(stringBounder); - } - - final PngTitler header = getHeader(); - Dimension2D dimHeader = new Dimension2DDouble(0, 0); - if (header != null && header.getTextBlock() != null) { - dimHeader = header.getTextBlock().calculateDimension(stringBounder); - } - - final double totalWidth = MathUtils.max(mainWidth, dimTitle.getWidth(), dimFooter.getWidth(), - dimHeader.getWidth()); - final double totalHeight = mainHeight + dimTitle.getHeight() + dimHeader.getHeight() + dimFooter.getHeight(); - final Dimension2D dim = new Dimension2DDouble(totalWidth, totalHeight); - final UGraphic2 ug2 = (UGraphic2) fileFormatOption.createUGraphic(skinParam.getColorMapper(), - diagram.getDpiFactor(fileFormatOption), dim, skinParam.getBackgroundColor(), false).apply( - new UTranslate(-min1.getCurrentValue(), 0)); - - UGraphic ug = diagram.getSkinParam().handwritten() ? new UGraphicHandwritten(ug2) : ug2; - - if (footer != null && footer.getTextBlock() != null) { - double dx = 0; - if (diagram.getFooterAlignment() == HorizontalAlignment.RIGHT) { - dx = totalWidth - dimFooter.getWidth(); - } else if (diagram.getFooterAlignment() == HorizontalAlignment.CENTER) { - dx = (totalWidth - dimFooter.getWidth()) / 2; - } - footer.getTextBlock().drawU( - ug.apply(new UTranslate(dx, mainHeight + dimTitle.getHeight() + dimHeader.getHeight()))); - } - if (header != null && header.getTextBlock() != null) { - double dx = 0; - if (diagram.getHeaderAlignment() == HorizontalAlignment.RIGHT) { - dx = totalWidth - dimHeader.getWidth(); - } else if (diagram.getHeaderAlignment() == HorizontalAlignment.CENTER) { - dx = (totalWidth - dimHeader.getWidth()) / 2; - } - header.getTextBlock().drawU(ug.apply(new UTranslate(dx, 0))); - } - if (compTitle != null) { - compTitle.drawU(ug.apply(new UTranslate((totalWidth - dimTitle.getWidth()) / 2, 0)), new Area(dimTitle), - new SimpleContext2D(false)); - ug = ug.apply(new UTranslate((totalWidth - mainWidth) / 2, dimTitle.getHeight() + dimHeader.getHeight())); - } - - drawMainTile(ug, mainTile, livingSpaces); - - ug2.writeImageTOBEMOVED(os, isWithMetadata ? diagram.getMetadata() : null, diagram.getDpi(fileFormatOption)); - final Dimension2D info = new Dimension2DDouble(dim.getWidth(), dim.getHeight()); - - // if (fileFormatOption.getFileFormat() == FileFormat.PNG && ug instanceof UGraphicG2d) { - // final Set urls = ((UGraphicG2d) ug).getAllUrlsEncountered(); - // if (urls.size() > 0) { - // if (scale == 0) { - // throw new IllegalStateException(); - // } - // final CMapData cmap = CMapData.cmapString(urls, scale); - // return new ImageDataComplex(info, cmap, null); - // } - // } - return new ImageDataSimple(info); + this.englobers.addConstraints(stringBounder); + origin.compileNow(); + return mainTile; } - private Component getCompTitle() { + public ISkinParam getSkinParam() { + return diagram.getSkinParam(); + } + + private TextBlock getTitle() { final Display title = diagram.getTitle(); - - final Component compTitle; if (title == null) { - compTitle = null; - } else { - compTitle = skin.createComponent(ComponentType.TITLE, null, diagram.getSkinParam(), title); + return new ComponentAdapter(null); } - return compTitle; + final Component compTitle = skin.createComponent(ComponentType.TITLE, null, getSkinParam(), title); + return new ComponentAdapter(compTitle); } - private PngTitler getFooter() { - if (diagram.getFooter() == null) { - return null; + private TextBlock getLegend() { + final Display legend = diagram.getLegend(); + if (legend == null) { + return TextBlockUtils.empty(0, 0); } - final HtmlColor hyperlinkColor = diagram.getSkinParam().getHyperlinkColor(); - final HtmlColor titleColor = diagram.getSkinParam().getFontHtmlColor(FontParam.FOOTER, null); - final String fontFamily = diagram.getSkinParam().getFont(FontParam.FOOTER, null, false).getFamily(null); - final int fontSize = diagram.getSkinParam().getFont(FontParam.FOOTER, null, false).getSize(); - final PngTitler pngTitler = new PngTitler(titleColor, diagram.getFooter(), fontSize, fontFamily, - diagram.getFooterAlignment(), hyperlinkColor, diagram.getSkinParam().useUnderlineForHyperlink()); - return pngTitler; + return EntityImageLegend.create(legend, diagram.getSkinParam()); } - private PngTitler getHeader() { - final HtmlColor hyperlinkColor = diagram.getSkinParam().getHyperlinkColor(); - final HtmlColor titleColor = diagram.getSkinParam().getFontHtmlColor(FontParam.HEADER, null); - final String fontFamily = diagram.getSkinParam().getFont(FontParam.HEADER, null, false).getFamily(null); - final int fontSize = diagram.getSkinParam().getFont(FontParam.HEADER, null, false).getSize(); - final PngTitler pngTitler = new PngTitler(titleColor, diagram.getHeader(), fontSize, fontFamily, - diagram.getHeaderAlignment(), hyperlinkColor, diagram.getSkinParam().useUnderlineForHyperlink()); - return pngTitler; - } - - private void drawMainTile(final UGraphic ug, final MainTile mainTile, LivingSpaces livingSpaces) { - final StringBounder stringBounder = ug.getStringBounder(); - - final Context2D context = new SimpleContext2D(false); - livingSpaces.drawHeads(ug, context, VerticalAlignment.BOTTOM); - - final double headHeight = livingSpaces.getHeadHeight(stringBounder); - - mainTile.drawU(ug.apply(new UTranslate(0, headHeight))); - livingSpaces.drawLifeLines(ug.apply(new UTranslate(0, headHeight)), mainTile.getPreferredHeight(stringBounder), - context); - livingSpaces.drawHeads(ug.apply(new UTranslate(0, mainTile.getPreferredHeight(stringBounder) + headHeight)), - context, VerticalAlignment.TOP); - mainTile.drawForeground(ug.apply(new UTranslate(0, headHeight))); + public TextBlock getFooterOrHeader(final FontParam param) { + final Display display = diagram.getFooterOrHeaderTeoz(param); + if (display == null) { + return new TeozLayer(null, stringBounder, param); + } + final HtmlColor hyperlinkColor = getSkinParam().getHyperlinkColor(); + final HtmlColor titleColor = getSkinParam().getFontHtmlColor(param, null); + final String fontFamily = getSkinParam().getFont(param, null, false).getFamily(null); + final int fontSize = getSkinParam().getFont(param, null, false).getSize(); + final PngTitler pngTitler = new PngTitler(titleColor, display, fontSize, fontFamily, + diagram.getAlignmentTeoz(param), hyperlinkColor, getSkinParam().useUnderlineForHyperlink()); + return new TeozLayer(pngTitler, stringBounder, param); } public int getNbPages() { diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/Stairs2.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/Stairs2.java index ce5e4bf80..e180e519e 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/Stairs2.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/Stairs2.java @@ -48,7 +48,7 @@ public class Stairs2 { private final Map cache = new HashMap(); public void addStep(StairsPosition position, int value, HtmlColor color) { - System.err.println("Stairs2::addStep " + position + " " + value + " color=" + color); + // System.err.println("Stairs2::addStep " + position + " " + value + " color=" + color); assert ys.size() == values.size(); if (ys.size() > 0) { final double lastY = ys.get(ys.size() - 1).getValue(); diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/TeozLayer.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/TeozLayer.java new file mode 100644 index 000000000..670f831c5 --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/TeozLayer.java @@ -0,0 +1,75 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2014, Arnaud Roques + * + * Project Info: http://plantuml.sourceforge.net + * + * 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. + * + * [Java is a trademark or registered trademark of Sun Microsystems, Inc. + * in the United States and other countries.] + * + * Original Author: Arnaud Roques + * + * Revision $Revision: 9591 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.teoz; + +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.png.PngTitler; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +public class TeozLayer implements TextBlock { + + private final PngTitler titler; + private Dimension2D dimension; + private final FontParam param; + + public TeozLayer(PngTitler titler, StringBounder stringBounder, FontParam param) { + this.titler = titler; + this.param = param; + + dimension = new Dimension2DDouble(0, 0); + if (titler != null && titler.getTextBlock() != null) { + dimension = titler.getTextBlock().calculateDimension(stringBounder); + } + } + + public Dimension2D calculateDimension(StringBounder stringBounder) { + return dimension; + } + + public FontParam getParam() { + return param; + } + + public void drawU(UGraphic ug) { + if (titler != null) { + titler.getTextBlock().drawU(ug); + } + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/TileArguments.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/TileArguments.java index 9cad60bc4..6ef53566d 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/TileArguments.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/TileArguments.java @@ -112,6 +112,14 @@ public class TileArguments { return result; } +// public double getAbsoluteMin() { +// return line.getAbsoluteMin(); +// } +// +// public double getAbsoluteMax() { +// return line.getAbsoluteMax(); +// } + // public void ensure(Tile tile) { // getAlpha().ensureLowerThan(tile.getMinX(getStringBounder())); // getOmega().ensureBiggerThan(tile.getMaxX(getStringBounder())); diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/TileBuilder.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/TileBuilder.java index e014f9fbb..6e2e9e1d0 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/TileBuilder.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/TileBuilder.java @@ -39,9 +39,8 @@ import java.util.Iterator; import java.util.List; import net.sourceforge.plantuml.ISkinParam; -import net.sourceforge.plantuml.SkinParamBackcoloredReference; -import net.sourceforge.plantuml.graphic.HtmlColorUtils; import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.real.Real; import net.sourceforge.plantuml.sequencediagram.Delay; import net.sourceforge.plantuml.sequencediagram.Divider; import net.sourceforge.plantuml.sequencediagram.Event; @@ -65,7 +64,8 @@ public class TileBuilder { final Tile tile = TileBuilder.buildOne(it, tileArguments, ev, parent); if (tile != null) { tiles.add(tile); - tileArguments.getOmega().ensureBiggerThan(tile.getMaxX(tileArguments.getStringBounder())); + final Real tmpMax = tile.getMaxX(tileArguments.getStringBounder()); + tileArguments.getOmega().ensureBiggerThan(tmpMax); } } return Collections.unmodifiableList(tiles); @@ -107,8 +107,7 @@ public class TileBuilder { } else if (ev instanceof MessageExo) { final MessageExo exo = (MessageExo) ev; final LivingSpace livingSpace1 = livingSpaces.get(exo.getParticipant()); - tile = new CommunicationExoTile(livingSpace1, exo, skin, skinParam, tileArguments.getOrigin(), - tileArguments.getOmega()); + tile = new CommunicationExoTile(livingSpace1, exo, skin, skinParam, tileArguments); if (exo.getNote() != null) { final NotePosition notePosition = exo.getNotePosition(); if (notePosition == NotePosition.LEFT) { diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/TileWithCallbackY.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/TileWithCallbackY.java new file mode 100644 index 000000000..011238d5e --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/TileWithCallbackY.java @@ -0,0 +1,40 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2014, Arnaud Roques + * + * Project Info: http://plantuml.sourceforge.net + * + * 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. + * + * [Java is a trademark or registered trademark of Sun Microsystems, Inc. + * in the United States and other countries.] + * + * Original Author: Arnaud Roques + * + * Revision $Revision: 4636 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.teoz; + + +public interface TileWithCallbackY extends Tile { + + public void callbackY(double y); +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/YPositionedTile.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/YPositionedTile.java index e5d503590..f99175d94 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/teoz/YPositionedTile.java +++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/YPositionedTile.java @@ -45,6 +45,9 @@ public class YPositionedTile implements UDrawable { public YPositionedTile(Tile tile, double y) { this.tile = tile; this.y = y; + if (tile instanceof TileWithCallbackY) { + ((TileWithCallbackY) tile).callbackY(y); + } } public void drawU(UGraphic ug) { diff --git a/src/net/sourceforge/plantuml/suggest/SuggestEngine.java b/src/net/sourceforge/plantuml/suggest/SuggestEngine.java index adbc43b66..c13100077 100644 --- a/src/net/sourceforge/plantuml/suggest/SuggestEngine.java +++ b/src/net/sourceforge/plantuml/suggest/SuggestEngine.java @@ -40,73 +40,57 @@ import java.util.Iterator; import java.util.List; import net.sourceforge.plantuml.AbstractPSystem; -import net.sourceforge.plantuml.command.Command; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.command.CommandControl; -import net.sourceforge.plantuml.command.CommandExecutionResult; -import net.sourceforge.plantuml.command.ProtectedCommand; import net.sourceforge.plantuml.command.UmlDiagramFactory; import net.sourceforge.plantuml.core.UmlSource; import net.sourceforge.plantuml.utils.StartUtils; +import net.sourceforge.plantuml.version.IteratorCounter; +import net.sourceforge.plantuml.version.IteratorCounterImpl; final public class SuggestEngine { private final UmlDiagramFactory systemFactory; - private final Iterator it; - private final String startLine; - - private String current = ""; - private String previous = ""; + private final IteratorCounter it; public SuggestEngine(UmlSource source, UmlDiagramFactory systemFactory) { this.systemFactory = systemFactory; this.it = source.iterator(); - startLine = next(); + final String startLine = it.next(); if (StartUtils.isArobaseStartDiagram(startLine) == false) { throw new UnsupportedOperationException(); } } - private boolean hasNext() { - return it.hasNext(); - } - - private String next() { - // nb++; - this.previous = this.current; - this.current = it.next(); - return current; - } - public SuggestEngineResult tryToSuggest(AbstractPSystem system) { return executeUmlCommand(system); } private SuggestEngineResult executeUmlCommand(AbstractPSystem system) { - // systemFactory.init(startLine); - while (hasNext()) { - final String s = next(); - if (StartUtils.isArobaseEndDiagram(s)) { + while (it.hasNext()) { + if (StartUtils.isArobaseEndDiagram(it.peek())) { return SuggestEngineResult.SYNTAX_OK; } - final SuggestEngineResult check = checkAndCorrect(s); + final SuggestEngineResult check = checkAndCorrect(); if (check.getStatus() != SuggestEngineStatus.SYNTAX_OK) { return check; } - final CommandControl commandControl = systemFactory.isValid(Arrays.asList(s)); + final CommandControl commandControl = systemFactory.isValid2(it); if (commandControl == CommandControl.OK_PARTIAL) { - final boolean ok = manageMultiline(s); - if (ok == false) { - return SuggestEngineResult.CANNOT_CORRECT; - } + systemFactory.goForwardMultiline(it); + // if (ok == false) { + // return SuggestEngineResult.CANNOT_CORRECT; + // } } else if (commandControl == CommandControl.OK) { -// final Command cmd = new ProtectedCommand(systemFactory.createCommand(Arrays.asList(s))); -// final CommandExecutionResult result = cmd.execute(system, Arrays.asList(s)); -// if (result.isOk() == false) { -// return SuggestEngineResult.CANNOT_CORRECT; -// } + it.next(); + // final Command cmd = new ProtectedCommand(systemFactory.createCommand(Arrays.asList(s))); + // final CommandExecutionResult result = cmd.execute(system, Arrays.asList(s)); + // if (result.isOk() == false) { + // return SuggestEngineResult.CANNOT_CORRECT; + // } } else { - assert false; + return SuggestEngineResult.CANNOT_CORRECT; } } throw new IllegalStateException(); @@ -115,8 +99,8 @@ final public class SuggestEngine { private boolean manageMultiline(final String init) { final List lines = new ArrayList(); lines.add(init); - while (hasNext()) { - final String s = next(); + while (it.hasNext()) { + final String s = it.next(); if (StartUtils.isArobaseEndDiagram(s)) { return false; } @@ -135,15 +119,17 @@ final public class SuggestEngine { } - SuggestEngineResult checkAndCorrect(final String incorrectLine) { - final CommandControl commandControl = systemFactory.isValid(Arrays.asList(incorrectLine)); + SuggestEngineResult checkAndCorrect() { + final CommandControl commandControl = systemFactory.isValid2(it); if (commandControl != CommandControl.NOT_OK) { return SuggestEngineResult.SYNTAX_OK; } - if (incorrectLine.trim().startsWith("{") - && systemFactory.isValid(Arrays.asList(previous + " {")) != CommandControl.NOT_OK) { - return new SuggestEngineResult(previous + " {"); + final String incorrectLine = it.peek(); + + if (StringUtils.trin(incorrectLine).startsWith("{") + && systemFactory.isValid(Arrays.asList(it.peekPrevious() + " {")) != CommandControl.NOT_OK) { + return new SuggestEngineResult(it.peekPrevious() + " {"); } final Collection> all = new ArrayList>(); @@ -154,8 +140,8 @@ final public class SuggestEngine { all.add(new VariatorAddOneCharBetweenWords(incorrectLine, ' ')); // all.add(new VariatorAddTwoChar(incorrectLine, '\"')); - for (Iterator it : all) { - final SuggestEngineResult result = tryThis(it); + for (Iterator it2 : all) { + final SuggestEngineResult result = tryThis(it2); if (result != null) { return result; } @@ -163,18 +149,30 @@ final public class SuggestEngine { return SuggestEngineResult.CANNOT_CORRECT; } - private SuggestEngineResult tryThis(Iterator it) { - while (it.hasNext()) { - final String newS = it.next(); - if (newS.trim().length() == 0) { + private SuggestEngineResult tryThis(Iterator it2) { + while (it2.hasNext()) { + final String newS = it2.next(); + if (StringUtils.trin(newS).length() == 0) { continue; } - final CommandControl commandControl = systemFactory.isValid(Arrays.asList(newS)); - if (commandControl != CommandControl.NOT_OK) { + final CommandControl commandControl = systemFactory.isValid2(replaceFirstLine(newS)); + if (commandControl == CommandControl.OK) { return new SuggestEngineResult(newS); } } return null; + } + private IteratorCounter replaceFirstLine(String s) { + final List tmp = new ArrayList(); + tmp.add(s); + final Iterator it3 = it.cloneMe(); + if (it3.hasNext()) { + it3.next(); + } + while (it3.hasNext()) { + tmp.add(it3.next()); + } + return new IteratorCounterImpl(tmp); } } diff --git a/src/net/sourceforge/plantuml/suggest/SuggestEngineResult.java b/src/net/sourceforge/plantuml/suggest/SuggestEngineResult.java index 5ff63dc7c..48431c941 100644 --- a/src/net/sourceforge/plantuml/suggest/SuggestEngineResult.java +++ b/src/net/sourceforge/plantuml/suggest/SuggestEngineResult.java @@ -33,6 +33,8 @@ */ package net.sourceforge.plantuml.suggest; +import net.sourceforge.plantuml.StringUtils; + public class SuggestEngineResult { @@ -77,7 +79,7 @@ public class SuggestEngineResult { } public SuggestEngineResult(String suggestedLine) { - if (suggestedLine.trim().length() == 0) { + if (StringUtils.trin(suggestedLine).length() == 0) { throw new IllegalArgumentException(); } this.status = SuggestEngineStatus.ONE_SUGGESTION; diff --git a/src/net/sourceforge/plantuml/svek/Bibliotekon.java b/src/net/sourceforge/plantuml/svek/Bibliotekon.java index 539daec38..9ccd40d34 100644 --- a/src/net/sourceforge/plantuml/svek/Bibliotekon.java +++ b/src/net/sourceforge/plantuml/svek/Bibliotekon.java @@ -180,4 +180,13 @@ public class Bibliotekon { throw new IllegalArgumentException(); } + public IEntity getOnlyOther(IEntity entity) { + for (Line line : allLines) { + final IEntity other = line.getOther(entity); + if (other != null) { + return other; + } + } + return null; + } } diff --git a/src/net/sourceforge/plantuml/svek/CucaDiagramFileMakerSvek.java b/src/net/sourceforge/plantuml/svek/CucaDiagramFileMakerSvek.java index 130bc421d..9fe523e70 100644 --- a/src/net/sourceforge/plantuml/svek/CucaDiagramFileMakerSvek.java +++ b/src/net/sourceforge/plantuml/svek/CucaDiagramFileMakerSvek.java @@ -120,8 +120,6 @@ public final class CucaDiagramFileMakerSvek implements CucaDiagramFileMaker { result = addTitle(result); result = addHeaderAndFooter(result); - final FileFormat fileFormat = fileFormatOption.getFileFormat(); - final String widthwarning = diagram.getSkinParam().getValue("widthwarning"); if (widthwarning != null && widthwarning.matches("\\d+")) { this.warningOrError = svek2.getBibliotekon().getWarningOrError(Integer.parseInt(widthwarning)); @@ -135,7 +133,7 @@ public final class CucaDiagramFileMakerSvek implements CucaDiagramFileMaker { result.getBackcolor(), fileFormatOption.isWithMetadata() ? diagram.getMetadata() : null, warningOrError, 0, 10, diagram.getAnimation(), diagram.getSkinParam().handwritten()); imageBuilder.addUDrawable(result); - return imageBuilder.writeImageTOBEMOVED(fileFormat, os); + return imageBuilder.writeImageTOBEMOVED(fileFormatOption, os); } diff --git a/src/net/sourceforge/plantuml/svek/CucaDiagramFileMakerSvek2.java b/src/net/sourceforge/plantuml/svek/CucaDiagramFileMakerSvek2.java index 2dc3e373f..dd9ec2d23 100644 --- a/src/net/sourceforge/plantuml/svek/CucaDiagramFileMakerSvek2.java +++ b/src/net/sourceforge/plantuml/svek/CucaDiagramFileMakerSvek2.java @@ -52,6 +52,7 @@ import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.Pragma; import net.sourceforge.plantuml.SkinParamForecolored; import net.sourceforge.plantuml.SkinParamSameClassWidth; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.UmlDiagramType; import net.sourceforge.plantuml.core.UmlSource; import net.sourceforge.plantuml.cucadiagram.Display; @@ -107,6 +108,7 @@ import net.sourceforge.plantuml.svek.image.EntityImageState2; import net.sourceforge.plantuml.svek.image.EntityImageStateBorder; import net.sourceforge.plantuml.svek.image.EntityImageStateEmptyDescription; import net.sourceforge.plantuml.svek.image.EntityImageSynchroBar; +import net.sourceforge.plantuml.svek.image.EntityImageTips; import net.sourceforge.plantuml.svek.image.EntityImageUseCase; public final class CucaDiagramFileMakerSvek2 { @@ -241,7 +243,7 @@ public final class CucaDiagramFileMakerSvek2 { final Pattern pGraph = Pattern.compile("(?mi)!-- generated by graphviz(.*)"); final Matcher mGraph = pGraph.matcher(svg); if (mGraph.find()) { - return mGraph.group(1).trim(); + return StringUtils.trin(mGraph.group(1)); } return null; } @@ -460,6 +462,9 @@ public final class CucaDiagramFileMakerSvek2 { if (leaf.getEntityType() == LeafType.PSEUDO_STATE) { return new EntityImagePseudoState(leaf, skinParam); } + if (leaf.getEntityType() == LeafType.TIPS) { + return new EntityImageTips(leaf, skinParam, bibliotekon, portionShower); + } throw new UnsupportedOperationException(leaf.getEntityType().toString()); } diff --git a/src/net/sourceforge/plantuml/svek/Line.java b/src/net/sourceforge/plantuml/svek/Line.java index cf2e9bc55..dbe2c530f 100644 --- a/src/net/sourceforge/plantuml/svek/Line.java +++ b/src/net/sourceforge/plantuml/svek/Line.java @@ -845,4 +845,11 @@ public class Line implements Moveable, Hideable { return new Point2D.Double(dx + end.getX(), dy + end.getY()); } + public IEntity getOther(IEntity entity) { + if (link.contains(entity)) { + return link.getOther(entity); + } + return null; + } + } diff --git a/src/net/sourceforge/plantuml/svek/Shape.java b/src/net/sourceforge/plantuml/svek/Shape.java index d3baad0d8..6bbf6eddc 100644 --- a/src/net/sourceforge/plantuml/svek/Shape.java +++ b/src/net/sourceforge/plantuml/svek/Shape.java @@ -260,4 +260,8 @@ public class Shape implements Positionable, IShapePseudo, Hideable { return octagon; } + public Point2D getPoint2D(double x, double y) { + return new Point2D.Double(minX + x, minY + y); + } + } diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageComponent.java b/src/net/sourceforge/plantuml/svek/image/EntityImageComponent.java index 4abb16d30..799fe9cc3 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageComponent.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageComponent.java @@ -75,7 +75,7 @@ public class EntityImageComponent extends AbstractEntityImage { final TextBlock desc = entity.getDisplay().isWhite() ? TextBlockUtils.empty(0, 0) : new BodyEnhanced( entity.getDisplay(), symbol.getFontParam(), skinParam, HorizontalAlignment.CENTER, stereotype, - symbol.manageHorizontalLine(), false); + symbol.manageHorizontalLine(), false, false); this.url = entity.getUrl99(); diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageLollipopInterfaceEye2.java b/src/net/sourceforge/plantuml/svek/image/EntityImageLollipopInterfaceEye2.java index 36ac1cfa7..50e4f66e8 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageLollipopInterfaceEye2.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageLollipopInterfaceEye2.java @@ -79,7 +79,7 @@ public class EntityImageLollipopInterfaceEye2 extends AbstractEntityImage { } this.desc = new BodyEnhanced(entity.getDisplay(), symbol.getFontParam(), skinParam, HorizontalAlignment.CENTER, - stereotype, symbol.manageHorizontalLine(), false); + stereotype, symbol.manageHorizontalLine(), false, false); this.url = entity.getUrl99(); diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageNote.java b/src/net/sourceforge/plantuml/svek/image/EntityImageNote.java index 7e8457de0..018322519 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageNote.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageNote.java @@ -100,7 +100,7 @@ public class EntityImageNote extends AbstractEntityImage implements Stencil { } else { noteBackgroundColor = entity.getSpecificBackColor(); } - borderColor = rose.getHtmlColor(skinParam, ColorParam.noteBorder); + this.borderColor = rose.getHtmlColor(skinParam, ColorParam.noteBorder); final HtmlColor fontColor = rose.getFontColor(skinParam, FontParam.NOTE); final UFont fontNote = skinParam.getFont(FontParam.NOTE, null, false); @@ -113,7 +113,7 @@ public class EntityImageNote extends AbstractEntityImage implements Stencil { } } - private static ISkinParam getSkin(ISkinParam skinParam, IEntity entity) { + static ISkinParam getSkin(ISkinParam skinParam, IEntity entity) { final Stereotype stereotype = entity.getStereotype(); HtmlColor back = entity.getSpecificBackColor(); if (back != null) { diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageState2.java b/src/net/sourceforge/plantuml/svek/image/EntityImageState2.java index 4797d5c64..407bbce92 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageState2.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageState2.java @@ -90,7 +90,7 @@ public class EntityImageState2 extends AbstractEntityImage { TextBlock stereo = TextBlockUtils.empty(0, 0); final TextBlock desc = new BodyEnhanced(entity.getDisplay(), symbol.getFontParam(), skinParam, - HorizontalAlignment.CENTER, stereotype, symbol.manageHorizontalLine(), false); + HorizontalAlignment.CENTER, stereotype, symbol.manageHorizontalLine(), false, false); asSmall = symbol.asSmall(desc, stereo, ctx); diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageTips.java b/src/net/sourceforge/plantuml/svek/image/EntityImageTips.java new file mode 100644 index 000000000..1a019e184 --- /dev/null +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageTips.java @@ -0,0 +1,153 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009-2014, Arnaud Roques + * + * Project Info: http://plantuml.sourceforge.net + * + * 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. + * + * [Java is a trademark or registered trademark of Sun Microsystems, Inc. + * in the United States and other countries.] + * + * Original Author: Arnaud Roques + * + * Revision $Revision: 5183 $ + * + */ +package net.sourceforge.plantuml.svek.image; + +import java.awt.geom.Dimension2D; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.util.Map; + +import net.sourceforge.plantuml.ColorParam; +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.ISkinParam; +import net.sourceforge.plantuml.cucadiagram.BlockMember; +import net.sourceforge.plantuml.cucadiagram.BodyEnhanced2; +import net.sourceforge.plantuml.cucadiagram.Display; +import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.ILeaf; +import net.sourceforge.plantuml.cucadiagram.PortionShower; +import net.sourceforge.plantuml.graphic.FontConfiguration; +import net.sourceforge.plantuml.graphic.HorizontalAlignment; +import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.skin.rose.Rose; +import net.sourceforge.plantuml.svek.AbstractEntityImage; +import net.sourceforge.plantuml.svek.Bibliotekon; +import net.sourceforge.plantuml.svek.Shape; +import net.sourceforge.plantuml.svek.ShapeType; +import net.sourceforge.plantuml.ugraphic.UFont; +import net.sourceforge.plantuml.ugraphic.UGraphic; +import net.sourceforge.plantuml.ugraphic.UTranslate; + +public class EntityImageTips extends AbstractEntityImage { + + final private Rose rose = new Rose(); + private final ISkinParam skinParam; + + private final HtmlColor noteBackgroundColor; + private final HtmlColor borderColor; + + private final Bibliotekon bibliotekon; + private PortionShower portionShower; + + private final double ySpacing = 10; + + public EntityImageTips(ILeaf entity, ISkinParam skinParam, Bibliotekon bibliotekon, PortionShower portionShower) { + super(entity, EntityImageNote.getSkin(skinParam, entity)); + this.skinParam = skinParam; + this.bibliotekon = bibliotekon; + this.portionShower = portionShower; + + if (entity.getSpecificBackColor() == null) { + noteBackgroundColor = rose.getHtmlColor(skinParam, ColorParam.noteBackground); + } else { + noteBackgroundColor = entity.getSpecificBackColor(); + } + this.borderColor = rose.getHtmlColor(skinParam, ColorParam.noteBorder); + } + + public ShapeType getShapeType() { + return ShapeType.RECTANGLE; + } + + public int getShield() { + return 0; + } + + public Dimension2D calculateDimension(StringBounder stringBounder) { + double width = 0; + double height = 0; + for (Map.Entry ent : getEntity().getTips().entrySet()) { + final Display display = ent.getValue(); + final Dimension2D dim = getOpale(display).calculateDimension(stringBounder); + height += dim.getHeight(); + height += ySpacing; + width = Math.max(width, dim.getWidth()); + } + return new Dimension2DDouble(width, height); + } + + public void drawU(UGraphic ug) { + final StringBounder stringBounder = ug.getStringBounder(); + + final IEntity other = bibliotekon.getOnlyOther(getEntity()); + final BlockMember otherBlockMember = other.getBody(portionShower); + // .asTextBlock(FontParam.CLASS_ATTRIBUTE, skinParam); + + final Shape shapeMe = bibliotekon.getShape(getEntity()); + final Shape shapeOther = bibliotekon.getShape(other); +// System.err.println("shapeMe=" + shapeMe.getPosition() + " " + shapeMe.getSize()); +// System.err.println("shapeOther=" + shapeOther.getPosition() + " " + shapeOther.getSize()); + bibliotekon.getShape(getEntity()); + for (Map.Entry ent : getEntity().getTips().entrySet()) { + final Display display = ent.getValue(); + final Rectangle2D memberPosition = otherBlockMember.getPosition(ent.getKey(), stringBounder, + FontParam.CLASS_ATTRIBUTE, skinParam); +// System.err.println("memberPosition=" + memberPosition); + final Opale opale = getOpale(display); + final Point2D pp1 = shapeMe.getPoint2D(0, 0); + final Point2D pp2 = shapeOther.getPoint2D(0, 0); + opale.setOpale(Direction.LEFT, pp1, pp2); + final Dimension2D dim = opale.calculateDimension(stringBounder); + opale.drawU(ug); + ug = ug.apply(new UTranslate(0, dim.getHeight() + ySpacing)); + } + + } + + private Opale getOpale(final Display display) { + final HtmlColor fontColor = rose.getFontColor(skinParam, FontParam.NOTE); + final UFont fontNote = skinParam.getFont(FontParam.NOTE, null, false); + + final TextBlock textBlock = new BodyEnhanced2(display, FontParam.NOTE, skinParam, HorizontalAlignment.LEFT, + new FontConfiguration(fontNote, fontColor, skinParam.getHyperlinkColor(), + skinParam.useUnderlineForHyperlink())); + final Opale opale = new Opale(borderColor, noteBackgroundColor, textBlock, skinParam.shadowing(), false); + return opale; + } + +} diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageUseCase.java b/src/net/sourceforge/plantuml/svek/image/EntityImageUseCase.java index d6c8b5184..464ae652c 100644 --- a/src/net/sourceforge/plantuml/svek/image/EntityImageUseCase.java +++ b/src/net/sourceforge/plantuml/svek/image/EntityImageUseCase.java @@ -76,7 +76,7 @@ public class EntityImageUseCase extends AbstractEntityImage { final Stereotype stereotype = entity.getStereotype(); final TextBlock tmp = new BodyEnhanced(entity.getDisplay(), FontParam.USECASE, skinParam, - HorizontalAlignment.CENTER, stereotype, true, false); + HorizontalAlignment.CENTER, stereotype, true, false, false); if (stereotype == null || stereotype.getLabel(false) == null) { this.desc = tmp; diff --git a/src/net/sourceforge/plantuml/svg/SvgData.java b/src/net/sourceforge/plantuml/svg/SvgData.java index be4568794..9360f1221 100644 --- a/src/net/sourceforge/plantuml/svg/SvgData.java +++ b/src/net/sourceforge/plantuml/svg/SvgData.java @@ -37,6 +37,8 @@ import java.util.StringTokenizer; import java.util.regex.Matcher; import java.util.regex.Pattern; +import net.sourceforge.plantuml.StringUtils; + public final class SvgData { private String svg; @@ -92,8 +94,8 @@ public final class SvgData { while (st.hasMoreTokens()) { final String token = st.nextToken(); final StringTokenizer st2 = new StringTokenizer(token, ","); - final double x = Double.parseDouble(st2.nextToken().trim()); - final double y = Double.parseDouble(st2.nextToken().trim()); + final double x = Double.parseDouble(StringUtils.trin(st2.nextToken())); + final double y = Double.parseDouble(StringUtils.trin(st2.nextToken())); if (x < minX) { minX = x; } diff --git a/src/net/sourceforge/plantuml/svg/SvgGraphics.java b/src/net/sourceforge/plantuml/svg/SvgGraphics.java index 54b7b04ee..36847921d 100644 --- a/src/net/sourceforge/plantuml/svg/SvgGraphics.java +++ b/src/net/sourceforge/plantuml/svg/SvgGraphics.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 15883 $ + * Revision $Revision: 16115 $ * */ package net.sourceforge.plantuml.svg; @@ -55,6 +55,7 @@ import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import net.sourceforge.plantuml.Log; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.code.Base64Coder; import net.sourceforge.plantuml.eps.EpsGraphics; import net.sourceforge.plantuml.graphic.HtmlColorGradient; @@ -62,7 +63,6 @@ import net.sourceforge.plantuml.ugraphic.ColorMapper; import net.sourceforge.plantuml.ugraphic.UPath; import net.sourceforge.plantuml.ugraphic.USegment; import net.sourceforge.plantuml.ugraphic.USegmentType; -import net.sourceforge.plantuml.StringUtils; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -270,19 +270,26 @@ public class SvgGraphics { } public void closeLink() { - final Element element = pendingLink2.get(0); - pendingLink2.remove(0); - getG().appendChild(element); + if (pendingLink2.size() > 0) { + final Element element = pendingLink2.get(0); + pendingLink2.remove(0); + getG().appendChild(element); + } } private final List pendingLink2 = new ArrayList(); - public void openLink(String url, String title) { + public void openLink(String url, String title, String target) { if (url == null) { throw new IllegalArgumentException(); } + if (pendingLink2.size() > 0) { + closeLink(); + } + pendingLink2.add(0, (Element) document.createElement("a")); + pendingLink2.get(0).setAttribute("target", target); pendingLink2.get(0).setAttribute("xlink:href", url); if (title == null) { pendingLink2.get(0).setAttribute("xlink:title", url); @@ -386,7 +393,8 @@ public class SvgGraphics { } public void text(String text, double x, double y, String fontFamily, int fontSize, String fontWeight, - String fontStyle, String textDecoration, double textLength, Map attributes) { + String fontStyle, String textDecoration, double textLength, Map attributes, + String textBackColor) { if (hidden == false) { final Element elt = (Element) document.createElement("text"); elt.setAttribute("x", format(x)); @@ -408,6 +416,10 @@ public class SvgGraphics { if (fontFamily != null) { elt.setAttribute("font-family", fontFamily); } + if (textBackColor != null) { + final String backFilterId = getFilterBackColor(textBackColor); + elt.setAttribute("filter", "url(#" + backFilterId + ")"); + } for (Map.Entry ent : attributes.entrySet()) { elt.setAttribute(ent.getKey(), ent.getValue()); } @@ -430,8 +442,33 @@ public class SvgGraphics { ensureVisible(x + textLength, y); } - public final Element getDefs() { - return defs; + private final Map filterBackColor = new HashMap(); + + private String getIdFilterBackColor(String color) { + String result = filterBackColor.get(color); + if (result == null) { + result = "b" + filterBackColor.size(); + filterBackColor.put(color, result); + } + return result; + } + + private String getFilterBackColor(String color) { + String id = filterBackColor.get(color); + if (id != null) { + return id; + } + id = getIdFilterBackColor(color); + final Element filter = (Element) document.createElement("filter"); + filter.setAttribute("id", id); + filter.setAttribute("x", "0"); + filter.setAttribute("y", "0"); + filter.setAttribute("width", "1"); + filter.setAttribute("height", "1"); + addFilter(filter, "feFlood", "flood-color", color); + addFilter(filter, "feComposite", "in", "SourceGraphic"); + defs.appendChild(filter); + return id; } private Transformer getTransformer() throws TransformerException { diff --git a/src/net/sourceforge/plantuml/swing/ImageWindow2.java b/src/net/sourceforge/plantuml/swing/ImageWindow2.java index cd4c2d36a..4f25b30ee 100644 --- a/src/net/sourceforge/plantuml/swing/ImageWindow2.java +++ b/src/net/sourceforge/plantuml/swing/ImageWindow2.java @@ -64,6 +64,7 @@ import javax.swing.ListModel; import javax.swing.WindowConstants; import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.FileFormatOption; import net.sourceforge.plantuml.GeneratedImage; import net.sourceforge.plantuml.graphic.GraphicStrings; import net.sourceforge.plantuml.ugraphic.ColorMapperIdentity; @@ -214,7 +215,7 @@ class ImageWindow2 extends JFrame { imageBuilder.addUDrawable(error); final ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { - imageBuilder.writeImageTOBEMOVED(FileFormat.PNG, baos); + imageBuilder.writeImageTOBEMOVED(new FileFormatOption(FileFormat.PNG), baos); baos.close(); image = ImageIO.read(new ByteArrayInputStream(baos.toByteArray())); } catch (IOException e) { diff --git a/src/net/sourceforge/plantuml/turing/PSystemTuring.java b/src/net/sourceforge/plantuml/turing/PSystemTuring.java index 7946cc5c9..bca09a466 100644 --- a/src/net/sourceforge/plantuml/turing/PSystemTuring.java +++ b/src/net/sourceforge/plantuml/turing/PSystemTuring.java @@ -65,7 +65,7 @@ public class PSystemTuring extends AbstractPSystem { final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, result.getBackcolor(), getMetadata(), null, 0, 0, null, false); imageBuilder.addUDrawable(result); - return imageBuilder.writeImageTOBEMOVED(fileFormat.getFileFormat(), os); + return imageBuilder.writeImageTOBEMOVED(fileFormat, os); } private GraphicStrings getGraphicStrings() throws IOException { diff --git a/src/net/sourceforge/plantuml/ugraphic/FontChecker.java b/src/net/sourceforge/plantuml/ugraphic/FontChecker.java index a74088a4d..bcaa26030 100644 --- a/src/net/sourceforge/plantuml/ugraphic/FontChecker.java +++ b/src/net/sourceforge/plantuml/ugraphic/FontChecker.java @@ -52,6 +52,7 @@ import javax.imageio.ImageIO; import javax.xml.transform.TransformerException; import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.FileFormatOption; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.HtmlColorUtils; import net.sourceforge.plantuml.graphic.TextBlockUtils; @@ -179,7 +180,7 @@ public class FontChecker { } }); final ByteArrayOutputStream os = new ByteArrayOutputStream(); - imageBuilder.writeImageTOBEMOVED(FileFormat.PNG, os); + imageBuilder.writeImageTOBEMOVED(new FileFormatOption(FileFormat.PNG), os); os.close(); return ImageIO.read(new ByteArrayInputStream(os.toByteArray())); } diff --git a/src/net/sourceforge/plantuml/ugraphic/ImageBuilder.java b/src/net/sourceforge/plantuml/ugraphic/ImageBuilder.java index 797be035f..048fe20cf 100644 --- a/src/net/sourceforge/plantuml/ugraphic/ImageBuilder.java +++ b/src/net/sourceforge/plantuml/ugraphic/ImageBuilder.java @@ -54,7 +54,9 @@ import net.sourceforge.plantuml.CMapData; import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.EmptyImageBuilder; import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.FileFormatOption; import net.sourceforge.plantuml.FileUtils; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.anim.AffineTransformation; import net.sourceforge.plantuml.anim.Animation; @@ -76,7 +78,6 @@ import net.sourceforge.plantuml.ugraphic.html5.UGraphicHtml5; import net.sourceforge.plantuml.ugraphic.svg.UGraphicSvg; import net.sourceforge.plantuml.ugraphic.tikz.UGraphicTikz; import net.sourceforge.plantuml.ugraphic.visio.UGraphicVdx; -import net.sourceforge.plantuml.StringUtils; public class ImageBuilder { @@ -114,16 +115,17 @@ public class ImageBuilder { this.udrawable = udrawable; } - public ImageData writeImageTOBEMOVED(FileFormat fileFormat, OutputStream os) throws IOException { + public ImageData writeImageTOBEMOVED(FileFormatOption fileFormatOption, OutputStream os) throws IOException { + final FileFormat fileFormat = fileFormatOption.getFileFormat(); if (fileFormat == FileFormat.MJPEG) { return writeImageMjpeg(os); } else if (fileFormat == FileFormat.ANIMATED_GIF) { return writeImageAnimatedGif(os); } - return writeImageTOBEMOVED(fileFormat, os, affineTransformations); + return writeImageTOBEMOVED(fileFormatOption, os, affineTransformations); } - private ImageData writeImageTOBEMOVED(FileFormat fileFormat, OutputStream os, Animation affineTransforms) + private ImageData writeImageTOBEMOVED(FileFormatOption fileFormatOption, OutputStream os, Animation affineTransforms) throws IOException { final LimitFinder limitFinder = new LimitFinder(TextBlockUtils.getDummyStringBounder(), true); udrawable.drawU(limitFinder); @@ -139,7 +141,7 @@ public class ImageBuilder { dy = -minmax.getMinY(); } - final UGraphic2 ug = createUGraphic(fileFormat, dim, affineTransforms, dx, dy); + final UGraphic2 ug = createUGraphic(fileFormatOption, dim, affineTransforms, dx, dy); udrawable.drawU(handwritten(ug.apply(new UTranslate(margin1, margin1)))); ug.writeImageTOBEMOVED(os, metadata, 96); os.flush(); @@ -222,7 +224,7 @@ public class ImageBuilder { private Image getAviImage(AffineTransformation affineTransform) throws IOException { final ByteArrayOutputStream baos = new ByteArrayOutputStream(); - writeImageTOBEMOVED(FileFormat.PNG, baos, Animation.singleton(affineTransform)); + writeImageTOBEMOVED(new FileFormatOption(FileFormat.PNG), baos, Animation.singleton(affineTransform)); baos.close(); final ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); @@ -231,13 +233,14 @@ public class ImageBuilder { return im; } - private UGraphic2 createUGraphic(FileFormat fileFormat, final Dimension2D dim, Animation affineTransforms, + private UGraphic2 createUGraphic(FileFormatOption fileFormatOption, final Dimension2D dim, Animation affineTransforms, double dx, double dy) { + final FileFormat fileFormat = fileFormatOption.getFileFormat(); switch (fileFormat) { case PNG: return createUGraphicPNG(colorMapper, dpiFactor, dim, mybackcolor, affineTransforms, dx, dy); case SVG: - return createUGraphicSVG(colorMapper, dpiFactor, dim, mybackcolor); + return createUGraphicSVG(colorMapper, dpiFactor, dim, mybackcolor, fileFormatOption.getSvgLinkTarget()); case EPS: return new UGraphicEps(colorMapper, EpsStrategy.getDefault2()); case EPS_TEXT: @@ -253,18 +256,18 @@ public class ImageBuilder { } } - private UGraphic2 createUGraphicSVG(ColorMapper colorMapper, double scale, Dimension2D dim, HtmlColor mybackcolor) { + private UGraphic2 createUGraphicSVG(ColorMapper colorMapper, double scale, Dimension2D dim, HtmlColor mybackcolor, String svgLinkTarget) { Color backColor = Color.WHITE; if (mybackcolor instanceof HtmlColorSimple) { backColor = colorMapper.getMappedColor(mybackcolor); } final UGraphicSvg ug; if (mybackcolor instanceof HtmlColorGradient) { - ug = new UGraphicSvg(colorMapper, (HtmlColorGradient) mybackcolor, false, scale); + ug = new UGraphicSvg(colorMapper, (HtmlColorGradient) mybackcolor, false, scale, svgLinkTarget); } else if (backColor == null || backColor.equals(Color.WHITE)) { - ug = new UGraphicSvg(colorMapper, false, scale); + ug = new UGraphicSvg(colorMapper, false, scale, svgLinkTarget); } else { - ug = new UGraphicSvg(colorMapper, StringUtils.getAsHtml(backColor), false, scale); + ug = new UGraphicSvg(colorMapper, StringUtils.getAsHtml(backColor), false, scale, svgLinkTarget); } return ug; diff --git a/src/net/sourceforge/plantuml/ugraphic/UGraphicUtils.java b/src/net/sourceforge/plantuml/ugraphic/UGraphicUtils.java index fb0642073..bc4bf8953 100644 --- a/src/net/sourceforge/plantuml/ugraphic/UGraphicUtils.java +++ b/src/net/sourceforge/plantuml/ugraphic/UGraphicUtils.java @@ -71,7 +71,7 @@ public abstract class UGraphicUtils { PngIO.write(im, os, fileFormatOption.isWithMetadata() ? metadata : null, 96); } else if (fileFormat == FileFormat.SVG) { final UGraphicSvg svg = new UGraphicSvg(colorMapper, StringUtils.getAsHtml(colorMapper - .getMappedColor(background)), false, 1.0); + .getMappedColor(background)), false, 1.0, fileFormatOption.getSvgLinkTarget()); image.drawU(svg); svg.createXml(os); } else if (fileFormat == FileFormat.EPS) { diff --git a/src/net/sourceforge/plantuml/ugraphic/svg/DriverTextSvg.java b/src/net/sourceforge/plantuml/ugraphic/svg/DriverTextSvg.java index c42b1cf33..b7291670c 100644 --- a/src/net/sourceforge/plantuml/ugraphic/svg/DriverTextSvg.java +++ b/src/net/sourceforge/plantuml/ugraphic/svg/DriverTextSvg.java @@ -31,7 +31,9 @@ */ package net.sourceforge.plantuml.ugraphic.svg; +import java.awt.Color; import java.awt.geom.Dimension2D; +import java.awt.geom.Rectangle2D; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.FontStyle; @@ -83,6 +85,11 @@ public class DriverTextSvg implements UDriver { textDecoration = "line-through"; } + String backColor = null; + if (fontConfiguration.containsStyle(FontStyle.BACKCOLOR)) { + backColor = StringUtils.getAsHtml(mapper.getMappedColor(fontConfiguration.getExtendedColor())); + } + svg.setFillColor(StringUtils.getAsHtml(mapper.getMappedColor(fontConfiguration.getColor()))); String text = shape.getText(); if (text.startsWith(" ")) { @@ -92,9 +99,9 @@ public class DriverTextSvg implements UDriver { text = text.substring(1); } } - text = text.trim(); + text = StringUtils.trin(text); final Dimension2D dim = stringBounder.calculateDimension(font, text); svg.text(text, x, y, font.getFamily(UFontContext.SVG), font.getSize(), fontWeight, fontStyle, textDecoration, - dim.getWidth(), fontConfiguration.getAttributes()); + dim.getWidth(), fontConfiguration.getAttributes(), backColor); } } diff --git a/src/net/sourceforge/plantuml/ugraphic/svg/UGraphicSvg.java b/src/net/sourceforge/plantuml/ugraphic/svg/UGraphicSvg.java index e769d878c..9d53d8617 100644 --- a/src/net/sourceforge/plantuml/ugraphic/svg/UGraphicSvg.java +++ b/src/net/sourceforge/plantuml/ugraphic/svg/UGraphicSvg.java @@ -61,6 +61,7 @@ public class UGraphicSvg extends AbstractUGraphic implements ClipCo private final StringBounder stringBounder; private final boolean textAsPath2; + private final String target; @Override protected AbstractCommonUGraphic copyUGraphic() { @@ -71,19 +72,20 @@ public class UGraphicSvg extends AbstractUGraphic implements ClipCo super(other); this.stringBounder = other.stringBounder; this.textAsPath2 = other.textAsPath2; + this.target = other.target; register(); } - public UGraphicSvg(ColorMapper colorMapper, String backcolor, boolean textAsPath, double scale) { - this(colorMapper, new SvgGraphics(backcolor, scale), textAsPath); + public UGraphicSvg(ColorMapper colorMapper, String backcolor, boolean textAsPath, double scale, String linkTarget) { + this(colorMapper, new SvgGraphics(backcolor, scale), textAsPath, linkTarget); } - public UGraphicSvg(ColorMapper colorMapper, boolean textAsPath, double scale) { - this(colorMapper, new SvgGraphics(scale), textAsPath); + public UGraphicSvg(ColorMapper colorMapper, boolean textAsPath, double scale, String linkTarget) { + this(colorMapper, new SvgGraphics(scale), textAsPath, linkTarget); } - public UGraphicSvg(ColorMapper mapper, HtmlColorGradient gr, boolean textAsPath, double scale) { - this(mapper, new SvgGraphics(scale), textAsPath); + public UGraphicSvg(ColorMapper mapper, HtmlColorGradient gr, boolean textAsPath, double scale, String linkTarget) { + this(mapper, new SvgGraphics(scale), textAsPath, linkTarget); final SvgGraphics svg = getGraphicObject(); svg.paintBackcolorGradient(mapper, gr); @@ -104,10 +106,11 @@ public class UGraphicSvg extends AbstractUGraphic implements ClipCo getGraphicObject().setHidden(false); } - private UGraphicSvg(ColorMapper colorMapper, SvgGraphics svg, boolean textAsPath) { + private UGraphicSvg(ColorMapper colorMapper, SvgGraphics svg, boolean textAsPath, String linkTarget) { super(colorMapper, svg); - stringBounder = TextBlockUtils.getDummyStringBounder(); + this.stringBounder = TextBlockUtils.getDummyStringBounder(); this.textAsPath2 = textAsPath; + this.target = linkTarget; register(); } @@ -145,7 +148,7 @@ public class UGraphicSvg extends AbstractUGraphic implements ClipCo } public void startUrl(Url url) { - getGraphicObject().openLink(url.getUrl(), url.getTooltip()); + getGraphicObject().openLink(url.getUrl(), url.getTooltip(), target); } public void closeAction() { diff --git a/src/net/sourceforge/plantuml/ugraphic/visio/DriverTextVdx.java b/src/net/sourceforge/plantuml/ugraphic/visio/DriverTextVdx.java index d1827411c..aae273492 100644 --- a/src/net/sourceforge/plantuml/ugraphic/visio/DriverTextVdx.java +++ b/src/net/sourceforge/plantuml/ugraphic/visio/DriverTextVdx.java @@ -33,6 +33,7 @@ package net.sourceforge.plantuml.ugraphic.visio; import java.awt.geom.Dimension2D; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.ugraphic.ColorMapper; @@ -67,7 +68,7 @@ public class DriverTextVdx implements UDriver { } } - text = text.trim(); + text = StringUtils.trin(text); final Dimension2D dim = stringBounder.calculateDimension(font, text); visio.text(text, x, y, font.getFamily(UFontContext.SVG), font.getSize(), dim.getWidth(), dim.getHeight(), fontConfiguration.getAttributes()); diff --git a/src/net/sourceforge/plantuml/utils/MathUtils.java b/src/net/sourceforge/plantuml/utils/MathUtils.java index 418a1e3c5..5fdf2d5be 100644 --- a/src/net/sourceforge/plantuml/utils/MathUtils.java +++ b/src/net/sourceforge/plantuml/utils/MathUtils.java @@ -40,11 +40,15 @@ public class MathUtils { } public static double max(double a, double b, double c) { - return Math.max(Math.max(a, b), c); + return max(max(a, b), c); } public static double max(double a, double b, double c, double d) { - return Math.max(Math.max(a, b), Math.max(c, d)); + return max(max(a, b), max(c, d)); + } + + public static double max(double a, double b, double c, double d, double e) { + return max(max(a, b, c), max(d, e)); } public static double limitation(double v, double min, double max) { diff --git a/src/net/sourceforge/plantuml/utils/StartUtils.java b/src/net/sourceforge/plantuml/utils/StartUtils.java index 2eeb311fb..4af1515f0 100644 --- a/src/net/sourceforge/plantuml/utils/StartUtils.java +++ b/src/net/sourceforge/plantuml/utils/StartUtils.java @@ -36,27 +36,28 @@ package net.sourceforge.plantuml.utils; import java.util.regex.Matcher; import java.util.regex.Pattern; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.command.regex.MyPattern; public class StartUtils { public static boolean isArobaseStartDiagram(String s) { - s = s.trim(); + s = StringUtils.trinNoTrace(s); return s.startsWith("@start"); } public static boolean isArobaseEndDiagram(String s) { - s = s.trim(); + s = StringUtils.trinNoTrace(s); return s.startsWith("@end"); } public static boolean isArobasePauseDiagram(String s) { - s = s.trim(); + s = StringUtils.trinNoTrace(s); return s.startsWith("@pause"); } public static boolean isArobaseUnpauseDiagram(String s) { - s = s.trim(); + s = StringUtils.trinNoTrace(s); return s.startsWith("@unpause"); } @@ -65,7 +66,7 @@ public class StartUtils { public static String getPossibleAppend(String s) { final Matcher m = append.matcher(s); if (m.find()) { - return s.substring(m.group(0).length()).trim(); + return StringUtils.trin(s.substring(m.group(0).length())); } return null; } diff --git a/src/net/sourceforge/plantuml/version/IteratorCounter.java b/src/net/sourceforge/plantuml/version/IteratorCounter.java index e74b3777e..9c21de799 100644 --- a/src/net/sourceforge/plantuml/version/IteratorCounter.java +++ b/src/net/sourceforge/plantuml/version/IteratorCounter.java @@ -34,7 +34,13 @@ package net.sourceforge.plantuml.version; import java.util.Iterator; public interface IteratorCounter extends Iterator { - + public int currentNum(); + public IteratorCounter cloneMe(); + + public String peek(); + + public String peekPrevious(); + } diff --git a/src/net/sourceforge/plantuml/version/IteratorCounterImpl.java b/src/net/sourceforge/plantuml/version/IteratorCounterImpl.java index 055d49182..f72b79774 100644 --- a/src/net/sourceforge/plantuml/version/IteratorCounterImpl.java +++ b/src/net/sourceforge/plantuml/version/IteratorCounterImpl.java @@ -31,33 +31,51 @@ */ package net.sourceforge.plantuml.version; -import java.util.Iterator; +import java.util.List; public class IteratorCounterImpl implements IteratorCounter { - private final Iterator it; + private final List data; private int nb; - - public IteratorCounterImpl(Iterator it) { - this.it = it; - this.nb = 0; + + public IteratorCounterImpl(List data) { + this(data, 0); } - + + private IteratorCounterImpl(List data, int nb) { + this.data = data; + this.nb = nb; + } + public int currentNum() { return nb; } public boolean hasNext() { - return it.hasNext(); + return nb < data.size(); } public String next() { - nb++; - return it.next(); + return data.get(nb++); + } + + public String peek() { + return data.get(nb); + } + + public String peekPrevious() { + if (nb == 0) { + return null; + } + return data.get(nb - 1); } public void remove() { throw new UnsupportedOperationException(); } + public IteratorCounter cloneMe() { + return new IteratorCounterImpl(data, nb); + } + } diff --git a/src/net/sourceforge/plantuml/version/PSystemLicense.java b/src/net/sourceforge/plantuml/version/PSystemLicense.java index e83627540..83b1f9e07 100644 --- a/src/net/sourceforge/plantuml/version/PSystemLicense.java +++ b/src/net/sourceforge/plantuml/version/PSystemLicense.java @@ -63,7 +63,7 @@ public class PSystemLicense extends AbstractPSystem { final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, result.getBackcolor(), getMetadata(), null, 0, 0, null, false); imageBuilder.addUDrawable(result); - return imageBuilder.writeImageTOBEMOVED(fileFormat.getFileFormat(), os); + return imageBuilder.writeImageTOBEMOVED(fileFormat, os); } public static PSystemLicense create() throws IOException { diff --git a/src/net/sourceforge/plantuml/version/PSystemVersion.java b/src/net/sourceforge/plantuml/version/PSystemVersion.java index b74af2bd4..4829f866d 100644 --- a/src/net/sourceforge/plantuml/version/PSystemVersion.java +++ b/src/net/sourceforge/plantuml/version/PSystemVersion.java @@ -139,13 +139,14 @@ public class PSystemVersion extends AbstractPSystem { final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, result.getBackcolor(), getMetadata(), null, 0, 0, null, false); imageBuilder.addUDrawable(result); - return imageBuilder.writeImageTOBEMOVED(fileFormat.getFileFormat(), os); + return imageBuilder.writeImageTOBEMOVED(fileFormat, os); } public static PSystemVersion createShowVersion() { final List strings = new ArrayList(); strings.add("PlantUML version " + Version.versionString() + " (" + Version.compileTimeString() + ")"); strings.add("(" + License.getCurrent() + " source distribution)"); + strings.add("Loaded from " + Version.getJarPath()); strings.add(" "); strings.addAll(GraphvizUtils.getTestDotStrings(true)); @@ -259,8 +260,8 @@ public class PSystemVersion extends AbstractPSystem { private GraphicStrings getGraphicStrings() throws IOException { final UFont font = new UFont("SansSerif", Font.PLAIN, 12); - return new GraphicStrings(strings, font, HtmlColorUtils.BLACK, HtmlColorUtils.WHITE, UAntiAliasing.ANTI_ALIASING_ON, - image, GraphicPosition.BACKGROUND_CORNER_BOTTOM_RIGHT); + return new GraphicStrings(strings, font, HtmlColorUtils.BLACK, HtmlColorUtils.WHITE, + UAntiAliasing.ANTI_ALIASING_ON, image, GraphicPosition.BACKGROUND_CORNER_BOTTOM_RIGHT); } public DiagramDescription getDescription() { diff --git a/src/net/sourceforge/plantuml/version/Version.java b/src/net/sourceforge/plantuml/version/Version.java index 64c245af9..6569f365c 100644 --- a/src/net/sourceforge/plantuml/version/Version.java +++ b/src/net/sourceforge/plantuml/version/Version.java @@ -28,17 +28,18 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 16013 $ + * Revision $Revision: 16251 $ * */ package net.sourceforge.plantuml.version; +import java.net.URL; import java.util.Date; public class Version { public static int version() { - return 8024; + return 8025; } public static String versionString() { @@ -62,7 +63,7 @@ public class Version { } private static long compileTime() { - return 1430665511202L; + return 1433095753149L; } public static String compileTimeString() { @@ -72,4 +73,23 @@ public class Version { return new Date(Version.compileTime()).toString(); } + public static String getJarPath() { + try { + final ClassLoader loader = Version.class.getClassLoader(); + if (loader == null) { + return "No ClassLoader?"; + } + final URL url = loader.getResource("net/sourceforge/plantuml/version/Version.class"); + if (url == null) { + return "No URL?"; + } + String fullpath = url.toString(); + fullpath = fullpath.replaceAll("net/sourceforge/plantuml/version/Version\\.class", ""); + return fullpath; + } catch (Throwable t) { + t.printStackTrace(); + return t.toString(); + } + } + }