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:
parent
3736d048b3
commit
3ecadf6bd5
5
pom.xml
5
pom.xml
@ -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>
|
||||
|
@ -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;
|
||||
}
|
@ -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();
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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));
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
46
src/net/sourceforge/plantuml/Stdrpt.java
Normal file
46
src/net/sourceforge/plantuml/Stdrpt.java
Normal 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);
|
||||
|
||||
}
|
47
src/net/sourceforge/plantuml/StdrptNull.java
Normal file
47
src/net/sourceforge/plantuml/StdrptNull.java
Normal 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) {
|
||||
}
|
||||
|
||||
}
|
56
src/net/sourceforge/plantuml/StdrptPipe0.java
Normal file
56
src/net/sourceforge/plantuml/StdrptPipe0.java
Normal 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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
80
src/net/sourceforge/plantuml/StdrptV1.java
Normal file
80
src/net/sourceforge/plantuml/StdrptV1.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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() {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -59,4 +59,9 @@ class GraphvizLinux extends AbstractGraphviz {
|
||||
return optLocalBinDot;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getExeName() {
|
||||
return "dot";
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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()) {
|
||||
|
@ -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";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
95
src/net/sourceforge/plantuml/evalex/AbstractFunction.java
Normal file
95
src/net/sourceforge/plantuml/evalex/AbstractFunction.java
Normal 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;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
102
src/net/sourceforge/plantuml/evalex/AbstractLazyOperator.java
Normal file
102
src/net/sourceforge/plantuml/evalex/AbstractLazyOperator.java
Normal 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;
|
||||
}
|
||||
}
|
80
src/net/sourceforge/plantuml/evalex/AbstractOperator.java
Normal file
80
src/net/sourceforge/plantuml/evalex/AbstractOperator.java
Normal 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()));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
1883
src/net/sourceforge/plantuml/evalex/Expression.java
Normal file
1883
src/net/sourceforge/plantuml/evalex/Expression.java
Normal file
File diff suppressed because it is too large
Load Diff
47
src/net/sourceforge/plantuml/evalex/Function.java
Normal file
47
src/net/sourceforge/plantuml/evalex/Function.java
Normal 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);
|
||||
}
|
85
src/net/sourceforge/plantuml/evalex/LazyFunction.java
Normal file
85
src/net/sourceforge/plantuml/evalex/LazyFunction.java
Normal 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);
|
||||
}
|
75
src/net/sourceforge/plantuml/evalex/LazyOperator.java
Normal file
75
src/net/sourceforge/plantuml/evalex/LazyOperator.java
Normal 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);
|
||||
}
|
61
src/net/sourceforge/plantuml/evalex/NString.java
Normal file
61
src/net/sourceforge/plantuml/evalex/NString.java
Normal 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();
|
||||
}
|
||||
}
|
44
src/net/sourceforge/plantuml/evalex/Operator.java
Normal file
44
src/net/sourceforge/plantuml/evalex/Operator.java
Normal 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);
|
||||
}
|
68
src/net/sourceforge/plantuml/evalex/Snipset1.java
Normal file
68
src/net/sourceforge/plantuml/evalex/Snipset1.java
Normal 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();
|
||||
}
|
||||
}
|
50
src/net/sourceforge/plantuml/evalex/Snipset2.java
Normal file
50
src/net/sourceforge/plantuml/evalex/Snipset2.java
Normal 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
|
||||
|
||||
}
|
||||
}
|
49
src/net/sourceforge/plantuml/evalex/Snipset3.java
Normal file
49
src/net/sourceforge/plantuml/evalex/Snipset3.java
Normal 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);
|
||||
|
||||
}
|
||||
}
|
@ -176,5 +176,10 @@ public class GraphicStrings extends AbstractTextBlock implements IEntityImage {
|
||||
public boolean isHidden() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public double getOverscanX(StringBounder stringBounder) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -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() {
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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*"
|
||||
+ "((?:\\([^()]*\\)|[^,'\"])*?)" + ")");
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
54
src/net/sourceforge/plantuml/project3/ComplementOpen.java
Normal file
54
src/net/sourceforge/plantuml/project3/ComplementOpen.java
Normal 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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
|
@ -35,7 +35,6 @@
|
||||
*/
|
||||
package net.sourceforge.plantuml.salt.factory;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -35,7 +35,6 @@
|
||||
*/
|
||||
package net.sourceforge.plantuml.salt.factory;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -35,7 +35,6 @@
|
||||
*/
|
||||
package net.sourceforge.plantuml.salt.factory;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -35,7 +35,6 @@
|
||||
*/
|
||||
package net.sourceforge.plantuml.salt.factory;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -35,7 +35,6 @@
|
||||
*/
|
||||
package net.sourceforge.plantuml.salt.factory;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.util.Arrays;
|
||||
|
||||
import net.sourceforge.plantuml.ISkinSimple;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
|
@ -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() {
|
||||
|
@ -80,4 +80,8 @@ public abstract class AbstractEntityImage extends AbstractTextBlock implements I
|
||||
return Margins.NONE;
|
||||
}
|
||||
|
||||
public double getOverscanX(StringBounder stringBounder) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -340,4 +340,8 @@ public class Shape implements Positionable, IShapePseudo, Hideable {
|
||||
}
|
||||
return pt;
|
||||
}
|
||||
|
||||
public double getOverscanX(StringBounder stringBounder) {
|
||||
return image.getOverscanX(stringBounder);
|
||||
}
|
||||
}
|
||||
|
@ -134,4 +134,8 @@ public final class SvekResult extends AbstractTextBlock implements IEntityImage,
|
||||
return false;
|
||||
}
|
||||
|
||||
public double getOverscanX(StringBounder stringBounder) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -88,5 +88,10 @@ public class EntityImageNoteLink extends AbstractTextBlock implements IEntityIma
|
||||
public boolean isHidden() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public double getOverscanX(StringBounder stringBounder) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
|
@ -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());
|
||||
|
||||
}
|
||||
|
||||
}
|
250
src/net/sourceforge/plantuml/version/PLSSignature.java
Normal file
250
src/net/sourceforge/plantuml/version/PLSSignature.java
Normal 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();
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user