diff --git a/image.hex b/image.hex new file mode 100644 index 000000000..57e6a1d2b --- /dev/null +++ b/image.hex @@ -0,0 +1 @@ +3c 3f 78 6d 6c 20 76 65 72 73 69 6f 6e 3d 22 31 2e 30 22 20 65 6e 63 6f 64 69 6e 67 3d 22 75 74 66 2d 38 22 3f 3e d a 3c 21 2d 2d 20 47 65 6e 65 72 61 74 6f 72 3a 20 41 64 6f 62 65 20 49 6c 6c 75 73 74 72 61 74 6f 72 20 31 36 2e 30 2e 30 2c 20 53 56 47 20 45 78 70 6f 72 74 20 50 6c 75 67 2d 49 6e 20 2e 20 53 56 47 20 56 65 72 73 69 6f 6e 3a 20 36 2e 30 30 20 42 75 69 6c 64 20 30 29 20 20 2d 2d 3e d a 3c 21 44 4f 43 54 59 50 45 20 73 76 67 20 50 55 42 4c 49 43 20 22 2d 2f 2f 57 33 43 2f 2f 44 54 44 20 53 56 47 20 31 2e 31 2f 2f 45 4e 22 20 22 68 74 74 70 3a 2f 2f 77 77 77 2e 77 33 2e 6f 72 67 2f 47 72 61 70 68 69 63 73 2f 53 56 47 2f 31 2e 31 2f 44 54 44 2f 73 76 67 31 31 2e 64 74 64 22 3e d a 3c 73 76 67 20 76 65 72 73 69 6f 6e 3d 22 31 2e 31 22 20 69 64 3d 22 4c 61 79 65 72 5f 31 22 20 78 6d 6c 6e 73 3d 22 68 74 74 70 3a 2f 2f 77 77 77 2e 77 33 2e 6f 72 67 2f 32 30 30 30 2f 73 76 67 22 20 78 6d 6c 6e 73 3a 78 6c 69 6e 6b 3d 22 68 74 74 70 3a 2f 2f 77 77 77 2e 77 33 2e 6f 72 67 2f 31 39 39 39 2f 78 6c 69 6e 6b 22 20 78 3d 22 30 70 78 22 20 79 3d 22 30 70 78 22 d a 9 20 77 69 64 74 68 3d 22 31 36 70 78 22 20 68 65 69 67 68 74 3d 22 31 36 70 78 22 20 76 69 65 77 42 6f 78 3d 22 30 20 30 20 31 36 20 31 36 22 20 73 74 79 6c 65 3d 22 65 6e 61 62 6c 65 2d 62 61 63 6b 67 72 6f 75 6e 64 3a 6e 65 77 20 30 20 30 20 31 36 20 31 36 3b 22 20 78 6d 6c 3a 73 70 61 63 65 3d 22 70 72 65 73 65 72 76 65 22 3e d a 3c 6c 69 6e 65 61 72 47 72 61 64 69 65 6e 74 20 69 64 3d 22 53 56 47 49 44 5f 31 5f 22 20 67 72 61 64 69 65 6e 74 55 6e 69 74 73 3d 22 75 73 65 72 53 70 61 63 65 4f 6e 55 73 65 22 20 78 31 3d 22 35 37 32 2e 36 39 39 32 22 20 79 31 3d 22 38 31 36 2e 33 30 30 38 22 20 78 32 3d 22 35 38 35 2e 36 39 39 32 22 20 79 32 3d 22 38 31 36 2e 33 30 30 38 22 20 67 72 61 64 69 65 6e 74 54 72 61 6e 73 66 6f 72 6d 3d 22 6d 61 74 72 69 78 28 31 20 30 20 30 20 31 20 2d 35 37 31 2e 31 39 39 32 20 2d 38 30 38 2e 38 30 30 38 29 22 3e d a 9 3c 73 74 6f 70 20 20 6f 66 66 73 65 74 3d 22 30 22 20 73 74 79 6c 65 3d 22 73 74 6f 70 2d 63 6f 6c 6f 72 3a 23 46 46 46 39 43 34 22 2f 3e d a 9 3c 73 74 6f 70 20 20 6f 66 66 73 65 74 3d 22 31 22 20 73 74 79 6c 65 3d 22 73 74 6f 70 2d 63 6f 6c 6f 72 3a 23 46 46 46 44 45 37 22 2f 3e d a 3c 2f 6c 69 6e 65 61 72 47 72 61 64 69 65 6e 74 3e d a 3c 72 65 63 74 20 78 3d 22 31 2e 35 22 20 79 3d 22 31 2e 35 22 20 73 74 79 6c 65 3d 22 66 69 6c 6c 3a 75 72 6c 28 23 53 56 47 49 44 5f 31 5f 29 3b 73 74 72 6f 6b 65 3a 23 34 32 34 32 34 32 3b 73 74 72 6f 6b 65 2d 6d 69 74 65 72 6c 69 6d 69 74 3a 31 30 3b 22 20 77 69 64 74 68 3d 22 31 33 22 20 68 65 69 67 68 74 3d 22 31 32 22 2f 3e d a 3c 6c 69 6e 65 20 73 74 79 6c 65 3d 22 66 69 6c 6c 3a 6e 6f 6e 65 3b 73 74 72 6f 6b 65 3a 23 34 32 34 32 34 32 3b 73 74 72 6f 6b 65 2d 6d 69 74 65 72 6c 69 6d 69 74 3a 31 30 3b 22 20 78 31 3d 22 32 22 20 79 31 3d 22 31 31 2e 35 22 20 78 32 3d 22 31 34 22 20 79 32 3d 22 31 31 2e 35 22 2f 3e d a 3c 6c 69 6e 65 20 73 74 79 6c 65 3d 22 66 69 6c 6c 3a 6e 6f 6e 65 3b 73 74 72 6f 6b 65 3a 23 34 32 34 32 34 32 3b 73 74 72 6f 6b 65 2d 6d 69 74 65 72 6c 69 6d 69 74 3a 31 30 3b 22 20 78 31 3d 22 32 22 20 79 31 3d 22 39 2e 35 22 20 78 32 3d 22 31 34 22 20 79 32 3d 22 39 2e 35 22 2f 3e d a 3c 67 3e d a 9 3c 70 61 74 68 20 73 74 79 6c 65 3d 22 66 69 6c 6c 3a 23 34 32 34 32 34 32 3b 22 20 64 3d 22 4d 36 2c 38 4c 34 2c 32 2e 33 68 31 2e 33 6c 31 2e 34 2c 34 2e 32 6c 31 2e 34 2d 34 2e 32 68 31 2e 32 4c 37 2e 33 2c 38 48 36 7a 22 2f 3e d a 9 3c 70 61 74 68 20 73 74 79 6c 65 3d 22 66 69 6c 6c 3a 23 34 32 34 32 34 32 3b 22 20 64 3d 22 4d 39 2e 32 2c 33 2e 38 68 31 76 30 2e 36 63 30 2e 31 2d 30 2e 32 2c 30 2e 33 2d 30 2e 34 2c 30 2e 35 2d 30 2e 35 73 30 2e 35 2d 30 2e 32 2c 30 2e 38 2d 30 2e 32 63 30 2e 35 2c 30 2c 30 2e 39 2c 30 2e 32 2c 31 2e 32 2c 30 2e 36 73 30 2e 35 2c 30 2e 39 2c 30 2e 35 2c 31 2e 36 d a 9 9 63 30 2c 30 2e 37 2d 30 2e 32 2c 31 2e 32 2d 30 2e 35 2c 31 2e 36 53 31 32 2c 38 2e 31 2c 31 31 2e 35 2c 38 2e 31 63 2d 30 2e 32 2c 30 2d 30 2e 34 2c 30 2d 30 2e 36 2d 30 2e 31 73 2d 30 2e 34 2d 30 2e 32 2d 30 2e 36 2d 30 2e 35 76 32 2e 31 48 39 2e 32 56 33 2e 38 7a 20 4d 31 30 2e 33 2c 35 2e 38 63 30 2c 30 2e 35 2c 30 2e 31 2c 30 2e 38 2c 30 2e 33 2c 31 d a 9 9 73 30 2e 34 2c 30 2e 33 2c 30 2e 37 2c 30 2e 33 63 30 2e 33 2c 30 2c 30 2e 35 2d 30 2e 31 2c 30 2e 36 2d 30 2e 33 73 30 2e 33 2d 30 2e 35 2c 30 2e 33 2d 31 63 30 2d 30 2e 34 2d 30 2e 31 2d 30 2e 38 2d 30 2e 33 2d 31 73 2d 30 2e 34 2d 30 2e 33 2d 30 2e 36 2d 30 2e 33 63 2d 30 2e 33 2c 30 2d 30 2e 35 2c 30 2e 31 2d 30 2e 37 2c 30 2e 33 d a 9 9 53 31 30 2e 33 2c 35 2e 34 2c 31 30 2e 33 2c 35 2e 38 7a 22 2f 3e d a 3c 2f 67 3e d a 3c 2f 73 76 67 3e d \ No newline at end of file diff --git a/src/main/dist/data/defaults/data/diagrams/View Diagram/descriptor.xml b/src/main/dist/data/defaults/data/diagrams/View Diagram/descriptor.xml index 3a774de39..83064f0a3 100644 --- a/src/main/dist/data/defaults/data/diagrams/View Diagram/descriptor.xml +++ b/src/main/dist/data/defaults/data/diagrams/View Diagram/descriptor.xml @@ -1,5 +1,5 @@ - + org.openmbee.mdk#Model Development Kit;SysML Extensions.mdxml;UML_Standard_Profile.mdzip @@ -630,6 +630,7 @@ + diff --git a/src/main/java/org/openmbee/mdk/MDKPluginHelper.java b/src/main/java/org/openmbee/mdk/MDKPluginHelper.java index 5ed50c2b7..5980f3786 100644 --- a/src/main/java/org/openmbee/mdk/MDKPluginHelper.java +++ b/src/main/java/org/openmbee/mdk/MDKPluginHelper.java @@ -5,10 +5,13 @@ import com.nomagic.magicdraw.core.Application; import com.nomagic.magicdraw.core.options.EnvironmentOptions; import com.nomagic.magicdraw.evaluation.EvaluationConfigurator; +import com.nomagic.magicdraw.hyperlinks.HyperlinksHandlersRegistry; import com.nomagic.magicdraw.uml.DiagramDescriptor; import com.nomagic.magicdraw.uml.DiagramTypeConstants; import org.openmbee.mdk.cli.AutomatedCommitter; import org.openmbee.mdk.cli.AutomatedViewGenerator; +import org.openmbee.mdk.hyperlinks.TranclusionHandler; +import org.openmbee.mdk.hyperlinks.TransclusionEditorPanel; import org.openmbee.mdk.mms.sync.status.SyncStatusConfigurator; import org.openmbee.mdk.options.ConfigureProjectOptions; import org.openmbee.mdk.options.MDKEnvironmentOptionsGroup; @@ -34,6 +37,8 @@ public void init() { // This somehow allows things to be loaded to evaluate opaque expressions or something. EvaluationConfigurator.getInstance().registerBinaryImplementers(this.getClass().getClassLoader()); + // Add Transclusion Handler + HyperlinksHandlersRegistry.addHandler(new TranclusionHandler()); CommandLineActionManager.getInstance().addAction(new AutomatedViewGenerator()); diff --git a/src/main/java/org/openmbee/mdk/actions/InstanceViewpointAction.java b/src/main/java/org/openmbee/mdk/actions/InstanceViewpointAction.java index 8bb54bd97..8705b5325 100644 --- a/src/main/java/org/openmbee/mdk/actions/InstanceViewpointAction.java +++ b/src/main/java/org/openmbee/mdk/actions/InstanceViewpointAction.java @@ -6,21 +6,31 @@ import com.nomagic.magicdraw.core.Project; import com.nomagic.magicdraw.openapi.uml.SessionManager; import com.nomagic.magicdraw.sysml.util.SysMLProfile; +import com.nomagic.ui.ResizableIconImageIcon; import com.nomagic.uml2.ext.jmi.helpers.ModelHelper; import com.nomagic.uml2.ext.jmi.helpers.StereotypesHelper; +import com.nomagic.uml2.ext.magicdraw.auxiliaryconstructs.mdtemplates.TemplateBinding; +import com.nomagic.uml2.ext.magicdraw.auxiliaryconstructs.mdtemplates.TemplateParameterSubstitution; import com.nomagic.uml2.ext.magicdraw.classes.mdkernel.*; import com.nomagic.uml2.ext.magicdraw.classes.mdkernel.Class; import com.nomagic.uml2.ext.magicdraw.classes.mdkernel.Package; import com.nomagic.uml2.ext.magicdraw.mdprofiles.Stereotype; import com.nomagic.uml2.impl.ElementsFactory; import org.openmbee.mdk.SysMLExtensions; +import org.openmbee.mdk.api.incubating.MDKConstants; +import org.openmbee.mdk.docgen.DocGenUtils; +import org.openmbee.mdk.options.MDKProjectOptions; import org.openmbee.mdk.util.Utils; import java.awt.event.ActionEvent; import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; /** * given a viewpoint composition hierarchy, makes the views, and have them @@ -48,8 +58,8 @@ public InstanceViewpointAction(Element e) { @Override public void actionPerformed(ActionEvent e) { GUILog gl = Application.getInstance().getGUILog(); - sysmlView = SysMLExtensions.getInstanceByProject(project).view().getStereotype(); - sysmlViewpoint = SysMLProfile.getInstanceByProject(project).viewpoint().getStereotype();; + sysmlView = SysMLProfile.getInstanceByProject(project).view().getStereotype(); + sysmlViewpoint = SysMLProfile.getInstanceByProject(project).viewpoint().getStereotype(); ef = Project.getProject(viewpoint).getElementsFactory(); if (sysmlView == null) { gl.log("The view stereotype cannot be found"); @@ -69,7 +79,7 @@ public void actionPerformed(ActionEvent e) { Project project = Application.getInstance().getProject(); try { SessionManager.getInstance().createSession(project, "instance viewpoint"); - instance(pack, (Class) viewpoint, ((Class) viewpoint).getName()); + instanceViewpoint(pack, (Class) viewpoint, ((Class) viewpoint).getName()); SessionManager.getInstance().closeSession(project); } catch (Exception ex) { SessionManager.getInstance().cancelSession(project); @@ -81,13 +91,58 @@ public void actionPerformed(ActionEvent e) { } } - private Class instance(Element owner, Class vp, String name) { + private Class instanceViewpoint(Element owner, Class vp, String name) { + + + HashMap paramMap = new HashMap<>(); + + if (vp.getTemplateBinding().size() > 0) { + TemplateBinding binding = vp.getTemplateBinding().stream().collect(Collectors.toList()).get(0); + + getTemplateMap(paramMap, binding); + Class templateVP = (Class) binding.getTarget().stream().collect(Collectors.toList()).get(0).getOwner(); + + return instance(owner, templateVP, templateVP.getName(), paramMap); + } else { + return instance(owner, vp, name, paramMap); + } + } + + private Class instance(Element owner, Class vp, String name, Map paramMap) { + + Class view = ef.createClassInstance(); view.setOwner(owner); + + if (paramMap.size() > 0) { + StringBuilder nameSB = new StringBuilder(name); + paramMap.forEach((param, replace) -> { + replaceAll(nameSB, "[[" + param + "]]", replace); + }); + name = nameSB.toString(); + } view.setName(name); + if (MDKProjectOptions.instanceVPDoc(project)) { + + String vp_doc = ModelHelper.getComment(vp); + if (vp_doc.isEmpty()) { + vp_doc = "" + name + " placeholder documentation"; + } else { + if (paramMap.size() > 0) { + StringBuilder docSB = new StringBuilder(vp_doc); + paramMap.forEach((param, replace) -> { + replaceAll(docSB, "[[" + param + "]]", replace); + }); + vp_doc = docSB.toString(); + } + } + + ModelHelper.setComment(view, vp_doc); + } + StereotypesHelper.addStereotype(view, sysmlView); Generalization conforms = ef.createGeneralizationInstance(); - StereotypesHelper.addStereotype(conforms, SysMLExtensions.getInstance(owner).conforms().getStereotype()); + StereotypesHelper.addStereotype(conforms, SysMLProfile.getInstance(owner).conform().getStereotype()); ModelHelper.setClientElement(conforms, view); ModelHelper.setSupplierElement(conforms, vp); conforms.setOwner(view); @@ -96,10 +151,10 @@ private Class instance(Element owner, Class vp, String name) { if (type instanceof Class && StereotypesHelper.hasStereotypeOrDerived(type, sysmlViewpoint)) { Class child = null; if (p.getName().isEmpty()) { - child = instance(view, (Class) type, type.getName()); + child = instance(view, (Class) type, type.getName(), paramMap); } else { - child = instance(view, (Class) type, p.getName()); + child = instance(view, (Class) type, p.getName(), paramMap); } Association asso = ef.createAssociationInstance(); asso.getMemberEnd().get(0).setOwner(view); @@ -112,4 +167,51 @@ private Class instance(Element owner, Class vp, String name) { } return view; } + + public static void getTemplateMap(Map paramMap, TemplateBinding binding) { + //Get Paramter Subs + binding.getParameterSubstitution().stream().forEach((parameter) -> { + String name = ((NamedElement) parameter.getFormal().getParameteredElement()).getName(); + if (!paramMap.containsKey(name)) { + Element element = parameter.getActual(); + + if (!(name.endsWith(MDKConstants.ID_KEY_SUFFIX) || name.endsWith(MDKConstants.NAME_KEY_SUFFIX))) { + paramMap.put(name + MDKConstants.ID_KEY_SUFFIX, DocGenUtils.fixId(element)); + paramMap.put(name + MDKConstants.NAME_KEY_SUFFIX, DocGenUtils.fixString(element)); + paramMap.put(name, DocGenUtils.fixString(element)); + } else if (name.endsWith(MDKConstants.ID_KEY_SUFFIX)) { + paramMap.put(name, DocGenUtils.fixId(element)); + } else { + paramMap.put(name, DocGenUtils.fixString(element)); + } + } + + }); + //Get Defaults + binding.getSignature().getParameter().forEach((parameter) -> { + String name = ((NamedElement) parameter.getParameteredElement()).getName(); + if (!paramMap.containsKey(name)) { + Element element = parameter; + + if (!(name.endsWith(MDKConstants.ID_KEY_SUFFIX) || name.endsWith(MDKConstants.NAME_KEY_SUFFIX))) { + paramMap.put(name + MDKConstants.ID_KEY_SUFFIX, DocGenUtils.fixId(element)); + paramMap.put(name + MDKConstants.NAME_KEY_SUFFIX, DocGenUtils.fixString(element)); + paramMap.put(name, DocGenUtils.fixString(element)); + } else if (name.endsWith(MDKConstants.ID_KEY_SUFFIX)) { + paramMap.put(name, DocGenUtils.fixId(element)); + } else { + paramMap.put(name, DocGenUtils.fixString(element)); + } + + } + }); + } + public static void replaceAll(StringBuilder sb, String from, String to) { + int index = sb.indexOf(from); + while (index != -1) { + sb.replace(index, index + from.length(), to); + index += to.length(); + index = sb.indexOf(from, index); + } + } } diff --git a/src/main/java/org/openmbee/mdk/api/incubating/MDKConstants.java b/src/main/java/org/openmbee/mdk/api/incubating/MDKConstants.java index 9e6d07081..8e18424d5 100644 --- a/src/main/java/org/openmbee/mdk/api/incubating/MDKConstants.java +++ b/src/main/java/org/openmbee/mdk/api/incubating/MDKConstants.java @@ -23,6 +23,7 @@ public class MDKConstants { TYPE_KEY = "type", TYPE_ID_KEY = TYPE_KEY + ID_KEY_SUFFIX, NAME_KEY = "name", + NAME_KEY_SUFFIX = "Name", FQN_KEY = "fullyQualifiedName", LABEL_KEY = "label", ID_KEY = "id", diff --git a/src/main/java/org/openmbee/mdk/docgen/DocGenUtils.java b/src/main/java/org/openmbee/mdk/docgen/DocGenUtils.java index 68e810066..637e951b4 100644 --- a/src/main/java/org/openmbee/mdk/docgen/DocGenUtils.java +++ b/src/main/java/org/openmbee/mdk/docgen/DocGenUtils.java @@ -241,6 +241,22 @@ else if (s != null) { return ""; } + public static String fixId(Object s) { + if (s instanceof String) { + return (String) s; + } else if (s instanceof ElementValue) { + return MDUtils.getEID(((ElementValue) s).getElement()); + } else if (s instanceof InstanceValue) { + InstanceSpecification is = ((InstanceValue) s).getInstance(); + if (is != null) { + return MDUtils.getEID(is); + } else { + return "notFound"; + } + } else { + return MDUtils.getEID((Element) s); + } + } //in case Expression is used other than RestrictedValue, only considered as RestrictedValue when 1st operand is LiteralString with "RestrictedValue" private static String getRestrictedValue(Object s) { if (s instanceof Expression) { //Expression is NamedElement diff --git a/src/main/java/org/openmbee/mdk/hyperlinks/AbstractTransclusion.java b/src/main/java/org/openmbee/mdk/hyperlinks/AbstractTransclusion.java new file mode 100644 index 000000000..aa284ad50 --- /dev/null +++ b/src/main/java/org/openmbee/mdk/hyperlinks/AbstractTransclusion.java @@ -0,0 +1,203 @@ +package org.openmbee.mdk.hyperlinks; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import javax.annotation.CheckForNull; + +import com.nomagic.magicdraw.hyperlinks.AbstractElementHyperlink; +import com.nomagic.magicdraw.hyperlinks.AbstractElementHyperlink.UrlResolver; +import com.nomagic.magicdraw.hyperlinks.Hyperlink; +import com.nomagic.magicdraw.hyperlinks.HyperlinkTextAttributes; +import com.nomagic.magicdraw.hyperlinks.Hyperlinks; +import com.nomagic.magicdraw.uml.BaseElement; +import com.nomagic.uml2.project.ElementProject; + + + +public abstract class AbstractTransclusion implements Hyperlink { + private static AbstractTransclusion.UrlResolver urlResolver = new AbstractTransclusion.UrlResolverImpl(); + + private String url; + @CheckForNull + private String text; + private final String protocol; + private final String typeText; + private Map attributes; + private Map textAttributes; + + @CheckForNull + private BaseElement element; + + protected AbstractTransclusion(String url, @CheckForNull String text) { + this(url, text, TransclusionUtils.getProtocol(url), (String)null); + } + + + public AbstractTransclusion(@CheckForNull BaseElement element, String url, @CheckForNull String text, @CheckForNull String typeText, Map attributes) { + this(url, text, "cf", typeText, attributes); + this.element = element; + } + + public AbstractTransclusion(@CheckForNull BaseElement element, String url, @CheckForNull String text, @CheckForNull String typeText, Map attributes, Map textAttributes) { + this(url, text, "cf", typeText, attributes, textAttributes); + this.element = element; + } + protected AbstractTransclusion(String url, @CheckForNull String text, String protocol, @CheckForNull String typeText) { + this(url, text, protocol, typeText, Collections.emptyMap()); + } + + + protected AbstractTransclusion(String url, @CheckForNull String text, String protocol, @CheckForNull String typeText, Map attributes) { + this(url, text, protocol, typeText, attributes, Collections.emptyMap()); + } + + protected AbstractTransclusion(String url, @CheckForNull String text, String protocol, @CheckForNull String typeText, Map attributes, Map textAttributes) { + this.url = url; + this.text = text; + this.protocol = protocol; + if (typeText == null) { + this.typeText = protocol; + } else { + this.typeText = typeText; + } + + this.attributes = new HashMap(attributes); + this.textAttributes = new HashMap(textAttributes); + this.fixURL(); + } + + public final void fixURL() { + if (this.url != null && this.protocol != null && this.protocol.length() > 0) { + int i = this.url.indexOf("://"); + if (i < 0) { + this.url = this.protocol + "://" + this.url; + } + } + + } + + public static String toUrl(@CheckForNull BaseElement element) { + return urlResolver.toUrl(element); + } + + public String getProtocol() { + return this.protocol; + } + + public String getUrl() { + return this.url; + } + + public String getText() { + if (this.text == null) { + this.text = ""; + } + + return this.text; + } + + public BaseElement getElement() { + return this.element; + } + + public static BaseElement getElement(String url, @CheckForNull ElementProject project) { + return urlResolver.getElement(url, project); + } + + protected void setElement(@CheckForNull BaseElement element) { + this.element = element; + } + + public boolean isValid() { + return this.url != null && this.url.length() > 0; + } + + public String getTypeText() { + return this.typeText == null ? this.getProtocol() : this.typeText; + } + + public Map getAttributes() { + return Collections.unmodifiableMap(this.attributes); + } + + public Map getTextAttributes() { + return Collections.unmodifiableMap(this.textAttributes); + } + + public static void setUrlResolver(AbstractTransclusion.UrlResolver urlResolver) { + AbstractTransclusion.urlResolver = urlResolver; + } + + public interface UrlResolver { + String toUrl(@CheckForNull BaseElement var1); + + BaseElement getElement(String var1, @CheckForNull ElementProject var2); + } + + public boolean isExternalHyperlink() { + return this.getElement() == null && isExternalHyperlink(this.getUrl()); + } + + public static boolean isExternalHyperlink(String url) { + return getProjectName(url) != null; + } + + public static class UrlResolverImpl implements UrlResolver { + private UrlResolverImpl() {} + + public String toUrl(BaseElement element) { + return element != null ? "cf://" + element.getID() : "cf://ANY"; + } + + @CheckForNull + public BaseElement getElement(String url, ElementProject project) { + BaseElement element = null; + if ("cf".equals(Hyperlinks.getProtocol(url))) { + url = Hyperlinks.clearParameters(url); + String address = Hyperlinks.getAddress(url); + if (address == null) { + return null; + } + + if (AbstractElementHyperlink.getDiagramID(address) != null) { + return null; + } + + element = project.getElementByID(AbstractElementHyperlink.getElementID(address)); + String qualifiedName; + if (element == null) { + qualifiedName = AbstractElementHyperlink.getModelElementID(url); + if (qualifiedName != null) { + element = project.getElementByID(qualifiedName); + } + } + + if (element == null) { + qualifiedName = AbstractElementHyperlink.getElementQualifiedName(url); + String metaType = AbstractElementHyperlink.getElementMetaType(url); + if (qualifiedName != null && metaType != null) { + return null; + } + } + } + + return element; + } + } + + + public static String getProjectBranch(String url) { + return TransclusionUtils.getParameterValue(url, "projectBranch"); + } + + public static String getProjectName(String url) { + return TransclusionUtils.getParameterValue(url, "projectName"); + } + + public static String getProjectVersion(String url) { + return TransclusionUtils.getParameterValue(url, "projectVersion"); + } + +} diff --git a/src/main/java/org/openmbee/mdk/hyperlinks/DTransclusion.java b/src/main/java/org/openmbee/mdk/hyperlinks/DTransclusion.java new file mode 100644 index 000000000..bf20eebec --- /dev/null +++ b/src/main/java/org/openmbee/mdk/hyperlinks/DTransclusion.java @@ -0,0 +1,22 @@ +package org.openmbee.mdk.hyperlinks; + +import javax.annotation.CheckForNull; + +public class DTransclusion extends AbstractTransclusion { + @CheckForNull + private final String a; + + public DTransclusion(String var1, @CheckForNull String var2) { + this(var1, var2, var2); + } + + public DTransclusion(String var1, @CheckForNull String var2, @CheckForNull String var3) { + super(var1, var2); + this.a = var3; + } + + @CheckForNull + public String s() { + return this.a; + } +} diff --git a/src/main/java/org/openmbee/mdk/hyperlinks/ITransclusion.java b/src/main/java/org/openmbee/mdk/hyperlinks/ITransclusion.java new file mode 100644 index 000000000..7b7d55904 --- /dev/null +++ b/src/main/java/org/openmbee/mdk/hyperlinks/ITransclusion.java @@ -0,0 +1,28 @@ +package org.openmbee.mdk.hyperlinks; + +import java.util.Map; + +import javax.annotation.CheckForNull; + +import com.nomagic.magicdraw.hyperlinks.i; + +import com.nomagic.magicdraw.hyperlinks.HyperlinkTextAttributes; +import com.nomagic.uml2.ext.magicdraw.classes.mdkernel.Element; + +public class ITransclusion extends Transclusion implements i { + public ITransclusion(Element var1, @CheckForNull String var2) { + super(var1, var2); + } + + public ITransclusion(Element var1, @CheckForNull String var2, Map var3) { + super(var1, var2, var3); + } + + public ITransclusion(Element var1, @CheckForNull String var2, Map var3, Map var4) { + super(var1, var2, var3, var4); + } + + public Element s() { + return (Element)this.getElement(); + } +} diff --git a/src/main/java/org/openmbee/mdk/hyperlinks/TranclusionHandler.java b/src/main/java/org/openmbee/mdk/hyperlinks/TranclusionHandler.java new file mode 100644 index 000000000..ca3983170 --- /dev/null +++ b/src/main/java/org/openmbee/mdk/hyperlinks/TranclusionHandler.java @@ -0,0 +1,143 @@ +package org.openmbee.mdk.hyperlinks; + + +import com.dassault_systemes.modeler.magic.ui.BaseElementClickHandlersManager; +import com.nomagic.actions.NMAction; +import com.nomagic.magicdraw.core.Project; +import com.nomagic.magicdraw.hyperlinks.ElementHyperlink; +import com.nomagic.magicdraw.hyperlinks.ElementHyperlinkHandler; +import com.nomagic.magicdraw.hyperlinks.Hyperlink; +import com.nomagic.magicdraw.hyperlinks.HyperlinkHandler; +import com.nomagic.magicdraw.hyperlinks.HyperlinkUtils; +import com.nomagic.magicdraw.hyperlinks.HyperlinksUIUtilsInternal; +import com.nomagic.magicdraw.hyperlinks.ui.HyperlinkEditor; +import com.nomagic.magicdraw.resources.DialogResource; +import com.nomagic.magicdraw.ui.Hint; +import com.nomagic.magicdraw.ui.HintsManager; +import com.nomagic.magicdraw.ui.LocationInTool; +import com.nomagic.magicdraw.ui.browser.Node; +import com.nomagic.magicdraw.ui.dialogs.MDDialogParentProvider; +import com.nomagic.magicdraw.uml.BaseElement; +import com.nomagic.magicdraw.uml.actions.SelectInContainmentTreeAction; +import com.nomagic.ui.BaseMessageDialog; +import com.nomagic.ui.SimpleBaseDialog; +import com.nomagic.uml2.ext.magicdraw.classes.mdkernel.Diagram; +import com.nomagic.uml2.ext.magicdraw.classes.mdkernel.Element; +import java.awt.AWTEvent; +import java.util.function.Function; +import javax.annotation.CheckForNull; +import javax.swing.Icon; + + +public class TranclusionHandler implements HyperlinkHandler { + private static Function EDITOR_FACTORY = TransclusionEditorPanel::new; + + public static void setEditorFactory(Function factoryFunction) { + EDITOR_FACTORY = factoryFunction; + } + + @Override + public boolean isSupportedProtocol(String arg0) { + return "cf".equals(arg0); + } + + @Override + public void activate(@CheckForNull Element var1, Hyperlink var2) { + activate(var1, var2, (AWTEvent)null, LocationInTool.unknown); + } + + public static void activate(@CheckForNull Element var0, Hyperlink var1, @CheckForNull AWTEvent var2, LocationInTool var3) { + Transclusion var4 = var1 instanceof Transclusion ? (Transclusion)var1 : null; + BaseElement var5 = var4 != null && !var4.isExternalHyperlink() ? var4.getElement() : null; + if (var5 != null) { + if (var5 instanceof Element) { + showNotEditableHyperlinkHint((Element)var5, var2); + } + + activateTreeOrOnFind(var5, var2, var3); + } else if (var0 != null) {//(!ExternalElementURLActivator.openExternalURL(var1.getUrl(), var2, var3) && var0 != null) { + BaseMessageDialog var6 = new BaseMessageDialog(MDDialogParentProvider.getProvider().getDialogOwner(), DialogResource.getString("ERROR"), true, SimpleBaseDialog.YES_NO_CANCEL_LABELS, SimpleBaseDialog.YES_NO_CANCEL_ARMAP, (String)null, DialogResource.getString("NOT_VALID_HYPERLINK_REMOVE"), 0, "/com/nomagic/ui/icons/error.png"); + var6.setVisible(true); + if (var6.getResult() == 2) { + Project var7 = Project.getProject(var0); + var7.getCommandHistory().startCommand(DialogResource.getString("EDIT_HYPERLINKS_COMMAND")); + HyperlinkUtils.removeHyperlink(var0, var1); + var7.getCommandHistory().complete(); + } + } + + } + + private static void showNotEditableHyperlinkHint(Element var0, @CheckForNull AWTEvent var1) { + int var2 = HyperlinksUIUtilsInternal.getEventOrLastHyperLinkEventModifiers(var1); + boolean var3 = (var2 & 8) != 0; + if (!(var0 instanceof Diagram) && !var3) { + Hint var4; + if ((var2 & 2) == 0) { + var4 = new Hint("SHOW_NOT_EDITABLE_HYPERLINK_CLICK", DialogResource.getString("NOT_EDITABLE_HYPERLINK_ACTIVATED"), 1); + } else { + var4 = new Hint("SHOW_NOT_EDITABLE_CTRL_HYPERLINK_CLICK", DialogResource.getString("NOT_EDITABLE_CTRL_HYPERLINK_ACTIVATED", new Object[]{NMAction.getMenuShortcutMaskAsString()}), 1); + } + + HintsManager.getInstance().showTip(var4); + } + + } + + @Override + public HyperlinkEditor getEditor() { + return (HyperlinkEditor)EDITOR_FACTORY.apply(this); + } + + @Override + public Icon getIcon(Hyperlink arg0) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'getIcon'"); + } + + public Hyperlink create(String text, String url, @CheckForNull Project project) { + return createHyperlinkInProject(text, url, project); + } + + public static Hyperlink createHyperlinkInProject(@CheckForNull String text, String url, @CheckForNull Project project) { + boolean var3 = false; //Transclusion.isExternalHyperlink(var1); + if (var3) { + return new Transclusion(url, text); + } else { + BaseElement element = project != null ? Transclusion.getElement(url, project) : null; + return (Hyperlink)(element != null ? create(text, project) : new DTransclusion(url, text, text)); + } + } + + public static Transclusion create(@CheckForNull String text, BaseElement element) { + return (Transclusion)(element instanceof Element ? new ITransclusion((Element)element, text) : new Transclusion(element, text)); + } + + + public static void activateTreeOrOnFind(BaseElement element, @CheckForNull AWTEvent var1, LocationInTool var2) { + int var3 = HyperlinksUIUtilsInternal.getEventOrLastHyperLinkEventModifiers(var1); + boolean var4 = (var3 & 8) != 0; + boolean var5 = (var1 == null || var4) && element instanceof Element; + if (var5) { + boolean var6 = Node.isLocked(); + long var7 = 0L; + + try { + if (var6) { + var7 = Node.setLocked(false); + } + + SelectInContainmentTreeAction.selectInBrowser(element); + } finally { + if (var6) { + Node.resetLock(true, var7); + } + + } + } else { + BaseElementClickHandlersManager.onFind(element, var2, var1); + } + + } +} + \ No newline at end of file diff --git a/src/main/java/org/openmbee/mdk/hyperlinks/Transclusion.java b/src/main/java/org/openmbee/mdk/hyperlinks/Transclusion.java new file mode 100644 index 000000000..8133e656b --- /dev/null +++ b/src/main/java/org/openmbee/mdk/hyperlinks/Transclusion.java @@ -0,0 +1,47 @@ +package org.openmbee.mdk.hyperlinks; + +import java.util.Collections; +import java.util.Map; + +import javax.annotation.CheckForNull; + +import com.nomagic.magicdraw.core.Application; +import com.nomagic.magicdraw.core.Project; +import com.nomagic.magicdraw.hyperlinks.HyperlinkTextAttributes; +import com.nomagic.magicdraw.resources.DialogResource; +import com.nomagic.magicdraw.uml.BaseElement; + +public class Transclusion extends AbstractTransclusion { + + private static final String TYPE_TEXT = DialogResource.getString("HyperlinksManagingGeneralPanel.TransclusionTypeValue"); + + public Transclusion(String var1, @CheckForNull String var2) { + this(var1, var2, Collections.emptyMap()); + } + + public Transclusion(BaseElement var1, @CheckForNull String var2) { + this(var1, var2, Collections.emptyMap()); + } + + public Transclusion(String var1, @CheckForNull String var2, Map var3) { + super((BaseElement)null, var1, var2, TYPE_TEXT, var3); + this.setElement(getProjectName(var1) == null ? getElement(var1, this.getProject()) : null); + } + + public Transclusion(@CheckForNull BaseElement var1, @CheckForNull String var2, Map var3) { + super(var1, toUrl(var1), var2, TYPE_TEXT, var3); + } + + public Transclusion(@CheckForNull BaseElement var1, @CheckForNull String var2, Map var3, Map var4) { + super(var1, toUrl(var1), var2, TYPE_TEXT, var3, var4); + } + + @CheckForNull + private Project getProject() { + BaseElement var1 = super.getElement(); + return var1 != null ? Project.getProject(var1) : Application.getInstance().getProject(); + } + + + +} diff --git a/src/main/java/org/openmbee/mdk/hyperlinks/TransclusionDialogResource.java b/src/main/java/org/openmbee/mdk/hyperlinks/TransclusionDialogResource.java new file mode 100644 index 000000000..805beea94 --- /dev/null +++ b/src/main/java/org/openmbee/mdk/hyperlinks/TransclusionDialogResource.java @@ -0,0 +1,34 @@ +package org.openmbee.mdk.hyperlinks; + +import com.nomagic.magicdraw.resources.ResourceManager; + +import java.text.MessageFormat; + +public class TransclusionDialogResource { + + public static final String BUNDLE_NAME = "org.openmbee.mdk.dialogs.TransclusionDialogResources"; + + /** + * Constructs this resource handler. + */ + private TransclusionDialogResource() { + // do nothing. + } + + /** + * Gets resource by key. + * + * @param key key by which to get the resource. + * @return translated resource. + */ + public static String getString(String key) { + return ResourceManager.getStringFor(key, BUNDLE_NAME, TransclusionDialogResource.class.getClassLoader()); + } + + public static String getStringFor(String var0, String... var1) { + String var2 = getString(var0); + var2 = var2.replaceAll("'", "''"); + var2 = MessageFormat.format(var2, (Object[])var1); + return var2; + } +} \ No newline at end of file diff --git a/src/main/java/org/openmbee/mdk/hyperlinks/TransclusionEditorPanel.java b/src/main/java/org/openmbee/mdk/hyperlinks/TransclusionEditorPanel.java new file mode 100644 index 000000000..8cb165104 --- /dev/null +++ b/src/main/java/org/openmbee/mdk/hyperlinks/TransclusionEditorPanel.java @@ -0,0 +1,313 @@ +package org.openmbee.mdk.hyperlinks; + +import javax.annotation.CheckForNull; +import javax.swing.JComboBox; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; + +import com.nomagic.annotation.NotApi; +import com.nomagic.magicdraw.core.Application; +import com.nomagic.magicdraw.core.Project; +import com.nomagic.magicdraw.elementreferenceintext.TransclusionType; +import com.nomagic.magicdraw.elementreferenceintext.ElementReferenceInTextInternalUtils; +import com.nomagic.magicdraw.elementreferenceintext.UpdateMode; +import com.nomagic.magicdraw.elementreferenceintext.resources.ElementReferenceInTextResource; +import com.nomagic.magicdraw.hyperlinks.ElementHyperlink; +import com.nomagic.magicdraw.hyperlinks.Hyperlink; +import com.nomagic.magicdraw.hyperlinks.HyperlinkHandler; +import com.nomagic.magicdraw.hyperlinks.HyperlinkTextAttributes; +import com.nomagic.magicdraw.hyperlinks.ui.HyperlinkEditorOptions; +import com.nomagic.magicdraw.hyperlinks.ui.HyperlinkEditorPanel; +import com.nomagic.magicdraw.hyperlinks.ui.LinkNamePanel; +import com.nomagic.magicdraw.hyperlinks.ui.LinkNameWrapper; +import com.nomagic.magicdraw.resources.DialogResource; +import com.nomagic.magicdraw.ui.Icons; +import com.nomagic.magicdraw.ui.dialogs.banners.BannerFactory; +import com.nomagic.magicdraw.ui.dialogs.banners.DefaultBanner; +import com.nomagic.magicdraw.uml.BaseElement; +import com.nomagic.magicdraw.uml.symbols.PresentationElement; +import com.nomagic.ui.FocusTextField; +import com.nomagic.ui.HiDPIScaleUtilities; +import com.nomagic.ui.ResizableIcon; +import com.nomagic.ui.banners.BannerProvider; + +import java.awt.Insets; +import java.util.Map; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; + +public class TransclusionEditorPanel extends HyperlinkEditorPanel implements BannerProvider { + private final JComboBox typeBox; + private final JComboBox updateBox = new JComboBox(UpdateMode.values()); + private final TransclusionTypePanel typePanel; + private BaseElement b; + private JLabel label; + + public TransclusionEditorPanel(HyperlinkHandler handler) { + super(TransclusionDialogResource.getString("TRANSCLUSION_TAB"),TransclusionDialogResource.getString("TRANSCLUSION_SELECT"), true, handler, "cf"); + this.updateBox.setName(ElementReferenceInTextResource.getString("UPDATE_MODE")); + this.typeBox = new JComboBox(new TransclusionType[]{TransclusionType.NAME, TransclusionType.REPRESENTATION_TEXT, TransclusionType.IMAGE_REPRESENTATION_TEXT, TransclusionType.CUSTOM_TEXT}); + this.typeBox.setName(ElementReferenceInTextResource.getString("DISPLAY_MODE")); + this.typeBox.setSelectedItem(u()); + this.typeBox.addItemListener((var1x) -> { + if (var1x.getStateChange() == 1) { + this.a((TransclusionType)var1x.getItem(), false); + } + + }); + this.typePanel = new TransclusionTypePanel(this.typeBox, this.updateBox); + this.typePanel.init(); + b var2 = new b(); + this.typeBox.setRenderer(var2); + this.updateBox.setRenderer(var2); + this.a((TransclusionType)this.typeBox.getSelectedItem(), true); + } + + protected JComponent createLinkLabel(String text) { + JPanel panel = new JPanel(new GridBagLayout()); + JLabel textLabel = new JLabel(text); + this.label = getLabel(); + this.label.setVisible(false); + GridBagConstraints constraints = new GridBagConstraints(); + constraints.anchor = 18; + constraints.fill = 2; + constraints.insets = new Insets(0, 5, HiDPIScaleUtilities.scaleUI(3), 0); + constraints.gridx = 0; + panel.add(textLabel, constraints); + constraints.insets = new Insets(0, 5, 0, 0); + constraints.gridx = 1; + panel.add(this.label, constraints); + constraints.gridx = 2; + constraints.weightx = 1.0D; + panel.add(new JPanel(), constraints); + return panel; + } + + protected void browse() {} + + @Override + public boolean isProjectScope() { + return true; + } + + private static JLabel getLabel() { + return new JLabel(Icons.WARNING_ICON); + } + + public DefaultBanner getBanner() { + return (DefaultBanner) BannerFactory.createBanner(TransclusionDialogResource.getString("TRANSCLUSION_EDITOR_DIALOG_BANNER_TITLE"), TransclusionDialogResource.getString("TRANSCLUSION_EDITOR_DIALOG_BANNER_DESCRIPTION"), BannerFactory.readBannerIcon("manage_hyperlinks_dialog_banner", ".png")); + } + + private static UpdateMode getUpdateMode() { + Project var0 = Application.getInstance().getProject(); + return var0 != null ? com.nomagic.magicdraw.elementreferenceintext.e.b(var0) : UpdateMode.AUTOMATIC_UPDATE; + } + + private static TransclusionType getTransclusionType() { + Project var0 = Application.getInstance().getProject(); + return var0 != null ? TransclusionUtils.getTransclusionType(var0) : TransclusionType.NAME; + } + + public void setOptions(@CheckForNull HyperlinkEditorOptions var1) { + if (var1 != null && var1.isSimpleMode()) { + this.typeBox.removeItem(TransclusionType.IMAGE_REPRESENTATION_TEXT); + } + + } + + protected FocusTextField createLinkAddressTextField(boolean var1, String var2) { + FocusTextField var3 = super.createLinkAddressTextField(var1, var2); + var3.getDocument().addDocumentListener(new Listener(this)); + return var3; + } + + private void a(@CheckForNull TransclusionType type, boolean var2) { + Hyperlink var3 = this.getHyperlink(LinkNamePanel.getText()); + if (var3 != null) { + this.b(var3); + } + + this.a(var1); + boolean var4 = var1 == TransclusionType.CUSTOM_TEXT; + this.typePanel.setEnabled(var4); + this.e.setEnabled(!var4); + if (var4) { + this.updateBox.setSelectedItem(UpdateMode.NO_UPDATE); + } else if (var2) { + this.updateBox.setSelectedItem(t()); + } + + } + + private void a(@CheckForNull TransclusionType var1) { + if (var1 == TransclusionType.CUSTOM_TEXT) { + this.typePanel.t(); + } else { + this.typePanel.s(); + } + + } + + public Component getComponent() { + Component var1 = super.getComponent(); + return (Component)(var1 instanceof LinkNameWrapper ? new LinkNameWrapper(this.typePanel, ((LinkNameWrapper)var1).getComponent()) : var1); + } + + @CheckForNull + public Hyperlink getHyperlink(String var1) { + Hyperlink var2 = super.getHyperlink(var1); + return this.typePanel.isAvailable() && var2 instanceof ElementHyperlink && c(var2) != null ? this.a((ElementHyperlink)var2) : var2; + } + + private Hyperlink a(ElementHyperlink var1) { + TransclusionType var2 = (TransclusionType)this.d.getSelectedItem(); + BaseElement var3 = var1.getElement(); + if (var3 != null) { + Map var4 = this.a(var1.getAttributes()); + Map var5 = this.b(var3); + String var6 = var1.getText(); + if (var2 != TransclusionType.CUSTOM_TEXT) { + var6 = var2.getReferencedElementTextRepresentation(var3); + } + + return new ElementHyperlink(var3, var6, var4, var5); + } else { + return var1; + } + } + + private Map a(Map var1) { + return a(var1, (TransclusionType)this.d.getSelectedItem(), (UpdateMode)this.e.getSelectedItem()); + } + + /** @deprecated */ + @NotApi( + reason = "No Magic internal source code. This code can be obfuscated and changed on each build." + ) + @Deprecated + public static Map a(Map var0, TransclusionType var1, UpdateMode var2) { + HashMap var3 = new HashMap(var0); + var3.put("erit:display", var1.toString()); + var3.put("erit:update", var2.toString()); + return var3; + } + + private Map b(BaseElement var1) { + return ElementReferenceInTextInternalUtils.getTextAttributes(var1, (TransclusionType)this.d.getSelectedItem()); + } + + public void setHyperlink(Hyperlink var1) { + super.setHyperlink(var1); + this.a(var1); + } + + private void a(Hyperlink var1) { + Map var2 = var1.getAttributes(); + if (!var2.isEmpty()) { + Object var3 = var2.get("erit:display"); + if (var3 != null && !var3.equals(this.d.getSelectedItem().toString())) { + TransclusionType var4 = TransclusionType.getTransclusionType(var3.toString()); + this.d.setSelectedItem(var4); + } + + Object var6 = var2.get("erit:update"); + if (var6 != null) { + UpdateMode var5 = UpdateMode.getUpdateMode(var6.toString(), UpdateMode.AUTOMATIC_CHECK); + if (!var5.equals(this.e.getSelectedItem())) { + this.e.setSelectedItem(var5); + } + } + + if (var3 == null) { + this.d.setSelectedItem(TransclusionType.CUSTOM_TEXT); + } + } + + } + + private void b(Hyperlink var1) { + TransclusionType var2 = (TransclusionType)this.typeBox.getSelectedItem(); + this.typePanel.x(); + if (var2 != TransclusionType.CUSTOM_TEXT) { + BaseElement var3 = c(var1); + TransclusionTypePanel.Label var4 = this.a(var2, var3); + this.typePanel.a(var4); + } + + } + + private TransclusionTypePanel.Label a(TransclusionType var1, @CheckForNull BaseElement var2) { + ResizableIcon var3 = var1 == TransclusionType.IMAGE_REPRESENTATION_TEXT ? Icons.getIconFor(var2) : null; + String var4 = var1.getReferencedElementTextRepresentation(var2); + if (var4.equals("< >")) { + if (var1 == TransclusionType.NAME) { + this.typePanel.v(); + } + + if (var1 == TransclusionType.REPRESENTATION_TEXT) { + this.typePanel.w(); + } + } + + return new TransclusionTypePanel.Label(var3, var4); + } + + @CheckForNull + private static BaseElement c(@CheckForNull Hyperlink var0) { + return var0 instanceof ElementHyperlink ? ((ElementHyperlink)var0).getElement() : null; + } + + private void c(BaseElement var1) { + if (var1 instanceof PresentationElement) { + this.d.setSelectedItem(TransclusionType.CUSTOM_TEXT); + this.d.setEnabled(false); + } else { + if (!this.d.isEditable()) { + this.d.setEnabled(true); + } + + } + } + private class Listener implements DocumentListener { + TransclusionEditorPanel instance; + private Listener(TransclusionEditorPanel instance) { + this.instance = instance; + } + + public void insertUpdate(DocumentEvent var1) { + this.s(); + this.t(); + } + + public void removeUpdate(DocumentEvent var1) { + this.s(); + } + + public void changedUpdate(DocumentEvent var1) { + this.s(); + } + + private void s() { + Hyperlink var1 = this.instance.getHyperlink(LinkNamePanel.getText()); + if (var1 != null) { + this.instance.b(var1); + } + + } + + private void t() { + Hyperlink var1 = this.instance.getHyperlink(LinkNamePanel.getText()); + if (var1 != null) { + BaseElement var2 = TransclusionEditorPanel.c(var1); + if (var2 != null) { + this.instance.c(var2); + } + } + + } + } + +} diff --git a/src/main/java/org/openmbee/mdk/hyperlinks/TransclusionListener.java b/src/main/java/org/openmbee/mdk/hyperlinks/TransclusionListener.java new file mode 100644 index 000000000..cbc007453 --- /dev/null +++ b/src/main/java/org/openmbee/mdk/hyperlinks/TransclusionListener.java @@ -0,0 +1,36 @@ +package org.openmbee.mdk.hyperlinks; + +import javax.swing.JComboBox; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; + + +public class TransclusionListener implements DocumentListener { + + private final TransclusionTypePanel panel; + private final JComboBox box; + + public TransclusionListener(TransclusionTypePanel panel, JComboBox box) { + this.panel = panel; + this.box = box; + } + + public void insertUpdate(DocumentEvent var1) { + this.refresh(); + } + + public void removeUpdate(DocumentEvent var1) { + this.refresh(); + } + + public void changedUpdate(DocumentEvent var1) { + this.refresh(); + } + + private void refresh() { + if (!this.panel.isShowing()) { + this.box.setSelectedItem(TransclusionType.CUSTOM_TEXT); + } + + } + } diff --git a/src/main/java/org/openmbee/mdk/hyperlinks/TransclusionTextAttributes.java b/src/main/java/org/openmbee/mdk/hyperlinks/TransclusionTextAttributes.java new file mode 100644 index 000000000..995607597 --- /dev/null +++ b/src/main/java/org/openmbee/mdk/hyperlinks/TransclusionTextAttributes.java @@ -0,0 +1,6 @@ +package org.openmbee.mdk.hyperlinks; + + +public enum TransclusionTextAttributes { + IMAGE_URL +} diff --git a/src/main/java/org/openmbee/mdk/hyperlinks/TransclusionType.java b/src/main/java/org/openmbee/mdk/hyperlinks/TransclusionType.java new file mode 100644 index 000000000..0824829f1 --- /dev/null +++ b/src/main/java/org/openmbee/mdk/hyperlinks/TransclusionType.java @@ -0,0 +1,39 @@ +package org.openmbee.mdk.hyperlinks; + +import com.nomagic.magicdraw.uml.BaseElement; +import com.nomagic.uml2.ext.jmi.smartlistener.SmartListenerConfig; +import com.nomagic.uml2.ext.magicdraw.classes.mdkernel.Element; +import java.util.Locale; +import java.util.function.Function; +import javax.annotation.CheckForNull; + +public enum TransclusionType { + NAME, + IMAGE_REPRESENTATION_TEXT, + REPRESENTATION_TEXT, + CUSTOM_TEXT; + + private static final String EMPTY_TEXT = ""; + + private static String getElementValue(@CheckForNull BaseElement element, String defaultValue, Function textProducer) { + if (element != null) { + String text = (String)textProducer.apply(element); + return !text.isEmpty() ? text : defaultValue; + } else { + return ""; + } + } + + @CheckForNull + public abstract SmartListenerConfig getSmartListenerConfig(Element var1); + + public abstract String getReferencedElementTextRepresentation(@CheckForNull BaseElement var1); + + public static TransclusionType getTransclusionType(String name) { + try { + return valueOf(name.toUpperCase(Locale.ENGLISH)); + } catch (IllegalArgumentException var2) { + return CUSTOM_TEXT; + } + } + } diff --git a/src/main/java/org/openmbee/mdk/hyperlinks/TransclusionTypePanel.java b/src/main/java/org/openmbee/mdk/hyperlinks/TransclusionTypePanel.java new file mode 100644 index 000000000..822f547f3 --- /dev/null +++ b/src/main/java/org/openmbee/mdk/hyperlinks/TransclusionTypePanel.java @@ -0,0 +1,164 @@ +package org.openmbee.mdk.hyperlinks; + +import java.awt.BorderLayout; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; + +import javax.annotation.CheckForNull; +import javax.swing.Icon; +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.SwingUtilities; + +import com.nomagic.annotation.NotApi; +import com.nomagic.magicdraw.elementreferenceintext.resources.ElementReferenceInTextResource; +import com.nomagic.magicdraw.hyperlinks.ui.LinkNamePanel; +import com.nomagic.magicdraw.resources.DialogResource; +import com.nomagic.magicdraw.ui.Icons; +import com.nomagic.magicdraw.ui.dialogs.specifications.ElementTextField; + +import java.awt.Insets; + +public class TransclusionTypePanel extends LinkNamePanel { + + private final JComboBox typeBox; + private final JComboBox updateBox; + private final ElementTextField c; + private JTextField d; + private final JPanel e; + private final JLabel f; + + public TransclusionTypePanel(JComboBox var1, JComboBox var2) { + this.typeBox = var1; + this.updateBox = var2; + this.f = u(); + this.f.setVisible(false); + this.e = new JPanel(); + this.c = new ElementTextField(); + this.c.setName(DialogResource.getString("TEXT_TO_DISPLAY")); + } + + public void init() { + this.setLayout(new GridBagLayout()); + this.e.setLayout(new BorderLayout()); + GridBagConstraints var1 = new GridBagConstraints(); + var1.anchor = 21; + var1.fill = 2; + var1.insets = new Insets(5, 5, 0, 5); + var1.gridy = 0; + var1.weightx = 0.0D; + JLabel var2 = createTextToDisplayLabel(); + var1.gridx = 0; + this.add(var2, var1); + var1.gridx = 1; + this.add(this.typeBox, var1); + var1.gridx = 2; + this.add(this.f, var1); + this.d = this.getLinkNameField(); + TransclusionListener listener = new TransclusionListener(this, this.typeBox); + this.d.getDocument().addDocumentListener(listener); + var1.gridx = 3; + var1.weightx = 1.0D; + this.add(this.e, var1); + var1.gridy = 1; + var1.weightx = 0.0D; + var1.gridx = 0; + this.add(new JLabel(ElementReferenceInTextResource.getString("UPDATE_MODE") + ":"), var1); + var1.gridx = 1; + this.add(this.updateBox, var1); + } + + private void a(JTextField var1) { + this.e.remove(this.d); + this.d = var1; + this.e.add(this.d); + this.revalidate(); + } + + public void setLocalEditable(boolean var1) { + super.setLocalEditable(var1); + this.typeBox.setEnabled(var1); + this.updateBox.setEnabled(var1); + } + + public void setEnabled(boolean var1) { + super.setEnabled(var1); + this.d.setEnabled(var1); + } + + /** @deprecated */ + @NotApi( + reason = "No Magic internal source code. This code can be obfuscated and changed on each build." + ) + @Deprecated + public void s() { + this.a((JTextField)this.c); + } + + /** @deprecated */ + @NotApi( + reason = "No Magic internal source code. This code can be obfuscated and changed on each build." + ) + @Deprecated + public void t() { + this.a(this.getLinkNameField()); + } + + /** @deprecated */ + @NotApi( + reason = "No Magic internal source code. This code can be obfuscated and changed on each build." + ) + @Deprecated + public void a(TransclusionTypePanel.Label var1) { + SwingUtilities.invokeLater(() -> { + this.c.setData(var1.getText(), var1.getIcon()); + LinkNamePanel.setText(var1.getText()); + }); + } + + private static JLabel u() { + return new TransclusionTypePanel.Label(Icons.WARNING_ICON); + } + + + public void v() { + this.f.setToolTipText(DialogResource.getString("NO_NAME_TEXT_FOR_HYPERLINK")); + this.f.setVisible(true); + } + + public void w() { + this.f.setToolTipText(DialogResource.getString("NO_REPRESENTATION_TEXT_FOR_HYPERLINK")); + this.f.setVisible(true); + } + + + public void x() { + this.f.setVisible(false); + } + + static class Label extends JLabel { + private final javax.swing.Icon icon; + private final String text; + + + public Label(@CheckForNull javax.swing.Icon icon, String text) { + this.icon = icon; + this.text = text; + } + + public Label(@CheckForNull javax.swing.Icon icon) { + this(icon, ""); + } + + + public javax.swing.Icon getIcon() { + return this.icon; + } + + public String getText() { + return this.text; + } + } +} diff --git a/src/main/java/org/openmbee/mdk/hyperlinks/TransclusionUtils.java b/src/main/java/org/openmbee/mdk/hyperlinks/TransclusionUtils.java new file mode 100644 index 000000000..7e238a4fc --- /dev/null +++ b/src/main/java/org/openmbee/mdk/hyperlinks/TransclusionUtils.java @@ -0,0 +1,61 @@ +package org.openmbee.mdk.hyperlinks; + +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; + +import javax.annotation.CheckForNull; + +import com.nomagic.magicdraw.core.Project; +import com.nomagic.magicdraw.core.options.ProjectOptions; +import com.nomagic.magicdraw.properties.Property; + +public class TransclusionUtils { + + public static String getProtocol(String url) { + if (url != null) { + int i = url.indexOf("://"); + if (i > 0) { + return url.substring(0, i); + } + } + + return ""; + } + + + public static String getParameterValue(@CheckForNull String url, String param) { + String ps = param + "="; + if (url == null) { + return null; + } else { + int i = url.indexOf(ps); + if (i != -1) { + String value = url.substring(i + ps.length()); + i = value.indexOf(38); + if (i != -1) { + value = value.substring(0, i); + } + + return URLDecoder.decode(value, StandardCharsets.UTF_8); + } else { + return null; + } + } + } + + public static TransclusionType getTransclusionType(Project var0) { + String var1 = getTransclusionType(var0, "DEFAULT_ELEMENT_REFERENCE_DISPLAY_MODE"); + return var1 != null ? TransclusionType.getTransclusionType(var1) : TransclusionType.NAME; + } + + private static String getTransclusionType(Project var0, String var1) { + Property var2 = getTransclusionProjectProperty(var0, var1); + return var2 != null ? (String)var2.getValue() : null; + } + + @CheckForNull + private static Property getTransclusionProjectProperty(Project var0, String var1) { + ProjectOptions var2 = var0.getOptions(); + return var2 != null ? var2.getProperty("PROJECT_GENERAL_PROPERTIES", var1) : null; + } +} diff --git a/src/main/java/org/openmbee/mdk/ocl/OclEvaluator.java b/src/main/java/org/openmbee/mdk/ocl/OclEvaluator.java index 68e4db035..535bb98a8 100644 --- a/src/main/java/org/openmbee/mdk/ocl/OclEvaluator.java +++ b/src/main/java/org/openmbee/mdk/ocl/OclEvaluator.java @@ -6,8 +6,11 @@ import com.nomagic.magicdraw.uml.BaseElement; import com.nomagic.uml2.ext.jmi.helpers.StereotypesHelper; import com.nomagic.uml2.ext.magicdraw.classes.mdkernel.Class; +import com.nomagic.uml2.ext.magicdraw.commonbehaviors.mdbasicbehaviors.OpaqueBehavior; import com.nomagic.uml2.ext.magicdraw.classes.mdkernel.*; import com.nomagic.uml2.ext.magicdraw.mdprofiles.Stereotype; +import com.nomagic.uml2.ext.magicdraw.metadata.UMLPackage; + import org.openmbee.mdk.SysMLExtensions; import org.openmbee.mdk.api.ElementFinder; import org.openmbee.mdk.api.incubating.convert.Converters; @@ -36,6 +39,7 @@ import org.eclipse.ocl.lpg.AbstractLexer; import org.eclipse.ocl.lpg.AbstractParser; import org.eclipse.ocl.lpg.ProblemHandler; +import org.eclipse.ocl.types.OCLStandardLibrary; import org.eclipse.ocl.util.OCLUtil; import java.util.ArrayList; @@ -44,6 +48,8 @@ import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collector; +import java.util.stream.Collectors; /** * Utility class for encapsulating the OCL query and constraint evaluations. @@ -200,6 +206,7 @@ public static String queryObjectToStringExpression(Object query) { if (query instanceof Element) { Element element = (Element) query; exprString = queryElementToStringExpression(element); + //if () } else if (query instanceof String) { exprString = (String) query; @@ -337,6 +344,7 @@ else if (context instanceof Collection) { // if ( !wasOn ) Debug.turnOff(); return result; } + public static List addOperation(String[] names, EClassifier callerType, EClassifier returnType, EClassifier parmType, String parmName, boolean zeroArgToo, @@ -686,7 +694,7 @@ protected static void addExpressionOperation(final String opName, final String e DocGenOperationInstance doi = new DocGenOperationInstance(); doi.setName(opName); doi.setAnnotationName("DocGenEnvironment"); - + // REVIEW -- Can we do better than OclAny? Would it help avoid needing // to add oclAsType() before and after? doi.setCallerType(OCLStandardLibraryImpl.INSTANCE.getOclAny()); @@ -710,7 +718,95 @@ public Object callOperation(Object source, Object[] args) { envFactory.getDgEnvironment().addDgOperation(doi); envFactory.getDgEvaluationEnvironment().addDgOperation(doi); } + protected static void addAdvancedExpressionOperation(String name, String exprString, OpaqueBehavior expression, DocGenEnvironmentFactory envFactory) { + DocGenOperationInstance doi = new DocGenOperationInstance(); + doi.setName(name); + doi.setAnnotationName("DocGenEnvironment"); + EClassifier callerType = OCLStandardLibraryImpl.INSTANCE.getOclAny(); + EClassifier returnType = OCLStandardLibraryImpl.INSTANCE.getOclAny(); + List preCondition = expression.getPrecondition().stream().collect(Collectors.toList()); + if (preCondition.size() > 0) { + String preConditionType = queryElementToStringExpression(preCondition.get(0)); + callerType = UMLPackage.eINSTANCE.getEClassifier(preConditionType); + if (callerType == null) { + Application.getInstance().getGUILog().log("Unable to find pre-condition type " + preConditionType + " for docgen expression " + name + " defaulting to OCLAny"); + callerType = OCLStandardLibraryImpl.INSTANCE.getOclAny(); + } + } + doi.setCallerType(callerType); + List postCondition = expression.getPostcondition().stream().collect(Collectors.toList()); + if (postCondition.size() > 0) { + String postConditionType = queryElementToStringExpression(postCondition.get(0)); + returnType = UMLPackage.eINSTANCE.getEClassifier(postConditionType); + if (returnType == null) { + Application.getInstance().getGUILog().log("Unable to find post-condition type " + postConditionType + " for docgen expression" + name + " defaulting to OCLAny"); + returnType = OCLStandardLibraryImpl.INSTANCE.getOclAny(); + } + } + doi.setReturnType(returnType); + expression.getOwnedParameter().stream().forEach(param -> { + EParameter eparam = EcoreFactory.eINSTANCE.createEParameter(); + eparam.setName(param.getName()); + if (param.getType() != null) { + EClassifier type = getParamType(param); + if (type != null) { + eparam.setEType(type); + doi.addParameter(eparam); + } else { + doi.addStringParameter(eparam); + } + } + }); + doi.setOperation(new CallOperation() { + @Override + public Object callOperation(Object source, Object[] args) { + Object result = null; + StringBuffer sb = new StringBuffer(); + List params = doi.getParameters(); + for (int i = 0; i < params.size(); i++) { + EParameter p = params.get(i); + try { + String arg = args[i].toString(); + sb.append("let "); + + sb.append(p.getName() + " : " + p.getEType().getName()); + sb.append(" = " + arg); + sb.append(" in "); + } catch (Throwable ignored) {} + } + sb.append(exprString); + try { + result = evaluateQuery(source, sb.toString(), isVerboseDefault()); + } catch (Throwable e) { + Debug.error(true, false, e.getLocalizedMessage()); + } + return result; + }; + }); + + envFactory.getDgEnvironment().addDgOperation(doi); + envFactory.getDgEvaluationEnvironment().addDgOperation(doi); + } + protected static EClassifier getParamType(Parameter param) { + String typeName = param.getType().getName(); + switch (typeName.toLowerCase()) { + case "string": { + return OCLStandardLibraryImpl.INSTANCE.getString(); + } + case "boolean": { + return OCLStandardLibraryImpl.INSTANCE.getBoolean(); + } + case "integer": + case "real": + case "unlimitednatural": { + return OCLStandardLibraryImpl.INSTANCE.getInteger(); + } + default: { + return param.getType().eClass(); + } + } + } // /** // * @param result // * @return an OclCollection @@ -850,6 +946,9 @@ protected static void addExpressionOperations(DocGenEnvironmentFactory envFactor String exprString = queryElementToStringExpression(expression); if (!Utils2.isNullOrEmpty(name)) { try { + if (expression instanceof OpaqueBehavior) { + addAdvancedExpressionOperation(name, exprString, (OpaqueBehavior) expression, envFactory); + } addExpressionOperation(name, exprString, envFactory); } catch (Throwable e) { Debug.error(true, false, "Could not add " + name + " OCL shortcut with expression \"" + exprString + "\". " + e.getLocalizedMessage()); diff --git a/src/main/java/org/openmbee/mdk/options/MDKProjectOptions.java b/src/main/java/org/openmbee/mdk/options/MDKProjectOptions.java index 7bca8d77f..9bee911e2 100644 --- a/src/main/java/org/openmbee/mdk/options/MDKProjectOptions.java +++ b/src/main/java/org/openmbee/mdk/options/MDKProjectOptions.java @@ -34,7 +34,8 @@ public class MDKProjectOptions { MDK_MIGRATE_STEREOTYPE = "MDK_MIGRATE_STEREOTYPE", PROPERTY_AUTOSAVE_MDKMODEL = "PROPERTY_AUTOSAVE_MDKMODEL", PROPERTY_AUTOSAVE_MDKZIP = "PROPERTY_AUTOSAVE_MDKZIP", - PROPERTY_CONTEXT_EXPORT_LEVEL = "PROPERTY_CONTEXT_EXPORT_LEVEL"; + PROPERTY_CONTEXT_EXPORT_LEVEL = "PROPERTY_CONTEXT_EXPORT_LEVEL", + INSTANCE_VP_DOC = "INSTANCE_VP_DOC"; public MDKProjectOptions() { } @@ -46,6 +47,7 @@ public static void init(ProjectOptions var0) { MDKProjectOptions.setOption(var0, VE_HOST_URL,""); MDKProjectOptions.setOption(var0, VE_BASE_PATH,""); MDKProjectOptions.setOption(var0, MDK_MIGRATE_STEREOTYPE, true); + MDKProjectOptions.setOption(var0, INSTANCE_VP_DOC, true); //below were added by LieberLieber's JSON export but doesn't seem to be used/called anywhere //MDKProjectOptions.setOption(var0, PROPERTY_AUTOSAVE_MDKMODEL, false); @@ -245,6 +247,16 @@ public static boolean isMigrationAllowed(Project project) { return false; } + public static boolean instanceVPDoc(Project project) { + if (project != null) { + Property instanceDoc = project.getOptions().getProperty(ProjectOptions.PROJECT_GENERAL_PROPERTIES, INSTANCE_VP_DOC); + if (instanceDoc instanceof BooleanProperty) { + return ((BooleanProperty) instanceDoc).getBoolean(); + } + } + return false; + } + /** * @description * @param project diff --git a/src/main/resources/org/openmbee/mdk/dialogs/TransclusionDialogResources.properties b/src/main/resources/org/openmbee/mdk/dialogs/TransclusionDialogResources.properties new file mode 100644 index 000000000..5055998e9 --- /dev/null +++ b/src/main/resources/org/openmbee/mdk/dialogs/TransclusionDialogResources.properties @@ -0,0 +1,6 @@ +TRANSCLUSION_TAB=OpenMBEE Transclusion +TRANSCLUSION_DESCRIPTION=Add, edit, or delete, transclusions of your model elements +TRANSCLUSION_SELECT=Select element/symbol or paste element URL (cf\://)\: +HyperlinksManagingGeneralPanel.TransclusionTypeValue=Transclusion +TRANSCLUSION_EDITOR_DIALOG_BANNER_TITLE=Add, edit, or delete, OpenMBEE transclusions +TRANSCLUSION_EDITOR_DIALOG_BANNER_DESCRIPTION=Add, edit, or delete, OpenMBEE transclusions \ No newline at end of file diff --git a/src/main/resources/org/openmbee/mdk/options/ProjectOptionsResources.properties b/src/main/resources/org/openmbee/mdk/options/ProjectOptionsResources.properties index 10eb3e8d0..9d6022958 100644 --- a/src/main/resources/org/openmbee/mdk/options/ProjectOptionsResources.properties +++ b/src/main/resources/org/openmbee/mdk/options/ProjectOptionsResources.properties @@ -16,6 +16,8 @@ MMS_GROUP=Model Management System (MMS) MMS_GROUP_DESCRIPTION=Configure Model Management System (MMS) settings VE_GROUP=View Editor VE_GROUP_DESCRIPTION=Configure View Editor settings +INSTANCE_VP_DOC=Instance Viewpoint Documentation +INSTANCE_VP_DOC_DESCRIPTION=Set if the documentation of the viewpoint is copied to the new view as preformatted prompt text PROPERTY_AUTOSAVE_MDKMODEL=Autosave MDK Model Json PROPERTY_AUTOSAVE_MDKMODEL_DESCRIPTION=TBD PROPERTY_AUTOSAVE_MDKZIP=Autosave MDK Zip diff --git a/test.svg b/test.svg new file mode 100644 index 000000000..323ed906f --- /dev/null +++ b/test.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + \ No newline at end of file