diff --git a/pom.xml b/pom.xml
index a61a91ad2..642323dd0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -35,7 +35,7 @@
net.sourceforge.plantuml
plantuml
- 1.2018.9-SNAPSHOT
+ 1.2018.10-SNAPSHOT
jar
PlantUML
diff --git a/src/net/sourceforge/plantuml/AlignParam.java b/src/net/sourceforge/plantuml/AlignmentParam.java
similarity index 79%
rename from src/net/sourceforge/plantuml/AlignParam.java
rename to src/net/sourceforge/plantuml/AlignmentParam.java
index 9a4fbaa55..e6293b238 100644
--- a/src/net/sourceforge/plantuml/AlignParam.java
+++ b/src/net/sourceforge/plantuml/AlignmentParam.java
@@ -38,17 +38,18 @@ package net.sourceforge.plantuml;
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
-public enum AlignParam {
+public enum AlignmentParam {
- ARROW_MESSAGE_ALIGN(HorizontalAlignment.LEFT),
- SEQUENCE_MESSAGE_ALIGN(HorizontalAlignment.LEFT),
- SEQUENCE_MESSAGETEXT_ALIGN(HorizontalAlignment.LEFT),
- SEQUENCE_REFERENCE_ALIGN(HorizontalAlignment.CENTER),
- PACKAGE_TITLE_ALIGNMENT(HorizontalAlignment.CENTER);
+ arrowMessageAlignment(HorizontalAlignment.LEFT),
+ sequenceMessageAlignment(HorizontalAlignment.LEFT),
+ sequenceMessageTextAlignment(HorizontalAlignment.LEFT),
+ sequenceReferenceAlignment(HorizontalAlignment.CENTER),
+ packageTitleAlignment(HorizontalAlignment.CENTER),
+ noteTextAlignment(HorizontalAlignment.LEFT);
private final HorizontalAlignment defaultValue;
- private AlignParam(HorizontalAlignment defaultValue) {
+ private AlignmentParam(HorizontalAlignment defaultValue) {
this.defaultValue = defaultValue;
}
diff --git a/src/net/sourceforge/plantuml/BlockUml.java b/src/net/sourceforge/plantuml/BlockUml.java
index 33a6d7b17..70dfbf8d0 100644
--- a/src/net/sourceforge/plantuml/BlockUml.java
+++ b/src/net/sourceforge/plantuml/BlockUml.java
@@ -173,9 +173,9 @@ public class BlockUml {
return data.get(0).toString().equalsIgnoreCase(signature);
}
- public List extends CharSequence> getDefinition() {
- if (data.get(0).toString().startsWith("@startdef") == false) {
- throw new IllegalStateException();
+ public List extends CharSequence> getDefinition(boolean withHeader) {
+ if (withHeader) {
+ return Collections.unmodifiableList(data);
}
return Collections.unmodifiableList(data.subList(1, data.size() - 1));
}
diff --git a/src/net/sourceforge/plantuml/BlockUmlBuilder.java b/src/net/sourceforge/plantuml/BlockUmlBuilder.java
index 33690243e..ef1587a86 100644
--- a/src/net/sourceforge/plantuml/BlockUmlBuilder.java
+++ b/src/net/sourceforge/plantuml/BlockUmlBuilder.java
@@ -141,7 +141,7 @@ public final class BlockUmlBuilder implements DefinitionsContainer {
for (BlockUml block : blocks) {
if (block.isStartDef(name)) {
this.defines.importFrom(block.getLocalDefines());
- return block.getDefinition();
+ return block.getDefinition(false);
}
}
return Collections.emptyList();
diff --git a/src/net/sourceforge/plantuml/EmptyImageBuilder.java b/src/net/sourceforge/plantuml/EmptyImageBuilder.java
index a5ae18d74..16824732e 100644
--- a/src/net/sourceforge/plantuml/EmptyImageBuilder.java
+++ b/src/net/sourceforge/plantuml/EmptyImageBuilder.java
@@ -49,18 +49,18 @@ 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) {
if (width > GraphvizUtils.getenvImageLimit()) {
- Log.info("Width too large " + width);
+ Log.info("Width too large " + width + ". You should set PLANTUML_LIMIT_SIZE");
width = GraphvizUtils.getenvImageLimit();
}
if (height > GraphvizUtils.getenvImageLimit()) {
- Log.info("Height too large " + height);
+ Log.info("Height too large " + height + ". You should set PLANTUML_LIMIT_SIZE");
height = GraphvizUtils.getenvImageLimit();
}
Log.info("Creating image " + width + "x" + height);
diff --git a/src/net/sourceforge/plantuml/FileFormat.java b/src/net/sourceforge/plantuml/FileFormat.java
index 5a7786050..ba691c926 100644
--- a/src/net/sourceforge/plantuml/FileFormat.java
+++ b/src/net/sourceforge/plantuml/FileFormat.java
@@ -55,7 +55,7 @@ import net.sourceforge.plantuml.ugraphic.UFont;
*
*/
public enum FileFormat {
- PNG, SVG, EPS, EPS_TEXT, ATXT, UTXT, XMI_STANDARD, XMI_STAR, XMI_ARGO, SCXML, PDF, MJPEG, ANIMATED_GIF, HTML, HTML5, VDX, LATEX, LATEX_NO_PREAMBLE, BASE64, BRAILLE_PNG;
+ PNG, SVG, EPS, EPS_TEXT, ATXT, UTXT, XMI_STANDARD, XMI_STAR, XMI_ARGO, SCXML, PDF, MJPEG, ANIMATED_GIF, HTML, HTML5, VDX, LATEX, LATEX_NO_PREAMBLE, BASE64, BRAILLE_PNG, PREPROC;
/**
* Returns the file format to be used for that format.
diff --git a/src/net/sourceforge/plantuml/ISkinParam.java b/src/net/sourceforge/plantuml/ISkinParam.java
index 8314e44be..22aed027a 100644
--- a/src/net/sourceforge/plantuml/ISkinParam.java
+++ b/src/net/sourceforge/plantuml/ISkinParam.java
@@ -51,6 +51,8 @@ import net.sourceforge.plantuml.ugraphic.UStroke;
public interface ISkinParam extends ISkinSimple {
+ public static final int SWIMLANE_WIDTH_SAME = -1;
+
public HtmlColor getHyperlinkColor();
public boolean useUnderlineForHyperlink();
@@ -67,7 +69,7 @@ public interface ISkinParam extends ISkinSimple {
public UFont getFont(Stereotype stereotype, boolean inPackageTitle, FontParam... fontParam);
- public HorizontalAlignment getHorizontalAlignment(AlignParam param, ArrowDirection arrowDirection);
+ public HorizontalAlignment getHorizontalAlignment(AlignmentParam param, ArrowDirection arrowDirection);
public HorizontalAlignment getDefaultTextAlignment(HorizontalAlignment defaultValue);
@@ -109,6 +111,8 @@ public interface ISkinParam extends ISkinSimple {
public LineBreakStrategy wrapWidth();
+ public LineBreakStrategy swimlaneWrapTitleWidth();
+
public boolean strictUmlStyle();
public boolean forceSequenceParticipantUnderlined();
diff --git a/src/net/sourceforge/plantuml/LineBreakStrategy.java b/src/net/sourceforge/plantuml/LineBreakStrategy.java
index 347d8fe04..5934eb7e7 100644
--- a/src/net/sourceforge/plantuml/LineBreakStrategy.java
+++ b/src/net/sourceforge/plantuml/LineBreakStrategy.java
@@ -45,7 +45,11 @@ public class LineBreakStrategy {
this.value = value;
}
- public double getMathWidth() {
+ public boolean isAuto() {
+ return "auto".equalsIgnoreCase(value);
+ }
+
+ public double getMaxWidth() {
if (value != null && value.matches("-?\\d+")) {
return Double.parseDouble(value);
}
diff --git a/src/net/sourceforge/plantuml/Option.java b/src/net/sourceforge/plantuml/Option.java
index fb2095488..0968f8fad 100644
--- a/src/net/sourceforge/plantuml/Option.java
+++ b/src/net/sourceforge/plantuml/Option.java
@@ -68,6 +68,7 @@ public class Option {
private boolean pipeNoStdErr = false;
private boolean syntax = false;
private boolean checkOnly = false;
+ private OptionPreprocOutputMode preprocessorOutput = null;
private boolean failfast = false;
private boolean failfast2 = false;
private boolean pattern = false;
@@ -332,6 +333,10 @@ public class Option {
textProgressBar = true;
} else if (s.equalsIgnoreCase("-nometadata")) {
hideMetadata = true;
+ } else if (s.equalsIgnoreCase("-preproc")) {
+ preprocessorOutput = OptionPreprocOutputMode.NORMAL;
+ } else if (s.equalsIgnoreCase("-cypher")) {
+ preprocessorOutput = OptionPreprocOutputMode.CYPHER;
} else if (s.equalsIgnoreCase("-checkmetadata")) {
checkMetadata = true;
} else if (s.equalsIgnoreCase("-pipeimageindex")) {
@@ -588,4 +593,12 @@ public class Option {
return checkMetadata;
}
+ public final OptionPreprocOutputMode getPreprocessorOutputMode() {
+ return preprocessorOutput;
+ }
+
+ // public final void setPreprocessorOutput(boolean preprocessorOutput) {
+ // this.preprocessorOutput = preprocessorOutput;
+ // }
+
}
diff --git a/src/net/sourceforge/plantuml/OptionPreprocOutputMode.java b/src/net/sourceforge/plantuml/OptionPreprocOutputMode.java
new file mode 100644
index 000000000..4fc91798a
--- /dev/null
+++ b/src/net/sourceforge/plantuml/OptionPreprocOutputMode.java
@@ -0,0 +1,41 @@
+/* ========================================================================
+ * PlantUML : a free UML diagram generator
+ * ========================================================================
+ *
+ * (C) Copyright 2009-2017, Arnaud Roques
+ *
+ * Project Info: http://plantuml.com
+ *
+ * If you like this project or if you find it useful, you can support us at:
+ *
+ * http://plantuml.com/patreon (only 1$ per month!)
+ * http://plantuml.com/paypal
+ *
+ * This file is part of PlantUML.
+ *
+ * PlantUML is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PlantUML distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ *
+ *
+ * Original Author: Arnaud Roques
+ *
+ *
+ */
+package net.sourceforge.plantuml;
+
+public enum OptionPreprocOutputMode {
+ NORMAL, CYPHER
+
+}
diff --git a/src/net/sourceforge/plantuml/OptionPrint.java b/src/net/sourceforge/plantuml/OptionPrint.java
index f368ce1c5..bd3e6e2bb 100644
--- a/src/net/sourceforge/plantuml/OptionPrint.java
+++ b/src/net/sourceforge/plantuml/OptionPrint.java
@@ -142,9 +142,10 @@ public class OptionPrint {
System.out.println(" -splash\t\tTo display a splash screen with some progress bar");
System.out.println(" -progress\t\tTo display a textual progress bar in console");
System.out.println(" -pipeimageindex N\tTo generate the Nth image with pipe option");
- System.out.println(" -stdlib\tTo print standart library info");
+ System.out.println(" -stdlib\t\tTo print standart library info");
System.out.println(" -extractstdlib\tTo extract PlantUML Standard Library into stdlib folder");
System.out.println(" -filename \"example.puml\"\tTo override %filename% variable");
+ System.out.println(" -preproc\t\tTo output preprocessor text of diagrams");
System.out.println();
System.out.println("If needed, you can setup the environment variable GRAPHVIZ_DOT.");
exit();
diff --git a/src/net/sourceforge/plantuml/PSystemError.java b/src/net/sourceforge/plantuml/PSystemError.java
index 64b19c028..407affa46 100644
--- a/src/net/sourceforge/plantuml/PSystemError.java
+++ b/src/net/sourceforge/plantuml/PSystemError.java
@@ -71,6 +71,7 @@ import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UImage;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.txt.UGraphicTxt;
+import net.sourceforge.plantuml.version.LicenseInfo;
import net.sourceforge.plantuml.version.PSystemVersion;
public class PSystemError extends AbstractPSystem {
@@ -144,9 +145,11 @@ public class PSystemError extends AbstractPSystem {
} else {
udrawable = result;
}
- final int min = (int) (System.currentTimeMillis() / 60000L) % 60;
- if (min == 0) {
- udrawable = addMessage(udrawable);
+ if (LicenseInfo.retrieveQuick().isValid() == false) {
+ final int min = (int) (System.currentTimeMillis() / 60000L) % 60;
+ if (min == 0) {
+ udrawable = addMessage(udrawable);
+ }
}
imageBuilder.setUDrawable(udrawable);
final ImageData imageData = imageBuilder.writeImageTOBEMOVED(fileFormat, seed(), os);
diff --git a/src/net/sourceforge/plantuml/Run.java b/src/net/sourceforge/plantuml/Run.java
index 1d5ea969a..7182af853 100644
--- a/src/net/sourceforge/plantuml/Run.java
+++ b/src/net/sourceforge/plantuml/Run.java
@@ -43,6 +43,9 @@ import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
@@ -67,12 +70,16 @@ import net.sourceforge.plantuml.sequencediagram.SequenceDiagramFactory;
import net.sourceforge.plantuml.statediagram.StateDiagramFactory;
import net.sourceforge.plantuml.stats.StatsUtils;
import net.sourceforge.plantuml.swing.MainWindow2;
+import net.sourceforge.plantuml.syntax.LanguageDescriptor;
import net.sourceforge.plantuml.ugraphic.sprite.SpriteGrayLevel;
import net.sourceforge.plantuml.ugraphic.sprite.SpriteUtils;
+import net.sourceforge.plantuml.utils.Cypher;
import net.sourceforge.plantuml.version.Version;
public class Run {
+ private static Cypher cypher;
+
public static void main(String[] argsArray) throws IOException, InterruptedException {
System.setProperty("log4j.debug", "false");
final long start = System.currentTimeMillis();
@@ -135,6 +142,9 @@ public class Run {
}
forceOpenJdkResourceLoad();
+ if (option.getPreprocessorOutputMode() == OptionPreprocOutputMode.CYPHER) {
+ cypher = new LanguageDescriptor().getCypher();
+ }
boolean error = false;
boolean forceQuit = false;
if (option.isPattern()) {
@@ -231,10 +241,13 @@ public class Run {
return false;
}
+ static private final String httpProtocol = "http://";
+ static private final String httpsProtocol = "https://";
+
private static void encodeSprite(List result) throws IOException {
SpriteGrayLevel level = SpriteGrayLevel.GRAY_16;
boolean compressed = false;
- final File f;
+ final String path;
if (result.size() > 1 && result.get(0).matches("(4|8|16)z?")) {
if (result.get(0).startsWith("8")) {
level = SpriteGrayLevel.GRAY_8;
@@ -243,28 +256,52 @@ public class Run {
level = SpriteGrayLevel.GRAY_4;
}
compressed = StringUtils.goLowerCase(result.get(0)).endsWith("z");
- f = new File(result.get(1));
+ path = result.get(1);
} else {
- f = new File(result.get(0));
+ path = result.get(0);
}
- final BufferedImage im = ImageIO.read(f);
- final String name = getSpriteName(f);
+
+ final String fileName;
+ final URL source;
+ final String lowerPath = StringUtils.goLowerCase(path);
+ if (lowerPath.startsWith(httpProtocol) || lowerPath.startsWith(httpsProtocol)) {
+ source = new URL(path);
+ final String p = source.getPath();
+ fileName = p.substring(p.lastIndexOf('/') + 1, p.length());
+ } else {
+ final File f = new File(path);
+ source = f.toURI().toURL();
+ fileName = f.getName();
+ }
+
+ InputStream stream = null;
+ final BufferedImage im;
+ try {
+ stream = source.openStream();
+ im = ImageIO.read(stream);
+ } finally {
+ if (stream != null) {
+ stream.close();
+ }
+ }
+
+ final String name = getSpriteName(fileName);
final String s = compressed ? SpriteUtils.encodeCompressed(im, name, level) : SpriteUtils.encode(im, name,
level);
System.out.println(s);
}
- private static String getSpriteName(File f) {
- final String s = getSpriteNameInternal(f);
+ private static String getSpriteName(String fileName) {
+ final String s = getSpriteNameInternal(fileName);
if (s.length() == 0) {
return "test";
}
return s;
}
- private static String getSpriteNameInternal(File f) {
+ private static String getSpriteNameInternal(String fileName) {
final StringBuilder sb = new StringBuilder();
- for (char c : f.getName().toCharArray()) {
+ for (char c : fileName.toCharArray()) {
if (("" + c).matches("[\\p{L}0-9_]")) {
sb.append(c);
} else {
@@ -291,7 +328,6 @@ public class Run {
for (String n : name) {
System.out.println("n=" + n);
}
-
}
private static void managePattern() {
@@ -356,6 +392,7 @@ public class Run {
files.addAll(group.getFiles());
}
}
+ Log.info("Found " + files.size() + " files");
for (File f : files) {
try {
final boolean error = manageFileInternal(f, option);
@@ -417,6 +454,7 @@ public class Run {
}
private static boolean manageFileInternal(File f, Option option) throws IOException, InterruptedException {
+ Log.info("Working on " + f.getAbsolutePath());
if (OptionFlags.getInstance().isExtractFromMetadata()) {
System.out.println("------------------------");
System.out.println(f);
@@ -435,6 +473,7 @@ public class Run {
option.getConfig(), option.getCharset(), option.getFileFormatOption());
}
sourceFileReader.setCheckMetadata(option.isCheckMetadata());
+
if (option.isComputeurl()) {
for (BlockUml s : sourceFileReader.getBlocks()) {
System.out.println(s.getEncodedUrl());
@@ -447,10 +486,33 @@ public class Run {
hasErrors(f, result);
return hasError;
}
+ if (option.getPreprocessorOutputMode() != null) {
+ extractPreproc(option, sourceFileReader);
+ return false;
+ }
final List result = sourceFileReader.getGeneratedImages();
+
return hasErrors(f, result);
}
+ private static void extractPreproc(Option option, final ISourceFileReader sourceFileReader) throws IOException {
+ final String charset = option.getCharset();
+ for (BlockUml blockUml : sourceFileReader.getBlocks()) {
+ final SuggestedFile suggested = ((SourceFileReaderAbstract) sourceFileReader).getSuggestedFile(blockUml)
+ .withPreprocFormat();
+ final File file = suggested.getFile(0);
+ Log.info("Export preprocessing source to " + file.getAbsolutePath());
+ final PrintWriter pw = charset == null ? new PrintWriter(file) : new PrintWriter(file, charset);
+ for (CharSequence s : blockUml.getDefinition(true)) {
+ if (cypher != null) {
+ s = cypher.cypher(s.toString());
+ }
+ pw.println(s);
+ }
+ pw.close();
+ }
+ }
+
private static boolean hasErrors(File f, final List list) throws IOException {
boolean result = false;
for (GeneratedImage i : list) {
diff --git a/src/net/sourceforge/plantuml/SignatureUtils.java b/src/net/sourceforge/plantuml/SignatureUtils.java
index 1d5b88a1c..ea0cf2d94 100644
--- a/src/net/sourceforge/plantuml/SignatureUtils.java
+++ b/src/net/sourceforge/plantuml/SignatureUtils.java
@@ -42,18 +42,30 @@ import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
+import java.security.spec.InvalidKeySpecException;
+
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
import net.sourceforge.plantuml.code.AsciiEncoder;
public class SignatureUtils {
+ public static byte[] salting(String pass, byte[] salt) throws NoSuchAlgorithmException, InvalidKeySpecException,
+ UnsupportedEncodingException {
+ final int iterations = 10000;
+ final int keyLength = 512;
+ final SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
+ final PBEKeySpec spec = new PBEKeySpec(pass.toCharArray(), salt, iterations, keyLength);
+ final SecretKey key = skf.generateSecret(spec);
+ return SignatureUtils.getSHA512raw(key.getEncoded());
+ }
+
public static String getSignature(String s) {
try {
- final AsciiEncoder coder = new AsciiEncoder();
- final MessageDigest msgDigest = MessageDigest.getInstance("MD5");
- msgDigest.update(s.getBytes("UTF-8"));
- final byte[] digest = msgDigest.digest();
- return coder.encode(digest);
+ final byte[] digest = getMD5raw(s);
+ return toString(digest);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
throw new UnsupportedOperationException(e);
@@ -63,21 +75,24 @@ public class SignatureUtils {
}
}
- public static String getMD5(String s) {
+ public static String toString(byte data[]) {
+ final AsciiEncoder coder = new AsciiEncoder();
+ return coder.encode(data);
+ }
+
+ public static String toHexString(byte data[]) {
+ final StringBuilder sb = new StringBuilder(data.length * 2);
+ for (byte b : data) {
+ sb.append(String.format("%02x", b));
+ }
+ return sb.toString();
+ }
+
+ public static String getMD5Hex(String s) {
try {
- final MessageDigest msgDigest = MessageDigest.getInstance("MD5");
- msgDigest.update(s.getBytes("UTF-8"));
- final byte[] digest = msgDigest.digest();
- final StringBuilder result = new StringBuilder(32);
- for (byte b : digest) {
- final String tmp = Integer.toHexString(b & 0xFF);
- if (tmp.length() == 1) {
- result.append("0");
- }
- result.append(tmp);
- }
- assert result.length() == 32;
- return result.toString();
+ final byte[] digest = getMD5raw(s);
+ assert digest.length == 16;
+ return toHexString(digest);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
throw new UnsupportedOperationException(e);
@@ -87,6 +102,36 @@ public class SignatureUtils {
}
}
+ public static String getSHA512Hex(String s) {
+ try {
+ final byte[] digest = getSHA512raw(s);
+ assert digest.length == 64;
+ return toHexString(digest);
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ throw new UnsupportedOperationException(e);
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ throw new UnsupportedOperationException(e);
+ }
+ }
+
+ public static byte[] getMD5raw(String s) throws NoSuchAlgorithmException, UnsupportedEncodingException {
+ final MessageDigest msgDigest = MessageDigest.getInstance("MD5");
+ msgDigest.update(s.getBytes("UTF-8"));
+ return msgDigest.digest();
+ }
+
+ public static byte[] getSHA512raw(String s) throws NoSuchAlgorithmException, UnsupportedEncodingException {
+ return getSHA512raw(s.getBytes("UTF-8"));
+ }
+
+ public static byte[] getSHA512raw(byte data[]) throws NoSuchAlgorithmException, UnsupportedEncodingException {
+ final MessageDigest msgDigest = MessageDigest.getInstance("SHA-512");
+ msgDigest.update(data);
+ return msgDigest.digest();
+ }
+
public static String getSignatureSha512(File f) throws IOException {
final InputStream is = new FileInputStream(f);
try {
@@ -98,14 +143,13 @@ public class SignatureUtils {
public static String getSignatureSha512(InputStream is) throws IOException {
try {
- final AsciiEncoder coder = new AsciiEncoder();
final MessageDigest msgDigest = MessageDigest.getInstance("SHA-512");
int read = 0;
while ((read = is.read()) != -1) {
msgDigest.update((byte) read);
}
final byte[] digest = msgDigest.digest();
- return coder.encode(digest);
+ return toString(digest);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
throw new UnsupportedOperationException(e);
@@ -130,7 +174,6 @@ public class SignatureUtils {
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;
@@ -139,7 +182,7 @@ public class SignatureUtils {
}
is.close();
final byte[] digest = msgDigest.digest();
- return coder.encode(digest);
+ return toString(digest);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
throw new UnsupportedOperationException(e);
diff --git a/src/net/sourceforge/plantuml/SkinParam.java b/src/net/sourceforge/plantuml/SkinParam.java
index b24ca1344..2216ab0fa 100644
--- a/src/net/sourceforge/plantuml/SkinParam.java
+++ b/src/net/sourceforge/plantuml/SkinParam.java
@@ -137,6 +137,7 @@ public class SkinParam implements ISkinParam {
key = key.replaceAll("statearrow", "arrow");
key = key.replaceAll("usecasearrow", "arrow");
key = key.replaceAll("sequencearrow", "arrow");
+ key = key.replaceAll("align$", "alignment");
final Matcher2 mm = stereoPattern.matcher(key);
final List result = new ArrayList();
while (mm.find()) {
@@ -427,8 +428,10 @@ public class SkinParam implements ISkinParam {
result.add("PageBorderColor");
result.add("PageExternalColor");
result.add("PageMargin");
+ result.add("WrapWidth");
+ result.add("SwimlaneWidth");
+ result.add("SwimlaneWrapTitleWidth");
-
for (FontParam p : EnumSet.allOf(FontParam.class)) {
final String h = humanName(p.name());
result.add(h + "FontStyle");
@@ -444,6 +447,10 @@ public class SkinParam implements ISkinParam {
final String h = capitalize(p.name());
result.add(h + "Thickness");
}
+ for (AlignmentParam p : EnumSet.allOf(AlignmentParam.class)) {
+ final String h = capitalize(p.name());
+ result.add(h);
+ }
return Collections.unmodifiableSet(result);
}
@@ -470,14 +477,14 @@ public class SkinParam implements ISkinParam {
return DotSplines.SPLINES;
}
- public HorizontalAlignment getHorizontalAlignment(AlignParam param, ArrowDirection arrowDirection) {
+ public HorizontalAlignment getHorizontalAlignment(AlignmentParam param, ArrowDirection arrowDirection) {
final String value;
switch (param) {
- case SEQUENCE_MESSAGE_ALIGN:
- value = getArg(getValue(AlignParam.SEQUENCE_MESSAGE_ALIGN.name()), 0);
+ case sequenceMessageAlignment:
+ value = getArg(getValue(AlignmentParam.sequenceMessageAlignment.name()), 0);
break;
- case SEQUENCE_MESSAGETEXT_ALIGN:
- value = getArg(getValue(AlignParam.SEQUENCE_MESSAGE_ALIGN.name()), 1);
+ case sequenceMessageTextAlignment:
+ value = getArg(getValue(AlignmentParam.sequenceMessageAlignment.name()), 1);
break;
default:
value = getValue(param.name());
@@ -489,6 +496,9 @@ public class SkinParam implements ISkinParam {
if (arrowDirection == ArrowDirection.RIGHT_TO_LEFT_REVERSE) {
return HorizontalAlignment.RIGHT;
}
+ if (arrowDirection == ArrowDirection.BOTH_DIRECTION) {
+ return HorizontalAlignment.CENTER;
+ }
}
if ("reversedirection".equalsIgnoreCase(value)) {
if (arrowDirection == ArrowDirection.LEFT_TO_RIGHT_NORMAL) {
@@ -497,9 +507,14 @@ public class SkinParam implements ISkinParam {
if (arrowDirection == ArrowDirection.RIGHT_TO_LEFT_REVERSE) {
return HorizontalAlignment.LEFT;
}
+ if (arrowDirection == ArrowDirection.BOTH_DIRECTION) {
+ return HorizontalAlignment.CENTER;
+ }
}
final HorizontalAlignment result = HorizontalAlignment.fromString(value);
- if (result == null) {
+ if (result == null && param == AlignmentParam.noteTextAlignment) {
+ return getDefaultTextAlignment(HorizontalAlignment.LEFT);
+ } else if (result == null) {
return param.getDefaultValue();
}
return result;
@@ -755,6 +770,11 @@ public class SkinParam implements ISkinParam {
return new LineBreakStrategy(value);
}
+ public LineBreakStrategy swimlaneWrapTitleWidth() {
+ final String value = getValue("swimlanewraptitlewidth");
+ return new LineBreakStrategy(value);
+ }
+
public boolean strictUmlStyle() {
final String value = getValue("style");
if ("strictuml".equalsIgnoreCase(value)) {
@@ -917,7 +937,7 @@ public class SkinParam implements ISkinParam {
public int swimlaneWidth() {
final String value = getValue("swimlanewidth");
if ("same".equalsIgnoreCase(value)) {
- return -1;
+ return SWIMLANE_WIDTH_SAME;
}
if (value != null && value.matches("\\d+")) {
return Integer.parseInt(value);
diff --git a/src/net/sourceforge/plantuml/SkinParamDelegator.java b/src/net/sourceforge/plantuml/SkinParamDelegator.java
index 362f2b6f3..854b1500b 100644
--- a/src/net/sourceforge/plantuml/SkinParamDelegator.java
+++ b/src/net/sourceforge/plantuml/SkinParamDelegator.java
@@ -103,7 +103,7 @@ public class SkinParamDelegator implements ISkinParam {
return skinParam.getDotExecutable();
}
- public HorizontalAlignment getHorizontalAlignment(AlignParam param, ArrowDirection arrowDirection) {
+ public HorizontalAlignment getHorizontalAlignment(AlignmentParam param, ArrowDirection arrowDirection) {
return skinParam.getHorizontalAlignment(param, arrowDirection);
}
@@ -295,4 +295,8 @@ public class SkinParamDelegator implements ISkinParam {
return skinParam.getCircledCharacter(stereotype);
}
+ public LineBreakStrategy swimlaneWrapTitleWidth() {
+ return skinParam.swimlaneWrapTitleWidth();
+ }
+
}
diff --git a/src/net/sourceforge/plantuml/SourceFileReaderAbstract.java b/src/net/sourceforge/plantuml/SourceFileReaderAbstract.java
index 93bbb0574..7b4bd1229 100644
--- a/src/net/sourceforge/plantuml/SourceFileReaderAbstract.java
+++ b/src/net/sourceforge/plantuml/SourceFileReaderAbstract.java
@@ -140,7 +140,7 @@ public abstract class SourceFileReaderAbstract {
final List result = new ArrayList();
for (BlockUml blockUml : builder.getBlockUmls()) {
- SuggestedFile suggested = getSuggestedFile(blockUml);
+ final SuggestedFile suggested = getSuggestedFile(blockUml);
final Diagram system;
try {
diff --git a/src/net/sourceforge/plantuml/SuggestedFile.java b/src/net/sourceforge/plantuml/SuggestedFile.java
index 5db9a0c12..834fe5ade 100644
--- a/src/net/sourceforge/plantuml/SuggestedFile.java
+++ b/src/net/sourceforge/plantuml/SuggestedFile.java
@@ -52,6 +52,10 @@ public class SuggestedFile {
this.initialCpt = initialCpt;
}
+ public SuggestedFile withPreprocFormat() {
+ return new SuggestedFile(outputFile, FileFormat.PREPROC, initialCpt);
+ }
+
@Override
public String toString() {
return outputFile.getAbsolutePath() + "[" + initialCpt + "]";
diff --git a/src/net/sourceforge/plantuml/SvgString.java b/src/net/sourceforge/plantuml/SvgString.java
index f580d4e88..7d589bfd8 100644
--- a/src/net/sourceforge/plantuml/SvgString.java
+++ b/src/net/sourceforge/plantuml/SvgString.java
@@ -48,8 +48,11 @@ public class SvgString {
this.scale = scale;
}
- public String getSvg() {
+ public String getSvg(boolean raw) {
String result = svg;
+ if (raw) {
+ return result;
+ }
if (result.startsWith(" swimlanes = new ArrayList();
+ private Swimlane currentSwimlane = null;
+
+ private final Instruction root = new InstructionList();
+ private Instruction currentInstruction = root;
+
+ private LinkRendering nextLinkRenderer = LinkRendering.none();
+
+ public SwimlanesA(ISkinParam skinParam, Pragma pragma) {
+ this.skinParam = skinParam;
+ this.pragma = pragma;
+ }
+
+ private FtileFactory getFtileFactory(StringBounder stringBounder) {
+ FtileFactory factory = new VCompactFactory(skinParam, stringBounder);
+ factory = new FtileFactoryDelegatorAddUrl(factory);
+ factory = new FtileFactoryDelegatorAssembly(factory);
+ factory = new FtileFactoryDelegatorIf(factory, pragma);
+ factory = new FtileFactoryDelegatorWhile(factory);
+ factory = new FtileFactoryDelegatorRepeat(factory);
+ factory = new FtileFactoryDelegatorCreateParallel(factory);
+ // factory = new FtileFactoryDelegatorCreateParallelAddingMargin(new
+ // FtileFactoryDelegatorCreateParallel1(factory));
+ factory = new FtileFactoryDelegatorAddNote(factory);
+ factory = new FtileFactoryDelegatorCreateGroup(factory);
+ return factory;
+ }
+
+ public void swimlane(String name, HtmlColor color, Display label) {
+ currentSwimlane = getOrCreate(name);
+ if (color != null) {
+ currentSwimlane.setSpecificColorTOBEREMOVED(ColorType.BACK, color);
+ }
+ if (Display.isNull(label) == false) {
+ currentSwimlane.setDisplay(label);
+ }
+ }
+
+ private Swimlane getOrCreate(String name) {
+ for (Swimlane s : swimlanes) {
+ if (s.getName().equals(name)) {
+ return s;
+ }
+ }
+ final Swimlane result = new Swimlane(name);
+ swimlanes.add(result);
+ return result;
+ }
+
+ class Cross extends UGraphicDelegator {
+
+ private Cross(UGraphic ug) {
+ super(ug);
+ }
+
+ @Override
+ public void draw(UShape shape) {
+ if (shape instanceof Ftile) {
+ final Ftile tile = (Ftile) shape;
+ tile.drawU(this);
+ } else if (shape instanceof Connection) {
+ final Connection connection = (Connection) shape;
+ final Ftile tile1 = connection.getFtile1();
+ final Ftile tile2 = connection.getFtile2();
+
+ if (tile1 == null || tile2 == null) {
+ return;
+ }
+ if (tile1.getSwimlaneOut() != tile2.getSwimlaneIn()) {
+ final ConnectionCross connectionCross = new ConnectionCross(connection);
+ connectionCross.drawU(getUg());
+ }
+ }
+ }
+
+ public UGraphic apply(UChange change) {
+ return new Cross(getUg().apply(change));
+ }
+
+ }
+
+ static protected final double separationMargin = 10;
+
+ private TextBlock full;
+
+ public void drawU(UGraphic ug) {
+ if (full == null) {
+ final FtileFactory factory = getFtileFactory(ug.getStringBounder());
+ full = root.createFtile(factory);
+ if (swimlanes.size() <= 1) {
+ // BUG42
+ full = new TextBlockInterceptorUDrawable(full);
+ }
+ }
+
+ ug = new UGraphicForSnake(ug);
+ if (swimlanes.size() <= 1) {
+ full.drawU(ug);
+ ug.flushUg();
+ return;
+ }
+
+ drawWhenSwimlanes(ug, full);
+ }
+
+ static private void printDebug(UGraphic ug, SlotSet slot, HtmlColor col, TextBlock full) {
+ slot.drawDebugX(ug.apply(new UChangeColor(col)).apply(new UChangeBackColor(col)),
+ full.calculateDimension(ug.getStringBounder()).getHeight());
+
+ }
+
+ protected void drawWhenSwimlanes(final UGraphic ug, TextBlock full) {
+ final StringBounder stringBounder = ug.getStringBounder();
+ final Dimension2D dimensionFull = full.calculateDimension(stringBounder);
+
+ computeSize(ug, full);
+ final UTranslate titleHeightTranslate = getTitleHeightTranslate(stringBounder);
+
+ double x2 = 0;
+ for (Swimlane swimlane : swimlanes) {
+ final HtmlColor back = swimlane.getColors(skinParam).getColor(ColorType.BACK);
+ if (back != null) {
+ final UGraphic background = ug.apply(new UChangeBackColor(back)).apply(new UChangeColor(back))
+ .apply(new UTranslate(x2, 0));
+ background.draw(new URectangle(swimlane.getActualWidth(), dimensionFull.getHeight()
+ + titleHeightTranslate.getDy()));
+ }
+
+ full.drawU(new UGraphicInterceptorOneSwimlane(ug, swimlane).apply(swimlane.getTranslate()).apply(
+ titleHeightTranslate));
+ x2 += swimlane.getActualWidth();
+
+ }
+ final Cross cross = new Cross(ug.apply(titleHeightTranslate));
+ full.drawU(cross);
+ cross.flushUg();
+ }
+
+ protected UTranslate getTitleHeightTranslate(final StringBounder stringBounder) {
+ return new UTranslate();
+ }
+
+ private void computeDrawingWidths(UGraphic ug, TextBlock full) {
+ final StringBounder stringBounder = ug.getStringBounder();
+ for (Swimlane swimlane : swimlanes) {
+ final LimitFinder limitFinder = new LimitFinder(stringBounder, false);
+ final UGraphicInterceptorOneSwimlane interceptor = new UGraphicInterceptorOneSwimlane(new UGraphicForSnake(
+ limitFinder), swimlane);
+ full.drawU(interceptor);
+ interceptor.flushUg();
+ final MinMax minMax = limitFinder.getMinMax();
+ swimlane.setMinMax(minMax);
+ }
+ }
+
+ private void computeSize(UGraphic ug, TextBlock full) {
+ computeDrawingWidths(ug, full);
+ double x1 = 0;
+
+ double swimlaneWidth = skinParam.swimlaneWidth();
+
+ if (swimlaneWidth == ISkinParam.SWIMLANE_WIDTH_SAME) {
+ for (Swimlane swimlane : swimlanes) {
+ swimlaneWidth = Math.max(swimlaneWidth, rawDrawingWidth(swimlane));
+ }
+
+ }
+ for (Swimlane swimlane : swimlanes) {
+ final double swimlaneActualWidth = swimlaneActualWidth(ug.getStringBounder(), swimlaneWidth, swimlane);
+
+ final UTranslate translate = new UTranslate(x1 - swimlane.getMinMax().getMinX() + separationMargin
+ + (swimlaneActualWidth - rawDrawingWidth(swimlane)) / 2.0, 0);
+ swimlane.setTranslateAndWidth(translate, swimlaneActualWidth);
+
+ x1 += swimlaneActualWidth;
+ }
+ }
+
+ protected double swimlaneActualWidth(StringBounder stringBounder, double swimlaneWidth, Swimlane swimlane) {
+ return MathUtils.max(swimlaneWidth, rawDrawingWidth(swimlane));
+ }
+
+ private double rawDrawingWidth(Swimlane swimlane) {
+ return swimlane.getMinMax().getWidth() + 2 * separationMargin;
+ }
+
+ public Dimension2D calculateDimension(StringBounder stringBounder) {
+ return getMinMax(stringBounder).getDimension();
+ }
+
+ public Instruction getCurrent() {
+ return currentInstruction;
+ }
+
+ public void setCurrent(Instruction current) {
+ this.currentInstruction = current;
+ }
+
+ public LinkRendering nextLinkRenderer() {
+ return nextLinkRenderer;
+ }
+
+ public void setNextLinkRenderer(LinkRendering link) {
+ if (link == null) {
+ throw new IllegalArgumentException();
+ }
+ this.nextLinkRenderer = link;
+ }
+
+ public Swimlane getCurrentSwimlane() {
+ return currentSwimlane;
+ }
+
+ private MinMax cachedMinMax;
+
+ @Override
+ public MinMax getMinMax(StringBounder stringBounder) {
+ if (cachedMinMax == null) {
+ cachedMinMax = TextBlockUtils.getMinMax(this, stringBounder);
+ }
+ return cachedMinMax;
+ }
+
+}
diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/SwimlanesB.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/SwimlanesB.java
new file mode 100644
index 000000000..9250a3274
--- /dev/null
+++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/SwimlanesB.java
@@ -0,0 +1,112 @@
+/* ========================================================================
+ * PlantUML : a free UML diagram generator
+ * ========================================================================
+ *
+ * (C) Copyright 2009-2017, Arnaud Roques
+ *
+ * Project Info: http://plantuml.com
+ *
+ * If you like this project or if you find it useful, you can support us at:
+ *
+ * http://plantuml.com/patreon (only 1$ per month!)
+ * http://plantuml.com/paypal
+ *
+ * This file is part of PlantUML.
+ *
+ * PlantUML is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PlantUML distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ *
+ *
+ * Original Author: Arnaud Roques
+ *
+ *
+ */
+package net.sourceforge.plantuml.activitydiagram3.ftile;
+
+import net.sourceforge.plantuml.FontParam;
+import net.sourceforge.plantuml.ISkinParam;
+import net.sourceforge.plantuml.LineBreakStrategy;
+import net.sourceforge.plantuml.Pragma;
+import net.sourceforge.plantuml.graphic.FontConfiguration;
+import net.sourceforge.plantuml.graphic.HorizontalAlignment;
+import net.sourceforge.plantuml.graphic.StringBounder;
+import net.sourceforge.plantuml.graphic.TextBlock;
+import net.sourceforge.plantuml.ugraphic.UGraphic;
+import net.sourceforge.plantuml.ugraphic.UTranslate;
+import net.sourceforge.plantuml.utils.MathUtils;
+
+public class SwimlanesB extends SwimlanesA {
+
+ public SwimlanesB(ISkinParam skinParam, Pragma pragma) {
+ super(skinParam, pragma);
+ }
+
+ @Override
+ protected void drawWhenSwimlanes(UGraphic ug, TextBlock full) {
+ super.drawWhenSwimlanes(ug, full);
+ double x2 = 0;
+
+ final StringBounder stringBounder = ug.getStringBounder();
+ for (Swimlane swimlane : swimlanes) {
+ final TextBlock swTitle = getTitle(swimlane);
+ final double titleWidth = swTitle.calculateDimension(stringBounder).getWidth();
+ final double posTitle = x2 + (swimlane.getActualWidth() - titleWidth) / 2;
+ swTitle.drawU(ug.apply(new UTranslate(posTitle, 0)));
+ x2 += swimlane.getActualWidth();
+ }
+ }
+
+ private TextBlock getTitle(Swimlane swimlane) {
+ final FontConfiguration fontConfiguration = new FontConfiguration(skinParam, FontParam.SWIMLANE_TITLE, null);
+
+ LineBreakStrategy wrap = getWrap();
+ if (wrap.isAuto()) {
+ wrap = new LineBreakStrategy("" + ((int) swimlane.getActualWidth()));
+ }
+
+ return swimlane.getDisplay().create(fontConfiguration, HorizontalAlignment.LEFT, skinParam, wrap);
+ }
+
+ private LineBreakStrategy getWrap() {
+ LineBreakStrategy wrap = skinParam.swimlaneWrapTitleWidth();
+ if (wrap == LineBreakStrategy.NONE) {
+ wrap = skinParam.wrapWidth();
+ }
+ return wrap;
+ }
+
+ @Override
+ protected double swimlaneActualWidth(StringBounder stringBounder, double swimlaneWidth, Swimlane swimlane) {
+ final double m1 = super.swimlaneActualWidth(stringBounder, swimlaneWidth, swimlane);
+ if (getWrap().isAuto()) {
+ return m1;
+ }
+
+ final double titleWidth = getTitle(swimlane).calculateDimension(stringBounder).getWidth();
+ return MathUtils.max(m1, titleWidth + 2 * separationMargin);
+
+ }
+
+ @Override
+ protected UTranslate getTitleHeightTranslate(final StringBounder stringBounder) {
+ double titlesHeight = 0;
+ for (Swimlane swimlane : swimlanes) {
+ final TextBlock swTitle = getTitle(swimlane);
+ titlesHeight = Math.max(titlesHeight, swTitle.calculateDimension(stringBounder).getHeight());
+ }
+ return new UTranslate(0, titlesHeight);
+ }
+
+}
diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/SwimlanesC.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/SwimlanesC.java
new file mode 100644
index 000000000..1184b410d
--- /dev/null
+++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/SwimlanesC.java
@@ -0,0 +1,89 @@
+/* ========================================================================
+ * PlantUML : a free UML diagram generator
+ * ========================================================================
+ *
+ * (C) Copyright 2009-2017, Arnaud Roques
+ *
+ * Project Info: http://plantuml.com
+ *
+ * If you like this project or if you find it useful, you can support us at:
+ *
+ * http://plantuml.com/patreon (only 1$ per month!)
+ * http://plantuml.com/paypal
+ *
+ * This file is part of PlantUML.
+ *
+ * PlantUML is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PlantUML distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ *
+ *
+ * Original Author: Arnaud Roques
+ *
+ *
+ */
+package net.sourceforge.plantuml.activitydiagram3.ftile;
+
+import java.awt.geom.Dimension2D;
+
+import net.sourceforge.plantuml.ColorParam;
+import net.sourceforge.plantuml.ISkinParam;
+import net.sourceforge.plantuml.LineParam;
+import net.sourceforge.plantuml.Pragma;
+import net.sourceforge.plantuml.graphic.HtmlColor;
+import net.sourceforge.plantuml.graphic.StringBounder;
+import net.sourceforge.plantuml.graphic.TextBlock;
+import net.sourceforge.plantuml.skin.rose.Rose;
+import net.sourceforge.plantuml.ugraphic.UChangeColor;
+import net.sourceforge.plantuml.ugraphic.UGraphic;
+import net.sourceforge.plantuml.ugraphic.ULine;
+import net.sourceforge.plantuml.ugraphic.UStroke;
+import net.sourceforge.plantuml.ugraphic.UTranslate;
+
+public class SwimlanesC extends SwimlanesB {
+
+ public SwimlanesC(ISkinParam skinParam, Pragma pragma) {
+ super(skinParam, pragma);
+ }
+
+ @Override
+ protected void drawWhenSwimlanes(UGraphic ug, TextBlock full) {
+ super.drawWhenSwimlanes(ug, full);
+ double x2 = 0;
+
+ final StringBounder stringBounder = ug.getStringBounder();
+ final Dimension2D dimensionFull = full.calculateDimension(stringBounder);
+
+ final UTranslate titleHeightTranslate = getTitleHeightTranslate(stringBounder);
+
+ for (Swimlane swimlane : swimlanes) {
+ drawSeparation(ug.apply(new UTranslate(x2, 0)), dimensionFull.getHeight() + titleHeightTranslate.getDy());
+
+ x2 += swimlane.getActualWidth();
+
+ }
+ drawSeparation(ug.apply(new UTranslate(x2, 0)), dimensionFull.getHeight() + titleHeightTranslate.getDy());
+
+ }
+
+ private void drawSeparation(UGraphic ug, double height) {
+ HtmlColor color = skinParam.getHtmlColor(ColorParam.swimlaneBorder, null, false);
+ if (color == null) {
+ color = ColorParam.swimlaneBorder.getDefaultValue();
+ }
+ final UStroke thickness = Rose.getStroke(skinParam, LineParam.swimlaneBorder, 2);
+ ug.apply(thickness).apply(new UChangeColor(color)).draw(new ULine(0, height));
+ }
+
+}
diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileGroup.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileGroup.java
index d249d56f8..c566a342e 100644
--- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileGroup.java
+++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileGroup.java
@@ -38,7 +38,7 @@ package net.sourceforge.plantuml.activitydiagram3.ftile.vcompact;
import java.awt.geom.Dimension2D;
import java.util.Set;
-import net.sourceforge.plantuml.AlignParam;
+import net.sourceforge.plantuml.AlignmentParam;
import net.sourceforge.plantuml.FontParam;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.LineParam;
@@ -196,7 +196,7 @@ public class FtileGroup extends AbstractFtile {
final SymbolContext symbolContext = new SymbolContext(backColor, borderColor).withShadow(
skinParam().shadowing()).withStroke(stroke);
- USymbol.FRAME.asBig(name, inner.skinParam().getHorizontalAlignment(AlignParam.PACKAGE_TITLE_ALIGNMENT, null),
+ USymbol.FRAME.asBig(name, inner.skinParam().getHorizontalAlignment(AlignmentParam.packageTitleAlignment, null),
TextBlockUtils.empty(0, 0), dimTotal.getWidth(), dimTotal.getHeight(), symbolContext).drawU(ug);
final Dimension2D dimHeaderNote = headerNote.calculateDimension(stringBounder);
diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileWhile.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileWhile.java
index 93f59ec48..85c17364e 100644
--- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileWhile.java
+++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vcompact/FtileWhile.java
@@ -250,7 +250,6 @@ class FtileWhile extends AbstractFtile {
final double x1 = p1.getX();
final double y1 = p1.getY();
final double x2 = p2.getX() + dimDiamond1.getWidth();
- // final double y2 = p2.getY() + dimDiamond1.getOutY() / 2;
final double half = (dimDiamond1.getOutY() - dimDiamond1.getInY()) / 2;
final double y2 = p2.getY() + dimDiamond1.getInY() + half;
@@ -268,8 +267,6 @@ class FtileWhile extends AbstractFtile {
ug.apply(new UTranslate(x1, y1bis)).draw(new UEmpty(5, Diamond.diamondHalfSize));
- // ug = ug.apply(new UChangeColor(endInlinkColor)).apply(new UChangeBackColor(endInlinkColor));
- // ug.apply(new UTranslate(xx, (y1 + y2) / 2)).draw(Arrows.asToUp());
}
public void drawTranslate(UGraphic ug, UTranslate translate1, UTranslate translate2) {
@@ -281,12 +278,13 @@ class FtileWhile extends AbstractFtile {
final Point2D p1 = translate1.getTranslated(ap1);
final Point2D p2 = translate2.getTranslated(ap2);
- final Dimension2D dimDiamond1 = diamond1.calculateDimension(stringBounder);
+ final FtileGeometry dimDiamond1 = diamond1.calculateDimension(stringBounder);
final double x1 = p1.getX();
final double y1 = p1.getY();
final double x2 = p2.getX() + dimDiamond1.getWidth();
- final double y2 = p2.getY() + dimDiamond1.getHeight() / 2;
+ final double half = (dimDiamond1.getOutY() - dimDiamond1.getInY()) / 2;
+ final double y2 = p2.getY() + dimDiamond1.getInY() + half;
snake.addPoint(x1, y1);
snake.addPoint(x1, y1 + Diamond.diamondHalfSize);
@@ -402,8 +400,6 @@ class FtileWhile extends AbstractFtile {
snake.goUnmergeable(MergeStrategy.LIMITED);
ug.draw(snake);
- // ug = ug.apply(new UChangeColor(afterEndwhileColor)).apply(new UChangeBackColor(afterEndwhileColor));
- // ug.apply(new UTranslate(Diamond.diamondHalfSize, (y1 + y2) / 2)).draw(Arrows.asToDown());
final Snake snake2 = new Snake(arrowHorizontalAlignment(), afterEndwhileColor);
snake2.addPoint(Diamond.diamondHalfSize, y2);
diff --git a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vertical/FtileBox.java b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vertical/FtileBox.java
index ff6970448..d7868eb86 100644
--- a/src/net/sourceforge/plantuml/activitydiagram3/ftile/vertical/FtileBox.java
+++ b/src/net/sourceforge/plantuml/activitydiagram3/ftile/vertical/FtileBox.java
@@ -125,7 +125,7 @@ public class FtileBox extends AbstractFtile {
final FontConfiguration fc = new FontConfiguration(skinParam, FontParam.ACTIVITY, null);
final Sheet sheet = new CreoleParser(fc, skinParam.getDefaultTextAlignment(HorizontalAlignment.LEFT),
skinParam, CreoleMode.FULL).createSheet(label);
- this.tb = new SheetBlock2(new SheetBlock1(sheet, LineBreakStrategy.NONE, skinParam.getPadding()), new MyStencil(), new UStroke(1));
+ this.tb = new SheetBlock2(new SheetBlock1(sheet, skinParam.wrapWidth(), skinParam.getPadding()), new MyStencil(), new UStroke(1));
this.print = label.toString();
}
diff --git a/src/net/sourceforge/plantuml/graphic/TextBlockCompressed2.java b/src/net/sourceforge/plantuml/code/ArobaseStringCompressor2.java
similarity index 55%
rename from src/net/sourceforge/plantuml/graphic/TextBlockCompressed2.java
rename to src/net/sourceforge/plantuml/code/ArobaseStringCompressor2.java
index 2a8e7a4d6..3433de76d 100644
--- a/src/net/sourceforge/plantuml/graphic/TextBlockCompressed2.java
+++ b/src/net/sourceforge/plantuml/code/ArobaseStringCompressor2.java
@@ -30,34 +30,33 @@
*
*
* Original Author: Arnaud Roques
- *
+ *
*
*/
-package net.sourceforge.plantuml.graphic;
+package net.sourceforge.plantuml.code;
-import java.awt.geom.Dimension2D;
+import java.io.IOException;
-import net.sourceforge.plantuml.Dimension2DDouble;
-import net.sourceforge.plantuml.ugraphic.CompressionTransform;
-import net.sourceforge.plantuml.ugraphic.UGraphic;
-import net.sourceforge.plantuml.ugraphic.UGraphicCompress2;
+import net.sourceforge.plantuml.StringUtils;
-public class TextBlockCompressed2 extends AbstractTextBlock implements TextBlock {
+public class ArobaseStringCompressor2 implements StringCompressor {
- private final TextBlock textBlock;
- private final CompressionTransform compressionTransform;
-
- public TextBlockCompressed2(TextBlock textBlock, CompressionTransform compressionTransform) {
- this.textBlock = textBlock;
- this.compressionTransform = compressionTransform;
+ public String compress(String data) throws IOException {
+ return clean2(data);
}
- public void drawU(final UGraphic ug) {
- textBlock.drawU(new UGraphicCompress2(ug, compressionTransform));
+ public String decompress(String s) throws IOException {
+ return clean2(s);
}
- public Dimension2D calculateDimension(StringBounder stringBounder) {
- final Dimension2D dim = textBlock.calculateDimension(stringBounder);
- return new Dimension2DDouble(compressionTransform.transform(dim.getWidth()), dim.getHeight());
+ private String clean2(String s) {
+ s = s.replace("\0", "");
+ s = StringUtils.trin(s);
+ s = s.replace("\r", "").replaceAll("\n+$", "");
+ if (s.startsWith("@start")) {
+ return s;
+ }
+ return "@startuml\n" + s + "\n@enduml";
}
+
}
\ No newline at end of file
diff --git a/src/net/sourceforge/plantuml/code/TranscoderSmart2.java b/src/net/sourceforge/plantuml/code/TranscoderSmart2.java
new file mode 100644
index 000000000..cbdec7e2a
--- /dev/null
+++ b/src/net/sourceforge/plantuml/code/TranscoderSmart2.java
@@ -0,0 +1,109 @@
+/* ========================================================================
+ * PlantUML : a free UML diagram generator
+ * ========================================================================
+ *
+ * (C) Copyright 2009-2017, Arnaud Roques
+ *
+ * Project Info: http://plantuml.com
+ *
+ * If you like this project or if you find it useful, you can support us at:
+ *
+ * http://plantuml.com/patreon (only 1$ per month!)
+ * http://plantuml.com/paypal
+ *
+ * This file is part of PlantUML.
+ *
+ * PlantUML is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PlantUML distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ *
+ *
+ * Original Author: Arnaud Roques
+ *
+ *
+ */
+package net.sourceforge.plantuml.code;
+
+import java.io.IOException;
+
+public class TranscoderSmart2 implements Transcoder {
+
+ // Legacy encoder
+ private final Transcoder oldOne = new TranscoderImpl(new AsciiEncoder(), new ArobaseStringCompressor2(),
+ new CompressionHuffman());
+ private final Transcoder zlib = new TranscoderImpl(new AsciiEncoder(), new ArobaseStringCompressor2(),
+ new CompressionZlib());
+ private final Transcoder brotli = new TranscoderImpl(new AsciiEncoder(), new ArobaseStringCompressor2(),
+ new CompressionBrotli());
+
+
+ private final Transcoder zlibBase64 = new TranscoderImpl(new AsciiEncoderBase64(), new ArobaseStringCompressor2(),
+ new CompressionZlib());
+ private final Transcoder brotliBase64 = new TranscoderImpl(new AsciiEncoderBase64(), new ArobaseStringCompressor2(),
+ new CompressionBrotli());
+ private final Transcoder base64only = new TranscoderImpl(new AsciiEncoderBase64(), new ArobaseStringCompressor2(),
+ new CompressionNone());
+ private final Transcoder hexOnly = new TranscoderImpl(new AsciiEncoderHex(), new ArobaseStringCompressor2(),
+ new CompressionNone());
+
+ public String decode(String code) throws IOException {
+ // Work in progress
+ // See https://github.com/plantuml/plantuml/issues/117
+
+ // Two char headers
+ if (code.startsWith("0A")) {
+ return zlibBase64.decode(code.substring(2));
+ }
+ if (code.startsWith("0B")) {
+ return brotliBase64.decode(code.substring(2));
+ }
+ if (code.startsWith("0C")) {
+ return base64only.decode(code.substring(2));
+ }
+ if (code.startsWith("0D")) {
+ return hexOnly.decode(code.substring(2));
+ }
+ // Text prefix
+ // Just a wild try: use them only for testing
+ if (code.startsWith("-deflate-")) {
+ return zlibBase64.decode(code.substring("-deflate-".length()));
+ }
+ if (code.startsWith("-brotli-")) {
+ return brotliBase64.decode(code.substring("-brotli-".length()));
+ }
+ if (code.startsWith("-base64-")) {
+ return base64only.decode(code.substring("-base64-".length()));
+ }
+ if (code.startsWith("-hex-")) {
+ return hexOnly.decode(code.substring("-hex-".length()));
+ }
+
+ // Legacy decoding : you should not use it any more.
+ if (code.startsWith("0")) {
+ return brotli.decode(code.substring(1));
+ }
+ try {
+ return zlib.decode(code);
+ } catch (Exception ex) {
+ return oldOne.decode(code);
+ }
+ // return zlib.decode(code);
+ }
+
+ public String encode(String text) throws IOException {
+ // Right now, we still use the legacy encoding.
+ // This will be changed in the incoming months
+ return zlib.encode(text);
+ }
+}
diff --git a/src/net/sourceforge/plantuml/code/TranscoderUtil.java b/src/net/sourceforge/plantuml/code/TranscoderUtil.java
index 21734bf99..0c0402215 100644
--- a/src/net/sourceforge/plantuml/code/TranscoderUtil.java
+++ b/src/net/sourceforge/plantuml/code/TranscoderUtil.java
@@ -41,4 +41,8 @@ public class TranscoderUtil {
return new TranscoderSmart();
}
+ public static Transcoder getDefaultTranscoder2() {
+ return new TranscoderSmart2();
+ }
+
}
diff --git a/src/net/sourceforge/plantuml/command/regex/Matcher2.java b/src/net/sourceforge/plantuml/command/regex/Matcher2.java
index 736802097..742e2b64b 100644
--- a/src/net/sourceforge/plantuml/command/regex/Matcher2.java
+++ b/src/net/sourceforge/plantuml/command/regex/Matcher2.java
@@ -40,6 +40,8 @@ import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import net.sourceforge.plantuml.Log;
+
public class Matcher2 {
private final static boolean INSTRUMENT = false;
@@ -80,6 +82,7 @@ public class Matcher2 {
}
private static final Map durations = new HashMap();
+ private static long printed;
private static synchronized void addTime(String id, long duration) {
Long total = durations.get(id);
@@ -88,12 +91,29 @@ public class Matcher2 {
}
total += duration;
durations.put(id, total);
- if (total > 200) {
- System.err.println("foo " + total + " " + id);
+ final String longest = getLongest();
+ if (longest == null) {
+ return;
+ }
+ if (durations.get(longest) > printed) {
+ Log.info("---------- Regex " + longest + " " + durations.get(longest) + "ms (" + durations.size() + ")");
+ printed = durations.get(longest);
}
}
+ private static String getLongest() {
+ long max = 0;
+ String result = null;
+ for (Map.Entry ent : durations.entrySet()) {
+ if (ent.getValue() > max) {
+ max = ent.getValue();
+ result = ent.getKey();
+ }
+ }
+ return result;
+ }
+
public String group(int n) {
final long now = System.currentTimeMillis();
try {
diff --git a/src/net/sourceforge/plantuml/creole/AtomText.java b/src/net/sourceforge/plantuml/creole/AtomText.java
index 32a7e7c20..47d51ec92 100644
--- a/src/net/sourceforge/plantuml/creole/AtomText.java
+++ b/src/net/sourceforge/plantuml/creole/AtomText.java
@@ -291,7 +291,7 @@ public class AtomText implements Atom {
}
public List getSplitted(StringBounder stringBounder, LineBreakStrategy maxWidthAsString) {
- final double maxWidth = maxWidthAsString.getMathWidth();
+ final double maxWidth = maxWidthAsString.getMaxWidth();
final List result = new ArrayList();
final StringTokenizer st = new StringTokenizer(text, " ", true);
final StringBuilder currentLine = new StringBuilder();
diff --git a/src/net/sourceforge/plantuml/creole/Fission.java b/src/net/sourceforge/plantuml/creole/Fission.java
index 0cdf3d41e..bfb84a055 100644
--- a/src/net/sourceforge/plantuml/creole/Fission.java
+++ b/src/net/sourceforge/plantuml/creole/Fission.java
@@ -58,7 +58,7 @@ public class Fission {
}
public List getSplitted(StringBounder stringBounder) {
- final double valueMaxWidth = maxWidth.getMathWidth();
+ final double valueMaxWidth = maxWidth.getMaxWidth();
if (valueMaxWidth == 0) {
return Arrays.asList(stripe);
}
diff --git a/src/net/sourceforge/plantuml/cucadiagram/BodyEnhanced.java b/src/net/sourceforge/plantuml/cucadiagram/BodyEnhanced.java
index 8258c70ce..8fb8b2bab 100644
--- a/src/net/sourceforge/plantuml/cucadiagram/BodyEnhanced.java
+++ b/src/net/sourceforge/plantuml/cucadiagram/BodyEnhanced.java
@@ -146,7 +146,7 @@ public class BodyEnhanced extends AbstractTextBlock implements TextBlock, WithPo
char separator = lineFirst ? '_' : 0;
TextBlock title = null;
List members = new ArrayList();
- final LineBreakStrategy lineBreakStrategy = skinParam.wrapWidth();
+ // final LineBreakStrategy lineBreakStrategy = skinParam.wrapWidth();
for (ListIterator it = rawBody.listIterator(); it.hasNext();) {
final String s = it.next();
if (manageHorizontalLine && isBlockSeparator(s)) {
diff --git a/src/net/sourceforge/plantuml/cucadiagram/Display.java b/src/net/sourceforge/plantuml/cucadiagram/Display.java
index 018a5fc51..4e6e16965 100644
--- a/src/net/sourceforge/plantuml/cucadiagram/Display.java
+++ b/src/net/sourceforge/plantuml/cucadiagram/Display.java
@@ -95,7 +95,8 @@ public class Display implements Iterable {
}
public boolean isWhite() {
- return display.size() == 0 || (display.size() == 1 && display.get(0).toString().matches("\\s*"));
+ return display == null || display.size() == 0
+ || (display.size() == 1 && display.get(0).toString().matches("\\s*"));
}
public static Display empty() {
@@ -398,8 +399,8 @@ public class Display implements Iterable {
public TextBlock create(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment,
ISkinSimple spriteContainer, CreoleMode modeSimpleLine, LineBreakStrategy maxMessageSize) {
- return create(fontConfiguration, horizontalAlignment, spriteContainer, maxMessageSize, modeSimpleLine,
- null, null);
+ return create(fontConfiguration, horizontalAlignment, spriteContainer, maxMessageSize, modeSimpleLine, null,
+ null);
}
public TextBlock create(FontConfiguration fontConfiguration, HorizontalAlignment horizontalAlignment,
diff --git a/src/net/sourceforge/plantuml/dedication/QBlock.java b/src/net/sourceforge/plantuml/dedication/QBlock.java
index 3fed0bcde..98f0c78aa 100644
--- a/src/net/sourceforge/plantuml/dedication/QBlock.java
+++ b/src/net/sourceforge/plantuml/dedication/QBlock.java
@@ -40,6 +40,8 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigInteger;
+import net.sourceforge.plantuml.version.Magic;
+
public class QBlock {
private final BigInteger big;
@@ -59,6 +61,20 @@ public class QBlock {
return new QBlock(new BigInteger(block));
}
+ public static QBlock fromMagic(Magic magic) {
+ final byte[] buffer = magic.getBuffer();
+ final byte[] block = new byte[buffer.length + 1];
+ System.arraycopy(buffer, 0, block, 1, buffer.length);
+ final BigInteger big = new BigInteger(block);
+ return new QBlock(big);
+ }
+
+ public Magic toMagic() {
+ final Magic magic = new Magic();
+ magic.set(0, getData512());
+ return magic;
+ }
+
public QBlock(BigInteger number) {
this.big = number;
}
@@ -68,13 +84,27 @@ public class QBlock {
return new QBlock(changed);
}
- public byte[] getData() {
+ private byte[] getData512() {
+ final byte[] nb = big.toByteArray();
+ if (nb.length == 512) {
+ return nb;
+ }
+ final byte[] result = new byte[512];
+ if (nb.length < 512) {
+ System.arraycopy(nb, 0, result, 512 - nb.length, nb.length);
+ } else {
+ System.arraycopy(nb, nb.length - 512, result, 0, 512);
+ }
+ return result;
+ }
+
+ public byte[] getDataRaw() {
return big.toByteArray();
}
@Override
public String toString() {
- return big.toByteArray().length + " " + big.toString();
+ return big.toByteArray().length + " " + big.toString(36);
}
public void write(OutputStream os, int size) throws IOException {
diff --git a/src/net/sourceforge/plantuml/dedication/QBlocks.java b/src/net/sourceforge/plantuml/dedication/QBlocks.java
index 6f052dc44..586c4e478 100644
--- a/src/net/sourceforge/plantuml/dedication/QBlocks.java
+++ b/src/net/sourceforge/plantuml/dedication/QBlocks.java
@@ -77,24 +77,24 @@ public class QBlocks {
}
}
- public String encodeAscii() {
- final StringBuilder sb = new StringBuilder();
- final AsciiEncoder encoder = new AsciiEncoder();
- for (QBlock rsa : all) {
- sb.append(encoder.encode(rsa.getData()));
- sb.append("!");
- }
- return sb.toString();
- }
+// public String encodeAscii() {
+// final StringBuilder sb = new StringBuilder();
+// final AsciiEncoder encoder = new AsciiEncoder();
+// for (QBlock rsa : all) {
+// sb.append(encoder.encode(rsa.getDataRaw()));
+// sb.append("!");
+// }
+// return sb.toString();
+// }
- public static QBlocks descodeAscii(String s) {
- final QBlocks result = new QBlocks();
- final AsciiEncoder encoder = new AsciiEncoder();
- for (String bl : s.split("!")) {
- final BigInteger bigInteger = new BigInteger(encoder.decode(bl));
- result.all.add(new QBlock(bigInteger));
-
- }
- return result;
- }
+// public static QBlocks descodeAscii(String s) {
+// final QBlocks result = new QBlocks();
+// final AsciiEncoder encoder = new AsciiEncoder();
+// for (String bl : s.split("!")) {
+// final BigInteger bigInteger = new BigInteger(encoder.decode(bl));
+// result.all.add(new QBlock(bigInteger));
+//
+// }
+// return result;
+// }
}
diff --git a/src/net/sourceforge/plantuml/dedication/TurningBytes.java b/src/net/sourceforge/plantuml/dedication/TurningBytes.java
index 9627c93e7..fa79642c1 100644
--- a/src/net/sourceforge/plantuml/dedication/TurningBytes.java
+++ b/src/net/sourceforge/plantuml/dedication/TurningBytes.java
@@ -35,7 +35,7 @@
*/
package net.sourceforge.plantuml.dedication;
-class TurningBytes {
+public class TurningBytes {
private final byte key[];
private int idx;
diff --git a/src/net/sourceforge/plantuml/descdiagram/command/CommandCreateElementMultilines.java b/src/net/sourceforge/plantuml/descdiagram/command/CommandCreateElementMultilines.java
index 268cb9bfc..27213b830 100644
--- a/src/net/sourceforge/plantuml/descdiagram/command/CommandCreateElementMultilines.java
+++ b/src/net/sourceforge/plantuml/descdiagram/command/CommandCreateElementMultilines.java
@@ -39,6 +39,9 @@ import java.util.List;
import net.sourceforge.plantuml.FontParam;
import net.sourceforge.plantuml.StringUtils;
+import net.sourceforge.plantuml.Url;
+import net.sourceforge.plantuml.UrlBuilder;
+import net.sourceforge.plantuml.UrlBuilder.ModeUrl;
import net.sourceforge.plantuml.classdiagram.AbstractEntityDiagram;
import net.sourceforge.plantuml.command.BlocLines;
import net.sourceforge.plantuml.command.CommandExecutionResult;
@@ -89,6 +92,8 @@ public class CommandCreateElementMultilines extends CommandMultilines2\\>)?"), //
new RegexLeaf("[%s]*"), //
+ new RegexLeaf("URL", "(" + UrlBuilder.getRegexp() + ")?"), //
+ new RegexLeaf("[%s]*"), //
ColorParser.exp1(), //
new RegexLeaf("[%s]*"), //
new RegexLeaf("DESC", "as[%s]*[%g]([^%g]*)$"));
@@ -100,6 +105,8 @@ public class CommandCreateElementMultilines extends CommandMultilines2\\>)?"), //
new RegexLeaf("[%s]*"), //
+ new RegexLeaf("URL", "(" + UrlBuilder.getRegexp() + ")?"), //
+ new RegexLeaf("[%s]*"), //
ColorParser.exp1(), //
new RegexLeaf("[%s]*"), //
new RegexLeaf("DESC", "\\[(.*)$"));
@@ -154,6 +161,14 @@ public class CommandCreateElementMultilines extends CommandMultilines2 lines, boolean emptyParentheses) {
- this.signature = new DefineSignature(key);
this.emptyParentheses = emptyParentheses;
if (lines == null) {
this.definition = null;
@@ -65,6 +64,7 @@ public class Define {
this.definition = sb.toString();
this.definitionQuoted = Matcher.quoteReplacement(definition);
}
+ this.signature = new DefineSignature(key, this.definitionQuoted);
}
@Override
@@ -78,7 +78,7 @@ public class Define {
}
if (signature.isMethod()) {
for (Variables vars : signature.getVariationVariables()) {
- line = vars.applyOn(line, signature.getFonctionName(), definitionQuoted);
+ line = vars.applyOn(line);
}
} else {
final String regex = "\\b" + signature.getKey() + "\\b" + (emptyParentheses ? "(\\(\\))?" : "");
diff --git a/src/net/sourceforge/plantuml/preproc/DefineSignature.java b/src/net/sourceforge/plantuml/preproc/DefineSignature.java
index 46235d1b1..6952810a7 100644
--- a/src/net/sourceforge/plantuml/preproc/DefineSignature.java
+++ b/src/net/sourceforge/plantuml/preproc/DefineSignature.java
@@ -43,24 +43,30 @@ import java.util.StringTokenizer;
public class DefineSignature {
private final String key;
- private final String fctName;
- private final Variables vars = new Variables();
+ private final String fonctionName;
+ private final List variables = new ArrayList();
- public DefineSignature(String key) {
+ public DefineSignature(String key, String definitionQuoted) {
this.key = key;
final StringTokenizer st = new StringTokenizer(key, "(),");
- this.fctName = st.nextToken().trim();
+ this.fonctionName = st.nextToken().trim();
+ final Variables master = new Variables(fonctionName, definitionQuoted);
while (st.hasMoreTokens()) {
final String var1 = st.nextToken().trim();
- this.vars.add(new DefineVariable(var1));
+ master.add(new DefineVariable(var1));
+ }
+
+ final int count = master.countDefaultValue();
+ for (int i = 0; i <= count; i++) {
+ variables.add(master.removeSomeDefaultValues(i));
}
}
@Override
public String toString() {
- return key + "/" + fctName + "/" + vars;
+ return key + "/" + fonctionName;
}
public boolean isMethod() {
@@ -72,16 +78,7 @@ public class DefineSignature {
}
public List getVariationVariables() {
- final List result = new ArrayList();
- final int count = vars.countDefaultValue();
- for (int i = 0; i <= count; i++) {
- result.add(vars.removeSomeDefaultValues(i));
- }
- return Collections.unmodifiableList(result);
- }
-
- public String getFonctionName() {
- return fctName;
+ return Collections.unmodifiableList(variables);
}
}
diff --git a/src/net/sourceforge/plantuml/preproc/IfManager.java b/src/net/sourceforge/plantuml/preproc/IfManager.java
index 85f9b1f58..dd38d199e 100644
--- a/src/net/sourceforge/plantuml/preproc/IfManager.java
+++ b/src/net/sourceforge/plantuml/preproc/IfManager.java
@@ -43,7 +43,7 @@ import net.sourceforge.plantuml.command.regex.MyPattern;
import net.sourceforge.plantuml.command.regex.Pattern2;
import net.sourceforge.plantuml.version.Version;
-class IfManager implements ReadLine {
+class IfManager extends ReadLineInstrumented implements ReadLine {
protected static final Pattern2 ifdefPattern = MyPattern.cmpile("^[%s]*!if(n)?def[%s]+(.+)$");
protected static final Pattern2 ifcomparePattern = MyPattern
@@ -61,7 +61,8 @@ class IfManager implements ReadLine {
this.source = source;
}
- final public CharSequence2 readLine() throws IOException {
+ @Override
+ final CharSequence2 readLineInst() throws IOException {
if (child != null) {
final CharSequence2 s = child.readLine();
if (s != null) {
@@ -117,7 +118,8 @@ class IfManager implements ReadLine {
return 0;
}
- public void close() throws IOException {
+ @Override
+ void closeInst() throws IOException {
source.close();
}
diff --git a/src/net/sourceforge/plantuml/preproc/Preprocessor.java b/src/net/sourceforge/plantuml/preproc/Preprocessor.java
index fde02325f..1a2e242d2 100644
--- a/src/net/sourceforge/plantuml/preproc/Preprocessor.java
+++ b/src/net/sourceforge/plantuml/preproc/Preprocessor.java
@@ -37,192 +37,62 @@ package net.sourceforge.plantuml.preproc;
import java.io.File;
import java.io.IOException;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import net.sourceforge.plantuml.CharSequence2;
-import net.sourceforge.plantuml.CharSequence2Impl;
import net.sourceforge.plantuml.DefinitionsContainer;
-import net.sourceforge.plantuml.StringUtils;
-import net.sourceforge.plantuml.command.regex.Matcher2;
-import net.sourceforge.plantuml.command.regex.MyPattern;
-import net.sourceforge.plantuml.command.regex.Pattern2;
-import net.sourceforge.plantuml.utils.StartUtils;
+import net.sourceforge.plantuml.Log;
-public class Preprocessor implements ReadLine {
+public class Preprocessor extends ReadLineInstrumented implements ReadLine {
- private static final String END_DEFINE_LONG = "!enddefinelong";
- private static final String ID = "[A-Za-z_][A-Za-z_0-9]*";
- private static final String ID_ARG = "\\s*[A-Za-z_][A-Za-z_0-9]*\\s*(?:=\\s*(?:\"[^\"]*\"|'[^']*')\\s*)?";
- private static final String ARG = "(?:\\(" + ID_ARG + "(?:," + ID_ARG + ")*?\\))?";
- private static final Pattern2 definePattern = MyPattern.cmpile("^[%s]*!define[%s]+(" + ID + ARG + ")"
- + "(?:[%s]+(.*))?$");
- private static final Pattern2 filenamePattern = MyPattern.cmpile("^[%s]*!filename[%s]+(.+)$");
- private static final Pattern2 undefPattern = MyPattern.cmpile("^[%s]*!undef[%s]+(" + ID + ")$");
- private static final Pattern2 definelongPattern = MyPattern.cmpile("^[%s]*!definelong[%s]+(" + ID + ARG + ")");
- private static final Pattern2 enddefinelongPattern = MyPattern.cmpile("^[%s]*" + END_DEFINE_LONG + "[%s]*$");
-
- private final Defines defines;
- private final PreprocessorInclude rawSource;
- private final ReadLineInsertable source;
+ private final PreprocessorInclude include;
private final SubPreprocessor subPreprocessor;
+ private final String description;
public Sub getSub(String blocname) {
return subPreprocessor.getSub(blocname);
}
+ // public Preprocessor(List config, ReadLine reader, String charset, Defines defines, File newCurrentDir,
+ // DefinitionsContainer definitionsContainer) {
+ //
+ // final ReadLine source2 = new IfManager(reader, defines);
+ // final ReadLineInsertable source3 = new ReadLineInsertable(source2);
+ // final ReadLine source4 = new PreprocessorDefine(defines, source3);
+ // this.include = new PreprocessorInclude(config, source4, defines, charset, newCurrentDir, definitionsContainer);
+ // this.subPreprocessor = new SubPreprocessor(config, charset, defines, definitionsContainer, include);
+ // }
+
public Preprocessor(List config, ReadLine reader, String charset, Defines defines, File newCurrentDir,
DefinitionsContainer definitionsContainer) {
- this.defines = defines;
- this.defines.saveState();
- this.rawSource = new PreprocessorInclude(config, reader, defines, charset, newCurrentDir, definitionsContainer);
- this.source = new ReadLineInsertable(new IfManager(rawSource, defines));
- this.subPreprocessor = new SubPreprocessor(config, charset, defines, definitionsContainer, new ReadLine() {
-
- public void close() throws IOException {
- Preprocessor.this.close();
- }
-
- public CharSequence2 readLine() throws IOException {
- return readLineInternal();
- }
- });
+ this.description = reader.toString();
+ this.include = new PreprocessorInclude(config, reader, defines, charset, newCurrentDir, definitionsContainer);
+ final ReadLine source2 = new IfManager(include, defines);
+ final ReadLineInsertable source3 = new ReadLineInsertable(source2);
+ final ReadLine source4 = new PreprocessorDefine(defines, source3);
+ this.subPreprocessor = new SubPreprocessor(config, charset, defines, definitionsContainer, source4);
}
- public CharSequence2 readLine() throws IOException {
+ @Override
+ CharSequence2 readLineInst() throws IOException {
return subPreprocessor.readLine();
}
- private CharSequence2 readLineInternal() throws IOException {
- final CharSequence2 s = source.readLine();
- if (s == null) {
- return null;
- }
- if (StartUtils.isArobaseStartDiagram(s)) {
- this.defines.restoreState();
- }
-
- Matcher2 m = filenamePattern.matcher(s);
- if (m.find()) {
- return manageFilename(m);
- }
- m = definePattern.matcher(s);
- if (m.find()) {
- return manageDefine(m, s.toString().trim().endsWith("()"));
- }
-
- m = definelongPattern.matcher(s);
- if (m.find()) {
- return manageDefineLong(m, s.toString().trim().endsWith("()"));
- }
-
- m = undefPattern.matcher(s);
- if (m.find()) {
- return manageUndef(m);
- }
-
- if (ignoreDefineDuringSeveralLines > 0) {
- ignoreDefineDuringSeveralLines--;
- return s;
- }
-
- List result = defines.applyDefines(s.toString2());
- if (result.size() > 1) {
- result = cleanEndDefineLong(result);
- final List inserted = cleanEndDefineLong(result.subList(1, result.size()));
- ignoreDefineDuringSeveralLines = inserted.size();
- source.insert(inserted, s.getLocation());
- }
- return new CharSequence2Impl(result.get(0), s.getLocation(), s.getPreprocessorError());
- }
-
- private List cleanEndDefineLong(List data) {
- final List result = new ArrayList();
- for (String s : data) {
- final String clean = cleanEndDefineLong(s);
- if (clean != null) {
- result.add(clean);
- }
- }
- return result;
-
- }
-
- private String cleanEndDefineLong(String s) {
- if (s.trim().startsWith(END_DEFINE_LONG)) {
- s = s.trim().substring(END_DEFINE_LONG.length());
- if (s.length() == 0) {
- return null;
- }
- }
- return s;
- }
-
- private int ignoreDefineDuringSeveralLines = 0;
-
- private CharSequence2 manageUndef(Matcher2 m) throws IOException {
- defines.undefine(m.group(1));
- return this.readLine();
- }
-
- private CharSequence2 manageDefineLong(Matcher2 m, boolean emptyParentheses) throws IOException {
- final String group1 = m.group(1);
- final List def = new ArrayList();
- while (true) {
- final CharSequence2 read = this.readLine();
- if (read == null) {
- return null;
- }
- if (enddefinelongPattern.matcher(read).find()) {
- defines.define(group1, def, emptyParentheses);
- return this.readLine();
- }
- def.add(read.toString2());
- }
- }
-
- private CharSequence2 manageFilename(Matcher2 m) throws IOException {
- final String group1 = m.group(1);
- this.defines.overrideFilename(group1);
- return this.readLine();
- }
-
- private CharSequence2 manageDefine(Matcher2 m, boolean emptyParentheses) throws IOException {
- final String group1 = m.group(1);
- final String group2 = m.group(2);
- if (group2 == null) {
- defines.define(group1, null, emptyParentheses);
- } else {
- final List strings = defines.applyDefines(group2);
- if (strings.size() > 1) {
- defines.define(group1, strings, emptyParentheses);
- } else {
- final StringBuilder value = new StringBuilder(strings.get(0));
- while (StringUtils.endsWithBackslash(value.toString())) {
- value.setLength(value.length() - 1);
- final CharSequence2 read = this.readLine();
- value.append(read.toString2());
- }
- final List li = new ArrayList();
- li.add(value.toString());
- defines.define(group1, li, emptyParentheses);
- }
- }
- return this.readLine();
- }
-
public int getLineNumber() {
- return rawSource.getLineNumber();
+ return include.getLineNumber();
}
- public void close() throws IOException {
- rawSource.close();
+ @Override
+ void closeInst() throws IOException {
+ // Log.info("Closing preprocessor of " + description);
+ include.close();
+ subPreprocessor.close();
}
public Set getFilesUsed() {
- return Collections.unmodifiableSet(rawSource.getFilesUsedGlobal());
+ return Collections.unmodifiableSet(include.getFilesUsedGlobal());
}
}
\ No newline at end of file
diff --git a/src/net/sourceforge/plantuml/preproc/PreprocessorDefine.java b/src/net/sourceforge/plantuml/preproc/PreprocessorDefine.java
new file mode 100644
index 000000000..13de98495
--- /dev/null
+++ b/src/net/sourceforge/plantuml/preproc/PreprocessorDefine.java
@@ -0,0 +1,201 @@
+/* ========================================================================
+ * PlantUML : a free UML diagram generator
+ * ========================================================================
+ *
+ * (C) Copyright 2009-2017, Arnaud Roques
+ *
+ * Project Info: http://plantuml.com
+ *
+ * If you like this project or if you find it useful, you can support us at:
+ *
+ * http://plantuml.com/patreon (only 1$ per month!)
+ * http://plantuml.com/paypal
+ *
+ * This file is part of PlantUML.
+ *
+ * PlantUML is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PlantUML distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ *
+ *
+ * Original Author: Arnaud Roques
+ *
+ *
+ */
+package net.sourceforge.plantuml.preproc;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import net.sourceforge.plantuml.CharSequence2;
+import net.sourceforge.plantuml.CharSequence2Impl;
+import net.sourceforge.plantuml.StringUtils;
+import net.sourceforge.plantuml.command.regex.Matcher2;
+import net.sourceforge.plantuml.command.regex.MyPattern;
+import net.sourceforge.plantuml.command.regex.Pattern2;
+import net.sourceforge.plantuml.utils.StartUtils;
+
+public class PreprocessorDefine extends ReadLineInstrumented implements ReadLine {
+
+ private static final String END_DEFINE_LONG = "!enddefinelong";
+ private static final String ID = "[A-Za-z_][A-Za-z_0-9]*";
+ private static final String ID_ARG = "\\s*[A-Za-z_][A-Za-z_0-9]*\\s*(?:=\\s*(?:\"[^\"]*\"|'[^']*')\\s*)?";
+ private static final String ARG = "(?:\\(" + ID_ARG + "(?:," + ID_ARG + ")*?\\))?";
+ private static final Pattern2 definePattern = MyPattern.cmpile("^[%s]*!define[%s]+(" + ID + ARG + ")"
+ + "(?:[%s]+(.*))?$");
+ private static final Pattern2 filenamePattern = MyPattern.cmpile("^[%s]*!filename[%s]+(.+)$");
+ private static final Pattern2 undefPattern = MyPattern.cmpile("^[%s]*!undef[%s]+(" + ID + ")$");
+ private static final Pattern2 definelongPattern = MyPattern.cmpile("^[%s]*!definelong[%s]+(" + ID + ARG + ")");
+ private static final Pattern2 enddefinelongPattern = MyPattern.cmpile("^[%s]*" + END_DEFINE_LONG + "[%s]*$");
+
+ private final Defines defines;
+
+ private final ReadLineInsertable source;
+
+ public PreprocessorDefine(Defines defines, ReadLineInsertable source) {
+ this.defines = defines;
+ this.defines.saveState();
+ this.source = source;
+ }
+
+ @Override
+ CharSequence2 readLineInst() throws IOException {
+ final CharSequence2 s = source.readLine();
+ if (s == null) {
+ return null;
+ }
+ if (StartUtils.isArobaseStartDiagram(s)) {
+ this.defines.restoreState();
+ }
+
+ Matcher2 m = filenamePattern.matcher(s);
+ if (m.find()) {
+ return manageFilename(m);
+ }
+ m = definePattern.matcher(s);
+ if (m.find()) {
+ return manageDefine(m, s.toString().trim().endsWith("()"));
+ }
+
+ m = definelongPattern.matcher(s);
+ if (m.find()) {
+ return manageDefineLong(m, s.toString().trim().endsWith("()"));
+ }
+
+ m = undefPattern.matcher(s);
+ if (m.find()) {
+ return manageUndef(m);
+ }
+
+ if (ignoreDefineDuringSeveralLines > 0) {
+ ignoreDefineDuringSeveralLines--;
+ return s;
+ }
+
+ List result = defines.applyDefines(s.toString2());
+ if (result.size() > 1) {
+ result = cleanEndDefineLong(result);
+ final List inserted = cleanEndDefineLong(result.subList(1, result.size()));
+ ignoreDefineDuringSeveralLines = inserted.size();
+ source.insert(inserted, s.getLocation());
+ }
+ return new CharSequence2Impl(result.get(0), s.getLocation(), s.getPreprocessorError());
+ }
+
+ private List cleanEndDefineLong(List data) {
+ final List result = new ArrayList();
+ for (String s : data) {
+ final String clean = cleanEndDefineLong(s);
+ if (clean != null) {
+ result.add(clean);
+ }
+ }
+ return result;
+
+ }
+
+ private String cleanEndDefineLong(String s) {
+ if (s.trim().startsWith(END_DEFINE_LONG)) {
+ s = s.trim().substring(END_DEFINE_LONG.length());
+ if (s.length() == 0) {
+ return null;
+ }
+ }
+ return s;
+ }
+
+ private int ignoreDefineDuringSeveralLines = 0;
+
+ private CharSequence2 manageUndef(Matcher2 m) throws IOException {
+ defines.undefine(m.group(1));
+ return this.readLine();
+ }
+
+ private CharSequence2 manageDefineLong(Matcher2 m, boolean emptyParentheses) throws IOException {
+ final String group1 = m.group(1);
+ final List def = new ArrayList();
+ while (true) {
+ final CharSequence2 read = this.readLine();
+ if (read == null) {
+ return null;
+ }
+ if (enddefinelongPattern.matcher(read).find()) {
+ defines.define(group1, def, emptyParentheses);
+ return this.readLine();
+ }
+ def.add(read.toString2());
+ }
+ }
+
+ private CharSequence2 manageFilename(Matcher2 m) throws IOException {
+ final String group1 = m.group(1);
+ this.defines.overrideFilename(group1);
+ return this.readLine();
+ }
+
+ private CharSequence2 manageDefine(Matcher2 m, boolean emptyParentheses) throws IOException {
+ final String group1 = m.group(1);
+ final String group2 = m.group(2);
+ if (group2 == null) {
+ defines.define(group1, null, emptyParentheses);
+ } else {
+ final List strings = defines.applyDefines(group2);
+ if (strings.size() > 1) {
+ defines.define(group1, strings, emptyParentheses);
+ } else {
+ final StringBuilder value = new StringBuilder(strings.get(0));
+ while (StringUtils.endsWithBackslash(value.toString())) {
+ value.setLength(value.length() - 1);
+ final CharSequence2 read = this.readLine();
+ value.append(read.toString2());
+ }
+ final List li = new ArrayList();
+ li.add(value.toString());
+ defines.define(group1, li, emptyParentheses);
+ }
+ }
+ return this.readLine();
+ }
+
+// public int getLineNumber() {
+// return source.getLineNumber();
+// }
+
+ @Override
+ void closeInst() throws IOException {
+ source.close();
+ }
+
+}
\ No newline at end of file
diff --git a/src/net/sourceforge/plantuml/preproc/PreprocessorInclude.java b/src/net/sourceforge/plantuml/preproc/PreprocessorInclude.java
index 7db9fa46f..bf542c716 100644
--- a/src/net/sourceforge/plantuml/preproc/PreprocessorInclude.java
+++ b/src/net/sourceforge/plantuml/preproc/PreprocessorInclude.java
@@ -63,7 +63,7 @@ import net.sourceforge.plantuml.command.regex.MyPattern;
import net.sourceforge.plantuml.command.regex.Pattern2;
import net.sourceforge.plantuml.utils.StartUtils;
-public class PreprocessorInclude implements ReadLine {
+public class PreprocessorInclude extends ReadLineInstrumented implements ReadLine {
private static final Pattern2 includeDefPattern = MyPattern.cmpile("^[%s]*!includedef[%s]+[%g]?([^%g]+)[%g]?$");
private static final Pattern2 includePattern = MyPattern.cmpile("^[%s]*!include[%s]+[%g]?([^%g]+)[%g]?$");
@@ -119,7 +119,8 @@ public class PreprocessorInclude implements ReadLine {
}
}
- public CharSequence2 readLine() throws IOException {
+ @Override
+ CharSequence2 readLineInst() throws IOException {
final CharSequence2 result = readLineInternal();
if (result != null && StartUtils.isArobaseStartDiagram(result) && config.size() > 0) {
final List empty = new ArrayList();
@@ -266,21 +267,13 @@ public class PreprocessorInclude implements ReadLine {
}
private InputStream getStdlibInputStream(String filename) {
- return Stdlib.getResourceAsStream(filename);
- }
-
- private InputStream getStdlibInputStreamOld(String filename) {
- if (filename.endsWith(".puml") == false) {
- filename = filename + ".puml";
- }
- InputStream is = PreprocessorInclude.class.getResourceAsStream("/stdlib/" + filename);
- if (is == null) {
- is = PreprocessorInclude.class.getResourceAsStream("/stdlib/" + filename.toLowerCase());
- }
- return is;
+ final InputStream result = Stdlib.getResourceAsStream(filename);
+ // Log.info("Loading sdlib " + filename + " ok");
+ return result;
}
private ReadLine getReaderStdlibInclude(CharSequence2 s, String filename) {
+ Log.info("Loading sdlib " + filename);
InputStream is = getStdlibInputStream(filename);
if (is == null) {
return null;
@@ -295,23 +288,12 @@ public class PreprocessorInclude implements ReadLine {
if (is == null) {
return null;
}
- return ReadLineReader.create(new InputStreamReader(is), filename);
+ return ReadLineReader.create(new InputStreamReader(is), description);
} catch (IOException e) {
return new ReadLineSimple(s, e.toString());
}
}
- // private ReadLine getReaderStdlibInclude2(CharSequence2 s, String filename) {
- // InputStream is = DummyEmptyStdlibFile.class.getResourceAsStream(filename);
- // if (is == null) {
- // is = DummyEmptyStdlibFile.class.getResourceAsStream(filename.toLowerCase());
- // }
- // if (is == null) {
- // return null;
- // }
- // return new ReadLineReader(new InputStreamReader(is), filename);
- // }
-
private ReadLine getReaderInclude(CharSequence2 s, final File f, String suf) {
try {
if (StartDiagramExtractReader.containsStartDiagram(s, f, charset)) {
@@ -352,7 +334,8 @@ public class PreprocessorInclude implements ReadLine {
return numLine;
}
- public void close() throws IOException {
+ @Override
+ void closeInst() throws IOException {
restoreCurrentDir();
reader2.close();
}
diff --git a/src/net/sourceforge/plantuml/preproc/ReadLineInstrumented.java b/src/net/sourceforge/plantuml/preproc/ReadLineInstrumented.java
new file mode 100644
index 000000000..b3c8d472b
--- /dev/null
+++ b/src/net/sourceforge/plantuml/preproc/ReadLineInstrumented.java
@@ -0,0 +1,98 @@
+/* ========================================================================
+ * PlantUML : a free UML diagram generator
+ * ========================================================================
+ *
+ * (C) Copyright 2009-2017, Arnaud Roques
+ *
+ * Project Info: http://plantuml.com
+ *
+ * If you like this project or if you find it useful, you can support us at:
+ *
+ * http://plantuml.com/patreon (only 1$ per month!)
+ * http://plantuml.com/paypal
+ *
+ * This file is part of PlantUML.
+ *
+ * PlantUML is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PlantUML distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ *
+ *
+ * Original Author: Arnaud Roques
+ *
+ *
+ */
+package net.sourceforge.plantuml.preproc;
+
+import java.io.IOException;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicLong;
+
+import net.sourceforge.plantuml.CharSequence2;
+import net.sourceforge.plantuml.Log;
+
+public abstract class ReadLineInstrumented implements ReadLine {
+
+ private static final boolean TRACE = false;
+
+ private static ConcurrentMap durations = new ConcurrentHashMap();
+ private static ConcurrentMap maxes = new ConcurrentHashMap();
+
+ private long current = 0;
+
+ private AtomicLong get(ConcurrentMap source) {
+ AtomicLong result = source.get(getClass());
+ if (result == null) {
+ result = new AtomicLong();
+ source.put(getClass(), result);
+ }
+ return result;
+ }
+
+ public final CharSequence2 readLine() throws IOException {
+ if (TRACE == false) {
+ return readLineInst();
+ }
+ final long now = System.currentTimeMillis();
+ try {
+ return readLineInst();
+ } finally {
+ final long time = System.currentTimeMillis() - now;
+ current += time;
+ get(durations).addAndGet(time);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return super.toString() + " current=" + current;
+ }
+
+ abstract CharSequence2 readLineInst() throws IOException;
+
+ public final void close() throws IOException {
+ if (TRACE) {
+ if (current > get(maxes).get()) {
+ get(maxes).set(current);
+ }
+ Log.info("DURATION::" + getClass() + " duration= " + get(durations).get() + " current=" + current + " max="
+ + get(maxes).get());
+ }
+ closeInst();
+ }
+
+ abstract void closeInst() throws IOException;
+
+}
\ No newline at end of file
diff --git a/src/net/sourceforge/plantuml/preproc/ReadLineQuoteComment.java b/src/net/sourceforge/plantuml/preproc/ReadLineQuoteComment.java
index 8fff8b065..60e2979f1 100644
--- a/src/net/sourceforge/plantuml/preproc/ReadLineQuoteComment.java
+++ b/src/net/sourceforge/plantuml/preproc/ReadLineQuoteComment.java
@@ -40,7 +40,7 @@ import java.io.IOException;
import net.sourceforge.plantuml.CharSequence2;
import net.sourceforge.plantuml.CharSequence2Impl;
-public class ReadLineQuoteComment implements ReadLine {
+public class ReadLineQuoteComment extends ReadLineInstrumented implements ReadLine {
private final ReadLine raw;
private boolean longComment = false;
@@ -49,11 +49,13 @@ public class ReadLineQuoteComment implements ReadLine {
this.raw = source;
}
- public void close() throws IOException {
+ @Override
+ void closeInst() throws IOException {
raw.close();
}
- public CharSequence2 readLine() throws IOException {
+ @Override
+ CharSequence2 readLineInst() throws IOException {
while (true) {
final CharSequence2 result = raw.readLine();
if (result == null) {
diff --git a/src/net/sourceforge/plantuml/preproc/ReadLineReader.java b/src/net/sourceforge/plantuml/preproc/ReadLineReader.java
index 1df3ea5fd..bb73124d0 100644
--- a/src/net/sourceforge/plantuml/preproc/ReadLineReader.java
+++ b/src/net/sourceforge/plantuml/preproc/ReadLineReader.java
@@ -43,19 +43,28 @@ import net.sourceforge.plantuml.CharSequence2;
import net.sourceforge.plantuml.CharSequence2Impl;
import net.sourceforge.plantuml.LineLocation;
import net.sourceforge.plantuml.LineLocationImpl;
+import net.sourceforge.plantuml.Log;
-public class ReadLineReader implements ReadLine {
+public class ReadLineReader extends ReadLineInstrumented implements ReadLine {
// private static final int LIMIT = 850;
private final BufferedReader br;
private LineLocationImpl location;
+ private final String description;
private ReadLineReader(Reader reader, String description, LineLocation parent) {
if (description == null) {
description = "?";
}
- br = new BufferedReader(reader);
- location = new LineLocationImpl(description, parent);
+ this.br = new BufferedReader(reader);
+ this.location = new LineLocationImpl(description, parent);
+ this.description = description;
+ Log.info("Reading from " + description);
+ }
+
+ @Override
+ public String toString() {
+ return super.toString() + " " + description;
}
private ReadLineReader(Reader reader, String desc) {
@@ -70,7 +79,8 @@ public class ReadLineReader implements ReadLine {
return new ReadLineReader(reader, description, parent);
}
- public CharSequence2 readLine() throws IOException {
+ @Override
+ CharSequence2 readLineInst() throws IOException {
String s = br.readLine();
location = location.oneLineRead();
if (s == null) {
@@ -99,7 +109,8 @@ public class ReadLineReader implements ReadLine {
return new CharSequence2Impl(s, location);
}
- public void close() throws IOException {
+ @Override
+ void closeInst() throws IOException {
br.close();
}
diff --git a/src/net/sourceforge/plantuml/preproc/Stdlib.java b/src/net/sourceforge/plantuml/preproc/Stdlib.java
index 99264779d..b29047a22 100644
--- a/src/net/sourceforge/plantuml/preproc/Stdlib.java
+++ b/src/net/sourceforge/plantuml/preproc/Stdlib.java
@@ -76,9 +76,11 @@ public class Stdlib {
if (cached != null) {
final String cachedResult = cached.get();
if (cachedResult != null) {
+ // Log.info("Using cache for " + file);
return cachedResult;
}
}
+ Log.info("No cache for " + file);
final DataInputStream dataStream = getDataStream();
if (dataStream == null) {
return null;
@@ -94,6 +96,7 @@ public class Stdlib {
while (true) {
final String filename = dataStream.readUTF();
if (filename.equals(SEPARATOR)) {
+ Log.info("Not found " + filename);
return null;
}
if (filename.equalsIgnoreCase(file)) {
@@ -121,8 +124,10 @@ public class Stdlib {
}
final int width = Integer.parseInt(m.group(1));
final int height = Integer.parseInt(m.group(2));
- final String sprite = readSprite(width, height, spriteStream);
- if (found != null) {
+ if (found == null) {
+ skipSprite(width, height, spriteStream);
+ } else {
+ final String sprite = readSprite(width, height, spriteStream);
found.append(sprite);
found.append("}\n");
}
@@ -141,9 +146,14 @@ public class Stdlib {
fillMap(info);
}
- private String readSprite(int width, int height, InputStream inputStream) throws IOException {
- final StringBuilder result = new StringBuilder();
+ private void skipSprite(int width, int height, InputStream inputStream) throws IOException {
final int nbLines = (height + 1) / 2;
+ inputStream.skip(nbLines * width);
+ }
+
+ private String readSprite(int width, int height, InputStream inputStream) throws IOException {
+ final int nbLines = (height + 1) / 2;
+ final StringBuilder result = new StringBuilder();
int line = 0;
for (int j = 0; j < nbLines; j++) {
final StringBuilder sb1 = new StringBuilder();
diff --git a/src/net/sourceforge/plantuml/preproc/SubPreprocessor.java b/src/net/sourceforge/plantuml/preproc/SubPreprocessor.java
index df9209e45..f9030f34f 100644
--- a/src/net/sourceforge/plantuml/preproc/SubPreprocessor.java
+++ b/src/net/sourceforge/plantuml/preproc/SubPreprocessor.java
@@ -52,7 +52,7 @@ import net.sourceforge.plantuml.command.regex.Matcher2;
import net.sourceforge.plantuml.command.regex.MyPattern;
import net.sourceforge.plantuml.command.regex.Pattern2;
-public class SubPreprocessor implements ReadLine {
+public class SubPreprocessor extends ReadLineInstrumented implements ReadLine {
private static final String ID = "[A-Za-z_][A-Za-z_0-9]*";
@@ -79,7 +79,8 @@ public class SubPreprocessor implements ReadLine {
this.definitionsContainer = definitionsContainer;
}
- public CharSequence2 readLine() throws IOException {
+ @Override
+ CharSequence2 readLineInst() throws IOException {
if (includedSub != null) {
final CharSequence2 s = includedSub.readLine();
if (s != null) {
@@ -176,7 +177,8 @@ public class SubPreprocessor implements ReadLine {
return result;
}
- public void close() throws IOException {
+ @Override
+ void closeInst() throws IOException {
source.close();
}
diff --git a/src/net/sourceforge/plantuml/preproc/UncommentReadLine.java b/src/net/sourceforge/plantuml/preproc/UncommentReadLine.java
index 1b03651e1..a8f1b73b5 100644
--- a/src/net/sourceforge/plantuml/preproc/UncommentReadLine.java
+++ b/src/net/sourceforge/plantuml/preproc/UncommentReadLine.java
@@ -44,21 +44,27 @@ import net.sourceforge.plantuml.command.regex.MyPattern;
import net.sourceforge.plantuml.command.regex.Pattern2;
import net.sourceforge.plantuml.utils.StartUtils;
-public class UncommentReadLine implements ReadLine {
+public class UncommentReadLine extends ReadLineInstrumented implements ReadLine {
+
+ private static final Pattern2 unpause = MyPattern.cmpile(StartUtils.PAUSE_PATTERN);
private final ReadLine raw;
- private final Pattern2 start;
- private final Pattern2 unpause;
+ // private final Pattern2 start;
private String headerToRemove;
private boolean paused;
public UncommentReadLine(ReadLine source) {
this.raw = source;
- this.start = MyPattern.cmpile(StartUtils.START_PATTERN);
- this.unpause = MyPattern.cmpile(StartUtils.PAUSE_PATTERN);
+ // this.start = MyPattern.cmpile(StartUtils.START_PATTERN);
}
- public CharSequence2 readLine() throws IOException {
+ @Override
+ public String toString() {
+ return "UncommentReadLine of " + raw;
+ }
+
+ @Override
+ CharSequence2 readLineInst() throws IOException {
final CharSequence2 result = raw.readLine();
if (result == null) {
@@ -88,7 +94,8 @@ public class UncommentReadLine implements ReadLine {
return result;
}
- public void close() throws IOException {
+ @Override
+ void closeInst() throws IOException {
this.raw.close();
}
diff --git a/src/net/sourceforge/plantuml/preproc/Variables.java b/src/net/sourceforge/plantuml/preproc/Variables.java
index d916c57cc..19442ac05 100644
--- a/src/net/sourceforge/plantuml/preproc/Variables.java
+++ b/src/net/sourceforge/plantuml/preproc/Variables.java
@@ -38,10 +38,18 @@ package net.sourceforge.plantuml.preproc;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
+import java.util.regex.Pattern;
public class Variables {
private final List all = new ArrayList();
+ private final String fonctionName;
+ private final String definitionQuoted;
+
+ public Variables(String fonctionName, String definitionQuoted) {
+ this.fonctionName = fonctionName;
+ this.definitionQuoted = definitionQuoted;
+ }
public void add(DefineVariable var) {
this.all.add(var);
@@ -61,7 +69,7 @@ public class Variables {
if (nb == 0) {
return this;
}
- final Variables result = new Variables();
+ final Variables result = new Variables(fonctionName, definitionQuoted);
for (DefineVariable v : all) {
if (v.getDefaultValue() != null && nb > 0) {
result.add(v.removeDefault());
@@ -76,36 +84,39 @@ public class Variables {
return result;
}
- public String applyOn(String line, String fonctionName, String newValue) {
- // System.err.println("KEY="+key);
- // final StringTokenizer st = new StringTokenizer(key, "(),");
- // final String fctName = st.nextToken();
- final StringBuilder regex = new StringBuilder("\\b" + fonctionName + "\\(");
+ private String newValue;
+ private Pattern regex2;
- final List variables = all;
- boolean appended = false;
- for (int j = 0; j < variables.size(); j++) {
- final DefineVariable variable = variables.get(j);
- final String varName = variable.getName();
- final String var2 = "(##" + varName + "\\b)|(\\b" + varName + "##)|(\\b" + varName + "\\b)";
- if (variable.getDefaultValue() == null) {
- regex.append("(?:(?:\\s*\"([^\"]*)\"\\s*)|(?:\\s*'([^']*)'\\s*)|\\s*" + "((?:\\([^()]*\\)|[^,'\"])*?)"
- + ")");
- final int i = 1 + 3 * j;
- newValue = newValue.replaceAll(var2, "\\$" + i + "\\$" + (i + 1) + "\\$" + (i + 2));
- regex.append(",");
- appended = true;
- } else {
- newValue = newValue.replaceAll(var2, Matcher.quoteReplacement(variable.getDefaultValue()));
+ public String applyOn(String line) {
+ if (newValue == null) {
+ newValue = definitionQuoted;
+ final StringBuilder regex = new StringBuilder("\\b" + fonctionName + "\\(");
+
+ final List variables = all;
+ boolean appended = false;
+ for (int j = 0; j < variables.size(); j++) {
+ final DefineVariable variable = variables.get(j);
+ final String varName = variable.getName();
+ final String var2 = "(##" + varName + "\\b)|(\\b" + varName + "##)|(\\b" + varName + "\\b)";
+ if (variable.getDefaultValue() == null) {
+ regex.append("(?:(?:\\s*\"([^\"]*)\"\\s*)|(?:\\s*'([^']*)'\\s*)|\\s*"
+ + "((?:\\([^()]*\\)|[^,'\"])*?)" + ")");
+ final int i = 1 + 3 * j;
+ newValue = newValue.replaceAll(var2, "\\$" + i + "\\$" + (i + 1) + "\\$" + (i + 2));
+ regex.append(",");
+ appended = true;
+ } else {
+ newValue = newValue.replaceAll(var2, Matcher.quoteReplacement(variable.getDefaultValue()));
+ }
}
+ if (appended == true) {
+ regex.setLength(regex.length() - 1);
+ }
+ regex.append("\\)");
+ regex2 = Pattern.compile(regex.toString());
}
- if (appended == true) {
- regex.setLength(regex.length() - 1);
- }
- regex.append("\\)");
- // System.err.println("regex=" + regex);
- // System.err.println("newValue=" + newValue);
- line = line.replaceAll(regex.toString(), newValue);
+ // line = line.replaceAll(regex.toString(), newValue);
+ line = regex2.matcher(line).replaceAll(newValue);
return line;
}
diff --git a/src/net/sourceforge/plantuml/project3/SubjectTask.java b/src/net/sourceforge/plantuml/project3/SubjectTask.java
index 84b565f3f..21632dfd1 100644
--- a/src/net/sourceforge/plantuml/project3/SubjectTask.java
+++ b/src/net/sourceforge/plantuml/project3/SubjectTask.java
@@ -48,7 +48,7 @@ public class SubjectTask implements SubjectPattern {
public Collection getVerbs() {
return Arrays. asList(new VerbLasts(), new VerbTaskStarts(), new VerbTaskStartsAbsolute(),
- new VerbHappens(), new VerbEnds(), new VerbIsColored());
+ new VerbHappens(), new VerbEnds(), new VerbTaskEndsAbsolute(), new VerbIsColored());
}
public IRegex toRegex() {
diff --git a/src/net/sourceforge/plantuml/project3/VerbTaskEndsAbsolute.java b/src/net/sourceforge/plantuml/project3/VerbTaskEndsAbsolute.java
new file mode 100644
index 000000000..b0f7cf466
--- /dev/null
+++ b/src/net/sourceforge/plantuml/project3/VerbTaskEndsAbsolute.java
@@ -0,0 +1,71 @@
+/* ========================================================================
+ * PlantUML : a free UML diagram generator
+ * ========================================================================
+ *
+ * (C) Copyright 2009-2017, Arnaud Roques
+ *
+ * Project Info: http://plantuml.com
+ *
+ * If you like this project or if you find it useful, you can support us at:
+ *
+ * http://plantuml.com/patreon (only 1$ per month!)
+ * http://plantuml.com/paypal
+ *
+ * This file is part of PlantUML.
+ *
+ * PlantUML is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PlantUML distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ *
+ *
+ * Original Author: Arnaud Roques
+ *
+ *
+ */
+package net.sourceforge.plantuml.project3;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import net.sourceforge.plantuml.command.CommandExecutionResult;
+import net.sourceforge.plantuml.command.regex.IRegex;
+import net.sourceforge.plantuml.command.regex.RegexLeaf;
+import net.sourceforge.plantuml.command.regex.RegexResult;
+
+public class VerbTaskEndsAbsolute implements VerbPattern {
+
+ public Collection getComplements() {
+ return Arrays. asList(new ComplementDate());
+ }
+
+ public IRegex toRegex() {
+ return new RegexLeaf("ends[%s]*(the[%s]*|on[%s]*|at[%s]*)*");
+ }
+
+ public Verb getVerb(final GanttDiagram project, RegexResult arg) {
+ return new Verb() {
+ public CommandExecutionResult execute(Subject subject, Complement complement) {
+ final Task task = (Task) subject;
+ final DayAsDate end = (DayAsDate) complement;
+ final DayAsDate startingDate = project.getStartingDate();
+ if (startingDate == null) {
+ return CommandExecutionResult.error("No starting date for the project");
+ }
+ task.setEnd(end.asInstantDay(startingDate));
+ return CommandExecutionResult.ok();
+ }
+
+ };
+ }
+}
diff --git a/src/net/sourceforge/plantuml/salt/PSystemSalt.java b/src/net/sourceforge/plantuml/salt/PSystemSalt.java
index fb8e697ad..f0ef2a5ea 100644
--- a/src/net/sourceforge/plantuml/salt/PSystemSalt.java
+++ b/src/net/sourceforge/plantuml/salt/PSystemSalt.java
@@ -47,6 +47,7 @@ import net.sourceforge.plantuml.AbstractPSystem;
import net.sourceforge.plantuml.Dimension2DDouble;
import net.sourceforge.plantuml.FileFormatOption;
import net.sourceforge.plantuml.Log;
+import net.sourceforge.plantuml.ScaleSimple;
import net.sourceforge.plantuml.UmlDiagram;
import net.sourceforge.plantuml.WithSprite;
import net.sourceforge.plantuml.api.ImageDataSimple;
@@ -108,7 +109,12 @@ public class PSystemSalt extends AbstractPSystem implements WithSprite {
final Element salt = createElement(manageSprite());
final Dimension2D size = salt.getPreferredDimension(fileFormat.getDefaultStringBounder(), 0, 0);
- final ImageBuilder builder = new ImageBuilder(new ColorMapperIdentity(), 1.0, HtmlColorUtils.WHITE, null,
+
+ double scale = 1;
+ if (getScale() != null) {
+ scale = getScale().getScale(size.getWidth(), size.getHeight());
+ }
+ final ImageBuilder builder = new ImageBuilder(new ColorMapperIdentity(), scale, HtmlColorUtils.WHITE, null,
null, 5, 5, null, false);
builder.setUDrawable(new UDrawable() {
@@ -146,6 +152,10 @@ public class PSystemSalt extends AbstractPSystem implements WithSprite {
// System.err.println("skipping " + s);
} else if (s.startsWith("skinparam ")) {
// System.err.println("skipping " + s);
+ } else if (s.startsWith("scale ")) {
+ final Double scale = Double.parseDouble(s.substring("scale ".length()));
+ this.setScale(new ScaleSimple(scale));
+ // System.err.println("skipping " + s);
} else if (s.startsWith("sprite $")) {
BlocLines bloc = BlocLines.single(s);
do {
diff --git a/src/net/sourceforge/plantuml/sequencediagram/SequenceDiagram.java b/src/net/sourceforge/plantuml/sequencediagram/SequenceDiagram.java
index b11a1ffac..94d847a61 100644
--- a/src/net/sourceforge/plantuml/sequencediagram/SequenceDiagram.java
+++ b/src/net/sourceforge/plantuml/sequencediagram/SequenceDiagram.java
@@ -280,7 +280,10 @@ public class SequenceDiagram extends UmlDiagram {
p.incInitialLife(new SymbolContext(backcolor, linecolor));
return null;
}
- return "Only activate command can occur before message are send";
+ if (p.getInitialLife() == 0) {
+ return "You cannot deactivate here";
+ }
+ return null;
}
if (lifeEventType == LifeEventType.ACTIVATE && lastEventWithDeactivate instanceof Message) {
activationState.push((Message) lastEventWithDeactivate);
diff --git a/src/net/sourceforge/plantuml/sequencediagram/graphic/SequenceDiagramTxtMaker.java b/src/net/sourceforge/plantuml/sequencediagram/graphic/SequenceDiagramTxtMaker.java
index f7ac12c9b..cc9b55c89 100644
--- a/src/net/sourceforge/plantuml/sequencediagram/graphic/SequenceDiagramTxtMaker.java
+++ b/src/net/sourceforge/plantuml/sequencediagram/graphic/SequenceDiagramTxtMaker.java
@@ -41,15 +41,19 @@ import java.io.OutputStream;
import java.io.PrintStream;
import net.sourceforge.plantuml.FileFormat;
+import net.sourceforge.plantuml.StringUtils;
import net.sourceforge.plantuml.api.ImageDataSimple;
import net.sourceforge.plantuml.asciiart.TextSkin;
import net.sourceforge.plantuml.asciiart.TextStringBounder;
+import net.sourceforge.plantuml.asciiart.UmlCharArea;
import net.sourceforge.plantuml.core.ImageData;
+import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.sequencediagram.Event;
import net.sourceforge.plantuml.sequencediagram.Participant;
import net.sourceforge.plantuml.sequencediagram.SequenceDiagram;
import net.sourceforge.plantuml.skin.Skin;
+import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.txt.UGraphicTxt;
public class SequenceDiagramTxtMaker implements FileMaker {
@@ -75,18 +79,18 @@ public class SequenceDiagramTxtMaker implements FileMaker {
}
for (Event ev : sequenceDiagram.events()) {
initializer.addEvent(ev);
-// if (ev instanceof Message) {
-// // TODO mieux faire
-// final Message m = (Message) ev;
-// for (LifeEvent lifeEvent : m.getLiveEvents()) {
-// if (lifeEvent.getType() == LifeEventType.DESTROY
-// /*
-// * || lifeEvent.getType() == LifeEventType.CREATE
-// */) {
-// initializer.addEvent(lifeEvent);
-// }
-// }
-// }
+ // if (ev instanceof Message) {
+ // // TODO mieux faire
+ // final Message m = (Message) ev;
+ // for (LifeEvent lifeEvent : m.getLiveEvents()) {
+ // if (lifeEvent.getType() == LifeEventType.DESTROY
+ // /*
+ // * || lifeEvent.getType() == LifeEventType.CREATE
+ // */) {
+ // initializer.addEvent(lifeEvent);
+ // }
+ // }
+ // }
}
drawableSet = initializer.createDrawableSet(dummyStringBounder);
// final List newpages = new ArrayList();
@@ -100,10 +104,24 @@ public class SequenceDiagramTxtMaker implements FileMaker {
final double tailHeight = drawableSet.getTailHeight(dummyStringBounder, diagram.isShowFootbox());
final double newpage2 = fullDimension.getHeight() - (diagram.isShowFootbox() ? tailHeight : 0) - headerHeight;
final Page page = new Page(headerHeight, 0, newpage2, tailHeight, 0, null);
- //drawableSet.drawU_REMOVEDME_4243(ug, 0, fullDimension.getWidth(), page, diagram.isShowFootbox());
- drawableSet.drawU22(ug, 0, fullDimension.getWidth(), page, diagram.isShowFootbox());
- }
+ // drawableSet.drawU_REMOVEDME_4243(ug, 0, fullDimension.getWidth(), page, diagram.isShowFootbox());
+ final Display title = diagram.getTitle().getDisplay();
+
+ final UGraphicTxt ug2;
+ if (title.isWhite()) {
+ ug2 = ug;
+ } else {
+ ug2 = (UGraphicTxt) ug.apply(new UTranslate(0, title.as().size() + 1));
+ }
+ drawableSet.drawU22(ug2, 0, fullDimension.getWidth(), page, diagram.isShowFootbox());
+ if (title.isWhite() == false) {
+ final int widthTitle = StringUtils.getWcWidth(title);
+ final UmlCharArea charArea = ug.getCharArea();
+ charArea.drawStringsLR(title.as(), (int) ((fullDimension.getWidth() - widthTitle) / 2), 0);
+ }
+
+ }
public ImageData createOne(OutputStream os, int index, boolean isWithMetadata) throws IOException {
if (fileFormat == FileFormat.UTXT) {
diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/LifeEventTile.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/LifeEventTile.java
index 68f18dcb2..a7428a5fb 100644
--- a/src/net/sourceforge/plantuml/sequencediagram/teoz/LifeEventTile.java
+++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/LifeEventTile.java
@@ -60,7 +60,7 @@ public class LifeEventTile implements TileWithUpdateStairs {
private final ISkinParam skinParam;
public void updateStairs(StringBounder stringBounder, double y) {
- System.err.println("LifeEventTile::updateStairs " + lifeEvent + " " + livingSpace.getParticipant() + " y=" + y);
+ // System.err.println("LifeEventTile::updateStairs " + lifeEvent + " " + livingSpace.getParticipant() + " y=" + y);
livingSpace.addStepForLivebox(getEvent(), y);
}
diff --git a/src/net/sourceforge/plantuml/sequencediagram/teoz/SequenceDiagramFileMakerTeoz.java b/src/net/sourceforge/plantuml/sequencediagram/teoz/SequenceDiagramFileMakerTeoz.java
index 67e5115ab..b3edc6766 100644
--- a/src/net/sourceforge/plantuml/sequencediagram/teoz/SequenceDiagramFileMakerTeoz.java
+++ b/src/net/sourceforge/plantuml/sequencediagram/teoz/SequenceDiagramFileMakerTeoz.java
@@ -148,8 +148,9 @@ public class SequenceDiagramFileMakerTeoz implements FileMaker {
public void drawU(UGraphic ug) {
ug = ug.apply(min1translate);
- englobers.drawEnglobers(goDownForEnglobers(ug), main.calculateDimension(stringBounder).getHeight()
- + heightEnglober1 + heightEnglober2 / 2, new SimpleContext2D(true));
+
+ englobers.drawEnglobers(goDownAndCenterForEnglobers(ug), main.calculateDimension(stringBounder)
+ .getHeight() + heightEnglober1 + heightEnglober2 / 2, new SimpleContext2D(true));
printAligned(ug, diagram.getFooterOrHeaderTeoz(FontParam.HEADER).getHorizontalAlignment(), header);
ug = goDown(ug, header);
@@ -182,13 +183,14 @@ public class SequenceDiagramFileMakerTeoz implements FileMaker {
}
- private UGraphic goDownForEnglobers(UGraphic ug) {
+ private UGraphic goDownAndCenterForEnglobers(UGraphic ug) {
ug = goDown(ug, title);
ug = goDown(ug, header);
if (diagram.getLegend().getVerticalAlignment() == VerticalAlignment.TOP) {
ug = goDown(ug, legend);
}
- return ug;
+ final double dx = (dimTotal.getWidth() - main.calculateDimension(stringBounder).getWidth()) / 2;
+ return ug.apply(new UTranslate(dx, 0));
}
private UGraphic goDown(UGraphic ug, TextBlock size) {
diff --git a/src/net/sourceforge/plantuml/skin/AbstractTextualComponent.java b/src/net/sourceforge/plantuml/skin/AbstractTextualComponent.java
index 741142705..bf7c6f5ff 100644
--- a/src/net/sourceforge/plantuml/skin/AbstractTextualComponent.java
+++ b/src/net/sourceforge/plantuml/skin/AbstractTextualComponent.java
@@ -84,7 +84,7 @@ public abstract class AbstractTextualComponent extends AbstractComponent {
if (strings.size() == 1 && strings.get(0).length() == 0) {
textBlock = new TextBlockEmpty();
} else if (enhanced) {
- textBlock = new BodyEnhanced2(strings, FontParam.NOTE, spriteContainer, HorizontalAlignment.LEFT, font,
+ textBlock = new BodyEnhanced2(strings, FontParam.NOTE, spriteContainer, horizontalAlignment, font,
maxMessageSize);
} else {
textBlock = strings.create(font, horizontalAlignment, spriteContainer, maxMessageSize, CreoleMode.FULL,
diff --git a/src/net/sourceforge/plantuml/skin/rose/ComponentRoseNote.java b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseNote.java
index c1aa2d71d..f9bf9f47d 100644
--- a/src/net/sourceforge/plantuml/skin/rose/ComponentRoseNote.java
+++ b/src/net/sourceforge/plantuml/skin/rose/ComponentRoseNote.java
@@ -60,9 +60,9 @@ final public class ComponentRoseNote extends AbstractTextualComponent implements
private final double roundCorner;
public ComponentRoseNote(SymbolContext symbolContext, FontConfiguration font, Display strings, double paddingX,
- double paddingY, ISkinSimple spriteContainer, double roundCorner) {
- super(LineBreakStrategy.NONE, strings, font, HorizontalAlignment.LEFT, 6, 15, 5, spriteContainer, true, null,
- null);
+ double paddingY, ISkinSimple spriteContainer, double roundCorner, HorizontalAlignment horizontalAlignment) {
+ super(LineBreakStrategy.NONE, strings, font, horizontalAlignment,
+ horizontalAlignment == HorizontalAlignment.CENTER ? 15 : 6, 15, 5, spriteContainer, true, null, null);
this.roundCorner = roundCorner;
this.paddingX = paddingX;
this.paddingY = paddingY;
diff --git a/src/net/sourceforge/plantuml/skin/rose/Rose.java b/src/net/sourceforge/plantuml/skin/rose/Rose.java
index dcdcc680a..784aa1873 100644
--- a/src/net/sourceforge/plantuml/skin/rose/Rose.java
+++ b/src/net/sourceforge/plantuml/skin/rose/Rose.java
@@ -35,7 +35,7 @@
*/
package net.sourceforge.plantuml.skin.rose;
-import net.sourceforge.plantuml.AlignParam;
+import net.sourceforge.plantuml.AlignmentParam;
import net.sourceforge.plantuml.ColorParam;
import net.sourceforge.plantuml.FontParam;
import net.sourceforge.plantuml.ISkinParam;
@@ -100,9 +100,9 @@ public class Rose implements Skin {
config, param, param.maxMessageSize(), param.strictUmlStyle() == false);
}
final HorizontalAlignment messageHorizontalAlignment = param.getHorizontalAlignment(
- AlignParam.SEQUENCE_MESSAGE_ALIGN, config.getArrowDirection());
+ AlignmentParam.sequenceMessageAlignment, config.getArrowDirection());
final HorizontalAlignment textHorizontalAlignment = param.getHorizontalAlignment(
- AlignParam.SEQUENCE_MESSAGETEXT_ALIGN, config.getArrowDirection());
+ AlignmentParam.sequenceMessageTextAlignment, config.getArrowDirection());
return new ComponentRoseArrow(sequenceArrow, getUFont2(param, FontParam.ARROW), stringsToDisplay, config,
messageHorizontalAlignment, param, textHorizontalAlignment, param.maxMessageSize(),
param.strictUmlStyle() == false, param.responseMessageBelowArrow());
@@ -198,8 +198,9 @@ public class Rose implements Skin {
FontParam.DATABASE_STEREOTYPE));
}
if (type == ComponentType.NOTE) {
+ final HorizontalAlignment alignment = param.getHorizontalAlignment(AlignmentParam.noteTextAlignment, null);
return new ComponentRoseNote(getSymbolContext(param, ColorParam.noteBorder), getUFont2(param,
- FontParam.NOTE), stringsToDisplay, paddingX, paddingY, param, roundCorner);
+ FontParam.NOTE), stringsToDisplay, paddingX, paddingY, param, roundCorner, alignment);
}
if (type == ComponentType.NOTE_HEXAGONAL) {
return new ComponentRoseNoteHexagonal(getSymbolContext(param, ColorParam.noteBorder), getUFont2(param,
@@ -258,7 +259,7 @@ public class Rose implements Skin {
if (type == ComponentType.REFERENCE) {
return new ComponentRoseReference(getUFont2(param, FontParam.SEQUENCE_REFERENCE), getSymbolContext(param,
ColorParam.sequenceReferenceBorder), bigFont, stringsToDisplay, param.getHorizontalAlignment(
- AlignParam.SEQUENCE_REFERENCE_ALIGN, null), param, getHtmlColor(param,
+ AlignmentParam.sequenceReferenceAlignment, null), param, getHtmlColor(param,
ColorParam.sequenceReferenceBackground));
}
// if (type == ComponentType.TITLE) {
diff --git a/src/net/sourceforge/plantuml/svek/Cluster.java b/src/net/sourceforge/plantuml/svek/Cluster.java
index 00d9cfa8d..f1c2d99de 100644
--- a/src/net/sourceforge/plantuml/svek/Cluster.java
+++ b/src/net/sourceforge/plantuml/svek/Cluster.java
@@ -48,7 +48,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
-import net.sourceforge.plantuml.AlignParam;
+import net.sourceforge.plantuml.AlignmentParam;
import net.sourceforge.plantuml.ColorParam;
import net.sourceforge.plantuml.Dimension2DDouble;
import net.sourceforge.plantuml.FontParam;
@@ -365,7 +365,7 @@ public class Cluster implements Moveable {
final ClusterDecoration decoration = new ClusterDecoration(style, group.getUSymbol(), ztitle, zstereo,
minX, minY, maxX, maxY, stroke2);
decoration.drawU(ug, back, borderColor, shadowing, roundCorner,
- skinParam2.getHorizontalAlignment(AlignParam.PACKAGE_TITLE_ALIGNMENT, null));
+ skinParam2.getHorizontalAlignment(AlignmentParam.packageTitleAlignment, null));
return;
}
final URectangle rect = new URectangle(maxX - minX, maxY - minY);
@@ -742,7 +742,7 @@ public class Cluster implements Moveable {
sblabel.append(">");
label = sblabel.toString();
final HorizontalAlignment align = skinParam
- .getHorizontalAlignment(AlignParam.PACKAGE_TITLE_ALIGNMENT, null);
+ .getHorizontalAlignment(AlignmentParam.packageTitleAlignment, null);
sb.append("labeljust=\"" + align.getGraphVizValue() + "\";");
} else {
label = "\"\"";
diff --git a/src/net/sourceforge/plantuml/svek/GraphvizCrash.java b/src/net/sourceforge/plantuml/svek/GraphvizCrash.java
index 7a82d6555..f7ea9c96e 100644
--- a/src/net/sourceforge/plantuml/svek/GraphvizCrash.java
+++ b/src/net/sourceforge/plantuml/svek/GraphvizCrash.java
@@ -184,7 +184,7 @@ public class GraphvizCrash extends AbstractTextBlock implements IEntityImage {
if (flashCode != null) {
final double h = graphicStrings.calculateDimension(ug.getStringBounder()).getHeight();
ug = ug.apply(new UTranslate(0, h));
- ug.draw(new UImage(flashCode));
+ ug.draw(new UImage(flashCode).scaleNearestNeighbor(3));
}
}
diff --git a/src/net/sourceforge/plantuml/svek/UGraphicForSnake.java b/src/net/sourceforge/plantuml/svek/UGraphicForSnake.java
index bfd74f055..fe4382279 100644
--- a/src/net/sourceforge/plantuml/svek/UGraphicForSnake.java
+++ b/src/net/sourceforge/plantuml/svek/UGraphicForSnake.java
@@ -51,6 +51,11 @@ public class UGraphicForSnake extends UGraphicDelegator {
private final double dy;
private final List snakes;
+ @Override
+ public String toString() {
+ return super.toString() + " " + getUg();
+ }
+
public UTranslate getTranslation() {
return new UTranslate(dx, dy);
}
diff --git a/src/net/sourceforge/plantuml/svek/image/EntityImageEmptyPackage.java b/src/net/sourceforge/plantuml/svek/image/EntityImageEmptyPackage.java
index d12cbe85f..3d86ef8ea 100644
--- a/src/net/sourceforge/plantuml/svek/image/EntityImageEmptyPackage.java
+++ b/src/net/sourceforge/plantuml/svek/image/EntityImageEmptyPackage.java
@@ -37,7 +37,7 @@ package net.sourceforge.plantuml.svek.image;
import java.awt.geom.Dimension2D;
-import net.sourceforge.plantuml.AlignParam;
+import net.sourceforge.plantuml.AlignmentParam;
import net.sourceforge.plantuml.ColorParam;
import net.sourceforge.plantuml.Dimension2DDouble;
import net.sourceforge.plantuml.FontParam;
@@ -130,7 +130,7 @@ public class EntityImageEmptyPackage extends AbstractEntityImage {
decoration.drawU(ug, back, SkinParamUtils.getColor(getSkinParam(), ColorParam.packageBorder, getStereo()),
getSkinParam().shadowing(), roundCorner,
- getSkinParam().getHorizontalAlignment(AlignParam.PACKAGE_TITLE_ALIGNMENT, null));
+ getSkinParam().getHorizontalAlignment(AlignmentParam.packageTitleAlignment, null));
if (url != null) {
ug.closeAction();
diff --git a/src/net/sourceforge/plantuml/svg/SvgGraphics.java b/src/net/sourceforge/plantuml/svg/SvgGraphics.java
index d3bfcc464..6005be725 100644
--- a/src/net/sourceforge/plantuml/svg/SvgGraphics.java
+++ b/src/net/sourceforge/plantuml/svg/SvgGraphics.java
@@ -743,11 +743,11 @@ public class SvgGraphics {
private String manageScale(SvgString svg) {
final double svgScale = svg.getScale();
if (svgScale * scale == 1) {
- return svg.getSvg();
+ return svg.getSvg(false);
}
final String s1 = "\\ preproc = new TreeSet();
public LanguageDescriptor() {
-
+
type.add("actor");
type.add("participant");
type.add("usecase");
@@ -165,6 +166,26 @@ public class LanguageDescriptor {
preproc.add("!enddefinelong");
}
+ public Cypher getCypher() {
+ final Cypher cypher = new Cypher();
+ for (String s : type) {
+ cypher.addException(s);
+ }
+ for (String s : keyword) {
+ cypher.addException(s.replace("@", ""));
+ }
+ for (String s : preproc) {
+ cypher.addException(s.substring(1));
+ }
+ for (String s : SkinParam.getPossibleValues()) {
+ cypher.addException(s);
+ }
+ for (String s : new HtmlColorSetSimple().names()) {
+ cypher.addException(s);
+ }
+ return cypher;
+ }
+
public void print(PrintStream ps) {
print(ps, "type", type);
print(ps, "keyword", keyword);
@@ -175,7 +196,7 @@ public class LanguageDescriptor {
}
private static void print(PrintStream ps, String name, Collection data) {
- ps.println(";"+name);
+ ps.println(";" + name);
ps.println(";" + data.size());
for (String k : data) {
ps.println(k);
diff --git a/src/net/sourceforge/plantuml/ugraphic/FontChecker.java b/src/net/sourceforge/plantuml/ugraphic/FontChecker.java
index 4e0ee26d1..68a6d7d1b 100644
--- a/src/net/sourceforge/plantuml/ugraphic/FontChecker.java
+++ b/src/net/sourceforge/plantuml/ugraphic/FontChecker.java
@@ -48,7 +48,6 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.HashSet;
-import java.util.Random;
import java.util.Set;
import javax.imageio.ImageIO;
diff --git a/src/net/sourceforge/plantuml/ugraphic/ImageBuilder.java b/src/net/sourceforge/plantuml/ugraphic/ImageBuilder.java
index 5b2ceebfd..e0ee57a9c 100644
--- a/src/net/sourceforge/plantuml/ugraphic/ImageBuilder.java
+++ b/src/net/sourceforge/plantuml/ugraphic/ImageBuilder.java
@@ -55,6 +55,7 @@ import javax.swing.ImageIcon;
import net.sourceforge.plantuml.AnimatedGifEncoder;
import net.sourceforge.plantuml.CMapData;
import net.sourceforge.plantuml.ColorParam;
+import net.sourceforge.plantuml.CornerParam;
import net.sourceforge.plantuml.Dimension2DDouble;
import net.sourceforge.plantuml.EmptyImageBuilder;
import net.sourceforge.plantuml.FileFormat;
@@ -63,7 +64,6 @@ import net.sourceforge.plantuml.FileUtils;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.LineParam;
import net.sourceforge.plantuml.OptionFlags;
-import net.sourceforge.plantuml.CornerParam;
import net.sourceforge.plantuml.StringUtils;
import net.sourceforge.plantuml.Url;
import net.sourceforge.plantuml.anim.AffineTransformation;
diff --git a/src/net/sourceforge/plantuml/ugraphic/SlotFinderX.java b/src/net/sourceforge/plantuml/ugraphic/SlotFinderX.java
deleted file mode 100644
index 0c3aabfba..000000000
--- a/src/net/sourceforge/plantuml/ugraphic/SlotFinderX.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/* ========================================================================
- * PlantUML : a free UML diagram generator
- * ========================================================================
- *
- * (C) Copyright 2009-2017, Arnaud Roques
- *
- * Project Info: http://plantuml.com
- *
- * If you like this project or if you find it useful, you can support us at:
- *
- * http://plantuml.com/patreon (only 1$ per month!)
- * http://plantuml.com/paypal
- *
- * This file is part of PlantUML.
- *
- * PlantUML is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * PlantUML distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA.
- *
- *
- * Original Author: Arnaud Roques
- *
- *
- */
-package net.sourceforge.plantuml.ugraphic;
-
-import net.sourceforge.plantuml.Url;
-import net.sourceforge.plantuml.graphic.StringBounder;
-
-public class SlotFinderX implements UGraphic {
-
- public boolean matchesProperty(String propertyName) {
- return false;
- }
-
- public double dpiFactor() {
- return 1;
- }
-
- public UGraphic apply(UChange change) {
- if (change instanceof UTranslate) {
- return new SlotFinderX(stringBounder, xslot, yslot, translate.compose((UTranslate) change));
- } else if (change instanceof UStroke) {
- return new SlotFinderX(this);
- } else if (change instanceof UChangeBackColor) {
- return new SlotFinderX(this);
- } else if (change instanceof UChangeColor) {
- return new SlotFinderX(this);
- }
- throw new UnsupportedOperationException();
- }
-
- private final SlotSet xslot;
- private final SlotSet yslot;
- private final StringBounder stringBounder;
- private final UTranslate translate;
-
- public SlotFinderX(StringBounder stringBounder) {
- this(stringBounder, new SlotSet(), new SlotSet(), new UTranslate());
- }
-
- private SlotFinderX(StringBounder stringBounder, SlotSet xslot, SlotSet yslot, UTranslate translate) {
- this.stringBounder = stringBounder;
- this.xslot = xslot;
- this.yslot = yslot;
- this.translate = translate;
- }
-
- private SlotFinderX(SlotFinderX other) {
- this(other.stringBounder, other.xslot, other.yslot, other.translate);
- }
-
- public StringBounder getStringBounder() {
- return stringBounder;
- }
-
- public UParam getParam() {
- return new UParamNull();
- }
-
- public void draw(UShape shape) {
- final double x = translate.getDx();
- final double y = translate.getDy();
- if (shape instanceof URectangle) {
- drawRectangle(x, y, (URectangle) shape);
- } else if (shape instanceof UPolygon) {
- drawPolygon(x, y, (UPolygon) shape);
- } else if (shape instanceof UEllipse) {
- drawEllipse(x, y, (UEllipse) shape);
- } else if (shape instanceof UText) {
- drawText(x, y, (UText) shape);
- } else if (shape instanceof UEmpty) {
- drawEmpty(x, y, (UEmpty) shape);
- }
- }
-
- private void drawEmpty(double x, double y, UEmpty shape) {
- xslot.addSlot(x, x + shape.getWidth());
- yslot.addSlot(y, y + shape.getHeight());
- }
-
- private void drawText(double x, double y, UText shape) {
- final TextLimitFinder finder = new TextLimitFinder(stringBounder, false);
- finder.apply(new UTranslate(x, y)).draw(shape);
- xslot.addSlot(finder.getMinX(), finder.getMaxX());
- yslot.addSlot(finder.getMinY(), finder.getMaxY());
- }
-
- private void drawEllipse(double x, double y, UEllipse shape) {
- xslot.addSlot(x, x + shape.getWidth());
- yslot.addSlot(y, y + shape.getHeight());
- }
-
- private void drawPolygon(double x, double y, UPolygon shape) {
- xslot.addSlot(x + shape.getMinX(), x + shape.getMaxX());
- yslot.addSlot(y + shape.getMinY(), y + shape.getMaxY());
- }
-
- private void drawRectangle(double x, double y, URectangle shape) {
- xslot.addSlot(x, x + shape.getWidth());
- yslot.addSlot(y, y + shape.getHeight());
- }
-
- public ColorMapper getColorMapper() {
- return new ColorMapperIdentity();
- }
-
- public void startUrl(Url url) {
- }
-
- public void closeAction() {
- }
-
- public SlotSet getXSlotSet() {
- return xslot;
- }
-
- public SlotSet getYSlotSet() {
- return yslot;
- }
-
- public void flushUg() {
- }
-
-}
diff --git a/src/net/sourceforge/plantuml/ugraphic/UGraphicCompress2.java b/src/net/sourceforge/plantuml/ugraphic/UGraphicCompress2.java
deleted file mode 100644
index e670639c1..000000000
--- a/src/net/sourceforge/plantuml/ugraphic/UGraphicCompress2.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/* ========================================================================
- * PlantUML : a free UML diagram generator
- * ========================================================================
- *
- * (C) Copyright 2009-2017, Arnaud Roques
- *
- * Project Info: http://plantuml.com
- *
- * If you like this project or if you find it useful, you can support us at:
- *
- * http://plantuml.com/patreon (only 1$ per month!)
- * http://plantuml.com/paypal
- *
- * This file is part of PlantUML.
- *
- * PlantUML is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * PlantUML distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA.
- *
- *
- * Original Author: Arnaud Roques
- *
- *
- */
-package net.sourceforge.plantuml.ugraphic;
-
-import net.sourceforge.plantuml.activitydiagram3.ftile.Snake;
-import net.sourceforge.plantuml.graphic.UGraphicDelegator;
-
-public class UGraphicCompress2 extends UGraphicDelegator {
-
- public UGraphic apply(UChange change) {
- if (change instanceof UTranslate) {
- return new UGraphicCompress2(getUg(), compressionTransform, translate.compose((UTranslate) change));
- } else if (change instanceof UStroke || change instanceof UChangeBackColor || change instanceof UChangeColor) {
- return new UGraphicCompress2(getUg().apply(change), compressionTransform, translate);
- }
- throw new UnsupportedOperationException();
- }
-
- private final CompressionTransform compressionTransform;
- private final UTranslate translate;
-
- public UGraphicCompress2(UGraphic ug, CompressionTransform compressionTransform) {
- this(ug, compressionTransform, new UTranslate());
- }
-
- private UGraphicCompress2(UGraphic ug, CompressionTransform compressionTransform, UTranslate translate) {
- super(ug);
- this.compressionTransform = compressionTransform;
- this.translate = translate;
- }
-
- public void draw(UShape shape) {
- final double x = translate.getDx();
- final double y = translate.getDy();
- if (shape instanceof ULine) {
- drawLine(x, y, (ULine) shape);
- } else if (shape instanceof Snake) {
- drawSnake(x, y, (Snake) shape);
- } else {
- getUg().apply(new UTranslate(ct(x), y)).draw(shape);
- }
- }
-
- private void drawSnake(double x, double y, Snake shape) {
- final Snake transformed = shape.translate(new UTranslate(x, y)).transformX(compressionTransform);
- getUg().draw(transformed);
- }
-
- private void drawLine(double x, double y, ULine shape) {
- drawLine(ct(x), y, ct(x + shape.getDX()), y + shape.getDY());
- }
-
- private double ct(double v) {
- return compressionTransform.transform(v);
- }
-
- private void drawLine(double x1, double y1, double x2, double y2) {
- final double xmin = Math.min(x1, x2);
- final double xmax = Math.max(x1, x2);
- final double ymin = Math.min(y1, y2);
- final double ymax = Math.max(y1, y2);
- getUg().apply(new UTranslate(xmin, ymin)).draw(new ULine(xmax - xmin, ymax - ymin));
- }
-
-}
diff --git a/src/net/sourceforge/plantuml/ugraphic/UImage.java b/src/net/sourceforge/plantuml/ugraphic/UImage.java
index 4936fd09d..41d356427 100644
--- a/src/net/sourceforge/plantuml/ugraphic/UImage.java
+++ b/src/net/sourceforge/plantuml/ugraphic/UImage.java
@@ -43,32 +43,19 @@ public class UImage implements UShape {
private final BufferedImage image;
- // public final double getScale() {
- // return scale;
- // }
-
public UImage(BufferedImage image) {
this.image = image;
}
- // public UImage(BufferedImage before, double scale) {
- // this.image = before;
- // this.scale = scale;
- // // if (scale == 1) {
- // // this.image = before;
- // // return;
- // // }
- //
- // // final int w = (int) Math.round(before.getWidth() * scale);
- // // final int h = (int) Math.round(before.getHeight() * scale);
- // // final BufferedImage after = new BufferedImage(w, h, before.getType());
- // // final AffineTransform at = new AffineTransform();
- // // at.scale(scale, scale);
- // // final AffineTransformOp scaleOp = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
- // // this.image = scaleOp.filter(before, after);
- // }
-
public UImage scale(double scale) {
+ return scale(scale, AffineTransformOp.TYPE_BILINEAR);
+ }
+
+ public UImage scaleNearestNeighbor(double scale) {
+ return scale(scale, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
+ }
+
+ private UImage scale(double scale, final int type) {
if (scale == 1) {
return this;
}
@@ -77,7 +64,7 @@ public class UImage implements UShape {
final BufferedImage after = new BufferedImage(w, h, image.getType());
final AffineTransform at = new AffineTransform();
at.scale(scale, scale);
- final AffineTransformOp scaleOp = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
+ final AffineTransformOp scaleOp = new AffineTransformOp(at, type);
return new UImage(scaleOp.filter(image, after));
}
@@ -93,8 +80,4 @@ public class UImage implements UShape {
return image.getHeight() - 1;
}
- // public UShape getScaled(double scale) {
- // return scale(scale);
- // }
-
}
diff --git a/src/net/sourceforge/plantuml/ugraphic/URectangle.java b/src/net/sourceforge/plantuml/ugraphic/URectangle.java
index eb110b320..0230333e7 100644
--- a/src/net/sourceforge/plantuml/ugraphic/URectangle.java
+++ b/src/net/sourceforge/plantuml/ugraphic/URectangle.java
@@ -44,13 +44,20 @@ public class URectangle extends AbstractShadowable implements Scalable, UShapeSi
private final double ry;
private final String comment;
- public URectangle withWidth(double newHeight) {
+ public URectangle withHeight(double newHeight) {
final URectangle result = new URectangle(width, newHeight, rx, ry, comment);
result.ignoreForCompression = this.ignoreForCompression;
result.setDeltaShadow(this.getDeltaShadow());
return result;
}
+ public URectangle withWidth(double newWidth) {
+ final URectangle result = new URectangle(newWidth, height, rx, ry, comment);
+ result.ignoreForCompression = this.ignoreForCompression;
+ result.setDeltaShadow(this.getDeltaShadow());
+ return result;
+ }
+
public UShape getScaled(double scale) {
if (scale == 1) {
return this;
diff --git a/src/net/sourceforge/plantuml/ugraphic/comp/CompressionMode.java b/src/net/sourceforge/plantuml/ugraphic/comp/CompressionMode.java
new file mode 100644
index 000000000..d14d55329
--- /dev/null
+++ b/src/net/sourceforge/plantuml/ugraphic/comp/CompressionMode.java
@@ -0,0 +1,41 @@
+/* ========================================================================
+ * PlantUML : a free UML diagram generator
+ * ========================================================================
+ *
+ * (C) Copyright 2009-2017, Arnaud Roques
+ *
+ * Project Info: http://plantuml.com
+ *
+ * If you like this project or if you find it useful, you can support us at:
+ *
+ * http://plantuml.com/patreon (only 1$ per month!)
+ * http://plantuml.com/paypal
+ *
+ * This file is part of PlantUML.
+ *
+ * PlantUML is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PlantUML distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ *
+ *
+ * Original Author: Arnaud Roques
+ *
+ *
+ */
+package net.sourceforge.plantuml.ugraphic.comp;
+
+public enum CompressionMode {
+ ON_X, ON_Y
+
+}
diff --git a/src/net/sourceforge/plantuml/ugraphic/CompressionTransform.java b/src/net/sourceforge/plantuml/ugraphic/comp/CompressionTransform.java
similarity index 97%
rename from src/net/sourceforge/plantuml/ugraphic/CompressionTransform.java
rename to src/net/sourceforge/plantuml/ugraphic/comp/CompressionTransform.java
index c229442d7..9cc7bd37b 100644
--- a/src/net/sourceforge/plantuml/ugraphic/CompressionTransform.java
+++ b/src/net/sourceforge/plantuml/ugraphic/comp/CompressionTransform.java
@@ -33,7 +33,7 @@
*
*
*/
-package net.sourceforge.plantuml.ugraphic;
+package net.sourceforge.plantuml.ugraphic.comp;
import java.util.List;
diff --git a/src/net/sourceforge/plantuml/ugraphic/Slot.java b/src/net/sourceforge/plantuml/ugraphic/comp/Slot.java
similarity index 98%
rename from src/net/sourceforge/plantuml/ugraphic/Slot.java
rename to src/net/sourceforge/plantuml/ugraphic/comp/Slot.java
index 671d6a282..8c0bd5ab9 100644
--- a/src/net/sourceforge/plantuml/ugraphic/Slot.java
+++ b/src/net/sourceforge/plantuml/ugraphic/comp/Slot.java
@@ -33,7 +33,7 @@
*
*
*/
-package net.sourceforge.plantuml.ugraphic;
+package net.sourceforge.plantuml.ugraphic.comp;
public class Slot implements Comparable {
diff --git a/src/net/sourceforge/plantuml/ugraphic/SlotFinder.java b/src/net/sourceforge/plantuml/ugraphic/comp/SlotFinder.java
similarity index 54%
rename from src/net/sourceforge/plantuml/ugraphic/SlotFinder.java
rename to src/net/sourceforge/plantuml/ugraphic/comp/SlotFinder.java
index b4992065f..bf26fb9de 100644
--- a/src/net/sourceforge/plantuml/ugraphic/SlotFinder.java
+++ b/src/net/sourceforge/plantuml/ugraphic/comp/SlotFinder.java
@@ -33,10 +33,28 @@
*
*
*/
-package net.sourceforge.plantuml.ugraphic;
+package net.sourceforge.plantuml.ugraphic.comp;
import net.sourceforge.plantuml.Url;
import net.sourceforge.plantuml.graphic.StringBounder;
+import net.sourceforge.plantuml.ugraphic.ColorMapper;
+import net.sourceforge.plantuml.ugraphic.ColorMapperIdentity;
+import net.sourceforge.plantuml.ugraphic.TextLimitFinder;
+import net.sourceforge.plantuml.ugraphic.UChange;
+import net.sourceforge.plantuml.ugraphic.UChangeBackColor;
+import net.sourceforge.plantuml.ugraphic.UChangeColor;
+import net.sourceforge.plantuml.ugraphic.UEllipse;
+import net.sourceforge.plantuml.ugraphic.UEmpty;
+import net.sourceforge.plantuml.ugraphic.UGraphic;
+import net.sourceforge.plantuml.ugraphic.UParam;
+import net.sourceforge.plantuml.ugraphic.UParamNull;
+import net.sourceforge.plantuml.ugraphic.UPath;
+import net.sourceforge.plantuml.ugraphic.UPolygon;
+import net.sourceforge.plantuml.ugraphic.URectangle;
+import net.sourceforge.plantuml.ugraphic.UShape;
+import net.sourceforge.plantuml.ugraphic.UStroke;
+import net.sourceforge.plantuml.ugraphic.UText;
+import net.sourceforge.plantuml.ugraphic.UTranslate;
public class SlotFinder implements UGraphic {
@@ -50,7 +68,7 @@ public class SlotFinder implements UGraphic {
public UGraphic apply(UChange change) {
if (change instanceof UTranslate) {
- return new SlotFinder(stringBounder, yslot, translate.compose((UTranslate) change));
+ return new SlotFinder(mode, stringBounder, slot, translate.compose((UTranslate) change));
} else if (change instanceof UStroke) {
return new SlotFinder(this);
} else if (change instanceof UChangeBackColor) {
@@ -61,22 +79,25 @@ public class SlotFinder implements UGraphic {
throw new UnsupportedOperationException();
}
- private final SlotSet yslot;
+ private final SlotSet slot;
+
private final StringBounder stringBounder;
private final UTranslate translate;
+ private final CompressionMode mode;
- public SlotFinder(StringBounder stringBounder) {
- this(stringBounder, new SlotSet(), new UTranslate());
+ public SlotFinder(CompressionMode mode, StringBounder stringBounder) {
+ this(mode, stringBounder, new SlotSet(), new UTranslate());
}
- private SlotFinder(StringBounder stringBounder, SlotSet yslot, UTranslate translate) {
+ private SlotFinder(CompressionMode mode, StringBounder stringBounder, SlotSet slot, UTranslate translate) {
this.stringBounder = stringBounder;
- this.yslot = yslot;
+ this.slot = slot;
this.translate = translate;
+ this.mode = mode;
}
private SlotFinder(SlotFinder other) {
- this(other.stringBounder, other.yslot, other.translate);
+ this(other.mode, other.stringBounder, other.slot, other.translate);
}
public StringBounder getStringBounder() {
@@ -92,12 +113,19 @@ public class SlotFinder implements UGraphic {
final double y = translate.getDy();
if (shape instanceof URectangle) {
final URectangle rect = (URectangle) shape;
- if (rect.isIgnoreForCompression()) {
+ if (mode == CompressionMode.ON_X && rect.isIgnoreForCompression()) {
+ drawRectangle(x, y, new URectangle(2, rect.getHeight()));
+ drawRectangle(x + rect.getWidth() - 2, y, new URectangle(2, rect.getHeight()));
+ return;
+ }
+ if (mode == CompressionMode.ON_Y && rect.isIgnoreForCompression()) {
drawRectangle(x, y, new URectangle(rect.getWidth(), 2));
drawRectangle(x, y + rect.getHeight() - 2, new URectangle(rect.getWidth(), 2));
return;
}
- drawRectangle(x, y, rect);
+ drawRectangle(x, y, (URectangle) shape);
+ } else if (shape instanceof UPath) {
+ drawPath(x, y, (UPath) shape);
} else if (shape instanceof UPolygon) {
drawPolygon(x, y, (UPolygon) shape);
} else if (shape instanceof UEllipse) {
@@ -109,26 +137,55 @@ public class SlotFinder implements UGraphic {
}
}
+ private void drawPath(double x, double y, UPath shape) {
+ if (mode == CompressionMode.ON_X) {
+ slot.addSlot(x + shape.getMinX(), x + shape.getMaxX());
+ } else {
+ slot.addSlot(y + shape.getMinY(), y + shape.getMaxY());
+ }
+
+ }
+
private void drawEmpty(double x, double y, UEmpty shape) {
- yslot.addSlot(y, y + shape.getHeight());
+ if (mode == CompressionMode.ON_X) {
+ slot.addSlot(x, x + shape.getWidth());
+ } else {
+ slot.addSlot(y, y + shape.getHeight());
+ }
}
private void drawText(double x, double y, UText shape) {
final TextLimitFinder finder = new TextLimitFinder(stringBounder, false);
finder.apply(new UTranslate(x, y)).draw(shape);
- yslot.addSlot(finder.getMinY(), finder.getMaxY());
+ if (mode == CompressionMode.ON_X) {
+ slot.addSlot(finder.getMinX(), finder.getMaxX());
+ } else {
+ slot.addSlot(finder.getMinY(), finder.getMaxY());
+ }
}
private void drawEllipse(double x, double y, UEllipse shape) {
- yslot.addSlot(y, y + shape.getHeight());
+ if (mode == CompressionMode.ON_X) {
+ slot.addSlot(x, x + shape.getWidth());
+ } else {
+ slot.addSlot(y, y + shape.getHeight());
+ }
}
private void drawPolygon(double x, double y, UPolygon shape) {
- yslot.addSlot(y + shape.getMinY(), y + shape.getMaxY());
+ if (mode == CompressionMode.ON_X) {
+ slot.addSlot(x + shape.getMinX(), x + shape.getMaxX());
+ } else {
+ slot.addSlot(y + shape.getMinY(), y + shape.getMaxY());
+ }
}
private void drawRectangle(double x, double y, URectangle shape) {
- yslot.addSlot(y, y + shape.getHeight());
+ if (mode == CompressionMode.ON_X) {
+ slot.addSlot(x, x + shape.getWidth());
+ } else {
+ slot.addSlot(y, y + shape.getHeight());
+ }
}
public ColorMapper getColorMapper() {
@@ -141,8 +198,8 @@ public class SlotFinder implements UGraphic {
public void closeAction() {
}
- public SlotSet getYSlotSet() {
- return yslot;
+ public SlotSet getSlotSet() {
+ return slot;
}
public void flushUg() {
diff --git a/src/net/sourceforge/plantuml/ugraphic/SlotSet.java b/src/net/sourceforge/plantuml/ugraphic/comp/SlotSet.java
similarity index 93%
rename from src/net/sourceforge/plantuml/ugraphic/SlotSet.java
rename to src/net/sourceforge/plantuml/ugraphic/comp/SlotSet.java
index 1ad5fc800..0be097d4d 100644
--- a/src/net/sourceforge/plantuml/ugraphic/SlotSet.java
+++ b/src/net/sourceforge/plantuml/ugraphic/comp/SlotSet.java
@@ -33,13 +33,17 @@
*
*
*/
-package net.sourceforge.plantuml.ugraphic;
+package net.sourceforge.plantuml.ugraphic.comp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
+import net.sourceforge.plantuml.ugraphic.UGraphic;
+import net.sourceforge.plantuml.ugraphic.URectangle;
+import net.sourceforge.plantuml.ugraphic.UTranslate;
+
public class SlotSet implements Iterable {
private final List all = new ArrayList();
diff --git a/src/net/sourceforge/plantuml/graphic/TextBlockCompressed.java b/src/net/sourceforge/plantuml/ugraphic/comp/TextBlockCompressedOnXorY.java
similarity index 73%
rename from src/net/sourceforge/plantuml/graphic/TextBlockCompressed.java
rename to src/net/sourceforge/plantuml/ugraphic/comp/TextBlockCompressedOnXorY.java
index 21a88ebbb..a5c03206e 100644
--- a/src/net/sourceforge/plantuml/graphic/TextBlockCompressed.java
+++ b/src/net/sourceforge/plantuml/ugraphic/comp/TextBlockCompressedOnXorY.java
@@ -33,30 +33,32 @@
*
*
*/
-package net.sourceforge.plantuml.graphic;
+package net.sourceforge.plantuml.ugraphic.comp;
import java.awt.geom.Dimension2D;
import net.sourceforge.plantuml.Dimension2DDouble;
-import net.sourceforge.plantuml.ugraphic.CompressionTransform;
+import net.sourceforge.plantuml.graphic.AbstractTextBlock;
+import net.sourceforge.plantuml.graphic.StringBounder;
+import net.sourceforge.plantuml.graphic.TextBlock;
+import net.sourceforge.plantuml.graphic.TextBlockUtils;
import net.sourceforge.plantuml.ugraphic.MinMax;
-import net.sourceforge.plantuml.ugraphic.SlotFinder;
-import net.sourceforge.plantuml.ugraphic.SlotSet;
import net.sourceforge.plantuml.ugraphic.UGraphic;
-import net.sourceforge.plantuml.ugraphic.UGraphicCompress;
-public class TextBlockCompressed extends AbstractTextBlock implements TextBlock {
+public class TextBlockCompressedOnXorY extends AbstractTextBlock implements TextBlock {
private final TextBlock textBlock;
+ private final CompressionMode mode;
- public TextBlockCompressed(TextBlock textBlock) {
+ public TextBlockCompressedOnXorY(CompressionMode mode, TextBlock textBlock) {
this.textBlock = textBlock;
+ this.mode = mode;
}
public void drawU(final UGraphic ug) {
final StringBounder stringBounder = ug.getStringBounder();
final CompressionTransform compressionTransform = getCompressionTransform(stringBounder);
- textBlock.drawU(new UGraphicCompress(ug, compressionTransform));
+ textBlock.drawU(new UGraphicCompressOnXorY(mode, ug, compressionTransform));
}
private MinMax cachedMinMax;
@@ -79,9 +81,9 @@ public class TextBlockCompressed extends AbstractTextBlock implements TextBlock
}
private CompressionTransform getCompressionTransformSlow(final StringBounder stringBounder) {
- final SlotFinder slotFinder = new SlotFinder(stringBounder);
+ final SlotFinder slotFinder = new SlotFinder(mode, stringBounder);
textBlock.drawU(slotFinder);
- final SlotSet ysSlotSet = slotFinder.getYSlotSet().reverse().smaller(5.0);
+ final SlotSet ysSlotSet = slotFinder.getSlotSet().reverse().smaller(5.0);
final CompressionTransform compressionTransform = new CompressionTransform(ysSlotSet);
return compressionTransform;
}
@@ -89,6 +91,10 @@ public class TextBlockCompressed extends AbstractTextBlock implements TextBlock
public Dimension2D calculateDimension(StringBounder stringBounder) {
final CompressionTransform compressionTransform = getCompressionTransform(stringBounder);
final Dimension2D dim = textBlock.calculateDimension(stringBounder);
- return new Dimension2DDouble(dim.getWidth(), compressionTransform.transform(dim.getHeight()));
+ if (mode == CompressionMode.ON_X) {
+ return new Dimension2DDouble(compressionTransform.transform(dim.getWidth()), dim.getHeight());
+ } else {
+ return new Dimension2DDouble(dim.getWidth(), compressionTransform.transform(dim.getHeight()));
+ }
}
}
\ No newline at end of file
diff --git a/src/net/sourceforge/plantuml/ugraphic/UGraphicCompress.java b/src/net/sourceforge/plantuml/ugraphic/comp/UGraphicCompressOnXorY.java
similarity index 56%
rename from src/net/sourceforge/plantuml/ugraphic/UGraphicCompress.java
rename to src/net/sourceforge/plantuml/ugraphic/comp/UGraphicCompressOnXorY.java
index 64dacfcc1..3986b217e 100644
--- a/src/net/sourceforge/plantuml/ugraphic/UGraphicCompress.java
+++ b/src/net/sourceforge/plantuml/ugraphic/comp/UGraphicCompressOnXorY.java
@@ -33,30 +33,42 @@
*
*
*/
-package net.sourceforge.plantuml.ugraphic;
+package net.sourceforge.plantuml.ugraphic.comp;
import net.sourceforge.plantuml.graphic.UGraphicDelegator;
+import net.sourceforge.plantuml.ugraphic.UChange;
+import net.sourceforge.plantuml.ugraphic.UChangeBackColor;
+import net.sourceforge.plantuml.ugraphic.UChangeColor;
+import net.sourceforge.plantuml.ugraphic.UGraphic;
+import net.sourceforge.plantuml.ugraphic.ULine;
+import net.sourceforge.plantuml.ugraphic.URectangle;
+import net.sourceforge.plantuml.ugraphic.UShape;
+import net.sourceforge.plantuml.ugraphic.UStroke;
+import net.sourceforge.plantuml.ugraphic.UTranslate;
-public class UGraphicCompress extends UGraphicDelegator {
+public class UGraphicCompressOnXorY extends UGraphicDelegator {
public UGraphic apply(UChange change) {
if (change instanceof UTranslate) {
- return new UGraphicCompress(getUg(), compressionTransform, translate.compose((UTranslate) change));
+ return new UGraphicCompressOnXorY(mode, getUg(), compressionTransform, translate.compose((UTranslate) change));
} else if (change instanceof UStroke || change instanceof UChangeBackColor || change instanceof UChangeColor) {
- return new UGraphicCompress(getUg().apply(change), compressionTransform, translate);
+ return new UGraphicCompressOnXorY(mode, getUg().apply(change), compressionTransform, translate);
}
throw new UnsupportedOperationException();
}
+ private final CompressionMode mode;
private final CompressionTransform compressionTransform;
private final UTranslate translate;
- public UGraphicCompress(UGraphic ug, CompressionTransform compressionTransform) {
- this(ug, compressionTransform, new UTranslate());
+ public UGraphicCompressOnXorY(CompressionMode mode, UGraphic ug, CompressionTransform compressionTransform) {
+ this(mode, ug, compressionTransform, new UTranslate());
}
- private UGraphicCompress(UGraphic ug, CompressionTransform compressionTransform, UTranslate translate) {
+ private UGraphicCompressOnXorY(CompressionMode mode, UGraphic ug, CompressionTransform compressionTransform,
+ UTranslate translate) {
super(ug);
+ this.mode = mode;
this.compressionTransform = compressionTransform;
this.translate = translate;
}
@@ -67,19 +79,32 @@ public class UGraphicCompress extends UGraphicDelegator {
if (shape instanceof URectangle) {
final URectangle rect = (URectangle) shape;
if (rect.isIgnoreForCompression()) {
- final double y2 = ct(y + rect.getHeight());
- shape = rect.withWidth(y2 - ct(y));
+ if (mode == CompressionMode.ON_X) {
+ final double x2 = ct(x + rect.getWidth());
+ shape = rect.withWidth(x2 - ct(x));
+ } else {
+ final double y2 = ct(y + rect.getHeight());
+ shape = rect.withHeight(y2 - ct(y));
+ }
}
}
if (shape instanceof ULine) {
drawLine(x, y, (ULine) shape);
} else {
- getUg().apply(new UTranslate(x, ct(y))).draw(shape);
+ if (mode == CompressionMode.ON_X) {
+ getUg().apply(new UTranslate(ct(x), y)).draw(shape);
+ } else {
+ getUg().apply(new UTranslate(x, ct(y))).draw(shape);
+ }
}
}
private void drawLine(double x, double y, ULine shape) {
- drawLine(x, ct(y), x + shape.getDX(), ct(y + shape.getDY()));
+ if (mode == CompressionMode.ON_X) {
+ drawLine(ct(x), y, ct(x + shape.getDX()), y + shape.getDY());
+ } else {
+ drawLine(x, ct(y), x + shape.getDX(), ct(y + shape.getDY()));
+ }
}
private double ct(double v) {
@@ -92,15 +117,7 @@ public class UGraphicCompress extends UGraphicDelegator {
return;
}
assert y1 <= y2;
- final double xmin = Math.min(x1, x2);
- final double xmax = Math.max(x1, x2);
- final double ymin = Math.min(y1, y2);
- final double ymax = Math.max(y1, y2);
- if (x2 >= x1) {
- getUg().apply(new UTranslate(xmin, ymin)).draw(new ULine(xmax - xmin, ymax - ymin));
- } else {
- getUg().apply(new UTranslate(xmax, ymin)).draw(new ULine(-(xmax - xmin), ymax - ymin));
- }
+ getUg().apply(new UTranslate(x1, y1)).draw(new ULine(x2 - x1, y2 - y1));
}
}
diff --git a/src/net/sourceforge/plantuml/ugraphic/txt/UGraphicTxt.java b/src/net/sourceforge/plantuml/ugraphic/txt/UGraphicTxt.java
index 90c8785ee..56ea48a40 100644
--- a/src/net/sourceforge/plantuml/ugraphic/txt/UGraphicTxt.java
+++ b/src/net/sourceforge/plantuml/ugraphic/txt/UGraphicTxt.java
@@ -84,7 +84,6 @@ public class UGraphicTxt extends AbstractCommonUGraphic implements ClipContainer
if (shape instanceof UText) {
final UText txt = (UText) shape;
final int y = ((int) (getTranslateY() + txt.getDescent())) / 10;
- System.err.println("x=" + getDx());
if (txt.getFontConfiguration().containsStyle(FontStyle.WAVE)) {
charArea.drawHLine('^', y, getDx(), txt.getText().length());
charArea.drawStringLR(txt.getText(), getDx(), y + 1);
diff --git a/src/net/sourceforge/plantuml/utils/Cypher.java b/src/net/sourceforge/plantuml/utils/Cypher.java
new file mode 100644
index 000000000..6588a2ae3
--- /dev/null
+++ b/src/net/sourceforge/plantuml/utils/Cypher.java
@@ -0,0 +1,98 @@
+/* ========================================================================
+ * PlantUML : a free UML diagram generator
+ * ========================================================================
+ *
+ * (C) Copyright 2009-2017, Arnaud Roques
+ *
+ * Project Info: http://plantuml.com
+ *
+ * If you like this project or if you find it useful, you can support us at:
+ *
+ * http://plantuml.com/patreon (only 1$ per month!)
+ * http://plantuml.com/paypal
+ *
+ * This file is part of PlantUML.
+ *
+ * PlantUML is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PlantUML distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ *
+ *
+ * Original Author: Arnaud Roques
+ *
+ *
+ */
+package net.sourceforge.plantuml.utils;
+
+import java.security.SecureRandom;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class Cypher {
+
+ final private static Pattern p = Pattern.compile("[\\p{L}\\p{N}]+");
+
+ private final SecureRandom rnd = new SecureRandom();
+ private final Map convert = new HashMap();
+ private final Set except = new HashSet();
+
+ public synchronized String cypher(String s) {
+
+ final Matcher m = p.matcher(s);
+ final StringBuffer sb = new StringBuffer();
+ while (m.find()) {
+ final String word = m.group(0);
+ m.appendReplacement(sb, changeWord(word));
+ }
+ m.appendTail(sb);
+
+ return sb.toString();
+ }
+
+ private String changeWord(final String word) {
+ final String lower = word.toLowerCase();
+ if (except.contains(lower) || lower.matches("^[a-f0-9]{6}$")) {
+ return word;
+ }
+ String res = convert.get(word);
+ if (res != null) {
+ return res;
+ }
+ int len = word.length();
+ if (len < 4) {
+ len = 4;
+ }
+ while (true) {
+ final StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < len; i++) {
+ final char letter = (char) ('a' + rnd.nextInt(26));
+ sb.append(letter);
+ }
+ res = sb.toString();
+ if (convert.containsValue(res) == false) {
+ convert.put(word, res);
+ return res;
+ }
+ }
+ }
+
+ public void addException(String word) {
+ except.add(word.toLowerCase());
+ }
+
+}
diff --git a/src/net/sourceforge/plantuml/version/License.java b/src/net/sourceforge/plantuml/version/License.java
index 8ebb8b8c0..6d7a0e39b 100644
--- a/src/net/sourceforge/plantuml/version/License.java
+++ b/src/net/sourceforge/plantuml/version/License.java
@@ -34,6 +34,7 @@
*/
package net.sourceforge.plantuml.version;
+import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -48,81 +49,81 @@ public enum License {
return GPL;
}
- private void addMit(final List text) {
+ private void addMit(final LicenseInfo licenseInfo, final List text) {
text.add("PlantUML is free software; you can redistribute it and/or modify it");
text.add("under the terms of the MIT License.");
- text.add("");
+ text.add(" ");
text.add("See http://opensource.org/licenses/MIT");
- text.add("");
+ text.add(" ");
text.add("Permission is hereby granted, free of charge, to any person obtaining");
text.add("a copy of this software and associated documentation files (the \"Software\"),");
text.add("to deal in the Software without restriction, including without limitation");
text.add("the rights to use, copy, modify, merge, publish, distribute, sublicense,");
text.add("and/or sell copies of the Software, and to permit persons to whom the");
text.add("Software is furnished to do so, subject to the following conditions:");
- text.add("");
+ text.add(" ");
text.add("The above copyright notice and this permission notice shall be included");
text.add("in all copies or substantial portions of the Software.");
- text.add("");
+ text.add(" ");
text.add("THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS");
text.add("OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,");
text.add("FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE");
text.add("AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,");
text.add("WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR");
text.add("IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.");
- text.add("");
- addSupplementary(text);
+ text.add(" ");
+ addSupplementary(licenseInfo, text);
text.add("the MIT License.");
- text.add("");
+ text.add(" ");
text.add("The generated images can then be used without any reference to the MIT License.");
text.add("It is not even necessary to stipulate that they have been generated with PlantUML,");
text.add("also this will be appreciate by PlantUML team.");
- text.add("");
+ text.add(" ");
text.add("There is an exception : if the textual description in PlantUML language is also covered");
text.add("by a license (like the MIT), then the generated images are logically covered");
text.add("by the very same license.");
}
- private void addEpl(final List text) {
+ private void addEpl(final LicenseInfo licenseInfo, final List text) {
text.add("PlantUML is free software; you can redistribute it and/or modify it");
text.add("under the terms of the Eclipse Public License.");
- text.add("");
+ text.add(" ");
text.add("THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC");
text.add("LICENSE (\"AGREEMENT\"). [Eclipse Public License - v 1.0]");
- text.add("");
+ text.add(" ");
text.add("ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES");
text.add("RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.");
- text.add("");
+ text.add(" ");
text.add("You may obtain a copy of the License at");
- text.add("");
+ text.add(" ");
text.add("http://www.eclipse.org/legal/epl-v10.html");
- text.add("");
+ text.add(" ");
text.add("Unless required by applicable law or agreed to in writing, software");
text.add("distributed under the License is distributed on an \"AS IS\" BASIS,");
text.add("WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.");
text.add("See the License for the specific language governing permissions and");
text.add("limitations under the License.");
- text.add("");
- addSupplementary(text);
+ text.add(" ");
+ addSupplementary(licenseInfo, text);
text.add("the Eclipse Public License.");
- text.add("");
+ text.add(" ");
text.add("The generated images can then be used without any reference to the Eclipse Public License.");
text.add("It is not even necessary to stipulate that they have been generated with PlantUML,");
text.add("also this will be appreciate by PlantUML team.");
- text.add("");
+ text.add(" ");
text.add("There is an exception : if the textual description in PlantUML language is also covered");
text.add("by a license (like the EPL), then the generated images are logically covered");
text.add("by the very same license.");
}
- private void addBsd(final List text) {
+ private void addBsd(final LicenseInfo licenseInfo, final List text) {
text.add("PlantUML is free software; you can redistribute it and/or modify it");
text.add("under the terms of the Revised BSD License.");
- text.add("");
+ text.add(" ");
text.add("All rights reserved.");
text.add("Redistribution and use in source and binary forms, with or without");
text.add("modification, are permitted provided that the following conditions are met:");
- text.add("");
+ text.add(" ");
text.add("* Redistributions of source code must retain the above copyright");
text.add(" notice, this list of conditions and the following disclaimer.");
text.add("* Redistributions in binary form must reproduce the above copyright");
@@ -131,7 +132,7 @@ public enum License {
text.add("* Neither the name of the University of California, Berkeley nor the");
text.add(" names of its contributors may be used to endorse or promote products");
text.add(" derived from this software without specific prior written permission.");
- text.add("");
+ text.add(" ");
text.add("THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY");
text.add("EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED");
text.add("WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE");
@@ -142,159 +143,180 @@ public enum License {
text.add("ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT");
text.add("(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS");
text.add("SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.");
- text.add("");
- addSupplementary(text);
+ text.add(" ");
+ addSupplementary(licenseInfo, text);
text.add("the Eclipse Public License.");
- text.add("");
+ text.add(" ");
text.add("The generated images can then be used without any reference to the Eclipse Public License.");
text.add("It is not even necessary to stipulate that they have been generated with PlantUML,");
text.add("also this will be appreciate by PlantUML team.");
- text.add("");
+ text.add(" ");
text.add("There is an exception : if the textual description in PlantUML language is also covered");
text.add("by a license (like the BSD), then the generated images are logically covered");
text.add("by the very same license.");
}
- private void addApache(final List text) {
+ private void addApache(final LicenseInfo licenseInfo, final List text) {
text.add("PlantUML is free software; you can redistribute it and/or modify it");
text.add("under the terms of the Apache Software License.");
- text.add("");
+ text.add(" ");
text.add("Licensed under the Apache License, Version 2.0 (the \"License\");");
text.add("you may not use this file except in compliance with the License.");
text.add("You may obtain a copy of the License at");
- text.add("");
+ text.add(" ");
text.add("http://www.apache.org/licenses/LICENSE-2.0");
- text.add("");
+ text.add(" ");
text.add("Unless required by applicable law or agreed to in writing, software");
text.add("distributed under the License is distributed on an \"AS IS\" BASIS,");
text.add("WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.");
text.add("See the License for the specific language governing permissions and");
text.add("limitations under the License.");
- text.add("");
- addSupplementary(text);
+ text.add(" ");
+ addSupplementary(licenseInfo, text);
text.add("the Apache license.");
- text.add("");
+ text.add(" ");
text.add("The generated images can then be used without any reference to the Apache license.");
text.add("It is not even necessary to stipulate that they have been generated with PlantUML,");
text.add("also this will be appreciate by PlantUML team.");
- text.add("");
+ text.add(" ");
text.add("There is an exception : if the textual description in PlantUML language is also covered");
text.add("by a license (like the Apache), then the generated images are logically covered");
text.add("by the very same license.");
}
- private void addGpl(final List text) {
+ private void addGpl(final LicenseInfo licenseInfo, final List text) {
text.add("PlantUML is free software; you can redistribute it and/or modify it");
text.add("under the terms of the GNU General Public License as published by");
text.add("the Free Software Foundation, either version 3 of the License, or");
text.add("(at your option) any later version.");
- text.add("");
+ text.add(" ");
text.add("PlantUML distributed in the hope that it will be useful, but");
text.add("WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY");
text.add("or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public");
text.add("License for more details.");
- text.add("");
+ text.add(" ");
text.add("You should have received a copy of the GNU General Public");
text.add("License along with this library; if not, write to the Free Software");
text.add("Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,");
text.add("USA.");
- text.add("");
- addSupplementary(text);
+ text.add(" ");
+ addSupplementary(licenseInfo, text);
text.add("the GPL license.");
- text.add("");
+ text.add(" ");
text.add("The generated images can then be used without any reference to the GPL license.");
text.add("It is not even necessary to stipulate that they have been generated with PlantUML,");
text.add("also this will be appreciate by PlantUML team.");
- text.add("");
+ text.add(" ");
text.add("There is an exception : if the textual description in PlantUML language is also covered");
text.add("by a license (like the GPL), then the generated images are logically covered");
text.add("by the very same license.");
}
- private void addGplV2(final List text) {
+ private void addGplV2(final LicenseInfo licenseInfo, final List text) {
text.add("PlantUML is free software; you can redistribute it and/or modify it");
text.add("under the terms of the GNU General Public License as published by");
text.add("the Free Software Foundation, either version 2 of the License, or");
text.add("(at your option) any later version.");
- text.add("");
+ text.add(" ");
text.add("PlantUML distributed in the hope that it will be useful, but");
text.add("WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY");
text.add("or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public");
text.add("License for more details.");
- text.add("");
+ text.add(" ");
text.add("You should have received a copy of the GNU General Public");
text.add("License along with this library; if not, write to the Free Software");
text.add("Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,");
text.add("USA.");
- text.add("");
- addSupplementary(text);
+ text.add(" ");
+ addSupplementary(licenseInfo, text);
text.add("the GPL license.");
- text.add("");
+ text.add(" ");
text.add("The generated images can then be used without any reference to the GPL license.");
text.add("It is not even necessary to stipulate that they have been generated with PlantUML,");
text.add("also this will be appreciate by PlantUML team.");
- text.add("");
+ text.add(" ");
text.add("There is an exception : if the textual description in PlantUML language is also covered");
text.add("by a license (like the GPL), then the generated images are logically covered");
text.add("by the very same license.");
}
- private void addLgpl(final List text) {
+ private void addLgpl(final LicenseInfo licenseInfo, final List text) {
text.add("PlantUML is free software; you can redistribute it and/or modify it");
text.add("under the terms of the GNU Lesser General Public License as published by");
text.add("the Free Software Foundation, either version 3 of the License, or");
text.add("(at your option) any later version.");
- text.add("");
+ text.add(" ");
text.add("PlantUML distributed in the hope that it will be useful, but");
text.add("WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY");
text.add("or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public");
text.add("License for more details.");
- text.add("");
+ text.add(" ");
text.add("You should have received a copy of the GNU Lesser General Public");
text.add("License along with this library; if not, write to the Free Software");
text.add("Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,");
text.add("USA.");
- text.add("");
- addSupplementary(text);
+ text.add(" ");
+ addSupplementary(licenseInfo, text);
text.add("the LGPL license.");
- text.add("");
+ text.add(" ");
text.add("The generated images can then be used without any reference to the LGPL license.");
text.add("It is not even necessary to stipulate that they have been generated with PlantUML,");
text.add("although this will be appreciate by PlantUML team.");
- text.add("");
+ text.add(" ");
text.add("There is an exception : if the textual description in PlantUML language is also covered");
text.add("by a license (like the LGPL), then the generated images are logically covered");
text.add("by the very same license.");
}
- private void addSupplementary(final List text) {
- text.add("PlantUML can occasionally display sponsored or advertising messages. Those");
- text.add("messages are usually generated on welcome or error images and never on");
- text.add("functional diagrams.");
- text.add(" ");
+ private void addSupplementary(final LicenseInfo licenseInfo, final List text) {
+ if (licenseInfo.isValid() == false) {
+ text.add("PlantUML can occasionally display sponsored or advertising messages. Those");
+ text.add("messages are usually generated on welcome or error images and never on");
+ text.add("functional diagrams.");
+ text.add(" ");
+ }
text.add("Images (whatever their format : PNG, SVG, EPS...) generated by running PlantUML");
text.add("are owned by the author of their corresponding sources code (that is, their");
text.add("textual description in PlantUML language). Those images are not covered by");
}
- private List getHeaderStart() {
+ private List getHeaderStart(LicenseInfo licenseInfo) {
final List text = new ArrayList();
- text.add("========================================================================");
- text.add("PlantUML : a free UML diagram generator");
- text.add("========================================================================");
- text.add("");
+ if (licenseInfo.isNone()) {
+ text.add("========================================================================");
+ text.add("PlantUML : a free UML diagram generator");
+ text.add("========================================================================");
+ text.add(" ");
+ } else {
+ text.add("========================================================================");
+ text.add("This is PlantUML Professional Edition");
+ text.add("========================================================================");
+ addLicenseInfo(text, licenseInfo);
+ text.add("========================================================================");
+ text.add(" ");
+ }
text.add("(C) Copyright 2009-2017, Arnaud Roques");
- text.add("");
+ text.add(" ");
text.add("Project Info: http://plantuml.com");
- text.add("");
- text.add("If you like this project or if you find it useful, you can support us at:");
- text.add("");
- text.add("http://plantuml.com/patreon (only 1$ per month!)");
- text.add("http://plantuml.com/paypal");
- text.add("");
+ text.add(" ");
+ if (licenseInfo.isValid() == false) {
+ text.add("If you like this project or if you find it useful, you can support us at:");
+ text.add(" ");
+ text.add("http://plantuml.com/patreon (only 1$ per month!)");
+ text.add("http://plantuml.com/paypal");
+ text.add(" ");
+ }
return text;
}
+ public static void addLicenseInfo(final List text, LicenseInfo licenseInfo) {
+ text.add("LICENSED TO : " + licenseInfo.getOwner());
+ text.add("EXPIRATION DATE : " + DateFormat.getDateInstance().format(licenseInfo.getExpirationDate()));
+ if (licenseInfo.hasExpired()) {
+ text.add("Warning: Your license has expired.");
+ }
+ }
+
public List getJavaHeader() {
final List h = new ArrayList();
h.add("/* ========================================================================");
@@ -430,30 +452,31 @@ public enum License {
}
public List getText() {
- final List text = getHeaderStart();
+ final LicenseInfo licenseInfo = LicenseInfo.retrieveSlow();
+ final List text = getHeaderStart(licenseInfo);
if (this == License.GPL) {
- addGpl(text);
+ addGpl(licenseInfo, text);
} else if (this == License.GPLV2) {
- addGplV2(text);
+ addGplV2(licenseInfo, text);
} else if (this == License.MIT) {
- addMit(text);
+ addMit(licenseInfo, text);
} else if (this == License.EPL) {
- addEpl(text);
+ addEpl(licenseInfo, text);
} else if (this == License.BSD) {
- addBsd(text);
+ addBsd(licenseInfo, text);
} else if (this == License.APACHE) {
- addApache(text);
+ addApache(licenseInfo, text);
} else if (this == License.LGPL) {
- addLgpl(text);
+ addLgpl(licenseInfo, text);
} else {
throw new IllegalStateException();
}
if (OptionFlags.getInstance().isEnableStats()) {
- text.add("");
+ text.add(" ");
text.add("This version of PlantUML records general local statistics about usage.");
text.add("(more info on http://plantuml.com/statistics-report)");
}
- text.add("");
+ text.add(" ");
text.add("Icons provided by OpenIconic : https://useiconic.com/open");
text.add("Archimate sprites provided by Archi : http://www.archimatetool.com");
text.add("Stdlib AWS provided by https://github.com/milo-minderbinder/AWS-PlantUML");
@@ -462,8 +485,7 @@ public enum License {
text.add("ASCIIMathML (c) David Lippman http://www.pierce.ctc.edu/dlippman");
text.add("CafeUndZopfli ported by Eugene Klyuchnikov https://github.com/eustas/CafeUndZopfli");
text.add("Brotli (c) by the Brotli Authors https://github.com/google/brotli");
- text.add("");
+ text.add(" ");
return text;
}
-
}
diff --git a/src/net/sourceforge/plantuml/version/LicenseInfo.java b/src/net/sourceforge/plantuml/version/LicenseInfo.java
new file mode 100644
index 000000000..1f842c496
--- /dev/null
+++ b/src/net/sourceforge/plantuml/version/LicenseInfo.java
@@ -0,0 +1,221 @@
+/* ========================================================================
+ * PlantUML : a free UML diagram generator
+ * ========================================================================
+ *
+ * (C) Copyright 2009-2017, Arnaud Roques
+ *
+ * Project Info: http://plantuml.com
+ *
+ * If you like this project or if you find it useful, you can support us at:
+ *
+ * http://plantuml.com/patreon (only 1$ per month!)
+ * http://plantuml.com/paypal
+ *
+ * This file is part of PlantUML.
+ *
+ * PlantUML is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PlantUML distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ *
+ *
+ * Original Author: Arnaud Roques
+ *
+ */
+package net.sourceforge.plantuml.version;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.NoSuchAlgorithmException;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.prefs.BackingStoreException;
+import java.util.prefs.Preferences;
+
+import net.sourceforge.plantuml.Log;
+import net.sourceforge.plantuml.SignatureUtils;
+import net.sourceforge.plantuml.dedication.Dedication;
+import net.sourceforge.plantuml.dedication.QBlock;
+
+public class LicenseInfo {
+
+ private final static Preferences prefs = Preferences.userNodeForPackage(LicenseInfo.class);
+ private final static LicenseInfo NONE = new LicenseInfo();
+
+ public static final int POS_TYPE = 2;
+ public static final int POS_SIGNATURE = 10;
+ public static final int POS_GENERATION = 100;
+ public static final int POS_EXPIRATION = 108;
+ public static final int POS_OWNER = 128;
+
+ private final long generationDate;
+ private final long expirationDate;
+ private final String owner;
+
+ private LicenseInfo() {
+ this.expirationDate = 0;
+ this.generationDate = 0;
+ this.owner = null;
+ }
+
+ private LicenseInfo(Magic magic) throws NoSuchAlgorithmException, IOException {
+ final String signature = SignatureUtils.toHexString(magic.get(LicenseInfo.POS_SIGNATURE, 64));
+ final String local = SignatureUtils.toHexString(Magic.signature());
+ if (local.equals(signature) == false) {
+ throw new IOException();
+ }
+ final int type = magic.getByte(Magic.signature(), LicenseInfo.POS_TYPE);
+ this.generationDate = bytesToLong(magic.get(LicenseInfo.POS_GENERATION, 8));
+ this.expirationDate = bytesToLong(magic.get(LicenseInfo.POS_EXPIRATION, 8));
+ this.owner = magic.getString(LicenseInfo.POS_OWNER);
+ }
+
+ public static long bytesToLong(byte[] b) {
+ long result = 0;
+ for (int i = 0; i < 8; i++) {
+ result <<= 8;
+ result |= (b[i] & 0xFF);
+ }
+ return result;
+ }
+
+ public static void persistMe(String key) throws BackingStoreException {
+ prefs.sync();
+ prefs.put("license", key);
+ }
+
+ private static LicenseInfo cache;
+
+ public static synchronized LicenseInfo retrieveQuick() {
+ if (cache == null) {
+ return retrieveSlow();
+ }
+ return cache;
+ }
+
+ public static synchronized LicenseInfo retrieveSlow() {
+ cache = LicenseInfo.NONE;
+ final String key = prefs.get("license", "");
+ if (key.length() > 0) {
+ cache = setIfValid(retrieve(key), cache);
+ if (cache.isValid()) {
+ return cache;
+ }
+ }
+ for (File f : fileCandidates()) {
+ try {
+ if (f.exists() && f.canRead()) {
+ final LicenseInfo result = retrieve(f);
+ cache = setIfValid(result, cache);
+ if (cache.isValid()) {
+ return cache;
+ }
+ }
+ } catch (IOException e) {
+ Log.info("Error " + e);
+ // e.printStackTrace();
+ }
+ }
+ return cache;
+ }
+
+ private static LicenseInfo setIfValid(LicenseInfo value, LicenseInfo def) {
+ if (value.isValid() || def.isNone()) {
+ return value;
+ }
+ return def;
+ }
+
+ private static LicenseInfo retrieve(File f) throws IOException {
+ final BufferedReader br = new BufferedReader(new FileReader(f));
+ final String s = br.readLine();
+ br.close();
+ final LicenseInfo result = retrieve(s);
+ if (result != null) {
+ Log.info("Reading license from " + f.getAbsolutePath());
+ }
+ return result;
+ }
+
+ public static LicenseInfo retrieve(final String key) {
+ if (key.matches("^[0-9a-z]+$")) {
+ try {
+ final BigInteger lu = new BigInteger(key, 36);
+ final QBlock qb2 = new QBlock(lu);
+ final QBlock qb3 = qb2.change(Dedication.E, Dedication.N);
+ final Magic magic = qb3.toMagic();
+
+ final String sig = SignatureUtils.toHexString(Magic.signature());
+ magic.xor(SignatureUtils.getSHA512raw(SignatureUtils.salting(sig, Magic.getSalt(sig))));
+ return new LicenseInfo(magic);
+ } catch (Exception e) {
+ // e.printStackTrace();
+ Log.info("Error " + e);
+ }
+ }
+ return LicenseInfo.NONE;
+ }
+
+ public static Collection fileCandidates() {
+ final Set result = new TreeSet();
+ final String classpath = System.getProperty("java.class.path");
+ String[] classpathEntries = classpath.split(File.pathSeparator);
+ for (String s : classpathEntries) {
+ File dir = new File(s);
+ if (dir.isFile()) {
+ dir = dir.getParentFile();
+ }
+ if (dir.isDirectory()) {
+ result.add(new File(dir, "license.txt"));
+ }
+ }
+ return result;
+ }
+
+ public static void main(String[] args) {
+ LicenseInfo info = retrieveSlow();
+ System.err.println("valid=" + info.isValid());
+ System.err.println("info=" + info.owner);
+
+ }
+
+ public final Date getGenerationDate() {
+ return new Date(generationDate);
+ }
+
+ public final Date getExpirationDate() {
+ return new Date(expirationDate);
+ }
+
+ public final String getOwner() {
+ return owner;
+ }
+
+ public boolean isNone() {
+ return owner == null;
+ }
+
+ public boolean isValid() {
+ return owner != null && System.currentTimeMillis() <= this.expirationDate;
+ }
+
+ public boolean hasExpired() {
+ return owner != null && System.currentTimeMillis() > this.expirationDate;
+ }
+
+}
diff --git a/src/net/sourceforge/plantuml/version/Magic.java b/src/net/sourceforge/plantuml/version/Magic.java
new file mode 100644
index 000000000..a5e7d2c8e
--- /dev/null
+++ b/src/net/sourceforge/plantuml/version/Magic.java
@@ -0,0 +1,192 @@
+/* ========================================================================
+ * PlantUML : a free UML diagram generator
+ * ========================================================================
+ *
+ * (C) Copyright 2009-2017, Arnaud Roques
+ *
+ * Project Info: http://plantuml.com
+ *
+ * If you like this project or if you find it useful, you can support us at:
+ *
+ * http://plantuml.com/patreon (only 1$ per month!)
+ * http://plantuml.com/paypal
+ *
+ * This file is part of PlantUML.
+ *
+ * PlantUML is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PlantUML distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ *
+ *
+ * Original Author: Arnaud Roques
+ *
+ */
+package net.sourceforge.plantuml.version;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.NetworkInterface;
+import java.security.NoSuchAlgorithmException;
+import java.util.Enumeration;
+import java.util.Random;
+
+import net.sourceforge.plantuml.OptionPrint;
+import net.sourceforge.plantuml.SignatureUtils;
+import net.sourceforge.plantuml.dedication.TurningBytes;
+
+public class Magic {
+
+ private final byte buffer[] = new byte[512];
+
+ @Override
+ public String toString() {
+ return SignatureUtils.toString(buffer);
+ }
+
+ public String toHexString() {
+ return SignatureUtils.toHexString(buffer);
+ }
+
+ private void xor(TurningBytes turningBytes) {
+ for (int i = 0; i < buffer.length; i++) {
+ buffer[i] ^= turningBytes.nextByte();
+ }
+ }
+
+ public void xor(byte[] key) {
+ xor(new TurningBytes(key));
+ }
+
+ public static Magic fromHexString(String s) {
+ if (s.length() != 1024) {
+ throw new IllegalArgumentException();
+ }
+ final Magic result = new Magic();
+ for (int i = 0; i < 512; i++) {
+ result.buffer[i] = (byte) (Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16) & 0xFF);
+ }
+ return result;
+ }
+
+ public final byte[] getBuffer() {
+ return buffer;
+ }
+
+ public void setByte(byte[] shrink, int pos, int data) {
+ buffer[pos] = (byte) (0xFF & (data ^ shrink(shrink)));
+ }
+
+ public int getByte(byte[] shrink, int pos) {
+ return buffer[pos] ^ shrink(shrink);
+ }
+
+ public void set(int pos, byte[] data) {
+ for (int i = 0; i < data.length; i++) {
+ buffer[pos + i] = data[i];
+ }
+ }
+
+ public void setString(int pos, String s) throws UnsupportedEncodingException, NoSuchAlgorithmException {
+ final byte[] tmp = s.getBytes("UTF-8");
+ buffer[pos] = (byte) tmp.length;
+ set(pos + 1, tmp);
+ // set(pos + 1 + tmp.length, SignatureUtils.getSHA512raw(s));
+ }
+
+ public String getString(int pos) throws UnsupportedEncodingException, NoSuchAlgorithmException {
+ final int len = buffer[pos];
+ if (len < 0 || len > 127) {
+ throw new IllegalArgumentException();
+ }
+ final String result = new String(get(pos + 1, len), "UTF-8");
+ // if (isEquals(SignatureUtils.getSHA512raw(result), get(pos + 1 + len, 64)) == false) {
+ // throw new UnsupportedEncodingException();
+ // }
+ return result;
+ }
+
+ public byte[] get(int pos, int len) {
+ final byte result[] = new byte[len];
+ System.arraycopy(buffer, pos, result, 0, len);
+ return result;
+ }
+
+ private boolean isEquals(byte data1[], byte[] data2) {
+ if (data1.length != data2.length) {
+ return false;
+ }
+ for (int i = 0; i < data1.length; i++) {
+ if (data1[i] != data2[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static byte[] signature() throws IOException {
+ final String signature = OptionPrint.getHostName() + getMacAddress();
+ try {
+ return SignatureUtils.getSHA512raw(SignatureUtils.salting(signature, getSalt(signature)));
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new IOException();
+ }
+ }
+
+ public static byte shrink(byte data[]) {
+ byte result = 42;
+ for (byte b : data) {
+ result ^= b;
+ }
+ return result;
+ }
+
+ public static byte[] getSalt(final String signature) throws UnsupportedEncodingException {
+ final Random rnd = new Random(getSeed(signature.getBytes("UTF-8")));
+ final byte salt[] = new byte[512];
+ rnd.nextBytes(salt);
+ return salt;
+ }
+
+ private static long getSeed(byte[] bytes) {
+ long result = 19;
+ for (byte b : bytes) {
+ result = result * 41 + b;
+ }
+ return result;
+ }
+
+ private static String getMacAddress() throws IOException {
+
+ final Enumeration net = NetworkInterface.getNetworkInterfaces();
+ final StringBuilder result = new StringBuilder();
+ while (net.hasMoreElements()) {
+ final NetworkInterface element = net.nextElement();
+ byte[] mac = element.getHardwareAddress();
+ if (mac != null) {
+ for (byte b : mac) {
+ result.append(String.format("%02x", b));
+ }
+ }
+ }
+ return result.toString();
+ }
+
+ public static void main(String[] args) throws IOException {
+ System.err.println(SignatureUtils.toHexString(signature()));
+ System.out.println("Mac: " + getMacAddress());
+
+ }
+
+}
diff --git a/src/net/sourceforge/plantuml/version/PSystemKeygen.java b/src/net/sourceforge/plantuml/version/PSystemKeygen.java
new file mode 100644
index 000000000..2693ac8d5
--- /dev/null
+++ b/src/net/sourceforge/plantuml/version/PSystemKeygen.java
@@ -0,0 +1,169 @@
+/* ========================================================================
+ * PlantUML : a free UML diagram generator
+ * ========================================================================
+ *
+ * (C) Copyright 2009-2017, Arnaud Roques
+ *
+ * Project Info: http://plantuml.com
+ *
+ * If you like this project or if you find it useful, you can support us at:
+ *
+ * http://plantuml.com/patreon (only 1$ per month!)
+ * http://plantuml.com/paypal
+ *
+ * This file is part of PlantUML.
+ *
+ * PlantUML is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PlantUML distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ *
+ *
+ * Original Author: Arnaud Roques
+ *
+ */
+package net.sourceforge.plantuml.version;
+
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.prefs.BackingStoreException;
+
+import net.sourceforge.plantuml.AbstractPSystem;
+import net.sourceforge.plantuml.FileFormatOption;
+import net.sourceforge.plantuml.SignatureUtils;
+import net.sourceforge.plantuml.core.DiagramDescription;
+import net.sourceforge.plantuml.core.ImageData;
+import net.sourceforge.plantuml.flashcode.FlashCodeFactory;
+import net.sourceforge.plantuml.flashcode.FlashCodeUtils;
+import net.sourceforge.plantuml.graphic.GraphicStrings;
+import net.sourceforge.plantuml.graphic.HtmlColorUtils;
+import net.sourceforge.plantuml.graphic.TextBlock;
+import net.sourceforge.plantuml.graphic.UDrawable;
+import net.sourceforge.plantuml.ugraphic.ColorMapperIdentity;
+import net.sourceforge.plantuml.ugraphic.ImageBuilder;
+import net.sourceforge.plantuml.ugraphic.UGraphic;
+import net.sourceforge.plantuml.ugraphic.UImage;
+import net.sourceforge.plantuml.ugraphic.UTranslate;
+
+public class PSystemKeygen extends AbstractPSystem {
+
+ final private String key;
+
+ public PSystemKeygen(String key) {
+ this.key = key;
+ }
+
+ @Override
+ final protected ImageData exportDiagramNow(OutputStream os, int num, FileFormatOption fileFormat, long seed)
+ throws IOException {
+ final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, HtmlColorUtils.WHITE,
+ getMetadata(), null, 0, 0, null, false);
+
+ imageBuilder.setUDrawable(new UDrawable() {
+ public void drawU(UGraphic ug) {
+ try {
+ drawInternal(ug);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ });
+ return imageBuilder.writeImageTOBEMOVED(fileFormat, seed, os);
+ }
+
+ public DiagramDescription getDescription() {
+ return new DiagramDescription("(Genkey)");
+ }
+
+ private void drawInternal(UGraphic ug) throws IOException {
+ if (key.length() == 0) {
+ drawFlash(ug);
+ return;
+ }
+ final LicenseInfo info = LicenseInfo.retrieve(key);
+ if (info.isNone()) {
+ drawFlash(ug);
+ return;
+ }
+ final List strings = header();
+ strings.add("Provided license information:");
+ License.addLicenseInfo(strings, info);
+ strings.add(" ");
+ strings.add("========================================================================");
+ try {
+ LicenseInfo.persistMe(key);
+ } catch (BackingStoreException e) {
+ strings.add("Error: Cannot store license key.");
+ }
+
+ final LicenseInfo installed = LicenseInfo.retrieveSlow();
+ if (installed.isNone()) {
+ strings.add("No license currently installed.");
+ strings.add(" ");
+ strings.add("Please copy license.txt to one of those files:");
+ for (File f : LicenseInfo.fileCandidates()) {
+ strings.add(f.getAbsolutePath());
+ }
+ strings.add(" ");
+ } else {
+ strings.add("Installed license:");
+ License.addLicenseInfo(strings, installed);
+ strings.add(" ");
+ }
+
+ final TextBlock disp = GraphicStrings.createBlackOnWhite(strings);
+ disp.drawU(ug);
+ }
+
+ private ArrayList header() {
+ final ArrayList strings = new ArrayList();
+ strings.add("PlantUML version " + Version.versionString() + " (" + Version.compileTimeString() + ")");
+ strings.add("(" + License.getCurrent() + " source distribution)");
+ strings.add("Loaded from " + Version.getJarPath());
+ strings.add(" ");
+ return strings;
+ }
+
+ public void drawFlash(UGraphic ug) throws IOException {
+ final List strings = header();
+ strings.add("To get your Professional Edition License,");
+ strings.add("please send this flashcode to plantuml@gmail.com :");
+
+ TextBlock disp = GraphicStrings.createBlackOnWhite(strings);
+ disp.drawU(ug);
+
+ ug = ug.apply(new UTranslate(0, disp.calculateDimension(ug.getStringBounder()).getHeight()));
+ final FlashCodeUtils utils = FlashCodeFactory.getFlashCodeUtils();
+ final BufferedImage im = utils.exportFlashcode(Version.versionString() + "\n"
+ + SignatureUtils.toHexString(Magic.signature()));
+ final UImage flash = new UImage(im).scaleNearestNeighbor(4);
+ ug.draw(flash);
+
+ ug = ug.apply(new UTranslate(0, flash.getHeight()));
+
+ final LicenseInfo info = LicenseInfo.retrieveSlow();
+ if (info.isNone() == false) {
+ strings.clear();
+ strings.add("Installed license:");
+ License.addLicenseInfo(strings, info);
+ strings.add(" ");
+ disp = GraphicStrings.createBlackOnWhite(strings);
+ disp.drawU(ug);
+ }
+
+ }
+}
diff --git a/src/net/sourceforge/plantuml/version/PSystemVersionFactory.java b/src/net/sourceforge/plantuml/version/PSystemVersionFactory.java
index 0f6a0ba70..a492e4ff7 100644
--- a/src/net/sourceforge/plantuml/version/PSystemVersionFactory.java
+++ b/src/net/sourceforge/plantuml/version/PSystemVersionFactory.java
@@ -62,6 +62,11 @@ public class PSystemVersionFactory extends PSystemSingleLineFactory {
if (line.matches("(?i)^checkversion\\s*$")) {
return PSystemVersion.createCheckVersions(null, null);
}
+ if (line.matches("(?i)^keygen(\\s+[0-9a-z]+)?\\s*$")) {
+ line = line.trim();
+ final String key = line.substring("keygen".length()).trim();
+ return new PSystemKeygen(key);
+ }
final Pattern p1 = Pattern.compile("(?i)^checkversion\\(proxy=([\\w.]+),port=(\\d+)\\)$");
final Matcher m1 = p1.matcher(line);
if (m1.matches()) {
diff --git a/src/net/sourceforge/plantuml/version/Professionnal.java b/src/net/sourceforge/plantuml/version/Professionnal.java
deleted file mode 100644
index edd9827f3..000000000
--- a/src/net/sourceforge/plantuml/version/Professionnal.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/* ========================================================================
- * PlantUML : a free UML diagram generator
- * ========================================================================
- *
- * (C) Copyright 2009-2017, Arnaud Roques
- *
- * Project Info: http://plantuml.com
- *
- * If you like this project or if you find it useful, you can support us at:
- *
- * http://plantuml.com/patreon (only 1$ per month!)
- * http://plantuml.com/paypal
- *
- * This file is part of PlantUML.
- *
- * PlantUML is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * PlantUML distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
- * License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA.
- *
- *
- * Original Author: Arnaud Roques
- *
- */
-package net.sourceforge.plantuml.version;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Date;
-import java.util.prefs.Preferences;
-
-import net.sourceforge.plantuml.OptionPrint;
-import net.sourceforge.plantuml.dedication.DecoderInputStream;
-import net.sourceforge.plantuml.dedication.Dedication;
-import net.sourceforge.plantuml.dedication.QBlocks;
-
-public class Professionnal {
-
- final private static Preferences prefs = Preferences.userNodeForPackage(Professionnal.class);
-
- private final String hostname;
- private final String organization;
- private final String mail;
- private final Date date1;
- private final Date date2;
-
- private Professionnal(String hostname, String organization, String mail, int date1, int date2) {
- this.hostname = hostname;
- this.organization = organization;
- this.mail = mail;
- this.date1 = new Date(date1 * 1000L);
- this.date2 = new Date(date2 * 1000L);
- }
-
- public static Professionnal decodeNow(final String license) throws IOException {
- final QBlocks data = QBlocks.descodeAscii(license);
- final QBlocks decrypted = data.change(Dedication.E, Dedication.N);
-
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- decrypted.writeTo(baos, Dedication.SIZE);
- baos.close();
-
- final String hostname = OptionPrint.getHostName();
- InputStream source1 = null;
- try {
- source1 = new DecoderInputStream(new ByteArrayInputStream(baos.toByteArray()), hostname);
- final DataInputStream src = new DataInputStream(source1);
- final int version = src.readByte();
- if (version != 42) {
- throw new IOException();
- }
- final String host1 = src.readUTF();
- final String organization = src.readUTF();
- final String mail = src.readUTF();
- final int date1 = src.readInt();
- final int date2 = src.readInt();
-
- return new Professionnal(host1, organization, mail, date1, date2);
- } finally {
- if (source1 != null) {
- source1.close();
- }
- }
- }
-
- public String getHostname() {
- return hostname;
- }
-
- public String getMail() {
- return mail;
- }
-
- public String getOrganization() {
- return organization;
- }
-
- public Date getDate1() {
- return date1;
- }
-
- public Date getDate2() {
- return date2;
- }
-
-}
diff --git a/src/net/sourceforge/plantuml/version/Version.java b/src/net/sourceforge/plantuml/version/Version.java
index 29050566d..8bc63d19c 100644
--- a/src/net/sourceforge/plantuml/version/Version.java
+++ b/src/net/sourceforge/plantuml/version/Version.java
@@ -43,7 +43,7 @@ public class Version {
private static final int MAJOR_SEPARATOR = 1000000;
public static int version() {
- return 1201808;
+ return 1201809;
}
public static int versionPatched() {
@@ -88,7 +88,7 @@ public class Version {
}
public static long compileTime() {
- return 1529843460982L;
+ return 1532710698423L;
}
public static String compileTimeString() {
diff --git a/stdlib/cloudogu-abx.repx b/stdlib/cloudogu-abx.repx
new file mode 100644
index 000000000..7bf0221c1
Binary files /dev/null and b/stdlib/cloudogu-abx.repx differ
diff --git a/stdlib/cloudogu-dex.repx b/stdlib/cloudogu-dex.repx
new file mode 100644
index 000000000..fd6dbd42e
Binary files /dev/null and b/stdlib/cloudogu-dex.repx differ
diff --git a/stdlib/home.repx b/stdlib/home.repx
index 582fbbff8..81206b6be 100644
--- a/stdlib/home.repx
+++ b/stdlib/home.repx
@@ -1,5 +1,6 @@
aws
cloudinsight
+cloudogu
devicons
font-awesome
material