diff --git a/src/net/sourceforge/plantuml/BlockUml.java b/src/net/sourceforge/plantuml/BlockUml.java index ca24b20ba..781a573c3 100644 --- a/src/net/sourceforge/plantuml/BlockUml.java +++ b/src/net/sourceforge/plantuml/BlockUml.java @@ -40,7 +40,7 @@ import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; -class BlockUml { +public class BlockUml { private final List data; private PSystem system; @@ -52,7 +52,7 @@ class BlockUml { } BlockUml(List strings) { - final String s0 = strings.get(0); + final String s0 = strings.get(0).trim(); if (s0.startsWith("@startuml") == false) { throw new IllegalArgumentException(); } @@ -63,7 +63,7 @@ class BlockUml { if (OptionFlags.getInstance().isWord()) { return null; } - final Matcher m = pattern1.matcher(data.get(0)); + final Matcher m = pattern1.matcher(data.get(0).trim()); final boolean ok = m.find(); if (ok == false) { return null; diff --git a/src/net/sourceforge/plantuml/BlockUmlBuilder.java b/src/net/sourceforge/plantuml/BlockUmlBuilder.java index 21c861641..67ae6665e 100644 --- a/src/net/sourceforge/plantuml/BlockUmlBuilder.java +++ b/src/net/sourceforge/plantuml/BlockUmlBuilder.java @@ -60,16 +60,19 @@ final public class BlockUmlBuilder { } } - private boolean isArobaseEnduml(final String s) { + static boolean isArobaseEnduml(String s) { + s = s.trim(); return s.equals("@enduml") || s.startsWith("@enduml "); } private boolean isIgnoredLine(final String s) { // return s.length() == 0 || s.startsWith("#") || s.startsWith("'"); - return s.length() == 0 || s.startsWith("'"); + // return s.length() == 0 || s.startsWith("'"); + return s.startsWith("'"); } - private boolean isArobaseStartuml(final String s) { + static boolean isArobaseStartuml(String s) { + s = s.trim(); return s.equals("@startuml") || s.startsWith("@startuml "); } @@ -80,7 +83,7 @@ final public class BlockUmlBuilder { if (isArobaseStartuml(s)) { current = new ArrayList(); } - if (current != null && isIgnoredLine(s) == false) { + if (current != null && isIgnoredLine(s.trim()) == false) { current.add(s); } if (isArobaseEnduml(s) && current != null) { diff --git a/src/net/sourceforge/plantuml/ColorParam.java b/src/net/sourceforge/plantuml/ColorParam.java index c15a6b022..df0998a3f 100644 --- a/src/net/sourceforge/plantuml/ColorParam.java +++ b/src/net/sourceforge/plantuml/ColorParam.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5218 $ + * Revision $Revision: 5823 $ * */ package net.sourceforge.plantuml; @@ -44,8 +44,8 @@ public enum ColorParam { activityBar, activityArrow, - actorBackground, - actorBorder, + usecaseActorBackground, + usecaseActorBorder, usecaseBorder, usecaseBackground, usecaseArrow, @@ -67,13 +67,15 @@ public enum ColorParam { componentBackground, componentBorder, - interfaceBackground, - interfaceBorder, + componentInterfaceBackground, + componentInterfaceBorder, componentArrow, stateBackground, stateBorder, stateArrow, + stateStart, + stateEnd, noteBackground(true), noteBorder, diff --git a/src/net/sourceforge/plantuml/DirWatcher.java b/src/net/sourceforge/plantuml/DirWatcher.java index d45b4bfb7..41dec6669 100644 --- a/src/net/sourceforge/plantuml/DirWatcher.java +++ b/src/net/sourceforge/plantuml/DirWatcher.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5229 $ + * Revision $Revision: 5794 $ * */ package net.sourceforge.plantuml; @@ -77,7 +77,7 @@ public class DirWatcher { if (previousModified == null || previousModified.longValue() != modified) { final SourceFileReader sourceFileReader = new SourceFileReader(new Defines(), f, option.getOutputDir(), - option.getConfig(), option.getCharset(), option.getFileFormat()); + option.getConfig(), option.getCharset(), option.getFileFormatOption()); for (GeneratedImage g : sourceFileReader.getGeneratedImages()) { result.add(g); } diff --git a/src/net/sourceforge/plantuml/EmptyImageBuilder.java b/src/net/sourceforge/plantuml/EmptyImageBuilder.java index d0087aa8d..b215bf14c 100644 --- a/src/net/sourceforge/plantuml/EmptyImageBuilder.java +++ b/src/net/sourceforge/plantuml/EmptyImageBuilder.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5579 $ + * Revision $Revision: 5810 $ * */ package net.sourceforge.plantuml; @@ -36,6 +36,7 @@ package net.sourceforge.plantuml; import java.awt.Color; import java.awt.Graphics2D; import java.awt.RenderingHints; +import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; public class EmptyImageBuilder { @@ -43,6 +44,10 @@ public class EmptyImageBuilder { private final BufferedImage im; private final Graphics2D g2d; + public EmptyImageBuilder(double width, double height, Color background) { + this((int) width, (int) height, background); + } + public EmptyImageBuilder(int width, int height, Color background) { Log.info("Creating image " + width + "x" + height); im = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); @@ -52,6 +57,13 @@ public class EmptyImageBuilder { g2d.fillRect(0, 0, width, height); } + public EmptyImageBuilder(int width, int height, Color background, double dpiFactor) { + this(width * dpiFactor, height * dpiFactor, background); + if (dpiFactor != 1.0) { + g2d.setTransform(AffineTransform.getScaleInstance(dpiFactor, dpiFactor)); + } + } + public BufferedImage getBufferedImage() { return im; } diff --git a/src/net/sourceforge/plantuml/FileFormat.java b/src/net/sourceforge/plantuml/FileFormat.java index 7e6e02f4a..721f2908c 100644 --- a/src/net/sourceforge/plantuml/FileFormat.java +++ b/src/net/sourceforge/plantuml/FileFormat.java @@ -28,19 +28,22 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5333 $ + * Revision $Revision: 5877 $ * */ package net.sourceforge.plantuml; public enum FileFormat { - PNG, SVG, EPS, EPS_VIA_SVG, ATXT, UTXT; + PNG, SVG, EPS, EPS_VIA_SVG, ATXT, UTXT, XMI_STANDARD, XMI_STAR, XMI_ARGO; public String getFileSuffix() { if (this == EPS_VIA_SVG) { throw new UnsupportedOperationException("Not used anymore"); // return EPS.getFileSuffix(); } + if (name().startsWith("XMI")) { + return ".XMI"; + } return "." + name().toLowerCase(); } } diff --git a/src/net/sourceforge/plantuml/FileFormatOption.java b/src/net/sourceforge/plantuml/FileFormatOption.java new file mode 100644 index 000000000..900827f19 --- /dev/null +++ b/src/net/sourceforge/plantuml/FileFormatOption.java @@ -0,0 +1,64 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009, 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 Lesser 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: 5333 $ + * + */ +package net.sourceforge.plantuml; + +public class FileFormatOption { + + private final FileFormat fileFormat; + private final int dpi; + + public FileFormatOption(FileFormat fileFormat, int dpi) { + this.fileFormat = fileFormat; + this.dpi = dpi; + } + + public FileFormatOption(FileFormat fileFormat) { + this(fileFormat, 96); + } + + public final FileFormat getFileFormat() { + return fileFormat; + } + +// public final int getDpi() { +// return dpi; +// } +// +// public double getDpiFactor() { +// if (dpi == 96) { +// return 1.0; +// } +// return dpi / 96.0; +// } +} diff --git a/src/net/sourceforge/plantuml/FileUtils.java b/src/net/sourceforge/plantuml/FileUtils.java new file mode 100644 index 000000000..f4549cf9f --- /dev/null +++ b/src/net/sourceforge/plantuml/FileUtils.java @@ -0,0 +1,97 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009, 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 Lesser 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: 5749 $ + * + */ +package net.sourceforge.plantuml; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; + +import net.sourceforge.plantuml.cucadiagram.dot.DrawFile; + +public class FileUtils { + + private static final Collection toDelete = new ArrayList(); + + public static void deleteOnExit(DrawFile file) { + if (toDelete.isEmpty()) { + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + if (OptionFlags.getInstance().isKeepTmpFiles() == false) { + for (DrawFile f : toDelete) { + f.delete(); + } + } + } + }); + } + toDelete.add(file); + } + + public static File getTmpDir() { + final File tmpDir = new File(System.getProperty("java.io.tmpdir")); + if (tmpDir.exists() == false || tmpDir.isDirectory() == false) { + throw new IllegalStateException(); + } + return tmpDir; + } + + public static void delete(File f) { + if (f == null) { + return; + } + Thread.yield(); + Log.info("Deleting temporary file " + f); + final boolean ok = f.delete(); + if (ok == false) { + Log.error("Cannot delete: " + f); + } + } + + static public File createTempFile(String prefix, String suffix) throws IOException { + if (suffix.startsWith(".") == false) { + throw new IllegalArgumentException(); + } + final File f = File.createTempFile(prefix, suffix); + Log.info("Creating temporary file: " + f); + if (OptionFlags.getInstance().isKeepTmpFiles() == false) { + f.deleteOnExit(); + } + return f; + } + + + +} diff --git a/src/net/sourceforge/plantuml/ISkinParam.java b/src/net/sourceforge/plantuml/ISkinParam.java index 05163be40..64228a025 100644 --- a/src/net/sourceforge/plantuml/ISkinParam.java +++ b/src/net/sourceforge/plantuml/ISkinParam.java @@ -43,17 +43,17 @@ public interface ISkinParam { public String getValue(String key); - public HtmlColor getHtmlColor(ColorParam param); + public HtmlColor getHtmlColor(ColorParam param, String stereotype); - public int getFontSize(FontParam param); + public int getFontSize(FontParam param, String stereotype); - public String getFontFamily(FontParam param); + public String getFontFamily(FontParam param, String stereotype); - public HtmlColor getFontHtmlColor(FontParam param); + public HtmlColor getFontHtmlColor(FontParam param, String stereotype); - public int getFontStyle(FontParam param); + public int getFontStyle(FontParam param, String stereotype); - public Font getFont(FontParam fontParam); + public Font getFont(FontParam fontParam, String stereotype); public int getCircledCharacterRadius(); @@ -62,5 +62,7 @@ public interface ISkinParam { public int classAttributeIconSize(); public boolean isMonochrome(); + + public int getDpi(); } \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/Option.java b/src/net/sourceforge/plantuml/Option.java index ad2c2afdc..72960ced8 100644 --- a/src/net/sourceforge/plantuml/Option.java +++ b/src/net/sourceforge/plantuml/Option.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5343 $ + * Revision $Revision: 5877 $ * */ package net.sourceforge.plantuml; @@ -82,6 +82,12 @@ public class Option { String s = arg[i]; if (s.equalsIgnoreCase("-tsvg") || s.equalsIgnoreCase("-svg")) { setFileFormat(FileFormat.SVG); + } else if (s.equalsIgnoreCase("-txmi") || s.equalsIgnoreCase("-xmi")) { + setFileFormat(FileFormat.XMI_STANDARD); + } else if (s.equalsIgnoreCase("-txmi:argo") || s.equalsIgnoreCase("-xmi:argo")) { + setFileFormat(FileFormat.XMI_ARGO); + } else if (s.equalsIgnoreCase("-txmi:star") || s.equalsIgnoreCase("-xmi:star")) { + setFileFormat(FileFormat.XMI_STAR); } else if (s.equalsIgnoreCase("-teps") || s.equalsIgnoreCase("-eps")) { setFileFormat(FileFormat.EPS); } else if (s.equalsIgnoreCase("-ttxt") || s.equalsIgnoreCase("-txt")) { @@ -261,4 +267,8 @@ public class Option { return syntax; } + public FileFormatOption getFileFormatOption() { + return new FileFormatOption(getFileFormat()); + } + } diff --git a/src/net/sourceforge/plantuml/OptionFlags.java b/src/net/sourceforge/plantuml/OptionFlags.java index ec165f866..d75fe287a 100644 --- a/src/net/sourceforge/plantuml/OptionFlags.java +++ b/src/net/sourceforge/plantuml/OptionFlags.java @@ -28,12 +28,14 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5244 $ + * Revision $Revision: 5746 $ * */ package net.sourceforge.plantuml; public class OptionFlags { + + static public final boolean PBBACK = false; void reset() { keepTmpFiles = false; @@ -58,21 +60,12 @@ public class OptionFlags { private boolean metadata = false; private boolean word = false; private boolean systemExit = true; -// private boolean pipe = false; private boolean debugDot = false; private boolean forceGd = false; private boolean forceCairo = false; private String dotExecutable = null; private boolean gui = false; private boolean quiet = false; -// -// public final boolean isPipe() { -// return pipe; -// } -// -// public final void setPipe(boolean pipe) { -// this.pipe = pipe; -// } private OptionFlags() { reset(); diff --git a/src/net/sourceforge/plantuml/PSystem.java b/src/net/sourceforge/plantuml/PSystem.java index b54b1baec..cab71b11d 100644 --- a/src/net/sourceforge/plantuml/PSystem.java +++ b/src/net/sourceforge/plantuml/PSystem.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5520 $ + * Revision $Revision: 5794 $ * */ package net.sourceforge.plantuml; @@ -40,9 +40,9 @@ import java.util.List; public interface PSystem { - List createFiles(File suggestedFile, FileFormat fileFormat) throws IOException, InterruptedException; + List createFiles(File suggestedFile, FileFormatOption fileFormatOption) throws IOException, InterruptedException; - void createFile(OutputStream os, int index, FileFormat fileFormat) throws IOException; + void createFile(OutputStream os, int index, FileFormatOption fileFormatOption) throws IOException; int getNbImages(); diff --git a/src/net/sourceforge/plantuml/PSystemError.java b/src/net/sourceforge/plantuml/PSystemError.java index 3c5d0bedb..71878b2cb 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: 5507 $ + * Revision $Revision: 5794 $ */ package net.sourceforge.plantuml; @@ -79,7 +79,10 @@ public class PSystemError extends AbstractPSystem { this(source, Arrays.asList(errorUml)); } - public List createFiles(File suggestedFile, FileFormat fileFormat) throws IOException, InterruptedException { + public List createFiles(File suggestedFile, FileFormatOption fileFormat) throws IOException, InterruptedException { + if (suggestedFile.exists() && suggestedFile.isDirectory()) { + throw new IllegalArgumentException("File is a directory "+suggestedFile); + } OutputStream os = null; try { os = new FileOutputStream(suggestedFile); @@ -92,7 +95,7 @@ public class PSystemError extends AbstractPSystem { return Arrays.asList(suggestedFile); } - public void createFile(OutputStream os, int index, FileFormat fileFormat) throws IOException { + public void createFile(OutputStream os, int index, FileFormatOption fileFormat) throws IOException { getPngError().writeImage(os, getMetadata(), fileFormat); } diff --git a/src/net/sourceforge/plantuml/PSystemSingleBuilder.java b/src/net/sourceforge/plantuml/PSystemSingleBuilder.java index 8b4e7c8fd..31e93e2fe 100644 --- a/src/net/sourceforge/plantuml/PSystemSingleBuilder.java +++ b/src/net/sourceforge/plantuml/PSystemSingleBuilder.java @@ -69,7 +69,7 @@ final public class PSystemSingleBuilder { public PSystemSingleBuilder(List strings, PSystemFactory systemFactory) throws IOException { source = new UmlSource(strings); it = strings.iterator(); - if (next().startsWith("@startuml") == false) { + if (BlockUmlBuilder.isArobaseStartuml(next()) == false) { throw new UnsupportedOperationException(); } @@ -84,7 +84,7 @@ final public class PSystemSingleBuilder { systemFactory.reset(); while (hasNext()) { final String s = next(); - if (s.equals("@enduml")) { + if (BlockUmlBuilder.isArobaseEnduml(s)) { if (source.getSize() == 2) { sys = buildEmptyError(source); } else { @@ -116,7 +116,7 @@ final public class PSystemSingleBuilder { systemFactory.reset(); while (hasNext()) { final String s = next(); - if (s.equals("@enduml")) { + if (BlockUmlBuilder.isArobaseEnduml(s)) { if (source.getSize() == 2) { sys = buildEmptyError(source); } else { @@ -174,7 +174,7 @@ final public class PSystemSingleBuilder { lines.add(init); while (hasNext()) { final String s = next(); - if (s.equals("@enduml")) { + if (BlockUmlBuilder.isArobaseEnduml(s)) { return false; } lines.add(s); diff --git a/src/net/sourceforge/plantuml/Run.java b/src/net/sourceforge/plantuml/Run.java index f92df1476..b88ba6f80 100644 --- a/src/net/sourceforge/plantuml/Run.java +++ b/src/net/sourceforge/plantuml/Run.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5391 $ + * Revision $Revision: 5810 $ * */ package net.sourceforge.plantuml; @@ -44,6 +44,7 @@ import java.util.List; import javax.swing.UIManager; import net.sourceforge.plantuml.code.Transcoder; +import net.sourceforge.plantuml.code.TranscoderUtil; import net.sourceforge.plantuml.png.MetadataTag; import net.sourceforge.plantuml.preproc.Defines; import net.sourceforge.plantuml.swing.MainWindow; @@ -113,7 +114,7 @@ public class Run { Log.error("InterruptedException " + e); } } else if (option.isPipe()) { - final String result = sourceStringReader.generateImage(ps, 0, option.getFileFormat()); + final String result = sourceStringReader.generateImage(ps, 0, option.getFileFormatOption()); } } @@ -127,7 +128,7 @@ public class Run { System.out.println("------------------------"); } else { final SourceFileReader sourceFileReader = new SourceFileReader(option.getDefaultDefines(), f, option - .getOutputDir(), option.getConfig(), option.getCharset(), option.getFileFormat()); + .getOutputDir(), option.getConfig(), option.getCharset(), option.getFileFormatOption()); if (option.isComputeurl()) { final List urls = sourceFileReader.getEncodedUrl(); for (String s : urls) { @@ -162,7 +163,7 @@ public class Run { private static void processArgs(Option option) throws IOException, InterruptedException { for (String s : option.getResult()) { if (option.isDecodeurl()) { - final Transcoder transcoder = new Transcoder(); + final Transcoder transcoder = TranscoderUtil.getDefaultTranscoder(); System.out.println("@startuml"); System.out.println(transcoder.decode(s)); System.out.println("@enduml"); diff --git a/src/net/sourceforge/plantuml/SignatureUtils.java b/src/net/sourceforge/plantuml/SignatureUtils.java index 19985936c..31686d057 100644 --- a/src/net/sourceforge/plantuml/SignatureUtils.java +++ b/src/net/sourceforge/plantuml/SignatureUtils.java @@ -28,11 +28,14 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 3883 $ + * Revision $Revision: 5877 $ * */ package net.sourceforge.plantuml; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -58,7 +61,8 @@ public class SignatureUtils { } public static String getSignatureWithoutImgSrc(String s) { - return getSignature(purge(s)); + s = getSignature(purge(s)); + return s; } public static String purge(String s) { @@ -68,4 +72,25 @@ public class SignatureUtils { s = s.replaceAll(regex2, "image=\"$1$2\""); return s; } + + public static String getSignature(File f) throws IOException { + try { + final AsciiEncoder coder = new AsciiEncoder(); + final MessageDigest msgDigest = MessageDigest.getInstance("MD5"); + final FileInputStream is = new FileInputStream(f); + int read = -1; + while ((read = is.read()) != -1) { + msgDigest.update((byte) read); + } + is.close(); + final byte[] digest = msgDigest.digest(); + return coder.encode(digest); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + throw new IllegalStateException(); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + throw new IllegalStateException(); + } + } } diff --git a/src/net/sourceforge/plantuml/SkinParam.java b/src/net/sourceforge/plantuml/SkinParam.java index 251523444..26171e852 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: 5403 $ + * Revision $Revision: 5845 $ * */ package net.sourceforge.plantuml; @@ -41,6 +41,8 @@ import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.TreeSet; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import net.sourceforge.plantuml.graphic.HtmlColor; @@ -49,11 +51,26 @@ public class SkinParam implements ISkinParam { private final Map params = new HashMap(); public void setParam(String key, String value) { - params.put(key.toLowerCase().trim(), value.trim()); + params.put(cleanForKey(key), value.trim()); + } + + private static final String stereoPatternString = "\\<\\<(.*?)\\>\\>"; + private static final Pattern stereoPattern = Pattern.compile(stereoPatternString); + + static String cleanForKey(String key) { + key = key.toLowerCase().trim(); + key = key.replaceAll("_|\\.|\\s", ""); + final Matcher m = stereoPattern.matcher(key); + if (m.find()) { + final String s = m.group(1); + key = key.replaceAll(stereoPatternString, ""); + key += "<<" + s + ">>"; + } + return key; } public HtmlColor getBackgroundColor() { - final HtmlColor result = getHtmlColor(ColorParam.background); + final HtmlColor result = getHtmlColor(ColorParam.background, null); if (result == null) { return new HtmlColor("white"); } @@ -61,7 +78,7 @@ public class SkinParam implements ISkinParam { } public String getValue(String key) { - return params.get(key.toLowerCase().replaceAll("_", "")); + return params.get(cleanForKey(key)); } static String humanName(String key) { @@ -79,7 +96,14 @@ public class SkinParam implements ISkinParam { return sb.toString(); } - public HtmlColor getHtmlColor(ColorParam param) { + public HtmlColor getHtmlColor(ColorParam param, String stereotype) { + if (stereotype != null) { + checkStereotype(stereotype); + final String value2 = getValue(param.name() + "color" + stereotype); + if (value2 != null && HtmlColor.isValid(value2)) { + return new HtmlColor(value2); + } + } final String value = getValue(param.name() + "color"); if (value == null || HtmlColor.isValid(value) == false) { return null; @@ -87,7 +111,20 @@ public class SkinParam implements ISkinParam { return new HtmlColor(value); } - public int getFontSize(FontParam param) { + private void checkStereotype(String stereotype) { + if (stereotype.startsWith("<<") == false || stereotype.endsWith(">>") == false) { + throw new IllegalArgumentException(); + } + } + + public int getFontSize(FontParam param, String stereotype) { + if (stereotype != null) { + checkStereotype(stereotype); + final String value2 = getValue(param.name() + "fontsize" + stereotype); + if (value2 != null && value2.matches("\\d+")) { + return Integer.parseInt(value2); + } + } String value = getValue(param.name() + "fontsize"); if (value == null || value.matches("\\d+") == false) { value = getValue("defaultfontsize"); @@ -98,34 +135,55 @@ public class SkinParam implements ISkinParam { return Integer.parseInt(value); } - public String getFontFamily(FontParam param) { + public String getFontFamily(FontParam param, String stereotype) { + if (stereotype != null) { + checkStereotype(stereotype); + final String value2 = getValue(param.name() + "fontname" + stereotype); + if (value2 != null) { + return StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(value2); + } + } // Times, Helvetica, Courier or Symbol String value = getValue(param.name() + "fontname"); if (value != null) { - return value; + return StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(value); } if (param != FontParam.CIRCLED_CHARACTER) { value = getValue("defaultfontname"); if (value != null) { - return value; + return StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(value); } } return param.getDefaultFamily(); } - public HtmlColor getFontHtmlColor(FontParam param) { - String value = getValue(param.name() + "fontcolor"); - if (value == null) { + public HtmlColor getFontHtmlColor(FontParam param, String stereotype) { + String value = null; + if (stereotype != null) { + checkStereotype(stereotype); + value = getValue(param.name() + "fontcolor" + stereotype); + } + if (value == null || HtmlColor.isValid(value) == false) { + value = getValue(param.name() + "fontcolor"); + } + if (value == null || HtmlColor.isValid(value) == false) { value = getValue("defaultfontcolor"); } - if (value == null) { + if (value == null || HtmlColor.isValid(value) == false) { value = param.getDefaultColor(); } return new HtmlColor(value); } - public int getFontStyle(FontParam param) { - String value = getValue(param.name() + "fontstyle"); + public int getFontStyle(FontParam param, String stereotype) { + String value = null; + if (stereotype != null) { + checkStereotype(stereotype); + value = getValue(param.name() + "fontstyle" + stereotype); + } + if (value == null) { + value = getValue(param.name() + "fontstyle"); + } if (value == null) { value = getValue("defaultfontstyle"); } @@ -142,8 +200,12 @@ public class SkinParam implements ISkinParam { return result; } - public Font getFont(FontParam fontParam) { - return new Font(getFontFamily(fontParam), getFontStyle(fontParam), getFontSize(fontParam)); + public Font getFont(FontParam fontParam, String stereotype) { + if (stereotype != null) { + checkStereotype(stereotype); + } + return new Font(getFontFamily(fontParam, stereotype), getFontStyle(fontParam, stereotype), getFontSize( + fontParam, stereotype)); } public int getCircledCharacterRadius() { @@ -154,7 +216,7 @@ public class SkinParam implements ISkinParam { // return 11; // System.err.println("SIZE1="+getFontSize(FontParam.CIRCLED_CHARACTER)); // System.err.println("SIZE1="+getFontSize(FontParam.CIRCLED_CHARACTER)/3); - return getFontSize(FontParam.CIRCLED_CHARACTER) / 3 + 6; + return getFontSize(FontParam.CIRCLED_CHARACTER, null) / 3 + 6; } public boolean isClassCollapse() { @@ -193,4 +255,12 @@ public class SkinParam implements ISkinParam { return Collections.unmodifiableSet(result); } + public int getDpi() { + final String value = getValue("dpi"); + if (value != null && value.matches("\\d+")) { + return Integer.parseInt(value); + } + return 96; + } + } diff --git a/src/net/sourceforge/plantuml/SkinParamBackcolored.java b/src/net/sourceforge/plantuml/SkinParamBackcolored.java index 04de12f6c..82a9f7113 100644 --- a/src/net/sourceforge/plantuml/SkinParamBackcolored.java +++ b/src/net/sourceforge/plantuml/SkinParamBackcolored.java @@ -65,31 +65,31 @@ public class SkinParamBackcolored implements ISkinParam { return skinParam.getCircledCharacterRadius(); } - public Font getFont(FontParam fontParam) { - return skinParam.getFont(fontParam); + public Font getFont(FontParam fontParam, String stereotype) { + return skinParam.getFont(fontParam, stereotype); } - public String getFontFamily(FontParam param) { - return skinParam.getFontFamily(param); + public String getFontFamily(FontParam param, String stereotype) { + return skinParam.getFontFamily(param, stereotype); } - public HtmlColor getFontHtmlColor(FontParam param) { - return skinParam.getFontHtmlColor(param); + public HtmlColor getFontHtmlColor(FontParam param, String stereotype) { + return skinParam.getFontHtmlColor(param, stereotype); } - public int getFontSize(FontParam param) { - return skinParam.getFontSize(param); + public int getFontSize(FontParam param, String stereotype) { + return skinParam.getFontSize(param, stereotype); } - public int getFontStyle(FontParam param) { - return skinParam.getFontStyle(param); + public int getFontStyle(FontParam param, String stereotype) { + return skinParam.getFontStyle(param, stereotype); } - public HtmlColor getHtmlColor(ColorParam param) { + public HtmlColor getHtmlColor(ColorParam param, String stereotype) { if (param.isBackground() && backColorElement != null) { return backColorElement; } - return skinParam.getHtmlColor(param); + return skinParam.getHtmlColor(param, stereotype); } public String getValue(String key) { @@ -107,4 +107,8 @@ public class SkinParamBackcolored implements ISkinParam { public boolean isMonochrome() { return skinParam.isMonochrome(); } + + public int getDpi() { + return skinParam.getDpi(); + } } diff --git a/src/net/sourceforge/plantuml/SourceFileReader.java b/src/net/sourceforge/plantuml/SourceFileReader.java index ba394f716..17b970e3e 100644 --- a/src/net/sourceforge/plantuml/SourceFileReader.java +++ b/src/net/sourceforge/plantuml/SourceFileReader.java @@ -45,6 +45,7 @@ import java.util.Collections; import java.util.List; import net.sourceforge.plantuml.code.Transcoder; +import net.sourceforge.plantuml.code.TranscoderUtil; import net.sourceforge.plantuml.preproc.Defines; public class SourceFileReader { @@ -53,24 +54,24 @@ public class SourceFileReader { private final File outputDirectory; private final BlockUmlBuilder builder; - private FileFormat fileFormat; + private FileFormatOption fileFormatOption; public SourceFileReader(File file) throws IOException { this(file, file.getAbsoluteFile().getParentFile()); } public SourceFileReader(final File file, File outputDirectory) throws IOException { - this(new Defines(), file, outputDirectory, Collections. emptyList(), null, FileFormat.PNG); + this(new Defines(), file, outputDirectory, Collections. emptyList(), null, new FileFormatOption(FileFormat.PNG)); } - public SourceFileReader(final File file, File outputDirectory, FileFormat fileFormat) throws IOException { - this(new Defines(), file, outputDirectory, Collections. emptyList(), null, fileFormat); + public SourceFileReader(final File file, File outputDirectory, FileFormatOption fileFormatOption) throws IOException { + this(new Defines(), file, outputDirectory, Collections. emptyList(), null, fileFormatOption); } public SourceFileReader(Defines defines, final File file, File outputDirectory, List config, - String charset, FileFormat fileFormat) throws IOException { + String charset, FileFormatOption fileFormatOption) throws IOException { this.file = file; - this.fileFormat = fileFormat; + this.fileFormatOption = fileFormatOption; if (file.exists() == false) { throw new IllegalArgumentException(); } @@ -98,13 +99,13 @@ public class SourceFileReader { String newName = blockUml.getFilename(); if (newName == null) { - newName = changeName(file.getName(), cpt++, fileFormat); + newName = changeName(file.getName(), cpt++, fileFormatOption.getFileFormat()); } final File suggested = new File(outputDirectory, newName); suggested.getParentFile().mkdirs(); - for (File f : blockUml.getSystem().createFiles(suggested, fileFormat)) { + for (File f : blockUml.getSystem().createFiles(suggested, fileFormatOption)) { final String desc = "[" + file.getName() + "] " + blockUml.getSystem().getDescription(); final GeneratedImage generatedImage = new GeneratedImage(f, desc); result.add(generatedImage); @@ -119,7 +120,7 @@ public class SourceFileReader { public List getEncodedUrl() throws IOException, InterruptedException { final List result = new ArrayList(); - final Transcoder transcoder = new Transcoder(); + final Transcoder transcoder = TranscoderUtil.getDefaultTranscoder(); for (BlockUml blockUml : builder.getBlockUmls()) { final String source = blockUml.getSystem().getSource().getPlainString(); final String encoded = transcoder.encode(source); @@ -144,8 +145,8 @@ public class SourceFileReader { return new InputStreamReader(new FileInputStream(file), charset); } - public final void setFileFormat(FileFormat fileFormat) { - this.fileFormat = fileFormat; + public final void setFileFormatOption(FileFormatOption fileFormatOption) { + this.fileFormatOption = fileFormatOption; } } diff --git a/src/net/sourceforge/plantuml/SourceStringReader.java b/src/net/sourceforge/plantuml/SourceStringReader.java index 2256ed885..f09c77e87 100644 --- a/src/net/sourceforge/plantuml/SourceStringReader.java +++ b/src/net/sourceforge/plantuml/SourceStringReader.java @@ -33,6 +33,8 @@ */ package net.sourceforge.plantuml; +import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.StringReader; @@ -64,18 +66,25 @@ public class SourceStringReader { return generateImage(os, 0); } - public String generateImage(OutputStream os, FileFormat fileFormat) throws IOException { - return generateImage(os, 0, fileFormat); + public String generateImage(File f) throws IOException { + final FileOutputStream os = new FileOutputStream(f); + final String result = generateImage(os, 0); + os.close(); + return result; + } + + public String generateImage(OutputStream os, FileFormatOption fileFormatOption) throws IOException { + return generateImage(os, 0, fileFormatOption); } public String generateImage(OutputStream os, int numImage) throws IOException { - return generateImage(os, numImage, FileFormat.PNG); + return generateImage(os, numImage, new FileFormatOption(FileFormat.PNG)); } - public String generateImage(OutputStream os, int numImage, FileFormat fileFormat) throws IOException { + public String generateImage(OutputStream os, int numImage, FileFormatOption fileFormatOption) throws IOException { if (blocks.size() == 0) { final GraphicStrings error = new GraphicStrings(Arrays.asList("No @startuml found")); - error.writeImage(os, fileFormat); + error.writeImage(os, fileFormatOption); return null; } try { @@ -83,7 +92,7 @@ public class SourceStringReader { final PSystem system = b.getSystem(); final int nbInSystem = system.getNbImages(); if (numImage < nbInSystem) { - system.createFile(os, numImage, fileFormat); + system.createFile(os, numImage, fileFormatOption); return system.getDescription(); } numImage -= nbInSystem; diff --git a/src/net/sourceforge/plantuml/StringUtils.java b/src/net/sourceforge/plantuml/StringUtils.java index f6355702f..e60363b17 100644 --- a/src/net/sourceforge/plantuml/StringUtils.java +++ b/src/net/sourceforge/plantuml/StringUtils.java @@ -28,37 +28,49 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5427 $ + * Revision $Revision: 5749 $ * */ package net.sourceforge.plantuml; import java.io.File; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; public class StringUtils { - static private final Pattern multiLines = Pattern.compile("((?:\\\\\\\\|[^\\\\])+)(\\\\n)?"); - public static String getPlateformDependentAbsolutePath(File file) { return file.getAbsolutePath(); - } public static List getWithNewlines(String s) { if (s == null) { throw new IllegalArgumentException(); } - final Matcher matcher = multiLines.matcher(s); - final List strings = new ArrayList(); - - while (matcher.find()) { - strings.add(matcher.group(1).replace("\\\\", "\\")); + final List result = new ArrayList(); + final StringBuilder current = new StringBuilder(); + for (int i = 0; i < s.length(); i++) { + final char c = s.charAt(i); + if (c == '\\' && i < s.length() + 1) { + final char c2 = s.charAt(i + 1); + i++; + if (c2 == 'n') { + result.add(current.toString()); + current.setLength(0); + } else if (c2 == 't') { + current.append('\t'); + } else if (c2 == '\\') { + current.append(c2); + } + } else { + current.append(c); + } } - return strings; + result.add(current.toString()); + return Collections.unmodifiableList(result); } public static String getMergedLines(List strings) { @@ -260,4 +272,46 @@ public class StringUtils { return stringsToDisplay.size(); } + private static boolean firstColumnRemovable(List data) { + boolean allEmpty = true; + for (String s : data) { + if (s.length() == 0) { + continue; + } + allEmpty = false; + final char c = s.charAt(0); + if (c != ' ' && c != '\t') { + return false; + } + } + return allEmpty == false; + } + + private static void removeFirstColumn(List data) { + for (int i = 0; i < data.size(); i++) { + final String s = data.get(i); + if (s.length() > 0) { + data.set(i, s.substring(1)); + } + } + } + + public static List removeEmptyColumns(List data) { + if (firstColumnRemovable(data) == false) { + return data; + } + final List result = new ArrayList(data); + do { + removeFirstColumn(result); + } while (firstColumnRemovable(result)); + return Collections.unmodifiableList(result); + } + + public static void trim(List data) { + for (int i = 0; i < data.size(); i++) { + final String s = data.get(i); + data.set(i, s.trim()); + } + } + } diff --git a/src/net/sourceforge/plantuml/UmlDiagram.java b/src/net/sourceforge/plantuml/UmlDiagram.java index f06093260..67928e68c 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: 5503 $ + * Revision $Revision: 5811 $ * */ package net.sourceforge.plantuml; @@ -126,9 +126,20 @@ public abstract class UmlDiagram extends AbstractPSystem implements PSystem { final public void setScale(Scale scale) { this.scale = scale; } - + final public Scale getScale() { return scale; } + public final double getDpiFactor(FileFormatOption fileFormatOption) { + if (getSkinParam().getDpi() == 96) { + return 1.0; + } + return getSkinParam().getDpi() / 96.0; + } + + public final int getDpi(FileFormatOption fileFormatOption) { + return getSkinParam().getDpi(); + } + } diff --git a/src/net/sourceforge/plantuml/activitydiagram/ActivityDiagram.java b/src/net/sourceforge/plantuml/activitydiagram/ActivityDiagram.java index bfe2afeb4..2abcb56e8 100644 --- a/src/net/sourceforge/plantuml/activitydiagram/ActivityDiagram.java +++ b/src/net/sourceforge/plantuml/activitydiagram/ActivityDiagram.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5223 $ + * Revision $Revision: 5721 $ * */ package net.sourceforge.plantuml.activitydiagram; @@ -52,7 +52,6 @@ public class ActivityDiagram extends CucaDiagram { private IEntity lastEntityConsulted; private IEntity lastEntityBrancheConsulted; private ConditionalContext currentContext; - private boolean acceptOldSyntaxForBranch = true; private String getAutoBranch() { return "#" + UniqueSequence.getValue(); @@ -63,7 +62,7 @@ public class ActivityDiagram extends CucaDiagram { if (entityExist(code)) { result = super.getOrCreateEntity(code, type); if (result.getType() != type) { - throw new IllegalArgumentException("Already known: " + code); + throw new IllegalArgumentException("Already known: " + code + " " + result.getType() + " " + type); // return null; } } else { @@ -73,8 +72,8 @@ public class ActivityDiagram extends CucaDiagram { return result; } - public void startIf() { - final IEntity br = createEntity(getAutoBranch(), "", EntityType.BRANCH); + public void startIf(String optionalCode) { + final IEntity br = createEntity(optionalCode == null ? getAutoBranch() : optionalCode, "", EntityType.BRANCH); currentContext = new ConditionalContext(currentContext, br, Direction.DOWN); } @@ -153,14 +152,6 @@ public class ActivityDiagram extends CucaDiagram { this.lastEntityConsulted = lastEntityConsulted; } - public final boolean isAcceptOldSyntaxForBranch() { - return acceptOldSyntaxForBranch; - } - - public final void setAcceptOldSyntaxForBranch(boolean acceptOldSyntaxForBranch) { - this.acceptOldSyntaxForBranch = acceptOldSyntaxForBranch; - } - public IEntity createInnerActivity() { // System.err.println("createInnerActivity A"); final String code = "##" + UniqueSequence.getValue(); diff --git a/src/net/sourceforge/plantuml/activitydiagram/ActivityDiagramFactory.java b/src/net/sourceforge/plantuml/activitydiagram/ActivityDiagramFactory.java index 5e85b9986..52865774e 100644 --- a/src/net/sourceforge/plantuml/activitydiagram/ActivityDiagramFactory.java +++ b/src/net/sourceforge/plantuml/activitydiagram/ActivityDiagramFactory.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5190 $ + * Revision $Revision: 5847 $ * */ package net.sourceforge.plantuml.activitydiagram; @@ -38,8 +38,8 @@ import net.sourceforge.plantuml.activitydiagram.command.CommandEndPartition; import net.sourceforge.plantuml.activitydiagram.command.CommandEndif; import net.sourceforge.plantuml.activitydiagram.command.CommandIf; import net.sourceforge.plantuml.activitydiagram.command.CommandInnerConcurrent; -import net.sourceforge.plantuml.activitydiagram.command.CommandLinkActivity2; -import net.sourceforge.plantuml.activitydiagram.command.CommandLinkLongActivity2; +import net.sourceforge.plantuml.activitydiagram.command.CommandLinkActivity; +import net.sourceforge.plantuml.activitydiagram.command.CommandLinkLongActivity; import net.sourceforge.plantuml.activitydiagram.command.CommandMultilinesNoteActivity; import net.sourceforge.plantuml.activitydiagram.command.CommandMultilinesNoteActivityLink; import net.sourceforge.plantuml.activitydiagram.command.CommandNoteActivity; @@ -61,10 +61,10 @@ public class ActivityDiagramFactory extends AbstractUmlSystemCommandFactory { addCommonCommands(system); - addCommand(new CommandLinkActivity2(system)); + addCommand(new CommandLinkActivity(system)); addCommand(new CommandPartition(system)); addCommand(new CommandEndPartition(system)); - addCommand(new CommandLinkLongActivity2(system)); + addCommand(new CommandLinkLongActivity(system)); addCommand(new CommandNoteActivity(system)); addCommand(new CommandMultilinesNoteActivity(system)); @@ -75,7 +75,7 @@ public class ActivityDiagramFactory extends AbstractUmlSystemCommandFactory { addCommand(new CommandIf(system)); addCommand(new CommandElse(system)); addCommand(new CommandEndif(system)); - addCommand(new CommandInnerConcurrent(system)); + // addCommand(new CommandInnerConcurrent(system)); } } diff --git a/src/net/sourceforge/plantuml/activitydiagram/command/CommandElse.java b/src/net/sourceforge/plantuml/activitydiagram/command/CommandElse.java index 7767de7b0..98719cd95 100644 --- a/src/net/sourceforge/plantuml/activitydiagram/command/CommandElse.java +++ b/src/net/sourceforge/plantuml/activitydiagram/command/CommandElse.java @@ -54,7 +54,6 @@ public class CommandElse extends SingleLineCommand { final IEntity branch = getSystem().getCurrentContext().getBranch(); getSystem().setLastEntityConsulted(branch); - getSystem().setAcceptOldSyntaxForBranch(false); return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/activitydiagram/command/CommandEndif.java b/src/net/sourceforge/plantuml/activitydiagram/command/CommandEndif.java index 1a54f414e..7b0b7acdd 100644 --- a/src/net/sourceforge/plantuml/activitydiagram/command/CommandEndif.java +++ b/src/net/sourceforge/plantuml/activitydiagram/command/CommandEndif.java @@ -51,7 +51,6 @@ public class CommandEndif extends SingleLineCommand { return CommandExecutionResult.error("No if for this endif"); } getSystem().endif(); - getSystem().setAcceptOldSyntaxForBranch(false); return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/activitydiagram/command/CommandIf.java b/src/net/sourceforge/plantuml/activitydiagram/command/CommandIf.java index 73cbfae3c..bef07f071 100644 --- a/src/net/sourceforge/plantuml/activitydiagram/command/CommandIf.java +++ b/src/net/sourceforge/plantuml/activitydiagram/command/CommandIf.java @@ -33,47 +33,63 @@ */ package net.sourceforge.plantuml.activitydiagram.command; -import java.util.List; +import java.util.Map; import net.sourceforge.plantuml.Direction; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.activitydiagram.ActivityDiagram; import net.sourceforge.plantuml.command.CommandExecutionResult; -import net.sourceforge.plantuml.command.SingleLineCommand; +import net.sourceforge.plantuml.command.SingleLineCommand2; +import net.sourceforge.plantuml.command.regex.RegexConcat; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexOr; +import net.sourceforge.plantuml.command.regex.RegexPartialMatch; import net.sourceforge.plantuml.cucadiagram.IEntity; import net.sourceforge.plantuml.cucadiagram.Link; import net.sourceforge.plantuml.cucadiagram.LinkDecor; import net.sourceforge.plantuml.cucadiagram.LinkType; -public class CommandIf extends SingleLineCommand { +public class CommandIf extends SingleLineCommand2 { public CommandIf(ActivityDiagram diagram) { - super( - diagram, - "(?i)^(?:(\\(\\*\\))|([\\p{L}0-9_.]+)|(?:==+)\\s*([\\p{L}0-9_.]+)\\s*(?:==+)|\"([^\"]+)\"(?:\\s+as\\s+([\\p{L}0-9_.]+))?)?" - + "\\s*([=-]+(?:left|right|up|down|le?|ri?|up?|do?)?[=-]*\\>)?\\s*(?:\\[([^\\]*]+[^\\]]*)\\])?\\s*if\\s*\"([^\"]*)\"\\s*then$"); + super(diagram, getRegexConcat()); } - @Override - protected CommandExecutionResult executeArg(List arg) { - final IEntity entity1 = CommandLinkActivity2.getEntity(getSystem(), arg, true); + static RegexConcat getRegexConcat() { + return new RegexConcat(new RegexLeaf("^"), + new RegexOr("FIRST", true, + new RegexLeaf("STAR", "(\\(\\*\\))"), + new RegexLeaf("CODE", "([\\p{L}0-9_.]+)"), + new RegexLeaf("BAR", "(?:==+)\\s*([\\p{L}0-9_.]+)\\s*(?:==+)"), + new RegexLeaf("QUOTED", "\"([^\"]+)\"(?:\\s+as\\s+([\\p{L}0-9_.]+))?")), + new RegexLeaf("\\s*"), + new RegexLeaf("ARROW", "([=-]+(?:left|right|up|down|le?|ri?|up?|do?)?[=-]*\\>)?"), + new RegexLeaf("\\s*"), + new RegexLeaf("BRACKET", "(?:\\[([^\\]*]+[^\\]]*)\\])?"), + new RegexLeaf("\\s*"), + new RegexLeaf("IF", "if\\s*\"([^\"]*)\"\\s*(?:as\\s+([\\p{L}0-9_.]+)\\s+)?then$")); + } - getSystem().startIf(); + + @Override + protected CommandExecutionResult executeArg(Map arg) { + final IEntity entity1 = CommandLinkActivity.getEntity(getSystem(), arg, true); + + getSystem().startIf(arg.get("IF").get(1)); int lenght = 2; - if (arg.get(5) != null) { - final String arrow = StringUtils.manageArrowForCuca(arg.get(5)); + if (arg.get("ARROW").get(0) != null) { + final String arrow = StringUtils.manageArrowForCuca(arg.get("ARROW").get(0)); lenght = arrow.length() - 1; } final IEntity branch = getSystem().getCurrentContext().getBranch(); - - Link link = new Link(entity1, branch, new LinkType(LinkDecor.ARROW, LinkDecor.NONE), arg.get(6), lenght, null, - arg.get(7), getSystem().getLabeldistance(), getSystem().getLabelangle()); - if (arg.get(5) != null) { - final Direction direction = StringUtils.getArrowDirection(arg.get(5)); + Link link = new Link(entity1, branch, new LinkType(LinkDecor.ARROW, LinkDecor.NONE), arg.get("BRACKET").get(0), + lenght, null, arg.get("IF").get(0), getSystem().getLabeldistance(), getSystem().getLabelangle()); + if (arg.get("ARROW").get(0) != null) { + final Direction direction = StringUtils.getArrowDirection(arg.get("ARROW").get(0)); if (direction == Direction.LEFT || direction == Direction.UP) { link = link.getInv(); } @@ -81,7 +97,6 @@ public class CommandIf extends SingleLineCommand { getSystem().addLink(link); - getSystem().setAcceptOldSyntaxForBranch(false); return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkActivity.java b/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkActivity.java new file mode 100644 index 000000000..6411b15f9 --- /dev/null +++ b/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkActivity.java @@ -0,0 +1,187 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009, 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 Lesser 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: 5024 $ + * + */ +package net.sourceforge.plantuml.activitydiagram.command; + +import java.util.Map; + +import net.sourceforge.plantuml.Direction; +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.activitydiagram.ActivityDiagram; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand2; +import net.sourceforge.plantuml.command.regex.RegexConcat; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexOr; +import net.sourceforge.plantuml.command.regex.RegexPartialMatch; +import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Link; +import net.sourceforge.plantuml.cucadiagram.LinkDecor; +import net.sourceforge.plantuml.cucadiagram.LinkType; +import net.sourceforge.plantuml.cucadiagram.Stereotype; + +public class CommandLinkActivity extends SingleLineCommand2 { + + public CommandLinkActivity(ActivityDiagram diagram) { + super( + diagram, getRegexConcat()); + } + + static RegexConcat getRegexConcat() { + return new RegexConcat(new RegexLeaf("^"), + new RegexOr("FIRST", true, + new RegexLeaf("STAR", "(\\(\\*\\))"), + new RegexLeaf("CODE", "([\\p{L}0-9_.]+)"), + new RegexLeaf("BAR", "(?:==+)\\s*([\\p{L}0-9_.]+)\\s*(?:==+)"), + new RegexLeaf("QUOTED", "\"([^\"]+)\"(?:\\s+as\\s+([\\p{L}0-9_.]+))?")), + new RegexLeaf("\\s*"), + new RegexLeaf("STEREOTYPE", "(\\<\\<.*\\>\\>)?"), + new RegexLeaf("\\s*"), + new RegexLeaf("BACKCOLOR", "(#\\w+)?"), + new RegexLeaf("\\s*"), + new RegexLeaf("ARROW", "([=-]+(?:left|right|up|down|le?|ri?|up?|do?)?[=-]*\\>)"), + new RegexLeaf("\\s*"), + new RegexLeaf("BRACKET", "(?:\\[([^\\]*]+[^\\]]*)\\])?"), + new RegexLeaf("\\s*"), + new RegexOr("FIRST2", + new RegexLeaf("STAR2", "(\\(\\*\\))"), + new RegexLeaf("OPENBRACKET2", "(\\{)"), + new RegexLeaf("CODE2", "([\\p{L}0-9_.]+)"), + new RegexLeaf("BAR2", "(?:==+)\\s*([\\p{L}0-9_.]+)\\s*(?:==+)"), + new RegexLeaf("QUOTED2", "\"([^\"]+)\"(?:\\s+as\\s+([\\p{L}0-9_.]+))?")), + new RegexLeaf("\\s*"), + new RegexLeaf("STEREOTYPE2", "(\\<\\<.*\\>\\>)?"), + new RegexLeaf("\\s*"), + new RegexLeaf("BACKCOLOR2", "(#\\w+)?"), + new RegexLeaf("$")); + } + + @Override + protected CommandExecutionResult executeArg(Map arg2) { + final IEntity entity1 = getEntity(getSystem(), arg2, true); + if (arg2.get("STEREOTYPE").get(0) != null) { + entity1.setStereotype(new Stereotype(arg2.get("STEREOTYPE").get(0))); + } + if (arg2.get("BACKCOLOR").get(0) != null) { + entity1.setSpecificBackcolor(arg2.get("BACKCOLOR").get(0)); + } + + final IEntity entity2 = getEntity(getSystem(), arg2, false); + if (arg2.get("BACKCOLOR2").get(0) != null) { + entity2.setSpecificBackcolor(arg2.get("BACKCOLOR2").get(0)); + } + if (arg2.get("STEREOTYPE2").get(0) != null) { + entity2.setStereotype(new Stereotype(arg2.get("STEREOTYPE2").get(0))); + } + + final String linkLabel = arg2.get("BRACKET").get(0); + + final String arrow = StringUtils.manageArrowForCuca(arg2.get("ARROW").get(0)); + final int lenght = arrow.length() - 1; + + Link link = new Link(entity1, entity2, new LinkType(LinkDecor.ARROW, LinkDecor.NONE), linkLabel, lenght); + final Direction direction = StringUtils.getArrowDirection(arg2.get("ARROW").get(0)); + if (direction == Direction.LEFT || direction == Direction.UP) { + link = link.getInv(); + } + + getSystem().addLink(link); + + return CommandExecutionResult.ok(); + + } + + + + + static IEntity getEntity(ActivityDiagram system, Map arg, final boolean start) { + final String suf = start ? "" : "2"; + + final RegexPartialMatch openBracket = arg.get("OPENBRACKET" + suf); + if (openBracket!=null && openBracket.get(0) != null) { + return system.createInnerActivity(); + } + if (arg.get("STAR" + suf).get(0) != null) { + if (start) { + return system.getStart(); + } + return system.getEnd(); + } + final String code = arg.get("CODE" + suf).get(0); + if (code != null) { + return system.getOrCreate(code, code, getTypeIfExisting(system, code)); + } + final String bar = arg.get("BAR" + suf).get(0); + if (bar != null) { + return system.getOrCreate(bar, bar, EntityType.SYNCHRO_BAR); + } + final RegexPartialMatch quoted = arg.get("QUOTED" + suf); + if (quoted.get(0) != null) { + final String quotedCode = quoted.get(1) == null ? quoted.get(0) : quoted.get(1); + return system.getOrCreate(quotedCode, quoted.get(0), getTypeIfExisting(system, + quotedCode)); + } + final String first = arg.get("FIRST" + suf).get(0); + if (first == null) { + return system.getLastEntityConsulted(); + } + throw new UnsupportedOperationException(); + } + + + static EntityType getTypeIfExisting(ActivityDiagram system, String code) { + if (system.entityExist(code)) { + final IEntity ent = system.entities().get(code); + if (ent.getType() == EntityType.BRANCH) { + return EntityType.BRANCH; + } + } + return EntityType.ACTIVITY; + } + + static EntityType getTypeFromString(String type, final EntityType circle) { + if (type == null) { + return EntityType.ACTIVITY; + } + if (type.equals("*")) { + return circle; + } + if (type.startsWith("=")) { + return EntityType.SYNCHRO_BAR; + } + throw new IllegalArgumentException(); + } + + +} diff --git a/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkActivity2.java b/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkActivity2.java deleted file mode 100644 index 77bfa3b7d..000000000 --- a/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkActivity2.java +++ /dev/null @@ -1,125 +0,0 @@ -/* ======================================================================== - * PlantUML : a free UML diagram generator - * ======================================================================== - * - * (C) Copyright 2009, 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 Lesser 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: 5024 $ - * - */ -package net.sourceforge.plantuml.activitydiagram.command; - -import java.util.List; - -import net.sourceforge.plantuml.Direction; -import net.sourceforge.plantuml.StringUtils; -import net.sourceforge.plantuml.activitydiagram.ActivityDiagram; -import net.sourceforge.plantuml.command.CommandExecutionResult; -import net.sourceforge.plantuml.command.SingleLineCommand; -import net.sourceforge.plantuml.cucadiagram.EntityType; -import net.sourceforge.plantuml.cucadiagram.IEntity; -import net.sourceforge.plantuml.cucadiagram.Link; -import net.sourceforge.plantuml.cucadiagram.LinkDecor; -import net.sourceforge.plantuml.cucadiagram.LinkType; - -public class CommandLinkActivity2 extends SingleLineCommand { - - public CommandLinkActivity2(ActivityDiagram diagram) { - super( - diagram, - "(?i)^(?:(\\(\\*\\))|([\\p{L}0-9_.]+)|(?:==+)\\s*([\\p{L}0-9_.]+)\\s*(?:==+)|\"([^\"]+)\"(?:\\s+as\\s+([\\p{L}0-9_.]+))?)?" - + "\\s*([=-]+(?:left|right|up|down|le?|ri?|up?|do?)?[=-]*\\>)\\s*(?:\\[([^\\]*]+[^\\]]*)\\])?\\s*" - + "(?:(\\(\\*\\)|\\{)|([\\p{L}0-9_.]+)|(?:==+)\\s*([\\p{L}0-9_.]+)\\s*(?:==+)|\"([^\"]+)\"(?:\\s+as\\s+([\\p{L}0-9_.]+))?)$"); - } - - @Override - protected void actionIfCommandValid() { - getSystem().setAcceptOldSyntaxForBranch(false); - } - - static IEntity getEntity(ActivityDiagram system, List arg, final boolean start) { - if ("{".equals(arg.get(0))) { - return system.createInnerActivity(); - } - if ("(*)".equals(arg.get(0))) { - if (start) { - return system.getStart(); - } - return system.getEnd(); - } - if (arg.get(1) != null) { - return system.getOrCreate(arg.get(1), arg.get(1), EntityType.ACTIVITY); - } - if (arg.get(2) != null) { - return system.getOrCreate(arg.get(2), arg.get(2), EntityType.SYNCHRO_BAR); - } - if (arg.get(3) != null) { - final String code = arg.get(4) == null ? arg.get(3) : arg.get(4); - return system.getOrCreate(code, arg.get(3), EntityType.ACTIVITY); - } - if (start && arg.get(0) == null && arg.get(1) == null && arg.get(2) == null && arg.get(3) == null - && arg.get(4) == null) { - return system.getLastEntityConsulted(); - } - throw new UnsupportedOperationException(); - } - - @Override - protected CommandExecutionResult executeArg(List arg) { - final IEntity entity1 = getEntity(getSystem(), arg, true); - final IEntity entity2 = getEntity(getSystem(), arg.subList(7, 12), false); - final String linkLabel = arg.get(6); - - final String arrow = StringUtils.manageArrowForCuca(arg.get(5)); - final int lenght = arrow.length() - 1; - - Link link = new Link(entity1, entity2, new LinkType(LinkDecor.ARROW, LinkDecor.NONE), linkLabel, lenght); - final Direction direction = StringUtils.getArrowDirection(arg.get(5)); - if (direction == Direction.LEFT || direction == Direction.UP) { - link = link.getInv(); - } - - getSystem().addLink(link); - - return CommandExecutionResult.ok(); - - } - - static EntityType getTypeFromString(String type, final EntityType circle) { - if (type == null) { - return EntityType.ACTIVITY; - } - if (type.equals("*")) { - return circle; - } - if (type.startsWith("=")) { - return EntityType.SYNCHRO_BAR; - } - throw new IllegalArgumentException(); - } - -} diff --git a/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkLongActivity2.java b/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkLongActivity.java similarity index 57% rename from src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkLongActivity2.java rename to src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkLongActivity.java index 55df3cc02..17ebd1525 100644 --- a/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkLongActivity2.java +++ b/src/net/sourceforge/plantuml/activitydiagram/command/CommandLinkLongActivity.java @@ -34,45 +34,69 @@ package net.sourceforge.plantuml.activitydiagram.command; import java.util.List; +import java.util.Map; import net.sourceforge.plantuml.Direction; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.activitydiagram.ActivityDiagram; import net.sourceforge.plantuml.command.CommandExecutionResult; -import net.sourceforge.plantuml.command.CommandMultilines; +import net.sourceforge.plantuml.command.CommandMultilines2; +import net.sourceforge.plantuml.command.regex.RegexConcat; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexOr; +import net.sourceforge.plantuml.command.regex.RegexPartialMatch; import net.sourceforge.plantuml.cucadiagram.Entity; import net.sourceforge.plantuml.cucadiagram.EntityType; import net.sourceforge.plantuml.cucadiagram.IEntity; import net.sourceforge.plantuml.cucadiagram.Link; import net.sourceforge.plantuml.cucadiagram.LinkDecor; import net.sourceforge.plantuml.cucadiagram.LinkType; +import net.sourceforge.plantuml.cucadiagram.Stereotype; -public class CommandLinkLongActivity2 extends CommandMultilines { +public class CommandLinkLongActivity extends CommandMultilines2 { - public CommandLinkLongActivity2(final ActivityDiagram diagram) { + public CommandLinkLongActivity(final ActivityDiagram diagram) { super( diagram, - "(?i)^(?:(\\(\\*\\))|([\\p{L}0-9_.]+)|(?:==+)\\s*([\\p{L}0-9_.]+)\\s*(?:==+)|\"([^\"]+)\"(?:\\s+as\\s+([\\p{L}0-9_.]+))?)?" - + "\\s*([=-]+(?:left|right|up|down|le?|ri?|up?|do?)?[=-]*\\>)\\s*(?:\\[([^\\]*]+[^\\]]*)\\])?\\s*\"([^\"]*?)\\s*$", - "(?i)^\\s*([^\"]*)\"(?:\\s+as\\s+([\\p{L}0-9_.]+))?$"); + getRegexConcat(), + "(?i)^\\s*([^\"]*)\"(?:\\s+as\\s+([\\p{L}0-9_.]+))?\\s*(\\<\\<.*\\>\\>)?\\s*(#\\w+)?$"); } - - @Override - protected void actionIfCommandValid() { - getSystem().setAcceptOldSyntaxForBranch(false); + + static RegexConcat getRegexConcat() { + return new RegexConcat(new RegexLeaf("^"), + new RegexOr("FIRST", true, + new RegexLeaf("STAR", "(\\(\\*\\))"), + new RegexLeaf("CODE", "([\\p{L}0-9_.]+)"), + new RegexLeaf("BAR", "(?:==+)\\s*([\\p{L}0-9_.]+)\\s*(?:==+)"), + new RegexLeaf("QUOTED", "\"([^\"]+)\"(?:\\s+as\\s+([\\p{L}0-9_.]+))?")), + new RegexLeaf("\\s*"), + new RegexLeaf("STEREOTYPE", "(\\<\\<.*\\>\\>)?"), + new RegexLeaf("\\s*"), + new RegexLeaf("BACKCOLOR", "(#\\w+)?"), + new RegexLeaf("\\s*"), + new RegexLeaf("ARROW", "([=-]+(?:left|right|up|down|le?|ri?|up?|do?)?[=-]*\\>)"), + new RegexLeaf("\\s*"), + new RegexLeaf("BRACKET", "(?:\\[([^\\]*]+[^\\]]*)\\])?"), + new RegexLeaf("\\s*"), + new RegexLeaf("DESC", "\"([^\"]*?)"), + new RegexLeaf("\\s*"), + new RegexLeaf("$")); } public CommandExecutionResult execute(List lines) { - - // final IEntity lastEntityConsulted = - // getSystem().getLastEntityConsulted(); - - final List line0 = StringUtils.getSplit(getStartingPattern(), lines.get(0)); - final IEntity entity1 = CommandLinkActivity2.getEntity(getSystem(), line0, true); + StringUtils.trim(lines); + final Map line0 = getStartingPattern().matcher(lines.get(0).trim()); + final IEntity entity1 = CommandLinkActivity.getEntity(getSystem(), line0, true); + if (line0.get("STEREOTYPE").get(0) != null) { + entity1.setStereotype(new Stereotype(line0.get("STEREOTYPE").get(0))); + } + if (line0.get("BACKCOLOR").get(0)!=null) { + entity1.setSpecificBackcolor(line0.get("BACKCOLOR").get(0)); + } final StringBuilder sb = new StringBuilder(); - if (StringUtils.isNotEmpty(line0.get(7))) { - sb.append(line0.get(7)); + if (StringUtils.isNotEmpty(line0.get("DESC").get(0))) { + sb.append(line0.get("DESC").get(0)); sb.append("\\n"); } for (int i = 1; i < lines.size() - 1; i++) { @@ -84,7 +108,9 @@ public class CommandLinkLongActivity2 extends CommandMultilines final List lineLast = StringUtils.getSplit(getEnding(), lines.get(lines.size() - 1)); if (StringUtils.isNotEmpty(lineLast.get(0))) { - sb.append("\\n"); + if (sb.toString().endsWith("\\n") == false) { + sb.append("\\n"); + } sb.append(lineLast.get(0)); } @@ -92,18 +118,24 @@ public class CommandLinkLongActivity2 extends CommandMultilines final String code = lineLast.get(1) == null ? display : lineLast.get(1); final Entity entity2 = getSystem().createEntity(code, display, EntityType.ACTIVITY); + if (lineLast.get(2)!=null) { + entity2.setStereotype(new Stereotype(lineLast.get(2))); + } + if (lineLast.get(3)!=null) { + entity2.setSpecificBackcolor(lineLast.get(3)); + } if (entity1 == null || entity2 == null) { return CommandExecutionResult.error("No such entity"); } - final String arrow = StringUtils.manageArrowForCuca(line0.get(5)); + final String arrow = StringUtils.manageArrowForCuca(line0.get("ARROW").get(0)); final int lenght = arrow.length() - 1; - final String linkLabel = line0.get(6); + final String linkLabel = line0.get("BRACKET").get(0); Link link = new Link(entity1, entity2, new LinkType(LinkDecor.ARROW, LinkDecor.NONE), linkLabel, lenght); - final Direction direction = StringUtils.getArrowDirection(line0.get(5)); + final Direction direction = StringUtils.getArrowDirection(line0.get("ARROW").get(0)); if (direction == Direction.LEFT || direction == Direction.UP) { link = link.getInv(); } diff --git a/src/net/sourceforge/plantuml/activitydiagram/command/CommandMultilinesNoteActivity.java b/src/net/sourceforge/plantuml/activitydiagram/command/CommandMultilinesNoteActivity.java index 984b0c378..9ac8153d3 100644 --- a/src/net/sourceforge/plantuml/activitydiagram/command/CommandMultilinesNoteActivity.java +++ b/src/net/sourceforge/plantuml/activitydiagram/command/CommandMultilinesNoteActivity.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5019 $ + * Revision $Revision: 5751 $ * */ package net.sourceforge.plantuml.activitydiagram.command; @@ -56,7 +56,7 @@ public class CommandMultilinesNoteActivity extends CommandMultilines lines) { - final List line0 = StringUtils.getSplit(getStartingPattern(), lines.get(0)); + final List line0 = StringUtils.getSplit(getStartingPattern(), lines.get(0).trim()); final String pos = line0.get(0); IEntity activity = getSystem().getLastEntityConsulted(); @@ -64,7 +64,7 @@ public class CommandMultilinesNoteActivity extends CommandMultilines strings = lines.subList(1, lines.size() - 1); + final List strings = StringUtils.removeEmptyColumns(lines.subList(1, lines.size() - 1)); final String s = StringUtils.getMergedLines(strings); final Entity note = getSystem().createEntity("GMN" + UniqueSequence.getValue(), s, EntityType.NOTE); diff --git a/src/net/sourceforge/plantuml/activitydiagram/command/CommandMultilinesNoteActivityLink.java b/src/net/sourceforge/plantuml/activitydiagram/command/CommandMultilinesNoteActivityLink.java index 70cf64040..6b888f863 100644 --- a/src/net/sourceforge/plantuml/activitydiagram/command/CommandMultilinesNoteActivityLink.java +++ b/src/net/sourceforge/plantuml/activitydiagram/command/CommandMultilinesNoteActivityLink.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 4762 $ + * Revision $Revision: 5751 $ * */ package net.sourceforge.plantuml.activitydiagram.command; @@ -49,7 +49,7 @@ public class CommandMultilinesNoteActivityLink extends CommandMultilines lines) { - final List strings = lines.subList(1, lines.size() - 1); + final List strings = StringUtils.removeEmptyColumns(lines.subList(1, lines.size() - 1)); final String s = StringUtils.getMergedLines(strings); final Link link = getSystem().getLastActivityLink(); diff --git a/src/net/sourceforge/plantuml/ant/PlantUmlTask.java b/src/net/sourceforge/plantuml/ant/PlantUmlTask.java index 242ae7fde..ac803e3c3 100644 --- a/src/net/sourceforge/plantuml/ant/PlantUmlTask.java +++ b/src/net/sourceforge/plantuml/ant/PlantUmlTask.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5354 $ + * Revision $Revision: 5877 $ * */ package net.sourceforge.plantuml.ant; @@ -145,7 +145,7 @@ public class PlantUmlTask extends Task { private void processingSingleFile(final File f) throws IOException, InterruptedException { this.log("Processing " + f.getAbsolutePath()); final SourceFileReader sourceFileReader = new SourceFileReader(new Defines(), f, option.getOutputDir(), option - .getConfig(), option.getCharset(), option.getFileFormat()); + .getConfig(), option.getCharset(), option.getFileFormatOption()); final Collection result = sourceFileReader.getGeneratedImages(); for (GeneratedImage g : result) { this.log(g + " " + g.getDescription()); @@ -198,6 +198,15 @@ public class PlantUmlTask extends Task { } public void setFormat(String s) { + if ("xmi".equalsIgnoreCase(s)) { + option.setFileFormat(FileFormat.XMI_STANDARD); + } + if ("xmi:argo".equalsIgnoreCase(s)) { + option.setFileFormat(FileFormat.XMI_ARGO); + } + if ("xmi:start".equalsIgnoreCase(s)) { + option.setFileFormat(FileFormat.XMI_STAR); + } if ("eps".equalsIgnoreCase(s)) { option.setFileFormat(FileFormat.EPS); } diff --git a/src/net/sourceforge/plantuml/ant/PlantuTask.java b/src/net/sourceforge/plantuml/ant/PlantuTask.java index 75cf2128a..2a8593379 100644 --- a/src/net/sourceforge/plantuml/ant/PlantuTask.java +++ b/src/net/sourceforge/plantuml/ant/PlantuTask.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5354 $ + * Revision $Revision: 5877 $ * */ package net.sourceforge.plantuml.ant; @@ -145,7 +145,7 @@ public class PlantuTask extends Task { private void processingSingleFile(final File f) throws IOException, InterruptedException { this.log("Processing " + f.getAbsolutePath()); final SourceFileReader sourceFileReader = new SourceFileReader(new Defines(), f, option.getOutputDir(), option - .getConfig(), option.getCharset(), option.getFileFormat()); + .getConfig(), option.getCharset(), option.getFileFormatOption()); final Collection result = sourceFileReader.getGeneratedImages(); for (GeneratedImage g : result) { this.log(g + " " + g.getDescription()); @@ -198,6 +198,15 @@ public class PlantuTask extends Task { } public void setFormat(String s) { + if ("xmi".equalsIgnoreCase(s)) { + option.setFileFormat(FileFormat.XMI_STANDARD); + } + if ("xmi:argo".equalsIgnoreCase(s)) { + option.setFileFormat(FileFormat.XMI_ARGO); + } + if ("xmi:start".equalsIgnoreCase(s)) { + option.setFileFormat(FileFormat.XMI_STAR); + } if ("eps".equalsIgnoreCase(s)) { option.setFileFormat(FileFormat.EPS); } diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateEntityClass.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateEntityClass.java deleted file mode 100644 index cc21ca9d7..000000000 --- a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateEntityClass.java +++ /dev/null @@ -1,77 +0,0 @@ -/* ======================================================================== - * PlantUML : a free UML diagram generator - * ======================================================================== - * - * (C) Copyright 2009, 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 Lesser 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: 5075 $ - * - */ -package net.sourceforge.plantuml.classdiagram.command; - -import java.util.List; - -import net.sourceforge.plantuml.FontParam; -import net.sourceforge.plantuml.classdiagram.ClassDiagram; -import net.sourceforge.plantuml.command.CommandExecutionResult; -import net.sourceforge.plantuml.command.SingleLineCommand; -import net.sourceforge.plantuml.cucadiagram.Entity; -import net.sourceforge.plantuml.cucadiagram.EntityType; -import net.sourceforge.plantuml.cucadiagram.Stereotype; - -public class CommandCreateEntityClass extends SingleLineCommand { - - public CommandCreateEntityClass(ClassDiagram diagram) { - super( - diagram, - "(?i)^(interface|enum|abstract\\s+class|abstract|class)\\s+(?:\"([^\"]+)\"\\s+as\\s+)?(\\.?[\\p{L}0-9_]+(?:\\.[\\p{L}0-9_]+)*)(?:\\s*([\\<\\[]{2}.*[\\>\\]]{2}))?$"); - } - - @Override - protected CommandExecutionResult executeArg(List arg) { - final String arg0 = arg.get(0).toUpperCase(); - final EntityType type = EntityType.getEntityType(arg0); - final String code = arg.get(2); - final String display = arg.get(1); - final String stereotype = arg.get(3); - final Entity entity; - if (getSystem().entityExist(code)) { - // return CommandExecutionResult.error("Class already exists : " - // + code); - entity = (Entity) getSystem().getOrCreateEntity(code, type); - entity.muteToType(type); - } else { - entity = getSystem().createEntity(code, display, type); - } - if (stereotype != null) { - entity.setStereotype(new Stereotype(stereotype, getSystem().getSkinParam().getCircledCharacterRadius(), - getSystem().getSkinParam().getFont(FontParam.CIRCLED_CHARACTER))); - } - return CommandExecutionResult.ok(); - } - -} diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateEntityClass2.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateEntityClass2.java index 8cfc15994..962aa8449 100644 --- a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateEntityClass2.java +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateEntityClass2.java @@ -89,7 +89,7 @@ public class CommandCreateEntityClass2 extends SingleLineCommand2 } if (stereotype != null) { entity.setStereotype(new Stereotype(stereotype, getSystem().getSkinParam().getCircledCharacterRadius(), - getSystem().getSkinParam().getFont(FontParam.CIRCLED_CHARACTER))); + getSystem().getSkinParam().getFont(FontParam.CIRCLED_CHARACTER, null))); } return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateEntityClassMultilines.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateEntityClassMultilines.java deleted file mode 100644 index 687b74a06..000000000 --- a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateEntityClassMultilines.java +++ /dev/null @@ -1,91 +0,0 @@ -/* ======================================================================== - * PlantUML : a free UML diagram generator - * ======================================================================== - * - * (C) Copyright 2009, 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 Lesser 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: 4161 $ - * - */ -package net.sourceforge.plantuml.classdiagram.command; - -import java.util.List; - -import net.sourceforge.plantuml.FontParam; -import net.sourceforge.plantuml.StringUtils; -import net.sourceforge.plantuml.classdiagram.ClassDiagram; -import net.sourceforge.plantuml.command.CommandExecutionResult; -import net.sourceforge.plantuml.command.CommandMultilines; -import net.sourceforge.plantuml.cucadiagram.Entity; -import net.sourceforge.plantuml.cucadiagram.EntityType; -import net.sourceforge.plantuml.cucadiagram.Stereotype; -import net.sourceforge.plantuml.skin.VisibilityModifier; - -public class CommandCreateEntityClassMultilines extends CommandMultilines { - - public CommandCreateEntityClassMultilines(ClassDiagram diagram) { - super( - diagram, - "(?i)^(interface|enum|abstract\\s+class|abstract|class)\\s+(?:\"([^\"]+)\"\\s+as\\s+)?(\\.?[\\p{L}0-9_]+(?:\\.[\\p{L}0-9_]+)*)(?:\\s*([\\<\\[]{2}.*[\\>\\]]{2}))?\\s*\\{\\s*$", - "(?i)^\\s*\\}\\s*$"); - } - - public CommandExecutionResult execute(List lines) { - final List line0 = StringUtils.getSplit(getStartingPattern(), lines.get(0)); - final Entity entity = executeArg0(line0); - if (entity == null) { - return CommandExecutionResult.error("No such entity"); - } - for (String s : lines.subList(1, lines.size() - 1)) { - if (s.length() > 0 && VisibilityModifier.isVisibilityCharacter(s.charAt(0))) { - getSystem().setVisibilityModifierPresent(true); - } - entity.addFieldOrMethod(s); - } - return CommandExecutionResult.ok(); - } - - private Entity executeArg0(List arg) { - final String arg0 = arg.get(0).toUpperCase(); - final EntityType type = EntityType.getEntityType(arg0); - final String code = arg.get(2); - final String display = arg.get(1); - final String stereotype = arg.get(3); - if (getSystem().entityExist(code)) { - final Entity result = (Entity) getSystem().getOrCreateClass(code); - result.muteToType(type); - return result; - } - final Entity entity = getSystem().createEntity(code, display, type); - if (stereotype != null) { - entity.setStereotype(new Stereotype(stereotype, getSystem().getSkinParam().getCircledCharacterRadius(), - getSystem().getSkinParam().getFont(FontParam.CIRCLED_CHARACTER))); - } - return entity; - } - -} diff --git a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateEntityClassMultilines2.java b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateEntityClassMultilines2.java index 05ffd625e..8d532f448 100644 --- a/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateEntityClassMultilines2.java +++ b/src/net/sourceforge/plantuml/classdiagram/command/CommandCreateEntityClassMultilines2.java @@ -37,6 +37,7 @@ import java.util.List; import java.util.Map; import net.sourceforge.plantuml.FontParam; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.classdiagram.ClassDiagram; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.CommandMultilines2; @@ -68,12 +69,16 @@ public class CommandCreateEntityClassMultilines2 extends CommandMultilines2 lines) { - final Map line0 = getStartingPattern().matcher(lines.get(0)); + StringUtils.trim(lines); + final Map line0 = getStartingPattern().matcher(lines.get(0).trim()); final Entity entity = executeArg0(line0); if (entity == null) { return CommandExecutionResult.error("No such entity"); } for (String s : lines.subList(1, lines.size() - 1)) { + if (s.length()==0) { + continue; + } if (s.length() > 0 && VisibilityModifier.isVisibilityCharacter(s.charAt(0))) { getSystem().setVisibilityModifierPresent(true); } @@ -107,7 +112,7 @@ public class CommandCreateEntityClassMultilines2 extends CommandMultilines2 { @@ -61,10 +63,10 @@ final public class CommandLinkClass2 extends SingleLineCommand2\\>)?"), new RegexLeaf("COUPLE1", "\\(\\s*(\\.?[\\p{L}0-9_]+(?:\\.[\\p{L}0-9_]+)*)\\s*,\\s*(\\.?[\\p{L}0-9_]+(?:\\.[\\p{L}0-9_]+)*)\\s*\\)")), new RegexLeaf("\\s*"), @@ -83,7 +85,7 @@ final public class CommandLinkClass2 extends SingleLineCommand2\\>)?"), new RegexLeaf("COUPLE2", "\\(\\s*(\\.?[\\p{L}0-9_]+(?:\\.[\\p{L}0-9_]+)*)\\s*,\\s*(\\.?[\\p{L}0-9_]+(?:\\.[\\p{L}0-9_]+)*)\\s*\\)")), new RegexLeaf("\\s*"), new RegexLeaf("LABEL_LINK", "(?::\\s*([^\"]+))?$")); @@ -133,6 +135,14 @@ final public class CommandLinkClass2 extends SingleLineCommand2o*+]|\\|[>\\]])?)|(([\\[))" + "(?:\\(\\)([-=.]+)|([-=.]+)\\(\\))" @@ -158,7 +158,7 @@ final public class CommandLinkLollipop extends SingleLineCommand { final String stereotype = arg.get(1); final Entity entity = (Entity) getSystem().getOrCreateClass(code); entity.setStereotype(new Stereotype(stereotype, getSystem().getSkinParam().getCircledCharacterRadius(), - getSystem().getSkinParam().getFont(FontParam.CIRCLED_CHARACTER))); + getSystem().getSkinParam().getFont(FontParam.CIRCLED_CHARACTER, null))); return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/code/CompressionZlib.java b/src/net/sourceforge/plantuml/code/CompressionZlib.java new file mode 100644 index 000000000..29b6b8535 --- /dev/null +++ b/src/net/sourceforge/plantuml/code/CompressionZlib.java @@ -0,0 +1,112 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009, 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 Lesser 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: 3827 $ + * + */ +package net.sourceforge.plantuml.code; + +import java.io.IOException; +import java.util.zip.DataFormatException; +import java.util.zip.Deflater; +import java.util.zip.Inflater; + +public class CompressionZlib implements Compression { + + public byte[] compress(byte[] in) { + int len = in.length * 2; + byte[] result = null; + while (result == null) { + result = tryCompress(in, len); + len *= 2; + } + return result; + } + + private byte[] tryCompress(byte[] in, final int len) { + // Compress the bytes + final Deflater compresser = new Deflater(9, true); + compresser.setInput(in); + compresser.finish(); + + final byte[] output = new byte[len]; + final int compressedDataLength = compresser.deflate(output); + if (compresser.finished() == false) { + return null; + } + final byte[] result = copyArray(output, compressedDataLength); + return result; + } + + public byte[] decompress(byte[] in) throws IOException { + + final byte in2[] = new byte[in.length + 256]; + for (int i = 0; i < in.length; i++) { + in2[i] = in[i]; + } + + int len = in.length * 5; + byte[] result = null; + while (result == null) { + result = tryDecompress(in2, len); + len *= 2; + } + return result; + } + + private byte[] tryDecompress(byte[] in, final int len) throws IOException { + // Decompress the bytes + final byte[] tmp = new byte[len]; + final Inflater decompresser = new Inflater(true); + decompresser.setInput(in); + try { + final int resultLength = decompresser.inflate(tmp); + if (decompresser.finished() == false) { + return null; + } + decompresser.end(); + + final byte[] result = copyArray(tmp, resultLength); + return result; + } catch (DataFormatException e) { + e.printStackTrace(); + throw new IOException(e.toString()); + } + } + + private byte[] copyArray(final byte[] data, final int len) { + final byte[] result = new byte[len]; + for (int i = 0; i < result.length; i++) { + result[i] = data[i]; + } + return result; + } + +} diff --git a/src/net/sourceforge/plantuml/code/Transcoder.java b/src/net/sourceforge/plantuml/code/Transcoder.java index 07131f074..85bb12d67 100644 --- a/src/net/sourceforge/plantuml/code/Transcoder.java +++ b/src/net/sourceforge/plantuml/code/Transcoder.java @@ -28,48 +28,16 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 3827 $ + * Revision $Revision: 5669 $ * */ package net.sourceforge.plantuml.code; import java.io.IOException; -public class Transcoder { +public interface Transcoder { - private final Compression compression; - private final URLEncoder urlEncoder; - private final StringCompressor stringCompressor; - - public Transcoder() { - this(new AsciiEncoder(), new CompressionHuffman()); - } - - public Transcoder(URLEncoder urlEncoder, Compression compression) { - this(urlEncoder, new ArobaseStringCompressor(), compression); - } - - public Transcoder(URLEncoder urlEncoder, StringCompressor stringCompressor, Compression compression) { - this.compression = compression; - this.urlEncoder = urlEncoder; - this.stringCompressor = stringCompressor; - } - - public String encode(String text) throws IOException { - - final String stringAnnoted = stringCompressor.compress(text); - - final byte[] data = stringAnnoted.getBytes("UTF-8"); - final byte[] compressedData = compression.compress(data); - - return urlEncoder.encode(compressedData); - } - - public String decode(String code) throws IOException { - final byte compressedData[] = urlEncoder.decode(code); - final byte data[] = compression.decompress(compressedData); - - return stringCompressor.decompress(new String(data, "UTF-8")); - } + public String encode(String text) throws IOException; + public String decode(String code) throws IOException; } diff --git a/src/net/sourceforge/plantuml/code/TranscoderImpl.java b/src/net/sourceforge/plantuml/code/TranscoderImpl.java new file mode 100644 index 000000000..57acc0ecd --- /dev/null +++ b/src/net/sourceforge/plantuml/code/TranscoderImpl.java @@ -0,0 +1,75 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009, 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 Lesser 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: 5667 $ + * + */ +package net.sourceforge.plantuml.code; + +import java.io.IOException; + +public class TranscoderImpl implements Transcoder { + + private final Compression compression; + private final URLEncoder urlEncoder; + private final StringCompressor stringCompressor; + + public TranscoderImpl() { + this(new AsciiEncoder(), new CompressionHuffman()); + } + + public TranscoderImpl(URLEncoder urlEncoder, Compression compression) { + this(urlEncoder, new ArobaseStringCompressor(), compression); + } + + public TranscoderImpl(URLEncoder urlEncoder, StringCompressor stringCompressor, Compression compression) { + this.compression = compression; + this.urlEncoder = urlEncoder; + this.stringCompressor = stringCompressor; + } + + public String encode(String text) throws IOException { + + final String stringAnnoted = stringCompressor.compress(text); + + final byte[] data = stringAnnoted.getBytes("UTF-8"); + final byte[] compressedData = compression.compress(data); + + return urlEncoder.encode(compressedData); + } + + public String decode(String code) throws IOException { + final byte compressedData[] = urlEncoder.decode(code); + final byte data[] = compression.decompress(compressedData); + + return stringCompressor.decompress(new String(data, "UTF-8")); + } + +} diff --git a/src/net/sourceforge/plantuml/code/TranscoderSmart.java b/src/net/sourceforge/plantuml/code/TranscoderSmart.java new file mode 100644 index 000000000..cfbe73ce0 --- /dev/null +++ b/src/net/sourceforge/plantuml/code/TranscoderSmart.java @@ -0,0 +1,54 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009, 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 Lesser 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: 5667 $ + * + */ +package net.sourceforge.plantuml.code; + +import java.io.IOException; + +public class TranscoderSmart implements Transcoder { + + private final Transcoder oldOne = new TranscoderImpl(new AsciiEncoder(), new CompressionHuffman()); + private final Transcoder zlib = new TranscoderImpl(new AsciiEncoder(), new CompressionZlib()); + + + public String decode(String code) throws IOException { + try { + return zlib.decode(code); + } catch (Exception ex) { + return oldOne.decode(code); + } + } + public String encode(String text) throws IOException { + return zlib.encode(text); + } +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/VirtualHBarType.java b/src/net/sourceforge/plantuml/code/TranscoderUtil.java similarity index 86% rename from src/net/sourceforge/plantuml/sequencediagram/graphic/VirtualHBarType.java rename to src/net/sourceforge/plantuml/code/TranscoderUtil.java index 17970c233..6877fc28d 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/VirtualHBarType.java +++ b/src/net/sourceforge/plantuml/code/TranscoderUtil.java @@ -27,13 +27,16 @@ * in the United States and other countries.] * * Original Author: Arnaud Roques - * - * Revision $Revision: 3836 $ + * + * Revision $Revision: 5667 $ * */ -package net.sourceforge.plantuml.sequencediagram.graphic; +package net.sourceforge.plantuml.code; -public enum VirtualHBarType { - START, END +public class TranscoderUtil { -} \ No newline at end of file + public static Transcoder getDefaultTranscoder() { + return new TranscoderSmart(); + } + +} diff --git a/src/net/sourceforge/plantuml/command/AbstractCommandMultilinesNoteEntity.java b/src/net/sourceforge/plantuml/command/AbstractCommandMultilinesNoteEntity.java index 3fb8132fa..f92a4d12e 100644 --- a/src/net/sourceforge/plantuml/command/AbstractCommandMultilinesNoteEntity.java +++ b/src/net/sourceforge/plantuml/command/AbstractCommandMultilinesNoteEntity.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5019 $ + * Revision $Revision: 5751 $ * */ package net.sourceforge.plantuml.command; @@ -53,12 +53,12 @@ public abstract class AbstractCommandMultilinesNoteEntity extends CommandMultili public final CommandExecutionResult execute(List lines) { - final List line0 = StringUtils.getSplit(getStartingPattern(), lines.get(0)); + final List line0 = StringUtils.getSplit(getStartingPattern(), lines.get(0).trim()); final String pos = line0.get(0); final IEntity cl1 = getSystem().getOrCreateClass(line0.get(1)); - final List strings = lines.subList(1, lines.size() - 1); + final List strings = StringUtils.removeEmptyColumns(lines.subList(1, lines.size() - 1)); final String s = StringUtils.getMergedLines(strings); final Entity note = getSystem().createEntity("GMN" + UniqueSequence.getValue(), s, EntityType.NOTE); diff --git a/src/net/sourceforge/plantuml/command/AbstractUmlSystemCommandFactory.java b/src/net/sourceforge/plantuml/command/AbstractUmlSystemCommandFactory.java index c102af3b5..50a165eae 100644 --- a/src/net/sourceforge/plantuml/command/AbstractUmlSystemCommandFactory.java +++ b/src/net/sourceforge/plantuml/command/AbstractUmlSystemCommandFactory.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5504 $ + * Revision $Revision: 5764 $ * */ package net.sourceforge.plantuml.command; @@ -77,6 +77,7 @@ public abstract class AbstractUmlSystemCommandFactory implements PSystemCommandF protected abstract void initCommands(); final protected void addCommonCommands(UmlDiagram system) { + addCommand(new CommandNope(system)); addCommand(new CommandPragma(system)); addCommand(new CommandTitle(system)); addCommand(new CommandMultilinesTitle(system)); @@ -88,6 +89,7 @@ public abstract class AbstractUmlSystemCommandFactory implements PSystemCommandF addCommand(new CommandMultilinesHeader(system)); addCommand(new CommandSkinParam(system)); + addCommand(new CommandSkinParamMultilines(system)); addCommand(new CommandMinwidth(system)); addCommand(new CommandRotate(system)); addCommand(new CommandScale(system)); diff --git a/src/net/sourceforge/plantuml/command/CommandMultilines.java b/src/net/sourceforge/plantuml/command/CommandMultilines.java index 9a60656bf..272702b28 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: 5041 $ + * Revision $Revision: 5749 $ * */ package net.sourceforge.plantuml.command; @@ -62,7 +62,7 @@ public abstract class CommandMultilines implements Command { if (isCommandForbidden()) { return CommandControl.NOT_OK; } - Matcher m1 = starting.matcher(lines.get(0)); + Matcher m1 = starting.matcher(lines.get(0).trim()); if (m1.matches() == false) { return CommandControl.NOT_OK; } @@ -70,7 +70,7 @@ public abstract class CommandMultilines implements Command { return CommandControl.OK_PARTIAL; } - m1 = ending.matcher(lines.get(lines.size() - 1)); + m1 = ending.matcher(lines.get(lines.size() - 1).trim()); 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 b48434ee2..a557daead 100644 --- a/src/net/sourceforge/plantuml/command/CommandMultilines2.java +++ b/src/net/sourceforge/plantuml/command/CommandMultilines2.java @@ -63,8 +63,7 @@ public abstract class CommandMultilines2 implements Command { if (isCommandForbidden()) { return CommandControl.NOT_OK; } - //Matcher m1 = starting.matcher(lines.get(0)); - final boolean result1 = starting.match(lines.get(0)); + final boolean result1 = starting.match(lines.get(0).trim()); if (result1 == false) { return CommandControl.NOT_OK; } @@ -72,7 +71,7 @@ public abstract class CommandMultilines2 implements Command { return CommandControl.OK_PARTIAL; } - Matcher m1 = ending.matcher(lines.get(lines.size() - 1)); + Matcher m1 = ending.matcher(lines.get(lines.size() - 1).trim()); if (m1.matches() == false) { return CommandControl.OK_PARTIAL; } diff --git a/src/net/sourceforge/plantuml/command/CommandMultilinesBracket.java b/src/net/sourceforge/plantuml/command/CommandMultilinesBracket.java new file mode 100644 index 000000000..7e02dfc9a --- /dev/null +++ b/src/net/sourceforge/plantuml/command/CommandMultilinesBracket.java @@ -0,0 +1,117 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009, 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 Lesser 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: 5041 $ + * + */ +package net.sourceforge.plantuml.command; + +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import net.sourceforge.plantuml.PSystem; + +public abstract class CommandMultilinesBracket implements Command { + + private final S system; + + private final Pattern starting; + + public CommandMultilinesBracket(final S system, String patternStart) { + if (patternStart.startsWith("(?i)^") == false || patternStart.endsWith("$") == false) { + throw new IllegalArgumentException("Bad pattern " + patternStart); + } + this.system = system; + this.starting = Pattern.compile(patternStart); + } + + protected boolean isCommandForbidden() { + return false; + } + + protected void actionIfCommandValid() { + } + + protected S getSystem() { + return system; + } + + protected final Pattern getStartingPattern() { + return starting; + } + + public boolean isDeprecated(List line) { + return false; + } + + public String getHelpMessageForDeprecated(List lines) { + return null; + } + + final public CommandControl isValid(List lines) { + if (isCommandForbidden()) { + return CommandControl.NOT_OK; + } + final Matcher m1 = starting.matcher(lines.get(0).trim()); + if (m1.matches() == false) { + return CommandControl.NOT_OK; + } + if (lines.size() == 1) { + return CommandControl.OK_PARTIAL; + } + + int level = 1; + for (int i = 1; i < lines.size(); i++) { + final String s = lines.get(i).trim(); + if (isLineConsistent(s, level) == false) { + return CommandControl.NOT_OK; + } + if (s.endsWith("{")) { + level++; + } + if (s.endsWith("}")) { + level--; + } + if (level < 0) { + return CommandControl.NOT_OK; + } + } + + if (level != 0) { + return CommandControl.OK_PARTIAL; + } + + actionIfCommandValid(); + return CommandControl.OK; + } + + protected abstract boolean isLineConsistent(String line, int level); +} diff --git a/src/net/sourceforge/plantuml/command/CommandMultilinesFooter.java b/src/net/sourceforge/plantuml/command/CommandMultilinesFooter.java index f5222067c..b381663d9 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: 4762 $ + * Revision $Revision: 5750 $ * */ package net.sourceforge.plantuml.command; @@ -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.UmlDiagram; import net.sourceforge.plantuml.graphic.HorizontalAlignement; @@ -46,7 +47,8 @@ public class CommandMultilinesFooter extends CommandMultilines { } public CommandExecutionResult execute(List lines) { - final Matcher m = getStartingPattern().matcher(lines.get(0)); + StringUtils.trim(lines); + final Matcher m = getStartingPattern().matcher(lines.get(0).trim()); 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 0933d055b..fa920d07f 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: 4762 $ + * Revision $Revision: 5750 $ * */ package net.sourceforge.plantuml.command; @@ -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.UmlDiagram; import net.sourceforge.plantuml.graphic.HorizontalAlignement; @@ -46,7 +47,8 @@ public class CommandMultilinesHeader extends CommandMultilines { } public CommandExecutionResult execute(List lines) { - final Matcher m = getStartingPattern().matcher(lines.get(0)); + StringUtils.trim(lines); + final Matcher m = getStartingPattern().matcher(lines.get(0).trim()); if (m.find() == false) { throw new IllegalStateException(); } diff --git a/src/net/sourceforge/plantuml/command/CommandMultilinesStandaloneNote.java b/src/net/sourceforge/plantuml/command/CommandMultilinesStandaloneNote.java index 8de232104..8ee643f4f 100644 --- a/src/net/sourceforge/plantuml/command/CommandMultilinesStandaloneNote.java +++ b/src/net/sourceforge/plantuml/command/CommandMultilinesStandaloneNote.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 4762 $ + * Revision $Revision: 5751 $ * */ package net.sourceforge.plantuml.command; @@ -47,9 +47,9 @@ public class CommandMultilinesStandaloneNote extends CommandMultilines lines) { - final List line0 = StringUtils.getSplit(getStartingPattern(), lines.get(0)); + final List line0 = StringUtils.getSplit(getStartingPattern(), lines.get(0).trim()); - final List strings = lines.subList(1, lines.size() - 1); + final List strings = StringUtils.removeEmptyColumns(lines.subList(1, lines.size() - 1)); final String display = StringUtils.getMergedLines(strings); final EntityType type = EntityType.NOTE; diff --git a/src/net/sourceforge/plantuml/command/CommandMultilinesTitle.java b/src/net/sourceforge/plantuml/command/CommandMultilinesTitle.java index eecb929e2..4c50c7046 100644 --- a/src/net/sourceforge/plantuml/command/CommandMultilinesTitle.java +++ b/src/net/sourceforge/plantuml/command/CommandMultilinesTitle.java @@ -28,13 +28,14 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 4765 $ + * Revision $Revision: 5752 $ * */ package net.sourceforge.plantuml.command; import java.util.List; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.UmlDiagram; public class CommandMultilinesTitle extends CommandMultilines { @@ -44,7 +45,7 @@ public class CommandMultilinesTitle extends CommandMultilines { } public CommandExecutionResult execute(List lines) { - final List strings = lines.subList(1, lines.size() - 1); + final List strings = StringUtils.removeEmptyColumns(lines.subList(1, lines.size() - 1)); if (strings.size() > 0) { getSystem().setTitle(strings); return CommandExecutionResult.ok(); diff --git a/src/net/sourceforge/plantuml/command/CommandNope.java b/src/net/sourceforge/plantuml/command/CommandNope.java new file mode 100644 index 000000000..25f338d07 --- /dev/null +++ b/src/net/sourceforge/plantuml/command/CommandNope.java @@ -0,0 +1,51 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009, 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 Lesser 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.command; + +import java.util.List; + +import net.sourceforge.plantuml.UmlDiagram; + +public class CommandNope extends SingleLineCommand { + + public CommandNope(UmlDiagram diagram) { + super(diagram, "(?i)^\\s*$"); + } + + @Override + protected CommandExecutionResult executeArg(List arg) { + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/command/CommandSkinParam.java b/src/net/sourceforge/plantuml/command/CommandSkinParam.java index 14625829c..3c9341398 100644 --- a/src/net/sourceforge/plantuml/command/CommandSkinParam.java +++ b/src/net/sourceforge/plantuml/command/CommandSkinParam.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 4762 $ + * Revision $Revision: 5769 $ * */ package net.sourceforge.plantuml.command; @@ -40,7 +40,7 @@ import net.sourceforge.plantuml.UmlDiagram; public class CommandSkinParam extends SingleLineCommand { public CommandSkinParam(UmlDiagram diagram) { - super(diagram, "(?i)^skinparam\\s+(\\w+)\\s+(.*)$"); + super(diagram, "(?i)^skinparam\\s+([\\w.]*(?:\\<\\<.*\\>\\>)?[\\w.]*)\\s+([^{}]*)$"); } @Override diff --git a/src/net/sourceforge/plantuml/command/CommandSkinParamMultilines.java b/src/net/sourceforge/plantuml/command/CommandSkinParamMultilines.java new file mode 100644 index 000000000..e3959581f --- /dev/null +++ b/src/net/sourceforge/plantuml/command/CommandSkinParamMultilines.java @@ -0,0 +1,116 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009, 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 Lesser 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: 5727 $ + * + */ +package net.sourceforge.plantuml.command; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.UmlDiagram; + +public class CommandSkinParamMultilines extends CommandMultilinesBracket { + + static class Context { + private List strings = new ArrayList(); + + public void push(String s) { + strings.add(s); + } + + public void pop() { + strings.remove(strings.size() - 1); + } + + public String getFullParam() { + final StringBuilder sb = new StringBuilder(); + for (String s : strings) { + sb.append(s); + } + return sb.toString(); + } + } + + private final static Pattern p1 = Pattern.compile("^([\\w.]*(?:\\<\\<.*\\>\\>)?[\\w.]*)\\s+(?:(\\{)|(.*))$|^\\}?$"); + + public CommandSkinParamMultilines(UmlDiagram diagram) { + super(diagram, "(?i)^skinparam\\s*(?:\\s+([\\w.]*(?:\\<\\<.*\\>\\>)?[\\w.]*))?\\s*\\{$"); + } + + @Override + protected boolean isLineConsistent(String line, int level) { + line = line.trim(); + return p1.matcher(line).matches(); + } + + public CommandExecutionResult execute(List lines) { + final Context context = new Context(); + final Matcher mStart = getStartingPattern().matcher(lines.get(0).trim()); + if (mStart.find() == false) { + throw new IllegalStateException(); + } + if (mStart.group(1) != null) { + context.push(mStart.group(1)); + } + + lines = new ArrayList(lines.subList(1, lines.size() - 1)); + StringUtils.trim(lines); + + for (String s : lines) { + if (s.length() == 0) { + continue; + } + if (s.equals("}")) { + context.pop(); + continue; + } + final Matcher m = p1.matcher(s); + if (m.find() == false) { + throw new IllegalStateException(); + } + if (m.group(2) != null) { + context.push(m.group(1)); + } else if (m.group(3) != null) { + final String key = context.getFullParam() + m.group(1); + getSystem().setParam(key, m.group(3)); + } else { + throw new IllegalStateException(); + } + } + + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/command/regex/RegexComposed.java b/src/net/sourceforge/plantuml/command/regex/RegexComposed.java index dbfea2245..6ac380884 100644 --- a/src/net/sourceforge/plantuml/command/regex/RegexComposed.java +++ b/src/net/sourceforge/plantuml/command/regex/RegexComposed.java @@ -78,7 +78,7 @@ public abstract class RegexComposed implements IRegex { public Map matcher(String s) { final Matcher matcher = getFull().matcher(s); if (matcher.find() == false) { - throw new IllegalArgumentException(s); + throw new IllegalArgumentException(getClass()+" "+s); } final Iterator it = new MatcherIterator(matcher); diff --git a/src/net/sourceforge/plantuml/command/regex/RegexConcat.java b/src/net/sourceforge/plantuml/command/regex/RegexConcat.java index 18410a9c7..cdd3f81a9 100644 --- a/src/net/sourceforge/plantuml/command/regex/RegexConcat.java +++ b/src/net/sourceforge/plantuml/command/regex/RegexConcat.java @@ -45,7 +45,7 @@ public class RegexConcat extends RegexComposed implements IRegex { for (IRegex p : partial) { sb.append(p.getPattern()); } - this.full = Pattern.compile(sb.toString()); + this.full = Pattern.compile(sb.toString(), Pattern.CASE_INSENSITIVE); } @Override diff --git a/src/net/sourceforge/plantuml/command/regex/RegexOr.java b/src/net/sourceforge/plantuml/command/regex/RegexOr.java index b662868e4..b1a31176b 100644 --- a/src/net/sourceforge/plantuml/command/regex/RegexOr.java +++ b/src/net/sourceforge/plantuml/command/regex/RegexOr.java @@ -48,6 +48,10 @@ public class RegexOr extends RegexComposed implements IRegex { } public RegexOr(String name, IRegex... partial) { + this(name, false, partial); + } + + public RegexOr(String name, boolean optionnal, IRegex... partial) { super(partial); this.name = name; final StringBuilder sb = new StringBuilder("("); @@ -60,6 +64,9 @@ public class RegexOr extends RegexComposed implements IRegex { } sb.setLength(sb.length() - 1); sb.append(')'); + if (optionnal) { + sb.append('?'); + } this.full = Pattern.compile(sb.toString()); } diff --git a/src/net/sourceforge/plantuml/componentdiagram/command/CommandCreateActorInComponent.java b/src/net/sourceforge/plantuml/componentdiagram/command/CommandCreateActorInComponent.java index 09bce8eca..ddeb19749 100644 --- a/src/net/sourceforge/plantuml/componentdiagram/command/CommandCreateActorInComponent.java +++ b/src/net/sourceforge/plantuml/componentdiagram/command/CommandCreateActorInComponent.java @@ -76,7 +76,7 @@ public class CommandCreateActorInComponent extends SingleLineCommand entity.setDisplay(display); if (stereotype != null) { entity.setStereotype(new Stereotype(stereotype, getSystem().getSkinParam().getCircledCharacterRadius(), - getSystem().getSkinParam().getFont(FontParam.CIRCLED_CHARACTER))); + getSystem().getSkinParam().getFont(FontParam.CIRCLED_CHARACTER, null))); } return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/componentdiagram/command/CommandLinkComponent.java b/src/net/sourceforge/plantuml/componentdiagram/command/CommandLinkComponent.java deleted file mode 100644 index 1f5747658..000000000 --- a/src/net/sourceforge/plantuml/componentdiagram/command/CommandLinkComponent.java +++ /dev/null @@ -1,128 +0,0 @@ -/* ======================================================================== - * PlantUML : a free UML diagram generator - * ======================================================================== - * - * (C) Copyright 2009, 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 Lesser 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: 5443 $ - * - */ -package net.sourceforge.plantuml.componentdiagram.command; - -import java.util.List; - -import net.sourceforge.plantuml.command.CommandExecutionResult; -import net.sourceforge.plantuml.command.SingleLineCommand; -import net.sourceforge.plantuml.componentdiagram.ComponentDiagram; -import net.sourceforge.plantuml.cucadiagram.Group; -import net.sourceforge.plantuml.cucadiagram.IEntity; -import net.sourceforge.plantuml.cucadiagram.Link; -import net.sourceforge.plantuml.cucadiagram.LinkDecor; -import net.sourceforge.plantuml.cucadiagram.LinkType; - -public class CommandLinkComponent extends SingleLineCommand { - - public CommandLinkComponent(ComponentDiagram diagram) { - super( - diagram, - "(?i)^([\\p{L}0-9_.]+|:[^:]+:|\\[[^\\]*]+[^\\]]*\\]|\\(\\)\\s*[\\p{L}0-9_.]+|\\(\\)\\s*\"[^\"]+\")\\s*" - + "(?:(" - + "([=-]+(?:left|right|up|down|le?|ri?|up?|do?)?[=-]*|\\.+(?:left|right|up|down|le?|ri?|up?|do?)?\\.*)([\\]>]|\\|[>\\]])?" - + ")|(" - + "([\\[<]|[<\\[]\\|)?([=-]*(?:left|right|up|down|le?|ri?|up?|do?)?[=-]+|\\.*(?:left|right|up|down|le?|ri?|up?|do?)?\\.+)" - + "))" - + "\\s*([\\p{L}0-9_.]+|:[^:]+:|\\[[^\\]*]+[^\\]]*\\]|\\(\\)\\s*[\\p{L}0-9_.]+|\\(\\)\\s*\"[^\"]+\")\\s*(?::\\s*([^\"]+))?$"); - } - - @Override - protected CommandExecutionResult executeArg(List arg) { - if (getSystem().isGroup(arg.get(0)) && getSystem().isGroup(arg.get(7))) { - return executePackageLink(arg); - } - if (getSystem().isGroup(arg.get(0)) || getSystem().isGroup(arg.get(7))) { - return CommandExecutionResult.error("Package can be only linked to other package"); - } - - final IEntity cl1 = getSystem().getOrCreateClass(arg.get(0)); - final IEntity cl2 = getSystem().getOrCreateClass(arg.get(7)); - - final LinkType linkType = arg.get(1) != null ? getLinkTypeNormal(arg) : getLinkTypeInv(arg); - final String queue = arg.get(1) != null ? arg.get(2) : arg.get(6); - - final Link link = new Link(cl1, cl2, linkType, arg.get(8), queue.length()); - getSystem().addLink(link); - return CommandExecutionResult.ok(); - } - - private CommandExecutionResult executePackageLink(List arg) { - final Group cl1 = getSystem().getGroup(arg.get(0)); - final Group cl2 = getSystem().getGroup(arg.get(7)); - - final LinkType linkType = arg.get(1) != null ? getLinkTypeNormal(arg) : getLinkTypeInv(arg); - final String queue = arg.get(1) != null ? arg.get(2) : arg.get(6); - - final Link link = new Link(cl1.getEntityCluster(), cl2.getEntityCluster(), linkType, arg.get(8), queue.length()); - getSystem().addLink(link); - return CommandExecutionResult.ok(); - } - - private LinkType getLinkTypeNormal(List arg) { - final String queue = arg.get(2); - final String key = arg.get(3); - LinkType linkType = getLinkTypeFromKey(key); - - if (queue.startsWith(".")) { - linkType = linkType.getDashed(); - } - return linkType; - } - - private LinkType getLinkTypeInv(List arg) { - final String queue = arg.get(6); - final String key = arg.get(5); - LinkType linkType = getLinkTypeFromKey(key); - - if (queue.startsWith(".")) { - linkType = linkType.getDashed(); - } - return linkType.getInv(); - } - - private LinkType getLinkTypeFromKey(String k) { - if (k == null) { - return new LinkType(LinkDecor.NONE, LinkDecor.NONE); - } - if (k.equals("<") || k.equals(">")) { - return new LinkType(LinkDecor.ARROW, LinkDecor.NONE); - } - if (k.equals("<|") || k.equals("|>")) { - return new LinkType(LinkDecor.EXTENDS, LinkDecor.NONE); - } - return null; - } - -} diff --git a/src/net/sourceforge/plantuml/componentdiagram/command/CommandLinkComponent2.java b/src/net/sourceforge/plantuml/componentdiagram/command/CommandLinkComponent2.java index 94b76ce25..f57370fc6 100644 --- a/src/net/sourceforge/plantuml/componentdiagram/command/CommandLinkComponent2.java +++ b/src/net/sourceforge/plantuml/componentdiagram/command/CommandLinkComponent2.java @@ -49,6 +49,7 @@ import net.sourceforge.plantuml.cucadiagram.IEntity; import net.sourceforge.plantuml.cucadiagram.Link; import net.sourceforge.plantuml.cucadiagram.LinkDecor; import net.sourceforge.plantuml.cucadiagram.LinkType; +import net.sourceforge.plantuml.cucadiagram.Stereotype; public class CommandLinkComponent2 extends SingleLineCommand2 { @@ -68,7 +69,7 @@ public class CommandLinkComponent2 extends SingleLineCommand2 private static RegexLeaf getRegexGroup(String name) { return new RegexLeaf(name, - "([\\p{L}0-9_.]+|:[^:]+:|\\[[^\\]*]+[^\\]]*\\]|\\(\\)\\s*[\\p{L}0-9_.]+|\\(\\)\\s*\"[^\"]+\")"); + "([\\p{L}0-9_.]+|:[^:]+:|\\[[^\\]*]+[^\\]]*\\]|\\(\\)\\s*[\\p{L}0-9_.]+|\\(\\)\\s*\"[^\"]+\")(?:\\s*(\\<\\<.*\\>\\>))?"); } @Override @@ -85,6 +86,14 @@ public class CommandLinkComponent2 extends SingleLineCommand2 final IEntity cl1 = getSystem().getOrCreateClass(g1); final IEntity cl2 = getSystem().getOrCreateClass(g2); + + + if (arg.get("G1").get(1) != null) { + cl1.setStereotype(new Stereotype(arg.get("G1").get(1))); + } + if (arg.get("G2").get(1) != null) { + cl2.setStereotype(new Stereotype(arg.get("G2").get(1))); + } final LinkType linkType; String queue; diff --git a/src/net/sourceforge/plantuml/cucadiagram/CucaDiagram.java b/src/net/sourceforge/plantuml/cucadiagram/CucaDiagram.java index 095e8e14b..b73b27d68 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/CucaDiagram.java +++ b/src/net/sourceforge/plantuml/cucadiagram/CucaDiagram.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5584 $ + * Revision $Revision: 5877 $ * */ package net.sourceforge.plantuml.cucadiagram; @@ -49,6 +49,7 @@ import java.util.Set; import java.util.TreeMap; import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.FileFormatOption; import net.sourceforge.plantuml.Log; import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.UmlDiagram; @@ -57,6 +58,7 @@ import net.sourceforge.plantuml.cucadiagram.dot.CucaDiagramFileMaker; import net.sourceforge.plantuml.cucadiagram.dot.CucaDiagramFileMakerBeta; import net.sourceforge.plantuml.cucadiagram.dot.CucaDiagramPngMaker3; import net.sourceforge.plantuml.cucadiagram.dot.CucaDiagramTxtMaker; +import net.sourceforge.plantuml.xmi.CucaDiagramXmiMaker; public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy, PortionShower { @@ -268,13 +270,19 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy, abstract protected List getDotStrings(); - final public List createFiles(File suggestedFile, FileFormat fileFormat) throws IOException, + final public List createFiles(File suggestedFile, FileFormatOption fileFormatOption) throws IOException, InterruptedException { + + final FileFormat fileFormat = fileFormatOption.getFileFormat(); if (fileFormat == FileFormat.ATXT || fileFormat == FileFormat.UTXT) { return createFilesTxt(suggestedFile, fileFormat); } + if (fileFormat.name().startsWith("XMI")) { + return createFilesXmi(suggestedFile, fileFormat); + } + if (OptionFlags.getInstance().useJavaInsteadOfDot()) { return createPng2(suggestedFile); } @@ -283,7 +291,12 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy, return maker.createFile(suggestedFile, getDotStrings(), fileFormat); } final CucaDiagramFileMaker maker = new CucaDiagramFileMaker(this); - return maker.createFile(suggestedFile, getDotStrings(), fileFormat); + return maker.createFile(suggestedFile, getDotStrings(), fileFormatOption); + } + + private List createFilesXmi(File suggestedFile, FileFormat fileFormat) throws IOException { + final CucaDiagramXmiMaker maker = new CucaDiagramXmiMaker(this, fileFormat); + return maker.createFiles(suggestedFile); } private List createFilesTxt(File suggestedFile, FileFormat fileFormat) throws IOException { @@ -293,7 +306,8 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy, public static boolean BETA; - final public void createFile(OutputStream os, int index, FileFormat fileFormat) throws IOException { + final public void createFile(OutputStream os, int index, FileFormatOption fileFormatOption) throws IOException { + final FileFormat fileFormat = fileFormatOption.getFileFormat(); if (fileFormat == FileFormat.ATXT || fileFormat == FileFormat.UTXT) { createFilesTxt(os, index, fileFormat); return; @@ -311,7 +325,7 @@ public abstract class CucaDiagram extends UmlDiagram implements GroupHierarchy, } final CucaDiagramFileMaker maker = new CucaDiagramFileMaker(this); try { - maker.createFile(os, getDotStrings(), fileFormat); + maker.createFile(os, getDotStrings(), fileFormatOption); } catch (InterruptedException e) { Log.error(e.toString()); throw new IOException(e.toString()); diff --git a/src/net/sourceforge/plantuml/cucadiagram/Entity.java b/src/net/sourceforge/plantuml/cucadiagram/Entity.java index a90d8f22f..568ee0ed3 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/Entity.java +++ b/src/net/sourceforge/plantuml/cucadiagram/Entity.java @@ -28,11 +28,13 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5593 $ + * Revision $Revision: 5694 $ * */ package net.sourceforge.plantuml.cucadiagram; +import java.io.File; +import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -226,4 +228,24 @@ public class Entity implements IEntity { return uid.equals(other.getUid()); } + private final List subImages = new ArrayList(); + + public void addSubImage(DrawFile subImage) { + if (subImage == null) { + throw new IllegalArgumentException(); + } + subImages.add(subImage); + } + + public DrawFile getImageFile(File searched) throws IOException { + if (imageFile != null && imageFile.getPng().getCanonicalFile().equals(searched)) { + return imageFile; + } + for (DrawFile f : subImages) { + if (f.getPng().getCanonicalFile().equals(searched)) { + return f; + } + } + return null; + } } diff --git a/src/net/sourceforge/plantuml/cucadiagram/EntityUtils.java b/src/net/sourceforge/plantuml/cucadiagram/EntityUtils.java index d282e87d0..5ee1e845a 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/EntityUtils.java +++ b/src/net/sourceforge/plantuml/cucadiagram/EntityUtils.java @@ -33,6 +33,8 @@ */ package net.sourceforge.plantuml.cucadiagram; +import java.io.File; +import java.io.IOException; import java.util.List; import net.sourceforge.plantuml.cucadiagram.dot.DrawFile; @@ -61,6 +63,10 @@ public abstract class EntityUtils { return ent.getStereotype(); } + public void setStereotype(Stereotype stereotype) { + ent.setStereotype(stereotype); + } + public EntityType getType() { return ent.getType(); } @@ -108,6 +114,10 @@ public abstract class EntityUtils { return ent.getCode(); } + public DrawFile getImageFile(File searched) throws IOException { + return ent.getImageFile(searched); + } + }; } diff --git a/src/net/sourceforge/plantuml/cucadiagram/Group.java b/src/net/sourceforge/plantuml/cucadiagram/Group.java index 083008b27..2be4798c0 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/Group.java +++ b/src/net/sourceforge/plantuml/cucadiagram/Group.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5190 $ + * Revision $Revision: 5743 $ * */ package net.sourceforge.plantuml.cucadiagram; @@ -259,5 +259,15 @@ public class Group { public final void setRankdir(Rankdir rankdir) { this.rankdir = rankdir; } + + private String stereotype; + + public final void setStereotype(String stereotype) { + this.stereotype = stereotype; + } + + public final String getStereotype() { + return stereotype; + } } diff --git a/src/net/sourceforge/plantuml/cucadiagram/IEntity.java b/src/net/sourceforge/plantuml/cucadiagram/IEntity.java index 643a3207d..831ebd9ef 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/IEntity.java +++ b/src/net/sourceforge/plantuml/cucadiagram/IEntity.java @@ -33,9 +33,12 @@ */ package net.sourceforge.plantuml.cucadiagram; +import java.io.File; +import java.io.IOException; import java.util.List; import net.sourceforge.plantuml.SpecificBackcolorable; +import net.sourceforge.plantuml.cucadiagram.dot.DrawFile; public interface IEntity extends Imaged, SpecificBackcolorable { @@ -53,8 +56,12 @@ public interface IEntity extends Imaged, SpecificBackcolorable { public Stereotype getStereotype(); + public void setStereotype(Stereotype stereotype); + public List methods2(); public String getCode(); + public DrawFile getImageFile(File searched) throws IOException; + } diff --git a/src/net/sourceforge/plantuml/cucadiagram/Link.java b/src/net/sourceforge/plantuml/cucadiagram/Link.java index 3dfc38b42..547019968 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/Link.java +++ b/src/net/sourceforge/plantuml/cucadiagram/Link.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5649 $ + * Revision $Revision: 5848 $ * */ package net.sourceforge.plantuml.cucadiagram; @@ -38,7 +38,6 @@ import java.awt.Font; import java.awt.geom.Dimension2D; import java.util.Arrays; -import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.UniqueSequence; import net.sourceforge.plantuml.cucadiagram.dot.DrawFile; import net.sourceforge.plantuml.graphic.HorizontalAlignement; @@ -61,7 +60,7 @@ public class Link implements Imaged { private DrawFile imageFile; private String note; private boolean invis = false; - private int weight = 1; + private double weight = 1.0; private final String labeldistance; private final String labelangle; @@ -178,11 +177,11 @@ public class Link implements Imaged { return qualifier2; } - public final int getWeight() { + public final double getWeight() { return weight; } - public final void setWeight(int weight) { + public final void setWeight(double weight) { this.weight = weight; } diff --git a/src/net/sourceforge/plantuml/cucadiagram/Member.java b/src/net/sourceforge/plantuml/cucadiagram/Member.java index e6703bd8f..ce65fce42 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/Member.java +++ b/src/net/sourceforge/plantuml/cucadiagram/Member.java @@ -62,7 +62,7 @@ public class Member { this.display = displayClean; visibilityModifier = null; } - assert VisibilityModifier.isVisibilityCharacter(this.display.charAt(0)) == false; + // assert VisibilityModifier.isVisibilityCharacter(this.display.charAt(0)) == false; } diff --git a/src/net/sourceforge/plantuml/cucadiagram/Stereotype.java b/src/net/sourceforge/plantuml/cucadiagram/Stereotype.java index 130f0f3f9..07542b6b5 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: 4111 $ + * Revision $Revision: 5771 $ * */ package net.sourceforge.plantuml.cucadiagram; @@ -77,6 +77,14 @@ public class Stereotype implements CharSequence { } } + public Stereotype(String stereotype) { + this.label = stereotype; + this.htmlColor = null; + this.character = '\0'; + this.radius = 0; + this.circledFont = null; + } + public Color getColor() { if (htmlColor == null) { return null; @@ -89,6 +97,7 @@ public class Stereotype implements CharSequence { } public String getLabel() { + assert label == null || label.length() > 0; return label; } diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/AbstractGraphviz.java b/src/net/sourceforge/plantuml/cucadiagram/dot/AbstractGraphviz.java index 78c3c295f..1623ae88b 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: 4826 $ + * Revision $Revision: 5794 $ * */ package net.sourceforge.plantuml.cucadiagram.dot; @@ -40,6 +40,7 @@ import java.util.ArrayList; import java.util.List; import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.FileFormatOption; import net.sourceforge.plantuml.Log; import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.StringUtils; @@ -85,7 +86,7 @@ abstract class AbstractGraphviz implements Graphviz { } if (illegalDotExe()) { - createPngNoGraphviz(os, FileFormat.valueOf(type[0].toUpperCase())); + createPngNoGraphviz(os, new FileFormatOption(FileFormat.valueOf(type[0].toUpperCase()))); return; } final String cmd = getCommandLine(); @@ -133,7 +134,7 @@ abstract class AbstractGraphviz implements Graphviz { return sb.toString().replace('\n', ' ').trim(); } - final private void createPngNoGraphviz(OutputStream os, FileFormat format) throws IOException { + final private void createPngNoGraphviz(OutputStream os, FileFormatOption format) throws IOException { final List msg = new ArrayList(); msg.add("Dot Executable: " + dotExe); if (dotExe != null) { diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramFileMaker.java b/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramFileMaker.java index 5ccf22861..e9dae3ccd 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramFileMaker.java +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramFileMaker.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5655 $ + * Revision $Revision: 5872 $ * */ package net.sourceforge.plantuml.cucadiagram.dot; @@ -51,7 +51,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; -import java.util.Map; import java.util.StringTokenizer; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -62,6 +61,8 @@ import net.sourceforge.plantuml.ColorParam; 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.FontParam; import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.Log; @@ -74,6 +75,7 @@ import net.sourceforge.plantuml.UniqueSequence; import net.sourceforge.plantuml.cucadiagram.CucaDiagram; import net.sourceforge.plantuml.cucadiagram.Entity; import net.sourceforge.plantuml.cucadiagram.EntityType; +import net.sourceforge.plantuml.cucadiagram.IEntity; import net.sourceforge.plantuml.cucadiagram.Imaged; import net.sourceforge.plantuml.cucadiagram.Link; import net.sourceforge.plantuml.cucadiagram.Stereotype; @@ -92,10 +94,11 @@ import net.sourceforge.plantuml.png.PngScaler; import net.sourceforge.plantuml.png.PngSizer; import net.sourceforge.plantuml.png.PngSplitter; import net.sourceforge.plantuml.png.PngTitler; +import net.sourceforge.plantuml.skin.CircleInterface; import net.sourceforge.plantuml.skin.Component; import net.sourceforge.plantuml.skin.ComponentType; import net.sourceforge.plantuml.skin.SimpleContext2D; -import net.sourceforge.plantuml.skin.VisibilityModifier; +import net.sourceforge.plantuml.skin.StickMan; import net.sourceforge.plantuml.skin.rose.Rose; import net.sourceforge.plantuml.svg.SvgTitler; import net.sourceforge.plantuml.ugraphic.eps.UGraphicEps; @@ -105,7 +108,7 @@ import net.sourceforge.plantuml.ugraphic.svg.UGraphicSvg; public final class CucaDiagramFileMaker { private final CucaDiagram diagram; - private final StaticFiles staticFiles; + private final StaticFilesMap staticFilesMap; private final Rose rose = new Rose(); static private final StringBounder stringBounder; @@ -118,20 +121,25 @@ public final class CucaDiagramFileMaker { public CucaDiagramFileMaker(CucaDiagram diagram) throws IOException { HtmlColor.setForceMonochrome(diagram.getSkinParam().isMonochrome()); this.diagram = diagram; - this.staticFiles = new StaticFiles(diagram.getSkinParam()); + if (diagram.getUmlDiagramType() == UmlDiagramType.CLASS || diagram.getUmlDiagramType() == UmlDiagramType.OBJECT) { + this.staticFilesMap = new StaticFilesMap(diagram.getSkinParam(), diagram.getDpiFactor(null)); + } else { + this.staticFilesMap = null; + } } static String changeName(String name) { return name.replaceAll("(?i)\\.png$", ".cmapx"); } - public List createFile(File suggested, List dotStrings, FileFormat fileFormat) throws IOException, - InterruptedException { + public List createFile(File suggested, List dotStrings, FileFormatOption fileFormatOption) + throws IOException, InterruptedException { + final FileFormat fileFormat = fileFormatOption.getFileFormat(); OutputStream os = null; try { os = new FileOutputStream(suggested); - final String cmap = createFile(os, dotStrings, fileFormat); + final String cmap = createFile(os, dotStrings, fileFormatOption); if (diagram.hasUrl() && fileFormat == FileFormat.PNG) { final File cmapFile = new File(changeName(suggested.getAbsolutePath())); final PrintWriter pw = new PrintWriter(cmapFile); @@ -145,8 +153,8 @@ public final class CucaDiagramFileMaker { } if (fileFormat == FileFormat.PNG) { - final List result = new PngSplitter(suggested, diagram.getHorizontalPages(), - diagram.getVerticalPages(), diagram.getMetadata()).getFiles(); + final List result = new PngSplitter(suggested, diagram.getHorizontalPages(), diagram + .getVerticalPages(), diagram.getMetadata(), diagram.getDpi(fileFormatOption)).getFiles(); for (File f : result) { Log.info("Creating file: " + f); } @@ -171,26 +179,28 @@ public final class CucaDiagramFileMaker { } - public String createFile(OutputStream os, List dotStrings, FileFormat fileFormat) throws IOException, - InterruptedException { + public String createFile(OutputStream os, List dotStrings, FileFormatOption fileFormatOption) + throws IOException, InterruptedException { + final FileFormat fileFormat = fileFormatOption.getFileFormat(); if (fileFormat == FileFormat.PNG) { - return createPng(os, dotStrings); + return createPng(os, dotStrings, fileFormatOption); } else if (fileFormat == FileFormat.SVG) { - return createSvg(os, dotStrings); + return createSvg(os, dotStrings, fileFormatOption); } else if (fileFormat == FileFormat.EPS_VIA_SVG) { - return createEpsViaSvg(os, dotStrings); + return createEpsViaSvg(os, dotStrings, fileFormatOption); } else if (fileFormat == FileFormat.EPS) { - return createEps(os, dotStrings); + return createEps(os, dotStrings, fileFormatOption); } else { throw new UnsupportedOperationException(); } } - private String createEpsViaSvg(OutputStream os, List dotStrings) throws IOException, InterruptedException { - final File svgTmp = createTempFile("svgtmp", ".svg"); + private String createEpsViaSvg(OutputStream os, List dotStrings, FileFormatOption fileFormatOption) + throws IOException, InterruptedException { + final File svgTmp = FileUtils.createTempFile("svgtmp", ".svg"); final FileOutputStream svgOs = new FileOutputStream(svgTmp); - final String status = createSvg(svgOs, dotStrings); + final String status = createSvg(svgOs, dotStrings, fileFormatOption); svgOs.close(); final SvgToEpsConverter converter = new SvgToEpsConverter(svgTmp); converter.createEps(os); @@ -199,14 +209,14 @@ public final class CucaDiagramFileMaker { private double deltaY; - private String createSvg(OutputStream os, List dotStrings) throws IOException, InterruptedException { + private String createSvg(OutputStream os, List dotStrings, FileFormatOption fileFormatOption) + throws IOException, InterruptedException { try { deltaY = 0; - populateImages(); - populateImagesLink(); - final GraphvizMaker dotMaker = createDotMaker(staticFiles.getStaticImages(), - staticFiles.getVisibilityImages(), dotStrings, FileFormat.SVG); + populateImages(diagram.getDpiFactor(fileFormatOption), diagram.getDpi(fileFormatOption)); + populateImagesLink(diagram.getDpiFactor(fileFormatOption), diagram.getDpi(fileFormatOption)); + final GraphvizMaker dotMaker = createDotMaker(dotStrings, fileFormatOption); final String dotString = dotMaker.createDotString(); if (OptionFlags.getInstance().isKeepTmpFiles()) { @@ -221,7 +231,7 @@ public final class CucaDiagramFileMaker { baos.close(); dotMaker.clean(); - String svg = new String(baos.toByteArray(), "UTF-8"); + String svg = new String(baos.toByteArray(), "UTF-8").replace('\\', '/'); final Dimension2D dim = getDimensionSvg(svg); if (dim != null) { @@ -233,26 +243,36 @@ public final class CucaDiagramFileMaker { // Image management final Pattern pImage = Pattern.compile("(?i)]*>"); - final Matcher mImage = pImage.matcher(svg); - final StringBuffer sb = new StringBuffer(); - while (mImage.find()) { - final String image = mImage.group(0); - final String href = getValue(image, "href"); - final double widthSvg = Double.parseDouble(getValuePx(image, "width")); - final double heightSvg = Double.parseDouble(getValuePx(image, "height")); - final double x = Double.parseDouble(getValue(image, "x")); - final double y = Double.parseDouble(getValue(image, "y")); - final DrawFile drawFile = getDrawFileFromHref(href); - final int widthPng = drawFile.getWidthPng(); - final int heightPng = drawFile.getHeightPng(); - String svg2 = drawFile.getSvg(); - final String scale = getScale(widthSvg, heightSvg, widthPng, heightPng); - svg2 = svg2 - .replaceFirst("<[gG]>", ""); - mImage.appendReplacement(sb, svg2); - } - mImage.appendTail(sb); - svg = sb.toString(); + boolean changed; + do { + changed = false; + final Matcher mImage = pImage.matcher(svg); + final StringBuffer sb = new StringBuffer(); + while (mImage.find()) { + final String image = mImage.group(0); + final String href = getValue(image, "href"); + final double widthSvg = Double.parseDouble(getValuePx(image, "width")); + final double heightSvg = Double.parseDouble(getValuePx(image, "height")); + final double x = Double.parseDouble(getValue(image, "x")); + final double y = Double.parseDouble(getValue(image, "y")); + final DrawFile drawFile = getDrawFileFromHref(href); + if (drawFile == null) { + mImage.appendReplacement(sb, image); + } else { + final int widthPng = drawFile.getWidthPng(); + final int heightPng = drawFile.getHeightPng(); + String svg2 = drawFile.getSvg(); + final String scale = getScale(widthSvg, heightSvg, widthPng, heightPng); + svg2 = svg2.replaceFirst("<[gG]>", ""); + svg2 = "" + svg2 + ""; + mImage.appendReplacement(sb, svg2); + changed = true; + } + } + mImage.appendTail(sb); + svg = sb.toString(); + } while (changed); } os.write(svg.getBytes("UTF-8")); @@ -326,22 +346,32 @@ public final class CucaDiagramFileMaker { return new Dimension2DDouble(maxX - minX, maxY - minY); } - private DrawFile getDrawFileFromHref(final String href) throws IOException { - final DrawFile drawFile = staticFiles.getDrawFile(href); - if (drawFile != null) { - return drawFile; - } - final File searched = new File(href).getCanonicalFile(); - - for (Entity ent : diagram.entities().values()) { - final DrawFile df = ent.getImageFile(); - if (df == null) { - continue; - } - if (df.getPng().getCanonicalFile().equals(searched)) { + private DrawFile searchImageFile(File searched, Collection entities) throws IOException { + for (IEntity ent : entities) { + final DrawFile df = ent.getImageFile(searched); + if (df != null) { + assert df.getPng().getCanonicalFile().equals(searched.getCanonicalFile()); return df; } } + return null; + + } + + private DrawFile getDrawFileFromHref(final String href) throws IOException { + if (diagram.getUmlDiagramType() == UmlDiagramType.CLASS || diagram.getUmlDiagramType() == UmlDiagramType.OBJECT) { + final DrawFile drawFile = staticFilesMap.getDrawFile(href); + if (drawFile != null) { + return drawFile; + } + } + final File searched = new File(href).getCanonicalFile(); + + final DrawFile result = searchImageFile(searched, diagram.entities().values()); + if (result != null) { + return result; + } + for (Link ent : diagram.getLinks()) { final DrawFile df = ent.getImageFile(); if (df == null) { @@ -351,38 +381,39 @@ public final class CucaDiagramFileMaker { return df; } } - return drawFile; + Log.error("Cannot find " + href); + return null; } - private String getScale(double widthSvg, double heightSvg, double widthPng, double heightPng) { + private static String getScale(double widthSvg, double heightSvg, double widthPng, double heightPng) { final double v1 = heightSvg / heightPng; final double v2 = widthSvg / widthPng; final double min = Math.min(v1, v2); return "scale(" + min + " " + min + ")"; } - static String getValue(String s, String param) { + private static String getValue(String s, String param) { final Pattern p = Pattern.compile("(?i)" + param + "=\"([^\"]+)\""); final Matcher m = p.matcher(s); m.find(); return m.group(1); } - static String getValuePx(String s, String param) { + private static String getValuePx(String s, String param) { final Pattern p = Pattern.compile("(?i)" + param + "=\"([^\"]+?)(?:px)?\""); final Matcher m = p.matcher(s); m.find(); return m.group(1); } - private String createPng(OutputStream os, List dotStrings) throws IOException, InterruptedException { + private String createPng(OutputStream os, List dotStrings, FileFormatOption fileFormatOption) + throws IOException, InterruptedException { final StringBuilder cmap = new StringBuilder(); try { - populateImages(); - populateImagesLink(); - final GraphvizMaker dotMaker = createDotMaker(staticFiles.getStaticImages(), - staticFiles.getVisibilityImages(), dotStrings, FileFormat.PNG); + populateImages(diagram.getDpiFactor(fileFormatOption), diagram.getDpi(fileFormatOption)); + populateImagesLink(diagram.getDpiFactor(fileFormatOption), diagram.getDpi(fileFormatOption)); + final GraphvizMaker dotMaker = createDotMaker(dotStrings, fileFormatOption); final String dotString = dotMaker.createDotString(); if (OptionFlags.getInstance().isKeepTmpFiles()) { @@ -392,12 +423,12 @@ public final class CucaDiagramFileMaker { final byte[] imageData = getImageData(dotString, cmap); if (imageData.length == 0) { - createError(os, imageData.length, FileFormat.PNG, "imageData.length == 0"); + createError(os, imageData.length, new FileFormatOption(FileFormat.PNG), "imageData.length == 0"); return null; } if (isPngHeader(imageData, 0) == false) { - createError(os, imageData.length, FileFormat.PNG, "No PNG header found", + createError(os, imageData.length, new FileFormatOption(FileFormat.PNG), "No PNG header found", "Try -forcegd or -forcecairo flag"); return null; } @@ -405,7 +436,7 @@ public final class CucaDiagramFileMaker { final ByteArrayInputStream bais = new ByteArrayInputStream(imageData); BufferedImage im = ImageIO.read(bais); if (im == null) { - createError(os, imageData.length, FileFormat.PNG, "im == null"); + createError(os, imageData.length, new FileFormatOption(FileFormat.PNG), "im == null"); return null; } bais.close(); @@ -426,7 +457,7 @@ public final class CucaDiagramFileMaker { im = PngRotation.process(im); } im = PngSizer.process(im, diagram.getMinwidth()); - PngIO.write(im, os, diagram.getMetadata()); + PngIO.write(im, os, diagram.getMetadata(), diagram.getDpi(fileFormatOption)); } finally { cleanTemporaryFiles(diagram.entities().values()); cleanTemporaryFiles(diagram.getLinks()); @@ -439,7 +470,7 @@ public final class CucaDiagramFileMaker { } private BufferedImage scaleImage(BufferedImage im, Scale scale) { - if (scale==null) { + if (scale == null) { return im; } return PngScaler.scale(im, scale.getScale(im.getWidth(), im.getHeight())); @@ -516,7 +547,7 @@ public final class CucaDiagramFileMaker { return "png"; } - void createError(OutputStream os, int length, FileFormat fileFormat, String... supp) throws IOException { + void createError(OutputStream os, int length, FileFormatOption fileFormat, String... supp) throws IOException { final List msg = new ArrayList(); msg.add("Error: Reading " + length + " byte(s) from dot"); msg.add("Error reading the generated image"); @@ -528,18 +559,18 @@ public final class CucaDiagramFileMaker { } private BufferedImage addTitle(BufferedImage im, final Color background) { - final Color titleColor = diagram.getSkinParam().getFontHtmlColor(FontParam.TITLE).getColor(); - final String fontFamily = getSkinParam().getFontFamily(FontParam.TITLE); - final int fontSize = getSkinParam().getFontSize(FontParam.TITLE); + final Color titleColor = diagram.getSkinParam().getFontHtmlColor(FontParam.TITLE, null).getColor(); + final String fontFamily = getSkinParam().getFontFamily(FontParam.TITLE, null); + final int fontSize = getSkinParam().getFontSize(FontParam.TITLE, null); final PngTitler pngTitler = new PngTitler(titleColor, diagram.getTitle(), fontSize, fontFamily, HorizontalAlignement.CENTER, VerticalPosition.TOP); return pngTitler.processImage(im, background, 3); } private String addTitleSvg(String svg, double width, double height) throws IOException { - final Color titleColor = diagram.getSkinParam().getFontHtmlColor(FontParam.TITLE).getColor(); - final String fontFamily = getSkinParam().getFontFamily(FontParam.TITLE); - final int fontSize = getSkinParam().getFontSize(FontParam.TITLE); + final Color titleColor = diagram.getSkinParam().getFontHtmlColor(FontParam.TITLE, null).getColor(); + final String fontFamily = getSkinParam().getFontFamily(FontParam.TITLE, null); + final int fontSize = getSkinParam().getFontSize(FontParam.TITLE, null); final SvgTitler svgTitler = new SvgTitler(titleColor, diagram.getTitle(), fontSize, fontFamily, HorizontalAlignement.CENTER, VerticalPosition.TOP, 3); @@ -548,39 +579,39 @@ public final class CucaDiagramFileMaker { } private String addHeaderSvg(String svg, double width, double height) throws IOException { - final Color titleColor = diagram.getSkinParam().getFontHtmlColor(FontParam.HEADER).getColor(); - final String fontFamily = getSkinParam().getFontFamily(FontParam.HEADER); - final int fontSize = getSkinParam().getFontSize(FontParam.HEADER); - final SvgTitler svgTitler = new SvgTitler(titleColor, diagram.getHeader(), fontSize, fontFamily, - diagram.getHeaderAlignement(), VerticalPosition.TOP, 3); + final Color titleColor = diagram.getSkinParam().getFontHtmlColor(FontParam.HEADER, null).getColor(); + final String fontFamily = getSkinParam().getFontFamily(FontParam.HEADER, null); + final int fontSize = getSkinParam().getFontSize(FontParam.HEADER, null); + final SvgTitler svgTitler = new SvgTitler(titleColor, diagram.getHeader(), fontSize, fontFamily, diagram + .getHeaderAlignement(), VerticalPosition.TOP, 3); this.deltaY += svgTitler.getHeight(); return svgTitler.addTitleSvg(svg, width, height); } private String addFooterSvg(String svg, double width, double height) throws IOException { - final Color titleColor = diagram.getSkinParam().getFontHtmlColor(FontParam.FOOTER).getColor(); - final String fontFamily = getSkinParam().getFontFamily(FontParam.FOOTER); - final int fontSize = getSkinParam().getFontSize(FontParam.FOOTER); - final SvgTitler svgTitler = new SvgTitler(titleColor, diagram.getFooter(), fontSize, fontFamily, - diagram.getFooterAlignement(), VerticalPosition.BOTTOM, 3); + final Color titleColor = diagram.getSkinParam().getFontHtmlColor(FontParam.FOOTER, null).getColor(); + final String fontFamily = getSkinParam().getFontFamily(FontParam.FOOTER, null); + final int fontSize = getSkinParam().getFontSize(FontParam.FOOTER, null); + final SvgTitler svgTitler = new SvgTitler(titleColor, diagram.getFooter(), fontSize, fontFamily, diagram + .getFooterAlignement(), VerticalPosition.BOTTOM, 3); return svgTitler.addTitleSvg(svg, width, height + deltaY); } private BufferedImage addFooter(BufferedImage im, final Color background) { - final Color titleColor = diagram.getSkinParam().getFontHtmlColor(FontParam.FOOTER).getColor(); - final String fontFamily = getSkinParam().getFontFamily(FontParam.FOOTER); - final int fontSize = getSkinParam().getFontSize(FontParam.FOOTER); - final PngTitler pngTitler = new PngTitler(titleColor, diagram.getFooter(), fontSize, fontFamily, - diagram.getFooterAlignement(), VerticalPosition.BOTTOM); + final Color titleColor = diagram.getSkinParam().getFontHtmlColor(FontParam.FOOTER, null).getColor(); + final String fontFamily = getSkinParam().getFontFamily(FontParam.FOOTER, null); + final int fontSize = getSkinParam().getFontSize(FontParam.FOOTER, null); + final PngTitler pngTitler = new PngTitler(titleColor, diagram.getFooter(), fontSize, fontFamily, diagram + .getFooterAlignement(), VerticalPosition.BOTTOM); return pngTitler.processImage(im, background, 3); } private BufferedImage addHeader(BufferedImage im, final Color background) throws IOException { - final Color titleColor = diagram.getSkinParam().getFontHtmlColor(FontParam.HEADER).getColor(); - final String fontFamily = getSkinParam().getFontFamily(FontParam.HEADER); - final int fontSize = getSkinParam().getFontSize(FontParam.HEADER); - final PngTitler pngTitler = new PngTitler(titleColor, diagram.getHeader(), fontSize, fontFamily, - diagram.getHeaderAlignement(), VerticalPosition.TOP); + final Color titleColor = diagram.getSkinParam().getFontHtmlColor(FontParam.HEADER, null).getColor(); + final String fontFamily = getSkinParam().getFontFamily(FontParam.HEADER, null); + final int fontSize = getSkinParam().getFontSize(FontParam.HEADER, null); + final PngTitler pngTitler = new PngTitler(titleColor, diagram.getHeader(), fontSize, fontFamily, diagram + .getHeaderAlignement(), VerticalPosition.TOP); return pngTitler.processImage(im, background, 3); } @@ -594,9 +625,10 @@ public final class CucaDiagramFileMaker { } } - private GraphvizMaker createDotMaker(Map staticImages, - Map visibilities, List dotStrings, FileFormat fileFormat) + private GraphvizMaker createDotMaker(List dotStrings, FileFormatOption fileFormatOption) throws IOException, InterruptedException { + + final FileFormat fileFormat = fileFormatOption.getFileFormat(); if (diagram.getUmlDiagramType() == UmlDiagramType.STATE || diagram.getUmlDiagramType() == UmlDiagramType.ACTIVITY) { new CucaDiagramSimplifier(diagram, dotStrings, fileFormat); @@ -604,52 +636,60 @@ public final class CucaDiagramFileMaker { final DotData dotData = new DotData(null, diagram.getLinks(), diagram.entities(), diagram.getUmlDiagramType(), diagram.getSkinParam(), diagram.getRankdir(), diagram, diagram); - dotData.putAllStaticImages(staticImages); - if (diagram.isVisibilityModifierPresent()) { - dotData.putAllVisibilityImages(visibilities); + dotData.setDpi(diagram.getDpi(fileFormatOption)); + + if (diagram.getUmlDiagramType() == UmlDiagramType.CLASS || diagram.getUmlDiagramType() == UmlDiagramType.OBJECT) { + dotData.setStaticImagesMap(staticFilesMap); + + if (diagram.isVisibilityModifierPresent()) { + dotData.setVisibilityModifierPresent(true); + } } return new DotMaker(dotData, dotStrings, fileFormat); } - private void populateImages() throws IOException { + private void populateImages(double dpiFactor, int dpi) throws IOException { for (Entity entity : diagram.entities().values()) { - final DrawFile f = createImage(entity); + final DrawFile f = createImage(entity, dpiFactor, dpi); if (f != null) { entity.setImageFile(f); } } } - private void populateImagesLink() throws IOException { + private void populateImagesLink(double dpiFactor, int dpi) throws IOException { for (Link link : diagram.getLinks()) { final String note = link.getNote(); if (note == null) { continue; } - final DrawFile f = createImageForNote(note, null); + final DrawFile f = createImageForNote(note, null, dpiFactor, dpi); if (f != null) { link.setImageFile(f); } } } - DrawFile createImage(Entity entity) throws IOException { + DrawFile createImage(Entity entity, double dpiFactor, int dpi) throws IOException { if (entity.getType() == EntityType.NOTE) { - return createImageForNote(entity.getDisplay(), entity.getSpecificBackColor()); + return createImageForNote(entity.getDisplay(), entity.getSpecificBackColor(), dpiFactor, dpi); } - if (entity.getType() == EntityType.ACTIVITY) { - return createImageForActivity(entity); + if (entity.getType() == EntityType.ACTOR) { + return createImageForActor(entity, dpiFactor); + } + if (entity.getType() == EntityType.CIRCLE_INTERFACE) { + return createImageForCircleInterface(entity, dpiFactor); } if (entity.getType() == EntityType.ABSTRACT_CLASS || entity.getType() == EntityType.CLASS || entity.getType() == EntityType.ENUM || entity.getType() == EntityType.INTERFACE) { - return createImageForCircleCharacter(entity); + return createImageForCircleCharacter(entity, dpiFactor); } return null; } - private DrawFile createImageForNote(String display, HtmlColor backColor) throws IOException { - final File fPng = createTempFile("plantumlB", ".png"); + private DrawFile createImageForNote(String display, HtmlColor backColor, double dpiFactor, int dpi) throws IOException { + final File fPng = FileUtils.createTempFile("plantumlB", ".png"); final Rose skin = new Rose(); @@ -657,29 +697,29 @@ public final class CucaDiagramFileMaker { final Component comp = skin .createComponent(ComponentType.NOTE, skinParam, StringUtils.getWithNewlines(display)); - final int width = (int) comp.getPreferredWidth(stringBounder); - final int height = (int) comp.getPreferredHeight(stringBounder); + final int width = (int) (comp.getPreferredWidth(stringBounder) * dpiFactor); + final int height = (int) (comp.getPreferredHeight(stringBounder) * dpiFactor); final Color background = diagram.getSkinParam().getBackgroundColor().getColor(); final EmptyImageBuilder builder = new EmptyImageBuilder(width, height, background); final BufferedImage im = builder.getBufferedImage(); final Graphics2D g2d = builder.getGraphics2D(); - comp.drawU(new UGraphicG2d(g2d, null), new Dimension(width, height), new SimpleContext2D(false)); - PngIO.write(im, fPng); + comp.drawU(new UGraphicG2d(g2d, null, dpiFactor), new Dimension(width, height), new SimpleContext2D(false)); + PngIO.write(im, fPng, dpi); g2d.dispose(); final UGraphicSvg ug = new UGraphicSvg(true); comp.drawU(ug, new Dimension(width, height), new SimpleContext2D(false)); - final File fEps = createTempFile("plantumlB", ".eps"); + final File fEps = FileUtils.createTempFile("plantumlB", ".eps"); final PrintWriter pw = new PrintWriter(fEps); final UGraphicEps uEps = new UGraphicEps(EpsStrategy.getDefault()); comp.drawU(uEps, new Dimension(width, height), new SimpleContext2D(false)); pw.print(uEps.getEPSCode()); pw.close(); - return new DrawFile(fPng, getSvg(ug), fEps); + return DrawFile.createFromFile(fPng, getSvg(ug), fEps); } static public String getSvg(UGraphicSvg ug) throws IOException { @@ -697,50 +737,125 @@ public final class CucaDiagramFileMaker { return null; } - private DrawFile createImageForCircleCharacter(Entity entity) throws IOException { + private DrawFile createImageForCircleInterface(Entity entity, final double dpiFactor) throws IOException { + final String stereo = entity.getStereotype() == null ? null : entity.getStereotype().getLabel(); + final Color interfaceBackground = rose.getHtmlColor(getSkinParam(), ColorParam.componentInterfaceBackground, stereo) + .getColor(); + final Color interfaceBorder = rose.getHtmlColor(getSkinParam(), ColorParam.componentInterfaceBorder, stereo).getColor(); + final Color background = rose.getHtmlColor(getSkinParam(), ColorParam.background, stereo).getColor(); + final CircleInterface circleInterface = new CircleInterface(interfaceBackground, interfaceBorder); + + final Lazy lpng = new Lazy() { + + public File getNow() throws IOException { + final EmptyImageBuilder builder = new EmptyImageBuilder(circleInterface.getPreferredWidth(null) + * dpiFactor, circleInterface.getPreferredHeight(null) * dpiFactor, background); + + final BufferedImage im = builder.getBufferedImage(); + final Graphics2D g2d = builder.getGraphics2D(); + + circleInterface.drawU(new UGraphicG2d(g2d, null, 1.0)); + + final File png = FileUtils.createTempFile("circleinterface", ".png"); + ImageIO.write(im, "png", png); + return png; + } + }; + + final Lazy leps = new Lazy() { + public File getNow() throws IOException { + final File epsFile = FileUtils.createTempFile("circleinterface", ".eps"); + UGraphicEps.copyEpsToFile(circleInterface, epsFile); + return epsFile; + } + }; + + final Lazy lsvg = new Lazy() { + public String getNow() throws IOException { + return UGraphicG2d.getSvgString(circleInterface); + } + + }; + + final Object signature = Arrays.asList("circleinterface", interfaceBackground, interfaceBorder, background, + dpiFactor); + + return DrawFile.create(lpng, lsvg, leps, signature); + } + + private DrawFile createImageForActor(Entity entity, final double dpiFactor) throws IOException { + final String stereo = entity.getStereotype() == null ? null : entity.getStereotype().getLabel(); + final Color actorBackground = rose.getHtmlColor(getSkinParam(), ColorParam.usecaseActorBackground, stereo).getColor(); + final Color actorBorder = rose.getHtmlColor(getSkinParam(), ColorParam.usecaseActorBorder, stereo).getColor(); + final Color background = rose.getHtmlColor(getSkinParam(), ColorParam.background, stereo).getColor(); + final StickMan stickMan = new StickMan(actorBackground, actorBorder); + + final Lazy lpng = new Lazy() { + public File getNow() throws IOException { + final EmptyImageBuilder builder = new EmptyImageBuilder(stickMan.getPreferredWidth(null) * dpiFactor, + // stickMan.getPreferredHeight(null) * dpiFactor, dpiFactor > 1 + // ? Color.BLUE : background); + stickMan.getPreferredHeight(null) * dpiFactor, background); + + final BufferedImage im = builder.getBufferedImage(); + final Graphics2D g2d = builder.getGraphics2D(); + + stickMan.drawU(new UGraphicG2d(g2d, null, dpiFactor)); + + final File png = FileUtils.createTempFile("actor", ".png"); + ImageIO.write(im, "png", png); + return png; + } + }; + final Lazy leps = new Lazy() { + public File getNow() throws IOException { + final File epsFile = FileUtils.createTempFile("actor", ".eps"); + UGraphicEps.copyEpsToFile(stickMan, epsFile); + return epsFile; + } + }; + + final Lazy lsvg = new Lazy() { + public String getNow() throws IOException { + return UGraphicG2d.getSvgString(stickMan); + } + + }; + + final Object signature = Arrays.asList("actor", actorBackground, actorBorder, background, dpiFactor); + + return DrawFile.create(lpng, lsvg, leps, signature); + } + + private DrawFile createImageForCircleCharacter(Entity entity, double dpiFactor) throws IOException { final Stereotype stereotype = entity.getStereotype(); if (stereotype == null || stereotype.getColor() == null) { return null; } - final File f = createTempFile("plantumlA", ".png"); - final File fEps = createTempFile("plantumlA", ".eps"); - final Color classBorder = rose.getHtmlColor(getSkinParam(), ColorParam.classBorder).getColor(); - final Color classBackground = rose.getHtmlColor(getSkinParam(), ColorParam.classBackground).getColor(); - final Font font = diagram.getSkinParam().getFont(FontParam.CIRCLED_CHARACTER); + final String stereo = stereotype.getLabel(); + + final Color classBorder = rose.getHtmlColor(getSkinParam(), ColorParam.classBorder, stereo).getColor(); + final Color classBackground = rose.getHtmlColor(getSkinParam(), ColorParam.classBackground, stereo).getColor(); + final Font font = diagram.getSkinParam().getFont(FontParam.CIRCLED_CHARACTER, stereo); final CircledCharacter circledCharacter = new CircledCharacter(stereotype.getCharacter(), getSkinParam() .getCircledCharacterRadius(), font, stereotype.getColor(), classBorder, Color.BLACK); - return staticFiles.generateCircleCharacter(f, fEps, circledCharacter, classBackground); - // return new DrawFile(f, UGraphicG2d.getSvgString(circledCharacter), - // fEps); - + return circledCharacter.generateCircleCharacter(classBackground, dpiFactor); } private ISkinParam getSkinParam() { return diagram.getSkinParam(); } - static public File createTempFile(String prefix, String suffix) throws IOException { - if (suffix.startsWith(".") == false) { - throw new IllegalArgumentException(); - } - final File f = File.createTempFile(prefix, suffix); - Log.info("Creating temporary file: " + f); - if (OptionFlags.getInstance().isKeepTmpFiles() == false) { - f.deleteOnExit(); - } - return f; - } - - private String createEps(OutputStream os, List dotStrings) throws IOException, InterruptedException { + private String createEps(OutputStream os, List dotStrings, FileFormatOption fileFormatOption) + throws IOException, InterruptedException { try { deltaY = 0; - populateImages(); - populateImagesLink(); - final GraphvizMaker dotMaker = createDotMaker(staticFiles.getStaticImages(), - staticFiles.getVisibilityImages(), dotStrings, FileFormat.EPS); + populateImages(diagram.getDpiFactor(fileFormatOption), diagram.getDpi(fileFormatOption)); + populateImagesLink(diagram.getDpiFactor(fileFormatOption), diagram.getDpi(fileFormatOption)); + final GraphvizMaker dotMaker = createDotMaker(dotStrings, fileFormatOption); final String dotString = dotMaker.createDotString(); if (OptionFlags.getInstance().isKeepTmpFiles()) { diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramFileMakerBeta.java b/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramFileMakerBeta.java index 3b857e5da..4ed0f6c63 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramFileMakerBeta.java +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramFileMakerBeta.java @@ -79,7 +79,7 @@ public final class CucaDiagramFileMakerBeta { if (fileFormat == FileFormat.PNG) { final List result = new PngSplitter(suggested, diagram.getHorizontalPages(), diagram - .getVerticalPages(), diagram.getMetadata()).getFiles(); + .getVerticalPages(), diagram.getMetadata(), 96).getFiles(); for (File f : result) { Log.info("Creating file: " + f); } @@ -109,7 +109,7 @@ public final class CucaDiagramFileMakerBeta { EmptyImageBuilder builder = new EmptyImageBuilder(10, 10, background); BufferedImage im = builder.getBufferedImage(); Graphics2D g2d = builder.getGraphics2D(); - UGraphicG2d ug = new UGraphicG2d(g2d, im); + UGraphicG2d ug = new UGraphicG2d(g2d, im, 1.0); final PlayField playField = new PlayField(diagram.getSkinParam()); final Collection entities = getFirstLevelEntities(); @@ -122,15 +122,15 @@ public final class CucaDiagramFileMakerBeta { final Dimension2D dim = playField.solve(); - builder = new EmptyImageBuilder((int) (dim.getWidth() + 1), (int) (dim.getHeight() + 1), background); + builder = new EmptyImageBuilder(dim.getWidth() + 1, dim.getHeight() + 1, background); im = builder.getBufferedImage(); g2d = builder.getGraphics2D(); g2d.translate(10, 0); - ug = new UGraphicG2d(g2d, im); + ug = new UGraphicG2d(g2d, im, 1.0); playField.drawInternal(ug); - PngIO.write(im, os); + PngIO.write(im, os, 96); } diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramPngMaker2.java b/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramPngMaker2.java index 9547820e5..aac00e324 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramPngMaker2.java +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramPngMaker2.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5047 $ + * Revision $Revision: 5872 $ * */ package net.sourceforge.plantuml.cucadiagram.dot; @@ -92,8 +92,7 @@ public final class CucaDiagramPngMaker2 { final List graphs = getGraphs2(zoda2.getHeaps()); final Dimension2D totalDim = getTotalDimension(graphs); - final EmptyImageBuilder im = new EmptyImageBuilder((int) totalDim.getWidth(), (int) totalDim.getHeight(), - Color.WHITE); + final EmptyImageBuilder im = new EmptyImageBuilder(totalDim.getWidth(), totalDim.getHeight(), Color.WHITE); double x = 0; @@ -178,7 +177,7 @@ public final class CucaDiagramPngMaker2 { } } - return new PngSplitter(pngFile, diagram.getHorizontalPages(), diagram.getVerticalPages(), diagram.getMetadata()) - .getFiles(); + return new PngSplitter(pngFile, diagram.getHorizontalPages(), diagram.getVerticalPages(), + diagram.getMetadata(), 96).getFiles(); } } diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramPngMaker3.java b/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramPngMaker3.java index a0841a53d..309c1063b 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramPngMaker3.java +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramPngMaker3.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5047 $ + * Revision $Revision: 5872 $ * */ package net.sourceforge.plantuml.cucadiagram.dot; @@ -91,7 +91,7 @@ public final class CucaDiagramPngMaker3 { final List graphs = getGraphs3(zoda2.getHeaps()); final Dimension2D totalDim = getTotalDimension(graphs); - final EmptyImageBuilder im = new EmptyImageBuilder((int) totalDim.getWidth(), (int) totalDim.getHeight(), + final EmptyImageBuilder im = new EmptyImageBuilder(totalDim.getWidth(), totalDim.getHeight(), Color.WHITE); double x = 0; @@ -156,7 +156,7 @@ public final class CucaDiagramPngMaker3 { } } - return new PngSplitter(pngFile, diagram.getHorizontalPages(), diagram.getVerticalPages(), diagram.getMetadata()) + return new PngSplitter(pngFile, diagram.getHorizontalPages(), diagram.getVerticalPages(), diagram.getMetadata(), 96) .getFiles(); } } diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramSimplifier.java b/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramSimplifier.java index 40c6380b6..3546382cc 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramSimplifier.java +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/CucaDiagramSimplifier.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5378 $ + * Revision $Revision: 5789 $ * */ package net.sourceforge.plantuml.cucadiagram.dot; @@ -41,21 +41,28 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; +import net.sourceforge.plantuml.ColorParam; import net.sourceforge.plantuml.FileFormat; -import net.sourceforge.plantuml.cucadiagram.Member; +import net.sourceforge.plantuml.FileUtils; +import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.cucadiagram.CucaDiagram; import net.sourceforge.plantuml.cucadiagram.Entity; import net.sourceforge.plantuml.cucadiagram.EntityType; import net.sourceforge.plantuml.cucadiagram.Group; import net.sourceforge.plantuml.cucadiagram.GroupType; +import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Member; +import net.sourceforge.plantuml.cucadiagram.Stereotype; +import net.sourceforge.plantuml.graphic.HtmlColor; +import net.sourceforge.plantuml.skin.rose.Rose; public final class CucaDiagramSimplifier { private final CucaDiagram diagram; private final FileFormat fileFormat; - public CucaDiagramSimplifier(CucaDiagram diagram, List dotStrings, FileFormat fileFormat) throws IOException, - InterruptedException { + public CucaDiagramSimplifier(CucaDiagram diagram, List dotStrings, FileFormat fileFormat) + throws IOException, InterruptedException { this.diagram = diagram; this.fileFormat = fileFormat; boolean changed; @@ -77,27 +84,66 @@ public final class CucaDiagramSimplifier { throw new IllegalStateException(); } final Entity proxy = new Entity("#" + g.getCode(), g.getDisplay(), type, g.getParent()); + if (type == EntityType.STATE) { + manageBackColorForState(diagram, g, proxy); + } for (Member field : g.getEntityCluster().fields2()) { proxy.addField(field); } computeImageGroup(g, proxy, dotStrings); diagram.overideGroup(g, proxy); + + for (IEntity sub : g.entities().values()) { + final DrawFile subImage = sub.getImageFile(); + if (subImage != null) { + proxy.addSubImage(subImage); + } + } + changed = true; } } } while (changed); } + private void manageBackColorForState(CucaDiagram diagram, Group g, final Entity proxy) { + if (OptionFlags.PBBACK == false) { + return; + } + if (g.getBackColor() != null) { + proxy.setSpecificBackcolor(g.getBackColor().getAsHtml()); + return; + } + assert g.getBackColor() == null; + if (g.getStereotype() != null) { + proxy.setStereotype(new Stereotype(g.getStereotype())); + } + //PBBACK + final Rose rose = new Rose(); + final HtmlColor back = rose.getHtmlColor(diagram.getSkinParam(), ColorParam.stateBackground, g.getStereotype()); +// final HtmlColor back = diagram.getSkinParam().getHtmlColor(ColorParam.stateBackground, g.getStereotype()); +// if (back != null) { +// proxy.setSpecificBackcolor(back.getAsHtml()); +// } + assert g.getBackColor() == null; + g.setBackColor(back); + } + private void computeImageGroup(final Group group, final Entity entity, List dotStrings) throws IOException, FileNotFoundException, InterruptedException { final GroupPngMaker maker = new GroupPngMaker(diagram, group, fileFormat); - final File f = CucaDiagramFileMaker.createTempFile("inner", ".png"); + final File f = FileUtils.createTempFile("inner", ".png"); FileOutputStream fos = null; try { fos = new FileOutputStream(f); maker.createPng(fos, dotStrings); final String svg = maker.createSvg(dotStrings); - entity.setImageFile(new DrawFile(f, svg)); + // final Pattern pImage = Pattern.compile("(?i)]*>"); + // final Matcher mImage = pImage.matcher(svg); + // if (mImage.find()) { + // throw new IllegalStateException(); + // } + entity.setImageFile(DrawFile.createFromFile(f, svg, null)); } finally { if (fos != null) { fos.close(); diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/DotData.java b/src/net/sourceforge/plantuml/cucadiagram/dot/DotData.java index 2e1ee8a40..4ddc60518 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/dot/DotData.java +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/DotData.java @@ -28,16 +28,15 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5084 $ + * Revision $Revision: 5813 $ * */ package net.sourceforge.plantuml.cucadiagram.dot; +import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.EnumMap; -import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -65,10 +64,10 @@ final public class DotData implements PortionShower { final private GroupHierarchy groupHierarchy; final private Group topParent; final private PortionShower portionShower; + private int dpi = 96; - final private Map staticImages = new HashMap(); - final private Map visibilityImages = new EnumMap( - VisibilityModifier.class); + private StaticFilesMap staticFilesMap; + private boolean visibilityModifierPresent; public DotData(Group topParent, List links, Map entities, UmlDiagramType umlDiagramType, ISkinParam skinParam, Rankdir rankdir, GroupHierarchy groupHierarchy, @@ -96,20 +95,38 @@ final public class DotData implements PortionShower { return true; } - public Map getStaticImages() { - return staticImages; + public DrawFile getStaticImages(EntityType type, String stereo) throws IOException { + checkObjectOrClassDiagram(); + assert type == EntityType.ABSTRACT_CLASS || type == EntityType.CLASS || type == EntityType.ENUM + || type == EntityType.INTERFACE || type == EntityType.LOLLIPOP; + return staticFilesMap.getStaticFiles(stereo).getStaticImages(type); } - public void putAllStaticImages(Map staticImages) { - this.staticImages.putAll(staticImages); + public DrawFile getVisibilityImages(VisibilityModifier visibilityModifier, String stereo) throws IOException { + checkObjectOrClassDiagram(); + return staticFilesMap.getStaticFiles(stereo).getVisibilityImages(visibilityModifier); + } + + public boolean isThereVisibilityImages() { + return visibilityModifierPresent; + } + + public void setVisibilityModifierPresent(boolean b) { + checkObjectOrClassDiagram(); + this.visibilityModifierPresent = b; } - public Map getVisibilityImages() { - return visibilityImages; + + + public void setStaticImagesMap(StaticFilesMap staticFilesMap) { + checkObjectOrClassDiagram(); + this.staticFilesMap = staticFilesMap; } - public void putAllVisibilityImages(Map visibilityImages) { - this.visibilityImages.putAll(visibilityImages); + private void checkObjectOrClassDiagram() { + if (umlDiagramType != UmlDiagramType.CLASS && umlDiagramType != UmlDiagramType.OBJECT) { + throw new IllegalStateException(); + } } public UmlDiagramType getUmlDiagramType() { @@ -231,4 +248,19 @@ final public class DotData implements PortionShower { return portionShower.showPortion(portion, entity); } + public final int getDpi() { + return dpi; + } + + public double getDpiFactor() { + if (dpi == 96) { + return 1.0; + } + return dpi / 96.0; + } + + public final void setDpi(int dpi) { + this.dpi = dpi; + } + } diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/DotExpression.java b/src/net/sourceforge/plantuml/cucadiagram/dot/DotExpression.java index 74ae4ca27..c1f0c1250 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/dot/DotExpression.java +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/DotExpression.java @@ -28,21 +28,28 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5396 $ + * Revision $Revision: 5705 $ * */ package net.sourceforge.plantuml.cucadiagram.dot; import java.awt.Color; import java.awt.Font; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.FileSystem; import net.sourceforge.plantuml.Log; import net.sourceforge.plantuml.graphic.FontChange; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.FontStyle; import net.sourceforge.plantuml.graphic.HtmlColor; import net.sourceforge.plantuml.graphic.HtmlCommand; +import net.sourceforge.plantuml.graphic.Img; import net.sourceforge.plantuml.graphic.Splitter; import net.sourceforge.plantuml.graphic.Text; @@ -60,7 +67,12 @@ final class DotExpression { private final FileFormat fileFormat; + private boolean hasImg; + DotExpression(String html, int defaultFontSize, HtmlColor color, String fontFamily, int style, FileFormat fileFormat) { + if (html.contains("\n")) { + throw new IllegalArgumentException(html); + } this.fontFamily = fontFamily; this.normalFont = new Font("SansSerif", Font.PLAIN, defaultFontSize); this.fontConfiguration = new FontConfiguration(normalFont, color.getColor()); @@ -78,15 +90,66 @@ final class DotExpression { html = html.replaceAll("\\ ", ""); underline = html.contains("") || html.contains(""); final Splitter splitter = new Splitter(html); - for (HtmlCommand command : splitter.getHtmlCommands()) { + List htmlCommands = splitter.getHtmlCommands(false); + for (HtmlCommand command : htmlCommands) { + if (command instanceof Img) { + hasImg = true; + } + } + if (hasImg) { + htmlCommands = splitter.getHtmlCommands(true); + sb.append(""); + for (Collection cmds : split(htmlCommands)) { + sb.append(""); + } + sb.append("
"); + manageCommands(cmds); + sb.append("
"); + } else { + manageCommands(htmlCommands); + } + } + + private static List> split(Collection all) { + final List> result = new ArrayList>(); + Collection current = null; + for (HtmlCommand c : all) { + if (c instanceof Text && ((Text) c).isNewline()) { + current = null; + } else { + if (current == null) { + current = new ArrayList(); + result.add(current); + } + current.add(c); + } + } + return result; + } + + private void manageCommands(Collection htmlCommands) { + for (HtmlCommand command : htmlCommands) { if (command instanceof Text) { manage((Text) command); } else if (command instanceof FontChange) { manage((FontChange) command); + } else if (command instanceof Img) { + manageImage((Img) command); } else { Log.error("Cannot manage " + command); } + } + } + private void manageImage(Img img) { + try { + final File f = FileSystem.getInstance().getFile(img.getFilePath()); + if (f.exists() == false) { + throw new IOException(); + } + sb.append(""); + } catch (IOException e) { + sb.append("File Not Found"); } } @@ -95,17 +158,29 @@ final class DotExpression { } private void manage(Text command) { + if (hasImg) { + sb.append(""); + } underline(false); sb.append(getFontTag()); String text = command.getText(); text = text.replace("<", "<"); text = text.replace(">", ">"); - text = text.replace("\\n", "
"); + + if (hasImg == false) { + text = text.replace("\\n", "
"); + } sb.append(text); sb.append(""); underline(true); + if (hasImg) { + sb.append(""); + if (text.contains("\\n")) { + throw new IllegalStateException(); + } + } } private String getFontTag() { diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/DotMaker.java b/src/net/sourceforge/plantuml/cucadiagram/dot/DotMaker.java index c95140614..92a35d045 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/dot/DotMaker.java +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/DotMaker.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5581 $ + * Revision $Revision: 5847 $ * */ package net.sourceforge.plantuml.cucadiagram.dot; @@ -49,6 +49,7 @@ import javax.imageio.ImageIO; import net.sourceforge.plantuml.ColorParam; import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.FileUtils; import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.Log; import net.sourceforge.plantuml.OptionFlags; @@ -100,7 +101,7 @@ final public class DotMaker implements GraphvizMaker { this.dotStrings = dotStrings; this.fileFormat = fileFormat; if (data.getSkinParam().classAttributeIconSize() > 0) { - this.isVisibilityModifierPresent = data.getVisibilityImages().size() > 0; + this.isVisibilityModifierPresent = data.isThereVisibilityImages(); } else { this.isVisibilityModifierPresent = false; } @@ -129,11 +130,11 @@ final public class DotMaker implements GraphvizMaker { final boolean huge = data.getEntities().size() > 800; sb.append("digraph unix {"); - if (isJunit == false) { + //if (isJunit == false) { for (String s : dotStrings) { sb.append(s); } - } + // } sb.append("bgcolor=\"" + data.getSkinParam().getBackgroundColor().getAsHtml() + "\";"); if (huge) { sb.append("size=\"400,400;\""); @@ -147,6 +148,11 @@ final public class DotMaker implements GraphvizMaker { if (data.getRankdir() == Rankdir.LEFT_TO_RIGHT) { sb.append("rankdir=LR;"); } + + if (data.getDpi() != 96) { + sb.append("dpi=" + data.getDpi() + ";"); + sb.append("imagescale=both;"); + } } private Collection getUnpackagedEntities() { @@ -185,27 +191,31 @@ final public class DotMaker implements GraphvizMaker { private void printGroupNormal(StringBuilder sb, Group g) throws IOException { + final String stereo = g.getStereotype(); + sb.append("subgraph " + g.getUid() + " {"); // sb.append("margin=10;"); - sb.append("fontsize=\"" + data.getSkinParam().getFontSize(getFontParamForGroup()) + "\";"); - final String fontFamily = data.getSkinParam().getFontFamily(getFontParamForGroup()); + sb.append("fontsize=\"" + data.getSkinParam().getFontSize(getFontParamForGroup(), stereo) + "\";"); + final String fontFamily = data.getSkinParam().getFontFamily(getFontParamForGroup(), stereo); if (fontFamily != null) { sb.append("fontname=\"" + fontFamily + "\";"); } if (g.getDisplay() != null) { - sb.append("label=<" + manageHtmlIB(g.getDisplay(), getFontParamForGroup()) + ">;"); + sb.append("label=<" + manageHtmlIB(g.getDisplay(), getFontParamForGroup(), stereo) + ">;"); } - final String fontColor = data.getSkinParam().getFontHtmlColor(getFontParamForGroup()).getAsHtml(); + final String fontColor = data.getSkinParam().getFontHtmlColor(getFontParamForGroup(), stereo).getAsHtml(); sb.append("fontcolor=\"" + fontColor + "\";"); + if (getGroupBackColor(g) != null) { sb.append("fillcolor=\"" + getGroupBackColor(g).getAsHtml() + "\";"); } + if (g.getType() == GroupType.STATE) { - sb.append("color=" + getColorString(ColorParam.stateBorder) + ";"); + sb.append("color=" + getColorString(ColorParam.stateBorder, stereo) + ";"); } else { - sb.append("color=" + getColorString(ColorParam.packageBorder) + ";"); + sb.append("color=" + getColorString(ColorParam.packageBorder, stereo) + ";"); } sb.append("style=\"" + getStyle(g) + "\";"); @@ -221,7 +231,7 @@ final public class DotMaker implements GraphvizMaker { private HtmlColor getGroupBackColor(Group g) { HtmlColor value = g.getBackColor(); if (value == null) { - value = data.getSkinParam().getHtmlColor(ColorParam.packageBackground); + value = data.getSkinParam().getHtmlColor(ColorParam.packageBackground, null); // value = rose.getHtmlColor(this.data.getSkinParam(), // ColorParam.packageBackground); } @@ -302,34 +312,35 @@ final public class DotMaker implements GraphvizMaker { } // sb.append(g.getUid() + "min->" + g.getUid() + "max;"); - sb.append("fontsize=\"" + data.getSkinParam().getFontSize(getFontParamForGroup()) + "\";"); - final String fontFamily = data.getSkinParam().getFontFamily(getFontParamForGroup()); + sb.append("fontsize=\"" + data.getSkinParam().getFontSize(getFontParamForGroup(), null) + "\";"); + final String fontFamily = data.getSkinParam().getFontFamily(getFontParamForGroup(), null); if (fontFamily != null) { sb.append("fontname=\"" + fontFamily + "\";"); } if (g.getDisplay() != null) { - final StringBuilder label = new StringBuilder(manageHtmlIB(g.getDisplay(), getFontParamForGroup())); + final StringBuilder label = new StringBuilder(manageHtmlIB(g.getDisplay(), getFontParamForGroup(), null)); if (g.getEntityCluster().fields2().size() > 0) { label.append("
"); for (Member att : g.getEntityCluster().fields2()) { label.append(manageHtmlIB(" " + att.getDisplayWithVisibilityChar() + " ", - FontParam.STATE_ATTRIBUTE)); + FontParam.STATE_ATTRIBUTE, null)); label.append("
"); } } sb.append("label=<" + label + ">;"); } - final String fontColor = data.getSkinParam().getFontHtmlColor(getFontParamForGroup()).getAsHtml(); + final String fontColor = data.getSkinParam().getFontHtmlColor(getFontParamForGroup(), null).getAsHtml(); sb.append("fontcolor=\"" + fontColor + "\";"); - if (getGroupBackColor(g) != null) { - sb.append("fillcolor=\"" + getGroupBackColor(g).getAsHtml() + "\";"); + final HtmlColor groupBackColor = getGroupBackColor(g); + if (groupBackColor != null) { + sb.append("fillcolor=\"" + groupBackColor.getAsHtml() + "\";"); } if (g.getType() == GroupType.STATE) { - sb.append("color=" + getColorString(ColorParam.stateBorder) + ";"); + sb.append("color=" + getColorString(ColorParam.stateBorder, null) + ";"); } else { - sb.append("color=" + getColorString(ColorParam.packageBorder) + ";"); + sb.append("color=" + getColorString(ColorParam.packageBorder, null) + ";"); } sb.append("style=\"" + getStyle(g) + "\";"); @@ -339,8 +350,17 @@ final public class DotMaker implements GraphvizMaker { sb.append("style=dotted;"); sb.append("label=\"i\";"); } else { - sb.append("style=invis;"); + + if (groupBackColor == null) { + sb.append("style=invis;"); + } else { + final String colorBack = getColorString(ColorParam.background, null); + sb.append("fillcolor=" + colorBack + ";"); + sb.append("color=" + colorBack + ";"); + sb.append("style=\"filled,rounded\";"); + } sb.append("label=\"\";"); + } printGroups(sb, g); @@ -373,14 +393,14 @@ final public class DotMaker implements GraphvizMaker { sb.append("style=invis;"); sb.append("label=\"\";"); } - final String decorationColor = ",color=" + getColorString(getArrowColorParam()); + final String decorationColor = ",color=" + getColorString(getArrowColorParam(), null); sb.append(g.getUid() + "lab0 [shape=point,width=.01,label=\"\"" + decorationColor + "]"); String autolabel = autolinks.get(0).getLabel(); if (autolabel == null) { autolabel = ""; } - sb.append(g.getUid() + "lab1 [label=<" + manageHtmlIB(autolabel, getArrowFontParam()) + sb.append(g.getUid() + "lab1 [label=<" + manageHtmlIB(autolabel, getArrowFontParam(), null) + ">,shape=plaintext,margin=0];"); sb.append(g.getUid() + "lab0 -> " + g.getUid() + "lab1 [minlen=0,style=invis];"); sb.append("}"); // end of l @@ -400,7 +420,7 @@ final public class DotMaker implements GraphvizMaker { sb.append("style=invis;"); sb.append("label=\"\";"); } - final String decorationColor = ",color=" + getColorString(getArrowColorParam()); + final String decorationColor = ",color=" + getColorString(getArrowColorParam(), null); String label = fromEdgeLinks.get(i).getLabel(); if (label == null) { label = ""; @@ -412,7 +432,7 @@ final public class DotMaker implements GraphvizMaker { + "v,arrowtail=none,arrowhead=none" + decorationColor + "];"); sb.append(g.getUid() + "fedge" + i + " -> " + fromEdgeLinks.get(i).getEntity2().getUid() + "[arrowtail=none,arrowhead=open" + decorationColor); - sb.append(",label=<" + manageHtmlIB(label, getArrowFontParam()) + ">];"); + sb.append(",label=<" + manageHtmlIB(label, getArrowFontParam(), null) + ">];"); } sb.append("}"); // end of a @@ -481,17 +501,17 @@ final public class DotMaker implements GraphvizMaker { final DrawFile noteLink = link.getImageFile(); if (link.getLabel() != null) { - decoration.append("label=<" + manageHtmlIB(link.getLabel(), getArrowFontParam()) + ">,"); + decoration.append("label=<" + manageHtmlIB(link.getLabel(), getArrowFontParam(), null) + ">,"); } else if (noteLink != null) { decoration .append("label=<" + getHtmlForLinkNote(noteLink.getPngOrEps(fileFormat == FileFormat.EPS)) + ">,"); } if (link.getQualifier1() != null) { - decoration.append("taillabel=<" + manageHtmlIB(link.getQualifier1(), getArrowFontParam()) + ">,"); + decoration.append("taillabel=<" + manageHtmlIB(link.getQualifier1(), getArrowFontParam(), null) + ">,"); } if (link.getQualifier2() != null) { - decoration.append("headlabel=<" + manageHtmlIB(link.getQualifier2(), getArrowFontParam()) + ">,"); + decoration.append("headlabel=<" + manageHtmlIB(link.getQualifier2(), getArrowFontParam(), null) + ">,"); } decoration.append(link.getType().getSpecificDecoration()); if (link.isInvis()) { @@ -552,12 +572,12 @@ final public class DotMaker implements GraphvizMaker { } private StringBuilder getLinkDecoration() { - final StringBuilder decoration = new StringBuilder("[color=" + getColorString(getArrowColorParam()) + ","); + final StringBuilder decoration = new StringBuilder("[color=" + getColorString(getArrowColorParam(), null) + ","); - decoration.append("fontcolor=" + getFontColorString(getArrowFontParam()) + ","); - decoration.append("fontsize=\"" + data.getSkinParam().getFontSize(getArrowFontParam()) + "\","); + decoration.append("fontcolor=" + getFontColorString(getArrowFontParam(), null) + ","); + decoration.append("fontsize=\"" + data.getSkinParam().getFontSize(getArrowFontParam(), null) + "\","); - final String fontName = data.getSkinParam().getFontFamily(getArrowFontParam()); + final String fontName = data.getSkinParam().getFontFamily(getArrowFontParam(), null); if (fontName != null) { decoration.append("fontname=\"" + fontName + "\","); } @@ -624,16 +644,16 @@ final public class DotMaker implements GraphvizMaker { throw new IllegalStateException(); } - private String getColorString(ColorParam colorParam) { - return "\"" + rose.getHtmlColor(data.getSkinParam(), colorParam).getAsHtml() + "\""; + private String getColorString(ColorParam colorParam, String stereotype) { + return "\"" + rose.getHtmlColor(data.getSkinParam(), colorParam, stereotype).getAsHtml() + "\""; } - private String getFontColorString(FontParam fontParam) { - return "\"" + getFontHtmlColor(fontParam).getAsHtml() + "\""; + private String getFontColorString(FontParam fontParam, String stereotype) { + return "\"" + getFontHtmlColor(fontParam, stereotype).getAsHtml() + "\""; } - private HtmlColor getFontHtmlColor(FontParam fontParam) { - return data.getSkinParam().getFontHtmlColor(fontParam); + private HtmlColor getFontHtmlColor(FontParam fontParam, String stereotype) { + return data.getSkinParam().getFontHtmlColor(fontParam, stereotype); } private void eventuallySameRank(StringBuilder sb, Group entityPackage, Link link) { @@ -718,10 +738,10 @@ final public class DotMaker implements GraphvizMaker { private void printEntity(StringBuilder sb, IEntity entity, String headOrTail) throws IOException { final EntityType type = entity.getType(); if (type == EntityType.LOLLIPOP) { - final String color1 = getColorString(ColorParam.classBackground); - final String color2 = getColorString(ColorParam.classBorder); - final String colorBack = getColorString(ColorParam.background); - final String labelLo = manageHtmlIB(entity.getDisplay(), FontParam.CLASS_ATTRIBUTE); + final String color1 = getColorString(ColorParam.classBackground, null); + final String color2 = getColorString(ColorParam.classBorder, null); + final String colorBack = getColorString(ColorParam.background, null); + final String labelLo = manageHtmlIB(entity.getDisplay(), FontParam.CLASS_ATTRIBUTE, null); sb.append(entity.getUid() + " [fillcolor=" + color1 + ",color=" + color2 + ",style=\"filled\"," + "shape=circle,width=0.12,height=0.12,label=\"\"];"); sb.append(entity.getUid() + " -> " + entity.getUid() + "[color=" + colorBack @@ -738,39 +758,40 @@ final public class DotMaker implements GraphvizMaker { if (type == EntityType.GROUP) { return; } + final String stereo = entity.getStereotype() == null ? null : entity.getStereotype().getLabel(); if (type == EntityType.ABSTRACT_CLASS || type == EntityType.CLASS || type == EntityType.INTERFACE || type == EntityType.ENUM) { - String dec = " [fontcolor=" + getFontColorString(FontParam.CLASS) + ",margin=0,fillcolor=" - + getColorString(ColorParam.classBackground) + ",color=" + getColorString(ColorParam.classBorder) - + ",style=filled,shape=box," + label; + String dec = " [fontcolor=" + getFontColorString(FontParam.CLASS, stereo) + ",margin=0,fillcolor=" + + getColorString(ColorParam.classBackground, stereo) + ",color=" + + getColorString(ColorParam.classBorder, stereo) + ",style=filled,shape=box," + label; if (this.data.hasUrl() && entity.getUrl() != null) { dec += ",URL=\"" + entity.getUrl() + "\""; } dec += "];"; sb.append(entity.getUid() + dec); } else if (type == EntityType.OBJECT) { - sb.append(entity.getUid() + " [fontcolor=" + getFontColorString(FontParam.CLASS) + ",margin=0,fillcolor=" - + getColorString(ColorParam.classBackground) + ",color=" + getColorString(ColorParam.classBorder) - + ",style=filled,shape=record," + label + "];"); + sb.append(entity.getUid() + " [fontcolor=" + getFontColorString(FontParam.CLASS, stereo) + + ",margin=0,fillcolor=" + getColorString(ColorParam.classBackground, stereo) + ",color=" + + getColorString(ColorParam.classBorder, stereo) + ",style=filled,shape=record," + label + "];"); } else if (type == EntityType.USECASE) { - sb.append(entity.getUid() + " [fontcolor=" + getFontColorString(FontParam.USECASE) + ",fillcolor=" - + getColorString(ColorParam.usecaseBackground) + ",color=" - + getColorString(ColorParam.usecaseBorder) + ",style=filled," + label + "];"); + sb.append(entity.getUid() + " [fontcolor=" + getFontColorString(FontParam.USECASE, stereo) + ",fillcolor=" + + getColorString(ColorParam.usecaseBackground, stereo) + ",color=" + + getColorString(ColorParam.usecaseBorder, stereo) + ",style=filled," + label + "];"); } else if (type == EntityType.ACTOR) { - sb.append(entity.getUid() + " [fontcolor=" + getFontColorString(FontParam.USECASE_ACTOR) + sb.append(entity.getUid() + " [fontcolor=" + getFontColorString(FontParam.USECASE_ACTOR, stereo) + ",margin=0,shape=plaintext," + label + "];"); } else if (type == EntityType.CIRCLE_INTERFACE) { sb.append(entity.getUid() + " [margin=0,shape=plaintext," + label + "];"); } else if (type == EntityType.COMPONENT) { - sb.append(entity.getUid() + " [margin=0.2,fontcolor=" + getFontColorString(FontParam.COMPONENT) - + ",fillcolor=" + getColorString(ColorParam.componentBackground) + ",color=" - + getColorString(ColorParam.componentBorder) + ",style=filled,shape=component," + label + "];"); + sb.append(entity.getUid() + " [margin=0.2,fontcolor=" + getFontColorString(FontParam.COMPONENT, stereo) + + ",fillcolor=" + getColorString(ColorParam.componentBackground, stereo) + ",color=" + + getColorString(ColorParam.componentBorder, stereo) + ",style=filled,shape=component," + label + + "];"); + } else if (type == EntityType.NOTE && data.getDpi() != 96) { + sb.append(entity.getUid() + " [margin=0,pad=0,shape=plaintext,label=" + getLabelForNoteDpi(entity) + "];"); } else if (type == EntityType.NOTE) { final DrawFile file = entity.getImageFile(); if (file == null) { - // sb.append(entity.getUid() + ";"); - // Log.error("Warning : no file for NOTE"); - // return; throw new IllegalStateException("No file for NOTE"); } if (file.getPngOrEps(fileFormat == FileFormat.EPS).exists() == false) { @@ -784,13 +805,12 @@ final public class DotMaker implements GraphvizMaker { if (entity.getImageFile() != null) { shape = "rect"; } - sb.append(entity.getUid() + " [fontcolor=" + getFontColorString(FontParam.ACTIVITY) + ",fillcolor=" - + getColorString(ColorParam.activityBackground) + ",color=" - + getColorString(ColorParam.activityBorder) + ",style=\"rounded,filled\",shape=" + shape + "," - + label + "];"); + sb.append(entity.getUid() + " [fontcolor=" + getFontColorString(FontParam.ACTIVITY, stereo) + ",fillcolor=" + + getBackColorOfEntity(entity) + ",color=" + getColorString(ColorParam.activityBorder, stereo) + + ",style=\"rounded,filled\",shape=" + shape + "," + label + "];"); } else if (type == EntityType.BRANCH) { - sb.append(entity.getUid() + " [fillcolor=" + getColorString(ColorParam.activityBackground) + ",color=" - + getColorString(ColorParam.activityBorder) + sb.append(entity.getUid() + " [fillcolor=" + getBackColorOfEntity(entity) + ",color=" + + getColorString(ColorParam.activityBorder, stereo) + ",style=\"filled\",shape=diamond,height=.25,width=.25,label=\"\"];"); // if (StringUtils.isNotEmpty(entity.getDisplay())) { // sb.append(entity.getUid() + "->" + entity.getUid() + @@ -798,27 +818,27 @@ final public class DotMaker implements GraphvizMaker { // + "\",arrowtail=none,arrowhead=none,color=\"white\"];"); // } } else if (type == EntityType.SYNCHRO_BAR) { - final String color = getColorString(ColorParam.activityBar); + final String color = getColorString(ColorParam.activityBar, null); sb.append(entity.getUid() + " [fillcolor=" + color + ",color=" + color + ",style=\"filled\"," + "shape=rect,height=.08,width=1.30,label=\"\"];"); } else if (type == EntityType.CIRCLE_START) { - final String color = getColorString(ColorParam.activityStart); + final String color = getColorString(getStartColorParam(), null); sb.append(entity.getUid() + " [fillcolor=" + color + ",color=" + color + ",style=\"filled\"," + "shape=circle,width=.20,height=.20,label=\"\"];"); } else if (type == EntityType.CIRCLE_END) { - final String color = getColorString(ColorParam.activityEnd); + final String color = getColorString(getEndColorParam(), null); sb.append(entity.getUid() + " [fillcolor=" + color + ",color=" + color + ",style=\"filled\"," + "shape=doublecircle,width=.13,height=.13,label=\"\"];"); } else if (type == EntityType.POINT_FOR_ASSOCIATION) { - sb.append(entity.getUid() + " [width=.05,shape=point,color=" + getColorString(ColorParam.classBorder) + sb.append(entity.getUid() + " [width=.05,shape=point,color=" + getColorString(ColorParam.classBorder, null) + "];"); } else if (type == EntityType.STATE) { - sb.append(entity.getUid() + " [color=" + getColorString(ColorParam.stateBorder) - + ",shape=record,style=\"rounded,filled\",color=" + getColorString(ColorParam.stateBorder)); + sb.append(entity.getUid() + " [color=" + getColorString(ColorParam.stateBorder, stereo) + + ",shape=record,style=\"rounded,filled\",color=" + getColorString(ColorParam.stateBorder, stereo)); if (entity.getImageFile() == null) { - sb.append(",fillcolor=" + getColorString(ColorParam.stateBackground)); + sb.append(",fillcolor=" + getBackColorOfEntity(entity)); } else { - sb.append(",fillcolor=" + getColorString(ColorParam.stateBackground)); + sb.append(",fillcolor=" + getBackColorOfEntity(entity)); // sb.append(",fillcolor=\"" + // data.getSkinParam().getBackgroundColor().getAsHtml() + "\""); } @@ -846,14 +866,34 @@ final public class DotMaker implements GraphvizMaker { sb.append(entity.getUid() + " [margin=0,pad=0," + label + ",style=dashed,shape=box,image=\"" + absolutePath + "\"];"); } else if (type == EntityType.EMPTY_PACKAGE) { - sb.append(entity.getUid() + " [margin=0.2,fontcolor=" + getFontColorString(FontParam.PACKAGE) - + ",fillcolor=" + getColorString(ColorParam.packageBackground) + ",color=" - + getColorString(ColorParam.packageBorder) + ",style=filled,shape=tab," + label + "];"); + sb.append(entity.getUid() + " [margin=0.2,fontcolor=" + getFontColorString(FontParam.PACKAGE, null) + + ",fillcolor=" + getColorString(ColorParam.packageBackground, null) + ",color=" + + getColorString(ColorParam.packageBorder, null) + ",style=filled,shape=tab," + label + "];"); } else { throw new IllegalStateException(type.toString() + " " + data.getUmlDiagramType()); } } + private ColorParam getEndColorParam() { + if (data.getUmlDiagramType() == UmlDiagramType.ACTIVITY) { + return ColorParam.activityEnd; + } + if (data.getUmlDiagramType() == UmlDiagramType.STATE) { + return ColorParam.stateEnd; + } + throw new IllegalStateException(data.getUmlDiagramType().toString()); + } + + private ColorParam getStartColorParam() { + if (data.getUmlDiagramType() == UmlDiagramType.ACTIVITY) { + return ColorParam.activityStart; + } + if (data.getUmlDiagramType() == UmlDiagramType.STATE) { + return ColorParam.stateStart; + } + throw new IllegalStateException(data.getUmlDiagramType().toString()); + } + private String getHeadOrTail(IEntity lollipop, Link link) { assert lollipop.getType() == EntityType.LOLLIPOP; if (link.getLength() > 1 && link.getEntity1() == lollipop) { @@ -897,9 +937,10 @@ final public class DotMaker implements GraphvizMaker { sb.append(">"); return sb.toString(); } - return "label=" + getSimpleLabelAsHtml(entity, FontParam.ACTIVITY); + final String stereotype = entity.getStereotype() == null ? null : entity.getStereotype().getLabel(); + return "label=" + getSimpleLabelAsHtml(entity, FontParam.ACTIVITY, stereotype); } else if (entity.getType() == EntityType.EMPTY_PACKAGE) { - return "label=" + getSimpleLabelAsHtml(entity, getFontParamForGroup()); + return "label=" + getSimpleLabelAsHtml(entity, getFontParamForGroup(), null); } else if (entity.getType() == EntityType.USECASE) { return "label=" + getLabelForUsecase(entity); } else if (entity.getType() == EntityType.STATE) { @@ -908,23 +949,40 @@ final public class DotMaker implements GraphvizMaker { return "label=\"" + entity.getDisplay() + "\""; } - private String getSimpleLabelAsHtml(IEntity entity, FontParam param) { - return "<" + manageHtmlIB(entity.getDisplay(), param) + ">"; + private String getSimpleLabelAsHtml(IEntity entity, FontParam param, String stereotype) { + return "<" + manageHtmlIB(entity.getDisplay(), param, stereotype) + ">"; + } + + private String getBackColorOfEntity(IEntity entity) { + if (entity.getSpecificBackColor() != null) { + return "\"" + entity.getSpecificBackColor().getAsHtml() + "\""; + } + final String stereo = entity.getStereotype() == null ? null : entity.getStereotype().getLabel(); + if (entity.getType() == EntityType.STATE || entity.getType() == EntityType.STATE_CONCURRENT) { + return getColorString(ColorParam.stateBackground, stereo); + } + if (entity.getType() == EntityType.ACTIVITY || entity.getType() == EntityType.ACTIVITY_CONCURRENT + || entity.getType() == EntityType.BRANCH) { + return getColorString(ColorParam.activityBackground, stereo); + } + throw new IllegalArgumentException(entity.getType().toString()); } private String getLabelForState(IEntity entity) throws IOException { final DrawFile cFile = entity.getImageFile(); - final String stateBgcolor = getColorString(ColorParam.stateBackground); + final String stateBgcolor = getBackColorOfEntity(entity); + + final String stereotype = entity.getStereotype() == null ? null : entity.getStereotype().getLabel(); final StringBuilder sb = new StringBuilder("<{"); - sb.append(""); + sb.append(""); sb.append("
" + manageHtmlIB(entity.getDisplay(), FontParam.STATE) + "
" + manageHtmlIB(entity.getDisplay(), FontParam.STATE, stereotype) + "
"); if (entity.fields2().size() > 0) { sb.append("|"); for (Member att : entity.fields2()) { - sb.append(manageHtmlIB(att.getDisplayWithVisibilityChar(), FontParam.STATE_ATTRIBUTE)); + sb.append(manageHtmlIB(att.getDisplayWithVisibilityChar(), FontParam.STATE_ATTRIBUTE, stereotype)); sb.append("
"); } } @@ -932,7 +990,13 @@ final public class DotMaker implements GraphvizMaker { if (cFile != null) { sb.append("|"); final String path = StringUtils.getPlateformDependentAbsolutePath(cFile.getPng()); - final String bgcolor = "\"" + data.getSkinParam().getBackgroundColor().getAsHtml() + "\""; + final String bgcolor; + if (OptionFlags.PBBACK) { + bgcolor = stateBgcolor; + } else { + bgcolor = "\"" + data.getSkinParam().getBackgroundColor().getAsHtml() + "\""; + } + // PBBACK sb.append(""); sb.append(""); @@ -952,14 +1016,16 @@ final public class DotMaker implements GraphvizMaker { private String getLabelForUsecase(IEntity entity) { final Stereotype stereotype = getStereotype(entity); + final String stereo = entity.getStereotype() == null ? null : entity.getStereotype().getLabel(); if (stereotype == null) { - return getSimpleLabelAsHtml(entity, FontParam.USECASE); + return getSimpleLabelAsHtml(entity, FontParam.USECASE, stereo); } final StringBuilder sb = new StringBuilder("<
"); if (isThereLabel(stereotype)) { - sb.append(""); + sb.append(""); } - sb.append(""); + sb.append(""); sb.append("
" + manageHtmlIB(stereotype.getLabel(), FontParam.USECASE_STEREOTYPE) + "
" + manageHtmlIB(stereotype.getLabel(), FontParam.USECASE_STEREOTYPE, stereo) + + "
" + manageHtmlIB(entity.getDisplay(), FontParam.USECASE) + "
" + manageHtmlIB(entity.getDisplay(), FontParam.USECASE, stereo) + "
>"); return sb.toString(); } @@ -967,61 +1033,129 @@ final public class DotMaker implements GraphvizMaker { private String getLabelForComponent(IEntity entity) { final Stereotype stereotype = getStereotype(entity); if (stereotype == null) { - return getSimpleLabelAsHtml(entity, FontParam.COMPONENT); + return getSimpleLabelAsHtml(entity, FontParam.COMPONENT, null); } + final String stereo = stereotype.getLabel(); final StringBuilder sb = new StringBuilder("<"); if (isThereLabel(stereotype)) { - sb.append(""); + sb.append(""); } - sb.append(""); + sb.append(""); sb.append("
" + manageHtmlIB(stereotype.getLabel(), FontParam.COMPONENT_STEREOTYPE) + "
" + manageHtmlIB(stereotype.getLabel(), FontParam.COMPONENT_STEREOTYPE, stereo) + + "
" + manageHtmlIB(entity.getDisplay(), FontParam.COMPONENT) + "
" + manageHtmlIB(entity.getDisplay(), FontParam.COMPONENT, stereo) + "
>"); return sb.toString(); } + private String getLabelForNoteDpi(IEntity entity) throws IOException { + final DrawFile file = entity.getImageFile(); + if (file == null) { + throw new IllegalStateException("No file for NOTE"); + } + if (file.getPngOrEps(fileFormat == FileFormat.EPS).exists() == false) { + throw new IllegalStateException(); + } + final String absolutePath = StringUtils.getPlateformDependentAbsolutePath(file + .getPngOrEps(fileFormat == FileFormat.EPS)); + + final StringBuilder sb = new StringBuilder("<"); + sb.append(""); + addTdImageBugB1983(sb, absolutePath); + sb.append(""); + sb.append("
>"); + return sb.toString(); + } + + private void addTdImageBugB1983(final StringBuilder sb, final String absolutePath) throws IOException { + // http://www.graphviz.org/bugs/b1983.html + final BufferedImage im = ImageIO.read(new File(absolutePath)); + final int height = im.getHeight(); + final int width = im.getWidth(); + final double f = 1.0 / data.getDpiFactor(); + final int w = (int) (width * f); + final int h = (int) (height * f); + final int w2 = (int) (width * getMagicFactorForImageDpi()); + final int h2 = (int) (height * getMagicFactorForImageDpi()); + sb.append(getTdHeaderForDpi(w, h)); + sb.append(""); + sb.append(""); + sb.append(getTdHeaderForDpi(w2, h2)); + sb.append(""); + sb.append(""); + sb.append(""); + sb.append("
"); + sb.append(""); + } + + private double getMagicFactorForImageDpi() { + return 10500 / 100000.0; + } + private String getLabelForActor(IEntity entity) throws IOException { - final String actorAbsolutePath = StringUtils.getPlateformDependentAbsolutePath(data.getStaticImages().get( - EntityType.ACTOR).getPngOrEps(fileFormat == FileFormat.EPS)); + final String actorAbsolutePath = StringUtils.getPlateformDependentAbsolutePath(entity.getImageFile() + .getPngOrEps(fileFormat == FileFormat.EPS)); final Stereotype stereotype = getStereotype(entity); + final String stereo = entity.getStereotype() == null ? null : entity.getStereotype().getLabel(); final StringBuilder sb = new StringBuilder("<"); if (isThereLabel(stereotype)) { - sb.append(""); } - sb.append(""); - sb.append(""); + if (data.getDpi() == 96) { + sb.append(""); + } else { + sb.append(""); + addTdImageBugB1983(sb, actorAbsolutePath); + sb.append(""); + } + sb.append(""); sb.append("
" + manageHtmlIB(stereotype.getLabel(), FontParam.USECASE_ACTOR_STEREOTYPE) + sb.append("
" + manageHtmlIB(stereotype.getLabel(), FontParam.USECASE_ACTOR_STEREOTYPE, stereo) + "
" + manageHtmlIB(entity.getDisplay(), FontParam.USECASE_ACTOR) + "
" + manageHtmlIB(entity.getDisplay(), FontParam.USECASE_ACTOR, stereo) + "
>"); return sb.toString(); } private String getLabelForCircleInterface(IEntity entity) throws IOException { - final String circleInterfaceAbsolutePath = StringUtils.getPlateformDependentAbsolutePath(data.getStaticImages() - .get(EntityType.CIRCLE_INTERFACE).getPngOrEps(fileFormat == FileFormat.EPS)); + final String circleInterfaceAbsolutePath = StringUtils.getPlateformDependentAbsolutePath(entity.getImageFile() + .getPngOrEps(fileFormat == FileFormat.EPS)); final Stereotype stereotype = getStereotype(entity); + final String stereo = entity.getStereotype() == null ? null : entity.getStereotype().getLabel(); final StringBuilder sb = new StringBuilder("<"); if (isThereLabel(stereotype)) { - sb.append(""); + sb.append(""); } - sb.append(""); - sb.append(""); + sb.append(""); + if (data.getDpi() == 96) { + sb.append(""); + } else { + addTdImageBugB1983(sb, circleInterfaceAbsolutePath); + } + sb.append(""); + sb.append(""); sb.append("
" + manageHtmlIB(stereotype.getLabel(), FontParam.COMPONENT_STEREOTYPE) + "
" + manageHtmlIB(stereotype.getLabel(), FontParam.COMPONENT_STEREOTYPE, stereo) + + "
" + manageHtmlIB(entity.getDisplay(), FontParam.COMPONENT) + "
" + manageHtmlIB(entity.getDisplay(), FontParam.COMPONENT, stereo) + "
>"); return sb.toString(); } private String getLabelForLollipop(IEntity entity) throws IOException { - final String circleInterfaceAbsolutePath = StringUtils.getPlateformDependentAbsolutePath(data.getStaticImages() - .get(EntityType.LOLLIPOP).getPngOrEps(fileFormat == FileFormat.EPS)); + final String stereo = entity.getStereotype() == null ? null : entity.getStereotype().getLabel(); + final String circleInterfaceAbsolutePath = StringUtils.getPlateformDependentAbsolutePath(data.getStaticImages( + EntityType.LOLLIPOP, stereo).getPngOrEps(fileFormat == FileFormat.EPS)); final Stereotype stereotype = getStereotype(entity); final StringBuilder sb = new StringBuilder("<"); if (isThereLabel(stereotype)) { - sb.append(""); + sb.append(""); } - sb.append(""); - sb.append(""); + sb.append(""); + if (data.getDpi() == 96) { + sb.append(""); + } else { + addTdImageBugB1983(sb, circleInterfaceAbsolutePath); + } + sb.append(""); + sb.append(""); sb.append("
" + manageHtmlIB(stereotype.getLabel(), FontParam.CLASS) + "
" + manageHtmlIB(stereotype.getLabel(), FontParam.CLASS, null) + "
" + manageHtmlIB(entity.getDisplay(), FontParam.CLASS) + "
" + manageHtmlIB(entity.getDisplay(), FontParam.CLASS, null) + "
>"); return sb.toString(); @@ -1038,7 +1172,8 @@ final public class DotMaker implements GraphvizMaker { private String getLabelForClassOrInterfaceOrEnumOld(IEntity entity) throws IOException { DrawFile cFile = entity.getImageFile(); if (cFile == null) { - cFile = data.getStaticImages().get(entity.getType()); + final String stereo = entity.getStereotype() == null ? null : entity.getStereotype().getLabel(); + cFile = data.getStaticImages(entity.getType(), stereo); } if (cFile == null) { throw new IllegalStateException(); @@ -1056,10 +1191,12 @@ final public class DotMaker implements GraphvizMaker { final boolean showFields = data.showPortion(EntityPortion.FIELD, entity); final boolean showMethods = data.showPortion(EntityPortion.METHOD, entity); + final String stereo = entity.getStereotype() == null ? null : entity.getStereotype().getLabel(); + if (showFields == false && showMethods == false) { sb.append(getHtmlHeaderTableForObjectOrClassOrInterfaceOrEnum(entity, circleAbsolutePath, 1, true, 1)); } else { - sb.append(""); sb.append(""); @@ -1091,8 +1228,8 @@ final public class DotMaker implements GraphvizMaker { final boolean hasStatic = hasStatic(entity.methods2()); sb.append(""); @@ -1119,10 +1256,10 @@ final public class DotMaker implements GraphvizMaker { } texts.add(s); } - final Font font = data.getSkinParam().getFont(FontParam.CLASS_ATTRIBUTE); - final Color color = getFontHtmlColor(FontParam.CLASS_ATTRIBUTE).getColor(); + final Font font = data.getSkinParam().getFont(FontParam.CLASS_ATTRIBUTE, null); + final Color color = getFontHtmlColor(FontParam.CLASS_ATTRIBUTE, null).getColor(); final TextBlock text = TextBlockUtils.create(texts, font, color, HorizontalAlignement.LEFT); - final File feps = CucaDiagramFileMaker.createTempFile("member", ".eps"); + final File feps = FileUtils.createTempFile("member", ".eps"); UGraphicEps.copyEpsToFile(new UDrawable() { public void drawU(UGraphic ug) { text.drawU(ug, 0, 0); @@ -1134,8 +1271,6 @@ final public class DotMaker implements GraphvizMaker { return ""; - // return ""; } private boolean hasStatic(Collection attributes) { @@ -1150,7 +1285,8 @@ final public class DotMaker implements GraphvizMaker { private String getLabelForClassOrInterfaceOrEnumWithVisibilityImage(IEntity entity) throws IOException { DrawFile cFile = entity.getImageFile(); if (cFile == null) { - cFile = data.getStaticImages().get(entity.getType()); + final String stereo = entity.getStereotype() == null ? null : entity.getStereotype().getLabel(); + cFile = data.getStaticImages(entity.getType(), stereo); } if (cFile == null) { throw new IllegalStateException(); @@ -1170,6 +1306,7 @@ final public class DotMaker implements GraphvizMaker { if (showFields == false && showMethods == false) { sb.append(getHtmlHeaderTableForObjectOrClassOrInterfaceOrEnum(entity, circleAbsolutePath, 1, true, 1)); } else { + final String stereo = entity.getStereotype() == null ? null : entity.getStereotype().getLabel(); final int longuestHeader = getLonguestHeader(entity); final int spring = computeSpring(longuestHeader, getLongestFieldOrAttribute(entity), 30); final int springField = computeSpring(getLongestField(entity), Math.max(longuestHeader, @@ -1177,7 +1314,7 @@ final public class DotMaker implements GraphvizMaker { final int springMethod = computeSpring(getLongestMethods(entity), Math.max(longuestHeader, getLongestField(entity)), 30); - sb.append("
"); final int longuestFieldOrAttribute = getLongestFieldOrAttribute(entity); @@ -1075,10 +1212,10 @@ final public class DotMaker implements GraphvizMaker { // sb.append(addFieldsEps(entity.fields2(), true)); // } else { final boolean hasStatic = hasStatic(entity.fields2()); - sb.append("
"); + sb.append("
"); for (Member att : entity.fields2()) { - sb.append(manageHtmlIBspecial(att, FontParam.CLASS_ATTRIBUTE, hasStatic, - getColorString(ColorParam.classBackground), true)); + sb.append(manageHtmlIBspecial(att, FontParam.CLASS_ATTRIBUTE, hasStatic, getColorString( + ColorParam.classBackground, stereo), true)); sb.append("
"); } sb.append("
"); for (Member att : entity.methods2()) { - sb.append(manageHtmlIBspecial(att, FontParam.CLASS_ATTRIBUTE, hasStatic, - getColorString(ColorParam.classBackground), true)); + sb.append(manageHtmlIBspecial(att, FontParam.CLASS_ATTRIBUTE, hasStatic, getColorString( + ColorParam.classBackground, stereo), true)); sb.append("
"); } sb.append("
" + "" + "" + "" + "
" + "
toto
"); sb.append(""); if (showFields) { - sb.append("
"); @@ -1185,7 +1322,7 @@ final public class DotMaker implements GraphvizMaker { sb.append("
"); + sb.append("
"); if (entity.fields2().size() > 0) { buildTableVisibility(entity, true, sb, springField); } @@ -1222,21 +1359,32 @@ final public class DotMaker implements GraphvizMaker { sb.append(""); final boolean hasStatic = hasStatic(entity.methods2()); + final boolean dpiNormal = data.getDpi() == 96; for (Member att : isField ? entity.fields2() : entity.methods2()) { - sb.append(""); + if (dpiNormal) { + sb.append(""); + } + sb.append(""); for (int i = 0; i < spring; i++) { sb.append(""); @@ -1299,17 +1447,20 @@ final public class DotMaker implements GraphvizMaker { final int springField = computeSpring(getLongestField(entity), Math.max(longuestHeader, getLongestMethods(entity)), 30); - final StringBuilder sb = new StringBuilder("<
"); + sb.append("
"); + } String s = att.getDisplayWithVisibilityChar(); final VisibilityModifier visibilityModifier = VisibilityModifier .getVisibilityModifier(s.charAt(0), isField); if (visibilityModifier != null) { - final String modifierFile = StringUtils.getPlateformDependentAbsolutePath(data.getVisibilityImages() - .get(visibilityModifier).getPngOrEps(fileFormat == FileFormat.EPS)); - sb.append(""); + final String stereo = entity.getStereotype() == null ? null : entity.getStereotype().getLabel(); + final String modifierFile = StringUtils.getPlateformDependentAbsolutePath(data.getVisibilityImages( + visibilityModifier, stereo).getPngOrEps(fileFormat == FileFormat.EPS)); + if (dpiNormal) { + sb.append(""); + } else { + addTdImageBugB1983(sb, modifierFile); + } s = s.substring(1); } - sb.append(""); - sb.append(manageHtmlIBspecial(att, FontParam.CLASS_ATTRIBUTE, hasStatic, - getColorString(ColorParam.classBackground), false)); - // sb.append(manageHtmlIB(s, FontParam.CLASS_ATTRIBUTE)); + if (dpiNormal) { + sb.append(""); + sb.append(manageHtmlIBspecial(att, FontParam.CLASS_ATTRIBUTE, hasStatic, getColorString( + ColorParam.classBackground, null), false)); sb.append("
"); sb.append(""); - sb.append("
"); sb.append(getHtmlHeaderTableForObjectOrClassOrInterfaceOrEnum(entity, null, spring, false, 0)); sb.append("
"); + sb.append("
"); if (entity.fields2().size() == 0) { - sb.append(manageHtmlIB(" ", FontParam.OBJECT_ATTRIBUTE)); + sb.append(manageHtmlIB(" ", FontParam.OBJECT_ATTRIBUTE, stereo)); } else { buildTableVisibility(entity, true, sb, springField); } @@ -1322,7 +1473,11 @@ final public class DotMaker implements GraphvizMaker { } private String getLabelForObjectOld(IEntity entity) throws IOException { - final StringBuilder sb = new StringBuilder("<"); sb.append(""); - sb.append("
"); @@ -1333,13 +1488,13 @@ final public class DotMaker implements GraphvizMaker { sb.append(getHtmlHeaderTableForObjectOrClassOrInterfaceOrEnum(entity, null, spring, false, 0)); sb.append("
"); + sb.append("
"); if (entity.fields2().size() == 0) { - sb.append(manageHtmlIB(" ", FontParam.OBJECT_ATTRIBUTE)); + sb.append(manageHtmlIB(" ", FontParam.OBJECT_ATTRIBUTE, stereo)); } else { for (Member att : entity.fields2()) { - sb.append(manageHtmlIB(att.getDisplayWithVisibilityChar(), FontParam.OBJECT_ATTRIBUTE)); + sb.append(manageHtmlIB(att.getDisplayWithVisibilityChar(), FontParam.OBJECT_ATTRIBUTE, stereo)); sb.append("
"); } } @@ -1350,13 +1505,20 @@ final public class DotMaker implements GraphvizMaker { return sb.toString(); } - private String manageHtmlIB(String s, FontParam param) { + private String getWitdh55() { + if (data.getDpi() == 96) { + return "WIDTH=\"55\""; + } + return "WIDTH=\"55\""; + } + + private String manageHtmlIB(String s, FontParam param, String stereotype) { s = unicode(s); - final int fontSize = data.getSkinParam().getFontSize(param); - final int style = data.getSkinParam().getFontStyle(param); - final String fontFamily = data.getSkinParam().getFontFamily(param); - final DotExpression dotExpression = new DotExpression(s, fontSize, getFontHtmlColor(param), fontFamily, style, - fileFormat); + final int fontSize = data.getSkinParam().getFontSize(param, stereotype); + final int style = data.getSkinParam().getFontStyle(param, stereotype); + final String fontFamily = data.getSkinParam().getFontFamily(param, stereotype); + final DotExpression dotExpression = new DotExpression(s, fontSize, getFontHtmlColor(param, stereotype), + fontFamily, style, fileFormat); final String result = dotExpression.getDotHtml(); if (dotExpression.isUnderline()) { underline = true; @@ -1371,12 +1533,12 @@ final public class DotMaker implements GraphvizMaker { prefix = "_"; } if (att.isAbstract()) { - return prefix + manageHtmlIB("" + att.getDisplay(withVisibilityChar), param); + return prefix + manageHtmlIB("" + att.getDisplay(withVisibilityChar), param, null); } if (att.isStatic()) { - return manageHtmlIB("" + att.getDisplay(withVisibilityChar), param); + return manageHtmlIB("" + att.getDisplay(withVisibilityChar), param, null); } - return prefix + manageHtmlIB(att.getDisplay(withVisibilityChar), param); + return prefix + manageHtmlIB(att.getDisplay(withVisibilityChar), param, null); } private String manageSpace(int size) { @@ -1400,15 +1562,20 @@ final public class DotMaker implements GraphvizMaker { } private String getHtmlHeaderTableForObjectOrClassOrInterfaceOrEnumNoSpring(IEntity entity, - final String circleAbsolutePath, int cellSpacing, boolean classes) { + final String circleAbsolutePath, int cellSpacing, boolean classes) throws IOException { final StringBuilder sb = new StringBuilder(); sb.append(""); sb.append(""); if (circleAbsolutePath == null) { sb.append(""); + if (data.getDpi() == 96) { + sb.append(""); + } else { + addTdImageBugB1983(sb, circleAbsolutePath); + + } sb.append(""); + if (data.getDpi() == 96) { + final BufferedImage im = ImageIO.read(new File(circleAbsolutePath)); + final int height = im.getHeight(); + final int width = im.getWidth(); + sb.append(""); + } else { + addTdImageBugB1983(sb, circleAbsolutePath); + } } else if (circleAbsolutePath.endsWith(".eps")) { sb.append(""); } @@ -1458,10 +1635,11 @@ final public class DotMaker implements GraphvizMaker { private void appendLabelAndStereotype(IEntity entity, final StringBuilder sb, boolean classes) { final Stereotype stereotype = getStereotype(entity); + final String stereo = entity.getStereotype() == null ? null : entity.getStereotype().getLabel(); if (isThereLabel(stereotype)) { sb.append("
"); sb.append(manageHtmlIB(stereotype.getLabel(), classes ? FontParam.CLASS_STEREOTYPE - : FontParam.OBJECT_STEREOTYPE)); + : FontParam.OBJECT_STEREOTYPE, stereo)); sb.append("
"); } String display = entity.getDisplay(); @@ -1470,7 +1648,7 @@ final public class DotMaker implements GraphvizMaker { if (italic) { display = "" + display; } - sb.append(manageHtmlIB(display, classes ? FontParam.CLASS : FontParam.OBJECT)); + sb.append(manageHtmlIB(display, classes ? FontParam.CLASS : FontParam.OBJECT, stereo)); } private String getHtmlHeaderTableForClassOrInterfaceOrEnumNew(Entity entity, final String circleAbsolutePath) { diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/DotMaker2.java b/src/net/sourceforge/plantuml/cucadiagram/dot/DotMaker2.java deleted file mode 100644 index 51fa95412..000000000 --- a/src/net/sourceforge/plantuml/cucadiagram/dot/DotMaker2.java +++ /dev/null @@ -1,1498 +0,0 @@ -/* ======================================================================== - * PlantUML : a free UML diagram generator - * ======================================================================== - * - * (C) Copyright 2009, 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 Lesser 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: 5383 $ - * - */ -package net.sourceforge.plantuml.cucadiagram.dot; - -import java.awt.Font; -import java.awt.image.BufferedImage; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import javax.imageio.ImageIO; - -import net.sourceforge.plantuml.ColorParam; -import net.sourceforge.plantuml.FileFormat; -import net.sourceforge.plantuml.FontParam; -import net.sourceforge.plantuml.OptionFlags; -import net.sourceforge.plantuml.SignatureUtils; -import net.sourceforge.plantuml.StringUtils; -import net.sourceforge.plantuml.UmlDiagramType; -import net.sourceforge.plantuml.cucadiagram.Entity; -import net.sourceforge.plantuml.cucadiagram.EntityPortion; -import net.sourceforge.plantuml.cucadiagram.EntityType; -import net.sourceforge.plantuml.cucadiagram.Group; -import net.sourceforge.plantuml.cucadiagram.GroupType; -import net.sourceforge.plantuml.cucadiagram.IEntity; -import net.sourceforge.plantuml.cucadiagram.Link; -import net.sourceforge.plantuml.cucadiagram.Member; -import net.sourceforge.plantuml.cucadiagram.Rankdir; -import net.sourceforge.plantuml.cucadiagram.Stereotype; -import net.sourceforge.plantuml.graphic.HtmlColor; -import net.sourceforge.plantuml.skin.VisibilityModifier; -import net.sourceforge.plantuml.skin.rose.Rose; - -final public class DotMaker2 implements GraphvizMaker { - - private final DotData data; - - private static boolean isJunit = false; - - private final List dotStrings; - private boolean underline = false; - private final Rose rose = new Rose(); - - private static String lastDotSignature; - - private final FileFormat fileFormat; - - private final boolean isVisibilityModifierPresent; - - public static void goJunit() { - isJunit = true; - } - - public DotMaker2(DotData data, List dotStrings, FileFormat fileFormat) { - this.data = data; - this.dotStrings = dotStrings; - this.fileFormat = fileFormat; - if (data.getSkinParam().classAttributeIconSize() > 0) { - this.isVisibilityModifierPresent = data.getVisibilityImages().size() > 0; - } else { - this.isVisibilityModifierPresent = false; - } - } - - public String createDotString() throws IOException { - - final StringBuilder sb = new StringBuilder(); - - initPrintWriter(sb); - printGroups(sb, null); - printEntities(sb, getUnpackagedEntities()); - printLinks(sb, data.getLinks()); - sb.append("}"); - - // System.err.println(sb); - if (isJunit) { - lastDotSignature = SignatureUtils.getSignatureWithoutImgSrc(sb.toString()); - } - return sb.toString(); - } - - private void initPrintWriter(StringBuilder sb) { - - sb.append("digraph unix {"); - if (isJunit == false) { - for (String s : dotStrings) { - sb.append(s); - } - } - sb.append("bgcolor=\"" + data.getSkinParam().getBackgroundColor().getAsHtml() + "\";"); - sb.append("ratio=auto;"); - sb.append("compound=true;"); - sb.append("remincross=true;"); - // sb.append("concentrate=true;"); - // pw.println("size=\"40,40;\""); - sb.append("searchsize=500;"); - if (data.getRankdir() == Rankdir.LEFT_TO_RIGHT) { - sb.append("rankdir=LR;"); - } - } - - private Collection getUnpackagedEntities() { - final List result = new ArrayList(); - for (IEntity ent : data.getEntities().values()) { - if (ent.getParent() == data.getTopParent()) { - result.add(ent); - } - } - return result; - } - - private void printGroups(StringBuilder sb, Group parent) throws IOException { - for (Group g : data.getGroupHierarchy().getChildrenGroups(parent)) { - if (data.isEmpty(g) && g.getType() == GroupType.PACKAGE) { - final IEntity folder = new Entity(g.getUid(), g.getCode(), g.getDisplay(), EntityType.EMPTY_PACKAGE, - null); - printEntity(sb, folder); - } else { - printGroup(sb, g); - } - } - } - - private void printGroup(StringBuilder sb, Group g) throws IOException { - if (g.getType() == GroupType.CONCURRENT_STATE) { - return; - } - - if (isSpecialGroup(g)) { - printGroupSpecial(sb, g); - } else { - printGroupNormal(sb, g); - } - } - - private void printGroupNormal(StringBuilder sb, Group g) throws IOException { - - sb.append("subgraph " + g.getUid() + " {"); - // sb.append("margin=10;"); - - sb.append("fontsize=\"" + data.getSkinParam().getFontSize(getFontParamForGroup()) + "\";"); - final String fontFamily = data.getSkinParam().getFontFamily(getFontParamForGroup()); - if (fontFamily != null) { - sb.append("fontname=\"" + fontFamily + "\";"); - } - - if (g.getDisplay() != null) { - sb.append("label=<" + manageHtmlIB(g.getDisplay(), getFontParamForGroup()) + ">;"); - } - final String fontColor = data.getSkinParam().getFontHtmlColor(getFontParamForGroup()).getAsHtml(); - sb.append("fontcolor=\"" + fontColor + "\";"); - if (getGroupBackColor(g) != null) { - sb.append("fillcolor=\"" + getGroupBackColor(g).getAsHtml() + "\";"); - } - if (g.getType() == GroupType.STATE) { - sb.append("color=" + getColorString(ColorParam.stateBorder) + ";"); - } else { - sb.append("color=" + getColorString(ColorParam.packageBorder) + ";"); - } - sb.append("style=\"" + getStyle(g) + "\";"); - - printGroups(sb, g); - - this.printEntities(sb, g.entities().values()); - for (Link link : data.getLinks()) { - eventuallySameRank(sb, g, link); - } - sb.append("}"); - } - - private HtmlColor getGroupBackColor(Group g) { - HtmlColor value = g.getBackColor(); - if (value == null) { - value = data.getSkinParam().getHtmlColor(ColorParam.packageBackground); - // value = rose.getHtmlColor(this.data.getSkinParam(), - // ColorParam.packageBackground); - } - return value; - } - - private void printGroupSpecial(StringBuilder sb, Group g) throws IOException { - - sb.append("subgraph " + g.getUid() + "a {"); - if (OptionFlags.getInstance().isDebugDot()) { - sb.append("style=dotted;"); - sb.append("label=\"a\";"); - } else { - sb.append("style=invis;"); - sb.append("label=\"\";"); - } - - sb.append("subgraph " + g.getUid() + "v {"); - sb.append("style=solid;"); - // sb.append("margin=10;"); - - final List autolinks = data.getAutoLinks(g); - final List toEdgeLinks = data.getToEdgeLinks(g); - final List fromEdgeLinks = data.getFromEdgeLinks(g); - final boolean autoLabel = autolinks.size() == 1; - - final List nodesHiddenUidOut = getNodesHiddenUidOut(g); - final List nodesHiddenUidIn = getNodesHiddenUidIn(g); - final List nodesHiddenUid = new ArrayList(nodesHiddenUidOut); - nodesHiddenUid.addAll(nodesHiddenUidIn); - for (Link link : nodesHiddenUid) { - final String uid = getHiddenNodeUid(g, link); - // sb.append("subgraph " + g.getUid() + "k" + uid + " {"); - if (OptionFlags.getInstance().isDebugDot()) { - sb.append("style=dotted;"); - sb.append("label=\"k" + uid + "\";"); - } else { - sb.append("style=invis;"); - sb.append("label=\"\";"); - } - if (OptionFlags.getInstance().isDebugDot()) { - sb.append(uid + ";"); - } else { - sb.append(uid + " [shape=point,width=.01,style=invis,label=\"\"];"); - } - // sb.append("}"); // end of k - } - - for (int j = 1; j < nodesHiddenUidOut.size(); j++) { - for (int i = 0; i < j; i++) { - final Link linki = nodesHiddenUidOut.get(i); - final Link linkj = nodesHiddenUidOut.get(j); - if (linki.getEntity2() != linkj.getEntity2()) { - continue; - } - final String uidi = getHiddenNodeUid(g, linki); - final String uidj = getHiddenNodeUid(g, linkj); - if (OptionFlags.getInstance().isDebugDot()) { - sb.append(uidi + "->" + uidj + ";"); - } else { - sb.append(uidi + "->" + uidj + " [style=invis,arrowtail=none,arrowhead=none];"); - } - - } - } - - if (autoLabel /* || toEdgeLinks.size() > 0 || fromEdgeLinks.size() > 0 */) { - if (OptionFlags.getInstance().isDebugDot()) { - sb.append(g.getUid() + "lmin;"); - sb.append(g.getUid() + "lmax;"); - sb.append(g.getUid() + "lmin->" + g.getUid() + "lmax [minlen=2]; "); - } else { - sb.append(g.getUid() + "lmin [shape=point,width=.01,style=invis,label=\"\"];"); - sb.append(g.getUid() + "lmax [shape=point,width=.01,style=invis,label=\"\"];"); - sb.append(g.getUid() + "lmin->" + g.getUid() - + "lmax [minlen=2,style=invis,arrowtail=none,arrowhead=none]; "); - } - } - // sb.append(g.getUid() + "min->" + g.getUid() + "max;"); - - sb.append("fontsize=\"" + data.getSkinParam().getFontSize(getFontParamForGroup()) + "\";"); - final String fontFamily = data.getSkinParam().getFontFamily(getFontParamForGroup()); - if (fontFamily != null) { - sb.append("fontname=\"" + fontFamily + "\";"); - } - - if (g.getDisplay() != null) { - final StringBuilder label = new StringBuilder(manageHtmlIB(g.getDisplay(), getFontParamForGroup())); - if (g.getEntityCluster().fields2().size() > 0) { - label.append("
"); - for (Member att : g.getEntityCluster().fields2()) { - label.append(manageHtmlIB(" " + att.getDisplayWithVisibilityChar() + " ", - FontParam.STATE_ATTRIBUTE)); - label.append("
"); - } - } - sb.append("label=<" + label + ">;"); - } - - final String fontColor = data.getSkinParam().getFontHtmlColor(getFontParamForGroup()).getAsHtml(); - sb.append("fontcolor=\"" + fontColor + "\";"); - if (getGroupBackColor(g) != null) { - sb.append("fillcolor=\"" + getGroupBackColor(g).getAsHtml() + "\";"); - } - if (g.getType() == GroupType.STATE) { - sb.append("color=" + getColorString(ColorParam.stateBorder) + ";"); - } else { - sb.append("color=" + getColorString(ColorParam.packageBorder) + ";"); - } - sb.append("style=\"" + getStyle(g) + "\";"); - - sb.append("subgraph " + g.getUid() + "i {"); - sb.append("label=\"i\";"); - if (OptionFlags.getInstance().isDebugDot()) { - sb.append("style=dotted;"); - sb.append("label=\"i\";"); - } else { - sb.append("style=invis;"); - sb.append("label=\"\";"); - } - - printGroups(sb, g); - - this.printEntities(sb, g.entities().values()); - for (Link link : data.getLinks()) { - eventuallySameRank(sb, g, link); - } - - for (int i = 0; i < fromEdgeLinks.size(); i++) { - if (OptionFlags.getInstance().isDebugDot()) { - sb.append("eds" + i + ";"); - } else { - sb.append("eds" + i + " [shape=point,width=.01,style=invis,label=\"\"];"); - } - sb.append("eds" + i + " ->" + fromEdgeLinks.get(i).getEntity2().getUid() - + " [minlen=2,style=invis,arrowtail=none,arrowhead=none]; "); - - } - - sb.append("}"); // end of i - sb.append("}"); // end of v - - if (autoLabel) { - sb.append("subgraph " + g.getUid() + "l {"); - if (OptionFlags.getInstance().isDebugDot()) { - sb.append("style=dotted;"); - sb.append("label=\"l\";"); - } else { - sb.append("style=invis;"); - sb.append("label=\"\";"); - } - final String decorationColor = ",color=" + getColorString(getArrowColorParam()); - - sb.append(g.getUid() + "lab0 [shape=point,width=.01,label=\"\"" + decorationColor + "]"); - String autolabel = autolinks.get(0).getLabel(); - if (autolabel == null) { - autolabel = ""; - } - sb.append(g.getUid() + "lab1 [label=<" + manageHtmlIB(autolabel, getArrowFontParam()) - + ">,shape=plaintext,margin=0];"); - sb.append(g.getUid() + "lab0 -> " + g.getUid() + "lab1 [minlen=0,style=invis];"); - sb.append("}"); // end of l - - sb.append(g.getUid() + "lmin -> " + g.getUid() + "lab0 [ltail=" + g.getUid() - + "v,arrowtail=none,arrowhead=none" + decorationColor + "];"); - sb.append(g.getUid() + "lab0 -> " + g.getUid() + "lmax [lhead=" + g.getUid() - + "v,arrowtail=none,arrowhead=open" + decorationColor + "];"); - } - - for (int i = 0; i < fromEdgeLinks.size(); i++) { - sb.append("subgraph " + g.getUid() + "ed" + i + " {"); - if (OptionFlags.getInstance().isDebugDot()) { - sb.append("style=dotted;"); - sb.append("label=\"ed" + i + "\";"); - } else { - sb.append("style=invis;"); - sb.append("label=\"\";"); - } - final String decorationColor = ",color=" + getColorString(getArrowColorParam()); - String label = fromEdgeLinks.get(i).getLabel(); - if (label == null) { - label = ""; - } - - sb.append(g.getUid() + "fedge" + i + " [shape=point,width=.01,label=\"\"" + decorationColor + "]"); - sb.append("}"); // end of ed - sb.append("eds" + i + " -> " + g.getUid() + "fedge" + i + " [ltail=" + g.getUid() - + "v,arrowtail=none,arrowhead=none" + decorationColor + "];"); - sb.append(g.getUid() + "fedge" + i + " -> " + fromEdgeLinks.get(i).getEntity2().getUid() - + "[arrowtail=none,arrowhead=open" + decorationColor); - sb.append(",label=<" + manageHtmlIB(label, getArrowFontParam()) + ">];"); - - } - sb.append("}"); // end of a - } - - private FontParam getFontParamForGroup() { - if (data.getUmlDiagramType() == UmlDiagramType.STATE) { - return FontParam.STATE; - } - return FontParam.PACKAGE; - } - - private String getStyle(Group g) { - final StringBuilder sb = new StringBuilder(); - if (g.isBold()) { - sb.append("bold"); - } else if (g.isDashed()) { - sb.append("dashed"); - } else { - sb.append("solid"); - - } - if (getGroupBackColor(g) != null) { - sb.append(",filled"); - } - if (g.isRounded()) { - sb.append(",rounded"); - } - return sb.toString(); - } - - private void printLinks(StringBuilder sb, List links) throws IOException { - for (Link link : appendPhantomLink(links)) { - final IEntity entity1 = link.getEntity1(); - final IEntity entity2 = link.getEntity2(); - if (entity1 == entity2 && entity1.getType() == EntityType.GROUP) { - continue; - } - if (entity1.getType() == EntityType.GROUP && entity2.getParent() == entity1.getParent()) { - continue; - } - if (entity2.getType() == EntityType.GROUP && entity1.getParent() == entity2.getParent()) { - continue; - } - if (entity1.getType() == EntityType.LOLLIPOP || entity2.getType() == EntityType.LOLLIPOP) { - continue; - } - // System.err.println("outing " + link); - printLink(sb, link); - } - } - - private void printLink(StringBuilder sb, Link link) throws IOException { - final StringBuilder decoration = getLinkDecoration(); - - if (link.getWeight() > 1) { - decoration.append("weight=" + link.getWeight() + ","); - } - if (link.getLabeldistance() != null) { - decoration.append("labeldistance=" + link.getLabeldistance() + ","); - } - if (link.getLabelangle() != null) { - decoration.append("labelangle=" + link.getLabelangle() + ","); - } - - final DrawFile noteLink = link.getImageFile(); - - if (link.getLabel() != null) { - decoration.append("label=<" + manageHtmlIB(link.getLabel(), getArrowFontParam()) + ">,"); - } else if (noteLink != null) { - decoration - .append("label=<" + getHtmlForLinkNote(noteLink.getPngOrEps(fileFormat == FileFormat.EPS)) + ">,"); - } - - if (link.getQualifier1() != null) { - decoration.append("taillabel=<" + manageHtmlIB(link.getQualifier1(), getArrowFontParam()) + ">,"); - } - if (link.getQualifier2() != null) { - decoration.append("headlabel=<" + manageHtmlIB(link.getQualifier2(), getArrowFontParam()) + ">,"); - } - decoration.append(link.getType().getSpecificDecoration()); - if (link.isInvis()) { - decoration.append(",style=invis"); - } - - final int len = link.getLength(); - final String lenString = len >= 3 ? ",minlen=" + (len - 1) : ""; - - String uid1 = link.getEntity1().getUid(); - String uid2 = link.getEntity2().getUid(); - if (link.getEntity1().getType() == EntityType.GROUP) { - uid1 = getHiddenNodeUid(link.getEntity1().getParent(), link); - decoration.append(",ltail=" + link.getEntity1().getParent().getUid() + "v"); - } - if (link.getEntity2().getType() == EntityType.GROUP) { - uid2 = getHiddenNodeUid(link.getEntity2().getParent(), link); - decoration.append(",lhead=" + link.getEntity2().getParent().getUid() + "v"); - } - - sb.append(uid1 + " -> " + uid2); - sb.append(decoration); - sb.append(lenString + "];"); - eventuallySameRank(sb, data.getTopParent(), link); - } - - private List getNodesHiddenUidOut(Group g) { - final List result = new ArrayList(); - for (Link link : data.getLinks()) { - if (link.getEntity1().getParent() == link.getEntity2().getParent()) { - continue; - } - if (link.getEntity1().getType() == EntityType.GROUP && link.getEntity1().getParent() == g) { - result.add(link); - } - } - return Collections.unmodifiableList(result); - } - - private List getNodesHiddenUidIn(Group g) { - final List result = new ArrayList(); - for (Link link : data.getLinks()) { - if (link.getEntity1().getParent() == link.getEntity2().getParent()) { - continue; - } - if (link.getEntity2().getType() == EntityType.GROUP && link.getEntity2().getParent() == g) { - result.add(link); - } - } - return Collections.unmodifiableList(result); - } - - private String getHiddenNodeUid(Group g, Link link) { - if (data.isEmpty(g) && g.getType() == GroupType.PACKAGE) { - return g.getUid(); - } - return g.getUid() + "_" + link.getUid(); - } - - private StringBuilder getLinkDecoration() { - final StringBuilder decoration = new StringBuilder("[color=" + getColorString(getArrowColorParam()) + ","); - - decoration.append("fontcolor=" + getFontColorString(getArrowFontParam()) + ","); - decoration.append("fontsize=\"" + data.getSkinParam().getFontSize(getArrowFontParam()) + "\","); - - final String fontName = data.getSkinParam().getFontFamily(getArrowFontParam()); - if (fontName != null) { - decoration.append("fontname=\"" + fontName + "\","); - } - return decoration; - } - - private List appendPhantomLink(List links) { - final List result = new ArrayList(links); - for (Link link : links) { - if (link.getLength() != 1) { - continue; - } - final DrawFile noteLink = link.getImageFile(); - if (noteLink == null) { - continue; - } - final Link phantom = new Link(link.getEntity1(), link.getEntity2(), link.getType(), "", link.getLength()); - phantom.setInvis(true); - result.add(phantom); - } - return result; - } - - private String getHtmlForLinkNote(File image) { - final String circleInterfaceAbsolutePath = StringUtils.getPlateformDependentAbsolutePath(image); - final StringBuilder sb = new StringBuilder("
"); } else { - sb.append(""); - sb.append(""); + sb.append(""); } @@ -1417,6 +1584,12 @@ final public class DotMaker implements GraphvizMaker { return sb.toString(); } + private String getTdHeaderForDpi(final double w, final double h) { + // return ""; + return ""; + } + private String getHtmlHeaderTableForObjectOrClassOrInterfaceOrEnum(IEntity entity, final String circleAbsolutePath, int spring, boolean classes, int border) throws IOException { if (spring == 0) { @@ -1435,11 +1608,15 @@ final public class DotMaker implements GraphvizMaker { if (circleAbsolutePath != null) { if (circleAbsolutePath.endsWith(".png")) { - final BufferedImage im = ImageIO.read(new File(circleAbsolutePath)); - final int height = im.getHeight(); - final int width = im.getWidth(); - sb.append("
"); - sb.append(""); - sb.append("
"); - return sb.toString(); - - } - - private FontParam getArrowFontParam() { - if (data.getUmlDiagramType() == UmlDiagramType.CLASS) { - return FontParam.CLASS_ARROW; - } else if (data.getUmlDiagramType() == UmlDiagramType.OBJECT) { - return FontParam.OBJECT_ARROW; - } else if (data.getUmlDiagramType() == UmlDiagramType.USECASE) { - return FontParam.USECASE_ARROW; - } else if (data.getUmlDiagramType() == UmlDiagramType.ACTIVITY) { - return FontParam.ACTIVITY_ARROW; - } else if (data.getUmlDiagramType() == UmlDiagramType.COMPONENT) { - return FontParam.COMPONENT_ARROW; - } else if (data.getUmlDiagramType() == UmlDiagramType.STATE) { - return FontParam.STATE_ARROW; - } - throw new IllegalStateException(); - } - - private ColorParam getArrowColorParam() { - if (data.getUmlDiagramType() == UmlDiagramType.CLASS) { - return ColorParam.classArrow; - } else if (data.getUmlDiagramType() == UmlDiagramType.OBJECT) { - return ColorParam.objectArrow; - } else if (data.getUmlDiagramType() == UmlDiagramType.USECASE) { - return ColorParam.usecaseArrow; - } else if (data.getUmlDiagramType() == UmlDiagramType.ACTIVITY) { - return ColorParam.activityArrow; - } else if (data.getUmlDiagramType() == UmlDiagramType.COMPONENT) { - return ColorParam.componentArrow; - } else if (data.getUmlDiagramType() == UmlDiagramType.STATE) { - return ColorParam.stateArrow; - } - throw new IllegalStateException(); - } - - private String getColorString(ColorParam colorParam) { - return "\"" + rose.getHtmlColor(data.getSkinParam(), colorParam).getAsHtml() + "\""; - } - - private String getFontColorString(FontParam fontParam) { - return "\"" + getFontHtmlColor(fontParam).getAsHtml() + "\""; - } - - private HtmlColor getFontHtmlColor(FontParam fontParam) { - return data.getSkinParam().getFontHtmlColor(fontParam); - } - - private void eventuallySameRank(StringBuilder sb, Group entityPackage, Link link) { - if (workAroundDotBug()) { - return; - } - final int len = link.getLength(); - if (len == 1 && link.getEntity1().getParent() == entityPackage - && link.getEntity2().getParent() == entityPackage) { - if (link.getEntity1().getType() == EntityType.GROUP) { - throw new IllegalArgumentException(); - } - if (link.getEntity2().getType() == EntityType.GROUP) { - throw new IllegalArgumentException(); - } - sb.append("{rank=same; " + link.getEntity1().getUid() + "; " + link.getEntity2().getUid() + "}"); - } - } - - private void printEntities(StringBuilder sb, Collection entities) throws IOException { - final Set lollipops = new HashSet(); - final Set lollipopsFriends = new HashSet(); - for (IEntity entity : entities) { - if (entity.getType() == EntityType.LOLLIPOP) { - lollipops.add(entity); - lollipopsFriends.add(getConnectedToLollipop(entity)); - } - } - for (IEntity entity : entities) { - if (lollipops.contains(entity) || lollipopsFriends.contains(entity)) { - continue; - } - printEntity(sb, entity); - } - - for (IEntity ent : lollipopsFriends) { - sb.append("subgraph cluster" + ent.getUid() + "lol {"); - sb.append("style=invis;"); - sb.append("label=\"\";"); - printEntity(sb, ent); - for (IEntity lollipop : getAllLollipop(ent)) { - final Link link = getLinkLollipop(lollipop, ent); - final String headOrTail = getHeadOrTail(lollipop, link); - printEntity(sb, lollipop, headOrTail); - printLink(sb, link); - } - sb.append("}"); - } - - } - - private Collection getAllLollipop(IEntity entity) { - final Collection result = new ArrayList(); - for (IEntity lollipop : data.getAllLinkedDirectedTo(entity)) { - if (lollipop.getType() == EntityType.LOLLIPOP) { - result.add(lollipop); - } - } - return result; - } - - private IEntity getConnectedToLollipop(IEntity lollipop) { - assert lollipop.getType() == EntityType.LOLLIPOP; - final Collection linked = data.getAllLinkedDirectedTo(lollipop); - if (linked.size() != 1) { - throw new IllegalStateException("size=" + linked.size()); - } - return linked.iterator().next(); - } - - private Link getLinkLollipop(IEntity lollipop, IEntity ent) { - assert lollipop.getType() == EntityType.LOLLIPOP; - for (Link link : data.getLinks()) { - if (link.isBetween(lollipop, ent)) { - return link; - } - } - throw new IllegalArgumentException(); - } - - private void printEntity(StringBuilder sb, IEntity entity, String headOrTail) throws IOException { - final EntityType type = entity.getType(); - if (type == EntityType.LOLLIPOP) { - final String color1 = getColorString(ColorParam.classBackground); - final String color2 = getColorString(ColorParam.classBorder); - final String colorBack = getColorString(ColorParam.background); - final String labelLo = manageHtmlIB(entity.getDisplay(), FontParam.CLASS_ATTRIBUTE); - sb.append(entity.getUid() + " [fillcolor=" + color1 + ",color=" + color2 + ",style=\"filled\"," - + "shape=circle,width=0.12,height=0.12,label=\"\"];"); - sb.append(entity.getUid() + " -> " + entity.getUid() + "[color=" + colorBack - + ",arrowtail=none,arrowhead=none," + headOrTail + "=<" + labelLo + ">];"); - } else { - throw new IllegalStateException(type.toString() + " " + data.getUmlDiagramType()); - } - - } - - private void printEntity(StringBuilder sb, IEntity entity) throws IOException { - final EntityType type = entity.getType(); - final String label = getLabel(entity); - if (type == EntityType.GROUP) { - return; - } - if (type == EntityType.ABSTRACT_CLASS || type == EntityType.CLASS || type == EntityType.INTERFACE - || type == EntityType.ENUM) { - String dec = " [fontcolor=" + getFontColorString(FontParam.CLASS) + ",margin=0,fillcolor=" - + getColorString(ColorParam.classBackground) + ",color=" + getColorString(ColorParam.classBorder) - + ",style=filled,shape=box," + label; - if (this.data.hasUrl() && entity.getUrl() != null) { - dec += ",URL=\"" + entity.getUrl() + "\""; - } - dec += "];"; - sb.append(entity.getUid() + dec); - } else if (type == EntityType.OBJECT) { - sb.append(entity.getUid() + " [fontcolor=" + getFontColorString(FontParam.CLASS) + ",margin=0,fillcolor=" - + getColorString(ColorParam.classBackground) + ",color=" + getColorString(ColorParam.classBorder) - + ",style=filled,shape=record," + label + "];"); - } else if (type == EntityType.USECASE) { - sb.append(entity.getUid() + " [fontcolor=" + getFontColorString(FontParam.USECASE) + ",fillcolor=" - + getColorString(ColorParam.usecaseBackground) + ",color=" - + getColorString(ColorParam.usecaseBorder) + ",style=filled," + label + "];"); - } else if (type == EntityType.ACTOR) { - sb.append(entity.getUid() + " [fontcolor=" + getFontColorString(FontParam.USECASE_ACTOR) - + ",margin=0,shape=plaintext," + label + "];"); - } else if (type == EntityType.CIRCLE_INTERFACE) { - sb.append(entity.getUid() + " [margin=0,shape=plaintext," + label + "];"); - } else if (type == EntityType.COMPONENT) { - sb.append(entity.getUid() + " [margin=0.2,fontcolor=" + getFontColorString(FontParam.COMPONENT) - + ",fillcolor=" + getColorString(ColorParam.componentBackground) + ",color=" - + getColorString(ColorParam.componentBorder) + ",style=filled,shape=component," + label + "];"); - } else if (type == EntityType.NOTE) { - final DrawFile file = entity.getImageFile(); - if (file == null) { - // sb.append(entity.getUid() + ";"); - // Log.error("Warning : no file for NOTE"); - // return; - throw new IllegalStateException("No file for NOTE"); - } - if (file.getPngOrEps(fileFormat == FileFormat.EPS).exists() == false) { - throw new IllegalStateException(); - } - final String absolutePath = StringUtils.getPlateformDependentAbsolutePath(file - .getPngOrEps(fileFormat == FileFormat.EPS)); - sb.append(entity.getUid() + " [margin=0,pad=0," + label + ",shape=none,image=\"" + absolutePath + "\"];"); - } else if (type == EntityType.ACTIVITY) { - String shape = "octagon"; - if (entity.getImageFile() != null) { - shape = "rect"; - } - sb.append(entity.getUid() + " [fontcolor=" + getFontColorString(FontParam.ACTIVITY) + ",fillcolor=" - + getColorString(ColorParam.activityBackground) + ",color=" - + getColorString(ColorParam.activityBorder) + ",style=\"rounded,filled\",shape=" + shape + "," - + label + "];"); - } else if (type == EntityType.BRANCH) { - sb.append(entity.getUid() + " [fillcolor=" + getColorString(ColorParam.activityBackground) + ",color=" - + getColorString(ColorParam.activityBorder) - + ",style=\"filled\",shape=diamond,height=.25,width=.25,label=\"\"];"); - // if (StringUtils.isNotEmpty(entity.getDisplay())) { - // sb.append(entity.getUid() + "->" + entity.getUid() + - // "[taillabel=\"" + entity.getDisplay() - // + "\",arrowtail=none,arrowhead=none,color=\"white\"];"); - // } - } else if (type == EntityType.SYNCHRO_BAR) { - final String color = getColorString(ColorParam.activityBar); - sb.append(entity.getUid() + " [fillcolor=" + color + ",color=" + color + ",style=\"filled\"," - + "shape=rect,height=.08,width=1.30,label=\"\"];"); - } else if (type == EntityType.CIRCLE_START) { - final String color = getColorString(ColorParam.activityStart); - sb.append(entity.getUid() + " [fillcolor=" + color + ",color=" + color + ",style=\"filled\"," - + "shape=circle,width=.20,label=\"\"];"); - } else if (type == EntityType.CIRCLE_END) { - final String color = getColorString(ColorParam.activityEnd); - sb.append(entity.getUid() + " [fillcolor=" + color + ",color=" + color + ",style=\"filled\"," - + "shape=doublecircle,width=.13,label=\"\"];"); - } else if (type == EntityType.POINT_FOR_ASSOCIATION) { - sb.append(entity.getUid() + " [width=.05,shape=point,color=" + getColorString(ColorParam.classBorder) - + "];"); - } else if (type == EntityType.STATE) { - sb.append(entity.getUid() + " [color=" + getColorString(ColorParam.stateBorder) - + ",shape=record,style=\"rounded,filled\",color=" + getColorString(ColorParam.stateBorder)); - if (entity.getImageFile() == null) { - sb.append(",fillcolor=" + getColorString(ColorParam.stateBackground)); - } else { - sb.append(",fillcolor=" + getColorString(ColorParam.stateBackground)); - // sb.append(",fillcolor=\"" + - // data.getSkinParam().getBackgroundColor().getAsHtml() + "\""); - } - sb.append("," + label + "];"); - } else if (type == EntityType.STATE_CONCURRENT) { - final DrawFile file = entity.getImageFile(); - if (file == null) { - throw new IllegalStateException(); - } - if (file.getPng().exists() == false) { - throw new IllegalStateException(); - } - final String absolutePath = StringUtils.getPlateformDependentAbsolutePath(file.getPng()); - sb.append(entity.getUid() + " [margin=1,pad=1," + label + ",style=dashed,shape=box,image=\"" + absolutePath - + "\"];"); - } else if (type == EntityType.ACTIVITY_CONCURRENT) { - final DrawFile file = entity.getImageFile(); - if (file == null) { - throw new IllegalStateException(); - } - if (file.getPng().exists() == false) { - throw new IllegalStateException(); - } - final String absolutePath = StringUtils.getPlateformDependentAbsolutePath(file.getPng()); - sb.append(entity.getUid() + " [margin=0,pad=0," + label + ",style=dashed,shape=box,image=\"" + absolutePath - + "\"];"); - } else if (type == EntityType.EMPTY_PACKAGE) { - sb.append(entity.getUid() + " [margin=0.2,fontcolor=" + getFontColorString(FontParam.PACKAGE) - + ",fillcolor=" + getColorString(ColorParam.packageBackground) + ",color=" - + getColorString(ColorParam.packageBorder) + ",style=filled,shape=tab," + label + "];"); - } else { - throw new IllegalStateException(type.toString() + " " + data.getUmlDiagramType()); - } - } - - private String getHeadOrTail(IEntity lollipop, Link link) { - assert lollipop.getType() == EntityType.LOLLIPOP; - if (link.getLength() > 1 && link.getEntity1() == lollipop) { - return "taillabel"; - } - return "headlabel"; - } - - private String getLabel(IEntity entity) throws IOException { - if (entity.getType() == EntityType.ABSTRACT_CLASS || entity.getType() == EntityType.CLASS - || entity.getType() == EntityType.INTERFACE || entity.getType() == EntityType.ENUM) { - return "label=" + getLabelForClassOrInterfaceOrEnum(entity); - } else if (entity.getType() == EntityType.LOLLIPOP) { - return "label=" + getLabelForLollipop(entity); - } else if (entity.getType() == EntityType.OBJECT) { - return "label=" + getLabelForObject(entity); - } else if (entity.getType() == EntityType.ACTOR) { - return "label=" + getLabelForActor(entity); - } else if (entity.getType() == EntityType.CIRCLE_INTERFACE) { - return "label=" + getLabelForCircleInterface(entity); - } else if (entity.getType() == EntityType.NOTE) { - return "label=\"\""; - } else if (entity.getType() == EntityType.STATE_CONCURRENT) { - return "label=\"\""; - } else if (entity.getType() == EntityType.ACTIVITY_CONCURRENT) { - return "label=\"\""; - } else if (entity.getType() == EntityType.COMPONENT) { - return "label=" + getLabelForComponent(entity); - } else if (entity.getType() == EntityType.ACTIVITY) { - final DrawFile drawFile = entity.getImageFile(); - if (drawFile != null) { - final String path = StringUtils.getPlateformDependentAbsolutePath(drawFile.getPng()); - final String bgcolor = "\"" + data.getSkinParam().getBackgroundColor().getAsHtml() + "\""; - final StringBuilder sb = new StringBuilder("label=<"); - sb.append(""); - sb.append(""); - sb.append(""); - sb.append("
"); - sb.append("
"); - sb.append(">"); - return sb.toString(); - } - return "label=" + getSimpleLabelAsHtml(entity, FontParam.ACTIVITY); - } else if (entity.getType() == EntityType.EMPTY_PACKAGE) { - return "label=" + getSimpleLabelAsHtml(entity, getFontParamForGroup()); - } else if (entity.getType() == EntityType.USECASE) { - return "label=" + getLabelForUsecase(entity); - } else if (entity.getType() == EntityType.STATE) { - return "label=" + getLabelForState(entity); - } - return "label=\"" + entity.getDisplay() + "\""; - } - - private String getSimpleLabelAsHtml(IEntity entity, FontParam param) { - return "<" + manageHtmlIB(entity.getDisplay(), param) + ">"; - } - - private String getLabelForState(IEntity entity) throws IOException { - final DrawFile cFile = entity.getImageFile(); - final String stateBgcolor = getColorString(ColorParam.stateBackground); - - final StringBuilder sb = new StringBuilder("<{"); - sb.append(""); - sb.append("
" + manageHtmlIB(entity.getDisplay(), FontParam.STATE) + "
"); - - if (entity.fields2().size() > 0) { - sb.append("|"); - for (Member att : entity.fields2()) { - sb.append(manageHtmlIB(att.getDisplayWithVisibilityChar(), FontParam.STATE_ATTRIBUTE)); - sb.append("
"); - } - } - - if (cFile != null) { - sb.append("|"); - final String path = StringUtils.getPlateformDependentAbsolutePath(cFile.getPng()); - final String bgcolor = "\"" + data.getSkinParam().getBackgroundColor().getAsHtml() + "\""; - - sb.append(""); - sb.append(""); - sb.append(""); - sb.append("
"); - sb.append("
"); - } - - if (entity.fields2().size() == 0 && cFile == null) { - sb.append("|"); - } - - sb.append("}>"); - - return sb.toString(); - } - - private String getLabelForUsecase(IEntity entity) { - final Stereotype stereotype = getStereotype(entity); - if (stereotype == null) { - return getSimpleLabelAsHtml(entity, FontParam.USECASE); - } - final StringBuilder sb = new StringBuilder("<"); - if (isThereLabel(stereotype)) { - sb.append(""); - } - sb.append(""); - sb.append("
" + manageHtmlIB(stereotype.getLabel(), FontParam.USECASE_STEREOTYPE) + "
" + manageHtmlIB(entity.getDisplay(), FontParam.USECASE) + "
>"); - return sb.toString(); - } - - private String getLabelForComponent(IEntity entity) { - final Stereotype stereotype = getStereotype(entity); - if (stereotype == null) { - return getSimpleLabelAsHtml(entity, FontParam.COMPONENT); - } - final StringBuilder sb = new StringBuilder("<"); - if (isThereLabel(stereotype)) { - sb.append(""); - } - sb.append(""); - sb.append("
" + manageHtmlIB(stereotype.getLabel(), FontParam.COMPONENT_STEREOTYPE) + "
" + manageHtmlIB(entity.getDisplay(), FontParam.COMPONENT) + "
>"); - return sb.toString(); - } - - private String getLabelForActor(IEntity entity) throws IOException { - final String actorAbsolutePath = StringUtils.getPlateformDependentAbsolutePath(data.getStaticImages().get( - EntityType.ACTOR).getPngOrEps(fileFormat == FileFormat.EPS)); - final Stereotype stereotype = getStereotype(entity); - - final StringBuilder sb = new StringBuilder("<"); - if (isThereLabel(stereotype)) { - sb.append(""); - } - sb.append(""); - sb.append(""); - sb.append("
" + manageHtmlIB(stereotype.getLabel(), FontParam.USECASE_ACTOR_STEREOTYPE) - + "
" + manageHtmlIB(entity.getDisplay(), FontParam.USECASE_ACTOR) + "
>"); - return sb.toString(); - - } - - private String getLabelForCircleInterface(IEntity entity) throws IOException { - final String circleInterfaceAbsolutePath = StringUtils.getPlateformDependentAbsolutePath(data.getStaticImages() - .get(EntityType.CIRCLE_INTERFACE).getPngOrEps(fileFormat == FileFormat.EPS)); - final Stereotype stereotype = getStereotype(entity); - - final StringBuilder sb = new StringBuilder("<"); - if (isThereLabel(stereotype)) { - sb.append(""); - } - sb.append(""); - sb.append(""); - sb.append("
" + manageHtmlIB(stereotype.getLabel(), FontParam.COMPONENT_STEREOTYPE) + "
" + manageHtmlIB(entity.getDisplay(), FontParam.COMPONENT) + "
>"); - return sb.toString(); - - } - - private String getLabelForLollipop(IEntity entity) throws IOException { - final String circleInterfaceAbsolutePath = StringUtils.getPlateformDependentAbsolutePath(data.getStaticImages() - .get(EntityType.LOLLIPOP).getPngOrEps(fileFormat == FileFormat.EPS)); - final Stereotype stereotype = getStereotype(entity); - - final StringBuilder sb = new StringBuilder("<"); - if (isThereLabel(stereotype)) { - sb.append(""); - } - sb.append(""); - sb.append(""); - sb.append("
" + manageHtmlIB(stereotype.getLabel(), FontParam.CLASS) + "
" + manageHtmlIB(entity.getDisplay(), FontParam.CLASS) + "
>"); - return sb.toString(); - - } - - private String getLabelForClassOrInterfaceOrEnum(IEntity entity) throws IOException { - if (isVisibilityModifierPresent) { - return getLabelForClassOrInterfaceOrEnumWithVisibilityImage(entity); - } - return getLabelForClassOrInterfaceOrEnumOld(entity); - - } - - private String getLabelForClassOrInterfaceOrEnumOld(IEntity entity) throws IOException { - DrawFile cFile = entity.getImageFile(); - if (cFile == null) { - cFile = data.getStaticImages().get(entity.getType()); - } - if (cFile == null) { - throw new IllegalStateException(); - } - final String circleAbsolutePath; - if (data.showPortion(EntityPortion.CIRCLED_CHARACTER, entity)) { - circleAbsolutePath = StringUtils.getPlateformDependentAbsolutePath(cFile - .getPngOrEps(fileFormat == FileFormat.EPS)); - } else { - circleAbsolutePath = null; - } - - final StringBuilder sb = new StringBuilder("<"); - - final boolean showFields = data.showPortion(EntityPortion.FIELD, entity); - final boolean showMethods = data.showPortion(EntityPortion.METHOD, entity); - - if (showFields == false && showMethods == false) { - sb.append(getHtmlHeaderTableForObjectOrClassOrInterfaceOrEnum(entity, circleAbsolutePath, 1, true, 1)); - } else { - sb.append(""); - sb.append(""); - - if (showFields) { - final boolean hasStatic = hasStatic(entity.fields2()); - sb.append(""); - } - if (showMethods) { - final boolean hasStatic = hasStatic(entity.methods2()); - sb.append(""); - } - - sb.append("
"); - final int longuestFieldOrAttribute = getLongestFieldOrAttribute(entity); - final int longuestHeader = getLonguestHeader(entity); - final int spring = computeSpring(longuestHeader, longuestFieldOrAttribute, 30); - - sb.append(getHtmlHeaderTableForObjectOrClassOrInterfaceOrEnum(entity, circleAbsolutePath, spring, true, 0)); - - sb.append("
"); - for (Member att : entity.fields2()) { - sb.append(manageHtmlIBspecial(att, FontParam.CLASS_ATTRIBUTE, hasStatic, - getColorString(ColorParam.classBackground), true)); - sb.append("
"); - } - sb.append("
"); - for (Member att : entity.methods2()) { - sb.append(manageHtmlIBspecial(att, FontParam.CLASS_ATTRIBUTE, hasStatic, - getColorString(ColorParam.classBackground), true)); - sb.append("
"); - } - sb.append("
"); - } - sb.append(">"); - - return sb.toString(); - } - - private boolean hasStatic(Collection attributes) { - for (Member att : attributes) { - if (att.isStatic()) { - return true; - } - } - return false; - } - - private String getLabelForClassOrInterfaceOrEnumWithVisibilityImage(IEntity entity) throws IOException { - DrawFile cFile = entity.getImageFile(); - if (cFile == null) { - cFile = data.getStaticImages().get(entity.getType()); - } - if (cFile == null) { - throw new IllegalStateException(); - } - final String circleAbsolutePath; - if (data.showPortion(EntityPortion.CIRCLED_CHARACTER, entity)) { - circleAbsolutePath = StringUtils.getPlateformDependentAbsolutePath(cFile - .getPngOrEps(fileFormat == FileFormat.EPS)); - } else { - circleAbsolutePath = null; - } - - final boolean showFields = data.showPortion(EntityPortion.FIELD, entity); - final boolean showMethods = data.showPortion(EntityPortion.METHOD, entity); - - final StringBuilder sb = new StringBuilder("<"); - if (showFields == false && showMethods == false) { - sb.append(getHtmlHeaderTableForObjectOrClassOrInterfaceOrEnum(entity, circleAbsolutePath, 1, true, 1)); - } else { - final int longuestHeader = getLonguestHeader(entity); - final int spring = computeSpring(longuestHeader, getLongestFieldOrAttribute(entity), 30); - final int springField = computeSpring(getLongestField(entity), Math.max(longuestHeader, - getLongestMethods(entity)), 30); - final int springMethod = computeSpring(getLongestMethods(entity), Math.max(longuestHeader, - getLongestField(entity)), 30); - - sb.append(""); - sb.append(""); - - if (showFields) { - sb.append(""); - } - if (showMethods) { - sb.append(""); - } - sb.append("
"); - - sb.append(getHtmlHeaderTableForObjectOrClassOrInterfaceOrEnum(entity, circleAbsolutePath, spring, true, 0)); - sb.append("
"); - if (entity.fields2().size() > 0) { - buildTableVisibility(entity, true, sb, springField); - } - sb.append("
"); - if (entity.methods2().size() > 0) { - buildTableVisibility(entity, false, sb, springMethod); - } - sb.append("
"); - } - sb.append(">"); - - return sb.toString(); - - } - - private int computeSpring(final int current, final int maximum, int maxSpring) { - if (maximum <= current) { - return 0; - } - final int spring = maximum - current; - if (spring > maxSpring) { - return maxSpring; - } - return spring; - } - - private void buildTableVisibility(IEntity entity, boolean isField, final StringBuilder sb, int spring) - throws IOException { - sb.append(""); - - final boolean hasStatic = hasStatic(entity.methods2()); - for (Member att : isField ? entity.fields2() : entity.methods2()) { - sb.append(""); - for (int i = 0; i < spring; i++) { - sb.append(""); - } - sb.append(""); - } - sb.append("
"); - String s = att.getDisplayWithVisibilityChar(); - final VisibilityModifier visibilityModifier = VisibilityModifier - .getVisibilityModifier(s.charAt(0), isField); - if (visibilityModifier != null) { - final String modifierFile = StringUtils.getPlateformDependentAbsolutePath(data.getVisibilityImages() - .get(visibilityModifier).getPngOrEps(fileFormat == FileFormat.EPS)); - sb.append(""); - s = s.substring(1); - } - sb.append(""); - sb.append(manageHtmlIBspecial(att, FontParam.CLASS_ATTRIBUTE, hasStatic, - getColorString(ColorParam.classBackground), false)); - // sb.append(manageHtmlIB(s, FontParam.CLASS_ATTRIBUTE)); - sb.append("
"); - } - - private int getLonguestHeader(IEntity entity) { - int result = entity.getDisplay().length(); - final Stereotype stereotype = getStereotype(entity); - if (isThereLabel(stereotype)) { - final int size = stereotype.getLabel().length(); - if (size > result) { - result = size; - } - } - return result; - } - - private int getLongestFieldOrAttribute(IEntity entity) { - return Math.max(getLongestField(entity), getLongestMethods(entity)); - } - - private int getLongestMethods(IEntity entity) { - int result = 0; - for (Member att : entity.methods2()) { - final int size = att.getDisplayWithVisibilityChar().length(); - if (size > result) { - result = size; - } - } - return result; - - } - - private int getLongestField(IEntity entity) { - int result = 0; - for (Member att : entity.fields2()) { - final int size = att.getDisplayWithVisibilityChar().length(); - if (size > result) { - result = size; - } - } - return result; - } - - private String getLabelForObject(IEntity entity) throws IOException { - if (isVisibilityModifierPresent) { - return getLabelForObjectWithVisibilityImage(entity); - } - return getLabelForObjectOld(entity); - } - - private String getLabelForObjectWithVisibilityImage(IEntity entity) throws IOException { - - final int longuestHeader = getLonguestHeader(entity); - final int spring = computeSpring(longuestHeader, getLongestFieldOrAttribute(entity), 30); - final int springField = computeSpring(getLongestField(entity), Math.max(longuestHeader, - getLongestMethods(entity)), 30); - - final StringBuilder sb = new StringBuilder("<"); - sb.append(""); - sb.append(""); - sb.append("
"); - - sb.append(getHtmlHeaderTableForObjectOrClassOrInterfaceOrEnum(entity, null, spring, false, 0)); - - sb.append("
"); - - if (entity.fields2().size() == 0) { - sb.append(manageHtmlIB(" ", FontParam.OBJECT_ATTRIBUTE)); - } else { - buildTableVisibility(entity, true, sb, springField); - } - - sb.append("
>"); - - return sb.toString(); - - } - - private String getLabelForObjectOld(IEntity entity) throws IOException { - final StringBuilder sb = new StringBuilder("<"); - sb.append(""); - sb.append(""); - sb.append("
"); - - final int longuestFieldOrAttribute = getLongestFieldOrAttribute(entity); - final int longuestHeader = getLonguestHeader(entity); - final int spring = computeSpring(longuestHeader, longuestFieldOrAttribute, 30); - - sb.append(getHtmlHeaderTableForObjectOrClassOrInterfaceOrEnum(entity, null, spring, false, 0)); - - sb.append("
"); - - if (entity.fields2().size() == 0) { - sb.append(manageHtmlIB(" ", FontParam.OBJECT_ATTRIBUTE)); - } else { - for (Member att : entity.fields2()) { - sb.append(manageHtmlIB(att.getDisplayWithVisibilityChar(), FontParam.OBJECT_ATTRIBUTE)); - sb.append("
"); - } - } - - sb.append("
>"); - - return sb.toString(); - } - - private String manageHtmlIB(String s, FontParam param) { - s = unicode(s); - final int fontSize = data.getSkinParam().getFontSize(param); - final int style = data.getSkinParam().getFontStyle(param); - final String fontFamily = data.getSkinParam().getFontFamily(param); - final DotExpression dotExpression = new DotExpression(s, fontSize, getFontHtmlColor(param), fontFamily, style, - fileFormat); - final String result = dotExpression.getDotHtml(); - if (dotExpression.isUnderline()) { - underline = true; - } - return result; - } - - private String manageHtmlIBspecial(Member att, FontParam param, boolean hasStatic, String backColor, boolean withVisibilityChar) { - String prefix = ""; - if (hasStatic) { - prefix = "_"; - } - if (att.isAbstract()) { - return prefix + manageHtmlIB("" + att.getDisplay(withVisibilityChar), param); - } - if (att.isStatic()) { - return manageHtmlIB("" + att.getDisplay(withVisibilityChar), param); - } - return prefix + manageHtmlIB(att.getDisplay(withVisibilityChar), param); - } - - private String manageSpace(int size) { - final DotExpression dotExpression = new DotExpression(" ", size, new HtmlColor("white"), null, Font.PLAIN, - fileFormat); - final String result = dotExpression.getDotHtml(); - return result; - } - - static String unicode(String s) { - final StringBuilder result = new StringBuilder(); - for (char c : s.toCharArray()) { - if (c > 127 || c == '&') { - final int i = c; - result.append("&#" + i + ";"); - } else { - result.append(c); - } - } - return result.toString(); - } - - private String getHtmlHeaderTableForObjectOrClassOrInterfaceOrEnumNoSpring(IEntity entity, - final String circleAbsolutePath, int cellSpacing, boolean classes) { - final StringBuilder sb = new StringBuilder(); - sb.append(""); - sb.append(""); - if (circleAbsolutePath == null) { - sb.append(""); - sb.append("
"); - } else { - sb.append(""); - sb.append(""); - } - - appendLabelAndStereotype(entity, sb, classes); - sb.append("
"); - return sb.toString(); - } - - private String getHtmlHeaderTableForObjectOrClassOrInterfaceOrEnum(IEntity entity, final String circleAbsolutePath, - int spring, boolean classes, int border) throws IOException { - if (spring == 0) { - return getHtmlHeaderTableForObjectOrClassOrInterfaceOrEnumNoSpring(entity, circleAbsolutePath, 0, classes); - } - final StringBuilder sb = new StringBuilder(); - - sb - .append(""); - sb.append(""); - - for (int i = 0; i < spring; i++) { - sb.append(""); - } - - if (circleAbsolutePath != null) { - if (circleAbsolutePath.endsWith(".png")) { - final BufferedImage im = ImageIO.read(new File(circleAbsolutePath)); - final int height = im.getHeight(); - final int width = im.getWidth(); - sb.append(""); - } else if (circleAbsolutePath.endsWith(".eps")) { - sb.append(""); - } - } - - sb.append(""); - - for (int i = 0; i < spring; i++) { - sb.append(""); - } - sb.append("
"); - appendLabelAndStereotype(entity, sb, classes); - sb.append("
"); - return sb.toString(); - } - - private void appendLabelAndStereotype(IEntity entity, final StringBuilder sb, boolean classes) { - final Stereotype stereotype = getStereotype(entity); - if (isThereLabel(stereotype)) { - sb.append("
"); - sb.append(manageHtmlIB(stereotype.getLabel(), classes ? FontParam.CLASS_STEREOTYPE - : FontParam.OBJECT_STEREOTYPE)); - sb.append("
"); - } - String display = entity.getDisplay(); - final boolean italic = entity.getType() == EntityType.ABSTRACT_CLASS - || entity.getType() == EntityType.INTERFACE; - if (italic) { - display = "" + display; - } - sb.append(manageHtmlIB(display, classes ? FontParam.CLASS : FontParam.OBJECT)); - } - - private String getHtmlHeaderTableForClassOrInterfaceOrEnumNew(Entity entity, final String circleAbsolutePath) { - final StringBuilder sb = new StringBuilder(); - sb.append(""); - sb.append("
"); - - appendLabelAndStereotype(entity, sb, true); - sb.append("
"); - return sb.toString(); - } - - private boolean isThereLabel(final Stereotype stereotype) { - return stereotype != null && stereotype.getLabel() != null; - } - - private Stereotype getStereotype(IEntity entity) { - if (data.showPortion(EntityPortion.STEREOTYPE, entity) == false) { - return null; - } - return entity.getStereotype(); - } - - public final boolean isUnderline() { - return underline; - } - - private boolean workAroundDotBug() { - for (Link link : data.getLinks()) { - if (link.getLength() != 1) { - return false; - } - } - if (data.getUmlDiagramType() == UmlDiagramType.CLASS && allEntitiesAreClasses(data.getEntities().values())) { - return true; - } - for (IEntity ent : data.getEntities().values()) { - if (data.getAllLinkedTo(ent).size() == 0) { - return true; - } - } - return false; - } - - private boolean allEntitiesAreClasses(Collection entities) { - for (IEntity ent : entities) { - if (ent.getType() != EntityType.CLASS && ent.getType() != EntityType.ABSTRACT_CLASS - && ent.getType() != EntityType.INTERFACE && ent.getType() != EntityType.ENUM) { - return false; - } - } - return true; - } - - private boolean isSpecialGroup(Group g) { - if (g.getType() == GroupType.STATE) { - return true; - } - if (g.getType() == GroupType.CONCURRENT_STATE) { - throw new IllegalStateException(); - } - if (data.isThereLink(g)) { - return true; - } - return false; - } - - public static final String getLastDotSignature() { - return lastDotSignature; - } - - public static final void reset() { - lastDotSignature = null; - } - - public void clean() { - // TODO Auto-generated method stub - - } - -} diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/DrawFile.java b/src/net/sourceforge/plantuml/cucadiagram/dot/DrawFile.java index 89aca01aa..cea2caa7c 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/dot/DrawFile.java +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/DrawFile.java @@ -36,48 +36,53 @@ package net.sourceforge.plantuml.cucadiagram.dot; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; +import java.util.HashMap; +import java.util.Map; import javax.imageio.ImageIO; +import net.sourceforge.plantuml.FileUtils; import net.sourceforge.plantuml.Log; public class DrawFile { - private final LazyCached png2; + private static final Map cache = new HashMap(); + + private final LazyFile png2; private final LazyCached svg2; - private final LazyCached eps2; + private final LazyFile eps2; private int widthPng = -1; private int heightPng = -1; - public DrawFile(Lazy png) { - this(png, (Lazy) null, null); + public static DrawFile create(Lazy png, Lazy svg, Lazy eps, Object signature) { + DrawFile result = cache.get(signature); + if (result == null) { + result = new DrawFile(png, svg, eps); + cache.put(signature, result); + Log.info("DrawFile cache size = " + cache.size()); + FileUtils.deleteOnExit(result); + } + return result; } - public DrawFile(Lazy png, Lazy svg) { - this(png, svg, null); + public static DrawFile createFromFile(File fPng, String svg, File fEps) { + final DrawFile result = new DrawFile(fPng, svg, fEps); + FileUtils.deleteOnExit(result); + return result; } - public DrawFile(Lazy png, Lazy svg, Lazy eps) { - this.png2 = new LazyCached(png); + private DrawFile(Lazy png, Lazy svg, Lazy eps) { + this.png2 = new LazyFile(png); this.svg2 = new LazyCached(svg); - this.eps2 = new LazyCached(eps); + this.eps2 = new LazyFile(eps); } - public DrawFile(File fPng, String svg, File fEps) { + private DrawFile(File fPng, String svg, File fEps) { this(new Unlazy(fPng), new Unlazy(svg), new Unlazy(fEps)); - } - - public DrawFile(File fPng, String svg, Lazy eps) { - this(new Unlazy(fPng), new Unlazy(svg), eps); - } - - public DrawFile(Lazy png, String svg, Lazy eps) { - this(png, new Unlazy(svg), eps); - } - - public DrawFile(File f, String svg) { - this(f, svg, (File) null); + if (svg.contains("\\")) { + throw new IllegalArgumentException(); + } } public File getPngOrEps(boolean isEps) throws IOException { diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/GroupPngMaker.java b/src/net/sourceforge/plantuml/cucadiagram/dot/GroupPngMaker.java index 19dbd3f18..336040262 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/dot/GroupPngMaker.java +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/GroupPngMaker.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5385 $ + * Revision $Revision: 5872 $ * */ package net.sourceforge.plantuml.cucadiagram.dot; @@ -48,7 +48,10 @@ import java.util.Map; import javax.imageio.ImageIO; import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.FileUtils; +import net.sourceforge.plantuml.ISkinParam; import net.sourceforge.plantuml.OptionFlags; +import net.sourceforge.plantuml.SkinParamBackcolored; import net.sourceforge.plantuml.cucadiagram.CucaDiagram; import net.sourceforge.plantuml.cucadiagram.Entity; import net.sourceforge.plantuml.cucadiagram.EntityType; @@ -57,13 +60,11 @@ import net.sourceforge.plantuml.cucadiagram.GroupHierarchy; import net.sourceforge.plantuml.cucadiagram.IEntity; import net.sourceforge.plantuml.cucadiagram.Link; import net.sourceforge.plantuml.png.PngIO; -import net.sourceforge.plantuml.skin.rose.Rose; public final class GroupPngMaker { private final CucaDiagram diagram; private final Group group; - private final Rose rose = new Rose(); private final FileFormat fileFormat; class InnerGroupHierarchy implements GroupHierarchy { @@ -115,7 +116,7 @@ public final class GroupPngMaker { // Color.BLACK).process(); // } - PngIO.write(im, os, diagram.getMetadata()); + PngIO.write(im, os, diagram.getMetadata(), 96); } finally { cleanTemporaryFiles(imageFiles); } @@ -143,7 +144,43 @@ public final class GroupPngMaker { String svg = new String(baos.toByteArray(), "UTF-8"); svg = removeSvgXmlHeader(svg); - return svg; + + // // Image management + // final Pattern pImage = Pattern.compile("(?i)]*>"); + // final Matcher mImage = pImage.matcher(svg); + // final StringBuffer sb = new StringBuffer(); + // while (mImage.find()) { + // final String image = mImage.group(0); + // final String href = CucaDiagramFileMaker.getValue(image, "href"); + // final double widthSvg = + // Double.parseDouble(CucaDiagramFileMaker.getValuePx(image, + // "width")); + // final double heightSvg = + // Double.parseDouble(CucaDiagramFileMaker.getValuePx(image, + // "height")); + // final double x = + // Double.parseDouble(CucaDiagramFileMaker.getValue(image, "x")) + + // 20; + // final double y = + // Double.parseDouble(CucaDiagramFileMaker.getValue(image, "y")) + + // 20; + // // final DrawFile drawFile = getDrawFileFromHref(href); + // // final int widthPng = drawFile.getWidthPng(); + // // final int heightPng = drawFile.getHeightPng(); + // // String svg2 = drawFile.getSvg(); + // // final String scale = CucaDiagramFileMaker.getScale(widthSvg, + // heightSvg, widthPng, heightPng); + // // svg2 = svg2 + // // .replaceFirst("<[gG]>", ""); + // String svg2 = "toto"; + // svg2 = "" + svg2 + ""; + // mImage.appendReplacement(sb, svg2); + // } + // mImage.appendTail(sb); + // svg = sb.toString(); + + return svg.replace('\\', '/'); } finally { cleanTemporaryFiles(imageFiles); @@ -160,15 +197,19 @@ public final class GroupPngMaker { private void cleanTemporaryFiles(final Map imageFiles) { if (OptionFlags.getInstance().isKeepTmpFiles() == false) { for (File f : imageFiles.values()) { - StaticFiles.delete(f); + FileUtils.delete(f); } } } GraphvizMaker createDotMaker(List dotStrings) { final List links = getPureInnerLinks(); - final DotData dotData = new DotData(group, links, group.entities(), diagram.getUmlDiagramType(), diagram - .getSkinParam(), group.getRankdir(), new InnerGroupHierarchy()); + ISkinParam skinParam = diagram.getSkinParam(); + if (OptionFlags.PBBACK && group.getBackColor() != null) { + skinParam = new SkinParamBackcolored(skinParam, null, group.getBackColor()); + } + final DotData dotData = new DotData(group, links, group.entities(), diagram.getUmlDiagramType(), skinParam, + group.getRankdir(), new InnerGroupHierarchy()); // dotData.putAllImages(images); // dotData.putAllStaticImages(staticImages); // dotData.putAllImagesLink(imagesLink); diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/LazyCached.java b/src/net/sourceforge/plantuml/cucadiagram/dot/LazyCached.java index 3cc5a6d51..dcb36d06a 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/dot/LazyCached.java +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/LazyCached.java @@ -45,12 +45,16 @@ public class LazyCached implements Lazy { } public O getNow() throws IOException { - if (data == null) { + if (isLoaded() == false) { this.data = this.lazy.getNow(); } return this.data; } + protected O getRowData() { + return data; + } + public boolean isLoaded() { return data != null; } diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/LazyFile.java b/src/net/sourceforge/plantuml/cucadiagram/dot/LazyFile.java new file mode 100644 index 000000000..2050bc823 --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/LazyFile.java @@ -0,0 +1,55 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009, 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 Lesser 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: 3977 $ + * + */ +package net.sourceforge.plantuml.cucadiagram.dot; + +import java.io.File; + +public class LazyFile extends LazyCached { + + public LazyFile(Lazy f) { + super(f); + } + + @Override + public boolean isLoaded() { + if (super.isLoaded() == false) { + return false; + } + if (getRowData().exists() == false) { + return false; + } + return true; + } + +} diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/PlayField.java b/src/net/sourceforge/plantuml/cucadiagram/dot/PlayField.java index ab2f1582a..aee1c53da 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/dot/PlayField.java +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/PlayField.java @@ -96,7 +96,7 @@ public final class PlayField { public PlayField(ISkinParam skinParam) { this.skinParam = skinParam; - this.fontQualif = skinParam.getFont(FontParam.CLASS_ARROW); + this.fontQualif = skinParam.getFont(FontParam.CLASS_ARROW, null); } public void initInternal(Collection entities, Collection links, StringBounder stringBounder) { @@ -259,7 +259,7 @@ public final class PlayField { final String qual1 = link.getQualifier1(); if (qual1 != null) { final TextBlock b = TextBlockUtils.create(Arrays.asList(qual1), fontQualif, - skinParam.getFontHtmlColor(FontParam.CLASS_ARROW).getColor(), HorizontalAlignement.LEFT); + skinParam.getFontHtmlColor(FontParam.CLASS_ARROW, null).getColor(), HorizontalAlignement.LEFT); final Point2D pos = p.getDotPath().getStartPoint(); b.drawU(ug, pos.getX(), pos.getY()); } @@ -267,7 +267,7 @@ public final class PlayField { final String qual2 = link.getQualifier2(); if (qual2 != null) { final TextBlock b = TextBlockUtils.create(Arrays.asList(qual2), fontQualif, - skinParam.getFontHtmlColor(FontParam.CLASS_ARROW).getColor(), HorizontalAlignement.LEFT); + skinParam.getFontHtmlColor(FontParam.CLASS_ARROW, null).getColor(), HorizontalAlignement.LEFT); final Point2D pos = p.getDotPath().getEndPoint(); b.drawU(ug, pos.getX(), pos.getY()); } diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/StaticFiles.java b/src/net/sourceforge/plantuml/cucadiagram/dot/StaticFiles.java index ef7172211..6e0904883 100644 --- a/src/net/sourceforge/plantuml/cucadiagram/dot/StaticFiles.java +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/StaticFiles.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5339 $ + * Revision $Revision: 5823 $ * */ package net.sourceforge.plantuml.cucadiagram.dot; @@ -39,9 +39,7 @@ import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; +import java.util.Arrays; import java.util.EnumMap; import java.util.EnumSet; import java.util.Map; @@ -50,16 +48,12 @@ import javax.imageio.ImageIO; import net.sourceforge.plantuml.ColorParam; import net.sourceforge.plantuml.EmptyImageBuilder; +import net.sourceforge.plantuml.FileUtils; import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.ISkinParam; -import net.sourceforge.plantuml.Log; -import net.sourceforge.plantuml.OptionFlags; import net.sourceforge.plantuml.cucadiagram.EntityType; import net.sourceforge.plantuml.graphic.CircledCharacter; -import net.sourceforge.plantuml.graphic.StringBounder; -import net.sourceforge.plantuml.graphic.StringBounderUtils; import net.sourceforge.plantuml.skin.CircleInterface; -import net.sourceforge.plantuml.skin.StickMan; import net.sourceforge.plantuml.skin.UDrawable; import net.sourceforge.plantuml.skin.VisibilityModifier; import net.sourceforge.plantuml.skin.rose.Rose; @@ -68,24 +62,9 @@ import net.sourceforge.plantuml.ugraphic.g2d.UGraphicG2d; public class StaticFiles { - private final String circleInterfaceName = "cinterface.png"; - private final String lollipopName = "lollipop.png"; - private final String actorName = "actor.png"; - private final String cName = "stereotypec.png"; - private final String iName = "stereotypei.png"; - private final String aName = "stereotypea.png"; - private final String eName = "stereotypee.png"; - - private final Color stereotypeCBackground; - private final Color stereotypeIBackground; - private final Color stereotypeABackground; - private final Color stereotypeEBackground; - private final Color interfaceBorder; private final Color classborder; - private final Color actorBorder; private final Color classBackground; - private final Color actorBackground; private final Color interfaceBackground; private final Color background; @@ -101,262 +80,105 @@ public class StaticFiles { private final Map backgroundColor = new EnumMap( VisibilityModifier.class); - private static final Collection toDelete = new ArrayList(); + private final double dpiFactor; - private void deleteOnExit() { - if (toDelete.isEmpty()) { - toDelete.addAll(staticImages.values()); - toDelete.addAll(visibilityImages.values()); - Runtime.getRuntime().addShutdownHook(new Thread() { - @Override - public void run() { - if (OptionFlags.getInstance().isKeepTmpFiles() == false) { - for (DrawFile f : toDelete) { - f.delete(); - } - } - } - }); - } - } - - public StaticFiles(ISkinParam param) throws IOException { + public StaticFiles(ISkinParam param, String stereotype, double dpiFactor) throws IOException { final Rose rose = new Rose(); - radius = param.getCircledCharacterRadius(); - circledFont = param.getFont(FontParam.CIRCLED_CHARACTER); - // circledFont = new Font("Courier", Font.BOLD, 17); + this.dpiFactor = dpiFactor; - actorBorder = rose.getHtmlColor(param, ColorParam.actorBorder).getColor(); - classborder = rose.getHtmlColor(param, ColorParam.classBorder).getColor(); - interfaceBorder = rose.getHtmlColor(param, ColorParam.interfaceBorder).getColor(); - interfaceBackground = rose.getHtmlColor(param, ColorParam.interfaceBackground).getColor(); - actorBackground = rose.getHtmlColor(param, ColorParam.actorBackground).getColor(); - classBackground = rose.getHtmlColor(param, ColorParam.classBackground).getColor(); - stereotypeCBackground = rose.getHtmlColor(param, ColorParam.stereotypeCBackground).getColor(); - stereotypeABackground = rose.getHtmlColor(param, ColorParam.stereotypeABackground).getColor(); - stereotypeIBackground = rose.getHtmlColor(param, ColorParam.stereotypeIBackground).getColor(); - stereotypeEBackground = rose.getHtmlColor(param, ColorParam.stereotypeEBackground).getColor(); + radius = param.getCircledCharacterRadius(); + circledFont = param.getFont(FontParam.CIRCLED_CHARACTER, stereotype); + + classborder = rose.getHtmlColor(param, ColorParam.classBorder, stereotype).getColor(); + interfaceBorder = rose.getHtmlColor(param, ColorParam.componentInterfaceBorder, stereotype).getColor(); + interfaceBackground = rose.getHtmlColor(param, ColorParam.componentInterfaceBackground, stereotype).getColor(); + classBackground = rose.getHtmlColor(param, ColorParam.classBackground, stereotype).getColor(); + final Color stereotypeCBackground = rose.getHtmlColor(param, ColorParam.stereotypeCBackground, stereotype) + .getColor(); + final Color stereotypeABackground = rose.getHtmlColor(param, ColorParam.stereotypeABackground, stereotype) + .getColor(); + final Color stereotypeIBackground = rose.getHtmlColor(param, ColorParam.stereotypeIBackground, stereotype) + .getColor(); + final Color stereotypeEBackground = rose.getHtmlColor(param, ColorParam.stereotypeEBackground, stereotype) + .getColor(); background = param.getBackgroundColor().getColor(); - final File dir = getTmpDir(); - staticImages.put(EntityType.LOLLIPOP, ensurePngLollipopPresent(dir)); - staticImages.put(EntityType.CIRCLE_INTERFACE, ensurePngCircleInterfacePresent(dir)); - staticImages.put(EntityType.ACTOR, ensurePngActorPresent(dir)); - staticImages.put(EntityType.ABSTRACT_CLASS, ensurePngAPresent(dir)); - staticImages.put(EntityType.CLASS, ensurePngCPresent(dir)); - staticImages.put(EntityType.INTERFACE, ensurePngIPresent(dir)); - staticImages.put(EntityType.ENUM, ensurePngEPresent(dir)); + final File dir = FileUtils.getTmpDir(); + staticImages.put(EntityType.LOLLIPOP, getLollipop()); + staticImages.put(EntityType.ABSTRACT_CLASS, getCircledCharacter('A', stereotypeABackground)); + staticImages.put(EntityType.CLASS, getCircledCharacter('C', stereotypeCBackground)); + staticImages.put(EntityType.INTERFACE, getCircledCharacter('I', stereotypeIBackground)); + staticImages.put(EntityType.ENUM, getCircledCharacter('E', stereotypeEBackground)); if (param.classAttributeIconSize() > 0) { for (VisibilityModifier modifier : EnumSet.allOf(VisibilityModifier.class)) { final Color back = modifier.getBackground() == null ? null : rose.getHtmlColor(param, - modifier.getBackground()).getColor(); - final Color fore = rose.getHtmlColor(param, modifier.getForeground()).getColor(); + modifier.getBackground(), stereotype).getColor(); + final Color fore = rose.getHtmlColor(param, modifier.getForeground(), stereotype).getColor(); backgroundColor.put(modifier, back); foregroundColor.put(modifier, fore); - visibilityImages.put(modifier, - ensureVisibilityModifierPresent(modifier, dir, param.classAttributeIconSize())); + visibilityImages.put(modifier, getVisibilityModifier(modifier, dir, param.classAttributeIconSize(), + dpiFactor)); } } - - deleteOnExit(); } - public File getTmpDir() { - final File tmpDir = new File(System.getProperty("java.io.tmpdir")); - if (tmpDir.exists() == false || tmpDir.isDirectory() == false) { - throw new IllegalStateException(); - } - return tmpDir; - } - - public static void delete(File f) { - if (f == null) { - return; - } - Thread.yield(); - Log.info("Deleting temporary file " + f); - final boolean ok = f.delete(); - if (ok == false) { - Log.error("Cannot delete: " + f); - } - } - - private DrawFile ensurePngActorPresent(final File dir) throws IOException { - final StickMan stickMan = new StickMan(actorBackground, actorBorder); - - final Lazy lpng = new Lazy() { - public File getNow() throws IOException { - final EmptyImageBuilder builder = new EmptyImageBuilder((int) stickMan.getPreferredWidth(null), - (int) stickMan.getPreferredHeight(null), background); - - final BufferedImage im = builder.getBufferedImage(); - final Graphics2D g2d = builder.getGraphics2D(); - - stickMan.drawU(new UGraphicG2d(g2d, null)); - - final File png = new File(dir, actorName); - Log.info("Creating temporary file: " + png); - ImageIO.write(im, "png", png); - return png; - } - }; - - final Lazy leps = new Lazy() { - public File getNow() throws IOException { - final File epsFile = new File(dir, actorName.replaceFirst("\\.png", ".eps")); - UGraphicEps.copyEpsToFile(stickMan, epsFile); - return epsFile; - } - }; - - return new DrawFile(lpng, UGraphicG2d.getSvgString(stickMan), leps); - } - - private DrawFile ensurePngCircleInterfacePresent(final File dir) throws IOException { - - final CircleInterface circleInterface = new CircleInterface(interfaceBackground, interfaceBorder); - - final Lazy lpng = new Lazy() { - - public File getNow() throws IOException { - final EmptyImageBuilder builder = new EmptyImageBuilder((int) circleInterface.getPreferredWidth(null), - (int) circleInterface.getPreferredHeight(null), background); - - final BufferedImage im = builder.getBufferedImage(); - final Graphics2D g2d = builder.getGraphics2D(); - - circleInterface.drawU(new UGraphicG2d(g2d, null)); - - final File png = new File(dir, circleInterfaceName); - Log.info("Creating temporary file: " + png); - ImageIO.write(im, "png", png); - return png; - } - }; - - final Lazy leps = new Lazy() { - public File getNow() throws IOException { - final File epsFile = new File(dir, circleInterfaceName.replaceFirst("\\.png", ".eps")); - Log.info("Creating temporary file: " + epsFile); - UGraphicEps.copyEpsToFile(circleInterface, epsFile); - return epsFile; - } - }; - - return new DrawFile(lpng, UGraphicG2d.getSvgString(circleInterface), leps); - - } - - private DrawFile ensurePngLollipopPresent(final File dir) throws IOException { + private DrawFile getLollipop() throws IOException { final CircleInterface circleInterface = new CircleInterface(interfaceBackground, interfaceBorder, 10, 2); final Lazy lpng = new Lazy() { public File getNow() throws IOException { - final EmptyImageBuilder builder = new EmptyImageBuilder((int) circleInterface.getPreferredWidth(null), - (int) circleInterface.getPreferredHeight(null), background); + final EmptyImageBuilder builder = new EmptyImageBuilder(circleInterface.getPreferredWidth(null), + circleInterface.getPreferredHeight(null), background); final BufferedImage im = builder.getBufferedImage(); final Graphics2D g2d = builder.getGraphics2D(); - circleInterface.drawU(new UGraphicG2d(g2d, null)); + circleInterface.drawU(new UGraphicG2d(g2d, null, dpiFactor)); - final File result = new File(dir, lollipopName); - Log.info("Creating temporary file: " + result); + final File result = FileUtils.createTempFile("lollipop", ".png"); ImageIO.write(im, "png", result); return result; } }; final Lazy leps = new Lazy() { - public File getNow() throws IOException { - final File epsFile = new File(dir, lollipopName.replaceFirst("\\.png", ".eps")); - Log.info("Creating temporary file: " + epsFile); + final File epsFile = FileUtils.createTempFile("lollipop", ".eps"); UGraphicEps.copyEpsToFile(circleInterface, epsFile); return epsFile; } }; - return new DrawFile(lpng, UGraphicG2d.getSvgString(circleInterface), leps); - - } - - private DrawFile ensurePngCPresent(File dir) throws IOException { - final CircledCharacter circledCharacter = new CircledCharacter('C', radius, circledFont, stereotypeCBackground, - classborder, Color.BLACK); - return generateCircleCharacterFile(dir, cName, circledCharacter, classBackground); - } - - private DrawFile ensurePngAPresent(File dir) throws IOException { - final CircledCharacter circledCharacter = new CircledCharacter('A', radius, circledFont, stereotypeABackground, - classborder, Color.BLACK); - return generateCircleCharacterFile(dir, aName, circledCharacter, classBackground); - } - - private DrawFile ensurePngIPresent(File dir) throws IOException { - final CircledCharacter circledCharacter = new CircledCharacter('I', radius, circledFont, stereotypeIBackground, - classborder, Color.BLACK); - return generateCircleCharacterFile(dir, iName, circledCharacter, classBackground); - } - - private DrawFile ensurePngEPresent(File dir) throws IOException { - final CircledCharacter circledCharacter = new CircledCharacter('E', radius, circledFont, stereotypeEBackground, - classborder, Color.BLACK); - return generateCircleCharacterFile(dir, eName, circledCharacter, classBackground); - } - - private DrawFile generateCircleCharacterFile(File dir, String filename, final CircledCharacter circledCharacter, - final Color yellow) throws IOException { - final File png = new File(dir, filename); - final File epsFile = new File(dir, filename.replaceFirst("\\.png", ".eps")); - - return generateCircleCharacter(png, epsFile, circledCharacter, yellow); - } - - public DrawFile generateCircleCharacter(final File png, final File epsFile, - final CircledCharacter circledCharacter, final Color yellow) throws IOException { - - final Lazy lpng = new Lazy() { - - public File getNow() throws IOException { - Log.info("Creating temporary file: " + png); - final EmptyImageBuilder builder = new EmptyImageBuilder(90, 90, yellow); - BufferedImage im = builder.getBufferedImage(); - final Graphics2D g2d = builder.getGraphics2D(); - final StringBounder stringBounder = StringBounderUtils.asStringBounder(g2d); - - circledCharacter.draw(g2d, 0, 0); - im = im.getSubimage(0, 0, (int) circledCharacter.getPreferredWidth(stringBounder) + 5, - (int) circledCharacter.getPreferredHeight(stringBounder) + 1); - - ImageIO.write(im, "png", png); - return png; + final Lazy lsvg = new Lazy() { + public String getNow() throws IOException { + return UGraphicG2d.getSvgString(circleInterface); } }; - final Lazy leps = new Lazy() { - public File getNow() throws IOException { - Log.info("Creating temporary file: " + epsFile); - UGraphicEps.copyEpsToFile(circledCharacter, epsFile); - return epsFile; - } - }; + final Object signature = Arrays.asList("lollipop", interfaceBackground, interfaceBorder, background); + + return DrawFile.create(lpng, lsvg, leps, signature); - return new DrawFile(lpng, UGraphicG2d.getSvgString(circledCharacter), leps); } - public final Map getStaticImages() { - return Collections.unmodifiableMap(staticImages); + private DrawFile getCircledCharacter(char c, Color background) throws IOException { + final CircledCharacter circledCharacter = new CircledCharacter(c, radius, circledFont, background, classborder, + Color.BLACK); + return circledCharacter.generateCircleCharacter(classBackground, dpiFactor); } - public final Map getVisibilityImages() { - return Collections.unmodifiableMap(visibilityImages); + public DrawFile getStaticImages(EntityType type) { + return staticImages.get(type); + } + + public final DrawFile getVisibilityImages(VisibilityModifier visibilityModifier) { + return visibilityImages.get(visibilityModifier); } public DrawFile getDrawFile(String pngPath) throws IOException { @@ -376,18 +198,18 @@ public class StaticFiles { return null; } - private DrawFile ensureVisibilityModifierPresent(final VisibilityModifier modifier, final File dir, final int size) - throws IOException { - final UDrawable drawable = modifier.getUDrawable(size, foregroundColor.get(modifier), - backgroundColor.get(modifier)); + private DrawFile getVisibilityModifier(final VisibilityModifier modifier, final File dir, final int size, + final double dpiFactor) throws IOException { + final UDrawable drawable = modifier.getUDrawable(size, foregroundColor.get(modifier), backgroundColor + .get(modifier)); final Lazy lpng = new Lazy() { public File getNow() throws IOException { - final File png = new File(dir, modifier.name() + ".png"); - Log.info("Creating temporary file: " + png); - final EmptyImageBuilder builder = new EmptyImageBuilder(size, size, classBackground); + final File png = FileUtils.createTempFile("visi", ".png"); + final EmptyImageBuilder builder = new EmptyImageBuilder(size * dpiFactor, size * dpiFactor, + classBackground); final BufferedImage im = builder.getBufferedImage(); - drawable.drawU(new UGraphicG2d(builder.getGraphics2D(), im)); + drawable.drawU(new UGraphicG2d(builder.getGraphics2D(), im, dpiFactor)); ImageIO.write(im, "png", png); return png; } @@ -395,14 +217,22 @@ public class StaticFiles { final Lazy leps = new Lazy() { public File getNow() throws IOException { - final File eps = new File(dir, modifier.name() + ".eps"); - Log.info("Creating temporary file: " + eps); + final File eps = FileUtils.createTempFile("visi", ".eps"); UGraphicEps.copyEpsToFile(drawable, eps); return eps; } }; - return new DrawFile(lpng, UGraphicG2d.getSvgString(drawable), leps); + final Lazy lsvg = new Lazy() { + public String getNow() throws IOException { + return UGraphicG2d.getSvgString(drawable); + } + }; + + final Object signature = Arrays.asList("visi", modifier, foregroundColor.get(modifier), backgroundColor + .get(modifier), size, classBackground); + + return DrawFile.create(lpng, lsvg, leps, signature); } } diff --git a/src/net/sourceforge/plantuml/cucadiagram/dot/StaticFilesMap.java b/src/net/sourceforge/plantuml/cucadiagram/dot/StaticFilesMap.java new file mode 100644 index 000000000..5560e8c36 --- /dev/null +++ b/src/net/sourceforge/plantuml/cucadiagram/dot/StaticFilesMap.java @@ -0,0 +1,72 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009, 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 Lesser 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: 5775 $ + * + */ +package net.sourceforge.plantuml.cucadiagram.dot; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import net.sourceforge.plantuml.ISkinParam; + +public class StaticFilesMap { + + private final Map map = new HashMap(); + private final ISkinParam param; + private final double dpiFactor; + + public StaticFilesMap(ISkinParam param, double dpiFactor) { + this.param = param; + this.dpiFactor = dpiFactor; + } + + public StaticFiles getStaticFiles(String stereotype) throws IOException { + StaticFiles result = map.get(stereotype); + if (result == null) { + result = new StaticFiles(param, stereotype, dpiFactor); + map.put(stereotype, result); + } + return result; + } + + public DrawFile getDrawFile(String href) throws IOException { + for (StaticFiles staticFiles : map.values()) { + final DrawFile drawFile = staticFiles.getDrawFile(href); + if (drawFile != null) { + return drawFile; + } + } + return null; + } + +} diff --git a/src/net/sourceforge/plantuml/eggs/GraphicsPath.java b/src/net/sourceforge/plantuml/eggs/GraphicsPath.java index bff654ebf..be52ce32b 100644 --- a/src/net/sourceforge/plantuml/eggs/GraphicsPath.java +++ b/src/net/sourceforge/plantuml/eggs/GraphicsPath.java @@ -57,7 +57,7 @@ public class GraphicsPath { public void writeImage(OutputStream os) throws IOException { final BufferedImage im = createImage(); - PngIO.write(im, os); + PngIO.write(im, os, 96); } private BufferedImage createImage() { @@ -66,7 +66,7 @@ public class GraphicsPath { final BufferedImage im = builder.getBufferedImage(); final Graphics2D g2d = builder.getGraphics2D(); - final UGraphicG2d ug = new UGraphicG2d(g2d, im); + final UGraphicG2d ug = new UGraphicG2d(g2d, im, 1.0); ug.getParam().setColor(Color.BLACK); final UMotif motif = new UMotif(path); motif.drawHorizontal(ug, 20, 20, 1); diff --git a/src/net/sourceforge/plantuml/eggs/PSystemEgg.java b/src/net/sourceforge/plantuml/eggs/PSystemEgg.java index 91a61b721..0b5bd38da 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: 4984 $ + * Revision $Revision: 5794 $ * */ package net.sourceforge.plantuml.eggs; @@ -45,7 +45,7 @@ import java.util.List; import java.util.StringTokenizer; import net.sourceforge.plantuml.AbstractPSystem; -import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.FileFormatOption; import net.sourceforge.plantuml.graphic.GraphicStrings; public class PSystemEgg extends AbstractPSystem { @@ -59,7 +59,7 @@ public class PSystemEgg extends AbstractPSystem { } } - public List createFiles(File suggestedFile, FileFormat fileFormat) throws IOException, InterruptedException { + public List createFiles(File suggestedFile, FileFormatOption fileFormat) throws IOException, InterruptedException { OutputStream os = null; try { os = new FileOutputStream(suggestedFile); @@ -72,7 +72,7 @@ public class PSystemEgg extends AbstractPSystem { return Arrays.asList(suggestedFile); } - public void createFile(OutputStream os, int index, FileFormat fileFormat) throws IOException { + public void createFile(OutputStream os, int index, FileFormatOption fileFormat) throws IOException { getGraphicStrings().writeImage(os, fileFormat); } diff --git a/src/net/sourceforge/plantuml/eggs/PSystemLost.java b/src/net/sourceforge/plantuml/eggs/PSystemLost.java index ee593da1c..81432656e 100644 --- a/src/net/sourceforge/plantuml/eggs/PSystemLost.java +++ b/src/net/sourceforge/plantuml/eggs/PSystemLost.java @@ -44,7 +44,7 @@ import java.util.Arrays; import java.util.List; import net.sourceforge.plantuml.AbstractPSystem; -import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.FileFormatOption; import net.sourceforge.plantuml.graphic.GraphicStrings; public class PSystemLost extends AbstractPSystem { @@ -55,7 +55,7 @@ public class PSystemLost extends AbstractPSystem { strings.add("Thank you for choosing Oceanic Airlines."); } - public List createFiles(File suggestedFile, FileFormat fileFormat) throws IOException, InterruptedException { + public List createFiles(File suggestedFile, FileFormatOption fileFormat) throws IOException, InterruptedException { OutputStream os = null; try { os = new FileOutputStream(suggestedFile); @@ -68,7 +68,7 @@ public class PSystemLost extends AbstractPSystem { return Arrays.asList(suggestedFile); } - public void createFile(OutputStream os, int index, FileFormat fileFormat) throws IOException { + public void createFile(OutputStream os, int index, FileFormatOption fileFormat) throws IOException { getGraphicStrings().writeImage(os, fileFormat); } diff --git a/src/net/sourceforge/plantuml/eggs/PSystemPath.java b/src/net/sourceforge/plantuml/eggs/PSystemPath.java index ac9144ddd..14ae68ecd 100644 --- a/src/net/sourceforge/plantuml/eggs/PSystemPath.java +++ b/src/net/sourceforge/plantuml/eggs/PSystemPath.java @@ -41,7 +41,7 @@ import java.util.Arrays; import java.util.List; import net.sourceforge.plantuml.AbstractPSystem; -import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.FileFormatOption; public class PSystemPath extends AbstractPSystem { @@ -52,7 +52,7 @@ public class PSystemPath extends AbstractPSystem { } - public List createFiles(File suggestedFile, FileFormat fileFormat) throws IOException, InterruptedException { + public List createFiles(File suggestedFile, FileFormatOption fileFormat) throws IOException, InterruptedException { OutputStream os = null; try { os = new FileOutputStream(suggestedFile); @@ -65,7 +65,7 @@ public class PSystemPath extends AbstractPSystem { return Arrays.asList(suggestedFile); } - public void createFile(OutputStream os, int index, FileFormat fileFormat) throws IOException { + public void createFile(OutputStream os, int index, FileFormatOption fileFormat) throws IOException { path.writeImage(os); } diff --git a/src/net/sourceforge/plantuml/eggs/PSystemRIP.java b/src/net/sourceforge/plantuml/eggs/PSystemRIP.java index 2d7d4fbcc..8f29ac0e4 100644 --- a/src/net/sourceforge/plantuml/eggs/PSystemRIP.java +++ b/src/net/sourceforge/plantuml/eggs/PSystemRIP.java @@ -49,7 +49,7 @@ import java.util.List; import javax.imageio.ImageIO; import net.sourceforge.plantuml.AbstractPSystem; -import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.FileFormatOption; import net.sourceforge.plantuml.graphic.GraphicPosition; import net.sourceforge.plantuml.graphic.GraphicStrings; @@ -75,7 +75,7 @@ public class PSystemRIP extends AbstractPSystem { is.close(); } - public List createFiles(File suggestedFile, FileFormat fileFormat) throws IOException, InterruptedException { + public List createFiles(File suggestedFile, FileFormatOption fileFormat) throws IOException, InterruptedException { OutputStream os = null; try { os = new FileOutputStream(suggestedFile); @@ -88,7 +88,7 @@ public class PSystemRIP extends AbstractPSystem { return Arrays.asList(suggestedFile); } - public void createFile(OutputStream os, int index, FileFormat fileFormat) throws IOException { + public void createFile(OutputStream os, int index, FileFormatOption fileFormat) throws IOException { getGraphicStrings().writeImage(os, fileFormat); } diff --git a/src/net/sourceforge/plantuml/eps/SvgToEpsConverter.java b/src/net/sourceforge/plantuml/eps/SvgToEpsConverter.java index 0cf595844..9973a17c1 100644 --- a/src/net/sourceforge/plantuml/eps/SvgToEpsConverter.java +++ b/src/net/sourceforge/plantuml/eps/SvgToEpsConverter.java @@ -40,8 +40,8 @@ import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; +import net.sourceforge.plantuml.FileUtils; import net.sourceforge.plantuml.OptionFlags; -import net.sourceforge.plantuml.cucadiagram.dot.CucaDiagramFileMaker; public class SvgToEpsConverter { @@ -53,7 +53,7 @@ public class SvgToEpsConverter { throw new IllegalArgumentException(); } this.inkscape = InkscapeUtils.create(); - this.svgFile = CucaDiagramFileMaker.createTempFile("convert", ".svg"); + this.svgFile = FileUtils.createTempFile("convert", ".svg"); final PrintWriter pw = new PrintWriter(svgFile); pw.println(svg); pw.close(); @@ -73,7 +73,7 @@ public class SvgToEpsConverter { public void createEps(OutputStream os) throws IOException, InterruptedException { - final File epsFile = CucaDiagramFileMaker.createTempFile("eps", ".eps"); + final File epsFile = FileUtils.createTempFile("eps", ".eps"); createEps(epsFile); int read; final InputStream is = new FileInputStream(epsFile); diff --git a/src/net/sourceforge/plantuml/graph/EntityImageClass.java b/src/net/sourceforge/plantuml/graph/EntityImageClass.java index 6bd3ffc61..19997a89d 100644 --- a/src/net/sourceforge/plantuml/graph/EntityImageClass.java +++ b/src/net/sourceforge/plantuml/graph/EntityImageClass.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5609 $ + * Revision $Revision: 5798 $ * */ package net.sourceforge.plantuml.graph; @@ -146,7 +146,7 @@ class EntityImageClass extends AbstractEntityImage { methods.drawTOBEREMOVED(g2d, xMargin, line2 + yMargin); if (circledCharacter != null) { - circledCharacter.draw(g2d, xMargin, yMargin); + circledCharacter.draw(g2d, xMargin, yMargin, 1.0); } } diff --git a/src/net/sourceforge/plantuml/graph/MethodsOrFieldsArea2.java b/src/net/sourceforge/plantuml/graph/MethodsOrFieldsArea2.java index c54036b0e..90f1babf5 100644 --- a/src/net/sourceforge/plantuml/graph/MethodsOrFieldsArea2.java +++ b/src/net/sourceforge/plantuml/graph/MethodsOrFieldsArea2.java @@ -67,7 +67,7 @@ public class MethodsOrFieldsArea2 { public MethodsOrFieldsArea2(List attributes, FontParam fontParam, ISkinParam skinParam) { this.members.addAll(attributes); this.skinParam = skinParam; - this.font = skinParam.getFont(fontParam); + this.font = skinParam.getFont(fontParam, null); this.color = rose.getFontColor(skinParam, FontParam.CLASS_ATTRIBUTE); } diff --git a/src/net/sourceforge/plantuml/graphic/CircledCharacter.java b/src/net/sourceforge/plantuml/graphic/CircledCharacter.java index 403732378..1ddff1409 100644 --- a/src/net/sourceforge/plantuml/graphic/CircledCharacter.java +++ b/src/net/sourceforge/plantuml/graphic/CircledCharacter.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5594 $ + * Revision $Revision: 5804 $ * */ package net.sourceforge.plantuml.graphic; @@ -41,13 +41,24 @@ import java.awt.font.FontRenderContext; import java.awt.font.TextLayout; import java.awt.geom.Dimension2D; import java.awt.geom.PathIterator; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.util.Arrays; + +import javax.imageio.ImageIO; import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.EmptyImageBuilder; +import net.sourceforge.plantuml.FileUtils; +import net.sourceforge.plantuml.cucadiagram.dot.DrawFile; +import net.sourceforge.plantuml.cucadiagram.dot.Lazy; import net.sourceforge.plantuml.skin.UDrawable; import net.sourceforge.plantuml.ugraphic.UEllipse; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UPath; import net.sourceforge.plantuml.ugraphic.USegmentType; +import net.sourceforge.plantuml.ugraphic.eps.UGraphicEps; import net.sourceforge.plantuml.ugraphic.g2d.UGraphicG2d; public class CircledCharacter implements UDrawable, TextBlock { @@ -68,8 +79,8 @@ public class CircledCharacter implements UDrawable, TextBlock { this.fontColor = fontColor; } - public void draw(Graphics2D g2d, int x, int y) { - drawU(new UGraphicG2d(g2d, null), x, y); + public void draw(Graphics2D g2d, int x, int y, double dpiFactor) { + drawU(new UGraphicG2d(g2d, null, 1.0), x, y); } public void drawU(UGraphic ug, double x, double y) { @@ -78,28 +89,14 @@ public class CircledCharacter implements UDrawable, TextBlock { ug.getParam().setColor(circle); } - // final Color circleToUse = circle == null ? ug.getParam().getColor() : circle; - // ug.getParam().setColor(circleToUse); - ug.getParam().setBackcolor(innerCircle); ug.draw(x, y, new UEllipse(radius * 2, radius * 2)); - ug.getParam().setColor(fontColor); - - // if (ug instanceof UGraphicSvg) { - // final UPath p = getUPath(new FontRenderContext(null, true, true)); - // ug.draw(x + radius, y + radius, p); - // } else { ug.centerChar(x + radius, y + radius, c.charAt(0), font); - // } } - private Dimension2D getStringDimension(StringBounder stringBounder) { - return stringBounder.calculateDimension(font, c); - } - final public double getPreferredWidth(StringBounder stringBounder) { return 2 * radius; } @@ -125,7 +122,6 @@ public class CircledCharacter implements UDrawable, TextBlock { final double coord[] = new double[6]; while (path.isDone() == false) { - // final int w = path.getWindingRule(); final int code = path.currentSegment(coord); result.add(coord, USegmentType.getByCode(code)); path.next(); @@ -142,4 +138,45 @@ public class CircledCharacter implements UDrawable, TextBlock { throw new UnsupportedOperationException(); } + public DrawFile generateCircleCharacter(final Color background, final double dpiFactor) throws IOException { + + final Lazy lpng = new Lazy() { + + public File getNow() throws IOException { + final File png = FileUtils.createTempFile("circle", ".png"); + final EmptyImageBuilder builder = new EmptyImageBuilder((int)(60 * dpiFactor), (int)(60 * dpiFactor), background, dpiFactor); + BufferedImage im = builder.getBufferedImage(); + final Graphics2D g2d = builder.getGraphics2D(); + final StringBounder stringBounder = StringBounderUtils.asStringBounder(g2d); + + draw(g2d, 0, 0, dpiFactor); + im = im.getSubimage(0, 0, (int) (getPreferredWidth(stringBounder) * dpiFactor) + 5, + (int) (getPreferredHeight(stringBounder) * dpiFactor) + 1); + + ImageIO.write(im, "png", png); + return png; + } + }; + + final Lazy leps = new Lazy() { + public File getNow() throws IOException { + final File epsFile = FileUtils.createTempFile("circle", ".eps"); + UGraphicEps.copyEpsToFile(CircledCharacter.this, epsFile); + return epsFile; + } + }; + + final Lazy lsvg = new Lazy() { + public String getNow() throws IOException { + return UGraphicG2d.getSvgString(CircledCharacter.this); + } + + }; + + final Object signature = Arrays.asList("circle", c, font, innerCircle, circle, fontColor, radius, background, + dpiFactor); + + return DrawFile.create(lpng, lsvg, leps, signature); + } + } diff --git a/src/net/sourceforge/plantuml/graphic/GraphicStrings.java b/src/net/sourceforge/plantuml/graphic/GraphicStrings.java index 0864acb9a..365caae55 100644 --- a/src/net/sourceforge/plantuml/graphic/GraphicStrings.java +++ b/src/net/sourceforge/plantuml/graphic/GraphicStrings.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5326 $ + * Revision $Revision: 5872 $ * */ package net.sourceforge.plantuml.graphic; @@ -47,6 +47,7 @@ import java.util.List; import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.EmptyImageBuilder; import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.FileFormatOption; import net.sourceforge.plantuml.png.PngIO; import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UImage; @@ -95,14 +96,15 @@ public class GraphicStrings { this.disableTextAliasing = disableTextAliasing; } - public void writeImage(OutputStream os, FileFormat fileFormat) throws IOException { + public void writeImage(OutputStream os, FileFormatOption fileFormat) throws IOException { writeImage(os, null, fileFormat); } - public void writeImage(OutputStream os, String metadata, FileFormat fileFormat) throws IOException { + public void writeImage(OutputStream os, String metadata, FileFormatOption fileFormatOption) throws IOException { + final FileFormat fileFormat = fileFormatOption.getFileFormat(); if (fileFormat == FileFormat.PNG) { final BufferedImage im = createImage(); - PngIO.write(im, os, metadata); + PngIO.write(im, os, metadata, 96); } else if (fileFormat == FileFormat.SVG || fileFormat == FileFormat.EPS_VIA_SVG) { final UGraphicSvg svg = new UGraphicSvg(HtmlColor.getAsHtml(background), false); drawU(svg); @@ -121,16 +123,16 @@ public class GraphicStrings { // BufferedImage im = builder.getBufferedImage(); Graphics2D g2d = builder.getGraphics2D(); - final Dimension2D size = drawU(new UGraphicG2d(g2d, null)); + final Dimension2D size = drawU(new UGraphicG2d(g2d, null, 1.0)); g2d.dispose(); - builder = new EmptyImageBuilder((int) size.getWidth(), (int) size.getHeight(), background); + builder = new EmptyImageBuilder(size.getWidth(), size.getHeight(), background); final BufferedImage im = builder.getBufferedImage(); g2d = builder.getGraphics2D(); if (disableTextAliasing) { g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); } - drawU(new UGraphicG2d(g2d, null)); + drawU(new UGraphicG2d(g2d, null, 1.0)); g2d.dispose(); return im; } diff --git a/src/net/sourceforge/plantuml/graphic/Img.java b/src/net/sourceforge/plantuml/graphic/Img.java index 5032d4c78..2022b14ba 100644 --- a/src/net/sourceforge/plantuml/graphic/Img.java +++ b/src/net/sourceforge/plantuml/graphic/Img.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5072 $ + * Revision $Revision: 5697 $ * */ package net.sourceforge.plantuml.graphic; @@ -42,7 +42,7 @@ import javax.imageio.ImageIO; import net.sourceforge.plantuml.FileSystem; -class Img implements HtmlCommand { +public class Img implements HtmlCommand { final static private Pattern srcPattern = Pattern.compile("(?i)src\\s*=\\s*[\"']?([^ \">]+)[\"']?"); final static private Pattern vspacePattern = Pattern.compile("(?i)vspace\\s*=\\s*[\"']?(\\d+)[\"']?"); @@ -50,9 +50,11 @@ class Img implements HtmlCommand { final static private Pattern srcPattern2 = Pattern.compile("(?i)" + Splitter.imgPattern2); private final TileImage tileImage; + private final String filePath; - private Img(TileImage image) throws IOException { + private Img(TileImage image, String filePath) throws IOException { this.tileImage = image; + this.filePath = filePath; } static int getVspace(String html) { @@ -82,10 +84,9 @@ class Img implements HtmlCommand { if (f.exists() == false) { return new Text("(File not found: " + f + ")"); } - final int vspace = getVspace(html); final ImgValign valign = getValign(html); - return new Img(new TileImage(ImageIO.read(f), valign, vspace)); + return new Img(new TileImage(ImageIO.read(f), valign, vspace), src); } catch (IOException e) { return new Text("ERROR " + e.toString()); } @@ -102,8 +103,7 @@ class Img implements HtmlCommand { if (f.exists() == false) { return new Text("(File not found: " + f + ")"); } - - return new Img(new TileImage(ImageIO.read(f), ImgValign.TOP, 0)); + return new Img(new TileImage(ImageIO.read(f), ImgValign.TOP, 0), src); } catch (IOException e) { return new Text("ERROR " + e.toString()); } @@ -112,4 +112,8 @@ class Img implements HtmlCommand { public TileImage createMonoImage() { return tileImage; } + + public final String getFilePath() { + return filePath; + } } diff --git a/src/net/sourceforge/plantuml/graphic/SingleLine.java b/src/net/sourceforge/plantuml/graphic/SingleLine.java index 30765baf7..209f41abb 100644 --- a/src/net/sourceforge/plantuml/graphic/SingleLine.java +++ b/src/net/sourceforge/plantuml/graphic/SingleLine.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 3834 $ + * Revision $Revision: 5741 $ * */ package net.sourceforge.plantuml.graphic; @@ -49,12 +49,15 @@ class SingleLine implements Line { private final HorizontalAlignement horizontalAlignement; public SingleLine(String text, Font font, Color paint, HorizontalAlignement horizontalAlignement) { + if (text.length() == 0) { + text = " "; + } this.horizontalAlignement = horizontalAlignement; final Splitter lineSplitter = new Splitter(text); FontConfiguration fontConfiguration = new FontConfiguration(font, paint); - for (HtmlCommand cmd : lineSplitter.getHtmlCommands()) { + for (HtmlCommand cmd : lineSplitter.getHtmlCommands(false)) { if (cmd instanceof Text) { final String s = ((Text) cmd).getText(); blocs.add(new TileText(s, fontConfiguration)); diff --git a/src/net/sourceforge/plantuml/graphic/Splitter.java b/src/net/sourceforge/plantuml/graphic/Splitter.java index 65ac021fe..af2b10c7d 100644 --- a/src/net/sourceforge/plantuml/graphic/Splitter.java +++ b/src/net/sourceforge/plantuml/graphic/Splitter.java @@ -28,12 +28,13 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5072 $ + * Revision $Revision: 5705 $ * */ package net.sourceforge.plantuml.graphic; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.EnumSet; import java.util.List; @@ -79,8 +80,7 @@ public class Splitter { sb.append(imgPattern2); htmlTag = sb.toString(); - tagOrText = Pattern.compile(htmlTag + "|.+?(?=" + htmlTag + ")|.+$", - Pattern.CASE_INSENSITIVE); + tagOrText = Pattern.compile(htmlTag + "|.+?(?=" + htmlTag + ")|.+$", Pattern.CASE_INSENSITIVE); } private final List splitted = new ArrayList(); @@ -98,13 +98,34 @@ public class Splitter { return splitted; } - public List getHtmlCommands() { + public List getHtmlCommands(boolean newLineAlone) { final HtmlCommandFactory factory = new HtmlCommandFactory(); final List result = new ArrayList(); for (String s : getSplittedInternal()) { - result.add(factory.getHtmlCommand(s)); + final HtmlCommand cmd = factory.getHtmlCommand(s); + if (newLineAlone && cmd instanceof Text) { + result.addAll(splitText((Text) cmd)); + } else { + result.add(cmd); + } } return Collections.unmodifiableList(result); } + private Collection splitText(Text cmd) { + String s = cmd.getText(); + final Collection result = new ArrayList(); + while (true) { + int x = s.indexOf(Text.NEWLINE.getText()); + if (x == -1) { + result.add(new Text(s)); + return result; + } + if (x > 0) { + result.add(new Text(s.substring(0, x))); + } + result.add(Text.NEWLINE); + s = s.substring(x + 2); + } + } } diff --git a/src/net/sourceforge/plantuml/graphic/Text.java b/src/net/sourceforge/plantuml/graphic/Text.java index e80ea7682..29fd812d1 100644 --- a/src/net/sourceforge/plantuml/graphic/Text.java +++ b/src/net/sourceforge/plantuml/graphic/Text.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 3834 $ + * Revision $Revision: 5705 $ * */ package net.sourceforge.plantuml.graphic; @@ -37,11 +37,24 @@ public class Text implements HtmlCommand { private final String text; + public static final Text NEWLINE = new Text("\\n"); + Text(String text) { this.text = text; + if (text.indexOf('\n') != -1) { + throw new IllegalArgumentException(); + } + if (text.length() == 0) { + throw new IllegalArgumentException(); + } } public String getText() { + assert text.length() > 0; return text; } + + public boolean isNewline() { + return text.equals("\\n"); + } } diff --git a/src/net/sourceforge/plantuml/graphic/TextBlockEmpty.java b/src/net/sourceforge/plantuml/graphic/TextBlockEmpty.java new file mode 100644 index 000000000..f457cc48a --- /dev/null +++ b/src/net/sourceforge/plantuml/graphic/TextBlockEmpty.java @@ -0,0 +1,54 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009, 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 Lesser 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: 4125 $ + * + */ +package net.sourceforge.plantuml.graphic; + +import java.awt.Graphics2D; +import java.awt.geom.Dimension2D; + +import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.ugraphic.UGraphic; + +public class TextBlockEmpty implements TextBlock { + + public Dimension2D calculateDimension(StringBounder stringBounder) { + return new Dimension2DDouble(0, 0); + } + + public void drawTOBEREMOVED(Graphics2D g2d, double x, double y) { + } + + public void drawU(UGraphic ug, double x, double y) { + } + +} \ No newline at end of file diff --git a/src/net/sourceforge/plantuml/graphic/TileText.java b/src/net/sourceforge/plantuml/graphic/TileText.java index e7065fc33..d69a03b8a 100644 --- a/src/net/sourceforge/plantuml/graphic/TileText.java +++ b/src/net/sourceforge/plantuml/graphic/TileText.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5507 $ + * Revision $Revision: 5757 $ * */ package net.sourceforge.plantuml.graphic; @@ -37,6 +37,7 @@ import java.awt.BasicStroke; import java.awt.FontMetrics; import java.awt.Graphics2D; import java.awt.geom.Dimension2D; +import java.util.StringTokenizer; import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.Log; @@ -61,7 +62,8 @@ class TileText implements Tile { if (h < 10) { h = 10; } - return new Dimension2DDouble(rect.getWidth(), h); + final double width = text.indexOf('\t') == -1 ? rect.getWidth() : getWidth(stringBounder); + return new Dimension2DDouble(width, h); } public double getFontSize2D() { @@ -91,11 +93,47 @@ class TileText implements Tile { } } - public void drawU(UGraphic ug, double x, double y) { - final UText utext = new UText(text, fontConfiguration); - ug.getParam().setColor(fontConfiguration.getColor()); - ug.draw(x, y, utext); + double getTabSize(StringBounder stringBounder) { + return stringBounder.calculateDimension(fontConfiguration.getFont(), " ").getWidth(); + } + public void drawU(UGraphic ug, double x, double y) { + ug.getParam().setColor(fontConfiguration.getColor()); + + final StringTokenizer tokenizer = new StringTokenizer(text, "\t", true); + + if (tokenizer.hasMoreTokens()) { + final double tabSize = getTabSize(ug.getStringBounder()); + while (tokenizer.hasMoreTokens()) { + final String s = tokenizer.nextToken(); + if (s.equals("\t")) { + final double remainder = x % tabSize; + x += tabSize - remainder; + } else { + final UText utext = new UText(s, fontConfiguration); + ug.draw(x, y, utext); + final Dimension2D dim = ug.getStringBounder().calculateDimension(fontConfiguration.getFont(), s); + x += dim.getWidth(); + } + } + } + } + + double getWidth(StringBounder stringBounder) { + final StringTokenizer tokenizer = new StringTokenizer(text, "\t", true); + final double tabSize = getTabSize(stringBounder); + double x = 0; + while (tokenizer.hasMoreTokens()) { + final String s = tokenizer.nextToken(); + if (s.equals("\t")) { + final double remainder = x % tabSize; + x += tabSize - remainder; + } else { + final Dimension2D dim = stringBounder.calculateDimension(fontConfiguration.getFont(), s); + x += dim.getWidth(); + } + } + return x; } } diff --git a/src/net/sourceforge/plantuml/objectdiagram/ObjectDiagramFactory.java b/src/net/sourceforge/plantuml/objectdiagram/ObjectDiagramFactory.java index c9a2fea71..cd4344df6 100644 --- a/src/net/sourceforge/plantuml/objectdiagram/ObjectDiagramFactory.java +++ b/src/net/sourceforge/plantuml/objectdiagram/ObjectDiagramFactory.java @@ -33,7 +33,7 @@ */ package net.sourceforge.plantuml.objectdiagram; -import net.sourceforge.plantuml.classdiagram.command.CommandLinkClass; +import net.sourceforge.plantuml.classdiagram.command.CommandLinkClass2; import net.sourceforge.plantuml.classdiagram.command.CommandMultilinesClassNote; import net.sourceforge.plantuml.command.AbstractUmlSystemCommandFactory; import net.sourceforge.plantuml.command.CommandCreateNote; @@ -62,7 +62,7 @@ public class ObjectDiagramFactory extends AbstractUmlSystemCommandFactory { addCommand(new CommandPage(system)); addCommand(new CommandAddData(system)); - addCommand(new CommandLinkClass(system)); + addCommand(new CommandLinkClass2(system)); // addCommand(new CommandCreateEntityObject(system)); addCommand(new CommandCreateNote(system)); diff --git a/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObject.java b/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObject.java index 01d70d8c2..746483114 100644 --- a/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObject.java +++ b/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObject.java @@ -61,7 +61,7 @@ public class CommandCreateEntityObject extends SingleLineCommand final Entity entity = getSystem().createEntity(code, display, EntityType.OBJECT); if (stereotype != null) { entity.setStereotype(new Stereotype(stereotype, getSystem().getSkinParam().getCircledCharacterRadius(), - getSystem().getSkinParam().getFont(FontParam.CIRCLED_CHARACTER))); + getSystem().getSkinParam().getFont(FontParam.CIRCLED_CHARACTER, null))); } return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObjectMultilines.java b/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObjectMultilines.java index 8ab3fb59b..9aab4eb9f 100644 --- a/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObjectMultilines.java +++ b/src/net/sourceforge/plantuml/objectdiagram/command/CommandCreateEntityObjectMultilines.java @@ -55,7 +55,8 @@ public class CommandCreateEntityObjectMultilines extends CommandMultilines lines) { - final List line0 = StringUtils.getSplit(getStartingPattern(), lines.get(0)); + StringUtils.trim(lines); + final List line0 = StringUtils.getSplit(getStartingPattern(), lines.get(0).trim()); final Entity entity = executeArg0(line0); if (entity == null) { return CommandExecutionResult.error("No such entity"); @@ -79,7 +80,7 @@ public class CommandCreateEntityObjectMultilines extends CommandMultilines createFiles(File suggestedFile, FileFormat fileFormat) throws IOException, InterruptedException { + public List createFiles(File suggestedFile, FileFormatOption fileFormat) throws IOException, InterruptedException { OutputStream os = null; try { os = new FileOutputStream(suggestedFile); @@ -75,7 +75,7 @@ public class PSystemOregon extends AbstractPSystem { return Arrays.asList(suggestedFile); } - public void createFile(OutputStream os, int index, FileFormat fileFormat) throws IOException { + public void createFile(OutputStream os, int index, FileFormatOption fileFormat) throws IOException { getGraphicStrings().writeImage(os, fileFormat); } diff --git a/src/net/sourceforge/plantuml/png/PngIO.java b/src/net/sourceforge/plantuml/png/PngIO.java index 570ec2e94..e5573f14d 100644 --- a/src/net/sourceforge/plantuml/png/PngIO.java +++ b/src/net/sourceforge/plantuml/png/PngIO.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 4301 $ + * Revision $Revision: 5872 $ * */ package net.sourceforge.plantuml.png; @@ -47,19 +47,19 @@ public class PngIO { private static final String copyleft = "Generated by http://plantuml.sourceforge.net"; - public static void write(RenderedImage image, File file) throws IOException { - write(image, file, null); + public static void write(RenderedImage image, File file, int dpi) throws IOException { + write(image, file, null, dpi); } - public static void write(RenderedImage image, OutputStream os) throws IOException { - write(image, os, null); + public static void write(RenderedImage image, OutputStream os, int dpi) throws IOException { + write(image, os, null, dpi); } - public static void write(RenderedImage image, File file, String metadata) throws IOException { + public static void write(RenderedImage image, File file, String metadata, int dpi) throws IOException { OutputStream os = null; try { os = new FileOutputStream(file); - write(image, os, metadata); + write(image, os, metadata, dpi); } finally { if (os != null) { os.close(); @@ -73,9 +73,9 @@ public class PngIO { } } - public static void write(RenderedImage image, OutputStream os, String metadata) throws IOException { + public static void write(RenderedImage image, OutputStream os, String metadata, int dpi) throws IOException { if (checkPNGMetadata()) { - PngIOMetadata.writeWithMetadata(image, os, metadata); + PngIOMetadata.writeWithMetadata(image, os, metadata, dpi); } else { ImageIO.write(image, "png", os); } diff --git a/src/net/sourceforge/plantuml/png/PngIOMetadata.java b/src/net/sourceforge/plantuml/png/PngIOMetadata.java index 262f1d634..262ae164e 100644 --- a/src/net/sourceforge/plantuml/png/PngIOMetadata.java +++ b/src/net/sourceforge/plantuml/png/PngIOMetadata.java @@ -50,7 +50,7 @@ public class PngIOMetadata { private static final String copyleft = "Generated by http://plantuml.sourceforge.net"; - public static void writeWithMetadata(RenderedImage image, OutputStream os, String metadata) throws IOException { + public static void writeWithMetadata(RenderedImage image, OutputStream os, String metadata, int dpi) throws IOException { final ImageWriter imagewriter = getImageWriter(); Log.debug("PngIOMetadata imagewriter=" + imagewriter); @@ -60,6 +60,13 @@ public class PngIOMetadata { // Create & populate metadata final PNGMetadata pngMetadata = new PNGMetadata(); + if (dpi != 96) { + pngMetadata.pHYs_present = true; + pngMetadata.pHYs_unitSpecifier = PNGMetadata.PHYS_UNIT_METER; + pngMetadata.pHYs_pixelsPerUnitXAxis = (int) Math.round(dpi / .0254 + 0.5); + pngMetadata.pHYs_pixelsPerUnitYAxis = pngMetadata.pHYs_pixelsPerUnitXAxis; + } + if (metadata != null) { pngMetadata.zTXt_keyword.add("plantuml"); pngMetadata.zTXt_compressionMethod.add(new Integer(0)); diff --git a/src/net/sourceforge/plantuml/png/PngSplitter.java b/src/net/sourceforge/plantuml/png/PngSplitter.java index f735945ff..3a0f227d9 100644 --- a/src/net/sourceforge/plantuml/png/PngSplitter.java +++ b/src/net/sourceforge/plantuml/png/PngSplitter.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 4165 $ + * Revision $Revision: 5872 $ * */ package net.sourceforge.plantuml.png; @@ -50,7 +50,7 @@ public class PngSplitter { private final List files = new ArrayList(); - public PngSplitter(File pngFile, int horizontalPages, int verticalPages, String source) throws IOException { + public PngSplitter(File pngFile, int horizontalPages, int verticalPages, String source, int dpi) throws IOException { if (horizontalPages == 1 && verticalPages == 1) { this.files.add(pngFile); return; @@ -81,7 +81,7 @@ public class PngSplitter { final BufferedImage imPiece = im.getSubimage(horizontalSegment.getStart(i), verticalSegment.getStart(j), horizontalSegment.getLen(i), verticalSegment.getLen(j)); Thread.yield(); - PngIO.write(imPiece, f, source); + PngIO.write(imPiece, f, source, dpi); Thread.yield(); } } diff --git a/src/net/sourceforge/plantuml/png/PngTitler.java b/src/net/sourceforge/plantuml/png/PngTitler.java index 7a6adc32e..353b17818 100644 --- a/src/net/sourceforge/plantuml/png/PngTitler.java +++ b/src/net/sourceforge/plantuml/png/PngTitler.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 4179 $ + * Revision $Revision: 5793 $ * */ package net.sourceforge.plantuml.png; @@ -137,7 +137,7 @@ public class PngTitler { } g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - textBloc.drawU(new UGraphicG2d(g2d, null), xText, yText); + textBloc.drawU(new UGraphicG2d(g2d, null, 1.0), xText, yText); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); final double delta2 = (width - im.getWidth()) / 2; diff --git a/src/net/sourceforge/plantuml/posimo/AbstractEntityImage2.java b/src/net/sourceforge/plantuml/posimo/AbstractEntityImage2.java index 9464cdf48..c88c6fb81 100644 --- a/src/net/sourceforge/plantuml/posimo/AbstractEntityImage2.java +++ b/src/net/sourceforge/plantuml/posimo/AbstractEntityImage2.java @@ -66,11 +66,11 @@ abstract class AbstractEntityImage2 implements IEntityImageBlock { } protected Font getFont(FontParam fontParam) { - return skinParam.getFont(fontParam); + return skinParam.getFont(fontParam, null); } protected Color getFontColor(FontParam fontParam) { - return skinParam.getFontHtmlColor(fontParam).getColor(); + return skinParam.getFontHtmlColor(fontParam, null).getColor(); } protected final Color getColor(ColorParam colorParam) { diff --git a/src/net/sourceforge/plantuml/posimo/EntityImageBlock.java b/src/net/sourceforge/plantuml/posimo/EntityImageBlock.java index e4c30f06b..60a7dfcf7 100644 --- a/src/net/sourceforge/plantuml/posimo/EntityImageBlock.java +++ b/src/net/sourceforge/plantuml/posimo/EntityImageBlock.java @@ -78,7 +78,7 @@ public class EntityImageBlock implements IEntityImageBlock { if (StringUtils.isNotEmpty(entity.getDisplay())) { this.name = TextBlockUtils.create(StringUtils.getWithNewlines(entity.getDisplay()), - param.getFont(titleParam), Color.BLACK, HorizontalAlignement.CENTER); + param.getFont(titleParam, null), Color.BLACK, HorizontalAlignement.CENTER); } else { this.name = null; } diff --git a/src/net/sourceforge/plantuml/posimo/EntityImageNote2.java b/src/net/sourceforge/plantuml/posimo/EntityImageNote2.java index 68d1697d9..5e88c9580 100644 --- a/src/net/sourceforge/plantuml/posimo/EntityImageNote2.java +++ b/src/net/sourceforge/plantuml/posimo/EntityImageNote2.java @@ -38,7 +38,6 @@ import java.util.Collection; import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.ISkinParam; -import net.sourceforge.plantuml.SkinParamBackcolored; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.cucadiagram.IEntity; import net.sourceforge.plantuml.cucadiagram.Link; diff --git a/src/net/sourceforge/plantuml/posimo/Frame.java b/src/net/sourceforge/plantuml/posimo/Frame.java index 8e222c5e9..5604c0251 100644 --- a/src/net/sourceforge/plantuml/posimo/Frame.java +++ b/src/net/sourceforge/plantuml/posimo/Frame.java @@ -114,8 +114,8 @@ public class Frame implements Component { } private TextBlock createTextBloc() { - final Font font = skinParam.getFont(FontParam.PACKAGE); - final Color textColor = skinParam.getFontHtmlColor(FontParam.PACKAGE).getColor(); + final Font font = skinParam.getFont(FontParam.PACKAGE, null); + final Color textColor = skinParam.getFontHtmlColor(FontParam.PACKAGE, null).getColor(); final TextBlock bloc = TextBlockUtils.create(name, font, textColor, HorizontalAlignement.LEFT); return bloc; } diff --git a/src/net/sourceforge/plantuml/posimo/LabelImage.java b/src/net/sourceforge/plantuml/posimo/LabelImage.java index e5a2a0886..c91066e45 100644 --- a/src/net/sourceforge/plantuml/posimo/LabelImage.java +++ b/src/net/sourceforge/plantuml/posimo/LabelImage.java @@ -61,7 +61,7 @@ public class LabelImage { // this.entity = entity; this.param = param; this.rose = rose; - this.name = TextBlockUtils.create(StringUtils.getWithNewlines(link.getLabel()), param.getFont(FontParam.CLASS), + this.name = TextBlockUtils.create(StringUtils.getWithNewlines(link.getLabel()), param.getFont(FontParam.CLASS, null), Color.BLACK, HorizontalAlignement.CENTER); } diff --git a/src/net/sourceforge/plantuml/posimo/PathDrawerInterface.java b/src/net/sourceforge/plantuml/posimo/PathDrawerInterface.java index 51fa15a06..1559f9aab 100644 --- a/src/net/sourceforge/plantuml/posimo/PathDrawerInterface.java +++ b/src/net/sourceforge/plantuml/posimo/PathDrawerInterface.java @@ -153,6 +153,9 @@ public class PathDrawerInterface implements PathDrawer { } private Point2D drawSymbol(UGraphic ug, double theta, final Point2D position, LinkDecor decor) { + if (1==1) { + return null; + } Point2D middle1 = null; // final double theta = Math.atan2( // -direction.getX() + position.getX(), direction.getY() diff --git a/src/net/sourceforge/plantuml/preproc/UncommentReadLine.java b/src/net/sourceforge/plantuml/preproc/UncommentReadLine.java index 89c23d6a4..7e5d9accf 100644 --- a/src/net/sourceforge/plantuml/preproc/UncommentReadLine.java +++ b/src/net/sourceforge/plantuml/preproc/UncommentReadLine.java @@ -57,10 +57,10 @@ public class UncommentReadLine implements ReadLine { } public static String cleanLineFromSource(String s) { - s = s.trim(); - while (s.startsWith(" ") || s.startsWith("\t")) { - s = s.substring(1).trim(); - } +// s = s.trim(); +// while (s.startsWith(" ") || s.startsWith("\t")) { +// s = s.substring(1).trim(); +// } return s; } diff --git a/src/net/sourceforge/plantuml/printskin/PrintSkin.java b/src/net/sourceforge/plantuml/printskin/PrintSkin.java index 49065aabb..2fd4ca6ed 100644 --- a/src/net/sourceforge/plantuml/printskin/PrintSkin.java +++ b/src/net/sourceforge/plantuml/printskin/PrintSkin.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 4633 $ + * Revision $Revision: 5872 $ * */ package net.sourceforge.plantuml.printskin; @@ -47,7 +47,7 @@ import java.util.List; import net.sourceforge.plantuml.AbstractPSystem; import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.EmptyImageBuilder; -import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.FileFormatOption; import net.sourceforge.plantuml.SkinParam; import net.sourceforge.plantuml.graphic.HorizontalAlignement; import net.sourceforge.plantuml.graphic.TextBlock; @@ -73,18 +73,18 @@ class PrintSkin extends AbstractPSystem { private float ypos = 0; private float maxYpos = 0; - public List createFiles(File suggestedFile, FileFormat fileFormat) throws IOException, InterruptedException { + public List createFiles(File suggestedFile, FileFormatOption fileFormat) throws IOException, InterruptedException { final List result = Arrays.asList(suggestedFile); final BufferedImage im = createImage(); - PngIO.write(im.getSubimage(0, 0, im.getWidth(), (int) maxYpos), suggestedFile); + PngIO.write(im.getSubimage(0, 0, im.getWidth(), (int) maxYpos), suggestedFile, 96); return result; } - public void createFile(OutputStream os, int index, FileFormat fileFormat) throws IOException { + public void createFile(OutputStream os, int index, FileFormatOption fileFormat) throws IOException { final BufferedImage im = createImage(); - PngIO.write(im.getSubimage(0, 0, im.getWidth(), (int) maxYpos), os); + PngIO.write(im.getSubimage(0, 0, im.getWidth(), (int) maxYpos), os, 96); } private BufferedImage createImage() { @@ -93,7 +93,7 @@ class PrintSkin extends AbstractPSystem { final BufferedImage im = builder.getBufferedImage(); final Graphics2D g2d = builder.getGraphics2D(); - ug = new UGraphicG2d(g2d, null); + ug = new UGraphicG2d(g2d, null, 1.0); for (ComponentType type : EnumSet.allOf(ComponentType.class)) { printComponent(type); diff --git a/src/net/sourceforge/plantuml/sequencediagram/InGroupable.java b/src/net/sourceforge/plantuml/sequencediagram/InGroupable.java index 84ea61791..3bac663a4 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/InGroupable.java +++ b/src/net/sourceforge/plantuml/sequencediagram/InGroupable.java @@ -42,5 +42,5 @@ public interface InGroupable { public double getMaxX(StringBounder stringBounder); public String toString(StringBounder stringBounder); - + } diff --git a/src/net/sourceforge/plantuml/sequencediagram/InGroupableList.java b/src/net/sourceforge/plantuml/sequencediagram/InGroupableList.java index 69f21c168..d2aabc963 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/InGroupableList.java +++ b/src/net/sourceforge/plantuml/sequencediagram/InGroupableList.java @@ -33,35 +33,38 @@ */ package net.sourceforge.plantuml.sequencediagram; +import java.util.ArrayList; import java.util.HashSet; +import java.util.List; import java.util.Set; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.sequencediagram.graphic.LivingParticipantBox; +import net.sourceforge.plantuml.sequencediagram.graphic.MessageExoArrow; import net.sourceforge.plantuml.sequencediagram.graphic.ParticipantBox; -import net.sourceforge.plantuml.sequencediagram.graphic.VirtualHBar; -import net.sourceforge.plantuml.sequencediagram.graphic.VirtualHBarType; public class InGroupableList implements InGroupable { - //public static boolean NEW_METHOD = true; + private static final int MARGIN5 = 5; + public static final int MARGIN10 = 10; private final GroupingStart groupingStart; private final Set inGroupables = new HashSet(); - private final VirtualHBar barStart; - private final VirtualHBar barEnd; private double minWidth; - public InGroupableList(GroupingStart groupingStart, double startingY) { - this.groupingStart = groupingStart; - this.barStart = new VirtualHBar(10, VirtualHBarType.START, startingY); - this.barEnd = new VirtualHBar(10, VirtualHBarType.END, startingY); + public List getInnerList() { + final List result = new ArrayList(); + for (InGroupable i : inGroupables) { + if (i instanceof InGroupableList) { + result.add((InGroupableList) i); + } + } + return result; } - public final void setEndingY(double endingY) { - this.barStart.setEndingY(endingY); - this.barEnd.setEndingY(endingY); + public InGroupableList(GroupingStart groupingStart, double startingY) { + this.groupingStart = groupingStart; } public void addInGroupable(InGroupable in) { @@ -86,35 +89,23 @@ public class InGroupableList implements InGroupable { return sb.toString(); } - public double getMinX(StringBounder stringBounder) { - if (inGroupables.size() == 0) { - return 0; - } - double result = Double.MAX_VALUE; + private InGroupable getMin(StringBounder stringBounder) { + InGroupable result = null; for (InGroupable in : inGroupables) { - final double v = in.getMinX(stringBounder); - if (v < result) { - result = v; + if (result == null || in.getMinX(stringBounder) < result.getMinX(stringBounder)) { + result = in; } } return result; } - public double getMaxX(StringBounder stringBounder) { - if (inGroupables.size() == 0) { - return minWidth; - } - double result = 0; + private InGroupable getMax(StringBounder stringBounder) { + InGroupable result = null; for (InGroupable in : inGroupables) { - final double v = in.getMaxX(stringBounder); - if (v > result) { - result = v; + if (result == null || in.getMaxX(stringBounder) > result.getMaxX(stringBounder)) { + result = in; } } - final double minX = getMinX(stringBounder); - if (result < minX + minWidth) { - return minX + minWidth; - } return result; } @@ -148,28 +139,48 @@ public class InGroupableList implements InGroupable { return last; } - // public void pushAllToLeft(double delta) { - // for (InGroupable in : inGroupables) { - // System.err.println("in=" + in); - // if (in instanceof LivingParticipantBox) { - // final ParticipantBox participantBox = ((LivingParticipantBox) - // in).getParticipantBox(); - // System.err.println("PUSHING " + participantBox + " " + delta); - // participantBox.pushToLeft(delta); - // } - // } - // } - // - // public final double getBarStartX(StringBounder stringBounder) { - // return getMinX(stringBounder) - barStart.getWidth() / 2; - // } - - public final VirtualHBar getBarStart() { - return barStart; + public double getMinX(StringBounder stringBounder) { + final InGroupable min = getMin(stringBounder); + if (min == null) { + return 0; + } + double m = min.getMinX(stringBounder); + if (min instanceof MessageExoArrow + && (((MessageExoArrow) min).getType() == MessageExoType.FROM_LEFT || ((MessageExoArrow) min).getType() == MessageExoType.TO_LEFT)) { + m += 3; + } else if (min instanceof InGroupableList) { + m -= MARGIN10; + } else { + m -= MARGIN5; + } + return m; } - public final VirtualHBar getBarEnd() { - return barEnd; + public double getMaxX(StringBounder stringBounder) { + final double min = getMinX(stringBounder); + final double max = getMaxXInternal(stringBounder); + assert max - min >= 0; + if (max - min < minWidth) { + return min + minWidth; + } + return max; + } + + private final double getMaxXInternal(StringBounder stringBounder) { + final InGroupable max = getMax(stringBounder); + if (max == null) { + return minWidth; + } + double m = max.getMaxX(stringBounder); + if (max instanceof MessageExoArrow + && (((MessageExoArrow) max).getType() == MessageExoType.FROM_RIGHT || ((MessageExoArrow) max).getType() == MessageExoType.TO_RIGHT)) { + m -= 3; + } else if (max instanceof InGroupableList) { + m += MARGIN10; + } else { + m += MARGIN5; + } + return m; } } diff --git a/src/net/sourceforge/plantuml/sequencediagram/SequenceDiagram.java b/src/net/sourceforge/plantuml/sequencediagram/SequenceDiagram.java index 73601393a..d29a6a936 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/SequenceDiagram.java +++ b/src/net/sourceforge/plantuml/sequencediagram/SequenceDiagram.java @@ -44,6 +44,8 @@ import java.util.List; import java.util.Map; import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.FileFormatOption; +import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.UmlDiagram; import net.sourceforge.plantuml.UmlDiagramType; import net.sourceforge.plantuml.graphic.HtmlColor; @@ -65,10 +67,15 @@ public class SequenceDiagram extends UmlDiagram { private Skin skin = new ProtectedSkin(new Rose()); + @Deprecated public Participant getOrCreateParticipant(String code) { + return getOrCreateParticipant(code, StringUtils.getWithNewlines(code)); + } + + public Participant getOrCreateParticipant(String code, List display) { Participant result = participants.get(code); if (result == null) { - result = new Participant(ParticipantType.PARTICIPANT, code, Arrays.asList(code)); + result = new Participant(ParticipantType.PARTICIPANT, code, display); participants.put(code, result); } return result; @@ -140,26 +147,22 @@ public class SequenceDiagram extends UmlDiagram { return Collections.unmodifiableList(events); } - private FileMaker getSequenceDiagramPngMaker(FileFormat fileFormat) { + private FileMaker getSequenceDiagramPngMaker(FileFormatOption fileFormatOption) { + + final FileFormat fileFormat = fileFormatOption.getFileFormat(); if (fileFormat == FileFormat.ATXT || fileFormat == FileFormat.UTXT) { return new SequenceDiagramTxtMaker(this, fileFormat); } - return new SequenceDiagramFileMaker(this, skin, fileFormat); - // if (fileFormat == FileFormat.TXT) { - // return new SequenceDiagramPngMaker(this, new TextSkin()); - // } else if (OptionFlags.getInstance().useU()) { - // return new SequenceDiagramFileMaker(this, skin, fileFormat); - // } - // return new SequenceDiagramPngMaker(this, skin); + return new SequenceDiagramFileMaker(this, skin, fileFormatOption); } - public List createFiles(File suggestedFile, FileFormat fileFormat) throws IOException { + public List createFiles(File suggestedFile, FileFormatOption fileFormat) throws IOException { return getSequenceDiagramPngMaker(fileFormat).createMany(suggestedFile); } - public void createFile(OutputStream os, int index, FileFormat fileFormat) throws IOException { + public void createFile(OutputStream os, int index, FileFormatOption fileFormat) throws IOException { getSequenceDiagramPngMaker(fileFormat).createOne(os, index); } @@ -314,10 +317,10 @@ public class SequenceDiagram extends UmlDiagram { public final List getParticipantEnglobers() { return Collections.unmodifiableList(participantEnglobers); } - + @Override public int getNbImages() { - return getSequenceDiagramPngMaker(FileFormat.PNG).getNbPages(); + return getSequenceDiagramPngMaker(new FileFormatOption(FileFormat.PNG)).getNbPages(); } } diff --git a/src/net/sourceforge/plantuml/sequencediagram/SequenceDiagramFactory.java b/src/net/sourceforge/plantuml/sequencediagram/SequenceDiagramFactory.java index f1b6a8cd8..221011637 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/SequenceDiagramFactory.java +++ b/src/net/sourceforge/plantuml/sequencediagram/SequenceDiagramFactory.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5397 $ + * Revision $Revision: 5731 $ * */ package net.sourceforge.plantuml.sequencediagram; @@ -36,7 +36,7 @@ package net.sourceforge.plantuml.sequencediagram; import net.sourceforge.plantuml.command.AbstractUmlSystemCommandFactory; import net.sourceforge.plantuml.sequencediagram.command.CommandActivate; import net.sourceforge.plantuml.sequencediagram.command.CommandActivate2; -import net.sourceforge.plantuml.sequencediagram.command.CommandArrow; +import net.sourceforge.plantuml.sequencediagram.command.CommandArrow2; import net.sourceforge.plantuml.sequencediagram.command.CommandAutoNewpage; import net.sourceforge.plantuml.sequencediagram.command.CommandAutonumber; import net.sourceforge.plantuml.sequencediagram.command.CommandBoxEnd; @@ -71,7 +71,7 @@ public class SequenceDiagramFactory extends AbstractUmlSystemCommandFactory { addCommand(new CommandParticipant(system)); addCommand(new CommandParticipant2(system)); - addCommand(new CommandArrow(system)); + addCommand(new CommandArrow2(system)); addCommand(new CommandExoArrowLeft(system)); addCommand(new CommandExoArrowRight(system)); addCommand(new CommandNoteSequence(system)); diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandActivate.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandActivate.java index 247585c9e..48e9b7881 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandActivate.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandActivate.java @@ -28,13 +28,14 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 4762 $ + * Revision $Revision: 5884 $ * */ package net.sourceforge.plantuml.sequencediagram.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.graphic.HtmlColor; @@ -45,13 +46,13 @@ import net.sourceforge.plantuml.sequencediagram.SequenceDiagram; public class CommandActivate extends SingleLineCommand { public CommandActivate(SequenceDiagram sequenceDiagram) { - super(sequenceDiagram, "(?i)^(activate|deactivate|destroy|create)\\s+([\\p{L}0-9_.]+)\\s*(#\\w+)?$"); + super(sequenceDiagram, "(?i)^(activate|deactivate|destroy|create)\\s+([\\p{L}0-9_.]+|\"[^\"]+\")\\s*(#\\w+)?$"); } @Override protected CommandExecutionResult executeArg(List arg) { final LifeEventType type = LifeEventType.valueOf(arg.get(0).toUpperCase()); - final Participant p = getSystem().getOrCreateParticipant(arg.get(1)); + final Participant p = getSystem().getOrCreateParticipant(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg.get(1))); getSystem().activate(p, type, HtmlColor.getColorIfValid(arg.get(2))); return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandArrow.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandArrow.java deleted file mode 100644 index 097067d7a..000000000 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandArrow.java +++ /dev/null @@ -1,85 +0,0 @@ -/* ======================================================================== - * PlantUML : a free UML diagram generator - * ======================================================================== - * - * (C) Copyright 2009, 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 Lesser 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: 5424 $ - * - */ -package net.sourceforge.plantuml.sequencediagram.command; - -import java.util.Arrays; -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.sequencediagram.Message; -import net.sourceforge.plantuml.sequencediagram.Participant; -import net.sourceforge.plantuml.sequencediagram.SequenceDiagram; - -public class CommandArrow extends SingleLineCommand { - - public CommandArrow(SequenceDiagram sequenceDiagram) { - super(sequenceDiagram, - "(?i)^([\\p{L}0-9_.]+)\\s*([=-]+[>\\]]{1,2}|[<\\[]{1,2}[=-]+)\\s*([\\p{L}0-9_.]+)\\s*(?::\\s*(.*))?$"); - } - - @Override - protected CommandExecutionResult executeArg(List arg) { - Participant p1; - Participant p2; - - final String arrow = StringUtils.manageArrowForSequence(arg.get(1)); - - if (arrow.endsWith(">")) { - p1 = getSystem().getOrCreateParticipant(arg.get(0)); - p2 = getSystem().getOrCreateParticipant(arg.get(2)); - } else if (arrow.startsWith("<")) { - p2 = getSystem().getOrCreateParticipant(arg.get(0)); - p1 = getSystem().getOrCreateParticipant(arg.get(2)); - } else { - throw new IllegalStateException(arg.toString()); - } - - final boolean full = (arrow.endsWith(">>") || arrow.startsWith("<<"))==false; - - final boolean dotted = arrow.contains("--"); - - final List labels; - if (arg.get(3) == null) { - labels = Arrays.asList(""); - } else { - labels = StringUtils.getWithNewlines(arg.get(3)); - } - - getSystem().addMessage(new Message(p1, p2, labels, dotted, full, getSystem().getNextMessageNumber())); - return CommandExecutionResult.ok(); - } - -} diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandArrow2.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandArrow2.java new file mode 100644 index 000000000..7cb001dbe --- /dev/null +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandArrow2.java @@ -0,0 +1,132 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009, 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 Lesser 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: 5424 $ + * + */ +package net.sourceforge.plantuml.sequencediagram.command; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import net.sourceforge.plantuml.StringUtils; +import net.sourceforge.plantuml.command.CommandExecutionResult; +import net.sourceforge.plantuml.command.SingleLineCommand2; +import net.sourceforge.plantuml.command.regex.RegexConcat; +import net.sourceforge.plantuml.command.regex.RegexLeaf; +import net.sourceforge.plantuml.command.regex.RegexOr; +import net.sourceforge.plantuml.command.regex.RegexPartialMatch; +import net.sourceforge.plantuml.sequencediagram.Message; +import net.sourceforge.plantuml.sequencediagram.Participant; +import net.sourceforge.plantuml.sequencediagram.SequenceDiagram; + +public class CommandArrow2 extends SingleLineCommand2 { + + public CommandArrow2(SequenceDiagram sequenceDiagram) { + super(sequenceDiagram, + getRegexConcat()); + } + + static RegexConcat getRegexConcat() { + return new RegexConcat( + new RegexLeaf("^"), + new RegexOr("PART1", + new RegexLeaf("PART1CODE", "([\\p{L}0-9_.]+)"), + new RegexLeaf("PART1LONG", "\"([^\"]+)\""), + new RegexLeaf("PART1LONGCODE", "\"([^\"]+)\"\\s*as\\s+([\\p{L}0-9_.]+)"), + new RegexLeaf("PART1CODELONG", "([\\p{L}0-9_.]+)\\s+as\\s*\"([^\"]+)\"")), + new RegexLeaf("\\s*"), + new RegexLeaf("ARROW", "([=-]+[>\\]]{1,2}|[<\\[]{1,2}[=-]+)"), + new RegexLeaf("\\s*"), + new RegexOr("PART2", + new RegexLeaf("PART2CODE", "([\\p{L}0-9_.]+)"), + new RegexLeaf("PART2LONG", "\"([^\"]+)\""), + new RegexLeaf("PART2LONGCODE", "\"([^\"]+)\"\\s*as\\s+([\\p{L}0-9_.]+)"), + new RegexLeaf("PART2CODELONG", "([\\p{L}0-9_.]+)\\s+as\\s*\"([^\"]+)\"")), + new RegexLeaf("\\s*"), + new RegexLeaf("MESSAGE", "(?::\\s*(.*))?$")); + } + + private Participant getOrCreateParticipant(Map arg2, String n) { + final String code; + final List display; + if (arg2.get(n + "CODE").get(0) != null) { + code = arg2.get(n + "CODE").get(0); + display = StringUtils.getWithNewlines(code); + } else if (arg2.get(n + "LONG").get(0) != null) { + code = arg2.get(n + "LONG").get(0); + display = StringUtils.getWithNewlines(code); + } else if (arg2.get(n + "LONGCODE").get(0) != null) { + display = StringUtils.getWithNewlines(arg2.get(n + "LONGCODE").get(0)); + code = arg2.get(n + "LONGCODE").get(1); + } else if (arg2.get(n + "CODELONG").get(0) != null) { + code = arg2.get(n + "CODELONG").get(0); + display = StringUtils.getWithNewlines(arg2.get(n + "CODELONG").get(1)); + return getSystem().getOrCreateParticipant(code, display); + } else { + throw new IllegalStateException(); + } + return getSystem().getOrCreateParticipant(code, display); + } + + @Override + protected CommandExecutionResult executeArg(Map arg2) { + Participant p1; + Participant p2; + + final String arrow = StringUtils.manageArrowForSequence(arg2.get("ARROW").get(0)); + + if (arrow.endsWith(">")) { + p1 = getOrCreateParticipant(arg2, "PART1"); + p2 = getOrCreateParticipant(arg2, "PART2"); + } else if (arrow.startsWith("<")) { + p2 = getOrCreateParticipant(arg2, "PART1"); + p1 = getOrCreateParticipant(arg2, "PART2"); + } else { + throw new IllegalStateException(arg2.toString()); + } + + final boolean full = (arrow.endsWith(">>") || arrow.startsWith("<<"))==false; + + final boolean dotted = arrow.contains("--"); + + final List labels; + if (arg2.get("MESSAGE").get(0) == null) { + labels = Arrays.asList(""); + } else { + labels = StringUtils.getWithNewlines(arg2.get("MESSAGE").get(0)); + } + + getSystem().addMessage(new Message(p1, p2, labels, dotted, full, getSystem().getNextMessageNumber())); + return CommandExecutionResult.ok(); + } + +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowAny.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowAny.java index 78e695c16..5350a91d5 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowAny.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowAny.java @@ -58,7 +58,7 @@ abstract class CommandExoArrowAny extends SingleLineCommand { @Override final protected CommandExecutionResult executeArg(List arg) { final String arrow = StringUtils.manageArrowForSequence(arg.get(posArrow)); - final Participant p = getSystem().getOrCreateParticipant(arg.get(posParticipant)); + final Participant p = getSystem().getOrCreateParticipant(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg.get(posParticipant))); final boolean full = (arrow.endsWith(">>") || arrow.startsWith("<<")) == false; final boolean dotted = arrow.contains("--"); diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowLeft.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowLeft.java index 8a5594916..be3feb2bf 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowLeft.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowLeft.java @@ -40,7 +40,7 @@ public class CommandExoArrowLeft extends CommandExoArrowAny { public CommandExoArrowLeft(SequenceDiagram sequenceDiagram) { super( sequenceDiagram, - "(?i)^(\\[[=-]+>{1,2}|\\[\\<{1,2}[=-]+)\\s*([\\p{L}0-9_.]+)\\s*(?::\\s*(.*))?$", + "(?i)^(\\[[=-]+>{1,2}|\\[\\<{1,2}[=-]+)\\s*([\\p{L}0-9_.]+|\"[^\"]+\")\\s*(?::\\s*(.*))?$", 0, 1); } diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowRight.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowRight.java index 0c095c250..835904f94 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowRight.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandExoArrowRight.java @@ -40,7 +40,7 @@ public class CommandExoArrowRight extends CommandExoArrowAny { public CommandExoArrowRight(SequenceDiagram sequenceDiagram) { super( sequenceDiagram, - "(?i)^([\\p{L}0-9_.]+)\\s*([=-]+>{1,2}\\]|\\<{1,2}[=-]+\\])\\s*(?::\\s*(.*))?$", + "(?i)^([\\p{L}0-9_.]+|\"[^\"]+\")\\s*([=-]+>{1,2}\\]|\\<{1,2}[=-]+\\])\\s*(?::\\s*(.*))?$", 1, 0); } diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandMultilinesNote.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandMultilinesNote.java index 65ac946d0..7094ae333 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandMultilinesNote.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandMultilinesNote.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 4762 $ + * Revision $Revision: 5884 $ * */ package net.sourceforge.plantuml.sequencediagram.command; @@ -46,16 +46,16 @@ import net.sourceforge.plantuml.sequencediagram.SequenceDiagram; public class CommandMultilinesNote extends CommandMultilines { public CommandMultilinesNote(final SequenceDiagram sequenceDiagram) { - super(sequenceDiagram, "(?i)^note\\s+(right|left|over)\\s+(?:of\\s+)?([\\p{L}0-9_.]+)\\s*(#\\w+)?$", "(?i)^end ?note$"); + super(sequenceDiagram, "(?i)^note\\s+(right|left|over)\\s+(?:of\\s+)?([\\p{L}0-9_.]+|\"[^\"]+\")\\s*(#\\w+)?$", "(?i)^end ?note$"); } public CommandExecutionResult execute(List lines) { - final List line0 = StringUtils.getSplit(getStartingPattern(), lines.get(0)); - final Participant p = getSystem().getOrCreateParticipant(line0.get(1)); + final List line0 = StringUtils.getSplit(getStartingPattern(), lines.get(0).trim()); + final Participant p = getSystem().getOrCreateParticipant(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(line0.get(1))); final NotePosition position = NotePosition.valueOf(line0.get(0).toUpperCase()); - final List strings = lines.subList(1, lines.size() - 1); + final List strings = StringUtils.removeEmptyColumns(lines.subList(1, lines.size() - 1)); if (strings.size() > 0) { final Note note = new Note(p, position, strings); note.setSpecificBackcolor(line0.get(2)); diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandMultilinesNoteOnArrow.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandMultilinesNoteOnArrow.java index 3b7233772..6aec417db 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandMultilinesNoteOnArrow.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandMultilinesNoteOnArrow.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 4762 $ + * Revision $Revision: 5751 $ * */ package net.sourceforge.plantuml.sequencediagram.command; @@ -49,12 +49,12 @@ public class CommandMultilinesNoteOnArrow extends CommandMultilines lines) { - final List line0 = StringUtils.getSplit(getStartingPattern(), lines.get(0)); + final List line0 = StringUtils.getSplit(getStartingPattern(), lines.get(0).trim()); final NotePosition position = NotePosition.valueOf(line0.get(0).toUpperCase()); final AbstractMessage m = getSystem().getLastMessage(); if (m != null) { - final List strings = lines.subList(1, lines.size() - 1); + final List strings = StringUtils.removeEmptyColumns(lines.subList(1, lines.size() - 1)); m.setNote(strings, position, line0.get(1)); } diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandMultilinesNoteOverSeveral.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandMultilinesNoteOverSeveral.java index 606c19942..3a2fb84ea 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandMultilinesNoteOverSeveral.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandMultilinesNoteOverSeveral.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 4762 $ + * Revision $Revision: 5884 $ * */ package net.sourceforge.plantuml.sequencediagram.command; @@ -45,16 +45,16 @@ import net.sourceforge.plantuml.sequencediagram.SequenceDiagram; public class CommandMultilinesNoteOverSeveral extends CommandMultilines { public CommandMultilinesNoteOverSeveral(final SequenceDiagram sequenceDiagram) { - super(sequenceDiagram, "(?i)^note\\s+over\\s+([\\p{L}0-9_.]+)\\s*\\,\\s*([\\p{L}0-9_.]+)\\s*(#\\w+)?$", "(?i)^end ?note$"); + super(sequenceDiagram, "(?i)^note\\s+over\\s+([\\p{L}0-9_.]+|\"[^\"]+\")\\s*\\,\\s*([\\p{L}0-9_.]+|\"[^\"]+\")\\s*(#\\w+)?$", "(?i)^end ?note$"); } public CommandExecutionResult execute(List lines) { - final List line0 = StringUtils.getSplit(getStartingPattern(), lines.get(0)); + final List line0 = StringUtils.getSplit(getStartingPattern(), lines.get(0).trim()); - final Participant p1 = getSystem().getOrCreateParticipant(line0.get(0)); - final Participant p2 = getSystem().getOrCreateParticipant(line0.get(1)); + final Participant p1 = getSystem().getOrCreateParticipant(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(line0.get(0))); + final Participant p2 = getSystem().getOrCreateParticipant(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(line0.get(1))); - final List strings = lines.subList(1, lines.size() - 1); + final List strings = StringUtils.removeEmptyColumns(lines.subList(1, lines.size() - 1)); if (strings.size() > 0) { final Note note = new Note(p1, p2, strings); note.setSpecificBackcolor(line0.get(2)); diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandNoteOverSeveral.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandNoteOverSeveral.java index 1e8ef9048..3541a8301 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandNoteOverSeveral.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandNoteOverSeveral.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 4762 $ + * Revision $Revision: 5884 $ * */ package net.sourceforge.plantuml.sequencediagram.command; @@ -45,13 +45,13 @@ import net.sourceforge.plantuml.sequencediagram.SequenceDiagram; public class CommandNoteOverSeveral extends SingleLineCommand { public CommandNoteOverSeveral(SequenceDiagram sequenceDiagram) { - super(sequenceDiagram, "(?i)^note\\s+over\\s+([\\p{L}0-9_.]+)\\s*\\,\\s*([\\p{L}0-9_.]+)\\s*(#\\w+)?\\s*:\\s*(.*)$"); + super(sequenceDiagram, "(?i)^note\\s+over\\s+([\\p{L}0-9_.]+|\"[^\"]+\")\\s*\\,\\s*([\\p{L}0-9_.]+|\"[^\"]+\")\\s*(#\\w+)?\\s*:\\s*(.*)$"); } @Override protected CommandExecutionResult executeArg(List arg) { - final Participant p1 = getSystem().getOrCreateParticipant(arg.get(0)); - final Participant p2 = getSystem().getOrCreateParticipant(arg.get(1)); + final Participant p1 = getSystem().getOrCreateParticipant(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg.get(0))); + final Participant p2 = getSystem().getOrCreateParticipant(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg.get(1))); final List strings = StringUtils.getWithNewlines(arg.get(3)); final Note note = new Note(p1, p2, strings); note.setSpecificBackcolor(arg.get(2)); diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandNoteSequence.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandNoteSequence.java index 1bc452256..67ff06894 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandNoteSequence.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandNoteSequence.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 4762 $ + * Revision $Revision: 5884 $ * */ package net.sourceforge.plantuml.sequencediagram.command; @@ -46,12 +46,12 @@ import net.sourceforge.plantuml.sequencediagram.SequenceDiagram; public class CommandNoteSequence extends SingleLineCommand { public CommandNoteSequence(SequenceDiagram sequenceDiagram) { - super(sequenceDiagram, "(?i)^note\\s+(right|left|over)\\s+(?:of\\s+)?([\\p{L}0-9_.]+)\\s*(#\\w+)?\\s*:\\s*(.*)$"); + super(sequenceDiagram, "(?i)^note\\s+(right|left|over)\\s+(?:of\\s+)?([\\p{L}0-9_.]+|\"[^\"]+\")\\s*(#\\w+)?\\s*:\\s*(.*)$"); } @Override protected CommandExecutionResult executeArg(List arg) { - final Participant p = getSystem().getOrCreateParticipant(arg.get(1)); + final Participant p = getSystem().getOrCreateParticipant(StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg.get(1))); final NotePosition position = NotePosition.valueOf(arg.get(0).toUpperCase()); diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipant.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipant.java index c9840c1b6..c15eda68c 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipant.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipant.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 4762 $ + * Revision $Revision: 5728 $ * */ package net.sourceforge.plantuml.sequencediagram.command; @@ -71,7 +71,7 @@ public class CommandParticipant extends SingleLineCommand { if (stereotype != null) { participant.setStereotype(new Stereotype(stereotype, getSystem().getSkinParam().getCircledCharacterRadius(), getSystem().getSkinParam().getFont( - FontParam.CIRCLED_CHARACTER))); + FontParam.CIRCLED_CHARACTER, null))); } participant.setSpecificBackcolor(arg.get(4)); diff --git a/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipant2.java b/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipant2.java index f1216ea70..499480a8f 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipant2.java +++ b/src/net/sourceforge/plantuml/sequencediagram/command/CommandParticipant2.java @@ -68,7 +68,7 @@ public class CommandParticipant2 extends SingleLineCommand { if (stereotype != null) { participant.setStereotype(new Stereotype(stereotype, getSystem().getSkinParam().getCircledCharacterRadius(), getSystem().getSkinParam().getFont( - FontParam.CIRCLED_CHARACTER))); + FontParam.CIRCLED_CHARACTER, null))); } participant.setSpecificBackcolor(arg.get(4)); diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/Arrow.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/Arrow.java index 5d7a707b9..37e75b8ea 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/Arrow.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/Arrow.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 4855 $ + * Revision $Revision: 5872 $ * */ package net.sourceforge.plantuml.sequencediagram.graphic; @@ -95,5 +95,10 @@ abstract class Arrow extends GraphicalElement implements InGroupable { protected final void setPaddingArrowHead(double paddingArrowHead) { this.paddingArrowHead = paddingArrowHead; } + + final public double getMargin() { + return 5; + } + } diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/ArrowAndNoteBox.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/ArrowAndNoteBox.java index 45ff6d824..c46567bb4 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/ArrowAndNoteBox.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/ArrowAndNoteBox.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 4855 $ + * Revision $Revision: 5870 $ * */ package net.sourceforge.plantuml.sequencediagram.graphic; @@ -56,10 +56,10 @@ class ArrowAndNoteBox extends Arrow implements InGroupable { final double diffHeightArrow = myHeight - arrowHeight; final double diffHeightNote = myHeight - noteHeight; if (diffHeightArrow > 0) { - arrow.pushToDown(-diffHeightArrow / 2); + arrow.pushToDown(diffHeightArrow / 2); } if (diffHeightNote > 0) { - noteBox.pushToDown(-diffHeightNote / 2); + noteBox.pushToDown(diffHeightNote / 2); } } @@ -133,6 +133,5 @@ class ArrowAndNoteBox extends Arrow implements InGroupable { public LivingParticipantBox getParticipantAt(StringBounder stringBounder, NotePosition position) { return arrow.getParticipantAt(stringBounder, position); } - - + } diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/ArrowAndParticipant.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/ArrowAndParticipant.java index 8b80a06d2..fbcd36000 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/ArrowAndParticipant.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/ArrowAndParticipant.java @@ -130,5 +130,5 @@ class ArrowAndParticipant extends Arrow implements InGroupable { public String toString(StringBounder stringBounder) { return arrow.toString(stringBounder); } - + } diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/ConstraintSetHBar.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/ConstraintSetHBar.java deleted file mode 100644 index 742e53f98..000000000 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/ConstraintSetHBar.java +++ /dev/null @@ -1,117 +0,0 @@ -/* ======================================================================== - * PlantUML : a free UML diagram generator - * ======================================================================== - * - * (C) Copyright 2009, 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 Lesser 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: 3836 $ - * - */ -package net.sourceforge.plantuml.sequencediagram.graphic; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import net.sourceforge.plantuml.graphic.StringBounder; -import net.sourceforge.plantuml.sequencediagram.InGroupableList; - -class ConstraintSetHBar { - - final private List pushables = new ArrayList(); - final private List inGroupableLists = new ArrayList(); - - public ConstraintSetHBar(Collection all) { - this.pushables.addAll(all); - } - - public void add(InGroupableList inGroupableList) { - this.inGroupableLists.add(inGroupableList); - } - - public double takeConstraintIntoAccount(StringBounder stringBounder, double freeX) { - for (InGroupableList list : inGroupableLists) { - if (list.isEmpty()) { - list.getBarEnd().pushToLeft(list.getMaxX(stringBounder)); - continue; - } - final ParticipantBox first = list.getFirstParticipantBox(); - final ParticipantBox last = list.getLastParticipantBox(); - final int idxFirst = pushables.indexOf(first); - final int idxLast = pushables.indexOf(last); - if (idxFirst == -1 || idxLast == -1) { - throw new IllegalStateException(); - } - pushables.add(idxFirst, list.getBarStart()); - pushables.add(idxLast + 2, list.getBarEnd()); - list.getBarStart().pushToLeft(list.getMinX(stringBounder)); - list.getBarEnd().pushToLeft(list.getMaxX(stringBounder)); - } - - double result = freeX; - for (int i = 0; i < pushables.size(); i++) { - final Pushable pushable = pushables.get(i); - if (pushable instanceof VirtualHBar) { - final VirtualHBar bar = (VirtualHBar) pushable; - final int j = getVirtualNext(i); - pushAllToLeft(j, bar.getWidth()); - result += bar.getWidth(); - i = j; - } - } - - for (InGroupableList list : inGroupableLists) { - final double endBar = list.getBarEnd().getCenterX(stringBounder) + 5; - if (endBar > result) { - result = endBar; - } - } - - return result; - } - - private int getVirtualNext(int i) { - final VirtualHBar ref = (VirtualHBar) pushables.get(i); - for (int j = i + 1; j < pushables.size(); j++) { - if (pushables.get(j) instanceof VirtualHBar == false) { - return j - 1; - } - final VirtualHBar other = (VirtualHBar) pushables.get(j); - if (other.canBeOnTheSameLine(ref) == false) { - return j - 1; - } - } - return pushables.size() - 1; - } - - private void pushAllToLeft(int afterThisOne, double deltaX) { - for (int i = afterThisOne + 1; i < pushables.size(); i++) { - pushables.get(i).pushToLeft(deltaX); - } - } - -} diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/DrawableSet.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/DrawableSet.java index a96ad3ff9..e051f197d 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: 5271 $ + * Revision $Revision: 5829 $ * */ package net.sourceforge.plantuml.sequencediagram.graphic; @@ -117,16 +117,6 @@ class DrawableSet { return events.get(ev); } - // public double getHeadHeightOld(StringBounder stringBounder) { - // double r = 0; - // for (LivingParticipantBox livingParticipantBox : participants.values()) { - // final double y = - // livingParticipantBox.getParticipantBox().getHeadHeight(stringBounder); - // r = Math.max(r, y); - // } - // return r; - // } - public double getHeadHeight(StringBounder stringBounder) { double r = 0; for (Participant p : participants.keySet()) { diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/DrawableSetInitializer.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/DrawableSetInitializer.java index b3c9b14dd..eceb2770e 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: 5528 $ + * Revision $Revision: 5875 $ * */ package net.sourceforge.plantuml.sequencediagram.graphic; @@ -69,13 +69,12 @@ class DrawableSetInitializer { private double freeX = 0; private double freeY = 0; - private final double groupingMargin = 10; + // private final double groupingMargin = 10; private final double autonewpage; - private int maxGrouping = 0; + // private int maxGrouping = 0; private ConstraintSet constraintSet; - private ConstraintSetHBar constraintSetHBar; public DrawableSetInitializer(Skin skin, ISkinParam skinParam, boolean showTail, double autonewpage) { this.drawableSet = new DrawableSet(skin, skinParam); @@ -96,16 +95,11 @@ class DrawableSetInitializer { } this.freeY = drawableSet.getHeadHeight(stringBounder); - // this.freeY += drawableSet.getOffsetForEnglobers(stringBounder); + this.lastFreeY = this.freeY; drawableSet.setTopStartingY(this.freeY); - // for (LivingParticipantBox p : - // drawableSet.getAllLivingParticipantBox()) { - // p.getParticipantBox().setTopStartingY(this.freeY); - // } - for (Participant p : drawableSet.getAllParticipants()) { final LivingParticipantBox living = drawableSet.getLivingParticipantBox(p); for (int i = 0; i < p.getInitialLife(); i++) { @@ -120,7 +114,6 @@ class DrawableSetInitializer { } constraintSet = new ConstraintSet(col, freeX); - constraintSetHBar = new ConstraintSetHBar(col); for (Event ev : new ArrayList(drawableSet.getAllEvents())) { final double diffY = freeY - lastFreeY; @@ -154,9 +147,7 @@ class DrawableSetInitializer { prepareMissingSpace(stringBounder); - final double diagramWidth = constraintSetHBar.takeConstraintIntoAccount(stringBounder, freeX) + 1; - - drawableSet.setDimension(new Dimension2DDouble(diagramWidth, getTotalHeight(freeY, stringBounder))); + drawableSet.setDimension(new Dimension2DDouble(freeX, getTotalHeight(freeY, stringBounder))); return drawableSet; } @@ -175,18 +166,10 @@ class DrawableSetInitializer { } else { final Pushable beforeFirst = constraintSet.getPrevious(first); final Pushable afterLast = constraintSet.getNext(last); - // final Constraint constraint1 = - // constraintSet.getConstraint(first, last); final Constraint constraint1 = constraintSet.getConstraint(beforeFirst, afterLast); constraint1.ensureValue(preferredWidth + beforeFirst.getPreferredWidth(stringBounder) / 2 + afterLast.getPreferredWidth(stringBounder) / 2 + 10); } - // final double x1 = drawableSet.getX1(pe); - // final double x2 = drawableSet.getX2(stringBounder, pe); - // assert x2 > x1; - // final double diff = preferredWidth - (x2 - x1); - // if (diff > 0) { - // } } } @@ -226,12 +209,19 @@ class DrawableSetInitializer { width = a.getActualWidth(stringBounder); } } + if (ev instanceof GroupingHeader) { + final GroupingHeader gh = (GroupingHeader) ev; + if (width < gh.getActualWidth(stringBounder)) { + width = gh.getActualWidth(stringBounder); + } + } final double endX = startX + width; final double delta2 = endX - freeX; if (delta2 > missingSpace2) { missingSpace2 = delta2; } } + if (missingSpace1 > 0) { constraintSet.pushToLeft(missingSpace1); } @@ -267,11 +257,11 @@ class DrawableSetInitializer { if (m.getType() != GroupingType.START) { throw new IllegalStateException(); } - final ISkinParam skinParam = new SkinParamBackcolored(drawableSet.getSkinParam(), m.getBackColorElement(), - m.getBackColorGeneral()); - this.maxGrouping++; - final List strings = m.getTitle().equals("group") ? Arrays.asList(m.getComment()) - : Arrays.asList(m.getTitle(), m.getComment()); + final ISkinParam skinParam = new SkinParamBackcolored(drawableSet.getSkinParam(), m.getBackColorElement(), m + .getBackColorGeneral()); + // this.maxGrouping++; + final List strings = m.getTitle().equals("group") ? Arrays.asList(m.getComment()) : Arrays.asList(m + .getTitle(), m.getComment()); final Component header = drawableSet.getSkin().createComponent(ComponentType.GROUPING_HEADER, skinParam, strings); final InGroupableList inGroupableList = new InGroupableList(m, freeY); @@ -279,10 +269,8 @@ class DrawableSetInitializer { other.addInGroupable(inGroupableList); } inGroupableLists.add(inGroupableList); - constraintSetHBar.add(inGroupableList); - final GraphicalElement element = new GroupingHeader(freeY, header, (m.getLevel() + 1) * groupingMargin, - inGroupableList); + final GraphicalElement element = new GroupingHeader(freeY, header, inGroupableList); inGroupableList.setMinWidth(element.getPreferredWidth(stringBounder)); freeY += element.getPreferredHeight(stringBounder); drawableSet.addEvent(m, element); @@ -301,8 +289,7 @@ class DrawableSetInitializer { if (before instanceof GroupingHeader) { initY += before.getPreferredHeight(stringBounder); } - element = new GroupingElse(freeY, initY, body, comp, (m.getLevel() + 1) * groupingMargin, - getTopGroupingStructure()); + element = new GroupingElse(freeY, initY, body, comp, getTopGroupingStructure()); freeY += element.getPreferredHeight(stringBounder); } else if (m.getType() == GroupingType.END) { final ISkinParam skinParam = new SkinParamBackcolored(drawableSet.getSkinParam(), null, m.getJustBefore() @@ -318,11 +305,10 @@ class DrawableSetInitializer { // initY += 7; initY += tail.getPreferredHeight(stringBounder); } - element = new GroupingTail(freeY, initY, (m.getLevel() + 1) * groupingMargin, body, tail, - getTopGroupingStructure()); + element = new GroupingTail(freeY, initY, body, tail, getTopGroupingStructure()); freeY += tail.getPreferredHeight(stringBounder); final int idx = inGroupableLists.size() - 1; - inGroupableLists.get(idx).setEndingY(freeY); + // inGroupableLists.get(idx).setEndingY(freeY); inGroupableLists.remove(idx); } else { throw new IllegalStateException(); diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/GroupingElse.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/GroupingElse.java index a0565338f..59877b25c 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/GroupingElse.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/GroupingElse.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 4696 $ + * Revision $Revision: 5874 $ * */ package net.sourceforge.plantuml.sequencediagram.graphic; @@ -42,42 +42,29 @@ import net.sourceforge.plantuml.skin.Component; import net.sourceforge.plantuml.skin.Context2D; import net.sourceforge.plantuml.ugraphic.UGraphic; -class GroupingElse extends GraphicalElement { +class GroupingElse extends GroupingGraphicalElement { - private final double xpos; private final Component comp; private final double initY; private final Component body; - private final InGroupableList inGroupableList; - public GroupingElse(double startingY, double initY, Component body, - Component comp, double xpos, InGroupableList inGroupableList) { - super(startingY); - this.xpos = xpos; + public GroupingElse(double startingY, double initY, Component body, Component comp, InGroupableList inGroupableList) { + super(startingY, inGroupableList); this.comp = comp; this.initY = initY; this.body = body; - this.inGroupableList = inGroupableList; - if (inGroupableList == null) { - throw new IllegalArgumentException(); - } } @Override protected void drawInternalU(UGraphic ug, double maxX, Context2D context) { final StringBounder stringBounder = ug.getStringBounder(); - // final double x1 = inGroupableList.getMinX(stringBounder); - final double x1 = inGroupableList.getBarStart().getCenterX( - stringBounder); - // final double x2 = inGroupableList.getMaxX(stringBounder); - final double x2 = inGroupableList.getBarEnd().getCenterX(stringBounder); + final double x1 = getInGroupableList().getMinX(stringBounder); + final double x2 = getInGroupableList().getMaxX(stringBounder); ug.translate(x1, getStartingY()); - final Dimension2D dim = new Dimension2DDouble(x2 - x1, comp - .getPreferredHeight(stringBounder)); + final Dimension2D dim = new Dimension2DDouble(x2 - x1, comp.getPreferredHeight(stringBounder)); - final Dimension2D dimBody = new Dimension2DDouble(x2 - x1, - getStartingY() - initY); + final Dimension2D dimBody = new Dimension2DDouble(x2 - x1, getStartingY() - initY); comp.drawU(ug, dim, context); ug.translate(0, initY - getStartingY()); @@ -95,9 +82,4 @@ class GroupingElse extends GraphicalElement { return comp.getPreferredWidth(stringBounder); } - @Override - public double getStartingX(StringBounder stringBounder) { - return xpos; - } - } diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/VirtualHBar.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/GroupingGraphicalElement.java similarity index 51% rename from src/net/sourceforge/plantuml/sequencediagram/graphic/VirtualHBar.java rename to src/net/sourceforge/plantuml/sequencediagram/graphic/GroupingGraphicalElement.java index 8163ee9a3..e738ba176 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/VirtualHBar.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/GroupingGraphicalElement.java @@ -28,83 +28,38 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 3836 $ + * Revision $Revision: 5873 $ * */ package net.sourceforge.plantuml.sequencediagram.graphic; import net.sourceforge.plantuml.graphic.StringBounder; +import net.sourceforge.plantuml.sequencediagram.InGroupableList; -public class VirtualHBar implements Pushable { +abstract class GroupingGraphicalElement extends GraphicalElement { - private static int CPT = 0; + private final InGroupableList inGroupableList; - private final double width; - private final VirtualHBarType type; - private double x; - private final double startingY; - private double endingY; + public GroupingGraphicalElement(double currentY, InGroupableList inGroupableList) { + super(currentY); + this.inGroupableList = inGroupableList; + if (inGroupableList == null) { + throw new IllegalArgumentException(); + } + } - private int cpt = CPT++; - - public VirtualHBar(double width, VirtualHBarType type, double startingY) { - this.width = width; - this.type = type; - this.x = width / 2; - this.startingY = startingY; + final public double getActualWidth(StringBounder stringBounder) { + return Math.max(getPreferredWidth(stringBounder), inGroupableList.getMaxX(stringBounder) + - inGroupableList.getMinX(stringBounder) + 2 * InGroupableList.MARGIN10); } @Override - public String toString() { - return "VHB" + cpt + " " + x + " " + startingY + "-" + endingY; + final public double getStartingX(StringBounder stringBounder) { + return inGroupableList.getMinX(stringBounder) - InGroupableList.MARGIN10; } - public VirtualHBarType getType() { - return type; + protected final InGroupableList getInGroupableList() { + return inGroupableList; } - public double getWidth() { - return width; - } - - public double getCenterX(StringBounder stringBounder) { - return x; - } - - public void pushToLeft(double deltaX) { - x += deltaX; - } - - public final double getEndingY() { - return endingY; - } - - public final void setEndingY(double endingY) { - if (endingY <= startingY) { - throw new IllegalArgumentException(); - } - this.endingY = endingY; - } - - public final double getStartingY() { - return startingY; - } - - public boolean canBeOnTheSameLine(VirtualHBar bar) { - if (this.x != bar.x) { - return false; - } - if (this.startingY >= bar.endingY) { - return true; - } - if (this.endingY <= bar.startingY) { - return true; - } - return false; - } - - public double getPreferredWidth(StringBounder stringBounder) { - throw new UnsupportedOperationException(); - } - -} \ No newline at end of file +} diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/GroupingHeader.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/GroupingHeader.java index 7eea93ca6..33e84d392 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/GroupingHeader.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/GroupingHeader.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 4696 $ + * Revision $Revision: 5874 $ * */ package net.sourceforge.plantuml.sequencediagram.graphic; @@ -42,32 +42,23 @@ import net.sourceforge.plantuml.skin.Component; import net.sourceforge.plantuml.skin.Context2D; import net.sourceforge.plantuml.ugraphic.UGraphic; -class GroupingHeader extends GraphicalElement { +class GroupingHeader extends GroupingGraphicalElement { private final Component comp; - private final double xpos; - private final InGroupableList inGroupableList; - public GroupingHeader(double currentY, Component comp, double xpos, - InGroupableList inGroupableList) { - super(currentY); - this.xpos = xpos; + public GroupingHeader(double currentY, Component comp, InGroupableList inGroupableList) { + super(currentY, inGroupableList); this.comp = comp; - this.inGroupableList = inGroupableList; - if (inGroupableList == null) { - throw new IllegalArgumentException(); - } } @Override public String toString() { - return super.toString() + " " - + (inGroupableList == null ? "no" : inGroupableList.toString()); + return super.toString() + " " + (getInGroupableList() == null ? "no" : getInGroupableList().toString()); } @Override final public double getPreferredWidth(StringBounder stringBounder) { - return comp.getPreferredWidth(stringBounder); + return comp.getPreferredWidth(stringBounder) + 5; } @Override @@ -75,22 +66,13 @@ class GroupingHeader extends GraphicalElement { return comp.getPreferredHeight(stringBounder); } - @Override - public double getStartingX(StringBounder stringBounder) { - return xpos; - } - @Override protected void drawInternalU(UGraphic ug, double maxX, Context2D context) { final StringBounder stringBounder = ug.getStringBounder(); - // final double x1 = inGroupableList.getMinX(stringBounder); - final double x1 = inGroupableList.getBarStart().getCenterX( - stringBounder); - final double x2 = inGroupableList.getBarEnd().getCenterX(stringBounder); - // final double x2 = inGroupableList.getMaxX(stringBounder); + final double x1 = getInGroupableList().getMinX(stringBounder); + final double x2 = getInGroupableList().getMaxX(stringBounder); ug.translate(x1, getStartingY()); - final Dimension2D dim = new Dimension2DDouble(x2 - x1, comp - .getPreferredHeight(stringBounder)); + final Dimension2D dim = new Dimension2DDouble(x2 - x1, comp.getPreferredHeight(stringBounder)); comp.drawU(ug, dim, context); } diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/GroupingTail.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/GroupingTail.java index c5493d398..023cb45e2 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/GroupingTail.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/GroupingTail.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5528 $ + * Revision $Revision: 5874 $ * */ package net.sourceforge.plantuml.sequencediagram.graphic; @@ -42,21 +42,17 @@ import net.sourceforge.plantuml.skin.Component; import net.sourceforge.plantuml.skin.Context2D; import net.sourceforge.plantuml.ugraphic.UGraphic; -class GroupingTail extends GraphicalElement { +class GroupingTail extends GroupingGraphicalElement { private final double initY; - private final double xpos; private final Component body; private final Component tail; - private final InGroupableList inGroupableList; - public GroupingTail(double currentY, double initY, double xpos, Component body, Component tail, - InGroupableList inGroupableList) { - super(currentY); + public GroupingTail(double currentY, double initY, Component body, Component tail, InGroupableList inGroupableList) { + super(currentY, inGroupableList); if (currentY < initY) { - // throw new IllegalArgumentException("currentY=" + currentY + " initY=" + initY); - System.err.println("currentY=" + currentY + " initY=" + initY); - + throw new IllegalArgumentException("currentY=" + currentY + " initY=" + initY); + // System.err.println("currentY=" + currentY + " initY=" + initY); } if (inGroupableList == null) { throw new IllegalArgumentException(); @@ -64,22 +60,13 @@ class GroupingTail extends GraphicalElement { this.body = body; this.tail = tail; this.initY = initY; - this.xpos = xpos; - this.inGroupableList = inGroupableList; - } - - @Override - public double getStartingX(StringBounder stringBounder) { - return xpos; } @Override protected void drawInternalU(UGraphic ug, double maxX, Context2D context) { final StringBounder stringBounder = ug.getStringBounder(); - // final double x1 = inGroupableList.getMinX(stringBounder); - final double x1 = inGroupableList.getBarStart().getCenterX(stringBounder); - final double x2 = inGroupableList.getBarEnd().getCenterX(stringBounder); - // final double x2 = inGroupableList.getMaxX(stringBounder); + final double x1 = getInGroupableList().getMinX(stringBounder); + final double x2 = getInGroupableList().getMaxX(stringBounder); ug.translate(x1, initY); final Dimension2D dimBody = new Dimension2DDouble(x2 - x1, getPreferredHeight(stringBounder)); body.drawU(ug, dimBody, context); diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/LivingParticipantBox.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/LivingParticipantBox.java index df54def1a..8c9a2d33e 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: 5636 $ + * Revision $Revision: 5870 $ * */ package net.sourceforge.plantuml.sequencediagram.graphic; @@ -101,5 +101,5 @@ public class LivingParticipantBox implements InGroupable { public String toString(StringBounder stringBounder) { return toString(); } - + } diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/MessageArrow.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/MessageArrow.java index c1bf0cdf4..9bae61128 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/MessageArrow.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/MessageArrow.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 4855 $ + * Revision $Revision: 5870 $ * */ package net.sourceforge.plantuml.sequencediagram.graphic; @@ -166,4 +166,5 @@ class MessageArrow extends Arrow { public String toString(StringBounder stringBounder) { return getMinX(stringBounder) + "-" + getMaxX(stringBounder); } + } diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/MessageExoArrow.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/MessageExoArrow.java index d9aee1514..97df4f0f6 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/MessageExoArrow.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/MessageExoArrow.java @@ -45,7 +45,7 @@ import net.sourceforge.plantuml.skin.Context2D; import net.sourceforge.plantuml.skin.Skin; import net.sourceforge.plantuml.ugraphic.UGraphic; -class MessageExoArrow extends Arrow { +public class MessageExoArrow extends Arrow { private final LivingParticipantBox p; private final MessageExoType type; @@ -159,5 +159,5 @@ class MessageExoArrow extends Arrow { public double getActualWidth(StringBounder stringBounder) { return getActualWidth(stringBounder, getMaxX()); } - + } diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/MessageSelfArrow.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/MessageSelfArrow.java index fc50c441d..803dad82b 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/MessageSelfArrow.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/MessageSelfArrow.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 4855 $ + * Revision $Revision: 5870 $ * */ package net.sourceforge.plantuml.sequencediagram.graphic; @@ -124,5 +124,4 @@ class MessageSelfArrow extends Arrow { public double getActualWidth(StringBounder stringBounder) { return getPreferredWidth(stringBounder); } - } diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/NoteBox.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/NoteBox.java index 89bc2f4a1..45dced98d 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/NoteBox.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/NoteBox.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 4696 $ + * Revision $Revision: 5870 $ * */ package net.sourceforge.plantuml.sequencediagram.graphic; @@ -135,4 +135,5 @@ class NoteBox extends GraphicalElement implements InGroupable { return toString(); } + } diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/SequenceDiagramFileMaker.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/SequenceDiagramFileMaker.java index 8419b3a44..7012fb104 100644 --- a/src/net/sourceforge/plantuml/sequencediagram/graphic/SequenceDiagramFileMaker.java +++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/SequenceDiagramFileMaker.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5520 $ + * Revision $Revision: 5872 $ * */ package net.sourceforge.plantuml.sequencediagram.graphic; @@ -52,6 +52,7 @@ import java.util.Map; import net.sourceforge.plantuml.Dimension2DDouble; import net.sourceforge.plantuml.EmptyImageBuilder; import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.FileFormatOption; import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.Log; import net.sourceforge.plantuml.eps.EpsStrategy; @@ -92,12 +93,12 @@ public class SequenceDiagramFileMaker implements FileMaker { private final DrawableSet drawableSet; private final Dimension2D fullDimension; private final List pages; - private final FileFormat fileFormat; + private final FileFormatOption fileFormatOption; - public SequenceDiagramFileMaker(SequenceDiagram sequenceDiagram, Skin skin, FileFormat fileFormat) { + public SequenceDiagramFileMaker(SequenceDiagram sequenceDiagram, Skin skin, FileFormatOption fileFormatOption) { HtmlColor.setForceMonochrome(sequenceDiagram.getSkinParam().isMonochrome()); this.diagram = sequenceDiagram; - this.fileFormat = fileFormat; + this.fileFormatOption = fileFormatOption; final DrawableSetInitializer initializer = new DrawableSetInitializer(skin, sequenceDiagram.getSkinParam(), sequenceDiagram.isShowFootbox(), sequenceDiagram.getAutonewpage()); @@ -137,7 +138,7 @@ public class SequenceDiagramFileMaker implements FileMaker { } pages = create(drawableSet, positions, sequenceDiagram.isShowFootbox(), sequenceDiagram.getTitle()).getPages(); } - + public int getNbPages() { return pages.size(); } @@ -157,6 +158,7 @@ public class SequenceDiagramFileMaker implements FileMaker { public List createMany(final File suggestedFile) throws IOException { final List result = new ArrayList(); + final FileFormat fileFormat = fileFormatOption.getFileFormat(); if (fileFormat == FileFormat.ATXT) { throw new UnsupportedOperationException(); } @@ -167,7 +169,7 @@ public class SequenceDiagramFileMaker implements FileMaker { if (createImage instanceof UGraphicG2d) { final BufferedImage im = ((UGraphicG2d) createImage).getBufferedImage(); Log.info("Image size " + im.getWidth() + " x " + im.getHeight()); - PngIO.write(im, f, diagram.getMetadata()); + PngIO.write(im, f, diagram.getMetadata(), diagram.getDpi(fileFormatOption)); } else if (createImage instanceof UGraphicSvg && fileFormat == FileFormat.SVG) { final UGraphicSvg svg = (UGraphicSvg) createImage; final FileOutputStream fos = new FileOutputStream(f); @@ -215,7 +217,7 @@ public class SequenceDiagramFileMaker implements FileMaker { final UGraphic createImage = createImage((int) fullDimension.getWidth(), pages.get(index), index); if (createImage instanceof UGraphicG2d) { final BufferedImage im = ((UGraphicG2d) createImage).getBufferedImage(); - PngIO.write(im, os, diagram.getMetadata()); + PngIO.write(im, os, diagram.getMetadata(), diagram.getDpi(fileFormatOption)); } else if (createImage instanceof UGraphicSvg) { final UGraphicSvg svg = (UGraphicSvg) createImage; svg.createXml(os); @@ -225,9 +227,9 @@ public class SequenceDiagramFileMaker implements FileMaker { } } - private double getImageWidth(SequenceDiagramArea area, boolean rotate) { + private double getImageWidth(SequenceDiagramArea area, boolean rotate, double dpiFactor) { final int minsize = diagram.getMinwidth(); - final double w = getImageWidthWithoutMinsize(area, rotate); + final double w = getImageWidthWithoutMinsize(area, rotate, dpiFactor); if (minsize == Integer.MAX_VALUE) { return w; } @@ -236,29 +238,29 @@ public class SequenceDiagramFileMaker implements FileMaker { } return minsize; } - + private double getScale(double width, double height) { - if (diagram.getScale()==null) { + if (diagram.getScale() == null) { return 1; } return diagram.getScale().getScale(width, height); } - private double getImageWidthWithoutMinsize(SequenceDiagramArea area, boolean rotate) { + private double getImageWidthWithoutMinsize(SequenceDiagramArea area, boolean rotate, double dpiFactor) { final double w; if (rotate) { - w = area.getHeight() * getScale(area.getWidth(), area.getHeight()); + w = area.getHeight() * getScale(area.getWidth(), area.getHeight()) * dpiFactor; } else { - w = area.getWidth() * getScale(area.getWidth(), area.getHeight()); + w = area.getWidth() * getScale(area.getWidth(), area.getHeight()) * dpiFactor; } return w; } - private double getImageHeight(SequenceDiagramArea area, final Page page, boolean rotate) { + private double getImageHeight(SequenceDiagramArea area, final Page page, boolean rotate, double dpiFactor) { if (rotate) { - return area.getWidth() * getScale(area.getWidth(), area.getHeight()); + return area.getWidth() * getScale(area.getWidth(), area.getHeight()) * dpiFactor; } - return area.getHeight() * getScale(area.getWidth(), area.getHeight()); + return area.getHeight() * getScale(area.getWidth(), area.getHeight()) * dpiFactor; } private UGraphic createImage(final int diagramWidth, final Page page, final int indice) { @@ -285,13 +287,15 @@ public class SequenceDiagramFileMaker implements FileMaker { final Color backColor = diagram.getSkinParam().getBackgroundColor().getColor(); final UGraphic ug; - final double imageWidth = getImageWidth(area, diagram.isRotation()); + final FileFormat fileFormat = fileFormatOption.getFileFormat(); + final double dpiFactor = diagram.getDpiFactor(fileFormatOption); + final double imageWidth = getImageWidth(area, diagram.isRotation(), dpiFactor); if (fileFormat == FileFormat.PNG) { - double imageHeight = getImageHeight(area, page, diagram.isRotation()); + double imageHeight = getImageHeight(area, page, diagram.isRotation(), dpiFactor); if (imageHeight == 0) { imageHeight = 1; } - final EmptyImageBuilder builder = new EmptyImageBuilder((int) imageWidth, (int) imageHeight, backColor); + final EmptyImageBuilder builder = new EmptyImageBuilder(imageWidth, imageHeight, backColor); final Graphics2D graphics2D = builder.getGraphics2D(); if (diagram.isRotation()) { @@ -303,7 +307,7 @@ public class SequenceDiagramFileMaker implements FileMaker { final AffineTransform scale = graphics2D.getTransform(); scale.scale(getScale(area.getWidth(), area.getHeight()), getScale(area.getWidth(), area.getHeight())); graphics2D.setTransform(scale); - ug = new UGraphicG2d(graphics2D, builder.getBufferedImage()); + ug = new UGraphicG2d(graphics2D, builder.getBufferedImage(), dpiFactor); } else if (fileFormat == FileFormat.SVG) { if (backColor.equals(Color.WHITE)) { ug = new UGraphicSvg(false); @@ -316,11 +320,12 @@ public class SequenceDiagramFileMaker implements FileMaker { throw new UnsupportedOperationException(); } - final int diff = (int) Math.round((imageWidth - getImageWidthWithoutMinsize(area, diagram.isRotation())) / 2); + final int diff = (int) Math.round((imageWidth - getImageWidthWithoutMinsize(area, diagram.isRotation(), + dpiFactor)) / 2); if (diagram.isRotation()) { - ug.translate(0, diff); + ug.translate(0, diff / dpiFactor); } else { - ug.translate(diff, 0); + ug.translate(diff / dpiFactor, 0); } if (compTitle != null) { @@ -354,9 +359,9 @@ public class SequenceDiagramFileMaker implements FileMaker { } private void addFooter2(SequenceDiagramArea area) { - final Color titleColor = diagram.getSkinParam().getFontHtmlColor(FontParam.FOOTER).getColor(); - final String fontFamily = diagram.getSkinParam().getFontFamily(FontParam.FOOTER); - final int fontSize = diagram.getSkinParam().getFontSize(FontParam.FOOTER); + final Color titleColor = diagram.getSkinParam().getFontHtmlColor(FontParam.FOOTER, null).getColor(); + final String fontFamily = diagram.getSkinParam().getFontFamily(FontParam.FOOTER, null); + final int fontSize = diagram.getSkinParam().getFontSize(FontParam.FOOTER, null); final PngTitler pngTitler = new PngTitler(titleColor, diagram.getFooter(), fontSize, fontFamily, diagram .getFooterAlignement(), VerticalPosition.BOTTOM); final Dimension2D dim = pngTitler.getTextDimension(dummyStringBounder); @@ -366,9 +371,9 @@ public class SequenceDiagramFileMaker implements FileMaker { } private void addHeader2(SequenceDiagramArea area) { - final Color titleColor = diagram.getSkinParam().getFontHtmlColor(FontParam.HEADER).getColor(); - final String fontFamily = diagram.getSkinParam().getFontFamily(FontParam.HEADER); - final int fontSize = diagram.getSkinParam().getFontSize(FontParam.HEADER); + final Color titleColor = diagram.getSkinParam().getFontHtmlColor(FontParam.HEADER, null).getColor(); + final String fontFamily = diagram.getSkinParam().getFontFamily(FontParam.HEADER, null); + final int fontSize = diagram.getSkinParam().getFontSize(FontParam.HEADER, null); final PngTitler pngTitler = new PngTitler(titleColor, diagram.getHeader(), fontSize, fontFamily, diagram .getHeaderAlignement(), VerticalPosition.TOP); final Dimension2D dim = pngTitler.getTextDimension(dummyStringBounder); @@ -378,9 +383,9 @@ public class SequenceDiagramFileMaker implements FileMaker { } private void addFooter3(SequenceDiagramArea area, UGraphic ug) { - final Color titleColor = diagram.getSkinParam().getFontHtmlColor(FontParam.FOOTER).getColor(); - final String fontFamily = diagram.getSkinParam().getFontFamily(FontParam.FOOTER); - final int fontSize = diagram.getSkinParam().getFontSize(FontParam.FOOTER); + final Color titleColor = diagram.getSkinParam().getFontHtmlColor(FontParam.FOOTER, null).getColor(); + final String fontFamily = diagram.getSkinParam().getFontFamily(FontParam.FOOTER, null); + final int fontSize = diagram.getSkinParam().getFontSize(FontParam.FOOTER, null); final PngTitler pngTitler = new PngTitler(titleColor, diagram.getFooter(), fontSize, fontFamily, diagram .getFooterAlignement(), VerticalPosition.BOTTOM); final TextBlock text = pngTitler.getTextBlock(); @@ -391,9 +396,9 @@ public class SequenceDiagramFileMaker implements FileMaker { } private void addHeader3(SequenceDiagramArea area, UGraphic ug) { - final Color titleColor = diagram.getSkinParam().getFontHtmlColor(FontParam.HEADER).getColor(); - final String fontFamily = diagram.getSkinParam().getFontFamily(FontParam.HEADER); - final int fontSize = diagram.getSkinParam().getFontSize(FontParam.HEADER); + final Color titleColor = diagram.getSkinParam().getFontHtmlColor(FontParam.HEADER, null).getColor(); + final String fontFamily = diagram.getSkinParam().getFontFamily(FontParam.HEADER, null); + final int fontSize = diagram.getSkinParam().getFontSize(FontParam.HEADER, null); final PngTitler pngTitler = new PngTitler(titleColor, diagram.getHeader(), fontSize, fontFamily, diagram .getHeaderAlignement(), VerticalPosition.TOP); final TextBlock text = pngTitler.getTextBlock(); diff --git a/src/net/sourceforge/plantuml/skin/AbstractTextualComponent.java b/src/net/sourceforge/plantuml/skin/AbstractTextualComponent.java index 9056d0cb0..20b54c4db 100644 --- a/src/net/sourceforge/plantuml/skin/AbstractTextualComponent.java +++ b/src/net/sourceforge/plantuml/skin/AbstractTextualComponent.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5277 $ + * Revision $Revision: 5741 $ * */ package net.sourceforge.plantuml.skin; @@ -42,6 +42,7 @@ import java.util.List; import net.sourceforge.plantuml.graphic.HorizontalAlignement; import net.sourceforge.plantuml.graphic.StringBounder; import net.sourceforge.plantuml.graphic.TextBlock; +import net.sourceforge.plantuml.graphic.TextBlockEmpty; import net.sourceforge.plantuml.graphic.TextBlockUtils; public abstract class AbstractTextualComponent extends AbstractComponent { @@ -72,7 +73,11 @@ public abstract class AbstractTextualComponent extends AbstractComponent { this.marginY = marginY; this.strings = strings; - textBlock = TextBlockUtils.create(strings, font, fontColor, horizontalAlignement); + if (strings.size() == 1 && strings.get(0).length() == 0) { + textBlock = new TextBlockEmpty(); + } else { + textBlock = TextBlockUtils.create(strings, font, fontColor, horizontalAlignement); + } } final protected TextBlock getTextBlock() { diff --git a/src/net/sourceforge/plantuml/skin/bluemodern/BlueModern.java b/src/net/sourceforge/plantuml/skin/bluemodern/BlueModern.java index 7e6d0b955..0798ccb45 100644 --- a/src/net/sourceforge/plantuml/skin/bluemodern/BlueModern.java +++ b/src/net/sourceforge/plantuml/skin/bluemodern/BlueModern.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5272 $ + * Revision $Revision: 5728 $ * */ package net.sourceforge.plantuml.skin.bluemodern; @@ -151,7 +151,7 @@ public class BlueModern implements Skin { } if (type == ComponentType.ENGLOBER) { return new ComponentBlueModernEnglober(blue1, blue3, stringsToDisplay, Color.BLACK, param - .getFont(FontParam.SEQUENCE_ENGLOBER)); + .getFont(FontParam.SEQUENCE_ENGLOBER, null)); } return null; diff --git a/src/net/sourceforge/plantuml/skin/rose/Rose.java b/src/net/sourceforge/plantuml/skin/rose/Rose.java index e1f5e4a59..782c0732c 100644 --- a/src/net/sourceforge/plantuml/skin/rose/Rose.java +++ b/src/net/sourceforge/plantuml/skin/rose/Rose.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5218 $ + * Revision $Revision: 5823 $ * */ package net.sourceforge.plantuml.skin.rose; @@ -81,15 +81,17 @@ public class Rose implements Skin { defaultsColor.put(ColorParam.stateBackground, new HtmlColor("#FEFECE")); defaultsColor.put(ColorParam.stateBorder, new HtmlColor("#A80036")); + defaultsColor.put(ColorParam.stateStart, new HtmlColor("black")); + defaultsColor.put(ColorParam.stateEnd, new HtmlColor("black")); defaultsColor.put(ColorParam.usecaseBackground, new HtmlColor("#FEFECE")); defaultsColor.put(ColorParam.usecaseBorder, new HtmlColor("#A80036")); defaultsColor.put(ColorParam.componentBackground, new HtmlColor("#FEFECE")); defaultsColor.put(ColorParam.componentBorder, new HtmlColor("#A80036")); - defaultsColor.put(ColorParam.interfaceBackground, new HtmlColor("#FEFECE")); - defaultsColor.put(ColorParam.interfaceBorder, new HtmlColor("#A80036")); - defaultsColor.put(ColorParam.actorBackground, new HtmlColor("#FEFECE")); - defaultsColor.put(ColorParam.actorBorder, new HtmlColor("#A80036")); + defaultsColor.put(ColorParam.componentInterfaceBackground, new HtmlColor("#FEFECE")); + defaultsColor.put(ColorParam.componentInterfaceBorder, new HtmlColor("#A80036")); + defaultsColor.put(ColorParam.usecaseActorBackground, new HtmlColor("#FEFECE")); + defaultsColor.put(ColorParam.usecaseActorBorder, new HtmlColor("#A80036")); defaultsColor.put(ColorParam.sequenceActorBackground, new HtmlColor("#FEFECE")); defaultsColor.put(ColorParam.sequenceActorBorder, new HtmlColor("#A80036")); @@ -120,11 +122,16 @@ public class Rose implements Skin { } public Color getFontColor(ISkinParam skin, FontParam fontParam) { - return skin.getFontHtmlColor(fontParam).getColor(); + return skin.getFontHtmlColor(fontParam, null).getColor(); + } + + public HtmlColor getHtmlColor(ISkinParam param, ColorParam color) { + return getHtmlColor(param, color, null); } - public HtmlColor getHtmlColor(ISkinParam param, ColorParam color) { - HtmlColor result = param.getHtmlColor(color); + + public HtmlColor getHtmlColor(ISkinParam param, ColorParam color, String stereotype) { + HtmlColor result = param.getHtmlColor(color, stereotype); if (result == null) { result = defaultsColor.get(color); if (result == null) { @@ -146,10 +153,10 @@ public class Rose implements Skin { // final Color borderColor = getHtmlColor(param, // ColorParam.border).getColor(); - final Font fontArrow = param.getFont(FontParam.SEQUENCE_ARROW); - final Font fontGrouping = param.getFont(FontParam.SEQUENCE_GROUPING); - final Font fontParticipant = param.getFont(FontParam.SEQUENCE_PARTICIPANT); - final Font fontActor = param.getFont(FontParam.SEQUENCE_ACTOR); + final Font fontArrow = param.getFont(FontParam.SEQUENCE_ARROW, null); + final Font fontGrouping = param.getFont(FontParam.SEQUENCE_GROUPING, null); + final Font fontParticipant = param.getFont(FontParam.SEQUENCE_PARTICIPANT, null); + final Font fontActor = param.getFont(FontParam.SEQUENCE_ACTOR, null); if (type == ComponentType.SELF_ARROW) { return new ComponentRoseSelfArrow(sequenceArrow, getFontColor(param, FontParam.SEQUENCE_ARROW), fontArrow, @@ -224,12 +231,12 @@ public class Rose implements Skin { if (type == ComponentType.NOTE) { final Color noteBackgroundColor = getHtmlColor(param, ColorParam.noteBackground).getColor(); final Color borderColor = getHtmlColor(param, ColorParam.noteBorder).getColor(); - final Font fontNote = param.getFont(FontParam.NOTE); + final Font fontNote = param.getFont(FontParam.NOTE, null); return new ComponentRoseNote(noteBackgroundColor, borderColor, getFontColor(param, FontParam.NOTE), fontNote, stringsToDisplay); } if (type == ComponentType.GROUPING_HEADER) { - final Font fontGroupingHeader = param.getFont(FontParam.SEQUENCE_GROUPING_HEADER); + final Font fontGroupingHeader = param.getFont(FontParam.SEQUENCE_GROUPING_HEADER, null); return new ComponentRoseGroupingHeader(getFontColor(param, FontParam.SEQUENCE_GROUPING_HEADER), background, groundBackgroundColor, fontGroupingHeader, fontGrouping, stringsToDisplay); } @@ -256,11 +263,11 @@ public class Rose implements Skin { } if (type == ComponentType.DIVIDER) { return new ComponentRoseDivider(getFontColor(param, FontParam.SEQUENCE_DIVIDER), param - .getFont(FontParam.SEQUENCE_DIVIDER), sequenceDividerBackground, stringsToDisplay); + .getFont(FontParam.SEQUENCE_DIVIDER, null), sequenceDividerBackground, stringsToDisplay); } if (type == ComponentType.TITLE) { return new ComponentRoseTitle(getFontColor(param, FontParam.SEQUENCE_TITLE), param - .getFont(FontParam.SEQUENCE_TITLE), stringsToDisplay); + .getFont(FontParam.SEQUENCE_TITLE, null), stringsToDisplay); } if (type == ComponentType.SIGNATURE) { return new ComponentRoseTitle(Color.BLACK, fontGrouping, Arrays.asList("This skin was created ", @@ -270,7 +277,7 @@ public class Rose implements Skin { final Color borderColor = getHtmlColor(param, ColorParam.sequenceEngloberLine).getColor(); final Color backColor = getHtmlColor(param, ColorParam.sequenceEngloberBackground).getColor(); return new ComponentRoseEnglober(borderColor, backColor, stringsToDisplay, getFontColor(param, - FontParam.SEQUENCE_ENGLOBER), param.getFont(FontParam.SEQUENCE_ENGLOBER)); + FontParam.SEQUENCE_ENGLOBER), param.getFont(FontParam.SEQUENCE_ENGLOBER, null)); } return null; } diff --git a/src/net/sourceforge/plantuml/statediagram/command/CommandCreatePackageState.java b/src/net/sourceforge/plantuml/statediagram/command/CommandCreatePackageState.java index dd665ee9c..93835e7f6 100644 --- a/src/net/sourceforge/plantuml/statediagram/command/CommandCreatePackageState.java +++ b/src/net/sourceforge/plantuml/statediagram/command/CommandCreatePackageState.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 4762 $ + * Revision $Revision: 5742 $ * */ package net.sourceforge.plantuml.statediagram.command; @@ -39,12 +39,13 @@ import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand; import net.sourceforge.plantuml.cucadiagram.Group; import net.sourceforge.plantuml.cucadiagram.GroupType; +import net.sourceforge.plantuml.graphic.HtmlColor; import net.sourceforge.plantuml.statediagram.StateDiagram; public class CommandCreatePackageState extends SingleLineCommand { public CommandCreatePackageState(StateDiagram diagram) { - super(diagram, "(?i)^state\\s+(?:\"([^\"]+)\"\\s+as\\s+)?([\\p{L}0-9_.]+)(?:\\s*\\{|\\s+begin)$"); + super(diagram, "(?i)^state\\s+(?:\"([^\"]+)\"\\s+as\\s+)?([\\p{L}0-9_.]+)\\s*(\\<\\<.*\\>\\>)?\\s*(#\\w+)?(?:\\s*\\{|\\s+begin)$"); } @Override @@ -57,6 +58,13 @@ public class CommandCreatePackageState extends SingleLineCommand { } final Group p = getSystem().getOrCreateGroup(code, display, null, GroupType.STATE, currentPackage); p.setRounded(true); + final String stereotype = arg.get(2); + if (stereotype != null) { + p.setStereotype(stereotype); + } + if (arg.get(3) != null && HtmlColor.isValid(arg.get(3))) { + p.setBackColor(new HtmlColor(arg.get(3))); + } return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/statediagram/command/CommandCreatePackageState2.java b/src/net/sourceforge/plantuml/statediagram/command/CommandCreatePackageState2.java index 1a2d2aaa4..ea1960ec8 100644 --- a/src/net/sourceforge/plantuml/statediagram/command/CommandCreatePackageState2.java +++ b/src/net/sourceforge/plantuml/statediagram/command/CommandCreatePackageState2.java @@ -39,12 +39,14 @@ import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand; import net.sourceforge.plantuml.cucadiagram.Group; import net.sourceforge.plantuml.cucadiagram.GroupType; +import net.sourceforge.plantuml.graphic.HtmlColor; import net.sourceforge.plantuml.statediagram.StateDiagram; public class CommandCreatePackageState2 extends SingleLineCommand { public CommandCreatePackageState2(StateDiagram diagram) { - super(diagram, "(?i)^state\\s+([\\p{L}0-9_.]+)\\s+as\\s+\"([^\"]+)\"(?:\\s*\\{|\\s+begin)$"); + super(diagram, + "(?i)^state\\s+([\\p{L}0-9_.]+)\\s+as\\s+\"([^\"]+)\"\\s*(\\<\\<.*\\>\\>)?\\s*(#\\w+)?(?:\\s*\\{|\\s+begin)$"); } @Override @@ -54,6 +56,13 @@ public class CommandCreatePackageState2 extends SingleLineCommand final String display = arg.get(1); final Group p = getSystem().getOrCreateGroup(code, display, null, GroupType.STATE, currentPackage); p.setRounded(true); + final String stereotype = arg.get(2); + if (stereotype != null) { + p.setStereotype(stereotype); + } + if (arg.get(3) != null && HtmlColor.isValid(arg.get(3))) { + p.setBackColor(new HtmlColor(arg.get(3))); + } return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/statediagram/command/CommandCreateState.java b/src/net/sourceforge/plantuml/statediagram/command/CommandCreateState.java index f91de7ab9..5679fa6b1 100644 --- a/src/net/sourceforge/plantuml/statediagram/command/CommandCreateState.java +++ b/src/net/sourceforge/plantuml/statediagram/command/CommandCreateState.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5019 $ + * Revision $Revision: 5727 $ * */ package net.sourceforge.plantuml.statediagram.command; @@ -38,19 +38,15 @@ import java.util.List; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand; import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.cucadiagram.Stereotype; import net.sourceforge.plantuml.statediagram.StateDiagram; public class CommandCreateState extends SingleLineCommand { public CommandCreateState(StateDiagram diagram) { - super(diagram, "(?i)^(?:state\\s+)(?:\"([^\"]+)\"\\s+as\\s+)?([\\p{L}0-9_.]+)$"); + super(diagram, "(?i)^(?:state\\s+)(?:\"([^\"]+)\"\\s+as\\s+)?([\\p{L}0-9_.]+)\\s*(\\<\\<.*\\>\\>)?\\s*(#\\w+)?$"); } - /* - * @Override protected boolean isForbidden(String line) { if - * (line.matches("^[\\p{L}0-9_.]+$")) { return true; } return false; } - */ - @Override protected CommandExecutionResult executeArg(List arg) { String display = arg.get(0); @@ -60,6 +56,14 @@ public class CommandCreateState extends SingleLineCommand { } final Entity ent = (Entity) getSystem().getOrCreateClass(code); ent.setDisplay(display); + + final String stereotype = arg.get(2); + if (stereotype != null) { + ent.setStereotype(new Stereotype(stereotype)); + } + if (arg.get(3)!=null) { + ent.setSpecificBackcolor(arg.get(3)); + } return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/statediagram/command/CommandCreateState2.java b/src/net/sourceforge/plantuml/statediagram/command/CommandCreateState2.java index 4bca92502..e331ddc22 100644 --- a/src/net/sourceforge/plantuml/statediagram/command/CommandCreateState2.java +++ b/src/net/sourceforge/plantuml/statediagram/command/CommandCreateState2.java @@ -38,12 +38,13 @@ import java.util.List; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand; import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.cucadiagram.Stereotype; import net.sourceforge.plantuml.statediagram.StateDiagram; public class CommandCreateState2 extends SingleLineCommand { public CommandCreateState2(StateDiagram diagram) { - super(diagram, "(?i)^(?:state\\s+)([\\p{L}0-9_.]+)\\s+as\\s+\"([^\"]+)\"$"); + super(diagram, "(?i)^(?:state\\s+)([\\p{L}0-9_.]+)\\s+as\\s+\"([^\"]+)\"\\s*(\\<\\<.*\\>\\>)?\\s*(#\\w+)?$"); } @Override @@ -52,7 +53,14 @@ public class CommandCreateState2 extends SingleLineCommand { final String display = arg.get(1); final Entity ent = (Entity) getSystem().getOrCreateClass(code); ent.setDisplay(display); + + final String stereotype = arg.get(2); + if (stereotype != null) { + ent.setStereotype(new Stereotype(stereotype)); + } + if (arg.get(3) != null) { + ent.setSpecificBackcolor(arg.get(3)); + } return CommandExecutionResult.ok(); } - } diff --git a/src/net/sourceforge/plantuml/statediagram/command/CommandLinkState.java b/src/net/sourceforge/plantuml/statediagram/command/CommandLinkState.java deleted file mode 100644 index 7518450ee..000000000 --- a/src/net/sourceforge/plantuml/statediagram/command/CommandLinkState.java +++ /dev/null @@ -1,88 +0,0 @@ -/* ======================================================================== - * PlantUML : a free UML diagram generator - * ======================================================================== - * - * (C) Copyright 2009, 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 Lesser 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: 5441 $ - * - */ -package net.sourceforge.plantuml.statediagram.command; - -import java.util.List; - -import net.sourceforge.plantuml.Direction; -import net.sourceforge.plantuml.StringUtils; -import net.sourceforge.plantuml.command.CommandExecutionResult; -import net.sourceforge.plantuml.command.SingleLineCommand; -import net.sourceforge.plantuml.cucadiagram.IEntity; -import net.sourceforge.plantuml.cucadiagram.Link; -import net.sourceforge.plantuml.cucadiagram.LinkDecor; -import net.sourceforge.plantuml.cucadiagram.LinkType; -import net.sourceforge.plantuml.statediagram.StateDiagram; - -public class CommandLinkState extends SingleLineCommand { - - public CommandLinkState(StateDiagram diagram) { - super(diagram, "(?i)^([\\p{L}0-9_.]+|\\[\\*\\])\\s*" + "(-+(?:left|right|up|down|le?|ri?|up?|do?)?-*[\\]>])" - + "\\s*([\\p{L}0-9_.]+|\\[\\*\\])\\s*(?::\\s*([^\"]+))?$"); - } - - @Override - protected CommandExecutionResult executeArg(List arg) { - final IEntity cl1 = getEntityStart(arg.get(0)); - final IEntity cl2 = getEntityEnd(arg.get(2)); - - final String queueRaw = arg.get(1).substring(0, arg.get(1).length() - 1); - final Direction direction = StringUtils.getQueueDirection(queueRaw); - final String queue = StringUtils.manageQueueForCuca(queueRaw); - final int lenght = queue.length(); - - Link link = new Link(cl1, cl2, new LinkType(LinkDecor.ARROW, LinkDecor.NONE), arg.get(3), lenght); - getSystem().addLink(link); - if (direction == Direction.LEFT || direction == Direction.UP) { - link = link.getInv(); - } - - return CommandExecutionResult.ok(); - } - - private IEntity getEntityStart(String code) { - if (code.startsWith("[*]")) { - return getSystem().getStart(); - } - return getSystem().getOrCreateClass(code); - } - - private IEntity getEntityEnd(String code) { - if (code.startsWith("[*]")) { - return getSystem().getEnd(); - } - return getSystem().getOrCreateClass(code); - } - -} diff --git a/src/net/sourceforge/plantuml/statediagram/command/CommandLinkState2.java b/src/net/sourceforge/plantuml/statediagram/command/CommandLinkState2.java index 3273a68e2..240d35543 100644 --- a/src/net/sourceforge/plantuml/statediagram/command/CommandLinkState2.java +++ b/src/net/sourceforge/plantuml/statediagram/command/CommandLinkState2.java @@ -46,26 +46,30 @@ import net.sourceforge.plantuml.cucadiagram.IEntity; import net.sourceforge.plantuml.cucadiagram.Link; import net.sourceforge.plantuml.cucadiagram.LinkDecor; import net.sourceforge.plantuml.cucadiagram.LinkType; +import net.sourceforge.plantuml.cucadiagram.Stereotype; import net.sourceforge.plantuml.statediagram.StateDiagram; public class CommandLinkState2 extends SingleLineCommand2 { public CommandLinkState2(StateDiagram diagram) { super(diagram, getRegex()); - // "(?i)^([\\p{L}0-9_.]+|\\[\\*\\])\\s*" + - // "(-+(?:left|right|up|down|le?|ri?|up?|do?)?-*[\\]>])" - // + "\\s*([\\p{L}0-9_.]+|\\[\\*\\])\\s*(?::\\s*([^\"]+))?$"); } static RegexConcat getRegex() { - return new RegexConcat(new RegexLeaf("^"), getStatePattern("ENT1"), new RegexLeaf("\\s*"), new RegexLeaf( - "ARROW", "((-+)(left|right|up|down|le?|ri?|up?|do?)?(-*)([\\]>]))"), new RegexLeaf("\\s*"), - getStatePattern("ENT2"), new RegexLeaf("\\s*"), new RegexLeaf("LABEL", "(?::\\s*([^\"]+))?"), + return new RegexConcat( + new RegexLeaf("^"), + getStatePattern("ENT1"), + new RegexLeaf("\\s*"), + new RegexLeaf("ARROW", "((-+)(left|right|up|down|le?|ri?|up?|do?)?(-*)([\\]>]))"), + new RegexLeaf("\\s*"), + getStatePattern("ENT2"), + new RegexLeaf("\\s*"), + new RegexLeaf("LABEL", "(?::\\s*([^\"]+))?"), new RegexLeaf("$")); } private static RegexLeaf getStatePattern(String name) { - return new RegexLeaf(name, "([\\p{L}0-9_.]+|\\[\\*\\])"); + return new RegexLeaf(name, "([\\p{L}0-9_.]+|\\[\\*\\])\\s*(\\<\\<.*\\>\\>)?\\s*(#\\w+)?"); } @Override @@ -75,6 +79,19 @@ public class CommandLinkState2 extends SingleLineCommand2 { final IEntity cl1 = getEntityStart(ent1); final IEntity cl2 = getEntityEnd(ent2); + + if (arg.get("ENT1").get(1) != null) { + cl1.setStereotype(new Stereotype(arg.get("ENT1").get(1))); + } + if (arg.get("ENT1").get(2) != null) { + cl1.setSpecificBackcolor(arg.get("ENT1").get(2)); + } + if (arg.get("ENT2").get(1) != null) { + cl2.setStereotype(new Stereotype(arg.get("ENT2").get(1))); + } + if (arg.get("ENT2").get(2) != null) { + cl2.setSpecificBackcolor(arg.get("ENT2").get(2)); + } String queue = arg.get("ARROW").get(1) + arg.get("ARROW").get(3); final Direction dir = getDirection(arg); diff --git a/src/net/sourceforge/plantuml/sudoku/GraphicsSudoku.java b/src/net/sourceforge/plantuml/sudoku/GraphicsSudoku.java index 3eafb07ce..bf00aa43f 100644 --- a/src/net/sourceforge/plantuml/sudoku/GraphicsSudoku.java +++ b/src/net/sourceforge/plantuml/sudoku/GraphicsSudoku.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 4125 $ + * Revision $Revision: 5872 $ * */ package net.sourceforge.plantuml.sudoku; @@ -61,7 +61,7 @@ public class GraphicsSudoku { public void writeImage(OutputStream os) throws IOException { final BufferedImage im = createImage(); - PngIO.write(im, os); + PngIO.write(im, os, 96); } final private int xOffset = 5; diff --git a/src/net/sourceforge/plantuml/sudoku/PSystemSudoku.java b/src/net/sourceforge/plantuml/sudoku/PSystemSudoku.java index 28692037e..64a0ac2de 100644 --- a/src/net/sourceforge/plantuml/sudoku/PSystemSudoku.java +++ b/src/net/sourceforge/plantuml/sudoku/PSystemSudoku.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 4041 $ + * Revision $Revision: 5794 $ * */ package net.sourceforge.plantuml.sudoku; @@ -41,13 +41,13 @@ import java.util.Arrays; import java.util.List; import net.sourceforge.plantuml.AbstractPSystem; -import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.FileFormatOption; public class PSystemSudoku extends AbstractPSystem { final private ISudoku sudoku; - public List createFiles(File suggestedFile, FileFormat fileFormat) throws IOException, InterruptedException { + public List createFiles(File suggestedFile, FileFormatOption fileFormat) throws IOException, InterruptedException { OutputStream os = null; try { os = new FileOutputStream(suggestedFile); @@ -60,7 +60,7 @@ public class PSystemSudoku extends AbstractPSystem { return Arrays.asList(suggestedFile); } - public void createFile(OutputStream os, int index, FileFormat fileFormat) throws IOException { + public void createFile(OutputStream os, int index, FileFormatOption fileFormat) throws IOException { new GraphicsSudoku(sudoku).writeImage(os); } diff --git a/src/net/sourceforge/plantuml/swing/ImageWindow.java b/src/net/sourceforge/plantuml/swing/ImageWindow.java index 41bd2d9ca..c7b04196c 100644 --- a/src/net/sourceforge/plantuml/swing/ImageWindow.java +++ b/src/net/sourceforge/plantuml/swing/ImageWindow.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 3837 $ + * Revision $Revision: 5885 $ * */ package net.sourceforge.plantuml.swing; @@ -36,26 +36,51 @@ package net.sourceforge.plantuml.swing; import java.awt.BorderLayout; import java.awt.Image; import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.File; import javax.swing.ImageIcon; +import javax.swing.JButton; import javax.swing.JFrame; +import javax.swing.JPanel; import javax.swing.JScrollPane; +import javax.swing.ListModel; import javax.swing.WindowConstants; class ImageWindow extends JFrame { - private final SimpleLine simpleLine; + private SimpleLine simpleLine; final private JScrollPane scrollPane; + private final JButton next = new JButton("Next"); + private final JButton previous = new JButton("Previous"); + private final ListModel listModel; + private int index; - public ImageWindow(SimpleLine simpleLine, final MainWindow main) { + public ImageWindow(SimpleLine simpleLine, final MainWindow main, ListModel listModel, int index) { super(simpleLine.toString()); - this.simpleLine = simpleLine; + this.listModel = listModel; + this.index = index; + + final JPanel north = new JPanel(); + north.add(previous); + north.add(next); + next.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent ae) { + next(); + } + }); + previous.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent ae) { + previous(); + } + }); scrollPane = new JScrollPane(buildScrollablePicture()); + getContentPane().add(north, BorderLayout.NORTH); getContentPane().add(scrollPane, BorderLayout.CENTER); setSize(640, 400); setVisible(true); @@ -69,6 +94,28 @@ class ImageWindow extends JFrame { }); } + private void next() { + index++; + updateSimpleLine(); + } + + private void previous() { + index--; + updateSimpleLine(); + } + + private void updateSimpleLine() { + if (index < 0) { + index = 0; + } + if (index > listModel.getSize() - 1) { + index = listModel.getSize() - 1; + } + simpleLine = (SimpleLine) listModel.getElementAt(index); + setTitle(simpleLine.toString()); + refreshImage(); + } + private ScrollablePicture buildScrollablePicture() { final File png = simpleLine.getGeneratedImage().getPngFile(); final Image image = Toolkit.getDefaultToolkit().createImage(png.getAbsolutePath()); diff --git a/src/net/sourceforge/plantuml/swing/MainWindow.java b/src/net/sourceforge/plantuml/swing/MainWindow.java index 58b73e250..6f74393f7 100644 --- a/src/net/sourceforge/plantuml/swing/MainWindow.java +++ b/src/net/sourceforge/plantuml/swing/MainWindow.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 4494 $ + * Revision $Revision: 5885 $ * */ package net.sourceforge.plantuml.swing; @@ -65,6 +65,7 @@ import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextField; +import javax.swing.ListModel; import javax.swing.SwingUtilities; import javax.swing.Timer; @@ -178,7 +179,7 @@ public class MainWindow extends JFrame { public void mouseClicked(MouseEvent e) { if (e.getClickCount() == 2) { final int index = jList1.locationToIndex(e.getPoint()); - doubleClick((SimpleLine) jList1.getModel().getElementAt(index)); + doubleClick((SimpleLine) jList1.getModel().getElementAt(index), jList1.getModel(), index); } } }; @@ -248,7 +249,7 @@ public class MainWindow extends JFrame { jList1.setVisible(true); } - private void doubleClick(SimpleLine simpleLine) { + private void doubleClick(SimpleLine simpleLine, ListModel listModel, int index) { for (ImageWindow win : openWindows) { if (win.getSimpleLine().equals(simpleLine)) { win.setVisible(true); @@ -256,7 +257,7 @@ public class MainWindow extends JFrame { return; } } - openWindows.add(new ImageWindow(simpleLine, this)); + openWindows.add(new ImageWindow(simpleLine, this, listModel, index)); } private void tick() { diff --git a/src/net/sourceforge/plantuml/ugraphic/UGroup.java b/src/net/sourceforge/plantuml/ugraphic/UGroup.java index 1e78fc96e..ec121d23e 100644 --- a/src/net/sourceforge/plantuml/ugraphic/UGroup.java +++ b/src/net/sourceforge/plantuml/ugraphic/UGroup.java @@ -33,7 +33,6 @@ */ package net.sourceforge.plantuml.ugraphic; -import java.awt.geom.Dimension2D; import java.awt.geom.Point2D; import java.util.Map; diff --git a/src/net/sourceforge/plantuml/ugraphic/UText.java b/src/net/sourceforge/plantuml/ugraphic/UText.java index d8e815d06..50fba8f48 100644 --- a/src/net/sourceforge/plantuml/ugraphic/UText.java +++ b/src/net/sourceforge/plantuml/ugraphic/UText.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 3837 $ + * Revision $Revision: 5755 $ * */ package net.sourceforge.plantuml.ugraphic; @@ -41,6 +41,7 @@ public class UText implements UShape { private final FontConfiguration font; public UText(String text, FontConfiguration font) { + assert text.indexOf('\t') == -1; this.text = text; this.font = font; } diff --git a/src/net/sourceforge/plantuml/ugraphic/eps/DriverRectangleEps.java b/src/net/sourceforge/plantuml/ugraphic/eps/DriverRectangleEps.java index 91527b49d..20290a188 100644 --- a/src/net/sourceforge/plantuml/ugraphic/eps/DriverRectangleEps.java +++ b/src/net/sourceforge/plantuml/ugraphic/eps/DriverRectangleEps.java @@ -31,8 +31,6 @@ */ package net.sourceforge.plantuml.ugraphic.eps; -import java.awt.Color; - import net.sourceforge.plantuml.eps.EpsGraphics; import net.sourceforge.plantuml.ugraphic.ClipContainer; import net.sourceforge.plantuml.ugraphic.UDriver; diff --git a/src/net/sourceforge/plantuml/ugraphic/g2d/DriverTextG2d.java b/src/net/sourceforge/plantuml/ugraphic/g2d/DriverTextG2d.java index 56361b023..d51c89885 100644 --- a/src/net/sourceforge/plantuml/ugraphic/g2d/DriverTextG2d.java +++ b/src/net/sourceforge/plantuml/ugraphic/g2d/DriverTextG2d.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5507 $ + * Revision $Revision: 5735 $ * */ package net.sourceforge.plantuml.ugraphic.g2d; @@ -38,9 +38,11 @@ import java.awt.Color; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics2D; +import java.awt.GraphicsEnvironment; import java.awt.geom.Dimension2D; import net.sourceforge.plantuml.Dimension2DDouble; +import net.sourceforge.plantuml.Log; import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.FontStyle; import net.sourceforge.plantuml.graphic.StringBounder; @@ -52,6 +54,19 @@ import net.sourceforge.plantuml.ugraphic.UText; public class DriverTextG2d implements UDriver { +// static { +// printFont(); +// } + + private static void printFont() { + final GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + final String fontNames[] = ge.getAvailableFontFamilyNames(); + final int j = fontNames.length; + for (int i = 0; i < j; i++) { + Log.info("Available fonts: " + fontNames[i]); + } + } + public void draw(UShape ushape, double x, double y, UParam param, Graphics2D g2d) { final UText shape = (UText) ushape; final FontConfiguration fontConfiguration = shape.getFontConfiguration(); diff --git a/src/net/sourceforge/plantuml/ugraphic/g2d/UGraphicG2d.java b/src/net/sourceforge/plantuml/ugraphic/g2d/UGraphicG2d.java index a482a1826..5952942b8 100644 --- a/src/net/sourceforge/plantuml/ugraphic/g2d/UGraphicG2d.java +++ b/src/net/sourceforge/plantuml/ugraphic/g2d/UGraphicG2d.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5326 $ + * Revision $Revision: 5793 $ * */ package net.sourceforge.plantuml.ugraphic.g2d; @@ -36,6 +36,7 @@ package net.sourceforge.plantuml.ugraphic.g2d; import java.awt.Font; import java.awt.Graphics2D; import java.awt.Shape; +import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.io.IOException; @@ -60,8 +61,16 @@ public class UGraphicG2d extends AbstractUGraphic { private final BufferedImage bufferedImage; - public UGraphicG2d(Graphics2D g2d, BufferedImage bufferedImage) { + private final double dpiFactor; + + public UGraphicG2d(Graphics2D g2d, BufferedImage bufferedImage, double dpiFactor) { super(g2d); + this.dpiFactor = dpiFactor; + if (dpiFactor != 1.0) { + final AffineTransform at = g2d.getTransform(); + at.concatenate(AffineTransform.getScaleInstance(dpiFactor, dpiFactor)); + g2d.setTransform(at); + } this.bufferedImage = bufferedImage; registerDriver(URectangle.class, new DriverRectangleG2d()); registerDriver(UText.class, new DriverTextG2d()); @@ -99,14 +108,18 @@ public class UGraphicG2d extends AbstractUGraphic { getGraphicObject().setFont(font); getGraphicObject().drawString("" + c, (float) (xpos + getTranslateX()), (float) (ypos + getTranslateY())); - //getGraphicObject().drawString("" + c, Math.round(xpos + getTranslateX()), Math.round(ypos + getTranslateY())); + // getGraphicObject().drawString("" + c, Math.round(xpos + + // getTranslateX()), Math.round(ypos + getTranslateY())); } - + static public String getSvgString(UDrawable udrawable) throws IOException { final UGraphicSvg ug = new UGraphicSvg(false); udrawable.drawU(ug); return CucaDiagramFileMaker.getSvg(ug); } + protected final double getDpiFactor() { + return dpiFactor; + } } diff --git a/src/net/sourceforge/plantuml/usecasediagram/command/CommandCreateActor.java b/src/net/sourceforge/plantuml/usecasediagram/command/CommandCreateActor.java index e2571ec52..be8cc7391 100644 --- a/src/net/sourceforge/plantuml/usecasediagram/command/CommandCreateActor.java +++ b/src/net/sourceforge/plantuml/usecasediagram/command/CommandCreateActor.java @@ -33,7 +33,6 @@ package net.sourceforge.plantuml.usecasediagram.command; import java.util.List; -import net.sourceforge.plantuml.FontParam; import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.SingleLineCommand; @@ -69,13 +68,12 @@ public class CommandCreateActor extends SingleLineCommand { display = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg.get(0)); code = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(arg.get(1)); } - final String stereotype = arg.get(2); final Entity entity = (Entity) getSystem().getOrCreateClass(code); entity.setDisplay(display); + final String stereotype = arg.get(2); if (stereotype != null) { - entity.setStereotype(new Stereotype(stereotype, getSystem().getSkinParam().getCircledCharacterRadius(), - getSystem().getSkinParam().getFont(FontParam.CIRCLED_CHARACTER))); + entity.setStereotype(new Stereotype(stereotype)); } return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/usecasediagram/command/CommandCreateActor2.java b/src/net/sourceforge/plantuml/usecasediagram/command/CommandCreateActor2.java index 7d554e963..ecb2167b0 100644 --- a/src/net/sourceforge/plantuml/usecasediagram/command/CommandCreateActor2.java +++ b/src/net/sourceforge/plantuml/usecasediagram/command/CommandCreateActor2.java @@ -67,7 +67,7 @@ public class CommandCreateActor2 extends SingleLineCommand { if (stereotype != null) { entity.setStereotype(new Stereotype(stereotype, getSystem().getSkinParam().getCircledCharacterRadius(), - getSystem().getSkinParam().getFont(FontParam.CIRCLED_CHARACTER))); + getSystem().getSkinParam().getFont(FontParam.CIRCLED_CHARACTER, null))); } return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/usecasediagram/command/CommandCreateUsecase.java b/src/net/sourceforge/plantuml/usecasediagram/command/CommandCreateUsecase.java index 051d95a77..aa84b5053 100644 --- a/src/net/sourceforge/plantuml/usecasediagram/command/CommandCreateUsecase.java +++ b/src/net/sourceforge/plantuml/usecasediagram/command/CommandCreateUsecase.java @@ -76,7 +76,7 @@ public class CommandCreateUsecase extends SingleLineCommand { entity.setDisplay(display); if (stereotype != null) { entity.setStereotype(new Stereotype(stereotype, getSystem().getSkinParam().getCircledCharacterRadius(), - getSystem().getSkinParam().getFont(FontParam.CIRCLED_CHARACTER))); + getSystem().getSkinParam().getFont(FontParam.CIRCLED_CHARACTER, null))); } return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/usecasediagram/command/CommandCreateUsecase2.java b/src/net/sourceforge/plantuml/usecasediagram/command/CommandCreateUsecase2.java index 8608a7bf1..047f56c2b 100644 --- a/src/net/sourceforge/plantuml/usecasediagram/command/CommandCreateUsecase2.java +++ b/src/net/sourceforge/plantuml/usecasediagram/command/CommandCreateUsecase2.java @@ -68,7 +68,7 @@ public class CommandCreateUsecase2 extends SingleLineCommand { entity.setDisplay(display); if (stereotype != null) { entity.setStereotype(new Stereotype(stereotype, getSystem().getSkinParam().getCircledCharacterRadius(), - getSystem().getSkinParam().getFont(FontParam.CIRCLED_CHARACTER))); + getSystem().getSkinParam().getFont(FontParam.CIRCLED_CHARACTER, null))); } return CommandExecutionResult.ok(); } diff --git a/src/net/sourceforge/plantuml/usecasediagram/command/CommandLinkUsecase.java b/src/net/sourceforge/plantuml/usecasediagram/command/CommandLinkUsecase.java deleted file mode 100644 index a2023369a..000000000 --- a/src/net/sourceforge/plantuml/usecasediagram/command/CommandLinkUsecase.java +++ /dev/null @@ -1,158 +0,0 @@ -/* ======================================================================== - * PlantUML : a free UML diagram generator - * ======================================================================== - * - * (C) Copyright 2009, 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 Lesser 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 - * - */ -package net.sourceforge.plantuml.usecasediagram.command; - -import java.util.List; - -import net.sourceforge.plantuml.Direction; -import net.sourceforge.plantuml.StringUtils; -import net.sourceforge.plantuml.command.CommandExecutionResult; -import net.sourceforge.plantuml.command.SingleLineCommand; -import net.sourceforge.plantuml.cucadiagram.Group; -import net.sourceforge.plantuml.cucadiagram.IEntity; -import net.sourceforge.plantuml.cucadiagram.Link; -import net.sourceforge.plantuml.cucadiagram.LinkDecor; -import net.sourceforge.plantuml.cucadiagram.LinkType; -import net.sourceforge.plantuml.usecasediagram.UsecaseDiagram; - -public class CommandLinkUsecase extends SingleLineCommand { - - private static final int FIRST_UC_AC_OR_GROUP = 0; - private static final int LEFT_TO_RIGHT = 1; - private static final int LEFT_TO_RIGHT_QUEUE = 2; - private static final int LEFT_TO_RIGHT_HEAD = 3; - private static final int RIGHT_TO_LEFT = 4; - private static final int RIGHT_TO_LEFT_HEAD = 5; - private static final int RIGHT_TO_LEFT_QUEUE = 6; - private static final int SECOND_UC_AC_OR_GROUP = 7; - private static final int LINK_LABEL = 8; - - public CommandLinkUsecase(UsecaseDiagram diagram) { - super( - diagram, - "(?i)^([\\p{L}0-9_.]+|:[^:]+:|\\((?!\\*\\))[^)]+\\))\\s*" - + "(?:(" - + "([=-]+(?:left|right|up|down|le?|ri?|up?|do?)?[=-]*|\\.+(?:left|right|up|down|le?|ri?|up?|do?)?\\.*)([\\]>]|\\|[>\\]])?" - + ")|(" - + "([\\[<]|[<\\[]\\|)?([=-]*(?:left|right|up|down|le?|ri?|up?|do?)?[=-]+|\\.*(?:left|right|up|down|le?|ri?|up?|do?)?\\.+)" - + "))" + "\\s*([\\p{L}0-9_.]+|:[^:]+:|\\((?!\\*\\))[^)]+\\))\\s*(?::\\s*([^\"]+))?$"); - } - - @Override - protected CommandExecutionResult executeArg(List arg) { - if (getSystem().isGroup(arg.get(FIRST_UC_AC_OR_GROUP)) && getSystem().isGroup(arg.get(SECOND_UC_AC_OR_GROUP))) { - return executePackageLink(arg); - } - if (getSystem().isGroup(arg.get(FIRST_UC_AC_OR_GROUP)) || getSystem().isGroup(arg.get(SECOND_UC_AC_OR_GROUP))) { - return CommandExecutionResult.error("Package can be only linked to other package"); - } - - final IEntity cl1 = getSystem().getOrCreateClass(arg.get(FIRST_UC_AC_OR_GROUP)); - final IEntity cl2 = getSystem().getOrCreateClass(arg.get(SECOND_UC_AC_OR_GROUP)); - - final LinkType linkType = arg.get(LEFT_TO_RIGHT) != null ? getLinkTypeNormal(arg) : getLinkTypeInv(arg); - final String queue = StringUtils.manageQueueForCuca(arg.get(LEFT_TO_RIGHT) != null ? arg - .get(LEFT_TO_RIGHT_QUEUE) : arg.get(RIGHT_TO_LEFT_QUEUE)); - - Link link = new Link(cl1, cl2, linkType, arg.get(LINK_LABEL), queue.length()); - if (arg.get(LEFT_TO_RIGHT) != null) { - Direction direction = StringUtils.getQueueDirection(arg.get(LEFT_TO_RIGHT_QUEUE)); - if (linkType.isExtendsOrAgregationOrCompositionOrPlus()) { - direction = direction.getInv(); - } - if (direction == Direction.LEFT || direction == Direction.UP) { - link = link.getInv(); - } - } - if (arg.get(RIGHT_TO_LEFT) != null) { - Direction direction = StringUtils.getQueueDirection(arg.get(RIGHT_TO_LEFT_QUEUE)); - if (linkType.isExtendsOrAgregationOrCompositionOrPlus()) { - direction = direction.getInv(); - } - if (direction == Direction.RIGHT || direction == Direction.DOWN) { - link = link.getInv(); - } - } - getSystem().addLink(link); - return CommandExecutionResult.ok(); - } - - private CommandExecutionResult executePackageLink(List arg) { - final Group cl1 = getSystem().getGroup(arg.get(FIRST_UC_AC_OR_GROUP)); - final Group cl2 = getSystem().getGroup(arg.get(SECOND_UC_AC_OR_GROUP)); - - final LinkType linkType = arg.get(LEFT_TO_RIGHT) != null ? getLinkTypeNormal(arg) : getLinkTypeInv(arg); - final String queue = arg.get(LEFT_TO_RIGHT) != null ? arg.get(LEFT_TO_RIGHT_QUEUE) : arg - .get(RIGHT_TO_LEFT_QUEUE); - - final Link link = new Link(cl1.getEntityCluster(), cl2.getEntityCluster(), linkType, arg.get(LINK_LABEL), queue - .length()); - getSystem().addLink(link); - return CommandExecutionResult.ok(); - } - - private LinkType getLinkTypeNormal(List arg) { - final String queue = arg.get(LEFT_TO_RIGHT_QUEUE); - final String key = arg.get(LEFT_TO_RIGHT_HEAD); - LinkType linkType = getLinkTypeFromKey(key); - - if (queue.startsWith(".")) { - linkType = linkType.getDashed(); - } - return linkType; - } - - private LinkType getLinkTypeInv(List arg) { - final String queue = arg.get(RIGHT_TO_LEFT_QUEUE); - final String key = arg.get(RIGHT_TO_LEFT_HEAD); - LinkType linkType = getLinkTypeFromKey(key); - - if (queue.startsWith(".")) { - linkType = linkType.getDashed(); - } - return linkType.getInv(); - } - - private LinkType getLinkTypeFromKey(String k) { - if (k == null) { - return new LinkType(LinkDecor.NONE, LinkDecor.NONE); - } - if (k.equals("<") || k.equals(">")) { - return new LinkType(LinkDecor.ARROW, LinkDecor.NONE); - } - if (k.equals("<|") || k.equals("|>")) { - return new LinkType(LinkDecor.EXTENDS, LinkDecor.NONE); - } - return null; - } - -} diff --git a/src/net/sourceforge/plantuml/usecasediagram/command/CommandLinkUsecase2.java b/src/net/sourceforge/plantuml/usecasediagram/command/CommandLinkUsecase2.java index 99cf91932..d719e085a 100644 --- a/src/net/sourceforge/plantuml/usecasediagram/command/CommandLinkUsecase2.java +++ b/src/net/sourceforge/plantuml/usecasediagram/command/CommandLinkUsecase2.java @@ -46,43 +46,31 @@ import net.sourceforge.plantuml.cucadiagram.IEntity; import net.sourceforge.plantuml.cucadiagram.Link; import net.sourceforge.plantuml.cucadiagram.LinkDecor; import net.sourceforge.plantuml.cucadiagram.LinkType; +import net.sourceforge.plantuml.cucadiagram.Stereotype; import net.sourceforge.plantuml.usecasediagram.UsecaseDiagram; public class CommandLinkUsecase2 extends SingleLineCommand2 { - private static final int FIRST_UC_AC_OR_GROUP = 0; - private static final int LEFT_TO_RIGHT = 1; - private static final int LEFT_TO_RIGHT_QUEUE = 2; - private static final int LEFT_TO_RIGHT_HEAD = 3; - private static final int RIGHT_TO_LEFT = 4; - private static final int RIGHT_TO_LEFT_HEAD = 5; - private static final int RIGHT_TO_LEFT_QUEUE = 6; - private static final int SECOND_UC_AC_OR_GROUP = 7; - private static final int LINK_LABEL = 8; - public CommandLinkUsecase2(UsecaseDiagram diagram) { super(diagram, getRegexConcat()); - // "(?i)^([\\p{L}0-9_.]+|:[^:]+:|\\((?!\\*\\))[^)]+\\))\\s*" - // + "(?:(" - // + - // "([=-]+(?:left|right|up|down|le?|ri?|up?|do?)?[=-]*|\\.+(?:left|right|up|down|le?|ri?|up?|do?)?\\.*)([\\]>]|\\|[>\\]])?" - // + ")|(" - // + - // "([\\[<]|[<\\[]\\|)?([=-]*(?:left|right|up|down|le?|ri?|up?|do?)?[=-]+|\\.*(?:left|right|up|down|le?|ri?|up?|do?)?\\.+)" - // + "))" + - // "\\s*([\\p{L}0-9_.]+|:[^:]+:|\\((?!\\*\\))[^)]+\\))\\s*(?::\\s*([^\"]+))?$"); } static RegexConcat getRegexConcat() { - return new RegexConcat(new RegexLeaf("^"), getGroup("ENT1"), new RegexLeaf("\\s*"), new RegexOr(new RegexLeaf( - "LEFT_TO_RIGHT", "(([-=.]+)(left|right|up|down|le?|ri?|up?|do?)?([-=.]*)([\\]>]|\\|[>\\]])?)"), - new RegexLeaf("RIGHT_TO_LEFT", - "(([\\[<]|[<\\[]\\|)?([-=.]*)(left|right|up|down|le?|ri?|up?|do?)?([-=.]+))")), new RegexLeaf( - "\\s*"), getGroup("ENT2"), new RegexLeaf("\\s*"), new RegexLeaf("LABEL_LINK", "(?::\\s*([^\"]+))?$")); + return new RegexConcat( + new RegexLeaf("^"), + getGroup("ENT1"), + new RegexLeaf("\\s*"), + new RegexOr( + new RegexLeaf("LEFT_TO_RIGHT", "(([-=.]+)(left|right|up|down|le?|ri?|up?|do?)?([-=.]*)([\\]>]|\\|[>\\]])?)"), + new RegexLeaf("RIGHT_TO_LEFT", "(([\\[<]|[<\\[]\\|)?([-=.]*)(left|right|up|down|le?|ri?|up?|do?)?([-=.]+))")), + new RegexLeaf("\\s*"), + getGroup("ENT2"), + new RegexLeaf("\\s*"), + new RegexLeaf("LABEL_LINK", "(?::\\s*([^\"]+))?$")); } private static RegexLeaf getGroup(String name) { - return new RegexLeaf(name, "([\\p{L}0-9_.]+|:[^:]+:|\\((?!\\*\\))[^)]+\\))"); + return new RegexLeaf(name, "([\\p{L}0-9_.]+|:[^:]+:|\\((?!\\*\\))[^)]+\\))(?:\\s*(\\<\\<.*\\>\\>))?"); } @Override @@ -99,6 +87,13 @@ public class CommandLinkUsecase2 extends SingleLineCommand2 { final IEntity cl1 = getSystem().getOrCreateClass(ent1); final IEntity cl2 = getSystem().getOrCreateClass(ent2); + + if (arg.get("ENT1").get(1) != null) { + cl1.setStereotype(new Stereotype(arg.get("ENT1").get(1))); + } + if (arg.get("ENT2").get(1) != null) { + cl2.setStereotype(new Stereotype(arg.get("ENT2").get(1))); + } final LinkType linkType = getLinkType(arg); Direction dir = getDirection(arg); diff --git a/src/net/sourceforge/plantuml/version/PSystemVersion.java b/src/net/sourceforge/plantuml/version/PSystemVersion.java index a4779d95a..df18fd728 100644 --- a/src/net/sourceforge/plantuml/version/PSystemVersion.java +++ b/src/net/sourceforge/plantuml/version/PSystemVersion.java @@ -48,7 +48,7 @@ import java.util.Properties; import javax.imageio.ImageIO; import net.sourceforge.plantuml.AbstractPSystem; -import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.FileFormatOption; import net.sourceforge.plantuml.OptionPrint; import net.sourceforge.plantuml.graphic.GraphicPosition; import net.sourceforge.plantuml.graphic.GraphicStrings; @@ -69,7 +69,7 @@ public class PSystemVersion extends AbstractPSystem { } } - public List createFiles(File suggestedFile, FileFormat fileFormat) throws IOException, InterruptedException { + public List createFiles(File suggestedFile, FileFormatOption fileFormat) throws IOException, InterruptedException { OutputStream os = null; try { os = new FileOutputStream(suggestedFile); @@ -82,7 +82,7 @@ public class PSystemVersion extends AbstractPSystem { return Arrays.asList(suggestedFile); } - public void createFile(OutputStream os, int index, FileFormat fileFormat) throws IOException { + public void createFile(OutputStream os, int index, FileFormatOption fileFormat) throws IOException { getGraphicStrings().writeImage(os, fileFormat); } diff --git a/src/net/sourceforge/plantuml/version/Version.java b/src/net/sourceforge/plantuml/version/Version.java index 2af35dff3..74b6de0ef 100644 --- a/src/net/sourceforge/plantuml/version/Version.java +++ b/src/net/sourceforge/plantuml/version/Version.java @@ -28,7 +28,7 @@ * * Original Author: Arnaud Roques * - * Revision $Revision: 5659 $ + * Revision $Revision: 5879 $ * */ package net.sourceforge.plantuml.version; @@ -36,11 +36,11 @@ package net.sourceforge.plantuml.version; public class Version { public static int version() { - return 5658; + return 5878; } public static long compileTime() { - return 1290708052921L; + return 1294177111625L; } } diff --git a/src/net/sourceforge/plantuml/xmi/CucaDiagramXmiMaker.java b/src/net/sourceforge/plantuml/xmi/CucaDiagramXmiMaker.java new file mode 100644 index 000000000..5c8db80a0 --- /dev/null +++ b/src/net/sourceforge/plantuml/xmi/CucaDiagramXmiMaker.java @@ -0,0 +1,78 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009, 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 Lesser 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: 5079 $ + * + */ +package net.sourceforge.plantuml.xmi; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Collections; +import java.util.List; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.TransformerException; + +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.Log; +import net.sourceforge.plantuml.classdiagram.ClassDiagram; +import net.sourceforge.plantuml.cucadiagram.CucaDiagram; + +public final class CucaDiagramXmiMaker { + + private final CucaDiagram diagram; + private final FileFormat fileFormat; + + public CucaDiagramXmiMaker(CucaDiagram diagram, FileFormat fileFormat) throws IOException { + this.diagram = diagram; + this.fileFormat = fileFormat; + } + + public List createFiles(File suggestedFile) throws IOException { + try { + final XmiClassDiagram xmi = new XmiClassDiagram((ClassDiagram) diagram, fileFormat); + final FileOutputStream fos = new FileOutputStream(suggestedFile); + xmi.transformerXml(fos); + fos.close(); + return Collections.singletonList(suggestedFile); + } catch (ParserConfigurationException e) { + Log.error(e.toString()); + e.printStackTrace(); + throw new IOException(e.toString()); + } catch (TransformerException e) { + Log.error(e.toString()); + e.printStackTrace(); + throw new IOException(e.toString()); + } + } + +} diff --git a/src/net/sourceforge/plantuml/xmi/XmiClassDiagram.java b/src/net/sourceforge/plantuml/xmi/XmiClassDiagram.java new file mode 100644 index 000000000..7583d6900 --- /dev/null +++ b/src/net/sourceforge/plantuml/xmi/XmiClassDiagram.java @@ -0,0 +1,243 @@ +/* ======================================================================== + * PlantUML : a free UML diagram generator + * ======================================================================== + * + * (C) Copyright 2009, 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 Lesser 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: 5616 $ + * + */ +package net.sourceforge.plantuml.xmi; + +import java.io.OutputStream; +import java.util.HashSet; +import java.util.Set; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import net.sourceforge.plantuml.FileFormat; +import net.sourceforge.plantuml.UniqueSequence; +import net.sourceforge.plantuml.classdiagram.ClassDiagram; +import net.sourceforge.plantuml.cucadiagram.Entity; +import net.sourceforge.plantuml.cucadiagram.IEntity; +import net.sourceforge.plantuml.cucadiagram.Link; +import net.sourceforge.plantuml.cucadiagram.Member; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +public class XmiClassDiagram { + + // http://pierre.ree7.fr/blog/?p=5 + + private final ClassDiagram classDiagram; + private final FileFormat fileFormat; + + private final Document document; + private final Element ownedElement; + + private final Set done = new HashSet(); + + public XmiClassDiagram(ClassDiagram classDiagram, FileFormat fileFormat) throws ParserConfigurationException { + this.classDiagram = classDiagram; + this.fileFormat = fileFormat; + final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + + final DocumentBuilder builder = factory.newDocumentBuilder(); + this.document = builder.newDocument(); + document.setXmlVersion("1.0"); + document.setXmlStandalone(true); + + final Element xmi = document.createElement("XMI"); + xmi.setAttribute("xmi.version", "1.1"); + xmi.setAttribute("xmlns:UML", "href://org.omg/UML/1.3"); + document.appendChild(xmi); + + final Element header = document.createElement("XMI.header"); + xmi.appendChild(header); + + final Element metamodel = document.createElement("XMI.metamodel"); + metamodel.setAttribute("xmi.name", "UML"); + metamodel.setAttribute("xmi.version", "1.3"); + header.appendChild(metamodel); + + final Element content = document.createElement("XMI.content"); + xmi.appendChild(content); + + // + final Element model = document.createElement("UML:Model"); + model.setAttribute("xmi.id", "model1"); + model.setAttribute("name", "PlantUML"); + content.appendChild(model); + + // + this.ownedElement = document.createElement("UML:Namespace.ownedElement"); + model.appendChild(ownedElement); + + for (final Entity ent : classDiagram.entities().values()) { + if (fileFormat == FileFormat.XMI_ARGO && isStandalone(ent) == false) { + continue; + } + final Element cla = createEntityNode(ent); + ownedElement.appendChild(cla); + done.add(ent); + } + + if (fileFormat != FileFormat.XMI_STANDARD) { + for (final Link link : classDiagram.getLinks()) { + addLink(link); + } + } + } + + private boolean isStandalone(IEntity ent) { + for (final Link link : classDiagram.getLinks()) { + if (link.getEntity1() == ent || link.getEntity2() == ent) { + return false; + } + } + return true; + } + + private void addLink(Link link) { + final Element association = document.createElement("UML:Association"); + final String assId = "ass" + UniqueSequence.getValue(); + association.setAttribute("xmi.id", assId); + association.setAttribute("namespace", "model1"); + + final Element connection = document.createElement("UML:Association.connection"); + final Element end1 = document.createElement("UML:AssociationEnd"); + end1.setAttribute("xmi.id", "end" + UniqueSequence.getValue()); + end1.setAttribute("association", assId); + end1.setAttribute("type", link.getEntity1().getUid()); + final Element endparticipant1 = document.createElement("UML:AssociationEnd.participant"); + if (fileFormat == FileFormat.XMI_ARGO) { + if (done.contains(link.getEntity1())) { + endparticipant1.appendChild(createEntityNodeRef(link.getEntity1())); + } else { + endparticipant1.appendChild(createEntityNode(link.getEntity1())); + done.add(link.getEntity1()); + } + } + end1.appendChild(endparticipant1); + connection.appendChild(end1); + + final Element end2 = document.createElement("UML:AssociationEnd"); + end2.setAttribute("xmi.id", "end" + UniqueSequence.getValue()); + end2.setAttribute("association", assId); + end2.setAttribute("type", link.getEntity2().getUid()); + final Element endparticipant2 = document.createElement("UML:AssociationEnd.participant"); + if (fileFormat == FileFormat.XMI_ARGO) { + if (done.contains(link.getEntity2())) { + endparticipant2.appendChild(createEntityNodeRef(link.getEntity2())); + } else { + endparticipant2.appendChild(createEntityNode(link.getEntity2())); + done.add(link.getEntity2()); + } + } + end2.appendChild(endparticipant2); + connection.appendChild(end2); + + association.appendChild(connection); + + ownedElement.appendChild(association); + + } + + private Element createEntityNode(IEntity entity) { + // + final Element cla = document.createElement("UML:Class"); + + cla.setAttribute("xmi.id", entity.getUid()); + cla.setAttribute("name", entity.getDisplay()); + cla.setAttribute("namespace", "model1"); + + final Element feature = document.createElement("UML:Classifier.feature"); + cla.appendChild(feature); + + for (Member m : entity.fields2()) { + // + final Element attribute = document.createElement("UML:Attribute"); + attribute.setAttribute("xmi.id", "att" + UniqueSequence.getValue()); + attribute.setAttribute("name", m.getDisplayWithoutVisibilityChar()); + feature.appendChild(attribute); + } + + for (Member m : entity.methods2()) { + // + final Element operation = document.createElement("UML:Operation"); + operation.setAttribute("xmi.id", "att" + UniqueSequence.getValue()); + operation.setAttribute("name", m.getDisplayWithoutVisibilityChar()); + feature.appendChild(operation); + } + return cla; + } + + private Element createEntityNodeRef(IEntity entity) { + final Element cla = document.createElement("UML:Class"); + cla.setAttribute("xmi.idref", entity.getUid()); + return cla; + } + + public void transformerXml(OutputStream os) throws TransformerException, ParserConfigurationException { + final Source source = new DOMSource(document); + + final Result resultat = new StreamResult(os); + + final TransformerFactory fabrique = TransformerFactory.newInstance(); + final Transformer transformer = fabrique.newTransformer(); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + // transformer.setOutputProperty(OutputKeys.ENCODING, "ISO-8859-1"); + transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); + // tf.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); + transformer.transform(source, resultat); + } + +}