...
 
Commits (44)
......@@ -20,16 +20,6 @@
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.fortiss.ide.dev_tools.warnings.RemoveWarningsBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.fortiss.ide.dev_tools.warnings.GuidelinesChecker</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.systemfocus.tooling.codereview.builder.CodeReviewBuilder</name>
<arguments>
......
Subproject commit cdce9ac9a94655561e7dff41ece863f0a7062f4a
Subproject commit d117b3db1742a745f515d2b6c52cc9a02e57c299
HierarchicModelElementTreeViewer.java 8662b201c3a459f3ebe3620970652f7a3f90270e GREEN
ModelElementTreeViewer.java 9c7637313b0ce4d70566ebb4f90dfca0d9931d09 GREEN
......@@ -15,37 +15,88 @@
+--------------------------------------------------------------------------*/
package org.fortiss.tooling.base.ui.javafx.control.treetableview;
import javafx.embed.swt.SWTFXUtils;
import javafx.scene.Node;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.TreeView;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import static javafx.embed.swt.SWTFXUtils.toFXImage;
import static org.fortiss.tooling.kernel.ui.util.KernelUIUtils.getName;
import java.util.ArrayList;
import java.util.List;
import org.fortiss.tooling.base.model.element.IHierarchicElement;
import org.fortiss.tooling.base.model.element.IModelElement;
import org.fortiss.tooling.common.ui.javafx.AF3FXViewPart;
import org.fortiss.tooling.common.ui.javafx.control.treetableview.DynamicTreeContentProviderBase;
import org.fortiss.tooling.common.ui.javafx.control.treetableview.DynamicTreeItem;
import org.fortiss.tooling.common.ui.javafx.control.treetableview.DynamicTreeUIProviderBase;
import org.fortiss.tooling.common.ui.javafx.control.treetableview.DynamicTreeViewer;
import org.fortiss.tooling.kernel.model.INamedCommentedElement;
import org.fortiss.tooling.kernel.model.INamedElement;
import org.fortiss.tooling.kernel.ui.service.IModelElementHandlerService;
import javafx.scene.Node;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TreeView;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
/**
* This class is a support fragment for creating tree views in JavaFX Controls. It provides the view
* counter part of a {@link DynamicTreeContentProviderBase}. The content provider is responsible
* for selecting elements from a base model and ordering them according to a custom defined
* structure.
* These two fragments have to be combined in a JavaFX controller inheriting from the base class
* {@link AF3FXViewPart}.
* <p>
* TreeViewer that constructs a DynamicTreeViewer whose UI provider uses the methods and kernel
* services for {@link IHierarchicElement}s and {@link INamedCommentedElement}s.
* The Viewer uses a composition principle where a client must provide {@link TreeView} (JavaFX), a
* root element (AF3), and a content provider that selects the elements to be displayed.
* services for {@link INamedElement}s.
* The Viewer uses a composition principle where a client must provide a {@link TreeView} (JavaFX),
* a root element (AF3), and a content provider that selects the elements to be displayed.
*
* @author diewald
*/
public class HierarchicModelElementTreeViewer<T extends IHierarchicElement & INamedCommentedElement> {
public class ModelElementTreeViewer<T extends INamedElement> {
/** {@link DynamicTreeUIProviderBase} for named (and commented) {@link IModelElement}s . */
protected class ModelElementUIProvider extends DynamicTreeUIProviderBase<T> {
/** {@inheritDoc} */
@Override
public String getLabel(T element) {
return getName(element);
}
/** {@inheritDoc} */
@Override
public Node getIconNode(T element) {
org.eclipse.swt.graphics.Image icon =
IModelElementHandlerService.getInstance().getIcon(element);
if(icon != null) {
Image fxImage = toFXImage(icon.getImageData(), null);
return new ImageView(fxImage);
}
return null;
}
/** {@inheritDoc} */
@Override
public ContextMenu createContextMenu(T element) {
ContextMenu menu = new ContextMenu();
contextMenuEntries.forEach(entry -> menu.getItems().add(entry));
return menu;
}
}
/** References the constructed {@link DynamicTreeViewer} "controller". */
protected DynamicTreeViewer<T> dynTreeViewer;
/**
* List of context menu entries that supplied by clients (see
* {@link #addContextMenuEntry(MenuItem)}).
*/
protected List<MenuItem> contextMenuEntries = new ArrayList<>();
/** Constructor. */
public HierarchicModelElementTreeViewer(TreeView<T> treeView, T modelRoot,
public ModelElementTreeViewer(TreeView<T> treeView, T modelRoot,
DynamicTreeContentProviderBase<T> contentProvider) {
DynamicTreeUIProviderBase<T> uiProvider = createContentUIProvider();
DynamicTreeUIProviderBase<T> uiProvider = createUIProvider();
dynTreeViewer =
new DynamicTreeViewer<T>(treeView, modelRoot, true, 0, contentProvider, uiProvider);
}
......@@ -54,48 +105,33 @@ public class HierarchicModelElementTreeViewer<T extends IHierarchicElement & INa
* Creates a default UI provider for {@link DynamicTreeViewer}s that present
* {@link IHierarchicElement}s. It also uses the {@link IModelElementHandlerService} for a nicer
* visual appearance.
* <p>
* Externalize this method into a class when subclassing seems appropriate.
*
* @return The constructed UI Provider.
*/
protected DynamicTreeUIProviderBase<T> createContentUIProvider() {
return new DynamicTreeUIProviderBase<T>() {
protected DynamicTreeUIProviderBase<T> createUIProvider() {
return new ModelElementUIProvider();
}
/** {@inheritDoc} */
@Override
public String getLabel(T element) {
return element.getName();
}
/**
* Method to define context {@link MenuItem}s for items of the underlying content. The given
* function may use the selected element (given as a parameter to the function) to define
* dynamic behavior.
*
* @param menuItem
* {@link MenuItem} and its logic to be added to the context menu.
*/
public void addContextMenuEntry(MenuItem menuItem) {
contextMenuEntries.add(menuItem);
}
/** {@inheritDoc} */
@Override
public Node getIconNode(T element) {
org.eclipse.swt.graphics.Image icon =
IModelElementHandlerService.getInstance().getIcon(element);
if(icon != null) {
Image fxImage = SWTFXUtils.toFXImage(icon.getImageData(), null);
return new ImageView(fxImage);
}
return null;
}
/** Update the internal viewer. */
public void update() {
dynTreeViewer.update();
}
/** {@inheritDoc} */
@Override
public ContextMenu createContextMenu(T element) {
ContextMenu menu = new ContextMenu();
// TODO (3209): Add sensible default operations for AF3 elements, if they are
// needed. Otherwise, use a list provided by subclasses that defines the menu items
// and their order. The code below is taken from SystemFOCUS and shall serve as a
// reference.
// MenuItem item = new MenuItem("Delete '" + getLabel(element) + "'.");
// item.setOnAction(event -> {
// new DeleteOperation(element).delete();
// viewer.update();
// });
// menu.getItems().add(item);
return menu;
}
};
/** Expands the tree down to the given value. */
public void expandItem(T value) {
DynamicTreeItem<T> item = dynTreeViewer.findItem(value);
dynTreeViewer.expandItem(item);
}
}
......@@ -5,11 +5,6 @@
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.fortiss.ide.dev_tools.emf.builder.EcoreBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.systemfocus.tooling.emfgeneration.git.EcoreBuilderGIT</name>
<arguments>
......@@ -30,16 +25,6 @@
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.fortiss.ide.dev_tools.warnings.RemoveWarningsBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.fortiss.ide.dev_tools.warnings.GuidelinesChecker</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.systemfocus.tooling.codereview.builder.CodeReviewBuilder</name>
<arguments>
......
Subproject commit cdce9ac9a94655561e7dff41ece863f0a7062f4a
Subproject commit d117b3db1742a745f515d2b6c52cc9a02e57c299
......@@ -20,16 +20,6 @@
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.fortiss.ide.dev_tools.warnings.RemoveWarningsBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.fortiss.ide.dev_tools.warnings.GuidelinesChecker</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.systemfocus.tooling.codereview.builder.CodeReviewBuilder</name>
<arguments>
......
Subproject commit cdce9ac9a94655561e7dff41ece863f0a7062f4a
Subproject commit d117b3db1742a745f515d2b6c52cc9a02e57c299
......@@ -17,9 +17,9 @@ Require-Bundle: org.fortiss.tooling.common;bundle-version="2.14.0";visibility:=r
org.eclipse.ui.views.properties.tabbed;visibility:=reexport,
org.eclipse.ui.ide;visibility:=reexport,
org.eclipse.jface.text;visibility:=reexport,
openjfx.controls;bundle-version="11.0.0";visibility:=reexport,
openjfx.base;bundle-version="11.0.0";visibility:=reexport,
openjfx.fxml;bundle-version="11.0.0";visibility:=reexport,
org.openjfx.controls;bundle-version="11.0.2";visibility:=reexport,
org.openjfx.base;bundle-version="11.0.2";visibility:=reexport,
org.openjfx.fxml;bundle-version="11.0.2";visibility:=reexport,
org.eclipse.fx.ui.workbench3;bundle-version="3.5.0";visibility:=reexport
Bundle-ClassPath: .,
lib/org.conqat.ide.commons.gef.jar,
......@@ -75,7 +75,8 @@ Export-Package: org.conqat.ide.commons.gef,
org.eclipse.wb.swt.widgets.baseline,
org.fortiss.tooling.common.ui,
org.fortiss.tooling.common.ui.javafx,
org.fortiss.tooling.common.ui.javafx.control.treetableview
org.fortiss.tooling.common.ui.javafx.control.treetableview,
org.fortiss.tooling.common.ui.javafx.util
Bundle-Vendor: fortiss GmbH
Bundle-Activator: org.fortiss.tooling.common.ui.ToolingCommonUIActivator
Bundle-ActivationPolicy: lazy
......
......@@ -18,31 +18,27 @@ package org.fortiss.tooling.common.ui.javafx;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.ResourceBundle;
import org.apache.commons.lang3.SystemUtils;
import org.eclipse.fx.ui.workbench3.FXViewPart;
import org.eclipse.ui.part.ViewPart;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import org.apache.commons.lang3.SystemUtils;
import org.eclipse.fx.ui.workbench3.FXViewPart;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.part.ViewPart;
/**
* Base class to create eclipse (SWT-based) views using JavaFX GUI elements. This class requires
* FXML file that defines the GUI elements of the view.
*
* @author diewald
*/
/**
* This class will be used for the migration to JavaFX, which is work-in-progress. Hence, mark the
* class for non-removal.
*/
public abstract class AF3FXViewPart extends FXViewPart { // NO_UCD
public abstract class AF3FXViewPart extends FXViewPart implements Initializable {
/** For later use, if we need to define different styles. */
private String cssLocation;
......@@ -104,26 +100,12 @@ public abstract class AF3FXViewPart extends FXViewPart { // NO_UCD
this.cssLocation = cssLocation;
}
/** {@inheritDoc} */
@Override
public void createPartControl(Composite parent) {
if("gtk".equals(System.getProperty("osgi.ws"))) {
if(!"0".equals(System.getenv("SWT_GTK3"))) {
org.eclipse.swt.widgets.Label errorLabel =
new org.eclipse.swt.widgets.Label(parent, SWT.BOLD);
errorLabel.setText("Cannot show JavaFX view without setting SWT_GTK3 to '0'.\n" +
"Please relaunch Eclipse using a terminal and 'SWT_GTK3=0 ./eclipse' command.");
return;
}
}
super.createPartControl(parent);
}
/** {@inheritDoc} */
@Override
protected Scene createFxScene() {
FXMLLoader loader = new FXMLLoader();
loader.setClassLoader(viewerClass.getClassLoader());
loader.setController(this);
if(fXMLLocation != null) {
loader.setLocation(viewerClass.getResource(fXMLLocation));
try {
......@@ -135,7 +117,8 @@ public abstract class AF3FXViewPart extends FXViewPart { // NO_UCD
} else {
root = new AnchorPane();
try {
viewerClass.getMethod("initialize").invoke(this);
viewerClass.getMethod("initialize", URL.class, ResourceBundle.class).invoke(this,
null, null);
} catch(IllegalAccessException | IllegalArgumentException | InvocationTargetException |
SecurityException e) {
throw new RuntimeException("The initialize method of the View " +
......@@ -164,17 +147,6 @@ public abstract class AF3FXViewPart extends FXViewPart { // NO_UCD
// Not needed.
}
/**
* Init method that is called after the JavaFX toolkit has been launched. The initialize method
* is needed for single-node/view/control {@link ViewPart}s and for controls in a FXML-based
* view that require an initial configuration. If no initial configuration is required place a
* stub.
* <p>
* For FXML, the initialize method is called via the JavaFX framework. Otherwise, it is called
* via reflection from this class.
*/
protected abstract void initialize();
/**
* Adds a single {@link Node} to this view. It embeds the given {@link Node} to the
* {@link AnchorPane} of this view and stretches it to the borders of the view.
......
......@@ -3,6 +3,6 @@ DynamicTreeItem.java afc105cf5acf3d2506d89e0892555100c234ce5b GREEN
DynamicTreeTableUIProviderBase.java fd9fce19a65eb1006ceacb0d869bbe90a8c578b3 GREEN
DynamicTreeTableViewer.java e474f3a890fd6525db7de8e299d7fbe67f932a15 GREEN
DynamicTreeUIProviderBase.java 56fe4df4577b35f1e5e6e4c4be189b706c852d52 GREEN
DynamicTreeViewer.java d5b9f87862d9c42327c46bce02fb34d64673d413 GREEN
DynamicTreeViewer.java da5e24ae57777a482d8e12c8262513d8143bfa93 GREEN
DynamicTreeViewerBase.java 47124c847de322a0ae26eb7a114f85ce4bd02d7e GREEN
IDoubleClickHandler.java 447f7769dead9a106b3ea3139ef0da51eb0b9a89 GREEN
......@@ -34,6 +34,8 @@ import javafx.scene.input.MouseEvent;
public final class DynamicTreeViewer<T> extends DynamicTreeViewerBase<T> {
/** The {@link TreeView} control to be managed. */
private final TreeView<T> view;
/** {@link TreeItem} constructed for the root object. */
private final DynamicTreeItem<T> rootItem;
/** The UI provider implementation. */
private final DynamicTreeUIProviderBase<T> uiProvider;
/** The selection change listener. */
......@@ -49,7 +51,7 @@ public final class DynamicTreeViewer<T> extends DynamicTreeViewerBase<T> {
this.uiProvider = uiProvider;
// construct view
this.view = view;
DynamicTreeItem<T> rootItem = new DynamicTreeItem<T>(root, this);
rootItem = new DynamicTreeItem<T>(root, this);
view.setRoot(rootItem);
view.setShowRoot(showRoot);
configureCellFactory();
......@@ -88,9 +90,14 @@ public final class DynamicTreeViewer<T> extends DynamicTreeViewerBase<T> {
view.getSelectionModel().select(row);
}
/** Searches the {@link DynamicTreeItem} for the given value from the root. */
public DynamicTreeItem<T> findItem(T value) {
return findItem(rootItem, value);
}
/** Searches the {@link DynamicTreeItem} for the given value. */
public DynamicTreeItem<T> findItem(DynamicTreeItem<T> item, Object value) {
if(item == null || value == null) {
if(item == null || value == null || item.getValue() == null) {
return null;
}
if(item.getValue().equals(value)) {
......@@ -142,6 +149,14 @@ public final class DynamicTreeViewer<T> extends DynamicTreeViewerBase<T> {
});
}
/** Expands the tree to the given item. */
public void expandItem(TreeItem<T> item) {
while(item.getParent() != null) {
item = item.getParent();
item.setExpanded(true);
}
}
/** Expands items up to the given level. */
private void expandItem(TreeItem<T> parentItem, int revealLevel) {
if(revealLevel <= 0) {
......@@ -165,7 +180,7 @@ public final class DynamicTreeViewer<T> extends DynamicTreeViewerBase<T> {
}
/**
* Customized event dispatcher to fix double-click behavior. Thiss prevents opening/closing of
* Customized event dispatcher to fix double-click behavior. This prevents opening/closing of
* tree items with double click listeners assigned.
*/
private class DoubleClickEventDispatcher implements EventDispatcher {
......
SceneGraphUtils.java f54304c2eb604934de9afdf9d2a8ca88a762398a GREEN
/*-------------------------------------------------------------------------+
| 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.common.ui.javafx.util;
import java.util.LinkedList;
import java.util.Queue;
import java.util.function.Predicate;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
/**
* Utility methods for {@link Scene} graph.
*
* @author hoelzl
* @author diewald
*/
public final class SceneGraphUtils {
/** Prevent instantiation. */
private SceneGraphUtils() {
// Nothing to do
}
/**
* Searches the scene graph hierarchy for the nearest parent node of the given class.
*
* @param start
* the start node
* @param clazz
* the target class of the node to be found
* @return the nearest parent node
*/
@SuppressWarnings("unchecked")
public static <T extends Node> T findParentNode(Parent start, Class<T> clazz) {
return (T)findParentNode(start, t -> clazz.isInstance(t));
}
/**
* Searches the scene graph hierarchy for the nearest child node with the given id.
*
* @param start
* the start node
* @param id
* string identified (field "fx:id" in FXML files).
* @return the nearest child node
*/
public static Node findParentById(Parent start, String id) {
return findParentNode(start, t -> t.getId().equals(id));
}
/**
* Searches the scene graph hierarchy for the nearest parent node with the given id and type.
*
* @param start
* the start node
* @param id
* string identified (field "fx:id" in FXML files).
* @param type
* the target class of the node to be found
* @return the nearest child node
*/
@SuppressWarnings("unchecked")
public static <T extends Node> T findParentByIdType(Parent start, String id, Class<T> type) {
return (T)findChildNode(start,
t -> (type.isAssignableFrom(type)) && (t.getId().equals(id)));
}
/**
* Searches the scene graph hierarchy for the nearest parent node fulfilling the given
* {@link Predicate}.
*
* @param start
* the start node
* @param pred
* predicate evaluated during the parent walk
* @return the nearest parent node
*/
public static Node findParentNode(Parent start, Predicate<Node> pred) {
while(start != null) {
start = start.getParent();
if(pred.test(start)) {
return start;
}
}
return null;
}
/**
* Searches the scene graph hierarchy for the nearest child node of the given class.
*
* @param start
* the start node
* @param clazz
* the target class of the node to be found
* @return the nearest child node
*/
@SuppressWarnings("unchecked")
public static <T extends Node> T findChildNode(Parent start, Class<T> clazz) {
return (T)findChildNode(start, t -> clazz.isInstance(t));
}
/**
* Searches the scene graph hierarchy for the nearest child node with the given id.
*
* @param start
* the start node
* @param id
* string identified (field "fx:id" in FXML files).
* @return the nearest child node
*/
public static Node findChildById(Parent start, String id) {
return findChildNode(start, t -> t.getId().equals(id));
}
/**
* Searches the scene graph hierarchy for the nearest child node with the given id and type.
*
* @param start
* the start node
* @param id
* string identified (field "fx:id" in FXML files).
* @param type
* the target class of the node to be found
* @return the nearest child node
*/
@SuppressWarnings("unchecked")
public static <T extends Node> T findChildByIdType(Parent start, String id, Class<T> type) {
// @CodeFormatterOff
return (T)findChildNode(start,
t -> (t.getId() != null
&& (t.getId().equals(id))
&& type.isAssignableFrom(t.getClass())));
// @CodeFormatterOn
}
/**
* Searches the scene graph hierarchy for the nearest child node of the given fulfilling the
* given {@link Predicate}.
*
* @param start
* the start node
* @param pred
* predicate evaluated during the child walk
* @return the nearest parent node
*/
public static Node findChildNode(Parent start, Predicate<Node> pred) {
Queue<Node> children = new LinkedList<>();
children.addAll(start.getChildrenUnmodifiable());
while(!children.isEmpty()) {
Node child = children.poll();
if(pred.test(child)) {
return child;
}
if(child instanceof Parent) {
children.addAll(((Parent)child).getChildrenUnmodifiable());
}
}
return null;
}
}
......@@ -5,11 +5,6 @@
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.fortiss.ide.dev_tools.emf.builder.EcoreBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.systemfocus.tooling.emfgeneration.git.EcoreBuilderGIT</name>
<arguments>
......@@ -30,16 +25,6 @@
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.fortiss.ide.dev_tools.warnings.RemoveWarningsBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.fortiss.ide.dev_tools.warnings.GuidelinesChecker</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.systemfocus.tooling.codereview.builder.CodeReviewBuilder</name>
<arguments>
......
Subproject commit cdce9ac9a94655561e7dff41ece863f0a7062f4a
Subproject commit d117b3db1742a745f515d2b6c52cc9a02e57c299
LambdaUtils.java 6a7260eca3f4c0f44e97a26cfeacb8801d00bf6c GREEN
LambdaUtils.java 3f5414dfe3e7efe4d2f75e8a7cd159655b2fb4c7 GREEN
......@@ -301,8 +301,24 @@ public class LambdaUtils {
}
/**
* Checks whether the given object inherits from any of the given Classes, i.e. the check
* {@link Class#isAssignableFrom(Class)} is performed for each given class on the given Object.
* Checks whether the given object inherits from any of the given {@link Class}es, i.e. the
* check {@link Class#isAssignableFrom(Class)} is performed for each given class on the given
* {@link Class}.
*
* @param types
* collection of classes to check inheritance.
* @param testType
* type to check whether it inherits from any of the given classes.
* @return see above.
*/
public static boolean isAssignableFromAny(Collection<Class<?>> types, Class<?> testType) {
return types.stream().anyMatch(t -> testType.isAssignableFrom(t));
}
/**
* Checks whether the given object inherits from any of the given {@link Class}es, i.e. the
* check {@link Class#isAssignableFrom(Class)} is performed for each given class on the given
* {@link Object}.
*
* @param types
* collection of classes to check inheritance.
......@@ -311,7 +327,7 @@ public class LambdaUtils {
* @return see above.
*/
public static boolean isAssignableFromAny(Collection<Class<?>> types, Object element) {
return types.stream().anyMatch(t -> t.isAssignableFrom(element.getClass()));
return isAssignableFromAny(types, element.getClass());
}
/**
......
......@@ -20,16 +20,6 @@
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.fortiss.ide.dev_tools.warnings.RemoveWarningsBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.fortiss.ide.dev_tools.warnings.GuidelinesChecker</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.systemfocus.tooling.codereview.builder.CodeReviewBuilder</name>
<arguments>
......
Subproject commit cdce9ac9a94655561e7dff41ece863f0a7062f4a
Subproject commit d117b3db1742a745f515d2b6c52cc9a02e57c299
......@@ -5,11 +5,6 @@
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.fortiss.ide.dev_tools.emf.builder.EcoreBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.systemfocus.tooling.emfgeneration.git.EcoreBuilderGIT</name>
<arguments>
......@@ -30,16 +25,6 @@
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.fortiss.ide.dev_tools.warnings.RemoveWarningsBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.fortiss.ide.dev_tools.warnings.GuidelinesChecker</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.systemfocus.tooling.codereview.builder.CodeReviewBuilder</name>
<arguments>
......
Subproject commit cdce9ac9a94655561e7dff41ece863f0a7062f4a
Subproject commit d117b3db1742a745f515d2b6c52cc9a02e57c299
......@@ -20,16 +20,6 @@
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.fortiss.ide.dev_tools.warnings.RemoveWarningsBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.fortiss.ide.dev_tools.warnings.GuidelinesChecker</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.systemfocus.tooling.codereview.builder.CodeReviewBuilder</name>
<arguments>
......
Subproject commit cdce9ac9a94655561e7dff41ece863f0a7062f4a
Subproject commit d117b3db1742a745f515d2b6c52cc9a02e57c299
......@@ -5,11 +5,6 @@
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.fortiss.ide.dev_tools.emf.builder.EcoreBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.systemfocus.tooling.emfgeneration.git.EcoreBuilderGIT</name>
<arguments>
......@@ -30,16 +25,6 @@
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.fortiss.ide.dev_tools.warnings.RemoveWarningsBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.fortiss.ide.dev_tools.warnings.GuidelinesChecker</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.systemfocus.tooling.codereview.builder.CodeReviewBuilder</name>
<arguments>
......
Subproject commit cdce9ac9a94655561e7dff41ece863f0a7062f4a
Subproject commit d117b3db1742a745f515d2b6c52cc9a02e57c299
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.fortiss.tooling.kernel;singleton:=true
Bundle-Version: 2.14.0.qualifier
Bundle-ClassPath: .
Bundle-Activator: org.fortiss.tooling.kernel.ToolingKernelActivator
Bundle-Vendor: %providerName
Bundle-Localization: plugin
Require-Bundle: org.fortiss.tooling.common;visibility:=reexport;bundle-version="2.14.0",
org.eclipse.core.runtime,
org.eclipse.emf.ecore;visibility:=reexport;bundle-version="2.7.0",
org.eclipse.emf.transaction;visibility:=reexport;bundle-version="1.4.0",
org.eclipse.emf.ecore.xmi;visibility:=reexport;bundle-version="2.7.0"
Bundle-RequiredExecutionEnvironment: JavaSE-11
Bundle-ActivationPolicy: lazy
Export-Package: org.fortiss.tooling.kernel;uses:="org.eclipse.core.runtime,
org.osgi.framework",
org.fortiss.tooling.kernel.constraint,
org.fortiss.tooling.kernel.extension,
org.fortiss.tooling.kernel.extension.base,
org.fortiss.tooling.kernel.extension.data,
org.fortiss.tooling.kernel.extension.exception,
org.fortiss.tooling.kernel.introspection,
org.fortiss.tooling.kernel.introspection.items,
org.fortiss.tooling.kernel.model;uses:=org.eclipse.emf.ecore,
org.fortiss.tooling.kernel.model.constraints,
org.fortiss.tooling.kernel.model.constraints.impl,
org.fortiss.tooling.kernel.model.constraints.util,
org.fortiss.tooling.kernel.model.impl;uses:=org.fortiss.tooling.kernel.model,
org.fortiss.tooling.kernel.model.util;uses:="org.eclipse.emf.ecore,
org.fortiss.tooling.kernel.model,
org.eclipse.emf.common.notify.impl,
org.eclipse.emf.common.notify",
org.fortiss.tooling.kernel.service;uses:="org.eclipse.core.runtime,
org.eclipse.emf.ecore,
org.fortiss.tooling.kernel.interfaces,
org.conqat.lib.commons.collections",
org.fortiss.tooling.kernel.service.base,
org.fortiss.tooling.kernel.service.listener,
org.fortiss.tooling.kernel.service.types,
org.fortiss.tooling.kernel.utils;uses:="org.eclipse.emf.ecore,
org.eclipse.core.resources"
Automatic-Module-Name: org.fortiss.tooling.kernel
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.fortiss.tooling.kernel;singleton:=true
Bundle-Version: 2.14.0.qualifier
Bundle-ClassPath: .
Bundle-Activator: org.fortiss.tooling.kernel.ToolingKernelActivator
Bundle-Vendor: %providerName
Bundle-Localization: plugin
Require-Bundle: org.fortiss.tooling.common;visibility:=reexport;bundle-version="2.14.0",
org.eclipse.core.runtime,
org.eclipse.emf.ecore;visibility:=reexport;bundle-version="2.7.0",
org.eclipse.emf.transaction;visibility:=reexport;bundle-version="1.4.0",
org.eclipse.emf.ecore.xmi;visibility:=reexport;bundle-version="2.7.0"
Bundle-RequiredExecutionEnvironment: JavaSE-11
Bundle-ActivationPolicy: lazy
Export-Package: org.fortiss.tooling.kernel;uses:="org.eclipse.core.runtime,
org.osgi.framework",
org.fortiss.tooling.kernel.constraint,
org.fortiss.tooling.kernel.extension,
org.fortiss.tooling.kernel.extension.base,
org.fortiss.tooling.kernel.extension.data,
org.fortiss.tooling.kernel.extension.exception,
org.fortiss.tooling.kernel.introspection,
org.fortiss.tooling.kernel.introspection.items,
org.fortiss.tooling.kernel.model;uses:=org.eclipse.emf.ecore,
org.fortiss.tooling.kernel.model.constraints,
org.fortiss.tooling.kernel.model.constraints.impl,
org.fortiss.tooling.kernel.model.constraints.util,
org.fortiss.tooling.kernel.model.impl;uses:=org.fortiss.tooling.kernel.model,
org.fortiss.tooling.kernel.model.util;uses:="org.eclipse.emf.ecore,
org.fortiss.tooling.kernel.model,
org.eclipse.emf.common.notify.impl,
org.eclipse.emf.common.notify",
org.fortiss.tooling.kernel.service;uses:="org.eclipse.core.runtime,
org.eclipse.emf.ecore,
org.fortiss.tooling.kernel.interfaces,
org.conqat.lib.commons.collections",
org.fortiss.tooling.kernel.service.base,
org.fortiss.tooling.kernel.service.listener,
org.fortiss.tooling.kernel.service.types,
org.fortiss.tooling.kernel.utils;uses:="org.eclipse.emf.ecore,
org.eclipse.core.resources"
Automatic-Module-Name: org.fortiss.tooling.kernel
Import-Package: com.google.common.collect
......@@ -5,6 +5,6 @@ DialogMessage.java 8420640e999e4fb15fa644333e5d71e1d16c2559 GREEN
ElementCompositorBase.java 7a445e5adde11878fe0515baca8b915287149b28 GREEN
MultiViolationConstraintCheckerBase.java 30886a94c99cf8948f64401b1db821abe06e1e6c GREEN
PrototypeProviderBase.java ebcd1794c3798b9899a620b01fd5aa0402129423 GREEN
RemoveDeprecatedArtifactsMigrationProviderBase.java 4a1b676223b7ec53259a26d1a671b11ff2f911e2 YELLOW
RemoveDeprecatedArtifactsMigrationProviderBase.java 4a1b676223b7ec53259a26d1a671b11ff2f911e2 GREEN
TransformationContextChainBase.java 1ef37880ab275778c563928e80ba378fec964cb6 GREEN
TransformationProviderBase.java 9e91100cc1f2c8fbd8d41af55aedfea34e02ff71 GREEN
......@@ -2,7 +2,7 @@ CompositionUtils.java 34c0a191bd0fb4176c94b4d61abb5c88a679d5e8 GREEN
ConstraintsUtils.java 0f8be020f2ca4bb08931c32452163c04a28e30ce GREEN
EMFResourceUtils.java 979d0e1f4f66a2b3e715d2da0ebef6493f547fd7 GREEN
EcoreSerializerBase.java 0a0c2969d793d2e68094c55c8f7b0a662ef6e5d5 GREEN
EcoreUtils.java aca34b67bcf6a6a488e83964bfea73f6bfbff6b1 GREEN
EcoreUtils.java 91087233c50130c4abde858d892c6a1e7991e1bf GREEN
ExtensionPointUtils.java 7ce63242b49eb9a7cd4eaadd223f5ebce1dfd75b GREEN
HierarchicalNameComparator.java 6face1b673126701a0721af48ead2f9766c17d46 GREEN
IdentifierUtils.java fff43dc4e84cdd89c3ece4f5d9d89aec4b0749c2 GREEN
......@@ -11,5 +11,5 @@ KernelModelElementUtils.java 56c86fe9afb23053f50d7279809afd2a5bb10eba GREEN
LoggingUtils.java 0e0aa5d466d80ea29cfc7e91178b23a5cdd4ddf7 GREEN
PrototypesUtils.java ec75bed75cfc5103f1f38e3a29df86f729428775 GREEN
ResourceUtils.java 698c7db34acb4f1a258a1953e6afcca9823763a8 GREEN
TransformationUtils.java 552d3a9d56d34450be781af828efe0b8aa5d359e YELLOW
TransformationUtils.java 552d3a9d56d34450be781af828efe0b8aa5d359e GREEN
UniqueIDUtils.java 665955b1790c1bd1c2087e23114da920bfec2265 GREEN
......@@ -15,12 +15,14 @@
+--------------------------------------------------------------------------*/
package org.fortiss.tooling.kernel.utils;
import static java.util.stream.Collectors.toList;
import static org.eclipse.emf.common.notify.Notification.EVENT_TYPE_COUNT;
import static org.eclipse.emf.ecore.util.EcoreUtil.getAllContents;
import static org.eclipse.emf.ecore.util.EcoreUtil.getRootContainer;
import static org.eclipse.emf.ecore.util.EcoreUtil.replace;
import static org.eclipse.emf.ecore.util.EcoreUtil.UsageCrossReferencer.find;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
......@@ -50,6 +52,9 @@ import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.util.EcoreUtil.Copier;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
/**
* Utility methods for dealing with <code>Ecore</code> models. These methods should be used to
* define EMF operations that make the models easier to use.
......@@ -395,6 +400,17 @@ public class EcoreUtils {
return t;
}
/**
* Returns a self-contained copy of the given collection of {@link EObject}s.
*
* @return Self-contained copy of the given {@link EObject}s.
*/
@SuppressWarnings("unchecked")
public static <T extends EObject> Collection<T> copy(Collection<T> eObjects) {
Map<EObject, EObject> copyMap = copyToRefMap(eObjects);
return (Collection<T>)eObjects.stream().map(orig -> copyMap.get(orig)).collect(toList());
}
/**
* Creates a self-contained copy of the given {@link EObject}.
*
......@@ -409,9 +425,79 @@ public class EcoreUtils {
return copier;
}
/** Map to cache potentially expensive lookups in {@link #getEClassForClass(Class)}. */
/**
* Creates a self-contained copy of the given collection of {@link EObject}s. References
* between elements of the given {@link EObject}s are updated to point to their copies.
*
* @param originalEObjects
* collection of {@link EObject}s to copy.
* @return The method returns a {@link Map} that relates each original sub-element (including
* the given {@link EObject}) to the corresponding copy.
*/
public static Map<EObject, EObject>
copyToRefMap(Collection<? extends EObject> originalEObjects) {
BiMap<EObject, EObject> copyRefMap = HashBiMap.create();
// First, create all copies such that bi-references between the input object can be
// resolved in a second step: This step requires the existence of all copied elements.
for(EObject originalElement : originalEObjects) {
Map<EObject, EObject> currentCopyMap = copyToRefMap(originalElement);
copyRefMap.putAll(currentCopyMap);
}
for(EObject eObject : copyRefMap.values()) {
Collection<EReference> refToOrigList = eObject.eClass().getEAllReferences();
for(EReference refToOrig : refToOrigList) {
if(refToOrig.isContainment()) {
// Containments are handled by the copy operation itself.
continue;
}
if(refToOrig.isMany()) {
@SuppressWarnings("unchecked") EList<EObject> origList =
(EList<EObject>)eObject.eGet(refToOrig, false);
List<EObject> origCacheList = new ArrayList<>(origList);
// WARNING! WARNING! WARNING!
// We MUST add the copied elements to the list first, such that the
// reference list is not nulled by EMF in the parent element. This
// happens if the list contains only a single element: Removing this
// element empties the list and triggers a removal of the list from
// its container via the EMF notification mechanism.
origCacheList.forEach(e -> {
EObject eObj = copyRefMap.get(e);
if(eObj != null) {
origList.add(eObj);
origList.remove(e);
}
});
} else {
EObject origRef = (EObject)eObject.eGet(refToOrig);
if(origRef == null && refToOrig.getEOpposite() != null) {
// Note: For bi-references between the input elements we must use the
// inverse view of the bi-copy-map since the bi-references are nulled at
// both ends.
EObject origEObj = copyRefMap.inverse().get(eObject);
origRef = (EObject)origEObj.eGet(refToOrig);
}
EObject copyRef = copyRefMap.get(origRef);
if(copyRef != null) {
eObject.eSet(refToOrig, copyRef);
}
}
}
}
return copyRefMap;
}
/** Map to cache expensive lookups in {@link #getEClassForClass(Class)}. */
private static Map<Class<?>, EClass> clazz2EClassCache = new HashMap<Class<?>, EClass>();
/**
* Cached list of registered {@link EPackage}s (lazy initialized in
* {@link #getEClassForClass(Class)}).
*/
private static List<EPackage> ePackagesCache = null;
/**
* <p>
* Determines the {@link EClass} corresponding to a give {@code clazz} (typically the interface
......@@ -423,24 +509,30 @@ public class EcoreUtils {
* expensive.
* </p>
*/
public static EClass getEClassForClass(Class<?> clazz) {
EClass eClass = null;
public static synchronized EClass getEClassForClass(Class<?> clazz) {
// Return cached result if it exists
EClass eClass = clazz2EClassCache.get(clazz);
if(eClass != null) {
return eClass;
}
if(clazz2EClassCache.containsKey(clazz)) {
return clazz2EClassCache.get(clazz);
// If needed, initialize list of registered EPackages
if(ePackagesCache == null) {
ePackagesCache = new ArrayList<>();
Registry registry = EPackage.Registry.INSTANCE;
for(String key : new HashSet<String>(registry.keySet())) {
try {
ePackagesCache.add(registry.getEPackage(key));
} catch(Exception e) {
System.out.println("Error: EPackage for \"" + key +
"\" has not been registered (in extension point \"org.eclipse.emf.ecore.generated_package\").");
continue;
}
}
}
// Query all registered EPackages for the given clazz
Registry registry = EPackage.Registry.INSTANCE;
for(String key : new HashSet<String>(registry.keySet())) {
EPackage ePackage;
try {
ePackage = registry.getEPackage(key);
} catch(Exception e) {
System.out.println("Error: EPackage for \"" + key +
"\" has not been registered (in extension point \"org.eclipse.emf.ecore.generated_package\").");
continue;
}
for(EPackage ePackage : ePackagesCache) {
for(EClassifier eClassifier : ePackage.getEClassifiers()) {
if(eClassifier instanceof EClass && eClassifier.getInstanceClass() != null &&
clazz.isAssignableFrom(eClassifier.getInstanceClass())) {
......
......@@ -20,16 +20,6 @@
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.fortiss.ide.dev_tools.warnings.RemoveWarningsBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.fortiss.ide.dev_tools.warnings.GuidelinesChecker</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.systemfocus.tooling.codereview.builder.CodeReviewBuilder</name>
<arguments>
......
Subproject commit cdce9ac9a94655561e7dff41ece863f0a7062f4a
Subproject commit d117b3db1742a745f515d2b6c52cc9a02e57c299