1
0
mirror of https://github.com/octoleo/plantuml.git synced 2024-11-24 13:57:33 +00:00

version 1.2018.14

This commit is contained in:
Arnaud Roques 2018-12-22 12:11:40 +01:00
parent 3736d048b3
commit 3ecadf6bd5
108 changed files with 4305 additions and 610 deletions

View File

@ -30,13 +30,12 @@
Script Author: Julien Eluard
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.sourceforge.plantuml</groupId>
<artifactId>plantuml</artifactId>
<version>1.2018.13-SNAPSHOT</version>
<version>1.2018.15-SNAPSHOT</version>
<packaging>jar</packaging>
<name>PlantUML</name>

View File

@ -35,54 +35,48 @@
*/
package net.sourceforge.plantuml;
public class QString {
public class ErrorStatus {
private final String data;
private final long mask;
private boolean noData;
private boolean hasErrors;
private boolean hasOk;
public QString(String data) {
this.data = data;
this.mask = getMask(data);
}
@Override
public String toString() {
return data;
private ErrorStatus() {
this.noData = true;
}
public boolean containsQ(QString other) {
if ((this.mask & other.mask) != other.mask) {
return false;
}
return this.data.contains(other.data);
public static ErrorStatus init() {
return new ErrorStatus();
}
static long getMask(String s) {
long result = 0;
for (int i = 0; i < s.length(); i++) {
result |= getMask(s.charAt(i));
}
return result;
// public synchronized void goNoData() {
// this.noData = true;
// }
public synchronized void goWithError() {
this.hasErrors = true;
this.noData = false;
}
static long getMask(char c) {
if (c >= '0' && c <= '9') {
final int n = c - '0';
return 1L << n;
public synchronized void goOk() {
this.hasOk = true;
this.noData = false;
}
public synchronized boolean hasError() {
return hasErrors;
}
public synchronized boolean isNoData() {
return noData;
}
public int getExitCode() {
if (isNoData()) {
return 100;
}
if (c >= 'a' && c <= 'z') {
final int n = c - 'a' + 10;
return 1L << n;
}
if (c >= 'A' && c <= 'Z') {
final int n = c - 'A' + 10 + 26;
return 1L << n;
}
if (c == '_') {
return 1L << (10 + 26 + 26);
}
if (c == '(') {
return 1L << 63;
if (hasErrors) {
return 200;
}
return 0;
}

View File

@ -68,7 +68,8 @@ public interface ISkinParam extends ISkinSimple {
public UFont getFont(Stereotype stereotype, boolean inPackageTitle, FontParam... fontParam);
public HorizontalAlignment getHorizontalAlignment(AlignmentParam param, ArrowDirection arrowDirection, boolean isReverseDefine);
public HorizontalAlignment getHorizontalAlignment(AlignmentParam param, ArrowDirection arrowDirection,
boolean isReverseDefine);
public HorizontalAlignment getDefaultTextAlignment(HorizontalAlignment defaultValue);
@ -80,8 +81,6 @@ public interface ISkinParam extends ISkinSimple {
public DotSplines getDotSplines();
public String getDotExecutable();
public boolean shadowing(Stereotype stereotype);
public boolean shadowingForNote(Stereotype stereotype);
@ -157,7 +156,11 @@ public interface ISkinParam extends ISkinSimple {
public boolean responseMessageBelowArrow();
public boolean svgDimensionStyle();
public boolean fixCircleLabelOverlapping();
public void setUseVizJs(boolean useVizJs);
public boolean isUseVizJs();
}

View File

@ -80,6 +80,7 @@ public class Option {
private int ftpPort = -1;
private boolean hideMetadata = false;
private boolean checkMetadata = false;
private int stdrpt = 0;
private int imageIndex = 0;
private File outputDir = null;
@ -344,6 +345,10 @@ public class Option {
preprocessorOutput = OptionPreprocOutputMode.CYPHER;
} else if (s.equalsIgnoreCase("-checkmetadata")) {
checkMetadata = true;
} else if (s.equalsIgnoreCase("-stdrpt:1")) {
stdrpt = 1;
} else if (s.equalsIgnoreCase("-stdrpt")) {
stdrpt = 1;
} else if (s.equalsIgnoreCase("-pipeimageindex")) {
i++;
if (i == arg.length) {
@ -369,6 +374,17 @@ public class Option {
}
}
public Stdrpt getStdrpt() {
if (stdrpt == 1) {
return new StdrptV1();
}
// Legacy case
if (isPipe() || isPipeMap() || isSyntax()) {
return new StdrptPipe0();
}
return new StdrptNull();
}
public int getFtpPort() {
return ftpPort;
}
@ -445,7 +461,7 @@ public class Option {
public Defines getDefaultDefines(File f) {
final Defines result = Defines.createWithFileName(f);
for (Map.Entry<String, String> ent : defines.entrySet()) {
result.define(ent.getKey(), Arrays.asList(ent.getValue()), false);
result.define(ent.getKey(), Arrays.asList(ent.getValue()), false, null);
}
return result;
}
@ -454,7 +470,7 @@ public class Option {
final Defines result = Defines.createEmpty();
result.overrideFilename(filename);
for (Map.Entry<String, String> ent : defines.entrySet()) {
result.define(ent.getKey(), Arrays.asList(ent.getValue()), false);
result.define(ent.getKey(), Arrays.asList(ent.getValue()), false, null);
}
return result;
}

View File

@ -160,7 +160,7 @@ public class OptionPrint {
}
public static void printLicense() throws InterruptedException {
for (String s : License.getCurrent().getText(false)) {
for (String s : License.getCurrent().getTextFull()) {
System.out.println(s);
}
exit();

View File

@ -155,6 +155,7 @@ public class PSystemError extends AbstractPSystem {
udrawable = result;
}
final int min = (int) (System.currentTimeMillis() / 60000L) % 60;
// udrawable = addMessageAdopt(udrawable);
if (min == 1 && LicenseInfo.retrieveNamedOrDistributorQuickIsValid() == false) {
udrawable = addMessagePatreon(udrawable);
} else if (min == 15 && LicenseInfo.retrieveNamedOrDistributorQuickIsValid() == false) {
@ -199,6 +200,12 @@ public class PSystemError extends AbstractPSystem {
return result;
}
private TextBlock addMessageAdopt(final TextBlock source) throws IOException {
final TextBlock message = getMessageAdopt();
TextBlock result = TextBlockUtils.mergeTB(message, source, HorizontalAlignment.LEFT);
return result;
}
private TextBlock addMessageArecibo(final TextBlock source) throws IOException {
final UImage message = new UImage(PSystemVersion.getArecibo());
TextBlock result = TextBlockUtils.mergeLR(source, TextBlockUtils.fromUImage(message), VerticalAlignment.TOP);
@ -207,7 +214,7 @@ public class PSystemError extends AbstractPSystem {
private TextBlockBackcolored getMessageDedication() {
final FlashCodeUtils utils = FlashCodeFactory.getFlashCodeUtils();
final HtmlColorSimple backColor = (HtmlColorSimple) new HtmlColorSetSimple().getColorIfValid("#DFDCD3");
final HtmlColorSimple backColor = (HtmlColorSimple) new HtmlColorSetSimple().getColorIfValid("#eae2c9");
final BufferedImage qrcode = smaller(utils.exportFlashcode("http://plantuml.com/dedication", Color.BLACK,
backColor.getColor999()));
@ -229,6 +236,22 @@ public class PSystemError extends AbstractPSystem {
}
private TextBlockBackcolored getMessageAdopt() {
final HtmlColorSimple backColor = (HtmlColorSimple) new HtmlColorSetSimple().getColorIfValid("#eff4d2");
final Display disp = Display.create("<b>Adopt-a-Word and put your message here!", " ",
"Details on <i>[[http://plantuml.com/adopt]]", " ");
final UFont font = UFont.sansSerif(14);
final FontConfiguration fc = new FontConfiguration(font, HtmlColorUtils.BLACK, HtmlColorUtils.BLACK, false);
final TextBlock text = TextBlockUtils.withMargin(
disp.create(fc, HorizontalAlignment.LEFT, new SpriteContainerEmpty()), 10, 0);
final TextBlock result;
result = text;
return TextBlockUtils.addBackcolor(result, backColor);
}
private TextBlockBackcolored getMessagePatreon() {
final UImage message = new UImage(PSystemVersion.getTime01());
final Color back = new Color(message.getImage().getRGB(0, 0));

View File

@ -40,6 +40,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.List;
import net.sourceforge.plantuml.core.Diagram;
import net.sourceforge.plantuml.core.DiagramDescription;
@ -52,23 +53,29 @@ public class Pipe {
private final PrintStream ps;
private boolean closed = false;
private final String charset;
private final Stdrpt stdrpt;
public Pipe(Option option, PrintStream ps, InputStream is, String charset) {
this.option = option;
this.is = is;
this.ps = ps;
this.charset = charset;
this.stdrpt = option.getStdrpt();
}
public boolean managePipe() throws IOException {
boolean error = false;
public void managePipe(ErrorStatus error) throws IOException {
final boolean noStdErr = option.isPipeNoStdErr();
int nb = 0;
do {
final String source = readOneDiagram();
if (source == null) {
ps.flush();
return error;
if (nb == 0) {
// error.goNoData();
}
return;
}
nb++;
final Defines defines = option.getDefaultDefines();
final SourceStringReader sourceStringReader = new SourceStringReader(defines, source, option.getConfig());
if (option.isComputeurl()) {
@ -78,12 +85,14 @@ public class Pipe {
} else if (option.isSyntax()) {
final Diagram system = sourceStringReader.getBlocks().get(0).getDiagram();
if (system instanceof UmlDiagram) {
error.goOk();
ps.println(((UmlDiagram) system).getUmlDiagramType().name());
ps.println(system.getDescription());
} else if (system instanceof PSystemError) {
error = true;
printErrorText(ps, (PSystemError) system);
error.goWithError();
stdrpt.printInfo(ps, (PSystemError) system);
} else {
error.goOk();
ps.println("OTHER");
ps.println(system.getDescription());
}
@ -99,13 +108,16 @@ public class Pipe {
final OutputStream os = noStdErr ? new ByteArrayOutputStream() : ps;
final DiagramDescription result = sourceStringReader.outputImage(os, option.getImageIndex(),
option.getFileFormatOption());
printInfo(noStdErr ? ps : System.err, sourceStringReader);
if (result != null && "(error)".equalsIgnoreCase(result.getDescription())) {
error = true;
manageErrors(noStdErr ? ps : System.err, sourceStringReader);
} else if (noStdErr) {
final ByteArrayOutputStream baos = (ByteArrayOutputStream) os;
baos.close();
ps.write(baos.toByteArray());
error.goWithError();
} else {
error.goOk();
if (noStdErr) {
final ByteArrayOutputStream baos = (ByteArrayOutputStream) os;
baos.close();
ps.write(baos.toByteArray());
}
}
if (option.getPipeDelimitor() != null) {
ps.println(option.getPipeDelimitor());
@ -113,23 +125,18 @@ public class Pipe {
}
ps.flush();
} while (closed == false);
return error;
}
private void manageErrors(final PrintStream output, final SourceStringReader sourceStringReader) {
// if (option.getPipeDelimitor() != null) {
// output.println(option.getPipeDelimitor());
// }
printErrorText(output, (PSystemError) sourceStringReader.getBlocks().get(0).getDiagram());
}
private void printErrorText(final PrintStream output, final PSystemError sys) {
output.println("ERROR");
output.println(sys.getHigherErrorPosition2().getPosition());
for (ErrorUml er : sys.getErrorsUml()) {
output.println(er.getError());
if (nb == 0) {
// error.goNoData();
}
}
private void printInfo(final PrintStream output, final SourceStringReader sourceStringReader) {
final List<BlockUml> blocks = sourceStringReader.getBlocks();
if (blocks.size() == 0) {
stdrpt.printInfo(output, null);
} else {
stdrpt.printInfo(output, blocks.get(0).getDiagram());
}
output.flush();
}
private boolean isFinished(String s) {

View File

@ -51,7 +51,6 @@ import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.imageio.ImageIO;
import javax.swing.UIManager;
@ -145,7 +144,7 @@ public class Run {
if (option.getPreprocessorOutputMode() == OptionPreprocOutputMode.CYPHER) {
cypher = new LanguageDescriptor().getCypher();
}
boolean error = false;
final ErrorStatus error = ErrorStatus.init();
boolean forceQuit = false;
if (option.isPattern()) {
managePattern();
@ -164,7 +163,7 @@ public class Run {
}
new MainWindow2(option, dir);
} else if (option.isPipe() || option.isPipeMap() || option.isSyntax()) {
error = managePipe(option);
managePipe(option, error);
forceQuit = true;
} else if (option.isFailfast2()) {
if (option.isSplash()) {
@ -172,21 +171,21 @@ public class Run {
}
final long start2 = System.currentTimeMillis();
option.setCheckOnly(true);
error = manageAllFiles(option);
manageAllFiles(option, error);
option.setCheckOnly(false);
if (option.isDuration()) {
final double duration = (System.currentTimeMillis() - start2) / 1000.0;
Log.error("Check Duration = " + duration + " seconds");
}
if (error == false) {
error = manageAllFiles(option);
if (error.hasError() == false) {
manageAllFiles(option, error);
}
forceQuit = true;
} else {
if (option.isSplash()) {
Splash.createSplash();
}
error = manageAllFiles(option);
manageAllFiles(option, error);
forceQuit = true;
}
@ -195,9 +194,13 @@ public class Run {
Log.error("Duration = " + duration + " seconds");
}
if (error) {
if (error.hasError()) {
Log.error("Some diagram description contains errors");
System.exit(1);
System.exit(error.getExitCode());
}
if (error.isNoData()) {
Log.error("No diagram found");
System.exit(error.getExitCode());
}
if (forceQuit && OptionFlags.getInstance().isSystemExit()) {
@ -349,12 +352,12 @@ public class Run {
}
}
private static boolean managePipe(Option option) throws IOException {
private static void managePipe(Option option, ErrorStatus error) throws IOException {
final String charset = option.getCharset();
return new Pipe(option, System.out, System.in, charset).managePipe();
new Pipe(option, System.out, System.in, charset).managePipe(error);
}
private static boolean manageAllFiles(Option option) throws IOException, InterruptedException {
private static void manageAllFiles(Option option, ErrorStatus error) throws IOException, InterruptedException {
File lockFile = null;
try {
@ -364,7 +367,7 @@ public class Run {
javaIsRunningFile.delete();
lockFile = new File(dir, "javaumllock.tmp");
}
return processArgs(option);
processArgs(option, error);
} finally {
if (lockFile != null) {
lockFile.delete();
@ -373,12 +376,12 @@ public class Run {
}
private static boolean processArgs(Option option) throws IOException, InterruptedException {
private static void processArgs(Option option, ErrorStatus error) throws IOException, InterruptedException {
if (option.isDecodeurl() == false && option.getNbThreads() > 1 && option.isCheckOnly() == false
&& OptionFlags.getInstance().isExtractFromMetadata() == false) {
return multithread(option);
multithread(option, error);
return;
}
boolean errorGlobal = false;
final List<File> files = new ArrayList<File>();
for (String s : option.getResult()) {
if (option.isDecodeurl()) {
@ -392,55 +395,54 @@ public class Run {
files.addAll(group.getFiles());
}
}
Log.info("Found " + files.size() + " files");
foundNbFiles(files.size());
for (File f : files) {
try {
final boolean error = manageFileInternal(f, option);
if (error) {
errorGlobal = true;
}
incDone(error);
if (error && option.isFailfastOrFailfast2()) {
return true;
manageFileInternal(f, option, error);
incDone(error.hasError());
if (error.hasError() && option.isFailfastOrFailfast2()) {
return;
}
} catch (IOException e) {
e.printStackTrace();
}
}
return errorGlobal;
}
private static boolean multithread(final Option option) throws InterruptedException {
private static void multithread(final Option option, final ErrorStatus error) throws InterruptedException {
Log.info("Using several threads: " + option.getNbThreads());
final ExecutorService executor = Executors.newFixedThreadPool(option.getNbThreads());
final AtomicBoolean errors = new AtomicBoolean(false);
int nb = 0;
for (String s : option.getResult()) {
final FileGroup group = new FileGroup(s, option.getExcludes(), option);
for (final File f : group.getFiles()) {
incTotal(1);
nb++;
executor.submit(new Runnable() {
public void run() {
if (errors.get() && option.isFailfastOrFailfast2()) {
if (error.hasError() && option.isFailfastOrFailfast2()) {
return;
}
try {
final boolean error = manageFileInternal(f, option);
if (error) {
errors.set(true);
}
manageFileInternal(f, option, error);
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
incDone(errors.get());
incDone(error.hasError());
}
});
}
}
foundNbFiles(nb);
executor.shutdown();
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);
return errors.get();
}
private static void foundNbFiles(int nb) {
Log.info("Found " + nb + " files");
}
private static void incDone(boolean error) {
@ -453,7 +455,8 @@ public class Run {
ProgressBar.incTotal(nb);
}
private static boolean manageFileInternal(File f, Option option) throws IOException, InterruptedException {
private static void manageFileInternal(File f, Option option, ErrorStatus error) throws IOException,
InterruptedException {
Log.info("Working on " + f.getAbsolutePath());
if (OptionFlags.getInstance().isExtractFromMetadata()) {
System.out.println("------------------------");
@ -468,7 +471,7 @@ public class Run {
System.out.println(data);
System.out.println("------------------------");
return false;
return;
}
final ISourceFileReader sourceFileReader;
if (option.getOutputFile() == null) {
@ -484,24 +487,35 @@ public class Run {
for (BlockUml s : sourceFileReader.getBlocks()) {
System.out.println(s.getEncodedUrl());
}
return false;
return;
}
if (option.isCheckOnly()) {
final boolean hasError = sourceFileReader.hasError();
final List<GeneratedImage> result = sourceFileReader.getGeneratedImages();
hasErrors(f, result);
return hasError;
if (hasError) {
error.goWithError();
}
// final List<GeneratedImage> result = sourceFileReader.getGeneratedImages();
// hasErrors(f, result, error);
return;
}
if (option.getPreprocessorOutputMode() != null) {
extractPreproc(option, sourceFileReader);
return false;
error.goOk();
return;
}
final List<GeneratedImage> result = sourceFileReader.getGeneratedImages();
final Stdrpt rpt = option.getStdrpt();
if (result.size() == 0) {
Log.error("Warning: no image in " + f.getCanonicalPath());
rpt.printInfo(System.err, null);
// error.goNoData();
return;
}
for (BlockUml s : sourceFileReader.getBlocks()) {
rpt.printInfo(System.err, s.getDiagram());
}
return hasErrors(f, result);
hasErrors(f, result, error);
}
private static void extractPreproc(Option option, final ISourceFileReader sourceFileReader) throws IOException {
@ -522,16 +536,20 @@ public class Run {
}
}
private static boolean hasErrors(File f, final List<GeneratedImage> list) throws IOException {
boolean result = false;
private static void hasErrors(File f, final List<GeneratedImage> list, ErrorStatus error) throws IOException {
if (list.size() == 0) {
// error.goNoData();
return;
}
for (GeneratedImage i : list) {
final int lineError = i.lineErrorRaw();
if (lineError != -1) {
Log.error("Error line " + lineError + " in file: " + f.getCanonicalPath());
result = true;
error.goWithError();
return;
}
}
return result;
error.goOk();
}
}

View File

@ -59,7 +59,7 @@ public class SignatureUtils {
// }
public static byte[] salting(String pass, byte[] salt) throws NoSuchAlgorithmException, InvalidKeySpecException {
final int iterations = 10000;
final int iterations = 500;
final int keyLength = 512;
final SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
final PBEKeySpec spec = new PBEKeySpec(pass.toCharArray(), salt, iterations, keyLength);

View File

@ -81,17 +81,8 @@ public class SkinParam implements ISkinParam {
private final Map<String, String> params = new HashMap<String, String>();
private Rankdir rankdir = Rankdir.TOP_TO_BOTTOM;
private String dotExecutable;
private final UmlDiagramType type;
public String getDotExecutable() {
return dotExecutable;
}
public void setDotExecutable(String dotExecutable) {
Log.info("Overwritting dot in skinparam " + dotExecutable);
this.dotExecutable = dotExecutable;
}
private boolean useVizJs;
public void setParam(String key, String value) {
for (String key2 : cleanForKey(key)) {
@ -1046,4 +1037,12 @@ public class SkinParam implements ISkinParam {
return false;
}
public void setUseVizJs(boolean useVizJs) {
this.useVizJs = useVizJs;
}
public boolean isUseVizJs() {
return useVizJs;
}
}

View File

@ -99,11 +99,8 @@ public class SkinParamDelegator implements ISkinParam {
return skinParam.getDotSplines();
}
public String getDotExecutable() {
return skinParam.getDotExecutable();
}
public HorizontalAlignment getHorizontalAlignment(AlignmentParam param, ArrowDirection arrowDirection, boolean isReverseDefine) {
public HorizontalAlignment getHorizontalAlignment(AlignmentParam param, ArrowDirection arrowDirection,
boolean isReverseDefine) {
return skinParam.getHorizontalAlignment(param, arrowDirection, isReverseDefine);
}
@ -303,4 +300,12 @@ public class SkinParamDelegator implements ISkinParam {
return skinParam.fixCircleLabelOverlapping();
}
public void setUseVizJs(boolean useVizJs) {
skinParam.setUseVizJs(useVizJs);
}
public boolean isUseVizJs() {
return skinParam.isUseVizJs();
}
}

View File

@ -0,0 +1,46 @@
/* ========================================================================
* 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;
import java.io.PrintStream;
import net.sourceforge.plantuml.core.Diagram;
public interface Stdrpt {
public void printInfo(PrintStream output, Diagram sys);
}

View File

@ -0,0 +1,47 @@
/* ========================================================================
* 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;
import java.io.PrintStream;
import net.sourceforge.plantuml.core.Diagram;
public class StdrptNull implements Stdrpt {
public void printInfo(final PrintStream output, final Diagram sys) {
}
}

View File

@ -0,0 +1,56 @@
/* ========================================================================
* 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;
import java.io.PrintStream;
import net.sourceforge.plantuml.core.Diagram;
public class StdrptPipe0 implements Stdrpt {
public void printInfo(final PrintStream output, final Diagram sys) {
if (sys instanceof PSystemError) {
final PSystemError err = (PSystemError) sys;
output.println("ERROR");
output.println(err.getHigherErrorPosition2().getPosition());
for (ErrorUml er : err.getErrorsUml()) {
output.println(er.getError());
}
output.flush();
}
}
}

View File

@ -0,0 +1,80 @@
/* ========================================================================
* 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;
import java.io.PrintStream;
import net.sourceforge.plantuml.command.PSystemAbstractFactory;
import net.sourceforge.plantuml.core.Diagram;
import net.sourceforge.plantuml.eggs.PSystemWelcome;
public class StdrptV1 implements Stdrpt {
public void printInfo(final PrintStream output, Diagram sys) {
if (sys instanceof PSystemWelcome) {
sys = null;
}
if (sys == null || sys instanceof PSystemError) {
out(output, (PSystemError) sys);
}
}
private void out(final PrintStream output, final PSystemError err) {
output.println("protocolVersion=1");
if (empty(err)) {
output.println("status=NO_DATA");
} else {
output.println("status=ERROR");
output.println("lineNumber=" + err.getHigherErrorPosition2().getPosition());
for (ErrorUml er : err.getErrorsUml()) {
output.println("label=" + er.getError());
}
}
output.flush();
}
private boolean empty(final PSystemError err) {
if (err == null) {
return true;
}
for (ErrorUml er : err.getErrorsUml()) {
if (PSystemAbstractFactory.EMPTY_DESCRIPTION.equals(er.getError()))
return true;
}
return false;
}
}

View File

@ -445,10 +445,6 @@ public abstract class UmlDiagram extends AbstractPSystem implements Diagram, Ann
return useJDot;
}
private void setDotExecutable(String dotExecutable) {
skinParam.setDotExecutable(dotExecutable);
}
public final Display getMainFrame() {
return mainFrame;
}

View File

@ -45,6 +45,7 @@ import net.sourceforge.plantuml.activitydiagram.command.CommandIf;
import net.sourceforge.plantuml.activitydiagram.command.CommandLinkActivity;
import net.sourceforge.plantuml.activitydiagram.command.CommandLinkLongActivity;
import net.sourceforge.plantuml.activitydiagram.command.CommandPartition;
import net.sourceforge.plantuml.classdiagram.command.CommandHideShow2;
import net.sourceforge.plantuml.command.Command;
import net.sourceforge.plantuml.command.CommandFootboxIgnored;
import net.sourceforge.plantuml.command.CommandRankDir;
@ -83,6 +84,7 @@ public class ActivityDiagramFactory extends UmlDiagramFactory {
cmds.add(new CommandEndif());
cmds.add(new CommandLinkActivity());
cmds.add(new CommandHideShow2());
// addCommand(new CommandInnerConcurrent(system));
return cmds;

View File

@ -140,7 +140,8 @@ public class ActivityDiagram3 extends UmlDiagram {
public void start() {
manageSwimlaneStrategy();
current().add(new InstructionStart(swinlanes.getCurrentSwimlane()));
current().add(new InstructionStart(swinlanes.getCurrentSwimlane(), nextLinkRenderer()));
setNextLinkRendererInternal(LinkRendering.none());
}
public void stop() {

View File

@ -41,8 +41,14 @@ import net.sourceforge.plantuml.activitydiagram3.ftile.Swimlane;
public class InstructionStart extends MonoSwimable implements Instruction {
public InstructionStart(Swimlane swimlane) {
private final LinkRendering inlinkRendering;
public InstructionStart(Swimlane swimlane, LinkRendering inlinkRendering) {
super(swimlane);
this.inlinkRendering = inlinkRendering;
if (inlinkRendering == null) {
throw new IllegalArgumentException();
}
}
public Ftile createFtile(FtileFactory factory) {
@ -60,7 +66,7 @@ public class InstructionStart extends MonoSwimable implements Instruction {
}
public LinkRendering getInLinkRendering() {
return LinkRendering.none();
return inlinkRendering;
}
}

View File

@ -292,6 +292,9 @@ public class FtileIfDown extends AbstractFtile {
final Snake snake = new Snake(arrowHorizontalAlignment(), endInlinkColor, Arrows.asToLeft());
final Point2D p1 = getP1(stringBounder);
if (calculateDimension(stringBounder).hasPointOut() == false) {
return;
}
final Point2D p2 = getP2(stringBounder);
final double x1 = p1.getX();
@ -353,7 +356,11 @@ public class FtileIfDown extends AbstractFtile {
if (optionalStop != null) {
width += optionalStop.calculateDimension(stringBounder).getWidth() + getAdditionalWidth(stringBounder);
}
return new FtileGeometry(width, height, geo.getLeft(), geoDiamond1.getInY(), height);
final FtileGeometry result = new FtileGeometry(width, height, geo.getLeft(), geoDiamond1.getInY(), height);
if (geoThen.hasPointOut() == false && optionalStop != null) {
return result.withoutPointOut();
}
return result;
}

View File

@ -161,8 +161,8 @@ class FtileIfLongHorizontal extends AbstractFtile {
for (Branch branch : thens) {
final TextBlock tb1 = branch.getLabelPositive().create(fcArrow, HorizontalAlignment.LEFT,
ftileFactory.skinParam());
final TextBlock tbTest = branch.getLabelTest().create(fcTest, HorizontalAlignment.LEFT,
ftileFactory.skinParam());
final TextBlock tbTest = branch.getLabelTest().create(fcTest,
ftileFactory.skinParam().getDefaultTextAlignment(HorizontalAlignment.LEFT), ftileFactory.skinParam());
final HtmlColor diamondColor = branch.getColor() == null ? backColor : branch.getColor();
FtileDiamondInside2 diamond = new FtileDiamondInside2(branch.skinParam(), diamondColor, borderColor,

View File

@ -151,8 +151,11 @@ class FtileIfLongVertical extends AbstractFtile {
List<Ftile> diamonds = new ArrayList<Ftile>();
for (Branch branch : thens) {
final TextBlock tb1 = branch.getLabelPositive().create(fc, HorizontalAlignment.LEFT, ftileFactory.skinParam());
final TextBlock tbTest = branch.getLabelTest().create(fc, HorizontalAlignment.LEFT, ftileFactory.skinParam());
final TextBlock tb1 = branch.getLabelPositive().create(fc, HorizontalAlignment.LEFT,
ftileFactory.skinParam());
final TextBlock tbTest = branch.getLabelTest().create(fc,
ftileFactory.skinParam().getDefaultTextAlignment(HorizontalAlignment.LEFT),
ftileFactory.skinParam());
FtileDiamondInside3 diamond = new FtileDiamondInside3(branch.skinParam(), backColor, borderColor, swimlane,
tbTest);
diamond = diamond.withEast(tb1);

View File

@ -53,6 +53,7 @@ import net.sourceforge.plantuml.activitydiagram3.ftile.Snake;
import net.sourceforge.plantuml.activitydiagram3.ftile.Swimlane;
import net.sourceforge.plantuml.activitydiagram3.ftile.vertical.FtileThinSplit;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.graphic.HtmlColor;
import net.sourceforge.plantuml.graphic.HtmlColorAndStyle;
import net.sourceforge.plantuml.graphic.Rainbow;
import net.sourceforge.plantuml.graphic.StringBounder;
@ -71,7 +72,7 @@ public class ParallelBuilderSplit2 extends ParallelFtilesBuilder {
Ftile result = getMiddle();
final List<Connection> conns = new ArrayList<Connection>();
final Rainbow thinColor = result.getInLinkRendering().getRainbow(HtmlColorAndStyle.build(skinParam()));
final Ftile thin = new FtileThinSplit(skinParam(), thinColor.getColor(), getList().get(0).getSwimlaneIn());
final Ftile thin = new FtileThinSplit(skinParam(), getThin1Color(thinColor), getList().get(0).getSwimlaneIn());
double x = 0;
double first = 0;
double last = 0;
@ -81,17 +82,34 @@ public class ParallelBuilderSplit2 extends ParallelFtilesBuilder {
first = x + dim.getLeft();
}
last = x + dim.getLeft();
conns.add(new ConnectionIn(thin, tmp, x, tmp.getInLinkRendering().getRainbow(
HtmlColorAndStyle.build(skinParam()))));
final Rainbow rainbow = tmp.getInLinkRendering().getRainbow(HtmlColorAndStyle.build(skinParam()));
conns.add(new ConnectionIn(thin, tmp, x, rainbow));
x += dim.getWidth();
}
result = FtileUtils.addConnection(result, conns);
final FtileGeometry geom = result.calculateDimension(getStringBounder());
if (last < geom.getLeft()) {
last = geom.getLeft();
}
if (first > geom.getLeft()) {
first = geom.getLeft();
}
((FtileThinSplit) thin).setGeom(first, last, result.calculateDimension(getStringBounder()).getWidth());
return new FtileAssemblySimple(thin, result);
}
private HtmlColor getThin1Color(final Rainbow thinColor) {
for (Ftile tmp : getList()) {
final Rainbow rainbow = tmp.getInLinkRendering().getRainbow(HtmlColorAndStyle.build(skinParam()));
if (rainbow.isInvisible() == false) {
return thinColor.getColor();
}
}
return null;
}
private boolean hasOut() {
for (Ftile tmp : getList()) {
final boolean hasOutTmp = tmp.calculateDimension(getStringBounder()).hasPointOut();

View File

@ -78,7 +78,6 @@ public class FtileThinSplit extends AbstractFtile {
}
public void drawU(UGraphic ug) {
// final URectangle rect = new URectangle(width, height);
final UShape rect = new ULine(last - first, 0);
ug = ug.apply(new UTranslate(first, 0));
ug.apply(new UChangeColor(colorBar)).apply(new UStroke(1.5)).draw(rect);

View File

@ -87,15 +87,13 @@ public class ClassDiagramFactory extends UmlDiagramFactory {
protected List<Command> createCommands() {
final List<Command> cmds = new ArrayList<Command>();
cmds.add(new CommandFootboxIgnored());
addCommonCommands(cmds);
cmds.add(new CommandRankDir());
cmds.add(new CommandNewpage(this));
// cmds.add(new CommandHideShowSpecificStereotype());
cmds.add(new CommandPage());
cmds.add(new CommandAddMethod());
cmds.add(new CommandHideShow2());
cmds.add(new CommandRemoveRestore());
cmds.add(new CommandCreateClassMultilines());
cmds.add(new CommandCreateEntityObjectMultilines());
@ -143,12 +141,12 @@ public class ClassDiagramFactory extends UmlDiagramFactory {
cmds.add(new CommandDiamondAssociation());
// cmds.add(new CommandHideShowSpecificClass());
cmds.add(new CommandNamespaceSeparator());
cmds.add(new CommandCreateElementMultilines(0));
cmds.add(new CommandCreateElementMultilines(1));
addCommonCommands(cmds);
cmds.add(new CommandHideShow2());
return cmds;
}

View File

@ -39,6 +39,7 @@ import java.util.List;
import net.sourceforge.plantuml.StringUtils;
import net.sourceforge.plantuml.UmlDiagram;
import net.sourceforge.plantuml.cucadiagram.dot.GraphvizUtils;
public class CommandPragma extends SingleLineCommand<UmlDiagram> {
@ -54,12 +55,9 @@ public class CommandPragma extends SingleLineCommand<UmlDiagram> {
if (name.equalsIgnoreCase("graphviz_dot") && value.equalsIgnoreCase("jdot")) {
system.setUseJDot(true);
}
// else if (name.equalsIgnoreCase("graphviz_dot") && OptionFlags.ALLOW_INCLUDE) {
// final String cmd = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(value);
// if (cmd.toLowerCase().endsWith("dot") || cmd.toLowerCase().endsWith("dot.exe")) {
// system.setDotExecutable(cmd);
// }
// }
if (name.equalsIgnoreCase("graphviz_dot") && value.equalsIgnoreCase(GraphvizUtils.VIZJS)) {
system.getSkinParam().setUseVizJs(true);
}
return CommandExecutionResult.ok();
}

View File

@ -46,6 +46,7 @@ import net.sourceforge.plantuml.core.UmlSource;
public abstract class PSystemAbstractFactory implements PSystemFactory {
public static final String EMPTY_DESCRIPTION = "Empty description";
private final DiagramType type;
protected PSystemAbstractFactory(DiagramType type) {
@ -53,7 +54,7 @@ public abstract class PSystemAbstractFactory implements PSystemFactory {
}
final protected AbstractPSystem buildEmptyError(UmlSource source, LineLocation lineLocation) {
final ErrorUml err = new ErrorUml(ErrorUmlType.SYNTAX_ERROR, "Empty description", /* 1, */lineLocation);
final ErrorUml err = new ErrorUml(ErrorUmlType.SYNTAX_ERROR, EMPTY_DESCRIPTION, /* 1, */lineLocation);
final PSystemError result = new PSystemError(source, err, null);
result.setSource(source);
return result;

View File

@ -44,7 +44,6 @@ import net.sourceforge.plantuml.AbstractPSystem;
import net.sourceforge.plantuml.CharSequence2;
import net.sourceforge.plantuml.ErrorUml;
import net.sourceforge.plantuml.ErrorUmlType;
import net.sourceforge.plantuml.NewpagedDiagram;
import net.sourceforge.plantuml.PSystemError;
import net.sourceforge.plantuml.StringUtils;
import net.sourceforge.plantuml.classdiagram.command.CommandHideShowByGender;

View File

@ -50,35 +50,45 @@ abstract class AbstractGraphviz implements Graphviz {
private final File dotExe;
private final String dotString;
private final String[] type;
private final ISkinParam skinParam;
static boolean isWindows() {
return File.separatorChar == '\\';
}
private static String findExecutableOnPath(String name) {
for (String dirname : System.getenv("PATH").split(File.pathSeparator)) {
File file = new File(dirname, name);
if (file.isFile() && file.canExecute()) {
return file.getAbsolutePath();
}
}
return null;
}
AbstractGraphviz(ISkinParam skinParam, String dotString, String... type) {
if (type == null) {
throw new IllegalArgumentException();
}
this.skinParam = skinParam;
this.dotExe = searchDotExe();
this.dotString = dotString;
this.type = type;
}
private File searchDotExe() {
if (skinParam == null || skinParam.getDotExecutable() == null) {
final String getenv = GraphvizUtils.getenvGraphvizDot();
if (getenv == null) {
return specificDotExe();
}
return new File(getenv);
String getenv = GraphvizUtils.getenvGraphvizDot();
if (getenv == null) {
getenv = findExecutableOnPath(getExeName());
}
return new File(skinParam.getDotExecutable());
if (getenv == null) {
return specificDotExe();
}
return new File(getenv);
}
abstract protected File specificDotExe();
abstract protected String getExeName();
final public ProcessState createFile3(OutputStream os) {
if (dotString == null) {
throw new IllegalArgumentException();

View File

@ -59,4 +59,9 @@ class GraphvizLinux extends AbstractGraphviz {
return optLocalBinDot;
}
@Override
protected String getExeName() {
return "dot";
}
}

View File

@ -52,7 +52,7 @@ import net.sourceforge.plantuml.vizjs.VizJsEngine;
public class GraphvizUtils {
private static final String VIZJS = "vizjs";
public static final String VIZJS = "vizjs";
private static int DOT_VERSION_LIMIT = 226;
private static boolean isWindows() {
@ -89,7 +89,7 @@ public class GraphvizUtils {
}
private static boolean useVizJs(ISkinParam skinParam) {
if (skinParam != null && VIZJS.equalsIgnoreCase(skinParam.getDotExecutable()) && VizJsEngine.isOk()) {
if (skinParam!=null && skinParam.isUseVizJs() && VizJsEngine.isOk()) {
return true;
}
if (VIZJS.equalsIgnoreCase(getenvGraphvizDot()) && VizJsEngine.isOk()) {

View File

@ -92,5 +92,11 @@ class GraphvizWindows extends AbstractGraphviz {
GraphvizWindows(ISkinParam skinParam, String dotString, String... type) {
super(skinParam, dotString, type);
}
@Override
protected String getExeName() {
return "dot.exe";
}
}

View File

@ -40,8 +40,6 @@ 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;
@ -61,20 +59,13 @@ public class QBlock {
return new QBlock(new BigInteger(block));
}
public static QBlock fromMagic(Magic magic) {
final byte[] buffer = magic.getBuffer();
public static QBlock fromBuffer(final byte[] buffer) {
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;
}
@ -84,7 +75,7 @@ public class QBlock {
return new QBlock(changed);
}
private byte[] getData512() {
public byte[] getData512() {
final byte[] nb = big.toByteArray();
if (nb.length == 512) {
return nb;

View File

@ -35,8 +35,8 @@
*/
package net.sourceforge.plantuml.descdiagram.command;
import net.sourceforge.plantuml.AbstractPSystem;
import net.sourceforge.plantuml.NewpagedDiagram;
import net.sourceforge.plantuml.UmlDiagram;
import net.sourceforge.plantuml.command.CommandExecutionResult;
import net.sourceforge.plantuml.command.SingleLineCommand2;
import net.sourceforge.plantuml.command.UmlDiagramFactory;
@ -44,7 +44,7 @@ import net.sourceforge.plantuml.command.regex.RegexConcat;
import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.command.regex.RegexResult;
public class CommandNewpage extends SingleLineCommand2<AbstractPSystem> {
public class CommandNewpage extends SingleLineCommand2<UmlDiagram> {
private final UmlDiagramFactory factory;
@ -60,9 +60,13 @@ public class CommandNewpage extends SingleLineCommand2<AbstractPSystem> {
}
@Override
protected CommandExecutionResult executeArg(AbstractPSystem diagram, RegexResult arg) {
NewpagedDiagram result = new NewpagedDiagram(diagram, factory.createEmptyDiagram());
// NewpagedDiagram result = NewpagedDiagram.newpage(diagram, factory.createEmptyDiagram());
protected CommandExecutionResult executeArg(UmlDiagram diagram, RegexResult arg) {
final int dpi = diagram.getSkinParam().getDpi();
final UmlDiagram emptyDiagram = (UmlDiagram) factory.createEmptyDiagram();
if (dpi != 96) {
emptyDiagram.setParam("dpi", "" + dpi);
}
NewpagedDiagram result = new NewpagedDiagram(diagram, emptyDiagram);
return CommandExecutionResult.newDiagram(result);
}
}

View File

@ -67,21 +67,21 @@ import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.version.PSystemVersion;
public class PSystemDonors extends AbstractPSystem {
public static final String DONORS = "6rK809m7nctnXhJewjSHZX8n3MVAYw086_hm054IjRdwqUp4_JWT81c0qvE5N5zqDfkGDMFIpNEMyuoY"
+ "M3uDM2zrsEPcFuYbilsNYTjr7R2bcYiX7iHwwS_VkmUE0bdSfipZmCR6EPRTasMlw6Rt1Lf0zRVHovPz"
+ "IWKtWSqlH9CQulutnzUhP56CxXGfihgn1SYueqQmRtIEyGNrnd_K8ZLfpQOXxZM0M4OAMVEsokHnaFqd"
+ "C50Y9r5tC8250uc3Vv63lZ-X05AnQjZmZs8orbgzvma799HG8GN_o4brRY7XKGOFv2Ik1W8oFu4HWBrM"
+ "K4dCrkm6P6aHBP8Q17N5Ui4Zih-OcZBdISDvv0w925e1LG2v2Bh0LsapboZNiIiiUFokZ7Ux542kiWO0"
+ "wSc2ljgwCc3-rqzchBgygMyjf7FATOv_dGtmh24pztOpkdXaCHRpnrmAmnSBa5-0JcqRBCRpY_FEGWm4"
+ "nvIweCpPStoTHC2ainGMVX5BMZF_hKlLMb74jsOi-W_xwugXX644LoAk0NnDo-8adIyKTmtrxqEkTXtV"
+ "8jPO9DIReMUdpEdizx9RYXcb6sXn4pfCbqUO6_QLLQ9OD14O0Vezu259xgJws-HHVLi-nDxs9y6yQU60"
+ "v3PZxE-gCnn53giW2zAsjui5m6ILQ1ToKZVYXaCTw2get4CZtFNNJRg7JHaJvutUyLWFCmRr9Jf6ll2u"
+ "c4j6SKEBp9lDXxItE0gu4L-SruzzgCzL0ElgtbMBq7W50_eUvWn3UWt9nv6snAEemumijmNFwcBFpUta"
+ "vg4ZVpXcjgZdZUCF7dyUCXDgtzkdbhf5cBi6GzyQapNPorEKMrWDrL616f5n7t0-CpbIoH5oOiEP3e6O"
+ "926txRns5DJWaYSM-dNBzjIq1Dcxh-u2tS4FoniPgFWxvY3YxE-KEAFNAB9VCU_Ch9lwFgJ4kO2SCKHm"
+ "bmhcDaAAQjYSHeRi-wYdEphvp9SsMqXiuvSjZoaKFY6YTOiD1fj2DEhmRzX50AxVfavUp9W80NoFqs_G"
+ "qqzraBEDbbOH1t1pIGY42drxr1_6ZZ9jjwQmBj7hjctxM3R--i-SPGMda5_6gWEaAaZl_sm8B1DsKzPT"
+ "qVU2JvkJMiWC7EfaErREZ9uAC2IeTqi0";
public static final String DONORS = "6t0809m7nctnXhJewjSHZX8n3MVAYw086_hm054IjRdQYUQl7wS390DmUhAGwulEPXEoPaowUSvodb4K"
+ "owS1wwKEszpi1x5KjlyoSRkk0xPKSoN4WrWl7Rft3nm5ihXDWKGK1pOsph7iBYfxHPVT2xI0zl_Vw6NB"
+ "FkK4kXvWDHpiUNFiN4fgnQW7aIAg6rk0Y3jg-6hZwmXVK7txZrga9gtPDCIz1X3BI25htlOqTXpaxsCO"
+ "A74Zi7SmW8G3YODzaOEyFg40vdoxOSCpYj9OKtMN9moGa465RFX7Jgfp2mcFCdZWHk1g823o4nW1iR_a"
+ "KvApbPq16LjaYvW6GLrwl-0Hx2-cfGmvq70MsI4GGIk02Y0dGHVusjhC9Sfrx0eBZzwLyVui0P2Rh0f0"
+ "UbAZhxok39Y7nPCPRL--LBSMqZdbEiU_pWPurf2PlTsCRxoo68lvOow5uOi5b5-03hK6Y_7yujon40N1"
+ "CQKkA7Ds7bzB4H2fB8M5NiIIrGn_xv9_B2VYMtCMpPR-TUbGmd04Look0NnTo-YapWt5LKFz-v2hhkDR"
+ "v1gZX7cJzEpKdCn-Bxkbp23TGNDDw71T5c4kwIkhQB7e8d04wE-0XoIvawflaqVxs_8XzhO_2UvD2WUa"
+ "i1bW_zG-mx79uIx83VcqgueQm7YLQ1TkX6x43Qiwq7bGUOP6kEklctGFcnfZvqQlM2w66qFxIpfAll2u"
+ "c4l65eP6MJGR3hNNE0gu3ZkKruzTAePL0DSrl4iMeV5A1kGrp1c6z1cIZoDjYSUc3ZEpF1Oyguizczl9"
+ "n4C7_t1CPL7R6ySVF7uuP7gy_4gVMkeMOUuQ37ihN5PlQsTH_i1yc8u8x94Pjm7dCvCzbHpXXcyuqy4H"
+ "aoJ4MkUrew00jt9Y_TOZsrFJ4cJjiRe9L2S_93SoKB4xPX_Y_DqHUKPZKM2_SjwHMJVrVKY9OG7POaZm"
+ "b0fc6o55UzYSJWRqNkXfZKu-ywND5wBR-EM71mmAFo7HekK6hKy16g-mRzWv0AxziafUr9W80NoFqs_G"
+ "qvHruBECbbOPPvCRf9J4n0FyOVnIiktMl9wYrstRzh5i_FMVESjAJdw_ZFKA9Bk1DF5FXq0oORzBkolu"
+ "lk5JtGWjP0PsTRATAyT6JmGO2ch2CjYhzch6skMzM78nOmS0";
@Override
final protected ImageData exportDiagramNow(OutputStream os, int num, FileFormatOption fileFormat, long seed)

View File

@ -0,0 +1,95 @@
/*
* Copyright 2018 Udo Klimaschewski
*
* http://UdoJava.com/
* http://about.me/udo.klimaschewski
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
package net.sourceforge.plantuml.evalex;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import net.sourceforge.plantuml.evalex.Expression.LazyNumber;
/**
* Abstract implementation of a direct function.<br>
* <br>
* This abstract implementation does implement lazyEval so that it returns
* the result of eval.
*/
public abstract class AbstractFunction extends AbstractLazyFunction implements Function {
/**
* Creates a new function with given name and parameter count.
*
* @param name
* The name of the function.
* @param numParams
* The number of parameters for this function.
* <code>-1</code> denotes a variable number of parameters.
*/
protected AbstractFunction(String name, int numParams) {
super(name, numParams);
}
/**
* Creates a new function with given name and parameter count.
*
* @param name
* The name of the function.
* @param numParams
* The number of parameters for this function.
* <code>-1</code> denotes a variable number of parameters.
* @param booleanFunction
* Whether this function is a boolean function.
*/
protected AbstractFunction(String name, int numParams, boolean booleanFunction) {
super(name, numParams, booleanFunction);
}
public LazyNumber lazyEval(final List<LazyNumber> lazyParams) {
return new LazyNumber() {
private List<Number> params;
public BigDecimal eval() {
return AbstractFunction.this.eval(getParams());
}
public String getString() {
return String.valueOf(AbstractFunction.this.eval(getParams()));
}
private List<? extends Number> getParams() {
if (params == null) {
params = new ArrayList<Number>();
for (LazyNumber lazyParam : lazyParams) {
params.add(lazyParam.eval());
}
}
return params;
}
};
}
}

View File

@ -0,0 +1,96 @@
/*
* Copyright 2018 Udo Klimaschewski
*
* http://UdoJava.com/
* http://about.me/udo.klimaschewski
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
package net.sourceforge.plantuml.evalex;
import java.util.Locale;
/**
* Abstract implementation of a lazy function which implements all necessary
* methods with the exception of the main logic.
*/
public abstract class AbstractLazyFunction implements LazyFunction {
/**
* Name of this function.
*/
protected String name;
/**
* Number of parameters expected for this function. <code>-1</code>
* denotes a variable number of parameters.
*/
protected int numParams;
/**
* Whether this function is a boolean function.
*/
protected boolean booleanFunction;
/**
* Creates a new function with given name and parameter count.
*
* @param name
* The name of the function.
* @param numParams
* The number of parameters for this function.
* <code>-1</code> denotes a variable number of parameters.
* @param booleanFunction
* Whether this function is a boolean function.
*/
protected AbstractLazyFunction(String name, int numParams, boolean booleanFunction) {
this.name = name.toUpperCase(Locale.ROOT);
this.numParams = numParams;
this.booleanFunction = booleanFunction;
}
/**
* Creates a new function with given name and parameter count.
*
* @param name
* The name of the function.
* @param numParams
* The number of parameters for this function.
* <code>-1</code> denotes a variable number of parameters.
*/
protected AbstractLazyFunction(String name, int numParams) {
this(name, numParams, false);
}
public String getName() {
return name;
}
public int getNumParams() {
return numParams;
}
public boolean numParamsVaries() {
return numParams < 0;
}
public boolean isBooleanFunction() {
return booleanFunction;
}
}

View File

@ -0,0 +1,102 @@
/*
* Copyright 2018 Udo Klimaschewski
*
* http://UdoJava.com/
* http://about.me/udo.klimaschewski
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
package net.sourceforge.plantuml.evalex;
/**
* Abstract implementation of an operator.
*/
public abstract class AbstractLazyOperator implements LazyOperator {
/**
* This operators name (pattern).
*/
protected String oper;
/**
* Operators precedence.
*/
protected int precedence;
/**
* Operator is left associative.
*/
protected boolean leftAssoc;
/**
* Whether this operator is boolean or not.
*/
protected boolean booleanOperator = false;
/**
* Creates a new operator.
*
* @param oper
* The operator name (pattern).
* @param precedence
* The operators precedence.
* @param leftAssoc
* <code>true</code> if the operator is left associative,
* else <code>false</code>.
* @param booleanOperator
* Whether this operator is boolean.
*/
protected AbstractLazyOperator(String oper, int precedence, boolean leftAssoc, boolean booleanOperator) {
this.oper = oper;
this.precedence = precedence;
this.leftAssoc = leftAssoc;
this.booleanOperator = booleanOperator;
}
/**
* Creates a new operator.
*
* @param oper
* The operator name (pattern).
* @param precedence
* The operators precedence.
* @param leftAssoc
* <code>true</code> if the operator is left associative,
* else <code>false</code>.
*/
protected AbstractLazyOperator(String oper, int precedence, boolean leftAssoc) {
this.oper = oper;
this.precedence = precedence;
this.leftAssoc = leftAssoc;
}
public String getOper() {
return oper;
}
public int getPrecedence() {
return precedence;
}
public boolean isLeftAssoc() {
return leftAssoc;
}
public boolean isBooleanOperator() {
return booleanOperator;
}
}

View File

@ -0,0 +1,80 @@
/*
* Copyright 2018 Udo Klimaschewski
*
* http://UdoJava.com/
* http://about.me/udo.klimaschewski
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
package net.sourceforge.plantuml.evalex;
import java.math.BigDecimal;
import net.sourceforge.plantuml.evalex.Expression.LazyNumber;
/**
* Abstract implementation of an operator.
*/
public abstract class AbstractOperator extends AbstractLazyOperator implements Operator {
/**
* Creates a new operator.
*
* @param oper
* The operator name (pattern).
* @param precedence
* The operators precedence.
* @param leftAssoc
* <code>true</code> if the operator is left associative,
* else <code>false</code>.
* @param booleanOperator
* Whether this operator is boolean.
*/
protected AbstractOperator(String oper, int precedence, boolean leftAssoc, boolean booleanOperator) {
super(oper, precedence, leftAssoc, booleanOperator);
}
/**
* Creates a new operator.
*
* @param oper
* The operator name (pattern).
* @param precedence
* The operators precedence.
* @param leftAssoc
* <code>true</code> if the operator is left associative,
* else <code>false</code>.
*/
protected AbstractOperator(String oper, int precedence, boolean leftAssoc) {
super(oper, precedence, leftAssoc);
}
public LazyNumber eval(final LazyNumber v1, final LazyNumber v2) {
return new LazyNumber() {
public Number eval() {
return AbstractOperator.this.eval(v1.eval(), v2.eval());
}
public String getString() {
return String.valueOf(AbstractOperator.this.eval(v1.eval(), v2.eval()));
}
};
}
}

View File

@ -0,0 +1,85 @@
/*
* Copyright 2018 Udo Klimaschewski
*
* http://UdoJava.com/
* http://about.me/udo.klimaschewski
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
package net.sourceforge.plantuml.evalex;
import net.sourceforge.plantuml.evalex.Expression.ExpressionException;
import net.sourceforge.plantuml.evalex.Expression.LazyNumber;
/**
* Abstract implementation of an unary operator.<br>
* <br>
* This abstract implementation implements eval so that it forwards its first
* parameter to evalUnary.
*/
public abstract class AbstractUnaryOperator extends AbstractOperator {
/**
* Creates a new operator.
*
* @param oper
* The operator name (pattern).
* @param precedence
* The operators precedence.
* @param leftAssoc
* <code>true</code> if the operator is left associative,
* else <code>false</code>.
*/
protected AbstractUnaryOperator(String oper, int precedence, boolean leftAssoc) {
super(oper, precedence, leftAssoc);
}
public LazyNumber eval(final LazyNumber v1, final LazyNumber v2) {
if (v2 != null) {
throw new ExpressionException("Did not expect a second parameter for unary operator");
}
return new LazyNumber() {
public String getString() {
return String.valueOf(AbstractUnaryOperator.this.evalUnary(v1.eval()));
}
public Number eval() {
return AbstractUnaryOperator.this.evalUnary(v1.eval());
}
};
}
public Number eval(Number v1, Number v2) {
if (v2 != null) {
throw new ExpressionException("Did not expect a second parameter for unary operator");
}
return evalUnary(v1);
}
/**
* Implementation of this unary operator.
*
* @param v1
* The parameter.
* @return The result of the operation.
*/
public abstract Number evalUnary(Number v1);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,47 @@
/*
* Copyright 2018 Udo Klimaschewski
*
* http://UdoJava.com/
* http://about.me/udo.klimaschewski
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
package net.sourceforge.plantuml.evalex;
import java.math.BigDecimal;
import java.util.List;
/**
* Base interface which is required for all directly evaluated functions.
*/
public interface Function extends LazyFunction {
/**
* Implementation for this function.
*
* @param parameters
* Parameters will be passed by the expression evaluator as a
* {@link List} of {@link BigDecimal} values.
* @return The function must return a new {@link BigDecimal} value as a
* computing result.
*/
public abstract BigDecimal eval(List<? extends Number> parameters);
}

View File

@ -0,0 +1,85 @@
/*
* Copyright 2018 Udo Klimaschewski
*
* http://UdoJava.com/
* http://about.me/udo.klimaschewski
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
package net.sourceforge.plantuml.evalex;
import java.util.List;
import net.sourceforge.plantuml.evalex.Expression.LazyNumber;
/**
* Base interface which is required for lazily evaluated functions. A function
* is defined by a name, a number of parameters it accepts and of course
* the logic for evaluating the result.
*/
public interface LazyFunction {
/**
* Gets the name of this function.<br>
* <br>
* The name is use to invoke this function in the expression.
*
* @return The name of this function.
*/
public abstract String getName();
/**
* Gets the number of parameters this function accepts.<br>
* <br>
* A value of <code>-1</code> denotes that this function accepts a variable
* number of parameters.
*
* @return The number of parameters this function accepts.
*/
public abstract int getNumParams();
/**
* Gets whether the number of accepted parameters varies.<br>
* <br>
* That means that the function does accept an undefined amount of
* parameters.
*
* @return <code>true</code> if the number of accepted parameters varies.
*/
public abstract boolean numParamsVaries();
/**
* Gets whether this function evaluates to a boolean expression.
*
* @return <code>true</code> if this function evaluates to a boolean
* expression.
*/
public abstract boolean isBooleanFunction();
/**
* Lazily evaluate this function.
*
* @param lazyParams
* The accepted parameters.
* @return The lazy result of this function.
*/
public abstract LazyNumber lazyEval(List<LazyNumber> lazyParams);
}

View File

@ -0,0 +1,75 @@
/*
* Copyright 2018 Udo Klimaschewski
*
* http://UdoJava.com/
* http://about.me/udo.klimaschewski
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
package net.sourceforge.plantuml.evalex;
import net.sourceforge.plantuml.evalex.Expression.LazyNumber;
/**
* Base interface which is required for all operators.
*/
public interface LazyOperator {
/**
* Gets the String that is used to denote the operator in the expression.
*
* @return The String that is used to denote the operator in the expression.
*/
public abstract String getOper();
/**
* Gets the precedence value of this operator.
*
* @return the precedence value of this operator.
*/
public abstract int getPrecedence();
/**
* Gets whether this operator is left associative (<code>true</code>) or if
* this operator is right associative (<code>false</code>).
*
* @return <code>true</code> if this operator is left associative.
*/
public abstract boolean isLeftAssoc();
/**
* Gets whether this operator evaluates to a boolean expression.
* @return <code>true</code> if this operator evaluates to a boolean
* expression.
*/
public abstract boolean isBooleanOperator();
/**
* Implementation for this operator.
*
* @param v1
* Operand 1.
* @param v2
* Operand 2.
* @return The result of the operation.
*/
public abstract LazyNumber eval(LazyNumber v1, LazyNumber v2);
}

View File

@ -0,0 +1,61 @@
/*
* Copyright 2018 Udo Klimaschewski
*
* http://UdoJava.com/
* http://about.me/udo.klimaschewski
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
package net.sourceforge.plantuml.evalex;
public class NString extends Number {
private final String s;
public NString(String s) {
this.s = s;
}
@Override
public String toString() {
return s;
}
@Override
public double doubleValue() {
throw new UnsupportedOperationException();
}
@Override
public float floatValue() {
throw new UnsupportedOperationException();
}
@Override
public int intValue() {
throw new UnsupportedOperationException();
}
@Override
public long longValue() {
throw new UnsupportedOperationException();
}
}

View File

@ -0,0 +1,44 @@
/*
* Copyright 2018 Udo Klimaschewski
*
* http://UdoJava.com/
* http://about.me/udo.klimaschewski
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
package net.sourceforge.plantuml.evalex;
/**
* Base interface which is required for all operators.
*/
public interface Operator extends LazyOperator {
/**
* Implementation for this operator.
*
* @param v1
* Operand 1.
* @param v2
* Operand 2.
* @return The result of the operation.
*/
public abstract Number eval(Number v1, Number v2);
}

View File

@ -0,0 +1,68 @@
/* ========================================================================
* 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.evalex;
import java.math.BigDecimal;
import java.math.RoundingMode;
public class Snipset1 {
public static void main(String[] args) {
Number result = null;
Expression expression = new Expression("1+1/3");
result = expression.eval();
expression.setPrecision(2);
result = expression.eval();
result = new Expression("(3.4 + -4.1)/2").eval();
result = new Expression("SQRT(a^2 + b^2)").with("a", "2.4").and("b", "9.253").eval();
BigDecimal a = new BigDecimal("2.4");
BigDecimal b = new BigDecimal("9.235");
result = new Expression("SQRT(a^2 + b^2)").with("a", a).and("b", b).eval();
result = new Expression("2.4/PI").setPrecision(128).setRoundingMode(RoundingMode.UP).eval();
result = new Expression("random() > 0.5").eval();
result = new Expression("not(x<7 || sqrt(max(x,9,3,min(4,3))) <= 3)").with("x", "22.9").eval();
System.err.println("foo1=" + result);
result = new Expression("log10(100)").eval();
}
}

View File

@ -0,0 +1,50 @@
/* ========================================================================
* 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.evalex;
public class Snipset2 {
public static void main(String[] args) {
Number result = null;
Expression expression = new Expression("'FOO'+'DUMMY'");
result = expression.eval();
System.err.println("result=" + result);
// Print FOODUMMY
}
}

View File

@ -0,0 +1,49 @@
/* ========================================================================
* 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.evalex;
public class Snipset3 {
public static void main(String[] args) {
Number result = null;
Expression expression = new Expression("3+4");
result = expression.eval();
System.err.println("foo1=" + result);
}
}

View File

@ -176,5 +176,10 @@ public class GraphicStrings extends AbstractTextBlock implements IEntityImage {
public boolean isHidden() {
return false;
}
public double getOverscanX(StringBounder stringBounder) {
return 0;
}
}

View File

@ -182,8 +182,10 @@ public class QuoteUtils {
"Cercner Guerr Frnyrq Rairybcrf...",
"Lbh xabj gung guvat lbh whfg qvq? Qba'g qb gung",
"Vg gbbx zr n ybat gvzr gb haqrefgnaq gung vs lbh jnag gb qb guvf wbo jryy lbh unir gb fgnl qrgnpurq.",
"Qb lbh yvxr lbhe zbeavat grn jrnx be fgebat ?", "Jvagre vf pbzvat",
"Jung sbbyf gurfr zbegnyf or!", "Fbzrguvat jvpxrq guvf jnl pbzrf.",
"Qb lbh yvxr lbhe zbeavat grn jrnx be fgebat ?",
"Jvagre vf pbzvat",
"Jung sbbyf gurfr zbegnyf or!",
"Fbzrguvat jvpxrq guvf jnl pbzrf.",
"V guvax V trg vg, jung jnf vg? Cbxre Avtug? Onpurybe Cnegl?",
"Vg'f nyevtug gb or fpnerq. Erzrzore, gurer vf ab pbhentr jvgubhg srne.",
"Guebhtu ernqvarff naq qvfpvcyvar jr ner znfgref bs bhe sngr.",
@ -197,14 +199,18 @@ public class QuoteUtils {
"Qbpgbe fnlf lbh'er pherq ohg lbh fgvyy srry gur cnva",
"Vf negvsvpvny vagryyvtrapr gur rknpg bccbfvgr bs angheny fghcvqvgl ?",
"Sbeprzrag, pn qrcraq, pn qrcnffr...",
"Gurer'f orra n cnggrea bs vafhobeqvangr orunivbe erpragyl.", "Ab. Jr ner abg na rssrpgvir grnz.",
"Gurer'f orra n cnggrea bs vafhobeqvangr orunivbe erpragyl.",
"Ab. Jr ner abg na rssrpgvir grnz.",
"Bhe wbo vf abg gb erzrzore... erzrzore?",
"Guvf vf zvffvba pbageby. Ubj ner lbh nyy qbvat guvf ybiryl zbeavat?",
"Vs lbh pbhyq frr lbhe jubyr yvsr ynvq bhg va sebag bs lbh, jbhyq lbh punatr guvatf?",
"Vf guvf n aba-mreb-fhz tnzr?", "Abj gung'f n cebcre vagebqhpgvba.",
"Vf guvf n aba-mreb-fhz tnzr?",
"Abj gung'f n cebcre vagebqhpgvba.",
"Rirelguvat unf punatrq naq vg jba'g fgbc punatvat nalgvzr fbba.",
"Jung znxrf lbh qvssrerag znxrf lbh qnatrebhf", "Qviretrapr vf rkgerzryl qnatrebhf",
"V'z Qviretrag. Naq V pna'g or pbagebyyrq", "Znl gur bqqf or rire va lbhe snibe",
"Jung znxrf lbh qvssrerag znxrf lbh qnatrebhf",
"Qviretrapr vf rkgerzryl qnatrebhf",
"V'z Qviretrag. Naq V pna'g or pbagebyyrq",
"Znl gur bqqf or rire va lbhe snibe",
"Ab WninFpevcg senzrjbexf jrer perngrq qhevat gur jevgvat bs guvf zrffntr.",
"P'rfg cerffr-cherr dhv g'nf vagreebtr ?",
"Ybbx, nygreangvir snpgf ner abg snpgf. Gurl'er snyfrubbqf",
@ -213,27 +219,36 @@ public class QuoteUtils {
"Guvf oht vf n srngher nf qrfpevorq ol gur znexrgvat qrcnegzrag.",
"Abg rirelobql haqrefgnaqf gur uhzbe bs cebtenzzref.",
"Vs lbh yvir na beqvanel yvsr, nyy lbh'yy unir ner beqvanel fgbevrf.",
"Pbzr jvgu zr vs lbh jnag gb yvir", "Gh y'nf gebhir bh pryhv-yn ?",
"Pbzr jvgu zr vs lbh jnag gb yvir",
"Gh y'nf gebhir bh pryhv-yn ?",
"Qb lbh ernyyl guvax lbh unir n punapr ntnvafg hf, Ze. Pbjobl?",
"Nggragvba, jubrire lbh ner, guvf punaary vf erfreirq sbe rzretrapl pnyyf bayl.",
"Qbrf vg fbhaq yvxr V'z beqrevat n cvmmn? ", "Jr'er tbaan arrq fbzr zber SOV thlf, V thrff.",
"Qbrf vg fbhaq yvxr V'z beqrevat n cvmmn? ",
"Jr'er tbaan arrq fbzr zber SOV thlf, V thrff.",
"Trg ernql sbe ehfu ubhe",
"V unir gb jnea lbh, V'ir urneq eryngvbafuvcf onfrq ba vagrafr rkcrevraprf arire jbex.",
"Nalguvat ryfr ohg gur onfrzrag gung'yy xrrc guvf ryringbe sebz snyyvat?",
"Vf guvf grfgvat jurgure V'z n ercyvpnag be n yrfovna, Ze. Qrpxneq? ",
"V'ir qbar... dhrfgvbanoyr guvatf", "Jbhyq lbh... yvxr gb or hctenqrq?",
"V'ir qbar... dhrfgvbanoyr guvatf",
"Jbhyq lbh... yvxr gb or hctenqrq?",
"Snhg erpbaanvger... p'rfg qh oehgny!",
"Fv ba oevpbynvg cyhf fbhirag, ba nhenvg zbvaf yn grgr nhk orgvfrf.",
"Wr invf yhv snver har beqbaanapr, rg har frirer...",
"Znvf vy pbaanvg cnf Enbhy, pr zrp! vy in nibve ha erirvy cravoyr.",
"W'nv ibhyh rger qvcybzngr n pnhfr qr ibhf gbhf, rivgre dhr yr fnat pbhyr.",
"Vtabenapr oevatf punbf, abg xabjyrqtr.", "Yrneavat vf nyjnlf n cnvashy cebprff.",
"V'z fbeel, ner lbh sebz gur cnfg ?", "Unir lbh gevrq gheavat vg bss naq ba ntnva ?",
"Vtabenapr oevatf punbf, abg xabjyrqtr.",
"Yrneavat vf nyjnlf n cnvashy cebprff.",
"V'z fbeel, ner lbh sebz gur cnfg ?",
"Unir lbh gevrq gheavat vg bss naq ba ntnva ?",
"Vs lbh qba'g xabj jurer lbh ner tbvat nal ebnq pna gnxr lbh gurer",
"Xrrc pnyz naq cerff Pgey-Nyg-Qry", "Vs lbh glcr Tbbtyr vagb Tbbtyr, lbh pna oernx gur Vagrearg.",
"V unir cneg bs n cyna.", "V'z cerggl fher gur nafjre vf: V nz Tebbg.",
"Nalguvat gung pna cbffvoyl tb jebat, qbrf", "Cyhf pn engr, cyhf ba n qr punapr dhr pn znepur",
"Fb V thrff gur sbeghar gryyre'f evtug...", "Jura rirelguvat'f tbar jebat fbzrubj...",
"Xrrc pnyz naq cerff Pgey-Nyg-Qry",
"Vs lbh glcr Tbbtyr vagb Tbbtyr, lbh pna oernx gur Vagrearg.",
"V unir cneg bs n cyna.",
"V'z cerggl fher gur nafjre vf: V nz Tebbg.",
"Nalguvat gung pna cbffvoyl tb jebat, qbrf",
"Cyhf pn engr, cyhf ba n qr punapr dhr pn znepur",
"Fb V thrff gur sbeghar gryyre'f evtug...",
"Jura rirelguvat'f tbar jebat fbzrubj...",
"V qba'g jnag gb yvir ba guvf cynarg nalzber",
"Oba, p'rfg y'urher bh yrf fbhiravef fr enzrarag...",
"Fhpprff pbafvfgf bs tbvat sebz snvyher gb snvyher jvgubhg ybff bs raguhfvnfz",
@ -241,31 +256,50 @@ public class QuoteUtils {
"Jre xnzcsg, xnaa ireyvrera. Jre avpug xnzcsg, ung fpuba ireybera.",
"P'rfg nh cvrq qh zhe dhr y'ba ibvg yr zvrhk yr zhe.",
"Jr xabj ubj uhznaf jbex. Gurl ner nyy fb cerqvpgnoyr.",
"Pyrneyl, lbh unir arire zrg n jbzna.",
"Gur qbtznf bs gur dhvrg cnfg ner vanqrdhngr gb gur fgbezl cerfrag",
"Ab jnl gb cerirag guvf, fnlf bayl angvba jurer guvf erthyneyl unccraf",
"L'n dhrydhrf dhrfgvbaf dhv erfgrag fbhf fvyrapr...",
"Vs gurer vf ab fbyhgvba, gurer vf ab ceboyrz",
"V unir zrzbevrf, ohg V pna'g gryy vs gurl'er erny.", "L n pbzzr ha tbhg nzre ra abhf",
"L n qrf fvyraprf dhv qvfrag ornhpbhc", "V frr lbh'ir unq fbzr qvfpvcyvanel ceboyrzf va gur cnfg.",
"V unir zrzbevrf, ohg V pna'g gryy vs gurl'er erny.",
"L n pbzzr ha tbhg nzre ra abhf",
"L n qrf fvyraprf dhv qvfrag ornhpbhc",
"V frr lbh'ir unq fbzr qvfpvcyvanel ceboyrzf va gur cnfg.",
"Cercnengvba vf gur xrl gb fhpprffshy, vapbafcvphbhf gvzr geniry.",
"Vg'f arire gbb yngr gb or jub lbh zvtug unir orra.",
"Rg cbhe nyyre purm Zvpxrl vyf ibag fherzrag cnf pbafgehver har tner gbhf yrf 100 zrgerf",
"Nyy lbhe onfr ner orybat gb hf", "Znqr ba Rnegu ol uhznaf", "Jvaaref Qba'g Hfr Qehtf",
"Nyy lbhe onfr ner orybat gb hf",
"Znqr ba Rnegu ol uhznaf",
"Jvaaref Qba'g Hfr Qehtf",
"Lbh xabj jung fhecevfrq zr gur zbfg? Vg jnfa'g zrrgvat gurz. Vg jnf zrrgvat lbh.",
"Va jne gurer ner ab jvaaref, bayl jvqbjf",
"Vs lbh guvax guvf Havirefr vf onq, lbh fubhyq frr fbzr bs gur bguref", "Cnp-Zna'f n onq thl?",
"Zl ernyvgl vf whfg qvssrerag guna lbhef", "L'ra n dh'bag rffnlr, vyf bag rh qrf ceboyrzrf",
"Vs lbh guvax guvf Havirefr vf onq, lbh fubhyq frr fbzr bs gur bguref",
"Cnp-Zna'f n onq thl?",
"Zl ernyvgl vf whfg qvssrerag guna lbhef",
"L'ra n dh'bag rffnlr, vyf bag rh qrf ceboyrzrf",
"Gb ree vf uhzna, ohg gb ernyyl sbhy guvatf hc erdhverf n pbzchgre.",
"Vs lbh oryvrir rirelguvat lbh ernq, lbh orggre abg ernq",
"Gurer vf ab ceboyrz fb onq lbh pna'g znxr vg jbefr", "Pn p'rfg qh ybheq... Ha gehp qr znynqr.",
"V qb abg guvax, gung V guvax.. V guvax.", "Gurer ner cynprf ybjre guna gur onfrzrag",
"Gurer vf ab ceboyrz fb onq lbh pna'g znxr vg jbefr",
"Pn p'rfg qh ybheq... Ha gehp qr znynqr.",
"V qb abg guvax, gung V guvax.. V guvax.",
"Gurer ner cynprf ybjre guna gur onfrzrag",
"Gurer ner 10 glcrf bs crbcyr: gubfr jub haqrefgnaq ovanel, naq gubfr jub qba'g.",
"Cyrnfr zvaq gur tnc orgjrra gur genva naq gur cyngsbez", "Nfuvzbgb av tb-puhv xhqnfnv",
"Cyrnfr zvaq gur tnc orgjrra gur genva naq gur cyngsbez",
"Nfuvzbgb av tb-puhv xhqnfnv",
"Vs lbh'er erprvivat guvf genafzvffvba, znxr ab nggrzcg gb pbzr gb vgf cbvag bs bevtva.",
"Obl, qb V ungr orvat evtug nyy gur gvzr!",
"Jub funirf gur oneore jub funirf nyy gur zra jub qba'g funir gurzfryirf?",
"V haqrefgnaq uhzna rzbgvbaf, nygubhtu V qb abg srry gurz zlfrys.",
"Lbh qvqa'g fnl gur zntvp jbeq!");
"Lbh qvqa'g fnl gur zntvp jbeq!",
"Gurer vf ab ceboyrz gung n ynpx bs fbyhgvba jba'g svanyyl erfbyir.",
"V unir n inthr srryvat bs vzcraqvat zvfsbeghar.",
"Jura lbh'er va gebhoyr, pbashfr rirelguvat",
"Jung gur uryy vf Cebwrpg Ryebaq?",
"Qba'g qvt hc gur ovt obk bs cyhgbavhz, Znex",
"Uryc vf bayl 140 zvyyvba zvyrf njnl.",
"P unf gur fcrrq naq rssvpvrapl bs nffrzoyl ynathntr pbzovarq jvgu ernqnovyvgl bs nffrzoyl ynathntr",
"Crey vf gur bayl ynathntr gung ybbxf gur fnzr orsber naq nsgre EFN rapelcgvba",
"Lbh pnaabg pher jung ur unf.", "Gur zber vg snvyf, gur zber yvxryl vg vf gung vg jvyy jbex");
private QuoteUtils() {
}

View File

@ -49,7 +49,7 @@ public class Rainbow {
private Rainbow(int colorArrowSeparationSpace) {
this.colorArrowSeparationSpace = colorArrowSeparationSpace;
}
@Override
public String toString() {
return colors.toString();
@ -74,7 +74,7 @@ public class Rainbow {
result.colors.add(color);
return result;
}
public static Rainbow build(ISkinParam skinParam, String colorString, int colorArrowSeparationSpace) {
if (colorString == null) {
return Rainbow.none();
@ -86,6 +86,15 @@ public class Rainbow {
return result;
}
public boolean isInvisible() {
for (HtmlColorAndStyle style : colors) {
if (style.getStyle().isInvisible()) {
return true;
}
}
return false;
}
public List<HtmlColorAndStyle> getColors() {
return Collections.unmodifiableList(colors);
}

View File

@ -40,6 +40,7 @@ import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.sourceforge.plantuml.AParentFolder;
import net.sourceforge.plantuml.BackSlash;
public class Define {
@ -49,8 +50,10 @@ public class Define {
private final String definitionQuoted;
private final boolean emptyParentheses;
private Pattern pattern;
private final AParentFolder currentDir;
public Define(String key, List<String> lines, boolean emptyParentheses) {
public Define(String key, List<String> lines, boolean emptyParentheses, AParentFolder currentDir) {
this.currentDir = currentDir;
this.emptyParentheses = emptyParentheses;
if (lines == null) {
this.definition = null;

View File

@ -49,6 +49,7 @@ import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.sourceforge.plantuml.AParentFolder;
import net.sourceforge.plantuml.Log;
import net.sourceforge.plantuml.api.ApiWarning;
import net.sourceforge.plantuml.version.Version;
@ -114,8 +115,8 @@ public class Defines implements Truth {
return name.substring(0, x);
}
public void define(String name, List<String> value, boolean emptyParentheses) {
values.put(name, new Define(name, value, emptyParentheses));
public void define(String name, List<String> value, boolean emptyParentheses, AParentFolder currentDir) {
values.put(name, new Define(name, value, emptyParentheses, currentDir));
magic = null;
}

View File

@ -97,7 +97,7 @@ public class Variables {
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)";
final String var2 = "(##" + varName + "##)|(##" + varName + "\\b)|(\\b" + varName + "##)|(\\b" + varName + "\\b)";
if (variable.getDefaultValue() == null) {
regex.append("(?:(?:\\s*\"([^\"]*)\"\\s*)|(?:\\s*'([^']*)'\\s*)|\\s*"
+ "((?:\\([^()]*\\)|[^,'\"])*?)" + ")");

View File

@ -75,7 +75,7 @@ public class Preprocessor2 implements ReadLineNumbered {
filters.add(new IfManagerFilter(defines));
filters.add(new PreprocessorDefine4Apply(defines));
filters.add(new SubPreprocessor2(charset, definitionsContainer));
filters.add(new PreprocessorDefine3Learner(defines));
filters.add(new PreprocessorDefine3Learner(defines, importedFiles.getCurrentDir()));
filters.add(include);
this.source = filters.applyFilter(reader);

View File

@ -39,12 +39,12 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import net.sourceforge.plantuml.AParentFolder;
import net.sourceforge.plantuml.CharSequence2;
import net.sourceforge.plantuml.StringUtils;
import net.sourceforge.plantuml.command.regex.Matcher2;
import net.sourceforge.plantuml.command.regex.MyPattern;
import net.sourceforge.plantuml.command.regex.Pattern2;
import net.sourceforge.plantuml.preproc.Defines;
import net.sourceforge.plantuml.preproc.DefinesGet;
import net.sourceforge.plantuml.preproc.ReadLine;
import net.sourceforge.plantuml.utils.StartUtils;
@ -55,7 +55,7 @@ public class PreprocessorDefine3Learner implements ReadFilter {
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 + ")"
private static final Pattern2 defineShortPattern = MyPattern.cmpile("^[%s]*!define[%s]+(" + ID + ARG + ")"
+ "(?:[%s]+(.*))?$");
private static final Pattern2 filenamePattern = MyPattern.cmpile("^[%s]*!filename[%s]+(.+)$");
private static final Pattern2 undefPattern = MyPattern.cmpile("^[%s]*!undef[%s]+(" + ID + ")$");
@ -63,13 +63,15 @@ public class PreprocessorDefine3Learner implements ReadFilter {
private static final Pattern2 enddefinelongPattern = MyPattern.cmpile("^[%s]*" + END_DEFINE_LONG + "[%s]*$");
private final DefinesGet defines;
private final AParentFolder currentDir;
public PreprocessorDefine3Learner(DefinesGet defines) {
public PreprocessorDefine3Learner(DefinesGet defines, AParentFolder currentDir) {
this.defines = defines;
this.currentDir = currentDir;
}
public static boolean isLearningLine(CharSequence2 s) {
Matcher2 m = definePattern.matcher(s);
Matcher2 m = defineShortPattern.matcher(s);
if (m.find()) {
return true;
}
@ -107,9 +109,9 @@ public class PreprocessorDefine3Learner implements ReadFilter {
manageFilename(m);
continue;
}
m = definePattern.matcher(s);
m = defineShortPattern.matcher(s);
if (m.find()) {
manageDefine(source, m, s.toString().trim().endsWith("()"));
manageDefineShort(source, m, s.toString().trim().endsWith("()"));
continue;
}
m = definelongPattern.matcher(s);
@ -142,7 +144,7 @@ public class PreprocessorDefine3Learner implements ReadFilter {
return;
}
if (enddefinelongPattern.matcher(read).find()) {
defines.get().define(group1, def, emptyParentheses);
defines.get().define(group1, def, emptyParentheses, currentDir);
return;
}
def.add(read.toString2());
@ -154,15 +156,15 @@ public class PreprocessorDefine3Learner implements ReadFilter {
this.defines.get().overrideFilename(group1);
}
private void manageDefine(ReadLine source, Matcher2 m, boolean emptyParentheses) throws IOException {
private void manageDefineShort(ReadLine source, Matcher2 m, boolean emptyParentheses) throws IOException {
final String group1 = m.group(1);
final String group2 = m.group(2);
if (group2 == null) {
defines.get().define(group1, null, emptyParentheses);
defines.get().define(group1, null, emptyParentheses, null);
} else {
final List<String> strings = defines.get().applyDefines(group2);
if (strings.size() > 1) {
defines.get().define(group1, strings, emptyParentheses);
defines.get().define(group1, strings, emptyParentheses, null);
} else {
final StringBuilder value = new StringBuilder(strings.get(0));
while (StringUtils.endsWithBackslash(value.toString())) {
@ -172,7 +174,7 @@ public class PreprocessorDefine3Learner implements ReadFilter {
}
final List<String> li = new ArrayList<String>();
li.add(value.toString());
defines.get().define(group1, li, emptyParentheses);
defines.get().define(group1, li, emptyParentheses, null);
}
}
}

View File

@ -41,12 +41,14 @@ import net.sourceforge.plantuml.command.regex.RegexResult;
public class ComplementClose implements ComplementPattern {
public static final Complement CLOSE = new Complement() {
};
public IRegex toRegex(String suffix) {
return new RegexLeaf("CLOSED" + suffix, "(closed?)");
}
public Failable<Complement> getComplement(GanttDiagram system, RegexResult arg, String suffix) {
return Failable.<Complement> ok(new Complement() {
});
return Failable.<Complement> ok(CLOSE);
}
}

View File

@ -0,0 +1,54 @@
/* ========================================================================
* 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 net.sourceforge.plantuml.command.regex.IRegex;
import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.command.regex.RegexResult;
public class ComplementOpen implements ComplementPattern {
public static final Complement OPEN = new Complement() {
};
public IRegex toRegex(String suffix) {
return new RegexLeaf("OPEN" + suffix, "(opene?d?)");
}
public Failable<Complement> getComplement(GanttDiagram system, RegexResult arg, String suffix) {
return Failable.<Complement> ok(OPEN);
}
}

View File

@ -81,6 +81,7 @@ public class GanttDiagram extends AbstractPSystem implements Subject {
private final IHtmlColorSet colorSet = new HtmlColorSetSimple();
private final Collection<DayOfWeek> closedDayOfWeek = EnumSet.noneOf(DayOfWeek.class);
private final Collection<DayAsDate> closedDayAsDate = new HashSet<DayAsDate>();
private final Collection<DayAsDate> openedDayAsDate = new HashSet<DayAsDate>();
private GCalendar calendar;
private final Instant min = new InstantDay(0);
@ -180,8 +181,7 @@ public class GanttDiagram extends AbstractPSystem implements Subject {
return 100;
}
final DayAsDate day = getCalendarSimple().toDayAsDate((InstantDay) instant);
final DayOfWeek dayOfWeek = day.getDayOfWeek();
if (closedDayOfWeek.contains(dayOfWeek) || closedDayAsDate.contains(day)) {
if (isClosed(day)) {
return 0;
}
return 100;
@ -189,6 +189,26 @@ public class GanttDiagram extends AbstractPSystem implements Subject {
};
}
private boolean isClosed(final DayAsDate day) {
if (openedDayAsDate.contains(day)) {
return false;
}
final DayOfWeek dayOfWeek = day.getDayOfWeek();
return closedDayOfWeek.contains(dayOfWeek) || closedDayAsDate.contains(day);
}
public void closeDayOfWeek(DayOfWeek day) {
closedDayOfWeek.add(day);
}
public void closeDayAsDate(DayAsDate day) {
closedDayAsDate.add(day);
}
public void openDayAsDate(DayAsDate day) {
openedDayAsDate.add(day);
}
private void drawConstraints(final UGraphic ug, TimeScale timeScale) {
for (GanttConstraint constraint : constraints) {
constraint.getUDrawable(timeScale).drawU(ug);
@ -531,14 +551,6 @@ public class GanttDiagram extends AbstractPSystem implements Subject {
return 7 - closedDayOfWeek.size();
}
public void closeDayOfWeek(DayOfWeek day) {
closedDayOfWeek.add(day);
}
public void closeDayAsDate(DayAsDate day) {
closedDayAsDate.add(day);
}
public Instant convert(DayAsDate day) {
return calendar.fromDayAsDate(day);
}

View File

@ -47,7 +47,8 @@ import net.sourceforge.plantuml.graphic.HtmlColor;
public class VerbIsOrAre implements VerbPattern {
public Collection<ComplementPattern> getComplements() {
return Arrays.<ComplementPattern> asList(new ComplementClose(), new ComplementInColors2());
return Arrays
.<ComplementPattern> asList(new ComplementClose(), new ComplementOpen(), new ComplementInColors2());
}
public IRegex toRegex() {
@ -61,7 +62,13 @@ public class VerbIsOrAre implements VerbPattern {
final HtmlColor color = ((ComplementColors) complement).getCenter();
return manageColor(project, subject, color);
}
return manageClose(project, subject);
if (complement == ComplementClose.CLOSE) {
return manageClose(project, subject);
}
if (complement == ComplementOpen.OPEN) {
return manageOpen(project, subject);
}
return CommandExecutionResult.error("assertion fail");
}
};
}
@ -93,4 +100,19 @@ public class VerbIsOrAre implements VerbPattern {
}
return CommandExecutionResult.ok();
}
private CommandExecutionResult manageOpen(final GanttDiagram project, Subject subject) {
if (subject instanceof DayAsDate) {
final DayAsDate day = (DayAsDate) subject;
project.openDayAsDate(day);
}
if (subject instanceof DaysAsDates) {
final DaysAsDates days = (DaysAsDates) subject;
for (DayAsDate d : days) {
project.openDayAsDate(d);
}
}
return CommandExecutionResult.ok();
}
}

View File

@ -36,16 +36,10 @@
package net.sourceforge.plantuml.salt;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
import net.sourceforge.plantuml.StringUtils;
import net.sourceforge.plantuml.WithSprite;
import net.sourceforge.plantuml.command.BlocLines;
import net.sourceforge.plantuml.command.Command;
import net.sourceforge.plantuml.command.CommandExecutionResult;
import net.sourceforge.plantuml.command.FactorySpriteCommand;
import net.sourceforge.plantuml.command.regex.Matcher2;
import net.sourceforge.plantuml.command.regex.MyPattern;
import net.sourceforge.plantuml.command.regex.Pattern2;
@ -56,7 +50,7 @@ public class DataSourceImpl implements DataSource {
private final List<Terminated<String>> data = new ArrayList<Terminated<String>>();
public DataSourceImpl(List<String> data) {
final Pattern2 p = MyPattern.cmpile("\\{[-+^#!*/]?");
final Pattern2 p = MyPattern.cmpile("\\{(?:[-+^#!*/]|S-|SI|S)?");
for (String s : data) {
final StringTokenizer st = new StringTokenizer(s, "|}", true);

View File

@ -74,6 +74,7 @@ import net.sourceforge.plantuml.salt.factory.ElementFactoryPyramid;
import net.sourceforge.plantuml.salt.factory.ElementFactoryRadioOff;
import net.sourceforge.plantuml.salt.factory.ElementFactoryRadioOn;
import net.sourceforge.plantuml.salt.factory.ElementFactoryRetrieveFromDictonnary;
import net.sourceforge.plantuml.salt.factory.ElementFactoryScroll;
import net.sourceforge.plantuml.salt.factory.ElementFactoryTab;
import net.sourceforge.plantuml.salt.factory.ElementFactoryText;
import net.sourceforge.plantuml.salt.factory.ElementFactoryTextField;
@ -178,6 +179,7 @@ public class PSystemSalt extends AbstractPSystem implements WithSprite {
// cpx.add(new ElementFactorySimpleFrame(source, dictionnary));
cpx.add(new ElementFactoryPyramid(source, dictionary));
cpx.add(new ElementFactoryScroll(source, dictionary));
cpx.add(new ElementFactoryBorder(source, dictionary));
for (AbstractElementFactoryComplex f : cpx) {

View File

@ -0,0 +1,144 @@
/* ========================================================================
* 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.salt.element;
import java.awt.geom.Dimension2D;
import net.sourceforge.plantuml.Dimension2DDouble;
import net.sourceforge.plantuml.ISkinSimple;
import net.sourceforge.plantuml.graphic.HtmlColorUtils;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.salt.Positionner2;
import net.sourceforge.plantuml.salt.factory.ScrollStrategy;
import net.sourceforge.plantuml.ugraphic.UChangeBackColor;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.ULine;
import net.sourceforge.plantuml.ugraphic.UPath;
import net.sourceforge.plantuml.ugraphic.URectangle;
import net.sourceforge.plantuml.ugraphic.UTranslate;
public class ElementPyramidScrolled extends ElementPyramid {
private final double v1 = 15;
private final double v2 = 12;
private final ScrollStrategy scrollStrategy;
public ElementPyramidScrolled(Positionner2 positionner, ISkinSimple spriteContainer, ScrollStrategy scrollStrategy) {
super(positionner, TableStrategy.DRAW_OUTSIDE, null, spriteContainer);
this.scrollStrategy = scrollStrategy;
}
@Override
public Dimension2D getPreferredDimension(StringBounder stringBounder, double x, double y) {
final Dimension2D result = super.getPreferredDimension(stringBounder, x, y);
if (scrollStrategy == ScrollStrategy.HORIZONTAL_ONLY) {
return Dimension2DDouble.delta(result, 0, 30);
}
if (scrollStrategy == ScrollStrategy.VERTICAL_ONLY) {
return Dimension2DDouble.delta(result, 30, 0);
}
return Dimension2DDouble.delta(result, 30);
}
@Override
public void drawU(UGraphic ug, int zIndex, Dimension2D dimToUse) {
super.drawU(ug, zIndex, dimToUse);
final Dimension2D dim = super.getPreferredDimension(ug.getStringBounder(), 0, 0);
if (scrollStrategy == ScrollStrategy.BOTH || scrollStrategy == ScrollStrategy.VERTICAL_ONLY) {
drawV(ug.apply(new UTranslate(dim.getWidth() + 4, 0)), v1, dim.getHeight());
}
if (scrollStrategy == ScrollStrategy.BOTH || scrollStrategy == ScrollStrategy.HORIZONTAL_ONLY) {
drawH(ug.apply(new UTranslate(0, dim.getHeight() + 4)), dim.getWidth(), v1);
}
}
private UPath getTr0() {
final UPath poly = new UPath();
poly.moveTo(3, 0);
poly.lineTo(6, 5);
poly.lineTo(0, 5);
poly.lineTo(3, 0);
poly.closePath();
return poly;
}
private UPath getTr180() {
final UPath poly = new UPath();
poly.moveTo(3, 5);
poly.lineTo(6, 0);
poly.lineTo(0, 0);
poly.lineTo(3, 5);
poly.closePath();
return poly;
}
private UPath getTr90() {
final UPath poly = new UPath();
poly.moveTo(0, 3);
poly.lineTo(5, 6);
poly.lineTo(5, 0);
poly.lineTo(0, 3);
poly.closePath();
return poly;
}
private UPath getTr270() {
final UPath poly = new UPath();
poly.moveTo(5, 3);
poly.lineTo(0, 6);
poly.lineTo(0, 0);
poly.lineTo(5, 3);
poly.closePath();
return poly;
}
private void drawV(UGraphic ug, double width, double height) {
ug.draw(new URectangle(width, height));
ug.apply(new UTranslate(0, v2)).draw(new ULine(width, 0));
ug.apply(new UTranslate(0, height - v2)).draw(new ULine(width, 0));
ug.apply(new UTranslate(4, 4)).apply(new UChangeBackColor(HtmlColorUtils.BLACK)).draw(getTr0());
ug.apply(new UTranslate(4, height - v2 + 4)).apply(new UChangeBackColor(HtmlColorUtils.BLACK)).draw(getTr180());
}
private void drawH(UGraphic ug, double width, double height) {
ug.draw(new URectangle(width, height));
ug.apply(new UTranslate(v2, 0)).draw(new ULine(0, height));
ug.apply(new UTranslate(width - v2, 0)).draw(new ULine(0, height));
ug.apply(new UTranslate(4, 4)).apply(new UChangeBackColor(HtmlColorUtils.BLACK)).draw(getTr90());
ug.apply(new UTranslate(width - v2 + 4, 4)).apply(new UChangeBackColor(HtmlColorUtils.BLACK)).draw(getTr270());
}
}

View File

@ -35,8 +35,6 @@
*/
package net.sourceforge.plantuml.salt.factory;
import java.awt.Font;
import net.sourceforge.plantuml.ISkinSimple;
import net.sourceforge.plantuml.salt.DataSource;
import net.sourceforge.plantuml.salt.Terminated;

View File

@ -35,7 +35,6 @@
*/
package net.sourceforge.plantuml.salt.factory;
import java.awt.Font;
import java.util.Arrays;
import java.util.List;

View File

@ -35,7 +35,6 @@
*/
package net.sourceforge.plantuml.salt.factory;
import java.awt.Font;
import java.util.Arrays;
import java.util.List;

View File

@ -35,8 +35,6 @@
*/
package net.sourceforge.plantuml.salt.factory;
import java.awt.Font;
import net.sourceforge.plantuml.ISkinSimple;
import net.sourceforge.plantuml.salt.DataSource;
import net.sourceforge.plantuml.salt.Terminated;

View File

@ -35,8 +35,6 @@
*/
package net.sourceforge.plantuml.salt.factory;
import java.awt.Font;
import net.sourceforge.plantuml.salt.DataSource;
import net.sourceforge.plantuml.salt.Dictionary;
import net.sourceforge.plantuml.salt.Terminated;

View File

@ -35,7 +35,6 @@
*/
package net.sourceforge.plantuml.salt.factory;
import java.awt.Font;
import java.util.Arrays;
import java.util.List;

View File

@ -35,7 +35,6 @@
*/
package net.sourceforge.plantuml.salt.factory;
import java.awt.Font;
import java.util.Arrays;
import java.util.List;

View File

@ -0,0 +1,77 @@
/* ========================================================================
* 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.salt.factory;
import net.sourceforge.plantuml.salt.DataSource;
import net.sourceforge.plantuml.salt.Dictionary;
import net.sourceforge.plantuml.salt.Positionner2;
import net.sourceforge.plantuml.salt.Terminated;
import net.sourceforge.plantuml.salt.element.Element;
import net.sourceforge.plantuml.salt.element.ElementPyramidScrolled;
public class ElementFactoryScroll extends AbstractElementFactoryComplex {
public ElementFactoryScroll(DataSource dataSource, Dictionary dictionary) {
super(dataSource, dictionary);
}
public Terminated<Element> create() {
if (ready() == false) {
throw new IllegalStateException();
}
final Terminated<String> tmp = getDataSource().next();
final String header = tmp.getElement();
assert header.startsWith("{");
final Positionner2 positionner = new Positionner2();
while (getDataSource().peek(0).getElement().equals("}") == false) {
final Terminated<Element> next = getNextElement();
positionner.add(next);
}
final Terminated<String> next = getDataSource().next();
return new Terminated<Element>(new ElementPyramidScrolled(positionner, getDictionary(),
ScrollStrategy.fromDesc(header)), next.getTerminator());
}
public boolean ready() {
final String text = getDataSource().peek(0).getElement();
if (text.equals("{S") || text.equals("{S-") || text.equals("{SI")) {
return true;
}
return false;
}
}

View File

@ -35,8 +35,6 @@
*/
package net.sourceforge.plantuml.salt.factory;
import java.awt.Font;
import net.sourceforge.plantuml.salt.DataSource;
import net.sourceforge.plantuml.salt.Dictionary;
import net.sourceforge.plantuml.salt.Terminated;

View File

@ -35,7 +35,6 @@
*/
package net.sourceforge.plantuml.salt.factory;
import java.awt.Font;
import java.util.Arrays;
import net.sourceforge.plantuml.ISkinSimple;

View File

@ -35,8 +35,6 @@
*/
package net.sourceforge.plantuml.salt.factory;
import java.awt.Font;
import net.sourceforge.plantuml.ISkinSimple;
import net.sourceforge.plantuml.salt.DataSource;
import net.sourceforge.plantuml.salt.Terminated;

View File

@ -35,8 +35,6 @@
*/
package net.sourceforge.plantuml.salt.factory;
import java.awt.Font;
import net.sourceforge.plantuml.salt.DataSource;
import net.sourceforge.plantuml.salt.Dictionary;
import net.sourceforge.plantuml.salt.Terminated;

View File

@ -0,0 +1,52 @@
/* ========================================================================
* 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.salt.factory;
public enum ScrollStrategy {
BOTH, VERTICAL_ONLY, HORIZONTAL_ONLY;
public static ScrollStrategy fromDesc(String s) {
if (s.endsWith("-")) {
return HORIZONTAL_ONLY;
}
if (s.endsWith("I")) {
return VERTICAL_ONLY;
}
return BOTH;
}
}

View File

@ -58,7 +58,6 @@ import net.sourceforge.plantuml.UmlDiagramType;
import net.sourceforge.plantuml.core.DiagramDescription;
import net.sourceforge.plantuml.core.ImageData;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.cucadiagram.DisplayPositionned;
import net.sourceforge.plantuml.cucadiagram.EntityPortion;
import net.sourceforge.plantuml.graphic.HtmlColor;
import net.sourceforge.plantuml.graphic.SymbolContext;

View File

@ -135,7 +135,7 @@ public class ComponentRoseArrow extends AbstractComponentRoseArrow {
final double posArrow;
final double yText;
if (belowForResponse && getDirection2() == ArrowDirection.RIGHT_TO_LEFT_REVERSE) {
if (isBelowForResponse()) {
posArrow = 0;
yText = getMarginY();
} else {
@ -164,6 +164,10 @@ public class ComponentRoseArrow extends AbstractComponentRoseArrow {
getTextBlock().drawU(ug.apply(new UTranslate(textPos, yText)));
}
private boolean isBelowForResponse() {
return belowForResponse && getDirection2() == ArrowDirection.RIGHT_TO_LEFT_REVERSE;
}
private void drawDressing1(UGraphic ug, double x, ArrowDressing dressing, ArrowDecoration decoration) {
if (decoration == ArrowDecoration.CIRCLE) {
@ -272,19 +276,26 @@ public class ComponentRoseArrow extends AbstractComponentRoseArrow {
}
public Point2D getStartPoint(StringBounder stringBounder, Dimension2D dimensionToUse) {
final double textHeight = getTextHeight(stringBounder);
final double y = getYPoint(stringBounder);
if (getDirection2() == ArrowDirection.LEFT_TO_RIGHT_NORMAL) {
return new Point2D.Double(getPaddingX(), textHeight + getPaddingY());
return new Point2D.Double(getPaddingX(), y);
}
return new Point2D.Double(dimensionToUse.getWidth() + getPaddingX(), textHeight + getPaddingY());
return new Point2D.Double(dimensionToUse.getWidth() + getPaddingX(), y);
}
public Point2D getEndPoint(StringBounder stringBounder, Dimension2D dimensionToUse) {
final double textHeight = getTextHeight(stringBounder);
final double y = getYPoint(stringBounder);
if (getDirection2() == ArrowDirection.LEFT_TO_RIGHT_NORMAL) {
return new Point2D.Double(dimensionToUse.getWidth() + getPaddingX(), textHeight + getPaddingY());
return new Point2D.Double(dimensionToUse.getWidth() + getPaddingX(), y);
}
return new Point2D.Double(getPaddingX(), textHeight + getPaddingY());
return new Point2D.Double(getPaddingX(), y);
}
private double getYPoint(StringBounder stringBounder) {
if (isBelowForResponse()) {
return getPaddingY();
}
return getTextHeight(stringBounder) + getPaddingY();
}
final private ArrowDirection getDirection2() {

View File

@ -80,4 +80,8 @@ public abstract class AbstractEntityImage extends AbstractTextBlock implements I
return Margins.NONE;
}
public double getOverscanX(StringBounder stringBounder) {
return 0;
}
}

View File

@ -156,4 +156,9 @@ public final class ConcurrentStateImage extends AbstractTextBlock implements IEn
public ShapeType getShapeType() {
return ShapeType.RECTANGLE;
}
public double getOverscanX(StringBounder stringBounder) {
return 0;
}
}

View File

@ -142,6 +142,10 @@ public final class CucaDiagramFileMakerSvek2InternalImage extends AbstractTextBl
public HtmlColor getBackcolor() {
return skinParam.getBackgroundColor();
}
public double getOverscanX(StringBounder stringBounder) {
return 0;
}
public boolean isHidden() {
return false;

View File

@ -366,9 +366,10 @@ public class DotStringFactory implements Moveable {
|| sh.getType() == ShapeType.RECTANGLE_WITH_CIRCLE_INSIDE || sh.getType() == ShapeType.FOLDER
|| sh.getType() == ShapeType.DIAMOND) {
final List<Point2D.Double> points = svgResult.substring(idx).extractList(SvgResult.POINTS_EQUALS);
final double minX = SvekUtils.getMinX(points);
final double minY = SvekUtils.getMinY(points);
corner1.manage(minX, minY);
final double overscanX = sh.getOverscanX(stringBounder);
final double minX = SvekUtils.getMinX(points);
corner1.manage(minX - overscanX, minY);
sh.moveSvek(minX, minY);
} else if (sh.getType() == ShapeType.ROUND_RECTANGLE) {
final int idx2 = svg.indexOf("d=\"", idx + 1);

View File

@ -94,5 +94,10 @@ public class EntityImageProtected extends AbstractTextBlock implements IEntityIm
public Margins getShield(StringBounder stringBounder) {
return orig.getShield(stringBounder);
}
public double getOverscanX(StringBounder stringBounder) {
return orig.getOverscanX(stringBounder);
}
}

View File

@ -196,5 +196,10 @@ public class GraphvizCrash extends AbstractTextBlock implements IEntityImage {
public Margins getShield(StringBounder stringBounder) {
return Margins.NONE;
}
public double getOverscanX(StringBounder stringBounder) {
return 0;
}
}

View File

@ -44,8 +44,10 @@ public interface IEntityImage extends Hideable, TextBlockBackcolored {
public static final int MARGIN = 5;
public static final int MARGIN_LINE = 5;
ShapeType getShapeType();
public ShapeType getShapeType();
Margins getShield(StringBounder stringBounder);
public Margins getShield(StringBounder stringBounder);
public double getOverscanX(StringBounder stringBounder);
}

View File

@ -97,5 +97,10 @@ public final class InnerActivity extends AbstractTextBlock implements IEntityIma
public boolean isHidden() {
return im.isHidden();
}
public double getOverscanX(StringBounder stringBounder) {
return 0;
}
}

View File

@ -146,5 +146,10 @@ public final class InnerStateAutonom extends AbstractTextBlock implements IEntit
public boolean isHidden() {
return im.isHidden();
}
public double getOverscanX(StringBounder stringBounder) {
return 0;
}
}

View File

@ -340,4 +340,8 @@ public class Shape implements Positionable, IShapePseudo, Hideable {
}
return pt;
}
public double getOverscanX(StringBounder stringBounder) {
return image.getOverscanX(stringBounder);
}
}

View File

@ -134,4 +134,8 @@ public final class SvekResult extends AbstractTextBlock implements IEntityImage,
return false;
}
public double getOverscanX(StringBounder stringBounder) {
return 0;
}
}

View File

@ -250,11 +250,11 @@ public class EntityImageDescription extends AbstractEntityImage {
final double space = 8;
final Dimension2D dimSmall = asSmall.calculateDimension(ug.getStringBounder());
final Dimension2D dimDesc = desc.calculateDimension(ug.getStringBounder());
desc.drawU(ug.apply(new UTranslate((dimSmall.getWidth() - dimDesc.getWidth()) / 2, space
+ dimSmall.getHeight())));
final double posx1 = (dimSmall.getWidth() - dimDesc.getWidth()) / 2;
desc.drawU(ug.apply(new UTranslate(posx1, space + dimSmall.getHeight())));
final Dimension2D dimStereo = stereo.calculateDimension(ug.getStringBounder());
stereo.drawU(ug.apply(new UTranslate((dimSmall.getWidth() - dimStereo.getWidth()) / 2, -space
- dimStereo.getHeight())));
final double posx2 = (dimSmall.getWidth() - dimStereo.getWidth()) / 2;
stereo.drawU(ug.apply(new UTranslate(posx2, -space - dimStereo.getHeight())));
}
if (url != null) {
@ -266,4 +266,16 @@ public class EntityImageDescription extends AbstractEntityImage {
return shapeType;
}
@Override
public double getOverscanX(StringBounder stringBounder) {
if (hideText) {
final Dimension2D dimSmall = asSmall.calculateDimension(stringBounder);
final Dimension2D dimDesc = desc.calculateDimension(stringBounder);
final Dimension2D dimStereo = stereo.calculateDimension(stringBounder);
final double posx1 = (dimSmall.getWidth() - dimDesc.getWidth()) / 2;
final double posx2 = (dimSmall.getWidth() - dimStereo.getWidth()) / 2;
return MathUtils.max(-posx1, -posx2, 0);
}
return 0;
}
}

View File

@ -88,5 +88,10 @@ public class EntityImageNoteLink extends AbstractTextBlock implements IEntityIma
public boolean isHidden() {
return false;
}
public double getOverscanX(StringBounder stringBounder) {
return 0;
}
}

View File

@ -71,7 +71,7 @@ class LicenseWindow extends JFrame {
this.setTitle("Licence PlantUML (" + Version.versionString() + ")");
getContentPane().add(getNorthLabel(), BorderLayout.NORTH);
final List<String> list = new ArrayList<String>(License.getCurrent().getText(false));
final List<String> list = new ArrayList<String>(License.getCurrent().getTextFull());
getContentPane().add(getJComponent(list), BorderLayout.CENTER);
getContentPane().add(getSouthLabel(), BorderLayout.SOUTH);

View File

@ -281,15 +281,13 @@ public enum License {
text.add("textual description in PlantUML language). Those images are not covered by");
}
private List<String> getHeaderStart(LicenseInfo licenseInfo, boolean withQrcode) {
final List<String> text = new ArrayList<String>();
private void header1(final List<String> text, LicenseInfo licenseInfo) {
if (licenseInfo.isNone()) {
text.add("+=======================================================================");
text.add("| ");
text.add("| PlantUML : a free UML diagram generator");
text.add("| ");
text.add("+=======================================================================");
text.add(" ");
} else {
text.add("+=======================================================================");
text.add("| ");
@ -298,8 +296,11 @@ public enum License {
text.add("+=======================================================================");
addLicenseInfo(text, licenseInfo);
text.add("+=======================================================================");
text.add(" ");
}
}
private void header2(final List<String> text, LicenseInfo licenseInfo, boolean withQrcode) {
text.add(" ");
text.add("(C) Copyright 2009-2017, Arnaud Roques");
text.add(" ");
text.add("Project Info: http://plantuml.com");
@ -317,7 +318,6 @@ public enum License {
text.add(" ");
}
}
return text;
}
public static void addLicenseInfo(final List<String> text, LicenseInfo licenseInfo) {
@ -331,7 +331,7 @@ public enum License {
text.add("| DISTRIBUTED BY : " + licenseInfo.getOwner());
text.add("| ");
}
if (licenseInfo.hasExpired()) {
if (licenseInfo.getLicenseType() != LicenseType.UNKNOWN && licenseInfo.hasExpired()) {
text.add("| <i>Warning: Your license has expired.");
text.add("| ");
}
@ -471,9 +471,29 @@ public enum License {
return Collections.unmodifiableList(h);
}
public List<String> getText(boolean withQrcode) {
public List<String> getTextFull() {
final LicenseInfo licenseInfo = LicenseInfo.retrieveQuick();
final List<String> text = getHeaderStart(licenseInfo, withQrcode);
final List<String> text = new ArrayList<String>();
header1(text, licenseInfo);
header2(text, licenseInfo, false);
end3(text, licenseInfo);
return text;
}
public List<String> getText1(LicenseInfo licenseInfo) {
final List<String> text = new ArrayList<String>();
header1(text, licenseInfo);
return text;
}
public List<String> getText2(LicenseInfo licenseInfo) {
final List<String> text = new ArrayList<String>();
header2(text, licenseInfo, true);
end3(text, licenseInfo);
return text;
}
private void end3(final List<String> text, final LicenseInfo licenseInfo) {
if (this == License.GPL) {
addGpl(licenseInfo, text);
} else if (this == License.GPLV2) {
@ -506,6 +526,5 @@ public enum License {
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(" ");
return text;
}
}

View File

@ -34,16 +34,13 @@
*/
package net.sourceforge.plantuml.version;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.Collection;
import java.util.Date;
import java.util.Set;
@ -51,69 +48,32 @@ import java.util.TreeSet;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;
import javax.imageio.ImageIO;
import net.sourceforge.plantuml.Log;
import net.sourceforge.plantuml.OptionFlags;
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(LicenseType.NONE, 0, 0, null, null);
public static final int POS_TYPE = 2;
public static final int POS_CONTEXT = 4;
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;
public final static LicenseInfo NONE = new LicenseInfo(LicenseType.NONE, 0, 0, null, null, null);
private final LicenseType type;
private final long generationDate;
private final long expirationDate;
private final String owner;
private final String context;
private final byte[] sha;
private LicenseInfo(LicenseType type, long generationDate, long expirationDate, String owner, String context) {
public LicenseInfo(LicenseType type, long generationDate, long expirationDate, String owner, String context,
byte[] sha) {
this.type = type;
this.generationDate = generationDate;
this.expirationDate = expirationDate;
this.owner = owner;
this.context = context;
}
private static LicenseInfo buildNamed(Magic magic, boolean doCheck) throws NoSuchAlgorithmException, IOException {
final String signature = SignatureUtils.toHexString(magic.get(LicenseInfo.POS_SIGNATURE, 64));
if (doCheck) {
final String local = SignatureUtils.toHexString(Magic.signature());
if (local.equals(signature) == false) {
throw new IOException();
}
}
final LicenseType type = LicenseType.fromInt(magic.getByte(Magic.signature(), LicenseInfo.POS_TYPE));
final long generation = bytesToLong(magic.get(LicenseInfo.POS_GENERATION, 8));
final long expiration = bytesToLong(magic.get(LicenseInfo.POS_EXPIRATION, 8));
final String owner = magic.getString(LicenseInfo.POS_OWNER);
return new LicenseInfo(type, generation, expiration, owner, null);
}
private static LicenseInfo buildDistributor(Magic magic) throws IOException, NoSuchAlgorithmException {
final LicenseType type = LicenseType.fromInt(magic.getByte(LicenseInfo.POS_TYPE));
final long generation = bytesToLong(magic.get(LicenseInfo.POS_GENERATION, 8));
final long expiration = bytesToLong(magic.get(LicenseInfo.POS_EXPIRATION, 8));
final String owner = magic.getString(LicenseInfo.POS_OWNER);
final String context = magic.getString(LicenseInfo.POS_CONTEXT);
return new LicenseInfo(type, generation, expiration, owner, context);
}
public static long bytesToLong(byte[] b) {
long result = 0;
for (int i = 0; i < 8; i++) {
result <<= 8;
result |= (b[i] & 0xFF);
}
return result;
this.sha = sha;
}
public static void persistMe(String key) throws BackingStoreException {
@ -169,8 +129,8 @@ public class LicenseInfo {
public static LicenseInfo retrieveNamed(final String key) {
if (key.length() > 99 && key.matches("^[0-9a-z]+$")) {
try {
final String sig = SignatureUtils.toHexString(Magic.signature());
return retrieveNamed(sig, key, true);
final String sig = SignatureUtils.toHexString(PLSSignature.signature());
return PLSSignature.retrieveNamed(sig, key, true);
} catch (Exception e) {
// e.printStackTrace();
Log.info("Error retrieving license info" + e);
@ -179,15 +139,29 @@ public class LicenseInfo {
return LicenseInfo.NONE;
}
public static LicenseInfo retrieveNamed(final String sig, final String key, boolean doCheck)
throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeySpecException, IOException {
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();
magic.xor(SignatureUtils.getSHA512raw(SignatureUtils.salting(sig, Magic.getSalt(sig))));
return LicenseInfo.buildNamed(magic, doCheck);
public static BufferedImage retrieveDistributorImage(LicenseInfo licenseInfo) {
if (licenseInfo.getLicenseType() != LicenseType.DISTRIBUTOR) {
return null;
}
try {
final byte[] s1 = PLSSignature.retrieveDistributorImageSignature();
if (SignatureUtils.toHexString(s1).equals(SignatureUtils.toHexString(licenseInfo.sha)) == false) {
return null;
}
final InputStream dis = PSystemVersion.class.getResourceAsStream("/distributor.png");
if (dis == null) {
return null;
}
try {
final BufferedImage result = ImageIO.read(dis);
return result;
} finally {
dis.close();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static LicenseInfo retrieveDistributor() {
@ -199,12 +173,7 @@ public class LicenseInfo {
final BufferedReader br = new BufferedReader(new InputStreamReader(dis));
final String licenseString = br.readLine();
br.close();
final BigInteger lu = new BigInteger(licenseString, 36);
final QBlock qb2 = new QBlock(lu);
final QBlock qb3 = qb2.change(Dedication.E, Dedication.N);
final Magic magic = qb3.toMagic();
final LicenseInfo result = LicenseInfo.buildDistributor(magic);
final LicenseInfo result = PLSSignature.retrieveDistributor(licenseString);
final Throwable creationPoint = new Throwable();
creationPoint.fillInStackTrace();
for (StackTraceElement ste : creationPoint.getStackTrace()) {
@ -234,7 +203,7 @@ public class LicenseInfo {
}
return result;
}
private static LicenseInfo setIfValid(LicenseInfo value, LicenseInfo def) {
if (value.isValid() || def.isNone()) {
return value;
@ -253,8 +222,6 @@ public class LicenseInfo {
return result;
}
public static void main(String[] args) {
LicenseInfo info = retrieveNamedSlow();
System.err.println("valid=" + info.isValid());

View File

@ -1,200 +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.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(int pos, int data) {
buffer[pos] = (byte) (0xFF & data);
}
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 int getByte(int pos) {
return buffer[pos];
}
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<NetworkInterface> 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());
}
}

View File

@ -0,0 +1,250 @@
/* ========================================================================
* 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.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.net.NetworkInterface;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.Enumeration;
import java.util.Random;
import net.sourceforge.plantuml.FileUtils;
import net.sourceforge.plantuml.OptionPrint;
import net.sourceforge.plantuml.SignatureUtils;
import net.sourceforge.plantuml.dedication.Dedication;
import net.sourceforge.plantuml.dedication.QBlock;
import net.sourceforge.plantuml.dedication.TurningBytes;
public class PLSSignature {
private final int type;
private final byte[] sha;
private final long now;
private final long exp;
private final String owner;
private final String context;
public PLSSignature(int type, byte[] sha, long now, long exp, String owner, String context) {
this.type = type;
this.sha = sha;
this.now = now;
this.exp = exp;
this.owner = owner;
this.context = context;
}
private LicenseInfo toLicenseInfo() {
return new LicenseInfo(LicenseType.fromInt(type), now, exp, owner, context, sha);
}
public static byte[] retrieveDistributorImageSignature() throws IOException, NoSuchAlgorithmException {
final InputStream dis = PSystemVersion.class.getResourceAsStream("/distributor.png");
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
FileUtils.copyToStream(dis, baos);
return SignatureUtils.getSHA512raw(baos.toByteArray());
}
public static PLSSignature fromRaw512(byte[] data) throws NoSuchAlgorithmException, IOException {
if (data.length != 512) {
throw new IllegalArgumentException();
}
final byte resultA[] = new byte[64];
final byte resultB[] = new byte[512 - 64];
System.arraycopy(data, 0, resultA, 0, resultA.length);
System.arraycopy(data, 64, resultB, 0, resultB.length);
final byte[] sig = SignatureUtils.getSHA512raw(resultB);
if (SignatureUtils.toHexString(resultA).equals(SignatureUtils.toHexString(sig)) == false) {
return null;
// throw new IOException();
}
final ByteArrayInputStream bais = new ByteArrayInputStream(resultB);
final int type = bais.read();
if (type == 0) {
final int version = bais.read();
final byte sha[] = readBytes(bais, 64);
final long now = readLong(bais);
final long exp = readLong(bais);
final String owner = readString(bais);
return new PLSSignature(type, sha, now, exp, owner, null);
}
if (type == 2) {
final int version = bais.read();
final byte sha[] = readBytes(bais, 64);
final long now = readLong(bais);
final long exp = readLong(bais);
final String owner = readString(bais);
final String context = readString(bais);
return new PLSSignature(type, sha, now, exp, owner, context);
}
return null;
}
// public static byte shrink(byte data[]) {
// byte result = 42;
// for (byte b : data) {
// result ^= b;
// }
// return result;
// }
private static byte[] readBytes(ByteArrayInputStream bais, int size) throws IOException {
byte[] result = new byte[size];
final int read = bais.read(result);
if (read != size) {
throw new IOException();
}
return result;
}
private static String readString(ByteArrayInputStream bais) throws IOException {
final int size = bais.read();
if (size > 80) {
throw new IOException();
}
byte[] result = new byte[size];
final int read = bais.read(result);
if (read != size) {
throw new IOException();
}
return new String(result, "UTF-8");
}
private static long readLong(ByteArrayInputStream bais) throws IOException {
final byte[] result = new byte[8];
final int read = bais.read(result);
if (read != 8) {
throw new IOException();
}
long ll = 0;
for (int i = 7; i >= 0; i--) {
final long mask = ((long) (result[i] & 0xFF)) << (8 * (7 - i));
ll = ll | mask;
}
return ll;
}
public static LicenseInfo retrieveNamed(String sig, String key, boolean doCheck) throws NoSuchAlgorithmException,
InvalidKeySpecException, IOException {
byte[] block = decode(key);
xor(block, SignatureUtils.getSHA512raw(SignatureUtils.salting(sig, getSalt(sig))));
final PLSSignature sig2 = PLSSignature.fromRaw512(block);
if (sig2 == null) {
return LicenseInfo.NONE;
}
return sig2.toLicenseInfo();
}
public static LicenseInfo retrieveDistributor(String key) throws IOException, NoSuchAlgorithmException {
byte[] block = decode(key);
final PLSSignature sig2 = PLSSignature.fromRaw512(block);
if (sig2 == null) {
return LicenseInfo.NONE;
}
return sig2.toLicenseInfo();
}
private static byte[] decode(String key) throws IOException {
final BigInteger lu = new BigInteger(key, 36);
final QBlock qb2 = new QBlock(lu);
final QBlock qb3 = qb2.change(Dedication.E, Dedication.N);
byte block[] = qb3.getData512();
if (block.length != 512) {
throw new IOException();
}
return block;
}
private static void xor(byte buffer[], TurningBytes turningBytes) {
for (int i = 0; i < buffer.length; i++) {
buffer[i] ^= turningBytes.nextByte();
}
}
public static void xor(byte buffer[], byte[] key) {
xor(buffer, new TurningBytes(key));
}
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;
}
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();
}
}
private static String getMacAddress() throws IOException {
final Enumeration<NetworkInterface> 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();
}
}

View File

@ -36,14 +36,12 @@ package net.sourceforge.plantuml.version;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.ArrayList;
import java.util.List;
import java.util.prefs.BackingStoreException;
import net.sourceforge.plantuml.AbstractPSystem;
import net.sourceforge.plantuml.FileFormatOption;
@ -98,7 +96,7 @@ public class PSystemKeycheck extends AbstractPSystem {
private void drawInternal(UGraphic ug) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
final List<String> strings = header();
try {
final LicenseInfo info = LicenseInfo.retrieveNamed(sig, key, false);
final LicenseInfo info = PLSSignature.retrieveNamed(sig, key, false);
strings.add("<u>Provided license information</u>:");
License.addLicenseInfo(strings, info);
strings.add(" ");
@ -133,7 +131,7 @@ public class PSystemKeycheck extends AbstractPSystem {
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()), Color.BLACK,
Version.versionString() + "\n" + SignatureUtils.toHexString(PLSSignature.signature()), Color.BLACK,
Color.WHITE);
if (im != null) {
final UImage flash = new UImage(im).scaleNearestNeighbor(4);

View File

@ -153,7 +153,7 @@ public class PSystemKeygen extends AbstractPSystem {
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()), Color.BLACK, Color.WHITE);
Version.versionString() + "\n" + SignatureUtils.toHexString(PLSSignature.signature()), Color.BLACK, Color.WHITE);
if (im != null) {
final UImage flash = new UImage(im).scaleNearestNeighbor(4);
ug.draw(flash);

View File

@ -34,6 +34,7 @@
*/
package net.sourceforge.plantuml.version;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
@ -44,25 +45,22 @@ import net.sourceforge.plantuml.FileFormatOption;
import net.sourceforge.plantuml.core.DiagramDescription;
import net.sourceforge.plantuml.core.ImageData;
import net.sourceforge.plantuml.graphic.GraphicStrings;
import net.sourceforge.plantuml.graphic.UDrawable;
import net.sourceforge.plantuml.svek.TextBlockBackcolored;
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 PSystemLicense extends AbstractPSystem {
private final List<String> strings = new ArrayList<String>();
PSystemLicense() throws IOException {
strings.addAll(License.getCurrent().getText(true));
}
public class PSystemLicense extends AbstractPSystem implements UDrawable {
@Override
final protected ImageData exportDiagramNow(OutputStream os, int num, FileFormatOption fileFormat, long seed)
throws IOException {
final TextBlockBackcolored result = getGraphicStrings();
final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, result.getBackcolor(),
getMetadata(), null, 0, 0, null, false);
imageBuilder.setUDrawable(result);
final ImageBuilder imageBuilder = new ImageBuilder(new ColorMapperIdentity(), 1.0, null, getMetadata(), null,
0, 0, null, false);
imageBuilder.setUDrawable(this);
return imageBuilder.writeImageTOBEMOVED(fileFormat, seed, os);
}
@ -70,7 +68,7 @@ public class PSystemLicense extends AbstractPSystem {
return new PSystemLicense();
}
private TextBlockBackcolored getGraphicStrings() throws IOException {
private TextBlockBackcolored getGraphicStrings(List<String> strings) {
return GraphicStrings.createBlackOnWhite(strings);
}
@ -78,4 +76,32 @@ public class PSystemLicense extends AbstractPSystem {
return new DiagramDescription("(License)");
}
public void drawU(UGraphic ug) {
final LicenseInfo licenseInfo = LicenseInfo.retrieveQuick();
final BufferedImage logo = LicenseInfo.retrieveDistributorImage(licenseInfo);
if (logo == null) {
final List<String> strings = new ArrayList<String>();
strings.addAll(License.getCurrent().getText1(licenseInfo));
strings.addAll(License.getCurrent().getText2(licenseInfo));
getGraphicStrings(strings).drawU(ug);
} else {
final List<String> strings1 = new ArrayList<String>();
final List<String> strings2 = new ArrayList<String>();
strings1.addAll(License.getCurrent().getText1(licenseInfo));
strings2.addAll(License.getCurrent().getText2(licenseInfo));
final TextBlockBackcolored result1 = getGraphicStrings(strings1);
result1.drawU(ug);
ug = ug.apply(new UTranslate(0, 4 + result1.calculateDimension(ug.getStringBounder()).getHeight()));
UImage im = new UImage(logo);
ug.apply(new UTranslate(20, 0)).draw(im);
ug = ug.apply(new UTranslate(0, im.getHeight()));
final TextBlockBackcolored result2 = getGraphicStrings(strings2);
result2.drawU(ug);
}
}
}

Some files were not shown because too many files have changed in this diff Show More