From 073d817b71c287ebee1a323c699e87142ea293ea Mon Sep 17 00:00:00 2001 From: Niklas Rentz Date: Fri, 14 Jul 2023 14:47:03 +0200 Subject: [PATCH] added proxy view renderings for bundles --- .../de/cau/cs/kieler/osgiviz/OsgiStyles.xtend | 69 ++++---- .../subsyntheses/BundleSynthesis.xtend | 150 +++++++++--------- 2 files changed, 119 insertions(+), 100 deletions(-) diff --git a/plugins/de.cau.cs.kieler.osgiviz/src/de/cau/cs/kieler/osgiviz/OsgiStyles.xtend b/plugins/de.cau.cs.kieler.osgiviz/src/de/cau/cs/kieler/osgiviz/OsgiStyles.xtend index d14dca6..2275aa2 100644 --- a/plugins/de.cau.cs.kieler.osgiviz/src/de/cau/cs/kieler/osgiviz/OsgiStyles.xtend +++ b/plugins/de.cau.cs.kieler.osgiviz/src/de/cau/cs/kieler/osgiviz/OsgiStyles.xtend @@ -821,11 +821,12 @@ class OsgiStyles { * @param inOverview If this bundle is shown in a bundle overview. * @param hasChildren If this rendering should leave space for a child area. * @param context The view context used in the synthesis. + * @param isProxy If this is the proxy representation of the bundle. * * @return The entire rendering for a bundle. */ def KRoundedRectangle addBundleRendering(KNode node, Bundle b, boolean inOverview, boolean hasChildren, - ViewContext context) { + ViewContext context, boolean isProxy) { node.addRoundedRectangle(ROUNDNESS, ROUNDNESS) => [ addDoubleClickAction(OpenBundleManifestAction::ID) if (b.isIsExternal) { @@ -837,7 +838,7 @@ class OsgiStyles { addRectangle => [ val interactiveButtons = context.getOptionValue(INTERACTIVE_BUTTONS) as Boolean var columns = 1 - if (interactiveButtons) { + if (interactiveButtons && !isProxy) { columns += 2 } setGridPlacement(columns) @@ -851,12 +852,20 @@ class OsgiStyles { if (b.descriptiveName !== null) { name += b.descriptiveName } - addSimpleLabel(name) => [ + // Shorten the name for proxies and add the long name as a hover tooltip + var shortenedName = name + if (shortenedName.length > 18) { + shortenedName = shortenedName.substring(0, 15) + "..." + } + val kText = addSimpleLabel(isProxy ? shortenedName : name) => [ fontBold = true selectionFontBold = true ] + if (isProxy && shortenedName != name) { + kText.tooltip = name + } ] - if (interactiveButtons) { + if (interactiveButtons && !isProxy) { addVerticalLine if (inOverview) { addCollapseExpandButton(false, context) @@ -865,36 +874,38 @@ class OsgiStyles { } } ] - addHorizontalSeperatorLine(1, 0) - addRectangle => [ - invisible = true - addSimpleLabel("ID: " + SynthesisUtils.getId(b.uniqueId, context)) => [ - tooltip = b.uniqueId - addSingleClickAction(SelectRelatedAction::ID, ModifierState.NOT_PRESSED, ModifierState.NOT_PRESSED, - ModifierState.NOT_PRESSED) + if (!isProxy) { + addHorizontalSeperatorLine(1, 0) + addRectangle => [ + invisible = true + addSimpleLabel("ID: " + SynthesisUtils.getId(b.uniqueId, context)) => [ + tooltip = b.uniqueId + addSingleClickAction(SelectRelatedAction::ID, ModifierState.NOT_PRESSED, ModifierState.NOT_PRESSED, + ModifierState.NOT_PRESSED) + ] ] - ] - if (context.getOptionValue(FILTER_DESCRIPTIONS) as Boolean) { - val desc = SynthesisUtils.descriptionLabel(b.about, context) - if (!desc.empty) { - addRectangle => [ - invisible = true - addSimpleLabel("Description: " + desc) => [ - tooltip = b.about - addSingleClickAction(SelectRelatedAction::ID, ModifierState.NOT_PRESSED, ModifierState.NOT_PRESSED, - ModifierState.NOT_PRESSED) + if (context.getOptionValue(FILTER_DESCRIPTIONS) as Boolean) { + val desc = SynthesisUtils.descriptionLabel(b.about, context) + if (!desc.empty) { + addRectangle => [ + invisible = true + addSimpleLabel("Description: " + desc) => [ + tooltip = b.about + addSingleClickAction(SelectRelatedAction::ID, ModifierState.NOT_PRESSED, ModifierState.NOT_PRESSED, + ModifierState.NOT_PRESSED) + ] ] - ] + } } - } - if (hasChildren) { - addHorizontalSeperatorLine(1, 0) - addChildArea + if (hasChildren) { + addHorizontalSeperatorLine(1, 0) + addChildArea + } + addSingleClickAction(SelectRelatedAction::ID, ModifierState.NOT_PRESSED, ModifierState.NOT_PRESSED, + ModifierState.NOT_PRESSED) + setSelectionStyle } setShadow(SHADOW_COLOR.color, 4, 4) - addSingleClickAction(SelectRelatedAction::ID, ModifierState.NOT_PRESSED, ModifierState.NOT_PRESSED, - ModifierState.NOT_PRESSED) - setSelectionStyle ] } diff --git a/plugins/de.cau.cs.kieler.osgiviz/src/de/cau/cs/kieler/osgiviz/subsyntheses/BundleSynthesis.xtend b/plugins/de.cau.cs.kieler.osgiviz/src/de/cau/cs/kieler/osgiviz/subsyntheses/BundleSynthesis.xtend index 310bbc6..acc7736 100644 --- a/plugins/de.cau.cs.kieler.osgiviz/src/de/cau/cs/kieler/osgiviz/subsyntheses/BundleSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.osgiviz/src/de/cau/cs/kieler/osgiviz/subsyntheses/BundleSynthesis.xtend @@ -23,6 +23,7 @@ import de.cau.cs.kieler.klighd.kgraph.KNode import de.cau.cs.kieler.klighd.krendering.extensions.KNodeExtensions import de.cau.cs.kieler.klighd.krendering.extensions.KPortExtensions import de.cau.cs.kieler.klighd.syntheses.AbstractSubSynthesis +import de.cau.cs.kieler.klighd.util.KlighdProperties import de.cau.cs.kieler.osgiviz.OsgiOptions import de.cau.cs.kieler.osgiviz.OsgiStyles import de.cau.cs.kieler.osgiviz.SynthesisUtils @@ -54,79 +55,86 @@ class BundleSynthesis extends AbstractSubSynthesis { override transform(BundleContext bc) { val bundle = bc.modelElement - return #[ - bc.createNode() => [ - addLayoutParam(CoreOptions::PORT_CONSTRAINTS, PortConstraints::FIXED_ORDER) - associateWith(bc) - data += createKIdentifier => [ it.id = bc.hashCode.toString ] - - // Only show any connection ports if this bundle is shown in a bundle overview. - if (bc.parent instanceof BundleOverviewContext) { - // The ports that show the connection to the usedBy / required bundles with actions to add them to - // the view. - val filteredUsedByBundles = SynthesisUtils.filteredElements(bundle.usedByBundle, - bc.parent as IOverviewVisualizationContext, usedContext) - if (!filteredUsedByBundles.empty) { - ports += createPort(bc, "usedByBundles") => [ - associateWith(bc) - // Identifier helps for connecting to this port later. - data += createKIdentifier => [ it.id = "usedByBundles" ] - // Used by bundles are always shown and expanded to the west against the drawing direction. - addLayoutParam(CoreOptions::PORT_SIDE, PortSide::WEST) - addUsedByBundlesPortRendering(filteredUsedByBundles.size, bc.allRequiringBundlesShown) - width = 12 - height = 12 - ] - } - val filteredRequiredBundles = SynthesisUtils.filteredElements(bundle.requiredBundles, - bc.parent as IOverviewVisualizationContext, usedContext) - if (!filteredRequiredBundles.empty) { - ports += createPort(bc, "requiredBundles") => [ - associateWith(bc) - data += createKIdentifier => [ it.id = "requiredBundles" ] - // Required bundles are always shown and expanded to the east with the drawing direction. - addLayoutParam(CoreOptions::PORT_SIDE, PortSide::EAST) - addLayoutParam(CoreOptions::PORT_INDEX, 0) - addRequiredBundlesPortRendering(filteredRequiredBundles.size, bc.allRequiredBundlesShown) - width = 12 - height = 12 - ] - } - // Port for connection of imported packages. - val importedPackages = bundle.importedPackages - if (!importedPackages.empty) { - ports += createPort(bc, "importedPackages") => [ - associateWith(bc) - data += createKIdentifier => [ it.id = "importedPackages" ] - // Bundles supporting used packages are always shown and expanded to the east with the drawing direction. - addLayoutParam(CoreOptions::PORT_SIDE, PortSide::EAST) - addLayoutParam(CoreOptions::PORT_INDEX, 1) - addUsedPackagesPortRendering(bc.allUsedPackagesShown) - width = 12 - height = 12 - ] - } - } - - // Show a service component overview of all service components provided by this bundle. - // Only show this, if the option for it says so and if the context is available. - if (usedContext.getOptionValue(OsgiOptions.BUNDLE_SHOW_SERVICES) === true - && bc.serviceOverviewContext !== null) { - setLayoutOption(CoreOptions::NODE_SIZE_CONSTRAINTS, EnumSet.of(SizeConstraint.MINIMUM_SIZE)) - // Commented out due to null pointer in ELK caused by a possible hierarchic edge going over this box layout + val node = bc.createNode() + val proxy = bc.createNode("proxy") + node.addLayoutParam(CoreOptions::PORT_CONSTRAINTS, PortConstraints::FIXED_ORDER) + node.associateWith(bc) + proxy.associateWith(bc) + node.data += createKIdentifier => [ it.id = bc.hashCode.toString ] + proxy.data += createKIdentifier => [ it.id = bc.hashCode.toString + "-proxy"] + + // Only show any connection ports if this bundle is shown in a bundle overview. + if (bc.parent instanceof BundleOverviewContext) { + // The ports that show the connection to the usedBy / required bundles with actions to add them to + // the view. + val filteredUsedByBundles = SynthesisUtils.filteredElements(bundle.usedByBundle, + bc.parent as IOverviewVisualizationContext, usedContext) + if (!filteredUsedByBundles.empty) { + node.ports += createPort(bc, "usedByBundles") => [ + associateWith(bc) + // Identifier helps for connecting to this port later. + data += createKIdentifier => [ it.id = "usedByBundles" ] + // Used by bundles are always shown and expanded to the west against the drawing direction. + addLayoutParam(CoreOptions::PORT_SIDE, PortSide::WEST) + addUsedByBundlesPortRendering(filteredUsedByBundles.size, bc.allRequiringBundlesShown) + width = 12 + height = 12 + ] + } + val filteredRequiredBundles = SynthesisUtils.filteredElements(bundle.requiredBundles, + bc.parent as IOverviewVisualizationContext, usedContext) + if (!filteredRequiredBundles.empty) { + node.ports += createPort(bc, "requiredBundles") => [ + associateWith(bc) + data += createKIdentifier => [ it.id = "requiredBundles" ] + // Required bundles are always shown and expanded to the east with the drawing direction. + addLayoutParam(CoreOptions::PORT_SIDE, PortSide::EAST) + addLayoutParam(CoreOptions::PORT_INDEX, 0) + addRequiredBundlesPortRendering(filteredRequiredBundles.size, bc.allRequiredBundlesShown) + width = 12 + height = 12 + ] + } + // Port for connection of imported packages. + val importedPackages = bundle.importedPackages + if (!importedPackages.empty) { + node.ports += createPort(bc, "importedPackages") => [ + associateWith(bc) + data += createKIdentifier => [ it.id = "importedPackages" ] + // Bundles supporting used packages are always shown and expanded to the east with the drawing direction. + addLayoutParam(CoreOptions::PORT_SIDE, PortSide::EAST) + addLayoutParam(CoreOptions::PORT_INDEX, 1) + addUsedPackagesPortRendering(bc.allUsedPackagesShown) + width = 12 + height = 12 + ] + } + } + + // Show a service component overview of all service components provided by this bundle. + // Only show this, if the option for it says so and if the context is available. + if (usedContext.getOptionValue(OsgiOptions.BUNDLE_SHOW_SERVICES) === true + && bc.serviceOverviewContext !== null) { + node.setLayoutOption(CoreOptions::NODE_SIZE_CONSTRAINTS, EnumSet.of(SizeConstraint.MINIMUM_SIZE)) + // Commented out due to null pointer in ELK caused by a possible hierarchic edge going over this box layout // SynthesisUtils.configureBoxLayout(it) // setLayoutOption(BoxLayouterOptions.BOX_PACKING_MODE, PackingMode.GROUP_MIXED) - val componentOverviewNodes = serviceOverviewSynthesis.transform(bc.serviceOverviewContext) - children += componentOverviewNodes - } - - // Add the rendering. - val hasChildren = !children.empty - val boolean inOverview = bc.parent instanceof BundleOverviewContext - || bc.parent instanceof ServiceOverviewContext - addBundleRendering(bundle, inOverview, hasChildren, usedContext) - ] - ] + val componentOverviewNodes = serviceOverviewSynthesis.transform(bc.serviceOverviewContext) + node.children += componentOverviewNodes + } + + // Add the rendering. + val hasChildren = !node.children.empty + val boolean inOverview = bc.parent instanceof BundleOverviewContext + || bc.parent instanceof ServiceOverviewContext + node.addBundleRendering(bundle, inOverview, hasChildren, usedContext, false) + proxy.addBundleRendering(bundle, inOverview, hasChildren, usedContext, true) + + node.setProperty(KlighdProperties.PROXY_VIEW_RENDER_NODE_AS_PROXY, true) + // FIXME: Do we need to create a proxy node if we only need its data? + node.setProperty(KlighdProperties.PROXY_VIEW_PROXY_RENDERING, proxy.data) + + return #[node] } }