mirror of
https://github.com/octoleo/plantuml.git
synced 2024-12-22 19:09:03 +00:00
Merge branch 'wip'
This commit is contained in:
commit
6fb89e85e7
@ -104,23 +104,20 @@ public class Link extends WithLinkType implements Hideable, Removeable {
|
||||
private Url url;
|
||||
|
||||
public String idCommentForSvg() {
|
||||
if (type.looksLikeRevertedForSvg()) {
|
||||
final String comment = getEntity1().getCodeGetName() + "-backto-" + getEntity2().getCodeGetName();
|
||||
return comment;
|
||||
}
|
||||
if (type.looksLikeNoDecorAtAllSvg()) {
|
||||
final String comment = getEntity1().getCodeGetName() + "-" + getEntity2().getCodeGetName();
|
||||
return comment;
|
||||
}
|
||||
final String comment = getEntity1().getCodeGetName() + "-to-" + getEntity2().getCodeGetName();
|
||||
return comment;
|
||||
if (type.looksLikeRevertedForSvg())
|
||||
return getEntity1().getCodeGetName() + "-backto-" + getEntity2().getCodeGetName();
|
||||
|
||||
if (type.looksLikeNoDecorAtAllSvg())
|
||||
return getEntity1().getCodeGetName() + "-" + getEntity2().getCodeGetName();
|
||||
|
||||
return getEntity1().getCodeGetName() + "-to-" + getEntity2().getCodeGetName();
|
||||
}
|
||||
|
||||
public UComment commentForSvg() {
|
||||
if (type.looksLikeRevertedForSvg()) {
|
||||
if (type.looksLikeRevertedForSvg())
|
||||
return new UComment(
|
||||
"reverse link " + getEntity1().getCodeGetName() + " to " + getEntity2().getCodeGetName());
|
||||
}
|
||||
|
||||
return new UComment("link " + getEntity1().getCodeGetName() + " to " + getEntity2().getCodeGetName());
|
||||
}
|
||||
|
||||
@ -158,33 +155,15 @@ public class Link extends WithLinkType implements Hideable, Removeable {
|
||||
this.labeldistance = labeldistance;
|
||||
this.labelangle = labelangle;
|
||||
this.setSpecificColor(specificColor);
|
||||
if (qualifier1 != null) {
|
||||
if (qualifier1 != null)
|
||||
((ILeaf) cl1).setNearDecoration(true);
|
||||
}
|
||||
if (qualifier2 != null) {
|
||||
|
||||
if (qualifier2 != null)
|
||||
((ILeaf) cl2).setNearDecoration(true);
|
||||
}
|
||||
// if (type.getDecor2() == LinkDecor.EXTENDS) {
|
||||
// setSametail(cl1.getUid());
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
// private static boolean doWeHaveToRemoveUrlAtStart(Display label) {
|
||||
// if (label.size() == 0) {
|
||||
// return false;
|
||||
// }
|
||||
// final String s = label.get(0).toString();
|
||||
// if (s.matches("^\\[\\[\\S+\\]\\].+$")) {
|
||||
// return true;
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
|
||||
public Link getInv() {
|
||||
// if (getLength() == 1) {
|
||||
// final int x = cl1.getXposition();
|
||||
// cl2.setXposition(x-1);
|
||||
// }
|
||||
final Link result = new Link(cl2, cl1, getType().getInversed(), label, length, qualifier2, qualifier1,
|
||||
labeldistance, labelangle, getSpecificColor(), styleBuilder);
|
||||
result.inverted = !this.inverted;
|
||||
@ -193,6 +172,7 @@ public class Link extends WithLinkType implements Hideable, Removeable {
|
||||
result.url = this.url;
|
||||
result.linkConstraint = this.linkConstraint;
|
||||
result.stereotype = stereotype;
|
||||
result.visibilityModifier = visibilityModifier;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -216,9 +196,9 @@ public class Link extends WithLinkType implements Hideable, Removeable {
|
||||
}
|
||||
|
||||
public final boolean isInvis() {
|
||||
if (type.isInvisible()) {
|
||||
if (type.isInvisible())
|
||||
return true;
|
||||
}
|
||||
|
||||
return invis;
|
||||
}
|
||||
|
||||
@ -227,12 +207,12 @@ public class Link extends WithLinkType implements Hideable, Removeable {
|
||||
}
|
||||
|
||||
public boolean isBetween(IEntity cl1, IEntity cl2) {
|
||||
if (cl1.equals(this.cl1) && cl2.equals(this.cl2)) {
|
||||
if (cl1.equals(this.cl1) && cl2.equals(this.cl2))
|
||||
return true;
|
||||
}
|
||||
if (cl1.equals(this.cl2) && cl2.equals(this.cl1)) {
|
||||
|
||||
if (cl1.equals(this.cl2) && cl2.equals(this.cl1))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -259,40 +239,40 @@ public class Link extends WithLinkType implements Hideable, Removeable {
|
||||
|
||||
@Override
|
||||
public LinkType getType() {
|
||||
if (opale) {
|
||||
if (opale)
|
||||
return new LinkType(LinkDecor.NONE, LinkDecor.NONE);
|
||||
}
|
||||
if (getSametail() != null) {
|
||||
|
||||
if (getSametail() != null)
|
||||
return new LinkType(LinkDecor.NONE, LinkDecor.NONE);
|
||||
}
|
||||
|
||||
LinkType result = type;
|
||||
if (OptionFlags.USE_INTERFACE_EYE1) {
|
||||
if (isLollipopInterfaceEye(cl1)) {
|
||||
if (isLollipopInterfaceEye(cl1))
|
||||
type = type.withLollipopInterfaceEye1();
|
||||
}
|
||||
if (isLollipopInterfaceEye(cl2)) {
|
||||
|
||||
if (isLollipopInterfaceEye(cl2))
|
||||
type = type.withLollipopInterfaceEye2();
|
||||
}
|
||||
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean isReallyGroup(IEntity ent) {
|
||||
if (ent.isGroup() == false) {
|
||||
if (ent.isGroup() == false)
|
||||
return false;
|
||||
}
|
||||
|
||||
final IGroup group = (IGroup) ent;
|
||||
return group.getChildren().size() + group.getLeafsDirect().size() > 0;
|
||||
}
|
||||
|
||||
public LinkType getTypePatchCluster() {
|
||||
LinkType result = getType();
|
||||
if (isReallyGroup(getEntity1())) {
|
||||
if (isReallyGroup(getEntity1()))
|
||||
result = result.withoutDecors2();
|
||||
}
|
||||
if (isReallyGroup(getEntity2())) {
|
||||
|
||||
if (isReallyGroup(getEntity2()))
|
||||
result = result.withoutDecors1();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -302,12 +282,12 @@ public class Link extends WithLinkType implements Hideable, Removeable {
|
||||
}
|
||||
LinkType result = type;
|
||||
if (OptionFlags.USE_INTERFACE_EYE1) {
|
||||
if (isLollipopInterfaceEye(cl1)) {
|
||||
if (isLollipopInterfaceEye(cl1))
|
||||
type = type.withLollipopInterfaceEye1();
|
||||
}
|
||||
if (isLollipopInterfaceEye(cl2)) {
|
||||
|
||||
if (isLollipopInterfaceEye(cl2))
|
||||
type = type.withLollipopInterfaceEye2();
|
||||
}
|
||||
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -375,39 +355,39 @@ public class Link extends WithLinkType implements Hideable, Removeable {
|
||||
}
|
||||
|
||||
public boolean isAutoLinkOfAGroup() {
|
||||
if (getEntity1().isGroup() == false) {
|
||||
if (getEntity1().isGroup() == false)
|
||||
return false;
|
||||
}
|
||||
if (getEntity2().isGroup() == false) {
|
||||
|
||||
if (getEntity2().isGroup() == false)
|
||||
return false;
|
||||
}
|
||||
if (getEntity1() == getEntity2()) {
|
||||
|
||||
if (getEntity1() == getEntity2())
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean containsType(LeafType type) {
|
||||
if (getEntity1().getLeafType() == type || getEntity2().getLeafType() == type) {
|
||||
if (getEntity1().getLeafType() == type || getEntity2().getLeafType() == type)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean contains(IEntity entity) {
|
||||
if (getEntity1() == entity || getEntity2() == entity) {
|
||||
if (getEntity1() == entity || getEntity2() == entity)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public IEntity getOther(IEntity entity) {
|
||||
if (getEntity1() == entity) {
|
||||
if (getEntity1() == entity)
|
||||
return getEntity2();
|
||||
}
|
||||
if (getEntity2() == entity) {
|
||||
|
||||
if (getEntity2() == entity)
|
||||
return getEntity1();
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
@ -455,9 +435,9 @@ public class Link extends WithLinkType implements Hideable, Removeable {
|
||||
}
|
||||
|
||||
public final LinkArrow getLinkArrow() {
|
||||
if (inverted) {
|
||||
if (inverted)
|
||||
return linkArrow.reverse();
|
||||
}
|
||||
|
||||
return linkArrow;
|
||||
}
|
||||
|
||||
@ -495,28 +475,28 @@ public class Link extends WithLinkType implements Hideable, Removeable {
|
||||
}
|
||||
|
||||
public boolean sameConnections(Link other) {
|
||||
if (this.cl1 == other.cl1 && this.cl2 == other.cl2) {
|
||||
if (this.cl1 == other.cl1 && this.cl2 == other.cl2)
|
||||
return true;
|
||||
}
|
||||
if (this.cl1 == other.cl2 && this.cl2 == other.cl1) {
|
||||
|
||||
if (this.cl1 == other.cl2 && this.cl2 == other.cl1)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean doesTouch(Link other) {
|
||||
if (this.cl1 == other.cl1) {
|
||||
if (this.cl1 == other.cl1)
|
||||
return true;
|
||||
}
|
||||
if (this.cl1 == other.cl2) {
|
||||
|
||||
if (this.cl1 == other.cl2)
|
||||
return true;
|
||||
}
|
||||
if (this.cl2 == other.cl1) {
|
||||
|
||||
if (this.cl2 == other.cl1)
|
||||
return true;
|
||||
}
|
||||
if (this.cl2 == other.cl2) {
|
||||
|
||||
if (this.cl2 == other.cl2)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -529,9 +509,9 @@ public class Link extends WithLinkType implements Hideable, Removeable {
|
||||
}
|
||||
|
||||
public boolean hasUrl() {
|
||||
if (Display.isNull(label) == false && label.hasUrl()) {
|
||||
if (Display.isNull(label) == false && label.hasUrl())
|
||||
return true;
|
||||
}
|
||||
|
||||
return getUrl() != null;
|
||||
}
|
||||
|
||||
@ -546,12 +526,12 @@ public class Link extends WithLinkType implements Hideable, Removeable {
|
||||
public void setPortMembers(String port1, String port2) {
|
||||
this.port1 = port1;
|
||||
this.port2 = port2;
|
||||
if (port1 != null) {
|
||||
if (port1 != null)
|
||||
((ILeaf) cl1).addPortShortName(port1);
|
||||
}
|
||||
if (port2 != null) {
|
||||
|
||||
if (port2 != null)
|
||||
((ILeaf) cl2).addPortShortName(port2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public final VisibilityModifier getVisibilityModifier() {
|
||||
@ -581,9 +561,9 @@ public class Link extends WithLinkType implements Hideable, Removeable {
|
||||
private LineLocation codeLine;
|
||||
|
||||
public String getCodeLine() {
|
||||
if (codeLine == null) {
|
||||
if (codeLine == null)
|
||||
return null;
|
||||
}
|
||||
|
||||
return "" + codeLine.getPosition();
|
||||
}
|
||||
|
||||
|
@ -43,6 +43,7 @@ import java.util.StringTokenizer;
|
||||
|
||||
import net.sourceforge.plantuml.BackSlash;
|
||||
import net.sourceforge.plantuml.Log;
|
||||
import net.sourceforge.plantuml.security.SecurityUtils;
|
||||
import net.sourceforge.plantuml.ugraphic.ShadowManager;
|
||||
import net.sourceforge.plantuml.ugraphic.UPath;
|
||||
import net.sourceforge.plantuml.ugraphic.USegment;
|
||||
@ -790,6 +791,10 @@ public class EpsGraphics {
|
||||
}
|
||||
|
||||
public void openLink(String url) {
|
||||
// javascript: security issue
|
||||
if (SecurityUtils.ignoreThisLink(url))
|
||||
return;
|
||||
|
||||
this.urlArea = new UrlArea(url);
|
||||
}
|
||||
|
||||
|
@ -78,11 +78,13 @@ public abstract class UGraphicDelegator implements UGraphic {
|
||||
public ColorMapper getColorMapper() {
|
||||
return ug.getColorMapper();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void startUrl(Url url) {
|
||||
ug.startUrl(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeUrl() {
|
||||
ug.closeUrl();
|
||||
}
|
||||
|
@ -97,29 +97,29 @@ public class SecurityUtils {
|
||||
public static final String PATHS_ALLOWED = "plantuml.allowlist.path";
|
||||
|
||||
/**
|
||||
* Paths to folders with security specific content (not allowed to read via SFile).
|
||||
* Paths to folders with security specific content (not allowed to read via
|
||||
* SFile).
|
||||
*/
|
||||
public static final String PATHS_SECURITY = "plantuml.security.credentials.path";
|
||||
|
||||
public static final String SECURITY_ALLOW_NONSSL_AUTH = "plantuml.security.allowNonSSLAuth";
|
||||
|
||||
/**
|
||||
* Standard BasicAuth authentication interceptor, to generate a SecurityAuthentication from credentials.
|
||||
* Standard BasicAuth authentication interceptor, to generate a
|
||||
* SecurityAuthentication from credentials.
|
||||
*/
|
||||
private static final SecurityAuthorizeManager PUBLIC_AUTH_MANAGER
|
||||
= new SecurityDefaultNoopAuthorizeManager();
|
||||
private static final SecurityAuthorizeManager PUBLIC_AUTH_MANAGER = new SecurityDefaultNoopAuthorizeManager();
|
||||
|
||||
/**
|
||||
* Standard interceptor for public endpoint access.
|
||||
*/
|
||||
private static final SecurityAccessInterceptor PUBLIC_ACCESS_INTERCEPTOR
|
||||
= new SecurityDefaultNoopAccessInterceptor();
|
||||
private static final SecurityAccessInterceptor PUBLIC_ACCESS_INTERCEPTOR = new SecurityDefaultNoopAccessInterceptor();
|
||||
|
||||
/**
|
||||
* Standard TokenAuth authorize manager, to generate a SecurityAuthentication from credentials.
|
||||
* Standard TokenAuth authorize manager, to generate a SecurityAuthentication
|
||||
* from credentials.
|
||||
*/
|
||||
private static final SecurityAuthorizeManager TOKEN_AUTH_MANAGER
|
||||
= new TokenAuthAuthorizeManager();
|
||||
private static final SecurityAuthorizeManager TOKEN_AUTH_MANAGER = new TokenAuthAuthorizeManager();
|
||||
|
||||
/**
|
||||
* Standard token access interceptor.
|
||||
@ -127,10 +127,10 @@ public class SecurityUtils {
|
||||
private static final SecurityAccessInterceptor TOKEN_ACCESS_INTERCEPTOR = new TokenAuthAccessInterceptor();
|
||||
|
||||
/**
|
||||
* Standard BasicAuth authorize manager, to generate a SecurityAuthentication from credentials.
|
||||
* Standard BasicAuth authorize manager, to generate a SecurityAuthentication
|
||||
* from credentials.
|
||||
*/
|
||||
private static final SecurityAuthorizeManager BASICAUTH_AUTH_MANAGER
|
||||
= new BasicAuthAuthorizeManager();
|
||||
private static final SecurityAuthorizeManager BASICAUTH_AUTH_MANAGER = new BasicAuthAuthorizeManager();
|
||||
|
||||
/**
|
||||
* Standard BasicAuth access interceptor.
|
||||
@ -140,14 +140,12 @@ public class SecurityUtils {
|
||||
/**
|
||||
* OAuth2 client credentials authorization manager.
|
||||
*/
|
||||
private static final SecurityAuthorizeManager OAUTH2_CLIENT_AUTH_MANAGER
|
||||
= new OAuth2ClientAccessAuthorizeManager();
|
||||
private static final SecurityAuthorizeManager OAUTH2_CLIENT_AUTH_MANAGER = new OAuth2ClientAccessAuthorizeManager();
|
||||
|
||||
/**
|
||||
* OAuth2 resource owner authorization manager.
|
||||
*/
|
||||
private static final SecurityAuthorizeManager OAUTH2_RESOURCEOWNER_AUTH_MANAGER
|
||||
= new OAuth2ResourceOwnerAccessAuthorizeManager();
|
||||
private static final SecurityAuthorizeManager OAUTH2_RESOURCEOWNER_AUTH_MANAGER = new OAuth2ResourceOwnerAccessAuthorizeManager();
|
||||
|
||||
/**
|
||||
* Standard 'bearer' OAuth2 access interceptor.
|
||||
@ -168,15 +166,19 @@ public class SecurityUtils {
|
||||
return current;
|
||||
}
|
||||
|
||||
public static boolean getJavascriptUnsecure() {
|
||||
final String env = getenv("PLANTUML_JAVASCRIPT_UNSECURE");
|
||||
if ("true".equalsIgnoreCase(env)) {
|
||||
public static boolean ignoreThisLink(String url) {
|
||||
if (allowJavascriptInLink() == false && isJavascriptLink(url))
|
||||
return true;
|
||||
}
|
||||
if ("false".equalsIgnoreCase(env)) {
|
||||
return false;
|
||||
}
|
||||
return OptionFlags.ALLOW_INCLUDE;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isJavascriptLink(String url) {
|
||||
return url.toLowerCase().replaceAll("[^a-z]", "").startsWith("javascript");
|
||||
}
|
||||
|
||||
private static boolean allowJavascriptInLink() {
|
||||
final String env = getenv("PLANTUML_ALLOW_JAVASCRIPT_IN_LINK");
|
||||
return "true".equalsIgnoreCase(env);
|
||||
}
|
||||
|
||||
public static String getenv(String name) {
|
||||
@ -188,8 +190,8 @@ public class SecurityUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the environment variable and returns true if the variable is used in security context. In this case, the
|
||||
* value should not be displayed in scripts.
|
||||
* Checks the environment variable and returns true if the variable is used in
|
||||
* security context. In this case, the value should not be displayed in scripts.
|
||||
*
|
||||
* @param name Environment variable to check
|
||||
* @return true, if this is a secret variable
|
||||
@ -201,7 +203,8 @@ public class SecurityUtils {
|
||||
/**
|
||||
* Configuration for Non-SSL authentication methods.
|
||||
*
|
||||
* @return true, if plantUML should allow authentication in plain connections (without encryption).
|
||||
* @return true, if plantUML should allow authentication in plain connections
|
||||
* (without encryption).
|
||||
* @see #SECURITY_ALLOW_NONSSL_AUTH
|
||||
*/
|
||||
public static boolean isNonSSLAuthenticationAllowed() {
|
||||
@ -336,7 +339,8 @@ public class SecurityUtils {
|
||||
public static boolean existsSecurityCredentials(String userToken) {
|
||||
SFile securityPath = getSecurityPath();
|
||||
if (securityPath != null) {
|
||||
// SFile does not allow access to the security path (to hide the credentials in DSL scripts)
|
||||
// SFile does not allow access to the security path (to hide the credentials in
|
||||
// DSL scripts)
|
||||
File securityFilePath = securityPath.conv();
|
||||
File userCredentials = new File(securityFilePath, userToken + ".credential");
|
||||
return userCredentials.exists() && userCredentials.canRead() && !userCredentials.isDirectory()
|
||||
@ -356,7 +360,8 @@ public class SecurityUtils {
|
||||
if (userToken != null && checkFileSystemSaveCharactersStrict(userToken) && !NO_CREDENTIALS.equals(userToken)) {
|
||||
final SFile securityPath = getSecurityPath();
|
||||
if (securityPath != null) {
|
||||
// SFile does not allow access to the security path (to hide the credentials in DSL scripts)
|
||||
// SFile does not allow access to the security path (to hide the credentials in
|
||||
// DSL scripts)
|
||||
File securityFilePath = securityPath.conv();
|
||||
File userCredentials = new File(securityFilePath, userToken + ".credential");
|
||||
JsonValue jsonValue = loadJson(userCredentials);
|
||||
@ -367,8 +372,8 @@ public class SecurityUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks, if the token of a pathname (filename, ext, directory-name) uses only a very strict set of characters and
|
||||
* not longer than 64 characters.
|
||||
* Checks, if the token of a pathname (filename, ext, directory-name) uses only
|
||||
* a very strict set of characters and not longer than 64 characters.
|
||||
* <p>
|
||||
* Only characters from a to Z, Numbers and - are allowed.
|
||||
*
|
||||
@ -377,15 +382,16 @@ public class SecurityUtils {
|
||||
* @see #SECURE_CHARS
|
||||
*/
|
||||
private static boolean checkFileSystemSaveCharactersStrict(String pathNameToken) {
|
||||
return StringUtils.isNotEmpty(pathNameToken)
|
||||
&& SECURE_CHARS.matcher(pathNameToken).matches() && pathNameToken.length() <= 64;
|
||||
return StringUtils.isNotEmpty(pathNameToken) && SECURE_CHARS.matcher(pathNameToken).matches()
|
||||
&& pathNameToken.length() <= 64;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the path to the configured security folder, if existing.
|
||||
* <p>
|
||||
* Please note: A SFile referenced to a security folder cannot access the files. The content of the files in the
|
||||
* security path should never have passed to DSL scripts.
|
||||
* Please note: A SFile referenced to a security folder cannot access the files.
|
||||
* The content of the files in the security path should never have passed to DSL
|
||||
* scripts.
|
||||
*
|
||||
* @return SFile folder or null
|
||||
*/
|
||||
@ -401,9 +407,9 @@ public class SecurityUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Loads a file as JSON object. If no file exists or the file is not parsable, the method returns an empty JSON.
|
||||
* Loads a file as JSON object. If no file exists or the file is not parsable,
|
||||
* the method returns an empty JSON.
|
||||
*
|
||||
* @param jsonFile file path to the JSON file
|
||||
* @return a Json vale (maybe empty)
|
||||
|
@ -912,9 +912,9 @@ public class SvgGraphics {
|
||||
Objects.requireNonNull(url);
|
||||
|
||||
// javascript: security issue
|
||||
if (SecurityUtils.getJavascriptUnsecure() == false && url.toLowerCase().startsWith("javascript")) {
|
||||
if (SecurityUtils.ignoreThisLink(url))
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (pendingAction.size() > 0) {
|
||||
closeLink();
|
||||
|
@ -173,9 +173,11 @@ public abstract class AbstractCommonUGraphic implements UGraphic {
|
||||
final public void flushUg() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startUrl(Url url) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeUrl() {
|
||||
}
|
||||
|
||||
|
@ -114,10 +114,12 @@ public class UGraphicEps extends AbstractUGraphic<EpsGraphics> implements ClipCo
|
||||
return ug.getEPSCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startUrl(Url url) {
|
||||
getGraphicObject().openLink(url.getUrl());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeUrl() {
|
||||
getGraphicObject().closeLink();
|
||||
}
|
||||
|
@ -55,6 +55,7 @@ import net.sourceforge.plantuml.anim.AffineTransformation;
|
||||
import net.sourceforge.plantuml.graphic.StringBounder;
|
||||
import net.sourceforge.plantuml.png.PngIO;
|
||||
import net.sourceforge.plantuml.posimo.DotPath;
|
||||
import net.sourceforge.plantuml.security.SecurityUtils;
|
||||
import net.sourceforge.plantuml.ugraphic.AbstractCommonUGraphic;
|
||||
import net.sourceforge.plantuml.ugraphic.AbstractUGraphic;
|
||||
import net.sourceforge.plantuml.ugraphic.UAntiAliasing;
|
||||
@ -82,7 +83,7 @@ public class UGraphicG2d extends AbstractUGraphic<Graphics2D> implements EnsureV
|
||||
|
||||
private UAntiAliasing antiAliasing = UAntiAliasing.ANTI_ALIASING_ON;
|
||||
|
||||
private/* final */List<Url> urls = new ArrayList<>();
|
||||
private List<Url> urls = new ArrayList<>();
|
||||
private Set<Url> allUrls = new HashSet<>();
|
||||
|
||||
private final boolean hasAffineTransform;
|
||||
@ -116,22 +117,22 @@ public class UGraphicG2d extends AbstractUGraphic<Graphics2D> implements EnsureV
|
||||
register(dpiFactor);
|
||||
}
|
||||
|
||||
public UGraphicG2d(HColor defaultBackground, ColorMapper colorMapper, StringBounder stringBounder, Graphics2D g2d, double dpiFactor) {
|
||||
public UGraphicG2d(HColor defaultBackground, ColorMapper colorMapper, StringBounder stringBounder, Graphics2D g2d,
|
||||
double dpiFactor) {
|
||||
this(defaultBackground, colorMapper, stringBounder, g2d, dpiFactor, null, 0, 0);
|
||||
}
|
||||
|
||||
public UGraphicG2d(HColor defaultBackground, ColorMapper colorMapper, StringBounder stringBounder, Graphics2D g2d, double dpiFactor,
|
||||
AffineTransformation affineTransform, double dx, double dy) {
|
||||
public UGraphicG2d(HColor defaultBackground, ColorMapper colorMapper, StringBounder stringBounder, Graphics2D g2d,
|
||||
double dpiFactor, AffineTransformation affineTransform, double dx, double dy) {
|
||||
super(defaultBackground, colorMapper, stringBounder, g2d);
|
||||
this.hasAffineTransform = affineTransform != null;
|
||||
this.dpiFactor = dpiFactor;
|
||||
if (dpiFactor != 1.0) {
|
||||
if (dpiFactor != 1.0)
|
||||
g2d.scale(dpiFactor, dpiFactor);
|
||||
}
|
||||
|
||||
if (this.hasAffineTransform) {
|
||||
if (dx != 0 || dy != 0) {
|
||||
if (dx != 0 || dy != 0)
|
||||
getGraphicObject().transform(AffineTransform.getTranslateInstance(dx, dy));
|
||||
}
|
||||
getGraphicObject().transform(affineTransform.getAffineTransform());
|
||||
}
|
||||
register(dpiFactor);
|
||||
@ -176,21 +177,28 @@ public class UGraphicG2d extends AbstractUGraphic<Graphics2D> implements EnsureV
|
||||
return dpiFactor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startUrl(Url url) {
|
||||
urls.add(Objects.requireNonNull(url));
|
||||
allUrls.add(url);
|
||||
Objects.requireNonNull(url);
|
||||
// javascript: security issue
|
||||
if (SecurityUtils.ignoreThisLink(url.getUrl())) {
|
||||
urls.add(null);
|
||||
} else {
|
||||
urls.add(url);
|
||||
allUrls.add(url);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeUrl() {
|
||||
urls.remove(urls.size() - 1);
|
||||
}
|
||||
|
||||
public void ensureVisible(double x, double y) {
|
||||
for (Url u : urls) {
|
||||
if (getClip() == null || getClip().isInside(x, y)) {
|
||||
for (Url u : urls)
|
||||
if (u != null && (getClip() == null || getClip().isInside(x, y)))
|
||||
u.ensureVisible(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public BufferedImage getBufferedImage() {
|
||||
|
@ -89,10 +89,12 @@ public class UGraphicTikz extends AbstractUGraphic<TikzGraphics> implements Clip
|
||||
registerDriver(UCenteredCharacter.class, new DriverCenteredCharacterTikz2());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startUrl(Url url) {
|
||||
getGraphicObject().openLink(url.getUrl(), url.getTooltip());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeUrl() {
|
||||
getGraphicObject().closeLink();
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ public class Version {
|
||||
}
|
||||
|
||||
public static int beta() {
|
||||
final int beta = 5;
|
||||
final int beta = 6;
|
||||
return beta;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user