diff --git a/org.fortiss.tooling.base.ui/META-INF/MANIFEST.MF b/org.fortiss.tooling.base.ui/META-INF/MANIFEST.MF index 791aa8d77355695d76da7a1ea13c3e00bd1cffee..42280c20dac8696d2d983387342bc6c3f3fef1cb 100644 --- a/org.fortiss.tooling.base.ui/META-INF/MANIFEST.MF +++ b/org.fortiss.tooling.base.ui/META-INF/MANIFEST.MF @@ -25,7 +25,9 @@ Export-Package: org.fortiss.tooling.base.ui, org.fortiss.tooling.base.ui.editor, org.fortiss.tooling.base.ui.editor.annotations, org.fortiss.tooling.base.ui.editor.fx, - org.fortiss.tooling.base.ui.editor.fx.visuals, + org.fortiss.tooling.base.ui.editor.fx.controller, + org.fortiss.tooling.base.ui.editor.fx.model, + org.fortiss.tooling.base.ui.editor.fx.visual, org.fortiss.tooling.base.ui.editpart, org.fortiss.tooling.base.ui.editpart.allocation, org.fortiss.tooling.base.ui.editpart.command, diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/.ratings b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/.ratings new file mode 100644 index 0000000000000000000000000000000000000000..4811e9c2991d2e451beef74b3519eb1eeb70d8b0 --- /dev/null +++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/.ratings @@ -0,0 +1,10 @@ +ContextMenuUtil.java 7be87ce47b775d90c533078e22d4d445d9864caf GREEN +EObjectDiagramController.java 66b14c1c77953cad7caecae1e04f455958943f28 GREEN +EObjectModelChangeProvider.java f4b60cebb088a5c81ca92a41614e1a5d40030502 GREEN +EObjectRectangularResizableContentControllerBase.java 787a540213f29e8daaecd9afe98af8b3f4088db7 GREEN +KernelServiceBasedModelChangeProviderBase.java 18e48f17ea8dfba90de024a8959fc5a4b0d05d45 GREEN +LayoutModelChangeProvider.java b5449d02eaf39086909720c43e21bd061005fc9e GREEN +LayoutedContentAnchorageController.java 3794b41d76e9ce14ead0bd812cde5c1a6d348d5c GREEN +LayoutedDiagramAnchorageController.java 1e1ac7c5fa26c632736f5023e90f05d09bc0710d GREEN +LayoutedLinkBendPointController.java a8372485ae96f2abf773d1baeb1f8c7b2b25985f GREEN +LayoutedRectangularResizableContentController.java 1e18af3ee10dd3754325ed389fed664da65a0b61 GREEN diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/ContextMenuUtil.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/ContextMenuUtil.java similarity index 98% rename from org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/ContextMenuUtil.java rename to org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/ContextMenuUtil.java index 3e04dbd52ee99a59735d39b4087c55b07fb91076..7be87ce47b775d90c533078e22d4d445d9864caf 100644 --- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/ContextMenuUtil.java +++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/ContextMenuUtil.java @@ -13,7 +13,7 @@ | See the License for the specific language governing permissions and | | limitations under the License. | +--------------------------------------------------------------------------*/ -package org.fortiss.tooling.base.ui.editor.fx; +package org.fortiss.tooling.base.ui.editor.fx.controller; import static org.fortiss.tooling.base.utils.LayoutModelElementFactory.createPoint; diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/EObjectBasedDiagramControllerBase.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/EObjectDiagramController.java similarity index 71% rename from org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/EObjectBasedDiagramControllerBase.java rename to org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/EObjectDiagramController.java index 3564ece9b3cac29caaf9201e0be3451a6a3c2b21..66b14c1c77953cad7caecae1e04f455958943f28 100644 --- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/EObjectBasedDiagramControllerBase.java +++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/EObjectDiagramController.java @@ -11,12 +11,13 @@ * Florian Hoelzl (fortiss GmbH) - initial implementation * *******************************************************************************/ -package org.fortiss.tooling.base.ui.editor.fx; +package org.fortiss.tooling.base.ui.editor.fx.controller; import static java.lang.Math.max; -import static org.fortiss.tooling.base.ui.editor.fx.ContextMenuUtil.createDisplayMenu; -import static org.fortiss.tooling.base.ui.editor.fx.ContextMenuUtil.createElementCompositionContext; -import static org.fortiss.tooling.base.ui.editor.fx.ContextMenuUtil.createPrototypeMenu; +import static java.util.Objects.requireNonNull; +import static org.fortiss.tooling.base.ui.editor.fx.controller.ContextMenuUtil.createDisplayMenu; +import static org.fortiss.tooling.base.ui.editor.fx.controller.ContextMenuUtil.createElementCompositionContext; +import static org.fortiss.tooling.base.ui.editor.fx.controller.ContextMenuUtil.createPrototypeMenu; import java.util.List; @@ -39,18 +40,20 @@ import javafx.scene.control.MenuItem; * * @author hoelzl */ -public abstract class EObjectBasedDiagramControllerBase extends ControllerBase { +public class EObjectDiagramController<T extends EObject> extends ControllerBase { /** The model change provider. */ private final EObjectModelChangeProvider modelChangeProvider; /** Constructor. */ - public EObjectBasedDiagramControllerBase(IMVCBundle mvcb) { + public EObjectDiagramController(IMVCBundle mvcb, Class<T> modelType) { super(mvcb); - if(!(getModel() instanceof EObject)) { - throw new IllegalArgumentException("Model element must be an instance of an EObject."); + Object model = requireNonNull(mvcb.getModel(), "The given model is null!"); + if(!modelType.isAssignableFrom(model.getClass())) { + throw new IllegalArgumentException("Expected model of type " + + modelType.getSimpleName() + ", but was " + model.getClass().getSimpleName()); } - this.modelChangeProvider = new EObjectModelChangeProvider(getEObject()); + this.modelChangeProvider = new EObjectModelChangeProvider(getModelElement()); } /** {@inheritDoc} */ @@ -60,9 +63,10 @@ public abstract class EObjectBasedDiagramControllerBase extends ControllerBase { } /** Returns the {@link EObject} model element. */ - protected EObject getEObject() { + @SuppressWarnings("unchecked") + protected T getModelElement() { // wild cast works: see constructor check with exception - return (EObject)getModel(); + return (T)getModel(); } /** {@inheritDoc} */ @@ -74,7 +78,7 @@ public abstract class EObjectBasedDiagramControllerBase extends ControllerBase { double y = max(features.getVerticalSpacing(), diagramLocation.getY()); // wild cast works: see constructor exception - EObject modelParent = getEObject(); + T modelParent = getModelElement(); IElementCompositionContext edc = createElementCompositionContext(modelParent, x, y, true, getViewer().getFeatures().getCurrentZoomFactor()); List<MenuItem> result = createPrototypeMenu(modelParent, edc); diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/EObjectModelChangeProvider.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/EObjectModelChangeProvider.java similarity index 97% rename from org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/EObjectModelChangeProvider.java rename to org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/EObjectModelChangeProvider.java index 664e4db2e32124832682aff8235ac380ed4db1c0..f4b60cebb088a5c81ca92a41614e1a5d40030502 100644 --- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/EObjectModelChangeProvider.java +++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/EObjectModelChangeProvider.java @@ -13,7 +13,7 @@ | See the License for the specific language governing permissions and | | limitations under the License. | +--------------------------------------------------------------------------*/ -package org.fortiss.tooling.base.ui.editor.fx; +package org.fortiss.tooling.base.ui.editor.fx.controller; import org.eclipse.emf.common.notify.Adapter; import org.eclipse.emf.common.notify.Notification; diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/EObjectBasedRectangularResizableContentControllerBase.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/EObjectRectangularResizableContentControllerBase.java similarity index 61% rename from org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/EObjectBasedRectangularResizableContentControllerBase.java rename to org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/EObjectRectangularResizableContentControllerBase.java index a263a6c123ee96015e0a5c37b6e3c13ebd0e8a75..787a540213f29e8daaecd9afe98af8b3f4088db7 100644 --- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/EObjectBasedRectangularResizableContentControllerBase.java +++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/EObjectRectangularResizableContentControllerBase.java @@ -11,11 +11,14 @@ * Florian Hoelzl (fortiss GmbH) - initial implementation * *******************************************************************************/ -package org.fortiss.tooling.base.ui.editor.fx; +package org.fortiss.tooling.base.ui.editor.fx.controller; import static java.lang.Math.max; -import static org.fortiss.tooling.base.ui.editor.fx.ContextMenuUtil.createElementCompositionContext; -import static org.fortiss.tooling.base.ui.editor.fx.ContextMenuUtil.createPrototypeMenu; +import static java.util.Objects.requireNonNull; +import static org.fortiss.tooling.base.layout.DefaultLayoutConstants.DEFAULT_SHAPE_MINIMUM_HEIGHT; +import static org.fortiss.tooling.base.layout.DefaultLayoutConstants.DEFAULT_SHAPE_MINIMUM_WIDTH; +import static org.fortiss.tooling.base.ui.editor.fx.controller.ContextMenuUtil.createElementCompositionContext; +import static org.fortiss.tooling.base.ui.editor.fx.controller.ContextMenuUtil.createPrototypeMenu; import java.util.List; @@ -25,9 +28,12 @@ import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramCoordinate; import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramViewerFeatures; import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.change.Change; import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.controller.IClickController; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.controller.IDragController; import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.controller.base.ClickControllerBase; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.controller.rectangular.RectangularContentAnchorageMoveController; import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.controller.rectangular.RectangularResizableContentControllerBase; import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.model.IModelChangeProvider; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IContentAnchorageMVCBundle; import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IContentMVCBundle; import org.fortiss.tooling.base.model.element.ElementPackage; import org.fortiss.tooling.base.model.layout.ILayoutedModelElement; @@ -37,6 +43,7 @@ import org.fortiss.tooling.kernel.ui.extension.IModelElementHandler; import org.fortiss.tooling.kernel.ui.service.IModelEditorBindingService; import org.fortiss.tooling.kernel.ui.service.IModelElementHandlerService; +import javafx.geometry.Dimension2D; import javafx.scene.Node; import javafx.scene.control.MenuItem; import javafx.scene.input.MouseEvent; @@ -47,28 +54,29 @@ import javafx.scene.input.MouseEvent; * * @author hoelzl */ -public abstract class EObjectBasedRectangularResizableContentControllerBase +public abstract class EObjectRectangularResizableContentControllerBase<T extends EObject> extends RectangularResizableContentControllerBase { + /** {@link IModelChangeProvider} for this controller */ - private final LayoutModelElementModelChangeProvider layoutModelChangeProvider; + private final LayoutModelChangeProvider layoutModelChangeProvider; /** The click controller handling double-click to open editor. */ private final IClickController openEditorDoubleClickController = new ClickControllerBase() { @Override public Change singleClick(MouseEvent event, Node node, DiagramCoordinate diagramLocation) { - return EObjectBasedRectangularResizableContentControllerBase.super.getClickController( - node, diagramLocation).singleClick(event, node, diagramLocation); + return EObjectRectangularResizableContentControllerBase.super.getClickController(node, + diagramLocation).singleClick(event, node, diagramLocation); } @Override public Change secondaryClick(MouseEvent event, Node node, DiagramCoordinate diagramLocation) { - return EObjectBasedRectangularResizableContentControllerBase.super.getClickController( - node, diagramLocation).secondaryClick(event, node, diagramLocation); + return EObjectRectangularResizableContentControllerBase.super.getClickController(node, + diagramLocation).secondaryClick(event, node, diagramLocation); } @Override public Change doubleClick(MouseEvent event, Node node, DiagramCoordinate diagramLocation) { - EObject eo = getLayoutedME(); + EObject eo = getModelElement(); IModelElementHandler<EObject> handler = IModelElementHandlerService.getInstance().getModelElementHandler(eo); if(handler != null) { @@ -80,18 +88,22 @@ public abstract class EObjectBasedRectangularResizableContentControllerBase }; /** Constructor. */ - public EObjectBasedRectangularResizableContentControllerBase(IContentMVCBundle mvcb) { + public EObjectRectangularResizableContentControllerBase(IContentMVCBundle mvcb, + Class<T> modelType) { super(mvcb); - if(!(mvcb.getModel() instanceof ILayoutedModelElement)) { - throw new IllegalArgumentException( - "Model element must be an instance of an ILayoutedModelElement."); + + Object model = requireNonNull(mvcb.getModel(), "The given model is null!"); + if(!modelType.isAssignableFrom(model.getClass())) { + throw new IllegalArgumentException("Expected model of type " + + modelType.getSimpleName() + ", but was " + model.getClass().getSimpleName()); } + ILayoutedModelElement lme = (ILayoutedModelElement)mvcb.getModel(); - this.layoutModelChangeProvider = new LayoutModelElementModelChangeProvider(lme) { + this.layoutModelChangeProvider = new LayoutModelChangeProvider(lme) { /** {@inheritDoc} */ @Override protected boolean acceptNotification(Notification notification) { - if(notification.getNotifier() != getLayoutedME()) { + if(notification.getNotifier() != getModelElement()) { return false; } return isAnchorageFeature(notification.getFeature()); @@ -99,10 +111,11 @@ public abstract class EObjectBasedRectangularResizableContentControllerBase }; } - /** Returns the {@link ILayoutedModelElement} model element. */ - protected ILayoutedModelElement getLayoutedME() { + /** Returns the correctly casted model element. */ + @SuppressWarnings("unchecked") + protected T getModelElement() { // wild cast works: see constructor check with exception - return (ILayoutedModelElement)getModel(); + return (T)getModel(); } /** {@inheritDoc} */ @@ -111,6 +124,28 @@ public abstract class EObjectBasedRectangularResizableContentControllerBase return layoutModelChangeProvider; } + /** {@inheritDoc} */ + @Override + protected IDragController createAnchorageMoveController(IContentAnchorageMVCBundle anchorage) { + // we need an overridden port move controller due to the frameworks default snapping + // behavior, which snaps to anchorage size while AF3 ports snap to half their size + return new RectangularContentAnchorageMoveController(this, anchorage) { + /** {@inheritDoc} */ + @Override + protected Dimension2D overrideBorderSnap(Dimension2D anchorageSize) { + // this override is required because ports can be moved by half their size + // while the default implementation would only allow for full size of the port + return new Dimension2D(anchorageSize.getWidth() / 2, anchorageSize.getHeight() / 2); + } + }; + } + + /** {@inheritDoc} */ + @Override + protected Dimension2D getMinimumSize() { + return new Dimension2D(DEFAULT_SHAPE_MINIMUM_WIDTH, DEFAULT_SHAPE_MINIMUM_HEIGHT); + } + /** {@inheritDoc} */ @Override public List<MenuItem> contextMenuContributions(Node node, DiagramCoordinate diagramLocation) { @@ -129,7 +164,7 @@ public abstract class EObjectBasedRectangularResizableContentControllerBase /** {@inheritDoc} */ @Override public void delete() { - IElementCompositorService.getInstance().decompose(getLayoutedME()); + IElementCompositorService.getInstance().decompose(getModelElement()); } /** Checks whether the given feature corresponds to an anchorage model element. */ diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/KernelServiceBasedModelChangeProviderBase.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/KernelServiceBasedModelChangeProviderBase.java similarity index 98% rename from org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/KernelServiceBasedModelChangeProviderBase.java rename to org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/KernelServiceBasedModelChangeProviderBase.java index 7c30347fb0c7cc4aacc79aeaf85167872afc1958..18e48f17ea8dfba90de024a8959fc5a4b0d05d45 100644 --- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/KernelServiceBasedModelChangeProviderBase.java +++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/KernelServiceBasedModelChangeProviderBase.java @@ -13,7 +13,7 @@ | See the License for the specific language governing permissions and | | limitations under the License. | +--------------------------------------------------------------------------*/ -package org.fortiss.tooling.base.ui.editor.fx; +package org.fortiss.tooling.base.ui.editor.fx.controller; import java.util.ArrayList; import java.util.EventObject; diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/LayoutModelElementModelChangeProvider.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/LayoutModelChangeProvider.java similarity index 94% rename from org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/LayoutModelElementModelChangeProvider.java rename to org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/LayoutModelChangeProvider.java index 70c50b789c0088a7e5363bf662bc707a5b5ddf10..b5449d02eaf39086909720c43e21bd061005fc9e 100644 --- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/LayoutModelElementModelChangeProvider.java +++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/LayoutModelChangeProvider.java @@ -13,7 +13,7 @@ | See the License for the specific language governing permissions and | | limitations under the License. | +--------------------------------------------------------------------------*/ -package org.fortiss.tooling.base.ui.editor.fx; +package org.fortiss.tooling.base.ui.editor.fx.controller; import static org.fortiss.tooling.base.model.layout.LayoutPackage.ILAYOUTED_MODEL_ELEMENT__LAYOUT_DATA; @@ -26,11 +26,11 @@ import org.fortiss.tooling.base.model.layout.ILayoutedModelElement; import org.fortiss.tooling.base.model.layout.LayoutPackage; /** - * An {@link KernelServiceBasedModelChangeProviderBase} for {@link ILayoutedModelElement}s. + * A {@link KernelServiceBasedModelChangeProviderBase} for {@link ILayoutedModelElement}s. * * @author hoelzl */ -class LayoutModelElementModelChangeProvider +class LayoutModelChangeProvider extends KernelServiceBasedModelChangeProviderBase<ILayoutedModelElement> { /** The layouted model element. */ private final ILayoutedModelElement modelElement; @@ -38,7 +38,7 @@ class LayoutModelElementModelChangeProvider private final LayoutModelElementAdapter notificationListener; /** Constructor. */ - public LayoutModelElementModelChangeProvider(ILayoutedModelElement modelElement) { + public LayoutModelChangeProvider(ILayoutedModelElement modelElement) { this.modelElement = modelElement; this.notificationListener = new LayoutModelElementAdapter(); } diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/LayoutedModelElementBasedContentAnchorageController.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/LayoutedContentAnchorageController.java similarity index 84% rename from org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/LayoutedModelElementBasedContentAnchorageController.java rename to org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/LayoutedContentAnchorageController.java index c4dfb9dbcd16078c63321d5dec13a902e4088949..3794b41d76e9ce14ead0bd812cde5c1a6d348d5c 100644 --- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/LayoutedModelElementBasedContentAnchorageController.java +++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/LayoutedContentAnchorageController.java @@ -11,8 +11,9 @@ * Florian Hoelzl (fortiss GmbH) - initial implementation * *******************************************************************************/ -package org.fortiss.tooling.base.ui.editor.fx; +package org.fortiss.tooling.base.ui.editor.fx.controller; +import static java.util.Objects.requireNonNull; import static org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramViewerDefaultTags.LINK_TARGET_ALLOWED_TAG; import static org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramViewerDefaultTags.LINK_TARGET_DENIED_TAG; @@ -34,20 +35,23 @@ import org.fortiss.tooling.kernel.service.IElementCompositorService; * * @author hoelzl */ -public class LayoutedModelElementBasedContentAnchorageController +public class LayoutedContentAnchorageController<T extends ILayoutedModelElement> extends DelegatingContentAnchorageController { /** {@link IModelChangeProvider} for this controller */ - private final LayoutModelElementModelChangeProvider layoutModelChangeProvider; + private final LayoutModelChangeProvider layoutModelChangeProvider; /** Constructor. */ - public LayoutedModelElementBasedContentAnchorageController(IContentAnchorageMVCBundle mvcb) { + public LayoutedContentAnchorageController(IContentAnchorageMVCBundle mvcb, Class<T> modelType) { super(mvcb); - if(!(mvcb.getModel() instanceof ILayoutedModelElement)) { - throw new IllegalArgumentException( - "Model element must be an instance of an ILayoutedModelElement."); + + Object model = requireNonNull(mvcb.getModel(), "The given model is null!"); + if(!modelType.isAssignableFrom(model.getClass())) { + throw new IllegalArgumentException("Expected model of type " + + modelType.getSimpleName() + ", but was " + model.getClass().getSimpleName()); } + ILayoutedModelElement lme = (ILayoutedModelElement)mvcb.getModel(); - this.layoutModelChangeProvider = new LayoutModelElementModelChangeProvider(lme); + this.layoutModelChangeProvider = new LayoutModelChangeProvider(lme); } /** Returns the model element. */ diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/LayoutedModelElementBasedDiagramAnchorageController.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/LayoutedDiagramAnchorageController.java similarity index 85% rename from org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/LayoutedModelElementBasedDiagramAnchorageController.java rename to org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/LayoutedDiagramAnchorageController.java index 8e66f7d8207d2b6a03abaa151f94b51449ad66c7..1e1ac7c5fa26c632736f5023e90f05d09bc0710d 100644 --- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/LayoutedModelElementBasedDiagramAnchorageController.java +++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/LayoutedDiagramAnchorageController.java @@ -11,8 +11,9 @@ * Florian Hoelzl (fortiss GmbH) - initial implementation * *******************************************************************************/ -package org.fortiss.tooling.base.ui.editor.fx; +package org.fortiss.tooling.base.ui.editor.fx.controller; +import static java.util.Objects.requireNonNull; import static org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramViewerDefaultTags.LINK_TARGET_ALLOWED_TAG; import static org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramViewerDefaultTags.LINK_TARGET_DENIED_TAG; import static org.fortiss.tooling.base.utils.LayoutDataUtils.moveNode; @@ -34,19 +35,23 @@ import org.fortiss.tooling.kernel.service.IElementCompositorService; * * @author hoelzl */ -public class LayoutedModelElementBasedDiagramAnchorageController extends MoveControllerBase { +public class LayoutedDiagramAnchorageController<T extends ILayoutedModelElement> + extends MoveControllerBase { /** {@link IModelChangeProvider} for this controller */ - private final LayoutModelElementModelChangeProvider layoutModelChangeProvider; + private final LayoutModelChangeProvider layoutModelChangeProvider; /** Constructor. */ - public LayoutedModelElementBasedDiagramAnchorageController(IMVCBundle mvcb) { + public LayoutedDiagramAnchorageController(IMVCBundle mvcb, Class<T> modelType) { super(mvcb); - if(!(mvcb.getModel() instanceof ILayoutedModelElement)) { - throw new IllegalArgumentException( - "Model element must be an instance of an ILayoutedModelElement."); + + Object model = requireNonNull(mvcb.getModel(), "The given model is null!"); + if(!modelType.isAssignableFrom(model.getClass())) { + throw new IllegalArgumentException("Expected model of type " + + modelType.getSimpleName() + ", but was " + model.getClass().getSimpleName()); } + ILayoutedModelElement lme = (ILayoutedModelElement)mvcb.getModel(); - this.layoutModelChangeProvider = new LayoutModelElementModelChangeProvider(lme); + this.layoutModelChangeProvider = new LayoutModelChangeProvider(lme); } /** Returns the model element. */ diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/LayoutedModelElementBasedLinkBendPointController.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/LayoutedLinkBendPointController.java similarity index 70% rename from org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/LayoutedModelElementBasedLinkBendPointController.java rename to org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/LayoutedLinkBendPointController.java index eb00b6119c02199b53b1a8e3cee2687f835b727c..a8372485ae96f2abf773d1baeb1f8c7b2b25985f 100644 --- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/LayoutedModelElementBasedLinkBendPointController.java +++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/LayoutedLinkBendPointController.java @@ -11,8 +11,9 @@ * Florian Hoelzl (fortiss GmbH) - initial implementation * *******************************************************************************/ -package org.fortiss.tooling.base.ui.editor.fx; +package org.fortiss.tooling.base.ui.editor.fx.controller; +import static java.util.Objects.requireNonNull; import static org.fortiss.tooling.base.ui.utils.LayoutDataUIUtils.addConnectionPoint; import static org.fortiss.tooling.base.ui.utils.LayoutDataUIUtils.getConnectionPoints; import static org.fortiss.tooling.base.ui.utils.LayoutDataUIUtils.removeConnectionPoint; @@ -37,24 +38,43 @@ import org.fortiss.tooling.kernel.service.IConnectionCompositorService; * * @author hoelzl */ -public class LayoutedModelElementBasedLinkBendPointController extends LinkControllerBase { +public class LayoutedLinkBendPointController<T extends ILayoutedModelElement> + extends LinkControllerBase { /** {@link IModelChangeProvider} for this controller */ - private final LayoutModelElementModelChangeProvider layoutModelChangeProvider; + private final LayoutModelChangeProvider layoutModelChangeProvider; /** Constructor. */ - public LayoutedModelElementBasedLinkBendPointController(ILinkMVCBundle mvcb) { + public LayoutedLinkBendPointController(ILinkMVCBundle mvcb, Class<T> modelType) { super(mvcb); - if(!(mvcb.getModel() instanceof ILayoutedModelElement)) { - throw new IllegalArgumentException( - "Model element must be an instance of an ILayoutedModelElement."); + + Object model = requireNonNull(mvcb.getModel(), "The given model is null!"); + if(!modelType.isAssignableFrom(model.getClass())) { + throw new IllegalArgumentException("Expected model of type " + + modelType.getSimpleName() + ", but was " + model.getClass().getSimpleName()); } + ILayoutedModelElement lme = (ILayoutedModelElement)mvcb.getModel(); - this.layoutModelChangeProvider = new LayoutModelElementModelChangeProvider(lme); + this.layoutModelChangeProvider = new LayoutModelChangeProvider(lme); } /** Returns the model element. */ - public ILayoutedModelElement getLayoutedME() { - return (ILayoutedModelElement)getModel(); + @SuppressWarnings("unchecked") + public T getModelElement() { + return (T)getModel(); + } + + /** {@inheritDoc} */ + @Override + protected boolean clampAndSnapBendPointToGridCenter() { + // disable default mode + return false; + } + + /** {@inheritDoc} */ + @Override + protected boolean clampAndSnapBendPointToGrid() { + // enable clamping mode + return true; } /** {@inheritDoc} */ @@ -66,7 +86,7 @@ public class LayoutedModelElementBasedLinkBendPointController extends LinkContro /** {@inheritDoc} */ @Override protected int getNumerOfBendPoints() { - return getBendPointList(getLayoutedME()).size(); + return getBendPointList(getModelElement()).size(); } /** Returns the list of bend-points. */ @@ -79,13 +99,13 @@ public class LayoutedModelElementBasedLinkBendPointController extends LinkContro protected void createBendPointAt(int bpIndex, DiagramCoordinate location) { int x = (int)location.getX(); int y = (int)location.getY(); - addConnectionPoint(getLayoutedME(), bpIndex, x, y); + addConnectionPoint(getModelElement(), bpIndex, x, y); } /** {@inheritDoc} */ @Override protected void updateModelAfterBendPointMove(int bpIndex, double dx, double dy) { - List<Point> oldPoints = getBendPointList(getLayoutedME()); + List<Point> oldPoints = getBendPointList(getModelElement()); Point point = oldPoints.get(bpIndex); int oldX = point.getX(); int oldY = point.getY(); @@ -98,7 +118,7 @@ public class LayoutedModelElementBasedLinkBendPointController extends LinkContro /** {@inheritDoc} */ @Override protected void deleteBendPoint(int bpIndex) { - removeConnectionPoint(getLayoutedME(), bpIndex); + removeConnectionPoint(getModelElement(), bpIndex); } /** {@inheritDoc} */ @@ -111,7 +131,7 @@ public class LayoutedModelElementBasedLinkBendPointController extends LinkContro /** {@inheritDoc} */ @Override protected void deleteLink() { - IConnectionCompositorService.getInstance().disconnect(getLayoutedME()); + IConnectionCompositorService.getInstance().disconnect(getModelElement()); } /** {@inheritDoc} */ diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/LayoutedRectangularResizableContentController.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/LayoutedRectangularResizableContentController.java new file mode 100644 index 0000000000000000000000000000000000000000..1e18af3ee10dd3754325ed389fed664da65a0b61 --- /dev/null +++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/LayoutedRectangularResizableContentController.java @@ -0,0 +1,90 @@ +/*-------------------------------------------------------------------------+ +| Copyright 2019 fortiss GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.base.ui.editor.fx.controller; + +import static java.util.Objects.requireNonNull; +import static org.fortiss.tooling.base.ui.utils.LWFXEditorUtils.convertSideToEOrientation; +import static org.fortiss.tooling.base.utils.LayoutDataUtils.getNodeSize; +import static org.fortiss.tooling.base.utils.LayoutDataUtils.moveNode; +import static org.fortiss.tooling.base.utils.LayoutDataUtils.setNodeSize; +import static org.fortiss.tooling.base.utils.LayoutDataUtils.setStickyConnectorLayoutData; + +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.FeedbackChange; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.controller.IController; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IContentAnchorageMVCBundle; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IContentMVCBundle; +import org.fortiss.tooling.base.model.element.IConnector; +import org.fortiss.tooling.base.model.layout.Dimension; +import org.fortiss.tooling.base.model.layout.ILayoutedModelElement; + +import javafx.geometry.Dimension2D; +import javafx.geometry.Side; + +/** + * {@link IController} for {@link ILayoutedModelElement}s that have a rectangular shape. + * + * @author diewald + */ +public class LayoutedRectangularResizableContentController<T extends ILayoutedModelElement> + extends EObjectRectangularResizableContentControllerBase<T> { + /** Constructor. */ + public LayoutedRectangularResizableContentController(IContentMVCBundle mvcb, + Class<T> modelType) { + super(mvcb, modelType); + + Object model = requireNonNull(mvcb.getModel(), "The given model is null!"); + if(!modelType.isAssignableFrom(model.getClass())) { + throw new IllegalArgumentException("Expected model of type " + + modelType.getSimpleName() + ", but was " + model.getClass().getSimpleName()); + } + } + + /** {@inheritDoc} */ + @Override + protected void moveAnchorageToSideOffset(IContentAnchorageMVCBundle anchorage, Side side, + double offset) { + Object connObj = anchorage.getModel(); + if(connObj instanceof IConnector && connObj instanceof ILayoutedModelElement) { + ILayoutedModelElement conn = (ILayoutedModelElement)connObj; + + Dimension2D portDim = anchorage.getVisual().getDimensions(); + int correction; + if(side == Side.TOP || side == Side.BOTTOM) { + correction = (int)portDim.getWidth() / 2; + } else { + correction = (int)portDim.getHeight() / 2; + } + int corrected = (int)offset + correction; + setStickyConnectorLayoutData(conn, convertSideToEOrientation(side), corrected); + } + } + + /** {@inheritDoc} */ + @Override + protected void move(FeedbackChange deltaChange) { + moveNode(getModelElement(), (int)deltaChange.getDeltaX(), (int)deltaChange.getDeltaY()); + } + + /** {@inheritDoc} */ + @Override + protected void resize(FeedbackChange delta) { + T element = getModelElement(); + Dimension d = getNodeSize(element); + int w = d.getWidth() + (int)delta.getDeltaW(); + int h = d.getHeight() + (int)delta.getDeltaH(); + setNodeSize(element, w, h); + } +} diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/model/.ratings b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/model/.ratings new file mode 100644 index 0000000000000000000000000000000000000000..1f94f2987b843eba33765b057f6d210e4bbbcbb4 --- /dev/null +++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/model/.ratings @@ -0,0 +1 @@ +HierarchicElementModelFactoryBase.java 9996bfc1402c27424f0ae69e64560acce0ef81f4 GREEN diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/model/HierarchicElementModelFactoryBase.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/model/HierarchicElementModelFactoryBase.java new file mode 100644 index 0000000000000000000000000000000000000000..9996bfc1402c27424f0ae69e64560acce0ef81f4 --- /dev/null +++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/model/HierarchicElementModelFactoryBase.java @@ -0,0 +1,106 @@ +/*-------------------------------------------------------------------------+ +| Copyright 2019 fortiss GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.base.ui.editor.fx.model; + +import static java.util.Collections.emptyList; +import static java.util.Objects.requireNonNull; +import static org.fortiss.tooling.common.util.LambdaUtils.filterList; + +import java.util.List; + +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.model.IModelFactory; +import org.fortiss.tooling.base.model.element.IConnection; +import org.fortiss.tooling.base.model.element.IHierarchicElement; + +/** + * {@link IModelFactory} for {@link IHierarchicElement}s of editors. + * + * @author diewald + */ +public abstract class HierarchicElementModelFactoryBase<T extends IHierarchicElement> + implements IModelFactory { + /** The currently edited element. */ + private final T rootElement; + + /** Constructor. */ + public HierarchicElementModelFactoryBase(T root) { + this.rootElement = requireNonNull(root); + } + + /** {@inheritDoc} */ + @Override + public T getRootModel() { + return rootElement; + } + + /** {@inheritDoc} */ + @Override + public List<?> getDiagramAnchorageModels() { + return rootElement.getConnectors(); + } + + /** {@inheritDoc} */ + @Override + public List<?> getContentAnchorageModels(Object parent) { + if(parent instanceof IHierarchicElement) { + return ((IHierarchicElement)parent).getConnectors(); + } + return emptyList(); + } + + /** {@inheritDoc} */ + @Override + public List<?> getLinkModels() { + return filterList(rootElement.getConnections(), + c -> filterPartiallyInitializedConnections(c)); + } + + /** Checks whether the given connection is only partially initialized. */ + private boolean filterPartiallyInitializedConnections(IConnection c) { + return c.getSource() != null && c.getTarget() != null && c.eContainer() != null; + } + + /** {@inheritDoc} */ + @Override + public Object getLinkStart(Object link) { + if(link instanceof IConnection) { + return ((IConnection)link).getSource(); + } + return null; + } + + /** {@inheritDoc} */ + @Override + public Object getLinkEnd(Object link) { + if(link instanceof IConnection) { + return ((IConnection)link).getTarget(); + } + return null; + } + + /** {@inheritDoc} */ + @Override + public Object getParent(Object element) { + // Not used at the moment, so return null. + return null; + } + + /** {@inheritDoc} */ + @Override + public void update() { + // Not used at the moment. + } +} diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/.ratings b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/.ratings new file mode 100644 index 0000000000000000000000000000000000000000..5a82836cd656dbc37a323c788161b6ffab643988 --- /dev/null +++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/.ratings @@ -0,0 +1,9 @@ +CoordinateCorrections.java c5cc475b45de38c56fc2e888a2d3093cd2efb52a GREEN +LayoutedCircularAnchorageContentVisualBase.java 2aa292444671bf644e37bc923b877c92de0235b1 GREEN +LayoutedCircularAnchorageDiagramVisualBase.java f06e3b908020408e3cd268a3c63edcd75ef74f8b GREEN +LayoutedLineLinkVisual.java feea85e0bd288590fbe06c152a8a8b138ea85ca2 GREEN +LayoutedRectangularContentVisualBase.java c2a3937b99284713e0bbcd3ce458874567b25ac5 GREEN +NamedLayoutedCircularAnchorageContentVisual.java c680002469ce897679fa5a3f4af51d1b19cb53d6 GREEN +NamedLayoutedCircularAnchorageDiagramVisual.java 714a176a0569a2049efb4009f710ca66bf3a57fb GREEN +NamedLayoutedLineLinkVisual.java e66e5b2aaa40fe8b22a292e175bb8f3af4539b9d GREEN +NamedLayoutedRectangularContentVisual.java 122e193ac587857d1dad23b42583a0bcf465f0d0 GREEN diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visuals/CoordinateCorrections.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/CoordinateCorrections.java similarity index 87% rename from org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visuals/CoordinateCorrections.java rename to org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/CoordinateCorrections.java index f78a936ba49c5fc4daf29237ecb4e86a446316d4..c5cc475b45de38c56fc2e888a2d3093cd2efb52a 100644 --- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visuals/CoordinateCorrections.java +++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/CoordinateCorrections.java @@ -13,7 +13,7 @@ | See the License for the specific language governing permissions and | | limitations under the License. | +--------------------------------------------------------------------------*/ -package org.fortiss.tooling.base.ui.editor.fx.visuals; +package org.fortiss.tooling.base.ui.editor.fx.visual; import static org.fortiss.tooling.base.layout.DefaultLayoutConstants.DEFAULT_CONNECTOR_SIZE; @@ -27,14 +27,15 @@ import javafx.geometry.Dimension2D; * This class contains corrections of {@link DefaultLayoutConstants}. * * @author hoelzl + * @author diewald */ -class CoordinateCorrections { +public class CoordinateCorrections { /** The insets of the {@link RectangularContentVisualBase}s. */ - /* package */ static final Dimension2D RECTANGLE_INSETS = + public static final Dimension2D RECTANGLE_INSETS = new Dimension2D(DEFAULT_CONNECTOR_SIZE / 2, DEFAULT_CONNECTOR_SIZE / 2); /** The default size of {@link ContentAnchorageVisualBase}s. */ - /* package */ static final Dimension2D ANCHOR_DIMENSION = + public static final Dimension2D ANCHOR_DIMENSION = new Dimension2D(DEFAULT_CONNECTOR_SIZE, DEFAULT_CONNECTOR_SIZE); /** The insets of the {@link ContentAnchorageVisualBase}s. */ - /* package */ static final double ANCHOR_INSET = DEFAULT_CONNECTOR_SIZE / 4.5; + public static final double ANCHOR_INSET = DEFAULT_CONNECTOR_SIZE / 4.5; } diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visuals/LayoutedCircularContentAnchorageVisualBase.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/LayoutedCircularAnchorageContentVisualBase.java similarity index 81% rename from org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visuals/LayoutedCircularContentAnchorageVisualBase.java rename to org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/LayoutedCircularAnchorageContentVisualBase.java index aa546c0c9d975972a33cf22682b5d6634e56d271..2aa292444671bf644e37bc923b877c92de0235b1 100644 --- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visuals/LayoutedCircularContentAnchorageVisualBase.java +++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/LayoutedCircularAnchorageContentVisualBase.java @@ -13,14 +13,14 @@ | See the License for the specific language governing permissions and | | limitations under the License. | +--------------------------------------------------------------------------*/ -package org.fortiss.tooling.base.ui.editor.fx.visuals; +package org.fortiss.tooling.base.ui.editor.fx.visual; import static javafx.scene.paint.Color.BLACK; import static javafx.scene.paint.Color.rgb; import static org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramViewerDefaultTags.LINK_TARGET_ALLOWED_TAG; import static org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramViewerDefaultTags.LINK_TARGET_DENIED_TAG; -import static org.fortiss.tooling.base.ui.editor.fx.visuals.CoordinateCorrections.ANCHOR_DIMENSION; -import static org.fortiss.tooling.base.ui.editor.fx.visuals.CoordinateCorrections.ANCHOR_INSET; +import static org.fortiss.tooling.base.ui.editor.fx.visual.CoordinateCorrections.ANCHOR_DIMENSION; +import static org.fortiss.tooling.base.ui.editor.fx.visual.CoordinateCorrections.ANCHOR_INSET; import static org.fortiss.tooling.base.ui.utils.LWFXEditorUtils.convertEOrientationToSide; import static org.fortiss.tooling.base.ui.utils.LayoutDataUIUtils.getConnectorOffsetOrientation; @@ -46,26 +46,36 @@ import javafx.scene.paint.Paint; * * @author munaro */ -public abstract class LayoutedCircularContentAnchorageVisualBase +public abstract class LayoutedCircularAnchorageContentVisualBase<T extends ILayoutedModelElement> extends CircularContentAnchorageVisualBase implements ISideLayout, IOffsetLayout { /** Constructor. */ - public LayoutedCircularContentAnchorageVisualBase(IContentAnchorageMVCBundle mvcb) { + public LayoutedCircularAnchorageContentVisualBase(IContentAnchorageMVCBundle mvcb, + Class<T> modelType) { super(mvcb); + // TODO(#3877): Move type checks to a common base class. Object model = mvcb.getModel(); - if(!(model instanceof ILayoutedModelElement)) { - throw new IllegalArgumentException( - "Expected model of type ILayoutedModelElement, but was " + - model.getClass().getSimpleName() + "."); + if(model == null) { + throw new IllegalArgumentException("The given model is null!"); + } + if(!modelType.isAssignableFrom(model.getClass())) { + throw new IllegalArgumentException("Expected model of type " + + modelType.getSimpleName() + ", but was " + model.getClass().getSimpleName()); } } + /** Returns the model element in the correct type. */ + @SuppressWarnings("unchecked") + protected T getModelElement() { + return (T)getModel(); + } + /** {@inheritDoc} */ @SuppressWarnings("unchecked") @Override - public <T extends ILayout> T getLayout(Class<T> type) { - return (T)this; + public <S extends ILayout> S getLayout(Class<S> type) { + return (S)this; } /** {@inheritDoc} */ @@ -92,7 +102,7 @@ public abstract class LayoutedCircularContentAnchorageVisualBase /** {@inheritDoc} */ @Override public double getOffset() { - OffsetOrientation offsetOrientation = getConnectorOffsetOrientation(getLayoutedModelElement()); + OffsetOrientation offsetOrientation = getConnectorOffsetOrientation(getModelElement()); double inset = getDimensions().getWidth() / 2; return offsetOrientation.getOffset() - inset; } @@ -101,7 +111,7 @@ public abstract class LayoutedCircularContentAnchorageVisualBase @Override public Side getSide() { // TODO (#3868): Remove null check. - OffsetOrientation offsetOrientation = getConnectorOffsetOrientation(getLayoutedModelElement()); + OffsetOrientation offsetOrientation = getConnectorOffsetOrientation(getModelElement()); EOrientation orientation = EOrientation.NORTH; if(offsetOrientation != null) { orientation = offsetOrientation.getOrientation(); @@ -139,11 +149,4 @@ public abstract class LayoutedCircularContentAnchorageVisualBase } return super.getInteractionColor(); } - - /** Return the {@link ILayoutedModelElement}. */ - // TODO(#3877): Implement an equivalent, but generic method in a common base class. - private ILayoutedModelElement getLayoutedModelElement() { - // Safe wild cast due to type check in constructor - return (ILayoutedModelElement)getModel(); - } } diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visuals/LayoutedCircularDiagramAnchorageVisualBase.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/LayoutedCircularAnchorageDiagramVisualBase.java similarity index 78% rename from org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visuals/LayoutedCircularDiagramAnchorageVisualBase.java rename to org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/LayoutedCircularAnchorageDiagramVisualBase.java index c5cc5fb41777166bc169011324585e51acda04c3..f06e3b908020408e3cd268a3c63edcd75ef74f8b 100644 --- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visuals/LayoutedCircularDiagramAnchorageVisualBase.java +++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/LayoutedCircularAnchorageDiagramVisualBase.java @@ -13,14 +13,14 @@ | See the License for the specific language governing permissions and | | limitations under the License. | +--------------------------------------------------------------------------*/ -package org.fortiss.tooling.base.ui.editor.fx.visuals; +package org.fortiss.tooling.base.ui.editor.fx.visual; import static javafx.scene.paint.Color.BLACK; import static javafx.scene.paint.Color.rgb; import static org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramViewerDefaultTags.LINK_TARGET_ALLOWED_TAG; import static org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramViewerDefaultTags.LINK_TARGET_DENIED_TAG; -import static org.fortiss.tooling.base.ui.editor.fx.visuals.CoordinateCorrections.ANCHOR_DIMENSION; -import static org.fortiss.tooling.base.ui.editor.fx.visuals.CoordinateCorrections.ANCHOR_INSET; +import static org.fortiss.tooling.base.ui.editor.fx.visual.CoordinateCorrections.ANCHOR_DIMENSION; +import static org.fortiss.tooling.base.ui.editor.fx.visual.CoordinateCorrections.ANCHOR_INSET; import static org.fortiss.tooling.base.utils.LayoutDataUtils.getNodePosition; import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IDiagramAnchorageMVCBundle; @@ -39,26 +39,35 @@ import javafx.scene.paint.Paint; * * @author munaro */ -public abstract class LayoutedCircularDiagramAnchorageVisualBase +public abstract class LayoutedCircularAnchorageDiagramVisualBase<T extends ILayoutedModelElement> extends CircularDiagramAnchorageVisualBase { /** Constructor. */ - public LayoutedCircularDiagramAnchorageVisualBase( - IDiagramAnchorageMVCBundle mvcb) { + public LayoutedCircularAnchorageDiagramVisualBase(IDiagramAnchorageMVCBundle mvcb, + Class<T> modelType) { super(mvcb); + // TODO(#3877): Move type checks to a common base class. Object model = mvcb.getModel(); - if(!(model instanceof ILayoutedModelElement)) { - throw new IllegalArgumentException( - "Expected model of type ILayoutedModelElement, but was " + - model.getClass().getSimpleName()); + if(model == null) { + throw new IllegalArgumentException("The given model is null!"); + } + if(!modelType.isAssignableFrom(model.getClass())) { + throw new IllegalArgumentException("Expected model of type " + + modelType.getSimpleName() + ", but was " + model.getClass().getSimpleName()); } } + /** Returns the wrapped model as the expected type. */ + @SuppressWarnings("unchecked") + protected T getModelElement() { + return (T)getModel(); + } + /** {@inheritDoc} */ @Override public Rectangle2D getModelBounds() { - Point p = getNodePosition(getLayoutedModelElement()); + Point p = getNodePosition(getModelElement()); Dimension2D dim = getDimensions(); return new Rectangle2D(p.getX(), p.getY(), dim.getWidth(), dim.getHeight()); } @@ -105,11 +114,4 @@ public abstract class LayoutedCircularDiagramAnchorageVisualBase } return super.getInteractionColor(); } - - /** Return the {@link ILayoutedModelElement}. */ - // TODO(#3877): Move type checks to a common base class. - private ILayoutedModelElement getLayoutedModelElement() { - // Safe wild cast due to type check in constructor - return (ILayoutedModelElement)getModel(); - } } diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visuals/LayoutedLineLinkVisualBase.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/LayoutedLineLinkVisual.java similarity index 78% rename from org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visuals/LayoutedLineLinkVisualBase.java rename to org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/LayoutedLineLinkVisual.java index 429483c1222a26345fbc3bf5c9b2dbe41c6ad5f1..feea85e0bd288590fbe06c152a8a8b138ea85ca2 100644 --- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visuals/LayoutedLineLinkVisualBase.java +++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/LayoutedLineLinkVisual.java @@ -13,7 +13,7 @@ | See the License for the specific language governing permissions and | | limitations under the License. | +--------------------------------------------------------------------------*/ -package org.fortiss.tooling.base.ui.editor.fx.visuals; +package org.fortiss.tooling.base.ui.editor.fx.visual; import static java.util.Collections.emptyList; import static org.fortiss.tooling.base.ui.utils.LWFXEditorUtils.computeLinkToCircleLocation; @@ -36,20 +36,33 @@ import javafx.geometry.Rectangle2D; * * @author munaro */ -public abstract class LayoutedLineLinkVisualBase extends LineLinkVisualBase { +// TODO (TM): As this class already requires the generic type to implement INamedElement +// NamedLayoutedLineLinkVisual becomes useless. Remove INamedElement here and make class +// abstract (consistent with the other Layouted*VisualBase classes) +public abstract class LayoutedLineLinkVisual<T extends ILayoutedModelElement> + extends LineLinkVisualBase { /** Constructor. */ - public LayoutedLineLinkVisualBase(ILinkMVCBundle mvcb) { + public LayoutedLineLinkVisual(ILinkMVCBundle mvcb, Class<T> modelType) { super(mvcb); + // TODO(#3877): Move type checks to a common base class. Object model = mvcb.getModel(); - if(!(model instanceof ILayoutedModelElement)) { - throw new IllegalArgumentException( - "Expected model of type ILayoutedModelElement, but was " + - model.getClass().getSimpleName()); + if(model == null) { + throw new IllegalArgumentException("The given model is null!"); + } + if(!modelType.isAssignableFrom(model.getClass())) { + throw new IllegalArgumentException("Expected model of type " + + modelType.getSimpleName() + ", but was " + model.getClass().getSimpleName()); } } + /** Returns the model element with the expected type. */ + @SuppressWarnings("unchecked") + protected T getModelElement() { + return (T)getModel(); + } + /** {@inheritDoc} */ @Override public DiagramCoordinate getBendPointLocation(int bpIndex) { @@ -85,7 +98,7 @@ public abstract class LayoutedLineLinkVisualBase extends LineLinkVisualBase { /** Returns the list of bend-points. */ private List<Point> getBendPointList() { - Points connectionPoints = getConnectionPoints(getLayoutedModelElement()); + Points connectionPoints = getConnectionPoints(getModelElement()); if(connectionPoints == null) { return emptyList(); } @@ -107,11 +120,4 @@ public abstract class LayoutedLineLinkVisualBase extends LineLinkVisualBase { protected double getInvisibleSelectionLineWidth() { return 3; } - - /** Return the {@link ILayoutedModelElement}. */ - // TODO(#3877): Move type checks to a common base class. - private ILayoutedModelElement getLayoutedModelElement() { - // Safe wild cast due to type check in constructor - return (ILayoutedModelElement)getModel(); - } } diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visuals/LayoutedRectangularContentVisualBase.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/LayoutedRectangularContentVisualBase.java similarity index 83% rename from org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visuals/LayoutedRectangularContentVisualBase.java rename to org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/LayoutedRectangularContentVisualBase.java index d4cd07a8056df99927b160f2d4ce1cf4778d1dfa..c2a3937b99284713e0bbcd3ce458874567b25ac5 100644 --- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visuals/LayoutedRectangularContentVisualBase.java +++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/LayoutedRectangularContentVisualBase.java @@ -13,10 +13,10 @@ | See the License for the specific language governing permissions and | | limitations under the License. | +--------------------------------------------------------------------------*/ -package org.fortiss.tooling.base.ui.editor.fx.visuals; +package org.fortiss.tooling.base.ui.editor.fx.visual; import static java.lang.Math.min; -import static org.fortiss.tooling.base.ui.editor.fx.visuals.CoordinateCorrections.RECTANGLE_INSETS; +import static org.fortiss.tooling.base.ui.editor.fx.visual.CoordinateCorrections.RECTANGLE_INSETS; import static org.fortiss.tooling.base.utils.LayoutDataUtils.getNodeBounds; import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramCoordinate; @@ -39,24 +39,36 @@ import javafx.geometry.Side; * * @author munaro */ -public abstract class LayoutedRectangularContentVisualBase extends RectangularContentVisualBase { +public abstract class LayoutedRectangularContentVisualBase<T extends ILayoutedModelElement> + extends RectangularContentVisualBase { /** Constructor. */ - public LayoutedRectangularContentVisualBase(IContentMVCBundle mvcb) { + public LayoutedRectangularContentVisualBase(IContentMVCBundle mvcb, Class<T> modelType) { super(mvcb); + // TODO(#3877): Move type checks to a common base class. Object model = mvcb.getModel(); - if(!(model instanceof ILayoutedModelElement)) { - throw new IllegalArgumentException( - "Expected model of type ILayoutedModelElement, but was " + - model.getClass().getSimpleName()); + if(model == null) { + throw new IllegalArgumentException("The given model is null!"); + } + if(!modelType.isAssignableFrom(model.getClass())) { + throw new IllegalArgumentException("Expected model of type " + + modelType.getSimpleName() + ", but was " + model.getClass().getSimpleName()); } } + /** Returns the model element with the specified type. */ + // TODO(#3877): Move type checks to a common base class. + @SuppressWarnings("unchecked") + protected T getModelElement() { + // Safe wild cast due to type check in constructor + return (T)getModel(); + } + /** {@inheritDoc} */ @Override public Rectangle2D getModelBounds() { - Rectangle rectangle = getNodeBounds(getLayoutedModelElement()); + Rectangle rectangle = getNodeBounds(getModelElement()); double insetRadius = RECTANGLE_INSETS.getWidth(); double insetDiameter = insetRadius * 2; return new Rectangle2D(rectangle.getX() + insetRadius, rectangle.getY() + insetRadius, @@ -102,11 +114,4 @@ public abstract class LayoutedRectangularContentVisualBase extends RectangularCo protected boolean requireSelectionForResizeGesture() { return false; } - - /** Return the {@link ILayoutedModelElement}. */ - // TODO(#3877): Move type checks to a common base class. - private ILayoutedModelElement getLayoutedModelElement() { - // Safe wild cast due to type check in constructor - return (ILayoutedModelElement)getModel(); - } } diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/NamedLayoutedCircularAnchorageContentVisual.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/NamedLayoutedCircularAnchorageContentVisual.java new file mode 100644 index 0000000000000000000000000000000000000000..c680002469ce897679fa5a3f4af51d1b19cb53d6 --- /dev/null +++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/NamedLayoutedCircularAnchorageContentVisual.java @@ -0,0 +1,43 @@ +/*-------------------------------------------------------------------------+ +| Copyright 2019 fortiss GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.base.ui.editor.fx.visual; + +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IContentAnchorageMVCBundle; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.visual.IVisual; +import org.fortiss.tooling.base.model.element.IConnector; +import org.fortiss.tooling.base.model.layout.ILayoutedModelElement; +import org.fortiss.tooling.kernel.model.INamedElement; + +/** + * {@link IVisual} for layouted and named {@link IConnector}s of some content element within a + * diagram (sticky connectors). + * + * @author diewald + */ +public class NamedLayoutedCircularAnchorageContentVisual<T extends ILayoutedModelElement & INamedElement> + extends LayoutedCircularAnchorageContentVisualBase<T> { + + /** Constructor. */ + public NamedLayoutedCircularAnchorageContentVisual(IContentAnchorageMVCBundle mvcb, Class<T> modelType) { + super(mvcb, modelType); + } + + /** {@inheritDoc} */ + @Override + protected String getHoverText() { + return getModelElement().getName(); + } +} diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/NamedLayoutedCircularAnchorageDiagramVisual.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/NamedLayoutedCircularAnchorageDiagramVisual.java new file mode 100644 index 0000000000000000000000000000000000000000..714a176a0569a2049efb4009f710ca66bf3a57fb --- /dev/null +++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/NamedLayoutedCircularAnchorageDiagramVisual.java @@ -0,0 +1,42 @@ +/*-------------------------------------------------------------------------+ +| Copyright 2019 fortiss GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.base.ui.editor.fx.visual; + +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IDiagramAnchorageMVCBundle; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.visual.IVisual; +import org.fortiss.tooling.base.model.element.IConnector; +import org.fortiss.tooling.base.model.layout.ILayoutedModelElement; +import org.fortiss.tooling.kernel.model.INamedElement; + +/** + * {@link IVisual} for layouted and named {@link IConnector}s within a diagram (free connectors). + * + * @author diewald + */ +public class NamedLayoutedCircularAnchorageDiagramVisual<T extends ILayoutedModelElement & INamedElement> + extends LayoutedCircularAnchorageDiagramVisualBase<T> { + + /** Constructor. */ + public NamedLayoutedCircularAnchorageDiagramVisual(IDiagramAnchorageMVCBundle mvcb, Class<T> modelType) { + super(mvcb, modelType); + } + + /** {@inheritDoc} */ + @Override + protected String getHoverText() { + return getModelElement().getName(); + } +} diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/NamedLayoutedLineLinkVisual.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/NamedLayoutedLineLinkVisual.java new file mode 100644 index 0000000000000000000000000000000000000000..e66e5b2aaa40fe8b22a292e175bb8f3af4539b9d --- /dev/null +++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/NamedLayoutedLineLinkVisual.java @@ -0,0 +1,47 @@ +/*-------------------------------------------------------------------------+ +| Copyright 2019 fortiss GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.base.ui.editor.fx.visual; + +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.ILinkMVCBundle; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.visual.IVisual; +import org.fortiss.tooling.base.model.element.IConnection; +import org.fortiss.tooling.base.model.layout.ILayoutedModelElement; +import org.fortiss.tooling.kernel.model.INamedElement; + +/** + * {@link IVisual} for layouted and named links within a diagram. Typically, those are + * {@link IConnection}s. + * + * @author diewald + */ +// TODO (TM): See comment in LayoutedLineLinkVisual +public class NamedLayoutedLineLinkVisual<T extends INamedElement & ILayoutedModelElement> + extends LayoutedLineLinkVisual<T> { + + /** Constructor. */ + public NamedLayoutedLineLinkVisual(ILinkMVCBundle mvcb, Class<T> modelType) { + super(mvcb, modelType); + } + + /** {@inheritDoc} */ + @Override + protected String getLabelText(int currentSegment, int lastSegment) { + if(currentSegment == 0) { + return getModelElement().getName(); + } + return null; + } +} diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/NamedLayoutedRectangularContentVisual.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/NamedLayoutedRectangularContentVisual.java new file mode 100644 index 0000000000000000000000000000000000000000..122e193ac587857d1dad23b42583a0bcf465f0d0 --- /dev/null +++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visual/NamedLayoutedRectangularContentVisual.java @@ -0,0 +1,40 @@ +/*-------------------------------------------------------------------------+ +| Copyright 2019 fortiss GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.base.ui.editor.fx.visual; + +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IContentMVCBundle; +import org.fortiss.tooling.base.model.layout.ILayoutedModelElement; +import org.fortiss.tooling.kernel.model.INamedElement; + +/** + * {@link LayoutedRectangularContentVisualBase} that defines its name. + * + * @author diewald + */ +public class NamedLayoutedRectangularContentVisual<T extends INamedElement & ILayoutedModelElement> + extends LayoutedRectangularContentVisualBase<T> { + + /** Constructor. */ + public NamedLayoutedRectangularContentVisual(IContentMVCBundle mvcb, Class<T> modelType) { + super(mvcb, modelType); + } + + /** {@inheritDoc} */ + @Override + protected String getName() { + return getModelElement().getName(); + } +} diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visuals/.ratings b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visuals/.ratings deleted file mode 100644 index 22e27e4c1bc1b40ffc645ab0ee36503bb4188ce5..0000000000000000000000000000000000000000 --- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/visuals/.ratings +++ /dev/null @@ -1,5 +0,0 @@ -CoordinateCorrections.java f78a936ba49c5fc4daf29237ecb4e86a446316d4 GREEN -LayoutedCircularContentAnchorageVisualBase.java aa546c0c9d975972a33cf22682b5d6634e56d271 GREEN -LayoutedCircularDiagramAnchorageVisualBase.java c5cc5fb41777166bc169011324585e51acda04c3 GREEN -LayoutedLineLinkVisualBase.java 429483c1222a26345fbc3bf5c9b2dbe41c6ad5f1 GREEN -LayoutedRectangularContentVisualBase.java d4cd07a8056df99927b160f2d4ce1cf4778d1dfa GREEN diff --git a/org.fortiss.tooling.base/src/org/fortiss/tooling/base/migration/.ratings b/org.fortiss.tooling.base/src/org/fortiss/tooling/base/migration/.ratings index 5633daf969db8251bbf77fd7418a1c19bf30868a..9d0d7f8df1b322b3005d555d7552e4aa62d05156 100644 --- a/org.fortiss.tooling.base/src/org/fortiss/tooling/base/migration/.ratings +++ b/org.fortiss.tooling.base/src/org/fortiss/tooling/base/migration/.ratings @@ -1,3 +1,3 @@ -AddMissingAnnotationsMigrationProvider.java a3f2b3cbcd39f85e15bc998650f899f55d9f563e GREEN -RemoveDuplicatedAnnotationsMigrationProvider.java f1bdb4733d5b9c6003a2b7fee59b89240a0a3b61 GREEN -RemoveOutdatedAnnotationInstanceMigrationProvider.java 29c29f2bb7515cad1de45a30ffc185001b47a016 GREEN +AddMissingAnnotationsMigrationProvider.java ebc5b9348b61ffb23493942949ecccf1c1fa2ae1 GREEN +RemoveDuplicatedAnnotationsMigrationProvider.java 6920909f8f211b9c5b5990644b5abcd8c4abaa3a GREEN +RemoveOutdatedAnnotationInstanceMigrationProvider.java 245530d6026f9ff29ffc577983d9de03ae5e75e5 GREEN diff --git a/org.fortiss.tooling.base/src/org/fortiss/tooling/base/migration/AddMissingAnnotationsMigrationProvider.java b/org.fortiss.tooling.base/src/org/fortiss/tooling/base/migration/AddMissingAnnotationsMigrationProvider.java index a3f2b3cbcd39f85e15bc998650f899f55d9f563e..ebc5b9348b61ffb23493942949ecccf1c1fa2ae1 100644 --- a/org.fortiss.tooling.base/src/org/fortiss/tooling/base/migration/AddMissingAnnotationsMigrationProvider.java +++ b/org.fortiss.tooling.base/src/org/fortiss/tooling/base/migration/AddMissingAnnotationsMigrationProvider.java @@ -15,6 +15,7 @@ +--------------------------------------------------------------------------*/ package org.fortiss.tooling.base.migration; +import static java.util.Collections.emptyMap; import static org.fortiss.tooling.base.utils.AnnotationUtils.instantiateAnnotationsRecursive; import java.util.ArrayList; @@ -49,9 +50,11 @@ public class AddMissingAnnotationsMigrationProvider implements IMigrationProvide /** {@inheritDoc} */ @Override - public void migrate(ITopLevelElement modelElement, Map<EObject, AnyType> unknownFeatures) { + public Map<EObject, AnyType> migrate(ITopLevelElement modelElement, + Map<EObject, AnyType> unknownFeatures) { EObject rootElement = modelElement.getRootModelElement(); instantiateAnnotationsRecursive(rootElement); migratedProjects.add(modelElement); + return emptyMap(); } } diff --git a/org.fortiss.tooling.base/src/org/fortiss/tooling/base/migration/RemoveDuplicatedAnnotationsMigrationProvider.java b/org.fortiss.tooling.base/src/org/fortiss/tooling/base/migration/RemoveDuplicatedAnnotationsMigrationProvider.java index f1bdb4733d5b9c6003a2b7fee59b89240a0a3b61..6920909f8f211b9c5b5990644b5abcd8c4abaa3a 100644 --- a/org.fortiss.tooling.base/src/org/fortiss/tooling/base/migration/RemoveDuplicatedAnnotationsMigrationProvider.java +++ b/org.fortiss.tooling.base/src/org/fortiss/tooling/base/migration/RemoveDuplicatedAnnotationsMigrationProvider.java @@ -15,6 +15,7 @@ +--------------------------------------------------------------------------*/ package org.fortiss.tooling.base.migration; +import static java.util.Collections.emptyMap; import static org.fortiss.tooling.kernel.utils.EcoreUtils.getChildrenWithType; import static org.fortiss.tooling.kernel.utils.EcoreUtils.pickInstanceOf; import static org.fortiss.tooling.kernel.utils.LoggingUtils.error; @@ -87,7 +88,8 @@ public class RemoveDuplicatedAnnotationsMigrationProvider implements IMigrationP /** {@inheritDoc} */ @Override - public void migrate(ITopLevelElement topLevelElement, Map<EObject, AnyType> unknownFeatures) { + public Map<EObject, AnyType> migrate(ITopLevelElement topLevelElement, + Map<EObject, AnyType> unknownFeatures) { doInternal(topLevelElement, true); @@ -95,5 +97,6 @@ public class RemoveDuplicatedAnnotationsMigrationProvider implements IMigrationP error(ToolingBaseActivator.getDefault(), "Duplicate annotations have been removed from \"" + uri.lastSegment() + "\". Please report this incident since it indicates an internal problem."); + return emptyMap(); } } diff --git a/org.fortiss.tooling.base/src/org/fortiss/tooling/base/migration/RemoveOutdatedAnnotationInstanceMigrationProvider.java b/org.fortiss.tooling.base/src/org/fortiss/tooling/base/migration/RemoveOutdatedAnnotationInstanceMigrationProvider.java index 29c29f2bb7515cad1de45a30ffc185001b47a016..245530d6026f9ff29ffc577983d9de03ae5e75e5 100644 --- a/org.fortiss.tooling.base/src/org/fortiss/tooling/base/migration/RemoveOutdatedAnnotationInstanceMigrationProvider.java +++ b/org.fortiss.tooling.base/src/org/fortiss/tooling/base/migration/RemoveOutdatedAnnotationInstanceMigrationProvider.java @@ -15,6 +15,7 @@ +--------------------------------------------------------------------------*/ package org.fortiss.tooling.base.migration; +import static java.util.Collections.emptyMap; import static org.eclipse.emf.ecore.util.EcoreUtil.delete; import static org.fortiss.tooling.common.util.LambdaUtils.isAssignableFromAny; import static org.fortiss.tooling.kernel.utils.EcoreUtils.getChildrenWithType; @@ -67,12 +68,14 @@ public abstract class RemoveOutdatedAnnotationInstanceMigrationProvider<T extend /** {@inheritDoc} */ @Override - public void migrate(ITopLevelElement modelElement, Map<EObject, AnyType> unknownFeatures) { + public Map<EObject, AnyType> migrate(ITopLevelElement modelElement, + Map<EObject, AnyType> unknownFeatures) { EObject rootModelElement = modelElement.getRootModelElement(); for(T annotation : getChildrenWithType(rootModelElement, annotationType)) { if(!isAssignableFromAny(modelElementTypes, annotation.getSpecificationOf())) { delete(annotation); } } + return emptyMap(); } } diff --git a/org.fortiss.tooling.common.ui/.classpath b/org.fortiss.tooling.common.ui/.classpath index cb4939f8345486a25a29b4f18626b12cc24eae60..d9ed18f5cea4deb235213896eef764feded19dee 100644 --- a/org.fortiss.tooling.common.ui/.classpath +++ b/org.fortiss.tooling.common.ui/.classpath @@ -3,8 +3,8 @@ <classpathentry kind="src" path="src"/> <classpathentry kind="src" path="external-src"/> <classpathentry kind="src" path="res"/> - <classpathentry exported="true" kind="lib" path="lib/org.eclipse.systemfocus.kernel.common_0.0.5.20191213.jar"/> - <classpathentry exported="true" kind="lib" path="lib/org.eclipse.systemfocus.kernel.common.ui_0.0.5.20191213.jar"/> + <classpathentry exported="true" kind="lib" path="lib/org.eclipse.systemfocus.kernel.common_0.0.5.20191219.jar"/> + <classpathentry exported="true" kind="lib" path="lib/org.eclipse.systemfocus.kernel.common.ui_0.0.5.20191219.jar"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"> <attributes> <attribute name="module" value="true"/> diff --git a/org.fortiss.tooling.common.ui/META-INF/MANIFEST.MF b/org.fortiss.tooling.common.ui/META-INF/MANIFEST.MF index 1898771c2202bd22a084d201e92eafb0f18d3b02..f158eb873beefe27aacb70e4e70c12c3efcf333b 100644 --- a/org.fortiss.tooling.common.ui/META-INF/MANIFEST.MF +++ b/org.fortiss.tooling.common.ui/META-INF/MANIFEST.MF @@ -25,8 +25,8 @@ Bundle-ClassPath: ., lib/org.conqat.ide.commons.gef.jar, lib/org.conqat.ide.commons.ui.jar, lib/swt-grouplayout.jar, - lib/org.eclipse.systemfocus.kernel.common_0.0.5.20191213.jar, - lib/org.eclipse.systemfocus.kernel.common.ui_0.0.5.20191213.jar + lib/org.eclipse.systemfocus.kernel.common_0.0.5.20191219.jar, + lib/org.eclipse.systemfocus.kernel.common.ui_0.0.5.20191219.jar Export-Package: aerofx, aquafx, jfxtras, diff --git a/org.fortiss.tooling.common.ui/build.properties b/org.fortiss.tooling.common.ui/build.properties index e4293a8077ba272c17cde3f615f0c17be7389027..047e606ce9d79664f75aab85d5fb16ee0ae09b08 100644 --- a/org.fortiss.tooling.common.ui/build.properties +++ b/org.fortiss.tooling.common.ui/build.properties @@ -6,8 +6,8 @@ bin.includes = .,\ lib/org.conqat.ide.commons.ui.jar,\ lib/swt-grouplayout.jar,\ res/,\ - lib/org.eclipse.systemfocus.kernel.common_0.0.5.20191213.jar,\ - lib/org.eclipse.systemfocus.kernel.common.ui_0.0.5.20191213.jar + lib/org.eclipse.systemfocus.kernel.common_0.0.5.20191219.jar,\ + lib/org.eclipse.systemfocus.kernel.common.ui_0.0.5.20191219.jar jars.compile.order = . source.. = src/,\ res/,\ diff --git a/org.fortiss.tooling.common.ui/lib/org.eclipse.systemfocus.kernel.common.ui_0.0.5.20191213.jar b/org.fortiss.tooling.common.ui/lib/org.eclipse.systemfocus.kernel.common.ui_0.0.5.20191213.jar deleted file mode 100644 index fb24b39f087a12b919462f58014ae5cc13d42a41..0000000000000000000000000000000000000000 Binary files a/org.fortiss.tooling.common.ui/lib/org.eclipse.systemfocus.kernel.common.ui_0.0.5.20191213.jar and /dev/null differ diff --git a/org.fortiss.tooling.common.ui/lib/org.eclipse.systemfocus.kernel.common.ui_0.0.5.20191219.jar b/org.fortiss.tooling.common.ui/lib/org.eclipse.systemfocus.kernel.common.ui_0.0.5.20191219.jar new file mode 100644 index 0000000000000000000000000000000000000000..395895b74e4f88edcd5118c917fd2ab6b413e057 Binary files /dev/null and b/org.fortiss.tooling.common.ui/lib/org.eclipse.systemfocus.kernel.common.ui_0.0.5.20191219.jar differ diff --git a/org.fortiss.tooling.common.ui/lib/org.eclipse.systemfocus.kernel.common_0.0.5.20191213.jar b/org.fortiss.tooling.common.ui/lib/org.eclipse.systemfocus.kernel.common_0.0.5.20191219.jar similarity index 80% rename from org.fortiss.tooling.common.ui/lib/org.eclipse.systemfocus.kernel.common_0.0.5.20191213.jar rename to org.fortiss.tooling.common.ui/lib/org.eclipse.systemfocus.kernel.common_0.0.5.20191219.jar index a7d80f27a40d52955285adc3b5a211581b4e93e7..b27db9f8c0e0c56fd798ea2b54927bc768b5ce64 100644 Binary files a/org.fortiss.tooling.common.ui/lib/org.eclipse.systemfocus.kernel.common_0.0.5.20191213.jar and b/org.fortiss.tooling.common.ui/lib/org.eclipse.systemfocus.kernel.common_0.0.5.20191219.jar differ diff --git a/org.fortiss.tooling.kernel.ui/META-INF/MANIFEST.MF b/org.fortiss.tooling.kernel.ui/META-INF/MANIFEST.MF index 881846afa276a61c6c3c08ca4e481866234ae095..ca6401da3143db4f507bbbef21b47a85dddd61e1 100644 --- a/org.fortiss.tooling.kernel.ui/META-INF/MANIFEST.MF +++ b/org.fortiss.tooling.kernel.ui/META-INF/MANIFEST.MF @@ -4,11 +4,12 @@ Bundle-Name: Tooling Kernel UI Bundle-SymbolicName: org.fortiss.tooling.kernel.ui;singleton:=true Bundle-Version: 2.16.0.qualifier Bundle-Activator: org.fortiss.tooling.kernel.ui.ToolingKernelUIActivator -Require-Bundle: org.fortiss.tooling.common.ui;bundle-version="2.16.0";visibility:=reexport, - org.fortiss.tooling.kernel;bundle-version="2.16.0";visibility:=reexport, +Require-Bundle: org.fortiss.tooling.common.ui;visibility:=reexport, + org.fortiss.tooling.kernel;visibility:=reexport, org.eclipse.core.resources;visibility:=reexport, org.eclipse.emf.databinding;visibility:=reexport, - org.eclipse.core.databinding.property;visibility:=reexport + org.eclipse.core.databinding.property;visibility:=reexport, + com.google.guava;visibility:=reexport Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-11 Bundle-Vendor: fortiss GmbH diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/.ratings b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/.ratings index e4afd03ed7a246008939ddd4dfced2250a797efa..0f71fc3dd92acfc4197b5dc1400f09fe10e33967 100644 --- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/.ratings +++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/.ratings @@ -4,7 +4,7 @@ IContextMenuContributor.java 0f09c76662c154cf52ddab61b417e82a42854162 GREEN IContextMenuMultiSelectionContributor.java 125b31dd38009bc2095b7e6bc860e946e39f58c4 GREEN IEditPartFactory.java 5729715847f553d95a5bad4a9211c7e6f458badd GREEN IModelEditor.java 962d7f7758abc88bbc6064c8b4eb32da00abf8e8 GREEN -IModelEditorBinding.java a3d5c344f61fa6f12ab944a4e933a557d6e7011b GREEN +IModelEditorBinding.java d6896569cfe7eb0d7f0b8e4a71573c50e8c75329 GREEN IModelElementHandler.java 21b4a96251e0267f156b4b8f2b95a97f6e81e646 GREEN ITutorialStepUI.java b8aee2b95857484ab6ad9ecd55b5de9f0ea158e5 GREEN ITutorialUIProvider.java aa0ff5db4d7ba0953e34edeb99f3e8279567e18f GREEN diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/IModelEditorBinding.java b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/IModelEditorBinding.java index a3d5c344f61fa6f12ab944a4e933a557d6e7011b..d6896569cfe7eb0d7f0b8e4a71573c50e8c75329 100644 --- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/IModelEditorBinding.java +++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/IModelEditorBinding.java @@ -16,6 +16,9 @@ package org.fortiss.tooling.kernel.ui.extension; import org.eclipse.emf.ecore.EObject; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.controller.IControllerFactory; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.model.IModelFactory; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.visual.IVisualFactory; import org.eclipse.ui.IEditorPart; import org.fortiss.tooling.kernel.service.base.IEObjectAware; import org.fortiss.tooling.kernel.ui.service.IModelEditorBindingService; @@ -24,12 +27,16 @@ import org.fortiss.tooling.kernel.ui.service.IModelEditorBindingService; * Interface for editor bindings. An editor binding a defines a model element * editor. Usually, an editor (in the Eclipse interpretation) is a view (in the * model-based development interpretation) on the underlying model. - * - * <P> + * <p> + * This interface also specifies bindings to those MVC factories that are responsible for the + * interaction of the editor with the model, its presentation, and behavior. + * <p> * Each editor provided by some binding becomes part of an Eclipse multi-page editor. Its page * carries the name delivered by {@link #getLabel}. The {@link IModelEditorBindingService} sorts the * provided editors according to their priority returned by {@link #getPriority} with higher values * having lower priority. + * <b>NOTE:</b>: The priority reported by {@link #getPriority()} is also used to define the order in + * which the factories are traversed. * * @see IModelEditorBindingService * @@ -40,6 +47,15 @@ public interface IModelEditorBinding<T extends EObject> extends IEObjectAware<EO /** Returns the class of the editor registered by this binding. */ Class<? extends IEditorPart> getEditorClass(T object); + /** Returns the {@link IModelFactory} to instantiate for the {@link IEditorPart}. */ + Class<? extends IModelFactory> getModelFactory(); + + /** Returns the {@link IVisualFactory} to instantiate for the {@link IEditorPart}. */ + Class<? extends IVisualFactory> getVisualFactory(); + + /** Returns the {@link IControllerFactory} to instantiate for the {@link IEditorPart}. */ + Class<? extends IControllerFactory> getControllerFactory(); + /** Returns the label of the editor. */ String getLabel(T object); diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/.ratings b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/.ratings index 976ba3f728d9b735717c8a0d137b2c2c1da9e672..a7f01cec28ced8ee225518f34ad81234c4f6d8a3 100644 --- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/.ratings +++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/.ratings @@ -7,8 +7,8 @@ EReferencePropertySectionBase.java 0548da6778516003257f59d0b4c2b60d458be3b6 GREE EditorBase.java 9c09fff92945256bb8680992ae7bb2c78f47b150 GREEN FXEditorBase.java 2e520be0bbae7d0aebdff70218a124dbe0896ce2 GREEN IListPropertySection.java 8bb00fe7959583e794ff9437b7a77404c9a9e70f GREEN -LWFXEFEditorBase.java 0b8e6af85d83d0542dcd908974e52c618bc22a08 GREEN -ModelEditorBindingBase.java 4c5ac569c0b6e7678fc8191096b26dfd09fdcb98 GREEN +LWFXEFEditorBase.java 2bd06235f20c18dc2e7d433700b2ad74a16664e2 GREEN +ModelEditorBindingBase.java c258cb0ea28d74440856cd2abf367408fbbc1279 GREEN ModelElementHandlerBase.java 384727748f125c9d43f19d9c0eba4ba1be5a7a26 GREEN MultiEObjectActionBase.java 9e237d8ea640c4194e4877af4a9cfce88698e543 GREEN NamedCommentedModelElementHandlerBase.java 681b98b50b362f01abb7a36f108f4f11b9e51829 GREEN diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/LWFXEFEditorBase.java b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/LWFXEFEditorBase.java index 0b8e6af85d83d0542dcd908974e52c618bc22a08..2bd06235f20c18dc2e7d433700b2ad74a16664e2 100644 --- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/LWFXEFEditorBase.java +++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/LWFXEFEditorBase.java @@ -15,8 +15,11 @@ +--------------------------------------------------------------------------*/ package org.fortiss.tooling.kernel.ui.extension.base; +import static java.util.stream.Collectors.toList; + import java.util.ArrayList; import java.util.List; +import java.util.Objects; import org.eclipse.emf.ecore.EObject; import org.eclipse.jface.viewers.ISelection; @@ -32,14 +35,21 @@ import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.controller.IContro import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.model.IModelFactory; import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IMVCBundle; import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.visual.IVisualFactory; +import org.eclipse.ui.IEditorPart; import org.fortiss.tooling.kernel.service.ICommandStackService; +import org.fortiss.tooling.kernel.ui.extension.IModelEditorBinding; +import org.fortiss.tooling.kernel.ui.extension.base.factory.DelegatingControllerFactory; +import org.fortiss.tooling.kernel.ui.extension.base.factory.DelegatingModelFactory; +import org.fortiss.tooling.kernel.ui.extension.base.factory.DelegatingVisualFactory; +import org.fortiss.tooling.kernel.ui.service.IModelEditorBindingService; import javafx.scene.Parent; /** - * Base implementation of model element editors which are using LWFXEF DiaViewer. + * Base class for JavaFX-based {@link IEditorPart}s that display diagrams of {@link EObject}s. * - * @author hoelzlf + * @author hoelzl + * @author diewald */ public abstract class LWFXEFEditorBase<T extends EObject> extends FXEditorBase<T> implements ISelectionProvider { @@ -48,30 +58,55 @@ public abstract class LWFXEFEditorBase<T extends EObject> extends FXEditorBase<T /** The list of {@link ISelectionChangedListener}s. */ private final List<ISelectionChangedListener> selectionListeners = new ArrayList<>(); + /** References the delegating {@link IModelFactory} of this JavaFX {@link IEditorPart}. */ + private IModelFactory delegatingModelFactory; + + /** References the delegating {@link IModelFactory} of this JavaFX {@link IEditorPart}. */ + private IVisualFactory delegatingVisualFactory; + + /** References the delegating {@link IModelFactory} of this JavaFX {@link IEditorPart}. */ + private IControllerFactory delegatingControllerFactory; + /** {@inheritDoc} */ @Override protected final Parent createSceneRoot() { - viewer = new DiagramViewer(createModelFactory(), createVisualFactory(), - createControllerFactory(), cb -> modelSelected(), chg -> applyModelChange(chg)); + constructMVCFactories(); + + viewer = new DiagramViewer(delegatingModelFactory, delegatingVisualFactory, + delegatingControllerFactory, cb -> modelSelected(), chg -> applyModelChange(chg)); customizeViewer(); getSite().setSelectionProvider(this); return viewer.getVisualNode(); } + /** + * Constructs delegating factories that wrap all factories registered by + * {@link IModelEditorBinding}s for the edited type. Delegating factories are used for extending + * editors of the same type. + */ + protected void constructMVCFactories() { + List<IModelEditorBinding<EObject>> bindings = + IModelEditorBindingService.getInstance().getBindings(editedObject); + bindings.removeIf(b -> (b.getEditorClass(editedObject) != null) && + (!LWFXEFEditorBase.class.isAssignableFrom(b.getEditorClass(editedObject)))); + + List<Class<? extends IModelFactory>> modelFactories = bindings.stream() + .map(b -> b.getModelFactory()).filter(Objects::nonNull).collect(toList()); + List<Class<? extends IVisualFactory>> visualFactories = bindings.stream() + .map(b -> b.getVisualFactory()).filter(Objects::nonNull).collect(toList()); + List<Class<? extends IControllerFactory>> controllerFactories = bindings.stream() + .map(b -> b.getControllerFactory()).filter(Objects::nonNull).collect(toList()); + + delegatingModelFactory = new DelegatingModelFactory(modelFactories, editedObject); + delegatingVisualFactory = new DelegatingVisualFactory(visualFactories); + delegatingControllerFactory = new DelegatingControllerFactory(controllerFactories); + } + /** Customize the viewer after it is created. The default implementation changes nothing. */ protected void customizeViewer() { // the default does nothing } - /** Create the {@link IModelFactory}. */ - protected abstract IModelFactory createModelFactory(); - - /** Create the {@link IVisualFactory}. */ - protected abstract IVisualFactory createVisualFactory(); - - /** Create the {@link IControllerFactory}. */ - protected abstract IControllerFactory createControllerFactory(); - /** Called when a model element is selected in the diagram viewer. */ protected void modelSelected() { getSite().getSelectionProvider().setSelection(createSelection()); diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/ModelEditorBindingBase.java b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/ModelEditorBindingBase.java index 4c5ac569c0b6e7678fc8191096b26dfd09fdcb98..c258cb0ea28d74440856cd2abf367408fbbc1279 100644 --- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/ModelEditorBindingBase.java +++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/ModelEditorBindingBase.java @@ -16,6 +16,9 @@ package org.fortiss.tooling.kernel.ui.extension.base; import org.eclipse.emf.ecore.EObject; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.controller.IControllerFactory; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.model.IModelFactory; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.visual.IVisualFactory; import org.fortiss.tooling.kernel.service.base.IEObjectAware; import org.fortiss.tooling.kernel.ui.extension.IModelEditorBinding; import org.fortiss.tooling.kernel.ui.service.IModelEditorBindingService; @@ -34,6 +37,7 @@ import org.fortiss.tooling.kernel.ui.service.IModelEditorBindingService; * @see IModelEditorBindingService * * @author hoelzl + * @author diewald */ public abstract class ModelEditorBindingBase<T extends EObject> implements IEObjectAware<EObject>, IModelEditorBinding<T> { @@ -48,6 +52,30 @@ public abstract class ModelEditorBindingBase<T extends EObject> return getEditorClass(null); } + /** {@inheritDoc} */ + @Override + public Class<? extends IModelFactory> getModelFactory() { + throw new UnsupportedOperationException("This method shall only be called from FX" + + " editors. Ensure to define the model factory in the editor binding. Remove" + + " this method when the ediors are migrated to JavaFX."); + } + + /** {@inheritDoc} */ + @Override + public Class<? extends IVisualFactory> getVisualFactory() { + throw new UnsupportedOperationException("This method shall only be called from FX" + + " editors. Ensure to define the visual factory in the editor binding. Remove" + + " this method when the ediors are migrated to JavaFX."); + } + + /** {@inheritDoc} */ + @Override + public Class<? extends IControllerFactory> getControllerFactory() { + throw new UnsupportedOperationException("This method shall only be called from FX" + + " editors. Ensure to define the controller factory in the editor binding. Remove" + + " this method when the ediors are migrated to JavaFX."); + } + /** Returns the label of editor */ @Override public String getLabel(T object) { diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/.ratings b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/.ratings new file mode 100644 index 0000000000000000000000000000000000000000..75b475f75083ac3976a4740cc7fc19976f96542c --- /dev/null +++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/.ratings @@ -0,0 +1,4 @@ +DelegatingControllerFactory.java ad214d83b5821b39862b7c382c91a13c3dfddbd0 GREEN +DelegatingFactoryBase.java f421742267610f41bb6196346026d2f239d90ed0 GREEN +DelegatingModelFactory.java 717b706781879efe9efcb5ce4bf53723e39a3e1b GREEN +DelegatingVisualFactory.java 7e834acd12ae4d1c2b2b32a5456dc9f2b6d4e466 GREEN diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/DelegatingControllerFactory.java b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/DelegatingControllerFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..ad214d83b5821b39862b7c382c91a13c3dfddbd0 --- /dev/null +++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/DelegatingControllerFactory.java @@ -0,0 +1,111 @@ +/*-------------------------------------------------------------------------+ +| Copyright 2019 fortiss GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.kernel.ui.extension.base.factory; + +import java.util.List; +import java.util.Optional; + +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.controller.IController; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.controller.IControllerFactory; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IContentAnchorageMVCBundle; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IContentMVCBundle; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IDiagramAnchorageMVCBundle; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IDiagramMVCBundle; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.ILinkMVCBundle; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IMVCBundle; + +/** + * Delegates the creational calls to concrete {@link IControllerFactory}s. The first non-null + * element returned by the factories of the initially given list is returned. If no element is + * created (all delegates returned null), this factory throws a {@link RuntimeException}. + * + * @author hoelzl + * @author diewald + */ +public class DelegatingControllerFactory extends DelegatingFactoryBase<IControllerFactory> + implements IControllerFactory { + + /** Constructor. */ + public DelegatingControllerFactory(List<Class<? extends IControllerFactory>> factories) { + super(factories, null); + } + + /** {@inheritDoc} */ + @Override + public IController createContentController(IContentMVCBundle modelBundle) { + Optional<IController> controller = + getDelegateFactories().stream().map(f -> f.createContentController(modelBundle)) + .filter(cc -> cc != null).findFirst(); + if(controller.isPresent()) { + return controller.get(); + } + throw createNoControllerException(modelBundle); + } + + /** {@inheritDoc} */ + @Override + public IController createDiagramAnchorageController(IDiagramAnchorageMVCBundle modelBundle) { + Optional<IController> controller = getDelegateFactories().stream() + .map(f -> f.createDiagramAnchorageController(modelBundle)).filter(cc -> cc != null) + .findFirst(); + if(controller.isPresent()) { + return controller.get(); + } + throw createNoControllerException(modelBundle); + } + + /** {@inheritDoc} */ + @Override + public IController createContentAnchorageController(IContentAnchorageMVCBundle modelBundle) { + Optional<IController> controller = getDelegateFactories().stream() + .map(f -> f.createContentAnchorageController(modelBundle)).filter(cc -> cc != null) + .findFirst(); + if(controller.isPresent()) { + return controller.get(); + } + throw createNoControllerException(modelBundle); + } + + /** {@inheritDoc} */ + @Override + public IController createLinkController(ILinkMVCBundle modelBundle) { + Optional<IController> controller = getDelegateFactories().stream() + .map(f -> f.createLinkController(modelBundle)).filter(cc -> cc != null).findFirst(); + if(controller.isPresent()) { + return controller.get(); + } + throw createNoControllerException(modelBundle); + } + + /** {@inheritDoc} */ + @Override + public IController createDiagramController(IDiagramMVCBundle diagramBundle) { + Optional<IController> controller = getDelegateFactories().stream().map(f -> { + return f.createDiagramController(diagramBundle); + }).filter(cc -> cc != null).findFirst(); + if(controller.isPresent()) { + return controller.get(); + } + throw createNoControllerException(diagramBundle); + } + + /** Throws a runtime exception indicating a missing controller. */ + private RuntimeException createNoControllerException(IMVCBundle modelBundle) { + return new RuntimeException("No controller has been specified for model elements of the" + + " type " + modelBundle.getModel().getClass().getSimpleName() + ". Please check" + + " the editor bindings and the delegate controllers."); + } +} diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/DelegatingFactoryBase.java b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/DelegatingFactoryBase.java new file mode 100644 index 0000000000000000000000000000000000000000..f421742267610f41bb6196346026d2f239d90ed0 --- /dev/null +++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/DelegatingFactoryBase.java @@ -0,0 +1,79 @@ +/*-------------------------------------------------------------------------+ +| Copyright 2019 fortiss GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.kernel.ui.extension.base.factory; + +import static java.util.stream.Collectors.toList; +import static org.apache.commons.lang3.reflect.ConstructorUtils.getMatchingAccessibleConstructor; +import static org.fortiss.tooling.kernel.utils.LoggingUtils.error; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import org.fortiss.tooling.kernel.ui.ToolingKernelUIActivator; + +import com.google.common.collect.ImmutableList; + +/** + * Base class for delegating MVC factories that wrap 1..n factories for editors of a defined type. + * + * @author diewald + */ +/* package */ abstract class DelegatingFactoryBase<T> { + + /** References the edited Object in case it is needed by some factory. May be {@code null}. */ + protected final Object editedObject; + + /** References the */ + private List<T> delegateFactories = new ArrayList<>(); + + /** Constructor. */ + protected DelegatingFactoryBase(List<Class<? extends T>> factories, Object editedObject) { + this.editedObject = editedObject; + + delegateFactories = factories.stream().map(fCls -> constructFactory(fCls)) + .flatMap(Optional::stream).collect(toList()); + } + + /** Creates an instance of the given {@code delegateFactory}. */ + protected Optional<? extends T> constructFactory(Class<? extends T> delegateFactory) { + Constructor<? extends T> ctor = null; + try { + ctor = getMatchingAccessibleConstructor(delegateFactory); + try { + return Optional.of(ctor.newInstance()); + } catch(InstantiationException | IllegalAccessException | IllegalArgumentException | + InvocationTargetException e) { + error(ToolingKernelUIActivator.getDefault(), "Failed to instantiate the factory " + + delegateFactory.getSimpleName() + "."); + return Optional.empty(); + } + } catch(NullPointerException | SecurityException e1) { + error(ToolingKernelUIActivator.getDefault(), "The factory " + + delegateFactory.getSimpleName() + + " is missing a no-arg Constructor. Only such constructors are allowed for" + + " these factories."); + return Optional.empty(); + } + } + + /** Returns the list of delegate factory instances whose types are given during construction. */ + protected ImmutableList<T> getDelegateFactories() { + return ImmutableList.copyOf(delegateFactories); + } +} diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/DelegatingModelFactory.java b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/DelegatingModelFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..717b706781879efe9efcb5ce4bf53723e39a3e1b --- /dev/null +++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/DelegatingModelFactory.java @@ -0,0 +1,144 @@ +/*-------------------------------------------------------------------------+ +| Copyright 2019 fortiss GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.kernel.ui.extension.base.factory; + +import static java.util.stream.Collectors.toList; +import static org.apache.commons.lang3.reflect.ConstructorUtils.getMatchingAccessibleConstructor; +import static org.conqat.lib.commons.collections.CollectionUtils.isNullOrEmpty; +import static org.fortiss.tooling.kernel.utils.EcoreUtils.getInterfaceType; +import static org.fortiss.tooling.kernel.utils.LoggingUtils.error; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.Collection; +import java.util.List; +import java.util.Optional; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.model.IModelFactory; +import org.fortiss.tooling.kernel.ui.ToolingKernelUIActivator; + +/** + * Delegates the creational and getter calls to concrete {@link IModelFactory}s. The first non-null + * element returned by the factories of the initially given list is returned. If no element is + * created (all delegates returned null), this factory also returns null. + * <p> + * Only the root model must be identical for all delegate factories. Hence, the root element of the + * first delegate is returned. + * + * @author hoelzl + */ +public class DelegatingModelFactory extends DelegatingFactoryBase<IModelFactory> + implements IModelFactory { + + /** Constructor. */ + public DelegatingModelFactory(List<Class<? extends IModelFactory>> factories, + Object editedObject) { + super(factories, editedObject); + } + + /** {@inheritDoc} */ + @Override + protected Optional<? extends IModelFactory> + constructFactory(Class<? extends IModelFactory> delegateFactory) { + Constructor<? extends IModelFactory> ctor = null; + try { + Class<?> ctorParamType = (editedObject instanceof EObject) + ? getInterfaceType((EObject)editedObject) : editedObject.getClass(); + ctor = getMatchingAccessibleConstructor(delegateFactory, ctorParamType); + try { + return Optional.of(ctor.newInstance(editedObject)); + } catch(InstantiationException | IllegalAccessException | IllegalArgumentException | + InvocationTargetException e) { + error(ToolingKernelUIActivator.getDefault(), "Failed to instantiate the factory " + + delegateFactory.getSimpleName() + "."); + return Optional.empty(); + } + } catch(NullPointerException | SecurityException e1) { + error(ToolingKernelUIActivator.getDefault(), "The factory " + + delegateFactory.getSimpleName() + + " is missing a single argument Constructor accepting the edited model." + + " Only such constructors are allowed for " + + IModelFactory.class.getSimpleName() + "s."); + return Optional.empty(); + } + } + + /** {@inheritDoc} */ + @Override + public List<?> getContentAnchorageModels(Object parent) { + return getDelegateFactories().stream().map(f -> f.getContentAnchorageModels(parent)) + .filter(lm -> !isNullOrEmpty(lm)).flatMap(Collection::stream).distinct() + .collect(toList()); + } + + /** {@inheritDoc} */ + @Override + public Object getLinkStart(Object link) { + return getDelegateFactories().stream().map(f -> f.getLinkStart(link)) + .filter(cc -> cc != null).findFirst().orElse(null); + } + + /** {@inheritDoc} */ + @Override + public Object getLinkEnd(Object link) { + return getDelegateFactories().stream().map(f -> f.getLinkEnd(link)).filter(cc -> cc != null) + .findFirst().orElse(null); + } + + /** {@inheritDoc} */ + @Override + public Object getParent(Object element) { + return getDelegateFactories().stream().map(f -> f.getParent(element)) + .filter(cc -> cc != null).findFirst().orElse(null); + } + + /** {@inheritDoc} */ + @Override + public Object getRootModel() { + return editedObject; + } + + /** {@inheritDoc} */ + @Override + public List<?> getContentModels() { + return getDelegateFactories().stream().map(f -> f.getContentModels()) + .filter(lm -> !isNullOrEmpty(lm)).flatMap(Collection::stream).distinct() + .collect(toList()); + } + + /** {@inheritDoc} */ + @Override + public List<?> getDiagramAnchorageModels() { + return getDelegateFactories().stream().map(f -> f.getDiagramAnchorageModels()) + .filter(lm -> !isNullOrEmpty(lm)).flatMap(Collection::stream).distinct() + .collect(toList()); + } + + /** {@inheritDoc} */ + @Override + public List<?> getLinkModels() { + return getDelegateFactories().stream().map(f -> f.getLinkModels()) + .filter(lm -> !isNullOrEmpty(lm)).flatMap(Collection::stream).distinct() + .collect(toList()); + } + + /** {@inheritDoc} */ + @Override + public void update() { + // Not yet needed. + } +} diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/DelegatingVisualFactory.java b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/DelegatingVisualFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..7e834acd12ae4d1c2b2b32a5456dc9f2b6d4e466 --- /dev/null +++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/factory/DelegatingVisualFactory.java @@ -0,0 +1,81 @@ +/*-------------------------------------------------------------------------+ +| Copyright 2019 fortiss GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.kernel.ui.extension.base.factory; + +import java.util.List; + +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IContentAnchorageMVCBundle; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IContentMVCBundle; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IDiagramAnchorageMVCBundle; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.ILinkMVCBundle; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.visual.IContentAnchorageVisual; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.visual.IContentVisual; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.visual.IDiagramAnchorageVisual; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.visual.ILinkVisual; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.visual.IVisualFactory; +import org.eclipse.ui.IEditorPart; +import org.fortiss.tooling.kernel.service.ITransformationService; +import org.fortiss.tooling.kernel.ui.extension.base.LWFXEFEditorBase; + +/** + * Base class for {@link IVisualFactory}s of extendable {@link LWFXEFEditorBase} + * {@link IEditorPart}s.The first non-null element returned by the factories of the initially given + * list is returned. If no element is + * created (all delegates returned null), this factory also returns null. + * <P> + * This class uses the {@link ITransformationService} to find a delegate visual factory for the + * model elements in question. + * + * @author hoelzl + */ +public class DelegatingVisualFactory extends DelegatingFactoryBase<IVisualFactory> + implements IVisualFactory { + + /** Constructor. */ + public DelegatingVisualFactory(List<Class<? extends IVisualFactory>> factories) { + super(factories, null); + } + + /** {@inheritDoc} */ + @Override + public IContentVisual createContentVisual(IContentMVCBundle modelBundle) { + return getDelegateFactories().stream().map(f -> f.createContentVisual(modelBundle)) + .filter(cc -> cc != null).findFirst().orElse(null); + } + + /** {@inheritDoc} */ + @Override + public IDiagramAnchorageVisual + createDiagramAnchorageVisual(IDiagramAnchorageMVCBundle modelBundle) { + return getDelegateFactories().stream().map(f -> f.createDiagramAnchorageVisual(modelBundle)) + .filter(cc -> cc != null).findFirst().orElse(null); + } + + /** {@inheritDoc} */ + @Override + public IContentAnchorageVisual + createContentAnchorageVisual(IContentAnchorageMVCBundle modelBundle) { + return getDelegateFactories().stream().map(f -> f.createContentAnchorageVisual(modelBundle)) + .filter(cc -> cc != null).findFirst().orElse(null); + } + + /** {@inheritDoc} */ + @Override + public ILinkVisual createLinkVisual(ILinkMVCBundle modelBundle) { + return getDelegateFactories().stream().map(f -> f.createLinkVisual(modelBundle)) + .filter(cc -> cc != null).findFirst().orElse(null); + } +} diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/.ratings b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/.ratings index 4ea2eb911c9c55e937b880dbeaf7c166dd8ac547..e61bcd66e8b7e1f52185aeeec04e87a887296375 100644 --- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/.ratings +++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/.ratings @@ -5,7 +5,7 @@ ConstraintUIService.java 433e35bb1c9bbc628c6ee070ff45632400becf4a GREEN ContextMenuService.java ca3c899293f25b70ce8e5f0d86ca2f9683329d81 GREEN EditPartFactoryService.java e9180c0020f1769d9e24ef3c08f9ca5599dbc5c3 GREEN MarkerService.java b01b7706034691683df7bbc2e7828c42574b3147 GREEN -ModelEditorBindingService.java 948fcdc298a74e366351ad8835a145af6cd238be GREEN +ModelEditorBindingService.java 577f5db41abf240291434dbad6bc6b0fde1eeb2b GREEN ModelElementHandlerService.java 07a30545ad687ff0fe13bf7a9348c41fb03e0b2c GREEN NavigatorService.java 2b1361eac805996e22e5409dafff9707fbac3376 GREEN ToolingKernelUIInternal.java 38903445a9084b7908716a00f41621dfb3126fca GREEN diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/ModelEditorBindingService.java b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/ModelEditorBindingService.java index 948fcdc298a74e366351ad8835a145af6cd238be..577f5db41abf240291434dbad6bc6b0fde1eeb2b 100644 --- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/ModelEditorBindingService.java +++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/ModelEditorBindingService.java @@ -16,10 +16,13 @@ package org.fortiss.tooling.kernel.ui.internal; import static java.util.Collections.emptyList; +import static java.util.Collections.sort; import static org.fortiss.tooling.kernel.utils.KernelModelElementUtils.getParentElement; import static org.fortiss.tooling.kernel.utils.KernelModelElementUtils.isChildElementOf; import static org.fortiss.tooling.kernel.utils.LoggingUtils.error; +import java.util.ArrayList; +import java.util.Comparator; import java.util.EventObject; import java.util.HashMap; import java.util.List; @@ -96,6 +99,16 @@ public class ModelEditorBindingService extends EObjectAwareServiceBase<IModelEdi @Override public void startService() { IKernelIntrospectionSystemService.getInstance().registerService(this); + + for(List<IModelEditorBinding<EObject>> bindings : handlerMap.values()) { + sort(bindings, new Comparator<IModelEditorBinding<EObject>>() { + @Override + public int compare(IModelEditorBinding<EObject> o1, + IModelEditorBinding<EObject> o2) { + return o2.getPriority() - o1.getPriority(); + } + }); + } } /** Registers the given editor binding with the service. */ @@ -169,12 +182,18 @@ public class ModelEditorBindingService extends EObjectAwareServiceBase<IModelEdi /** {@inheritDoc} */ @Override - public List<IModelEditorBinding<EObject>> getBindings(EObject element) { - List<IModelEditorBinding<EObject>> bindings = getRegisteredHandlers(element.getClass()); + public List<IModelEditorBinding<EObject>> getBindings(Class<? extends EObject> elementType) { + List<IModelEditorBinding<EObject>> bindings = getRegisteredHandlers(elementType); if(bindings == null) { bindings = emptyList(); } - return bindings; + return new ArrayList<>(bindings); + } + + /** {@inheritDoc} */ + @Override + public List<IModelEditorBinding<EObject>> getBindings(EObject element) { + return getBindings(element.getClass()); } /** {@inheritDoc} */ diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/editor/.ratings b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/editor/.ratings index 7b672cb407f325d3e708dae32125084d5b8d68e2..04963a065a9a724a7e30606456560f819bf493b7 100644 --- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/editor/.ratings +++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/editor/.ratings @@ -1,5 +1,5 @@ ActionBarContributor.java 18d9db3744c5381cca8b6823b5f7bc18183a1cfa GREEN -ExtendableMultiPageEditor.java f8eb6fdc347098fb03e776f23fab61109aa55d6e GREEN +ExtendableMultiPageEditor.java b18b5eed364eaa1c83cbcb64a89288d1ad263f7d GREEN IActionContributingEditor.java 4aa7496d67822de919a8cf0af0ddaafc61bf2919 GREEN ModelElementEditorInput.java e269eff5d992d375a646e54d048f1f0efc6144dd GREEN TutorialStepUIEditor.java 9eadc96c302b5131ff4cc3715777718fa06ec7e8 GREEN diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/editor/ExtendableMultiPageEditor.java b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/editor/ExtendableMultiPageEditor.java index f8eb6fdc347098fb03e776f23fab61109aa55d6e..b18b5eed364eaa1c83cbcb64a89288d1ad263f7d 100644 --- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/editor/ExtendableMultiPageEditor.java +++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/editor/ExtendableMultiPageEditor.java @@ -15,11 +15,10 @@ +--------------------------------------------------------------------------*/ package org.fortiss.tooling.kernel.ui.internal.editor; -import static java.util.Collections.sort; import static org.conqat.ide.commons.ui.logging.LoggingUtils.error; +import java.lang.reflect.Constructor; import java.util.Collection; -import java.util.Comparator; import java.util.EventObject; import java.util.List; @@ -185,18 +184,13 @@ public class ExtendableMultiPageEditor extends MultiPageEditorPart int pageIndex = 0; List<IModelEditorBinding<EObject>> bindings = IModelEditorBindingService.getInstance().getBindings(editedObject); - sort(bindings, new Comparator<IModelEditorBinding<EObject>>() { - @Override - public int compare(IModelEditorBinding<EObject> o1, IModelEditorBinding<EObject> o2) { - return o2.getPriority() - o1.getPriority(); - } - }); for(IModelEditorBinding<EObject> editorBinding : bindings) { try { Class<? extends IEditorPart> editorClass = editorBinding.getEditorClass(editedObject); if(editorClass != null) { - IEditorPart editorPart = editorClass.newInstance(); + Class<? extends EObject> inputType = editedObject.getClass(); + IEditorPart editorPart = constructEditorPart(editorClass, inputType); addPage(editorPart, getEditorInput()); setPageText(pageIndex++, editorBinding.getLabel(editedObject)); } @@ -206,6 +200,23 @@ public class ExtendableMultiPageEditor extends MultiPageEditorPart } } + /** + * Constructs an {@link IEditorPart} instance of the given {@code editorClass}. + * {@link IEditorPart}s that take the input model element type as a parameter are preferred over + * no-arg constructors. + */ + protected IEditorPart constructEditorPart(Class<? extends IEditorPart> editorClass, + Class<? extends EObject> inputType) throws Exception { + try { + Constructor<? extends IEditorPart> ctor = editorClass.getConstructor(Class.class); + return ctor.newInstance(inputType); + } catch(NoSuchMethodException | SecurityException e) { + // Fallback for no-arg constructors. + Constructor<? extends IEditorPart> ctor = editorClass.getConstructor(); + return ctor.newInstance(); + } + } + /** {@inheritDoc} */ @Override public void doSave(IProgressMonitor monitor) { diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/service/.ratings b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/service/.ratings index e97d02bb76318c4fa509cab879c8029ee5376253..fd22b149f0941e9eed55e12988c6bc503e54c1e8 100644 --- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/service/.ratings +++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/service/.ratings @@ -4,7 +4,7 @@ IConstraintUIService.java 07df6b9553bf04f8c414c976dc630e6a1dd5ec96 GREEN IContextMenuService.java cfb6b8237b6cd2b0e461991a9ceb95969f330265 GREEN IEditPartFactoryService.java c448bff63fb81f57037c9f1dc5319859c12d0c4d GREEN IMarkerService.java d433e838e387dd2fe61b8dea7395ebb7203ae39b GREEN -IModelEditorBindingService.java e000fb7faf558d1201c5c26e449e0019b4ec24b0 GREEN +IModelEditorBindingService.java ce2ae1957e2232bb0fac1d1d262103f9adfc5266 GREEN IModelElementHandlerService.java c04c2876ccb8b3f8597c8e443f9c7c3db0945430 GREEN INavigatorService.java 8d2ffeb6f075d3abea904b84d8a40090d97837fd GREEN ITutorialUIService.java 72707c60c3d23d8ffc5c579cb9b022bb614eb094 GREEN diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/service/IModelEditorBindingService.java b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/service/IModelEditorBindingService.java index e000fb7faf558d1201c5c26e449e0019b4ec24b0..ce2ae1957e2232bb0fac1d1d262103f9adfc5266 100644 --- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/service/IModelEditorBindingService.java +++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/service/IModelEditorBindingService.java @@ -54,6 +54,9 @@ public interface IModelEditorBindingService { /** Returns the currently active editor. */ IModelEditor<EObject> getActiveEditor(); + /** Returns registered editor bindings for the given class. */ + List<IModelEditorBinding<EObject>> getBindings(Class<? extends EObject> elementType); + /** Returns registered editor bindings for the given {@link EObject}. */ List<IModelEditorBinding<EObject>> getBindings(EObject element); diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/.ratings b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/.ratings index 0a98fb5c57e6ec70b3853c8145ec72ebe32eb99e..b2f23c1f28fd6be6f4cd785dfbd17d06d59c5604 100644 --- a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/.ratings +++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/.ratings @@ -6,7 +6,7 @@ IEclipseResourceStorageLocationProvider.java 0ab7f304d52a9d86f01f66e308e9a7ca420 IElementCompositor.java 5b0ab1732f71b3f8467e0276c844f0dd549e191f GREEN ILibraryElementHandler.java 00ef5b25c63b8570006e6f6748aed0da1f33a5f1 GREEN ILogMessageHandler.java 9ab53e836a095ef00fd84ecc0375167edf593b46 GREEN -IMigrationProvider.java fdb1078dfca10a82a18f79b862d7b8644e80e14e GREEN +IMigrationProvider.java 241bfd8594dfb86ce0f89dc95b43662f52d9e450 GREEN IPrototypeProvider.java d5e3dbae19b5654caf28b81da6b1609d3c12be12 GREEN IStorageProvider.java d9b14cdd254d0c956dc5715c1c4d4d955a705dd5 GREEN ITransformationProvider.java a4ee2ea08720bb2fce29806062eb01499bb5071e GREEN diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/IMigrationProvider.java b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/IMigrationProvider.java index fdb1078dfca10a82a18f79b862d7b8644e80e14e..241bfd8594dfb86ce0f89dc95b43662f52d9e450 100644 --- a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/IMigrationProvider.java +++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/IMigrationProvider.java @@ -45,12 +45,12 @@ public interface IMigrationProvider extends IObjectAware<ITopLevelElement> { /** * Applies the provider to the given element. * - * The parameter "unknownFeatures" returns a map indicating the features that are not recognized + * The parameter "unknownFeatures" indicates the features that are not recognized * in the model. This can be useful to detect features coming from old models and can be then * translated to the new model by a migrator. * - * The migrator should remove from unknownFeatures the features that it dealt with. - * If one forgets to do so, the migrator will run into an infinite loop! + * @return all unknown features that have successfully been migrated. */ - void migrate(ITopLevelElement modelElement, Map<EObject, AnyType> unknownFeatures); + Map<EObject, AnyType> migrate(ITopLevelElement modelElement, + Map<EObject, AnyType> unknownFeatures); } diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/base/RemoveDeprecatedArtifactsMigrationProviderBase.java b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/base/RemoveDeprecatedArtifactsMigrationProviderBase.java deleted file mode 100644 index 4a1b676223b7ec53259a26d1a671b11ff2f911e2..0000000000000000000000000000000000000000 --- a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/base/RemoveDeprecatedArtifactsMigrationProviderBase.java +++ /dev/null @@ -1,95 +0,0 @@ -/*-------------------------------------------------------------------------+ -| Copyright 2018 fortiss GmbH | -| | -| Licensed under the Apache License, Version 2.0 (the "License"); | -| you may not use this file except in compliance with the License. | -| You may obtain a copy of the License at | -| | -| http://www.apache.org/licenses/LICENSE-2.0 | -| | -| Unless required by applicable law or agreed to in writing, software | -| distributed under the License is distributed on an "AS IS" BASIS, | -| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | -| See the License for the specific language governing permissions and | -| limitations under the License. | -+--------------------------------------------------------------------------*/ -package org.fortiss.tooling.kernel.extension.base; - -import static org.conqat.lib.commons.reflect.ReflectionUtils.isInstanceOfAny; -import static org.eclipse.emf.ecore.util.EcoreUtil.delete; -import static org.fortiss.tooling.common.util.LambdaUtils.asStream; - -import java.util.Collection; -import java.util.Map; -import java.util.Optional; -import java.util.stream.Stream; - -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.xml.type.AnyType; -import org.fortiss.tooling.kernel.extension.IMigrationProvider; -import org.fortiss.tooling.kernel.extension.data.ITopLevelElement; -import org.fortiss.tooling.kernel.model.INamedCommentedElement; - -/** - * Remove artificats related to deprecated use case model. - * - * @author barner - */ -public abstract class RemoveDeprecatedArtifactsMigrationProviderBase implements IMigrationProvider { // NO_UCD - // Migrators are retired after a release, but this base class should be available when needed. - // See https://af3-developer.fortiss.org/projects/autofocus3/wiki/Model_Migration - - /** Returns the {@link Collection} of deprecated artifact types to be removed from the model. */ - protected abstract Collection<Class<? extends EObject>> getDeprecatedArtifacts(); - - /** - * Returns the {@link Collection} of deprecated root artifact types (possibly empty subset of - * {@link #getDeprecatedArtifacts()}) for which a comment is added to the migrated model that - * deprecated artifacts have been removed. - */ - protected abstract Collection<Class<? extends EObject>> getDeprecatedRootArtifacts(); - - /** Returns the {@link Stream} of deprecated model elements to be removed. */ - private Stream<EObject> getDeprecatedModelElements(ITopLevelElement modelElement) { - Stream<EObject> root = asStream(modelElement.getRootModelElement().eAllContents()); - Collection<Class<? extends EObject>> deprArtifacts = getDeprecatedArtifacts(); - return root.filter( - e -> isInstanceOfAny(e, deprArtifacts.toArray(new Class[deprArtifacts.size()]))); - } - - /** {@inheritDoc} */ - - @Override - public boolean needMigration(ITopLevelElement modelElement, - Map<EObject, AnyType> unknownFeatures) { - - return getDeprecatedModelElements(modelElement).findAny().isPresent(); - } - - /** {@inheritDoc} */ - @Override - public void migrate(ITopLevelElement modelElement, Map<EObject, AnyType> unknownFeatures) { - EObject object; - do { - object = null; - Stream<EObject> deprecatedModelElements = getDeprecatedModelElements(modelElement); - Optional<EObject> anyObject = deprecatedModelElements.findAny(); - if(anyObject.isPresent()) { - object = anyObject.get(); - if(object.eContainer() instanceof INamedCommentedElement) { - INamedCommentedElement parent = (INamedCommentedElement)object.eContainer(); - if(parent.getComment() == null || parent.getComment().isEmpty()) { - for(Class<? extends EObject> rootType : getDeprecatedRootArtifacts()) { - if(rootType.isAssignableFrom(object.getClass())) { - parent.setComment(rootType.getSimpleName() + - " models are no longer supported. This sub-model has been removed automatically!"); - break; - } - } - } - } - delete(object); - } - } while(object != null); - } -} diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/.ratings b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/.ratings index e6e117aec42749c55a27ff79b3607f3b914272f7..2f69b2046501b5917850e19477bc500f81ea116c 100644 --- a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/.ratings +++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/.ratings @@ -7,7 +7,7 @@ ElementCompositorService.java 98c5d27e09881e60aa4f87c1ac0c7787cdec9f7c GREEN LibraryPrototypeProvider.java b77eddbdca78f561ffb1233e98817be361c690ae GREEN LibraryService.java d22671ba820466062852c15873698adf28960d94 GREEN LoggingService.java da784259f7b456b54bf75c41ec268f64919ce78d GREEN -MigrationService.java 632c13563a3d69681e2a608023fcdadbe5340c4b GREEN +MigrationService.java 2f800eac9793aa736089a802bbfc2c4c1c09770d GREEN PersistencyService.java 103eef642c038ef63fa49b743d803aaa3fea2724 GREEN PrototypeService.java 18c3db05ab11f189a9711bf241c3c7f35c954a9e GREEN ToolingKernelInternal.java d624a5f6b237ce993e150e2b8d1b4390e3fc8f7a GREEN diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/MigrationService.java b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/MigrationService.java index 632c13563a3d69681e2a608023fcdadbe5340c4b..2f800eac9793aa736089a802bbfc2c4c1c09770d 100644 --- a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/MigrationService.java +++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/MigrationService.java @@ -16,18 +16,21 @@ package org.fortiss.tooling.kernel.internal; import static java.util.Collections.emptyList; +import static java.util.stream.Collectors.joining; +import static java.util.stream.Collectors.toSet; import static org.fortiss.tooling.kernel.utils.EcoreUtils.getFirstChildWithType; import static org.fortiss.tooling.kernel.utils.LoggingUtils.error; +import static org.fortiss.tooling.kernel.utils.LoggingUtils.warning; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.stream.Stream; import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.emf.common.util.BasicEList; import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.util.FeatureMap; import org.eclipse.emf.ecore.xml.type.AnyType; import org.fortiss.tooling.kernel.ToolingKernelActivator; import org.fortiss.tooling.kernel.extension.IMigrationProvider; @@ -97,19 +100,6 @@ public class MigrationService extends ObjectAwareServiceBase<IMigrationProvider> return false; } - /** Extracts the list of feature names from a map of features. */ - private List<String> featuresToStrings(Map<EObject, AnyType> features) { - List<String> res = new BasicEList<String>(); - for(AnyType featuresPerKey : features.values()) { - FeatureMap actualFeatures = featuresPerKey.getMixed(); - actualFeatures.addAll(featuresPerKey.getAnyAttribute()); - for(FeatureMap.Entry feature : actualFeatures) { - res.add(feature.getEStructuralFeature().getName()); - } - } - return res; - } - /** {@inheritDoc} */ @Override public void migrate(final ITopLevelElement input, final Map<EObject, AnyType> unknownFeatures) { @@ -117,17 +107,12 @@ public class MigrationService extends ObjectAwareServiceBase<IMigrationProvider> @Override public void run() { + Map<EObject, AnyType> migratedFeatures = new HashMap<EObject, AnyType>(); for(IMigrationProvider provider : getProviders(input)) { if(provider.needMigration(input, unknownFeatures)) { - provider.migrate(input, unknownFeatures); + migratedFeatures.putAll(provider.migrate(input, unknownFeatures)); } } - if(!unknownFeatures.isEmpty()) { - error(ToolingKernelActivator.getDefault(), - input.getSaveableName() + " contains one or more unknown feature(s): " + - featuresToStrings(unknownFeatures)); - } - for(IMigrationProvider provider : getProviders(input)) { if(provider.needMigration(input, unknownFeatures)) { error(ToolingKernelActivator.getDefault(), @@ -136,6 +121,19 @@ public class MigrationService extends ObjectAwareServiceBase<IMigrationProvider> "already performed. Please fix the migrator (or model)."); } } + unknownFeatures.entrySet().removeAll(migratedFeatures.entrySet()); + if(!unknownFeatures.isEmpty()) { + Stream<AnyType> anyTypes = unknownFeatures.values().stream() + .map(v -> v.getMixed()).flatMap(f -> f.stream()).map(e -> e.getValue()) + .filter(AnyType.class::isInstance).map(AnyType.class::cast); + String removedTypes = anyTypes.map(a -> a.eClass().getName()).collect(toSet()) + .stream().collect(joining(", ")); + warning(ToolingKernelActivator.getDefault(), input.getSaveableName() + + " contains one or more feature(s) of the following unkown types that will be deleted: " + + removedTypes + "."); + + unknownFeatures.clear(); + } } }); diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/storage/eclipse/.ratings b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/storage/eclipse/.ratings index 4a4edee0b9b29c4f7e79c5026854886346e3d02a..605b741d853bf1e95bbf06c68ab9a477dea3beb5 100644 --- a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/storage/eclipse/.ratings +++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/storage/eclipse/.ratings @@ -1,5 +1,5 @@ AutoUndoCommandStack.java fc326adf66c6cea2354884cdc240da5f2f82689a GREEN EMFTransactionalCommand.java ba4b5bead9768b6ce6c955b9238cd96cb722533c GREEN EclipseResourceStorageService.java e29e32272286921c5e43963253902b3ba54490c7 GREEN -ModelContext.java 55de5f19c5d625f935fb8136ff72d80b3a54ff19 GREEN +ModelContext.java db1735834c85e7b508266f56463d011f2b72af0e GREEN NonDirtyingEMFTransactionalCommand.java d288ebe35d22442c603496b0c917fb99a8febeea GREEN diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/storage/eclipse/ModelContext.java b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/storage/eclipse/ModelContext.java index 55de5f19c5d625f935fb8136ff72d80b3a54ff19..db1735834c85e7b508266f56463d011f2b72af0e 100644 --- a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/storage/eclipse/ModelContext.java +++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/storage/eclipse/ModelContext.java @@ -330,7 +330,9 @@ class ModelContext implements ITopLevelElement, CommandStackListener { // Step 3..n: Save resources not managed by kernel for(Resource currentResource : rset.getResources()) { - if(currentResource != resource && !editingDomain.isReadOnly(currentResource)) { + if(currentResource != resource && !editingDomain.isReadOnly(currentResource) && + !currentResource.getContents().isEmpty()) { + // do not save resources which are not contained (by a FileProject) try { currentResource.save(saveOptions); } catch(IOException e) { diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/utils/.ratings b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/utils/.ratings index d85861e2edafbeb32da7cbcff68cc64ad45f8ba9..a14d336f35b4b272093a2fc62dcf8c95d8cadab7 100644 --- a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/utils/.ratings +++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/utils/.ratings @@ -10,6 +10,6 @@ JavaUtils.java 65cdadfb9137a240ad59992eacf53a15b7f20804 GREEN KernelModelElementUtils.java fded09befe7e543fc04ea5184ffc1c8a309d7a66 GREEN LoggingUtils.java 0e0aa5d466d80ea29cfc7e91178b23a5cdd4ddf7 GREEN PrototypesUtils.java ec75bed75cfc5103f1f38e3a29df86f729428775 GREEN -ResourceUtils.java 698c7db34acb4f1a258a1953e6afcca9823763a8 GREEN +ResourceUtils.java e31eda3fdbedd2e44c85d471f717b14f92a3c663 GREEN TransformationUtils.java 552d3a9d56d34450be781af828efe0b8aa5d359e GREEN UniqueIDUtils.java 665955b1790c1bd1c2087e23114da920bfec2265 GREEN diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/utils/ResourceUtils.java b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/utils/ResourceUtils.java index 698c7db34acb4f1a258a1953e6afcca9823763a8..e31eda3fdbedd2e44c85d471f717b14f92a3c663 100644 --- a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/utils/ResourceUtils.java +++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/utils/ResourceUtils.java @@ -51,6 +51,11 @@ import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.resource.impl.ResourceFactoryImpl; import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; import org.eclipse.emf.ecore.xmi.PackageNotFoundException; +import org.eclipse.emf.ecore.xmi.XMLHelper; +import org.eclipse.emf.ecore.xmi.XMLLoad; +import org.eclipse.emf.ecore.xmi.XMLResource; +import org.eclipse.emf.ecore.xmi.impl.SAXXMIHandler; +import org.eclipse.emf.ecore.xmi.impl.XMILoadImpl; import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl; import org.eclipse.emf.ecore.xmi.impl.XMLResourceFactoryImpl; import org.eclipse.emf.ecore.xml.type.AnyType; @@ -58,6 +63,7 @@ import org.fortiss.tooling.kernel.ToolingKernelActivator; import org.fortiss.tooling.kernel.extension.data.ITopLevelElement; import org.fortiss.tooling.kernel.model.IIdLabeled; import org.fortiss.tooling.kernel.service.IPersistencyService; +import org.xml.sax.helpers.DefaultHandler; /** * Utility class for dealing with EMF {@link Resource}s. @@ -77,12 +83,79 @@ public final class ResourceUtils { */ public static class KernelResourceFactory extends ResourceFactoryImpl { + /** + * XMIHandler that cleans up dangling references when loading models with unknown types + * instead of throwing an exception. + */ + private final class DanglingReferencesCleanupXMIHandler extends SAXXMIHandler { + /** Constructor. */ + private DanglingReferencesCleanupXMIHandler(XMLResource xmiResource, XMLHelper helper, + Map<?, ?> options) { + super(xmiResource, helper, options); + } + + /** {@inheritDoc} */ + @Override + protected void handleForwardReferences(boolean isEndDocument) { + List<SingleReference> toRemoveFwdSingleRefs = new ArrayList<>(); + for(SingleReference ref : forwardSingleReferences) { + EObject obj; + try { + obj = xmlResource.getEObject((String)ref.getValue()); + } catch(RuntimeException exception) { + obj = null; + } + if(obj == null || obj instanceof AnyType) { + warnRefWithUnknownType((AnyType)obj, ref.getLineNumber(), + ref.getColumnNumber()); + toRemoveFwdSingleRefs.add(ref); + } + } + forwardSingleReferences.removeAll(toRemoveFwdSingleRefs); + + List<ManyReference> toRemoveFwdManyRefs = new ArrayList<>(); + for(ManyReference ref : forwardManyReferences) { + Object[] values = ref.getValues(); + + for(String id : (String[])values) { + + EObject obj; + try { + obj = xmlResource.getEObject(id); + } catch(RuntimeException exception) { + obj = null; + } + if(obj == null || obj instanceof AnyType) { + warnRefWithUnknownType((AnyType)obj, ref.getLineNumber(), + ref.getColumnNumber()); + toRemoveFwdManyRefs.add(ref); + break; + } + } + } + forwardManyReferences.removeAll(toRemoveFwdManyRefs); + + super.handleForwardReferences(isEndDocument); + } + + /** Issues a warning for a given {@link AnyType}d object. */ + private void warnRefWithUnknownType(AnyType obj, int line, int col) { + String message = "Removing reference to element with unknown type" + + (obj != null ? " \"" + obj.eClass().getName() + "\"" : "") + " in line " + + line + ", column " + col + "."; + + // Static inline not possible: name clash with XMLHandler::warning() + LoggingUtils.warning(ToolingKernelActivator.getDefault(), message); + } + } + /** * {@link XMIResourceImpl} used to persist models managed by the tooling kernel. * * @author barner */ private final class KernelXMIResource extends XMIResourceImpl { + /** Constructs a new {@link KernelXMIResource}. */ private KernelXMIResource(URI uri) { super(uri); @@ -99,7 +172,7 @@ public final class ResourceUtils { public String getID(EObject eObject) { String id = super.getID(eObject); if(id == null && eObject instanceof IIdLabeled) { - id = new Integer(((IIdLabeled)eObject).getId()).toString(); + id = String.valueOf(((IIdLabeled)eObject).getId()); setID(eObject, id); } return id; @@ -140,6 +213,18 @@ public final class ResourceUtils { } return eObjectToExtensionMap; } + + /** {@inheritDoc} */ + @Override + protected XMLLoad createXMLLoad() { + return new XMILoadImpl(createXMLHelper()) { + /** {@inheritDoc} */ + @Override + protected DefaultHandler makeDefaultHandler() { + return new DanglingReferencesCleanupXMIHandler(resource, helper, options); + } + }; + } } /** {@inheritDoc} */ @@ -196,13 +281,13 @@ public final class ResourceUtils { /** * <p> - * Determines the {@link ITopLevelElement} which shares the same {@link ResourceSet} as the a - * {@link Resource} with the specified {@link URI}. If no such {@link Resource} has been loaded, - * {@code null} is returned. + * Determines the {@link ITopLevelElement} which shares the same {@link ResourceSet} as the + * a {@link Resource} with the specified {@link URI}. If no such {@link Resource} has been + * loaded, {@code null} is returned. * </p> * <p> - * This is useful to determine to which model managed by the Kernel a given (external) model is - * linked. + * This is useful to determine to which model managed by the Kernel a given (external) model + * is linked. * </p> * * @param uri @@ -226,8 +311,8 @@ public final class ResourceUtils { } /** - * Obtains a model of a given type from a {@code resourceSet}, or {@code null} if it could not - * be found. + * Obtains a model of a given type from a {@code resourceSet}, or {@code null} if it could + * not be found. * * @param resourceSet * {@link ResourceSet} from which model of given type should be determined @@ -251,25 +336,30 @@ public final class ResourceUtils { } /** - * Obtains a model of a given type from a {@code resourceSet}, and creates the model if it does - * not exist yet (and adds it to the given {@code resourceSet}). Returns {@code null} if the - * model could not be created. + * Obtains a model of a given type from a {@code resourceSet}, and creates the model if it + * does not exist yet (and adds it to the given {@code resourceSet}). Returns {@code null} if + * the model could not be created. * * @param resourceSet * {@link ResourceSet} from which model of given type should be determined * @param clazz * Type of model to be returned. * @param factory - * {@link EFactory} to create root model element in case the model does not exist in + * {@link EFactory} to create root model element in case the model does not exist + * in * the {@code resourceSet} yet. * @param fileExtension - * File extension to be used in case a new resource has to be created and added to - * the given given {@code resourceSet}. In case this parameter is {@code null}, this + * File extension to be used in case a new resource has to be created and added + * to + * the given given {@code resourceSet}. In case this parameter is {@code null}, + * this * method effectively behaves like {@link #getModel(ResourceSet, Class)}. * @param referenceClazz - * Type of root model element whose {@link Resource} {@link URI} should be used to + * Type of root model element whose {@link Resource} {@link URI} should be used + * to * derive the base name in case a new {@link Resource} has to be created. In case - * this parameter is {@code null}, the {@link URI} of the first {@link Resource} in + * this parameter is {@code null}, the {@link URI} of the first {@link Resource} + * in * the given {@link ResourceSet} is used. * * @return Model of a given type, or {@code null} if it could not be created. @@ -368,12 +458,14 @@ public final class ResourceUtils { * {@link Resource} for which {@link URI}s of directly or indirectly referencing * resources should be determined. * @param includeSelf - * Flag if the {@link URI} of the given {@code resource} should be contained in the + * Flag if the {@link URI} of the given {@code resource} should be contained in + * the * result. * @param progressMonitor * {@link IProgressMonitor} (may be {@code null}). Loading all resources in a * directory may be a long-running operation. - * @return {@link URI}s of directly or indirectly referencing resources, possibly including the + * @return {@link URI}s of directly or indirectly referencing resources, possibly including + * the * {@link URI} of the given {@code resource} itself (see {@code includeSelf}). */ public static Collection<URI> getReferencingResourceURIs(Resource resource, boolean includeSelf,