diff --git a/.gitignore b/.gitignore
index 775fcc8d4..b4c043ee1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,6 +9,7 @@ tmp/
# Genenerated Files
src-gen/
+*.polyglot.META-INF
# Xtend
xtend-gen/
@@ -23,4 +24,5 @@ target/
EvaluationData
*.DS_Store
*.polyglot
-*.pom.tycho
\ No newline at end of file
+*.pom.tycho
+*.settings/
diff --git a/bundles/tools.vitruv.applications.SimuLinkAutoSAR/.classpath b/bundles/tools.vitruv.applications.SimuLinkAutoSAR/.classpath
index 412b338a8..bd2afe379 100644
--- a/bundles/tools.vitruv.applications.SimuLinkAutoSAR/.classpath
+++ b/bundles/tools.vitruv.applications.SimuLinkAutoSAR/.classpath
@@ -18,4 +18,4 @@
-
+
\ No newline at end of file
diff --git a/bundles/tools.vitruv.applications.SimuLinkAutoSAR/.settings/org.eclipse.core.resources.prefs b/bundles/tools.vitruv.applications.SimuLinkAutoSAR/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 99f26c020..000000000
--- a/bundles/tools.vitruv.applications.SimuLinkAutoSAR/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-encoding/=UTF-8
diff --git a/bundles/tools.vitruv.applications.cbs.commonalities/.classpath b/bundles/tools.vitruv.applications.cbs.commonalities/.classpath
index 6b47084e1..034a46731 100644
--- a/bundles/tools.vitruv.applications.cbs.commonalities/.classpath
+++ b/bundles/tools.vitruv.applications.cbs.commonalities/.classpath
@@ -38,4 +38,4 @@
-
+
\ No newline at end of file
diff --git a/bundles/tools.vitruv.applications.cbs.commonalities/.settings/org.eclipse.core.resources.prefs b/bundles/tools.vitruv.applications.cbs.commonalities/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 99f26c020..000000000
--- a/bundles/tools.vitruv.applications.cbs.commonalities/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-encoding/=UTF-8
diff --git a/bundles/tools.vitruv.applications.cbs.testutils/.classpath b/bundles/tools.vitruv.applications.cbs.testutils/.classpath
index 7bb4abd5f..00a29aef6 100644
--- a/bundles/tools.vitruv.applications.cbs.testutils/.classpath
+++ b/bundles/tools.vitruv.applications.cbs.testutils/.classpath
@@ -5,4 +5,4 @@
-
+
\ No newline at end of file
diff --git a/bundles/tools.vitruv.applications.cbs.testutils/.settings/org.eclipse.core.resources.prefs b/bundles/tools.vitruv.applications.cbs.testutils/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 99f26c020..000000000
--- a/bundles/tools.vitruv.applications.cbs.testutils/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-encoding/=UTF-8
diff --git a/bundles/tools.vitruv.applications.pcmjava/.classpath b/bundles/tools.vitruv.applications.pcmjava/.classpath
index 1fbe59dca..fd023a9ad 100644
--- a/bundles/tools.vitruv.applications.pcmjava/.classpath
+++ b/bundles/tools.vitruv.applications.pcmjava/.classpath
@@ -18,4 +18,4 @@
-
+
\ No newline at end of file
diff --git a/bundles/tools.vitruv.applications.pcmjava/.settings/org.eclipse.core.resources.prefs b/bundles/tools.vitruv.applications.pcmjava/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 99f26c020..000000000
--- a/bundles/tools.vitruv.applications.pcmjava/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-encoding/=UTF-8
diff --git a/bundles/tools.vitruv.applications.pcmumlclass/.settings/org.eclipse.core.resources.prefs b/bundles/tools.vitruv.applications.pcmumlclass/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 99f26c020..000000000
--- a/bundles/tools.vitruv.applications.pcmumlclass/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-encoding/=UTF-8
diff --git a/bundles/tools.vitruv.applications.testutility/.settings/org.eclipse.core.resources.prefs b/bundles/tools.vitruv.applications.testutility/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 99f26c020..000000000
--- a/bundles/tools.vitruv.applications.testutility/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-encoding/=UTF-8
diff --git a/bundles/tools.vitruv.applications.umljava/.classpath b/bundles/tools.vitruv.applications.umljava/.classpath
index 412b338a8..bd2afe379 100644
--- a/bundles/tools.vitruv.applications.umljava/.classpath
+++ b/bundles/tools.vitruv.applications.umljava/.classpath
@@ -18,4 +18,4 @@
-
+
\ No newline at end of file
diff --git a/bundles/tools.vitruv.applications.umljava/.settings/org.eclipse.core.resources.prefs b/bundles/tools.vitruv.applications.umljava/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 99f26c020..000000000
--- a/bundles/tools.vitruv.applications.umljava/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-encoding/=UTF-8
diff --git a/bundles/tools.vitruv.applications.util.temporary/.classpath b/bundles/tools.vitruv.applications.util.temporary/.classpath
index ef548cb96..30b0b3921 100644
--- a/bundles/tools.vitruv.applications.util.temporary/.classpath
+++ b/bundles/tools.vitruv.applications.util.temporary/.classpath
@@ -13,4 +13,4 @@
-
+
\ No newline at end of file
diff --git a/bundles/tools.vitruv.applications.util.temporary/.settings/org.eclipse.core.resources.prefs b/bundles/tools.vitruv.applications.util.temporary/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 99f26c020..000000000
--- a/bundles/tools.vitruv.applications.util.temporary/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-encoding/=UTF-8
diff --git a/bundles/tools.vitruv.applications.viewfilter/.classpath b/bundles/tools.vitruv.applications.viewfilter/.classpath
new file mode 100644
index 000000000..097ebb04e
--- /dev/null
+++ b/bundles/tools.vitruv.applications.viewfilter/.classpath
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/bundles/tools.vitruv.applications.viewfilter/.maven_enable_dsls-compiler b/bundles/tools.vitruv.applications.viewfilter/.maven_enable_dsls-compiler
new file mode 100644
index 000000000..e69de29bb
diff --git a/bundles/tools.vitruv.applications.viewfilter/.project b/bundles/tools.vitruv.applications.viewfilter/.project
new file mode 100644
index 000000000..95111f560
--- /dev/null
+++ b/bundles/tools.vitruv.applications.viewfilter/.project
@@ -0,0 +1,34 @@
+
+
+ tools.vitruv.views.viewfilter
+
+
+
+
+
+ org.eclipse.xtext.ui.shared.xtextBuilder
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.pde.ManifestBuilder
+
+
+
+
+ org.eclipse.pde.SchemaBuilder
+
+
+
+
+
+ org.eclipse.pde.PluginNature
+ org.eclipse.jdt.core.javanature
+ org.eclipse.xtext.ui.shared.xtextNature
+
+
diff --git a/bundles/tools.vitruv.applications.viewfilter/META-INF/MANIFEST.MF b/bundles/tools.vitruv.applications.viewfilter/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..44b193924
--- /dev/null
+++ b/bundles/tools.vitruv.applications.viewfilter/META-INF/MANIFEST.MF
@@ -0,0 +1,24 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Vitruv Viewfilter Application
+Bundle-SymbolicName: tools.vitruv.views.viewfilter;singleton:=true
+Bundle-Version: 3.0.1.qualifier
+Automatic-Module-Name: tools.vitruv.applications.viewfilter
+Bundle-RequiredExecutionEnvironment: JavaSE-17
+Eclipse-ExtensibleAPI: true
+Require-Bundle: org.eclipse.uml2.uml;visibility:=reexport,
+ org.palladiosimulator.pcm;visibility:=reexport,
+ edu.kit.ipd.sdq.activextendannotations,
+ edu.kit.ipd.sdq.commons.util.emf,
+ edu.kit.ipd.sdq.commons.util.java,
+ tools.vitruv.framework.applications,
+ tools.vitruv.dsls.reactions.runtime,
+ tools.vitruv.applications.util.temporary,
+ tools.vitruv.framework.views;bundle-version="3.0.1",
+ tools.vitruv.change.atomic,
+ tools.vitruv.change.composite
+Bundle-Vendor: vitruv.tools
+Export-Package: tools.vitruv.applications.viewfilter.util.framework,
+ tools.vitruv.applications.viewfilter.util.framework.impl,
+ tools.vitruv.applications.viewfilter.util.framework.selectors
+Import-Package: tools.vitruv.views.viewfilter.infostructure.model.infostructuremodel
diff --git a/bundles/tools.vitruv.applications.viewfilter/build.properties b/bundles/tools.vitruv.applications.viewfilter/build.properties
new file mode 100644
index 000000000..2c5b31414
--- /dev/null
+++ b/bundles/tools.vitruv.applications.viewfilter/build.properties
@@ -0,0 +1,7 @@
+source.. = src/,\
+ src-gen/,\
+ xtend-gen/
+output.. = target/classes/
+bin.includes = META-INF/,\
+ plugin.xml,\
+ .
diff --git a/bundles/tools.vitruv.applications.viewfilter/plugin.xml b/bundles/tools.vitruv.applications.viewfilter/plugin.xml
new file mode 100644
index 000000000..828835a00
--- /dev/null
+++ b/bundles/tools.vitruv.applications.viewfilter/plugin.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/application/viewfilter/informationview/internal/CountElementsTransformator.java b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/application/viewfilter/informationview/internal/CountElementsTransformator.java
new file mode 100644
index 000000000..03cf8722c
--- /dev/null
+++ b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/application/viewfilter/informationview/internal/CountElementsTransformator.java
@@ -0,0 +1,62 @@
+package tools.vitruv.application.viewfilter.informationview.internal;
+
+
+import java.util.List;
+
+import org.eclipse.emf.ecore.EObject;
+
+import tools.vitruv.applications.viewfilter.helpers.ViewFilterHelper;
+import tools.vitruv.views.viewfilter.infostructure.model.infostructuremodel.InfostructuremodelFactory;
+import tools.vitruv.views.viewfilter.infostructure.model.infostructuremodel.SingleInformation;
+
+/**
+ * Transforms models into an information. Instances of this class can be used to count elements of a certain
+ * type in a given set of models. Class uses {@link takeElementIntoAccount()} to determine whether a model-object is
+ * supposed to be counted (increase the counter by 1) or not. Class returns the determined information as
+ * an instance of {@link SingleInformation}. It therefor uses the {@link getTitle()} method to determine the title
+ * for the {@link SingleInformation}. Implementations of this abstract class therefor must implement those methods
+ * according to what is supposed to be counted.
+ */
+public abstract class CountElementsTransformator implements InformationViewTransformator {
+
+ @Override
+ public SingleInformation transform(List roots) {
+ SingleInformation createSingleInformation = InfostructuremodelFactory.eINSTANCE.createSingleInformation();
+ createSingleInformation.setTitle(getTitle());
+ int count = 0;
+
+ for (EObject root : roots) {
+ List allElements = ViewFilterHelper.convertTreeIterator2List(root.eAllContents());
+
+ for (EObject element : allElements) {
+ if (takeElementIntoAccount(element)) {
+ count++;
+ }
+ }
+ }
+
+ createSingleInformation.setValue(count);
+ return createSingleInformation;
+ }
+
+
+ /**
+ * Method determines whether a model-object is supposed to be counted (if the counter is supposed
+ * to be increased for this object). If the given object is supposed to be counted, which means it is taken into
+ * account, this method returns true. If not, it returns false.
+ *
+ * @param object The object for which the method is supposed to determine whether it is supposed to be taken into account
+ * @return true if the object is supposed to be taken into account
+ */
+ protected abstract boolean takeElementIntoAccount(EObject object);
+
+ /**
+ * Method returns the title which the {@link SingleInformation} object which this {@link CountElementsTransformator}
+ * instance returns, is supposed to have.
+ *
+ * @return The title of {@link SingleInformation} objects which this {@link CountElementsTransformator} returns
+ */
+ protected abstract String getTitle();
+
+
+}
diff --git a/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/application/viewfilter/informationview/internal/CountUmlClassesTransformator.java b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/application/viewfilter/informationview/internal/CountUmlClassesTransformator.java
new file mode 100644
index 000000000..54428ee8f
--- /dev/null
+++ b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/application/viewfilter/informationview/internal/CountUmlClassesTransformator.java
@@ -0,0 +1,27 @@
+package tools.vitruv.application.viewfilter.informationview.internal;
+
+import org.eclipse.emf.ecore.EObject;
+
+/**
+ * This transformator counts the {@link org.eclipse.uml2.Class} instances in the given models and
+ * returns the result in a {@link SingleInformation} object.
+ */
+public class CountUmlClassesTransformator extends CountElementsTransformator {
+
+ private static final String NUMBER_OF_ELEMENTS = "Number of elements";
+
+ @Override
+ protected boolean takeElementIntoAccount(EObject object) {
+ if (object instanceof org.eclipse.uml2.uml.Class) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ protected String getTitle() {
+ return NUMBER_OF_ELEMENTS;
+ }
+
+}
diff --git a/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/application/viewfilter/informationview/internal/InformationViewTransformator.java b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/application/viewfilter/informationview/internal/InformationViewTransformator.java
new file mode 100644
index 000000000..b1d285e1d
--- /dev/null
+++ b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/application/viewfilter/informationview/internal/InformationViewTransformator.java
@@ -0,0 +1,28 @@
+package tools.vitruv.application.viewfilter.informationview.internal;
+
+import java.util.List;
+
+import org.eclipse.emf.ecore.EObject;
+
+import tools.vitruv.views.viewfilter.infostructure.model.infostructuremodel.SingleInformation;
+
+/**
+ * Transforms given models into a {@link SingleInformation}. A transformation could be
+ * counting the elements of a certain type in a given model for instance.
+ * The actual transformation depends on the overwriting implementation.
+ */
+public interface InformationViewTransformator {
+
+ /**
+ * Method transforms the given models (represented by their roots) into a {@link SingleInformation}.
+ * The transformation corresponds to the calculation of the actual information, which will than
+ * be represented by the {@link SingleInformation} instance which the method returns.
+ * A transformation could be counting the elements of a certain type in a given model for instance.
+ * The actual transformation depends on the actual implementation of this method
+ *
+ * @param roots The list of root elements of the models which are supposed to be transformed
+ * @return The information which has been extracted from the given models
+ */
+ public abstract SingleInformation transform(List roots);
+
+}
diff --git a/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/helpers/ViewFilterHelper.java b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/helpers/ViewFilterHelper.java
new file mode 100644
index 000000000..9f17f2305
--- /dev/null
+++ b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/helpers/ViewFilterHelper.java
@@ -0,0 +1,23 @@
+package tools.vitruv.applications.viewfilter.helpers;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.eclipse.emf.common.util.TreeIterator;
+import org.eclipse.emf.ecore.EObject;
+
+public class ViewFilterHelper {
+
+ private ViewFilterHelper() {
+ //static helper class - should not be instantiated
+ }
+
+ public static List convertTreeIterator2List(TreeIterator content) {
+ List list = new LinkedList();
+ while(content.hasNext()) {
+ list.add(content.next());
+ }
+ return list;
+ }
+
+}
diff --git a/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/informationview/views/BasicInformationFilterView.java b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/informationview/views/BasicInformationFilterView.java
new file mode 100644
index 000000000..d074186bc
--- /dev/null
+++ b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/informationview/views/BasicInformationFilterView.java
@@ -0,0 +1,73 @@
+package tools.vitruv.applications.viewfilter.informationview.views;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EObject;
+
+import tools.vitruv.application.viewfilter.informationview.internal.InformationViewTransformator;
+import tools.vitruv.applications.viewfilter.util.framework.impl.ViewCreatingViewType;
+import tools.vitruv.applications.viewfilter.util.framework.selection.ElementViewSelection;
+import tools.vitruv.applications.viewfilter.viewbuild.ViewFilter;
+import tools.vitruv.applications.viewfilter.views.BasicFilterView;
+import tools.vitruv.change.atomic.hid.HierarchicalId;
+import tools.vitruv.framework.views.ChangeableViewSource;
+import tools.vitruv.framework.views.ModifiableViewSelection;
+import tools.vitruv.framework.views.ViewSelection;
+import tools.vitruv.framework.views.ViewSelector;
+import tools.vitruv.views.viewfilter.infostructure.model.infostructuremodel.InformationStructure;
+import tools.vitruv.views.viewfilter.infostructure.model.infostructuremodel.InfostructuremodelFactory;
+import tools.vitruv.views.viewfilter.infostructure.model.infostructuremodel.SingleInformation;
+
+public class BasicInformationFilterView extends BasicFilterView {
+
+ private final InformationViewTransformator infoTransformator;
+
+
+ public BasicInformationFilterView(ViewCreatingViewType extends ViewSelector, HierarchicalId> viewType,
+ ChangeableViewSource viewSource, ViewSelection selection, ViewFilter viewFilter,
+ InformationViewTransformator infoTransformator) {
+ super(viewType, viewSource, selection, viewFilter);
+ checkArgument(infoTransformator != null, "Transformator must be not null");
+ this.infoTransformator = infoTransformator;
+ update();
+ }
+
+
+ @Override
+ protected void updateRootAndSelectedElements(ModifiableViewSelection selection) {
+ if (selection == null) {
+ throw new NullPointerException("selection is null");
+ }
+ if (infoTransformator == null) {
+ //method has been called as part of constructor and before the info transformator could be set
+ return;
+ }
+ InformationStructure informationStructure = InfostructuremodelFactory.eINSTANCE.createInformationStructure();
+ EList singleinformationList = informationStructure.getSingleinformation();
+
+ for(EObject root : selection.getSelectableElements()) {
+ if (selection.isSelected(root)) {
+ List rootList = new ArrayList();
+ rootList.add(root);
+ SingleInformation transformResult = infoTransformator.transform(rootList);
+ if (transformResult != null) {
+ singleinformationList.add(transformResult);
+ }
+ }
+ }
+
+ List selectionList = new ArrayList();
+ selectionList.add(informationStructure);
+
+ setRootObjects(selectionList);
+
+ ElementViewSelection elementViewSelection = new ElementViewSelection(selectionList);
+ elementViewSelection.setSelected(informationStructure, true);
+ setSelection(elementViewSelection);
+ }
+
+}
diff --git a/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/informationview/views/CountUmlClassesView.java b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/informationview/views/CountUmlClassesView.java
new file mode 100644
index 000000000..f2e51f41f
--- /dev/null
+++ b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/informationview/views/CountUmlClassesView.java
@@ -0,0 +1,32 @@
+package tools.vitruv.applications.viewfilter.informationview.views;
+
+import tools.vitruv.application.viewfilter.informationview.internal.CountUmlClassesTransformator;
+import tools.vitruv.applications.viewfilter.util.framework.impl.ViewCreatingViewType;
+import tools.vitruv.applications.viewfilter.viewbuild.ViewFilter;
+import tools.vitruv.change.atomic.hid.HierarchicalId;
+import tools.vitruv.framework.views.ChangeableViewSource;
+import tools.vitruv.framework.views.ViewSelection;
+import tools.vitruv.framework.views.ViewSelector;
+
+/**
+ * Utility class for creating a {@link InformationView} which counts all uml2.Class objects
+ * in a model. Used a given {@link ViewFilter} object to filter the model for objects which are
+ * supposed to be taken into account
+ */
+public class CountUmlClassesView extends BasicInformationFilterView {
+
+ /**
+ * Creates an {@link InformationView} object which counts all uml2.Class objects in a model
+ * and displays the result.
+ *
+ * @param viewType The viewType for this {@link InformationView} object
+ * @param viewSource The viewSource for this {@link InformationView} object
+ * @param selection The selection for this {@link InformationView} object
+ * @param viewFilter The viewFilter used to filter objects which are supposed to displayed in the view.
+ */
+ public CountUmlClassesView(ViewCreatingViewType extends ViewSelector, HierarchicalId> viewType,
+ ChangeableViewSource viewSource, ViewSelection selection, ViewFilter viewFilter) {
+ super(viewType, viewSource, selection, viewFilter, new CountUmlClassesTransformator());
+
+ }
+}
diff --git a/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/util/framework/FilterSupportingViewTypeFactory.java b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/util/framework/FilterSupportingViewTypeFactory.java
new file mode 100644
index 000000000..4feb7328c
--- /dev/null
+++ b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/util/framework/FilterSupportingViewTypeFactory.java
@@ -0,0 +1,19 @@
+package tools.vitruv.applications.viewfilter.util.framework;
+
+import tools.vitruv.applications.viewfilter.util.framework.impl.CountUmlClassesIdentityMappingViewType;
+import tools.vitruv.applications.viewfilter.util.framework.impl.FilterSupportingIdentityMappingViewType;
+import tools.vitruv.framework.views.ViewSelector;
+import tools.vitruv.framework.views.ViewType;
+
+public class FilterSupportingViewTypeFactory {
+
+ public static ViewType extends ViewSelector> createFilterSupportingIdentityMappingViewType(String name) {
+ return new FilterSupportingIdentityMappingViewType(name);
+
+ }
+
+
+ public static ViewType extends ViewSelector> createCountUmlClassesInformationFilterViewViewType(String name) {
+ return new CountUmlClassesIdentityMappingViewType(name);
+ }
+}
diff --git a/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/util/framework/impl/AbstractViewType.xtend b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/util/framework/impl/AbstractViewType.xtend
new file mode 100644
index 000000000..3d464ed06
--- /dev/null
+++ b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/util/framework/impl/AbstractViewType.xtend
@@ -0,0 +1,16 @@
+package tools.vitruv.applications.viewfilter.util.framework.impl
+
+import org.eclipse.xtend.lib.annotations.Accessors
+import tools.vitruv.framework.views.ViewSelector
+
+import static com.google.common.base.Preconditions.checkArgument
+
+abstract package class AbstractViewType implements ViewCreatingViewType {
+ @Accessors(PUBLIC_GETTER)
+ val String name
+
+ new(String name) {
+ checkArgument(name !== null, "view type name must not be null")
+ this.name = name
+ }
+}
diff --git a/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/util/framework/impl/CountUmlClassesIdentityMappingViewType.java b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/util/framework/impl/CountUmlClassesIdentityMappingViewType.java
new file mode 100644
index 000000000..ed86d971e
--- /dev/null
+++ b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/util/framework/impl/CountUmlClassesIdentityMappingViewType.java
@@ -0,0 +1,25 @@
+package tools.vitruv.applications.viewfilter.util.framework.impl;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+import tools.vitruv.applications.viewfilter.informationview.views.BasicInformationFilterView;
+import tools.vitruv.applications.viewfilter.informationview.views.CountUmlClassesView;
+import tools.vitruv.applications.viewfilter.util.framework.selectors.FilterSupportingViewElementSelectorImpl;
+import tools.vitruv.change.atomic.hid.HierarchicalId;
+
+public class CountUmlClassesIdentityMappingViewType extends FilterSupportingIdentityMappingViewType {
+
+ public CountUmlClassesIdentityMappingViewType(String name) {
+ super(name);
+ }
+
+
+ @Override
+ public ModifiableView createView(FilterSupportingViewElementSelectorImpl selector) {
+ checkArgument(selector.getViewType() == this, "cannot create view with selector for different view type");
+ BasicInformationFilterView view = new CountUmlClassesView(selector.getViewType(), selector.getViewSource(), selector.getSelection(), selector.getViewFilter());
+ return view;
+ }
+
+}
+
\ No newline at end of file
diff --git a/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/util/framework/impl/FilterSupportingIdentityMappingViewType.java b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/util/framework/impl/FilterSupportingIdentityMappingViewType.java
new file mode 100644
index 000000000..f91cda6b2
--- /dev/null
+++ b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/util/framework/impl/FilterSupportingIdentityMappingViewType.java
@@ -0,0 +1,111 @@
+package tools.vitruv.applications.viewfilter.util.framework.impl;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static edu.kit.ipd.sdq.commons.util.org.eclipse.emf.ecore.resource.ResourceSetUtil.withGlobalFactories;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Stream;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+
+import edu.kit.ipd.sdq.commons.util.org.eclipse.emf.ecore.resource.ResourceCopier;
+import tools.vitruv.applications.viewfilter.util.framework.selectors.FilterSupportingViewElementSelectorImpl;
+import tools.vitruv.applications.viewfilter.views.BasicFilterView;
+import tools.vitruv.applications.viewfilter.views.FilterChangeRecordingView;
+import tools.vitruv.applications.viewfilter.views.FilterableView;
+import tools.vitruv.change.atomic.hid.HierarchicalId;
+import tools.vitruv.change.atomic.uuid.Uuid;
+import tools.vitruv.change.atomic.uuid.UuidResolver;
+import tools.vitruv.change.composite.description.VitruviusChange;
+import tools.vitruv.change.composite.description.VitruviusChangeResolver;
+import tools.vitruv.framework.views.ChangeableViewSource;
+import tools.vitruv.framework.views.ViewSelection;
+
+
+/**
+ * A view type that allows creating views based on a basic element-wise
+ * selection mechanism and a filter-function. The filter-function can be used for
+ * selecting single objects in a model.
+ */
+public class FilterSupportingIdentityMappingViewType extends AbstractViewType, HierarchicalId> {
+
+ public FilterSupportingIdentityMappingViewType(String name) {
+ super(name);
+ }
+
+
+
+ @Override
+ public FilterSupportingViewElementSelectorImpl createSelector(ChangeableViewSource viewSource) {
+ return new FilterSupportingViewElementSelectorImpl<>(this, viewSource,
+ viewSource.getViewSourceModels().stream().map(resource -> {
+ if (!resource.getContents().isEmpty() && ResourceCopier.requiresFullCopy(resource)) {
+ // Some resources (like UML) can only be copied as a whole, so no option to select
+ // specific root elements
+ return Stream.of(resource.getContents().get(0));
+ }
+ return resource.getContents().stream();
+ }).flatMap(Function.identity()).filter(it -> it != null).toList());
+ }
+
+
+ @Override
+ public ModifiableView createView(FilterSupportingViewElementSelectorImpl selector) {
+ checkArgument(selector.getViewType() == this, "cannot create view with selector for different view type");
+ return new BasicFilterView(selector.getViewType(), selector.getViewSource(), selector.getSelection(), selector.getViewFilter());
+ }
+
+ @Override
+ public void updateView(ModifiableView view) {
+ view.modifyContents((viewResourceSet) -> {
+ viewResourceSet.getResources().forEach(Resource::unload);
+ viewResourceSet.getResources().clear();
+ createViewResources(view, viewResourceSet);
+ });
+ }
+
+
+ @Override
+ public void commitViewChanges(ModifiableView view, VitruviusChange viewChange) {
+ VitruviusChange unresolvedViewResourceChanges = viewChange;
+
+ if (view instanceof FilterableView filterableView) {
+ //in case the changes have been performed on a FilteredView, the viewChange references the filterResourceSet
+ //transform the viewChanges on the ViewResourceSet first..
+ ResourceSet unfilteredResourceSet = ((FilterChangeRecordingView) view).getNonFilteredViewResourceSet();
+ ResourceSet filteredResourceSetInOriginalState = ((FilterChangeRecordingView) view).backwardExecuteChangesAndReturnResourceSet();
+ VitruviusChangeResolver viewResourceIdChangeResolver =
+ VitruviusChangeResolver.forHierarchicalIdsAndFilteredModel(unfilteredResourceSet, filteredResourceSetInOriginalState, filterableView.getMapCopy2OriginalObject());
+ VitruviusChange viewResourceResolvedChange = viewResourceIdChangeResolver.resolveAndApply(viewChange);
+ VitruviusChangeResolver changeResolver = VitruviusChangeResolver.forHierarchicalIds(unfilteredResourceSet);
+ unresolvedViewResourceChanges = changeResolver.assignIds(viewResourceResolvedChange);
+ }
+
+ ResourceSet viewSourceCopyResourceSet = withGlobalFactories(new ResourceSetImpl());
+ VitruviusChangeResolver idChangeResolver = VitruviusChangeResolver.forHierarchicalIds(viewSourceCopyResourceSet);
+ UuidResolver viewSourceCopyUuidResolver = UuidResolver.create(viewSourceCopyResourceSet);
+ VitruviusChangeResolver uuidChangeResolver = VitruviusChangeResolver.forUuids(viewSourceCopyUuidResolver);
+ Map mapping = createViewResources(view, viewSourceCopyResourceSet);
+ view.getViewSource().getUuidResolver().resolveResources(mapping, viewSourceCopyUuidResolver);
+
+ VitruviusChange resolvedChange = idChangeResolver.resolveAndApply(unresolvedViewResourceChanges);
+ VitruviusChange unresolvedChanges = uuidChangeResolver.assignIds(resolvedChange);
+ view.getViewSource().propagateChange(unresolvedChanges);
+ }
+
+ private Map createViewResources(ModifiableView view, ResourceSet viewResourceSet) {
+ Collection viewSources = view.getViewSource().getViewSourceModels();
+ ViewSelection selection = ((FilterableView) view).getPreFilterSelection();
+ List resourcesWithSelectedElements = viewSources.stream()
+ .filter(resource -> resource.getContents().stream().anyMatch(selection::isViewObjectSelected)).toList();
+ return ResourceCopier.copyViewSourceResources(resourcesWithSelectedElements, viewResourceSet,
+ selection::isViewObjectSelected);
+ }
+
+}
diff --git a/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/util/framework/impl/ModifiableView.xtend b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/util/framework/impl/ModifiableView.xtend
new file mode 100644
index 000000000..55fd5fe0a
--- /dev/null
+++ b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/util/framework/impl/ModifiableView.xtend
@@ -0,0 +1,14 @@
+package tools.vitruv.applications.viewfilter.util.framework.impl
+
+import org.eclipse.emf.ecore.resource.ResourceSet
+import tools.vitruv.framework.views.ChangeableViewSource
+import tools.vitruv.framework.views.View
+
+/**
+ * A view whose contents can be modified, in particular by a view type implementation.
+ */
+interface ModifiableView extends View {
+ def void modifyContents((ResourceSet)=>void modificationFunction);
+
+ def ChangeableViewSource getViewSource()
+}
\ No newline at end of file
diff --git a/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/util/framework/impl/ViewCreatingViewType.java b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/util/framework/impl/ViewCreatingViewType.java
new file mode 100644
index 000000000..f92d8197d
--- /dev/null
+++ b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/util/framework/impl/ViewCreatingViewType.java
@@ -0,0 +1,45 @@
+package tools.vitruv.applications.viewfilter.util.framework.impl;
+
+import tools.vitruv.change.composite.description.VitruviusChange;
+import tools.vitruv.framework.views.ChangeableViewSource;
+import tools.vitruv.framework.views.ViewSelector;
+import tools.vitruv.framework.views.ViewType;
+
+/**
+ * A specific view type that is able to create and update views. This is not its
+ * public interface but only for internal usage by views and their selectors.
+ *
+ * @param the type of view selector this view type uses.
+ * @param the type of Id the changes to commit must have.
+ */
+public interface ViewCreatingViewType extends ViewType {
+ /**
+ * Creates a view for the given {@link ViewSelector}. The selector must have
+ * been created by calling the {@link #createSelector} method of the same
+ * {@link ViewCreatingViewType}.
+ *
+ * @param selector the {@link ViewSelector} to create a view for
+ * @return a {@link ModifiableView} with elements according to the selector.
+ */
+ ModifiableView createView(S selector);
+
+ /**
+ * Updates a view that is created from this view type to ensure it is consistent
+ * with the virtual model.
+ *
+ * @param view is the view to be updated.
+ */
+ void updateView(ModifiableView view);
+
+ /**
+ * Commits the changes made to the view and its containing elements to the
+ * underlying {@link ChangeableViewSource}. Since view elements do not
+ * necessarily correspond to elements of the underlying view source, the view
+ * type is responsible for transforming the given {@link VitruviusChange} such
+ * that the underlying view source can process it.
+ *
+ * @param view is the modified view.
+ * @param viewChange are the changes performed to the view.
+ */
+ void commitViewChanges(ModifiableView view, VitruviusChange viewChange);
+}
\ No newline at end of file
diff --git a/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/util/framework/selection/AbstractViewSelection.java b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/util/framework/selection/AbstractViewSelection.java
new file mode 100644
index 000000000..fb71c04d7
--- /dev/null
+++ b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/util/framework/selection/AbstractViewSelection.java
@@ -0,0 +1,55 @@
+package tools.vitruv.applications.viewfilter.util.framework.selection;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.emf.ecore.EObject;
+
+import tools.vitruv.framework.views.ModifiableViewSelection;
+
+public abstract class AbstractViewSelection implements ModifiableViewSelection {
+ final Map elementsSelection = new HashMap<>();
+
+ public AbstractViewSelection(Collection selectableElements) {
+ selectableElements.forEach(object -> this.elementsSelection
+ .put(checkNotNull(object, "element to select must not be null"), false));
+ }
+
+ public AbstractViewSelection(ModifiableViewSelection sourceViewSelection) {
+ this(sourceViewSelection.getSelectableElements());
+ for (EObject selectableElement : sourceViewSelection.getSelectableElements()) {
+ setSelected(selectableElement, sourceViewSelection.isSelected(selectableElement));
+ }
+ }
+
+ private void checkIsSelectable(EObject eObject) {
+ checkState(isSelectable(eObject), "given object %s must be contained in the selector elements", eObject);
+ }
+
+ @Override
+ public boolean isSelected(EObject eObject) {
+ return elementsSelection.getOrDefault(eObject, false);
+ }
+
+ @Override
+ public boolean isSelectable(EObject eObject) {
+ return elementsSelection.keySet().contains(eObject);
+ }
+
+ @Override
+ public Collection getSelectableElements() {
+ return Collections.unmodifiableSet(elementsSelection.keySet());
+ }
+
+ @Override
+ public void setSelected(EObject eObject, boolean selected) {
+ checkIsSelectable(eObject);
+ elementsSelection.put(eObject, selected);
+ }
+
+}
\ No newline at end of file
diff --git a/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/util/framework/selection/ElementViewSelection.java b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/util/framework/selection/ElementViewSelection.java
new file mode 100644
index 000000000..0678dc5a3
--- /dev/null
+++ b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/util/framework/selection/ElementViewSelection.java
@@ -0,0 +1,24 @@
+package tools.vitruv.applications.viewfilter.util.framework.selection;
+
+import java.util.Collection;
+
+import org.eclipse.emf.ecore.EObject;
+
+import tools.vitruv.framework.views.ModifiableViewSelection;
+
+public class ElementViewSelection extends AbstractViewSelection {
+
+ public ElementViewSelection(Collection selectableElements) {
+ super(selectableElements);
+ }
+
+ public ElementViewSelection(ModifiableViewSelection sourceViewSelection) {
+ super(sourceViewSelection);
+ }
+
+ @Override
+ public boolean isViewObjectSelected(EObject eObject) {
+ return isSelected(eObject);
+ }
+
+}
\ No newline at end of file
diff --git a/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/util/framework/selectors/DirectViewElementSelector.xtend b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/util/framework/selectors/DirectViewElementSelector.xtend
new file mode 100644
index 000000000..5b5f84c88
--- /dev/null
+++ b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/util/framework/selectors/DirectViewElementSelector.xtend
@@ -0,0 +1,74 @@
+package tools.vitruv.applications.viewfilter.util.framework.selectors
+
+import java.util.Collection
+import org.eclipse.emf.ecore.EObject
+import org.eclipse.xtend.lib.annotations.Accessors
+import org.eclipse.xtend.lib.annotations.Delegate
+import tools.vitruv.framework.views.ChangeableViewSource
+import tools.vitruv.framework.views.ModifiableViewSelection
+import tools.vitruv.framework.views.ViewSelector
+import tools.vitruv.framework.views.ViewType
+import tools.vitruv.applications.viewfilter.util.framework.selection.ElementViewSelection
+
+import tools.vitruv.applications.viewfilter.util.framework.impl.ViewCreatingViewType
+import static com.google.common.base.Preconditions.checkArgument
+import static com.google.common.base.Preconditions.checkState
+
+/**
+ * A view selector that provides a selection of elements being view objects at
+ * the same time. This means, there is no indirection between selected elements
+ * and view elements (such as selecting types but providing instances in the view),
+ * but a selection is performed on the view elements themselves.
+ */
+class DirectViewElementSelector implements ViewSelector {
+ @Delegate
+ val ModifiableViewSelection viewSelection
+
+ @Accessors(PUBLIC_GETTER)
+ val ChangeableViewSource viewSource
+
+ @Accessors(PUBLIC_GETTER)
+ val ViewCreatingViewType, Id> viewType
+
+ /**
+ * Creates a new selector based on the given collection of selectable elements
+ * for the given {@link ViewType} and {@link ChangeableViewSource}. All arguments
+ * must not be null
.
+ * All elements will be unselected after creation.
+ *
+ * @param viewType - the {@link ViewType} to create a view for when
+ * calling {@link createView}
+ * @param viewSource - the {@link ChangeableViewSource} to create a view
+ * from
+ * @param selectableElements - the elements to select from to be used by the
+ * {@link ViewType} when creating a view
+ */
+ new(ViewCreatingViewType, Id> viewType, ChangeableViewSource viewSource,
+ Collection selectableElements) {
+ checkArgument(selectableElements !== null, "selectable elements must not be null")
+ checkArgument(viewType !== null, "view type must not be null")
+ checkArgument(viewSource !== null, "view source must not be null")
+ this.viewType = viewType
+ this.viewSource = viewSource
+ this.viewSelection = new ElementViewSelection(selectableElements)
+ }
+
+ override createView() {
+ checkState(isValid(), "the current selection is invalid, thus a view cannot be created")
+ return viewType.createView(this)
+ }
+
+ /**
+ * {@link DirectViewElementSelector}s are always valid.
+ */
+ override boolean isValid() {
+ // A basic selection is always valid. In particular, it does not require at least one element to be selected
+ // because it must be possible to create empty views upon creation of a (virtual) model.
+ true
+ }
+
+ override getSelection() {
+ return new ElementViewSelection(viewSelection)
+ }
+
+}
diff --git a/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/util/framework/selectors/FilterSupportingViewElementSelector.java b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/util/framework/selectors/FilterSupportingViewElementSelector.java
new file mode 100644
index 000000000..7fd424aac
--- /dev/null
+++ b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/util/framework/selectors/FilterSupportingViewElementSelector.java
@@ -0,0 +1,56 @@
+package tools.vitruv.applications.viewfilter.util.framework.selectors;
+
+import java.util.Collection;
+import java.util.function.Function;
+
+import org.eclipse.emf.ecore.EObject;
+
+import tools.vitruv.framework.views.ViewSelector;
+
+/**
+ * Instances of this interface provide various methods for filtering. Filtering is not only
+ * restricted on the model-roots. Instead, the selector filters individual elements of the
+ * model. The model contained in a constructed {@link View} might not contain objects
+ * which equal to the original objects in the original model.
+ *
+ * Example:
+ *
+ * Root
+ * - Element_1
+ * - Element_2
+ * - Child_Element_1
+ *
+ * The selector still does only select the model-root itself, but it can further filter
+ * the model-elements, like Element_1 and Child_Element_1. So one could use an instance
+ * of {@link FilterSupportingViewElementSelector} to select Root and than further filter
+ * for Element_1 and Child_Element_1. If the {@link FilterSupportingViewElementSelector}
+ * is then used to create a corresponding {@link View}, this {@link View} will contain
+ * a Model-Root and only Element_1 and Child_Element_1 attached to the Model-Root.
+ */
+public interface FilterSupportingViewElementSelector extends ViewSelector {
+
+ /**
+ * Method deselects all models which are not of one of the given rootTypes.
+ * Obviously, the method will remove whole models and not only certain elements
+ * of one model, as all elements of a model are from the same root type.
+ *
+ * @param rootTypes The rootTypes which are supposed to be removed
+ */
+ void deselectElementsExceptForRootType(Collection> rootTypes);
+
+ /**
+ * Filters all Model-Elements by the given function. Notice: This method won't
+ * change the selection, but only modifies the filter used to filter Model-Elements.
+ *
+ * @param filter The function which is supposed to be used for filtering
+ */
+ void filterModelElementsByLambda(Function filter);
+
+ /**
+ * Method filters out all attributes of {@link org.eclipse.uml2.uml.Class} instances.
+ * Won't change instances of other types.
+ */
+ void removeOwnedAttributesFromUmlClasses();
+
+
+}
diff --git a/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/util/framework/selectors/FilterSupportingViewElementSelectorImpl.java b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/util/framework/selectors/FilterSupportingViewElementSelectorImpl.java
new file mode 100644
index 000000000..ac17e9b8c
--- /dev/null
+++ b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/util/framework/selectors/FilterSupportingViewElementSelectorImpl.java
@@ -0,0 +1,110 @@
+package tools.vitruv.applications.viewfilter.util.framework.selectors;
+
+import java.util.Collection;
+import java.util.function.Function;
+
+import org.eclipse.emf.ecore.EObject;
+
+import com.google.common.base.Preconditions;
+
+import tools.vitruv.applications.viewfilter.util.framework.impl.ViewCreatingViewType;
+import tools.vitruv.applications.viewfilter.util.framework.selection.ElementViewSelection;
+import tools.vitruv.applications.viewfilter.viewbuild.ViewFilter;
+import tools.vitruv.applications.viewfilter.viewbuild.ViewFilterImpl;
+import tools.vitruv.applications.viewfilter.viewbuild.ViewFilterImpl.ViewFilterBuilder;
+import tools.vitruv.framework.views.ChangeableViewSource;
+import tools.vitruv.framework.views.ModifiableViewSelection;
+import tools.vitruv.framework.views.View;
+import tools.vitruv.framework.views.ViewSelection;
+
+public class FilterSupportingViewElementSelectorImpl implements FilterSupportingViewElementSelector {
+
+ private ModifiableViewSelection viewSelection;
+
+ private final ChangeableViewSource viewSource;
+
+ private final ViewCreatingViewType, Id> viewType;
+
+ private ViewFilterBuilder viewFilterBuilder;
+
+ private ViewFilterImpl viewFilter;
+
+ private View createdView;
+
+ public FilterSupportingViewElementSelectorImpl(
+ ViewCreatingViewType, Id> viewType,
+ ChangeableViewSource viewSource, Collection selectableElements) {
+ Preconditions.checkArgument((selectableElements != null), "selectable elements must not be null");
+ Preconditions.checkArgument((viewType != null), "view type must not be null");
+ Preconditions.checkArgument((viewSource != null), "view source must not be null");
+ this.viewType = viewType;
+ this.viewSource = viewSource;
+ this.viewSelection = new ElementViewSelection(selectableElements);
+ selectableElements.forEach(element -> viewSelection.setSelected(element, true));
+ viewFilterBuilder = new ViewFilterBuilder();
+ }
+
+ @Override
+ public View createView() {
+ viewFilter = viewFilterBuilder.build();
+ Preconditions.checkState(this.isValid(), "the current selection is invalid, thus a view cannot be created");
+ createdView = viewType.createView(this);
+ return createdView;
+ }
+
+ public void deselectElementsExceptForRootType(Collection> rootTypes) {
+ getSelectableElements().stream().filter(element -> (isViewObjectSelected(element) && !(rootTypes.stream().anyMatch(it -> it.isInstance(element)))))
+ .forEach(element -> setSelected(element, false));
+ }
+
+ public void filterModelElementsByLambda(Function filter) {
+ viewFilterBuilder.filterByLambda(filter);
+ }
+
+ public void removeOwnedAttributesFromUmlClasses() {
+ viewFilterBuilder.removeOwnedUmlAttributes();
+ }
+
+ @Override
+ public boolean isValid() {
+ return true;
+ }
+
+ @Override
+ public ViewSelection getSelection() {
+ return new ElementViewSelection(this.viewSelection);
+ }
+
+ public Collection getSelectableElements() {
+ return this.viewSelection.getSelectableElements();
+ }
+
+ public boolean isSelectable(final EObject eObject) {
+ return this.viewSelection.isSelectable(eObject);
+ }
+
+ public boolean isSelected(final EObject eObject) {
+ return this.viewSelection.isSelected(eObject);
+ }
+
+ public boolean isViewObjectSelected(final EObject eObject) {
+ return this.viewSelection.isViewObjectSelected(eObject);
+ }
+
+ public void setSelected(final EObject eObject, final boolean selected) {
+ this.viewSelection.setSelected(eObject, selected);
+ }
+
+ public ChangeableViewSource getViewSource() {
+ return this.viewSource;
+ }
+
+ public ViewCreatingViewType, Id> getViewType() {
+ return this.viewType;
+ }
+
+ public ViewFilter getViewFilter() {
+ return viewFilter;
+ }
+
+}
diff --git a/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/viewbuild/ViewFilter.java b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/viewbuild/ViewFilter.java
new file mode 100644
index 000000000..968540132
--- /dev/null
+++ b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/viewbuild/ViewFilter.java
@@ -0,0 +1,44 @@
+package tools.vitruv.applications.viewfilter.viewbuild;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.emf.ecore.EObject;
+
+/**
+ * A ViewFilter filters the model objects contained in a {@link View}. What kind of
+ * elements will be filtered by an instance, depends on the implementation of the interface.
+ * When {@link filterElements} is executed, the given models are filtered and the results
+ * are returned.
+ * It also depends on the implementation, how the Filter deals with objects, if their parent
+ * has been filtered out. One possibility is, that the filter creates a stub-model-root
+ * and mounts all filtered elements under the stub-model-root.
+ */
+public interface ViewFilter {
+
+ /**
+ * This method executes the actual filter mechanism on the models which belong
+ * to the given model roots. It depends on the implementation, how the method deals
+ * with objects, if their parent
+ * has been filtered out. One possibility is, that the filter creates a stub-model-root
+ * and mounts all filtered elements under the stub-model-root.
+ * @param roots The roots of the models that are supposed to be filtered
+ * @return The remaining model objects after all other objects have been filtered out according
+ * to the used filter.
+ */
+ Set filterElements(Collection roots);
+
+
+ /**
+ * Returns a {@link Map} which can be used to map the copied {@link EObject} in a Filter-Model
+ * to its original {@link EObject}. The map can only be used to map {@link EObject}s which have
+ * been created by the same {@link ViewFilter} instance on which this method is then called.
+ *
+ * @return A map which maps the copied {@link EObject} on its original {@link EObject} in the unfiltered model
+ */
+ public Map getMapCopy2Original();
+
+
+
+}
diff --git a/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/viewbuild/ViewFilterImpl.java b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/viewbuild/ViewFilterImpl.java
new file mode 100644
index 000000000..711d03526
--- /dev/null
+++ b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/viewbuild/ViewFilterImpl.java
@@ -0,0 +1,199 @@
+package tools.vitruv.applications.viewfilter.viewbuild;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Function;
+
+import org.eclipse.emf.common.util.TreeIterator;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.net4j.util.ImplementationError;
+import org.eclipse.uml2.uml.Model;
+import org.eclipse.uml2.uml.Type;
+import org.eclipse.uml2.uml.UMLFactory;
+import org.palladiosimulator.pcm.repository.DataType;
+import org.palladiosimulator.pcm.repository.Repository;
+import org.palladiosimulator.pcm.repository.RepositoryComponent;
+import org.palladiosimulator.pcm.repository.RepositoryFactory;
+
+import tools.vitruv.applications.viewfilter.helpers.ViewFilterHelper;
+
+public class ViewFilterImpl implements ViewFilter {
+
+ private Set rootListForView;
+
+ private final ViewFilterBuilder builder;
+
+ private Map mapCopy2Original;
+
+ private ViewFilterImpl(ViewFilterBuilder viewFilterBuilder) {
+ builder = viewFilterBuilder;
+ }
+
+
+ public Set filterElements(Collection roots) {
+ mapCopy2Original = new HashMap();
+ //Collection rootsCopy = EcoreUtil.copyAll(roots);
+ rootListForView = new HashSet();
+
+ copyElementsOfRootTypeToSelectionByLambda(roots);
+ removeOwnedAttributesFromUmlClasses();
+ return rootListForView;
+ }
+
+
+ private void copyElementsOfRootTypeToSelectionByLambda(Collection roots) {
+ if (!builder.filterByLambdaActive) {
+ return;
+ }
+ for (EObject root : roots) {
+ filterAllContents(root, builder.filter, rootListForView);
+ }
+ }
+
+
+ private void removeOwnedAttributesFromUmlClasses() {
+ if (!builder.removeAttributesActive) {
+ return;
+ }
+ for (EObject root : rootListForView) {
+ TreeIterator content = root.eAllContents();
+ List contentList = ViewFilterHelper.convertTreeIterator2List(content);
+ for (EObject object : contentList) {
+ if (object instanceof org.eclipse.uml2.uml.Class) {
+ org.eclipse.uml2.uml.Class classifierObject = (org.eclipse.uml2.uml.Class) object;
+ classifierObject.getOwnedAttributes().removeAll(classifierObject.getOwnedAttributes());
+ }
+ }
+ }
+ }
+
+
+ private void filterAllContents(EObject root, Function filter, Set rootListForView) {
+ EObject filteredModelRootStub = null;
+ Iterator contentIterator = root.eAllContents();
+ while(contentIterator.hasNext()) {
+ EObject contentElement = contentIterator.next();
+ if (filter.apply(contentElement)) {
+ filteredModelRootStub = createAndRegisterModelRootIfNotExistent(filteredModelRootStub, root);
+ EObject copyOfContentElement = copyEObject(contentElement);
+ attachElementToRoot(filteredModelRootStub, copyOfContentElement);
+ }
+ }
+ }
+
+
+ private void attachElementToRoot(EObject root, EObject object) {
+ if (root instanceof Model) {
+ attachElementToRootUml((Model) root, object);
+ mapCopy2Original.get(object);
+ } else if (root instanceof Repository) {
+ attachElementToRootPcm((Repository) root, object);
+ } else {
+ throw new RuntimeException("Not implemented yet! Undefined type: " + object.eClass());
+ }
+ }
+
+
+ private void attachElementToRootUml(Model root, EObject object) {
+ if (object instanceof Type) {
+ root.getOwnedTypes().add((Type) object);
+ } else {
+ throw new RuntimeException("Warning: Undefined type: " + object.eClass());
+ }
+ }
+
+ private EObject copyEObject(EObject object) {
+ EObject copyOfContentElement = EcoreUtil.copy(object);
+ getMapCopy2Original().put(copyOfContentElement, object);
+ return copyOfContentElement;
+ }
+
+
+
+ private void attachElementToRootPcm(Repository root, EObject object) {
+ if (object instanceof RepositoryComponent) {
+ root.getComponents__Repository().add((RepositoryComponent) object);
+ } else if (object instanceof DataType) {
+ root.getDataTypes__Repository().add((DataType) object);
+ } else {
+ throw new RuntimeException("Warning: Undefined type: " + object.eClass());
+ }
+ }
+
+ private EObject createAndRegisterModelRootIfNotExistent(EObject filteredRoot, EObject root) {
+ if (filteredRoot == null) {
+ EObject modelRoot = createFilteredModelRootIfNotExistent(filteredRoot, root);
+ //Map root stub to original root
+ mapCopy2Original.put(modelRoot, root);
+ rootListForView.add(modelRoot);
+ return modelRoot;
+ } else {
+ return filteredRoot;
+ }
+
+ }
+
+
+ private EObject createFilteredModelRootIfNotExistent(EObject filteredRoot, EObject root) {
+ if (root instanceof Model) {
+ Model modelCopy = UMLFactory.eINSTANCE.createModel();
+ modelCopy.setName(((Model) root).getName());
+ return modelCopy;
+ } else if (root instanceof Repository) {
+ Repository repositoryCopy = RepositoryFactory.eINSTANCE.createRepository();
+ repositoryCopy.setEntityName(((Repository) root).getEntityName());
+ return repositoryCopy;
+ }
+ else {
+ throw new RuntimeException("The type " + root.getClass() + " is not supported!");
+ }
+ }
+
+
+ public Map getMapCopy2Original() {
+ return mapCopy2Original;
+ }
+
+
+ //---------------------------------
+ /**
+ * Builder for ViewFilterImpl
+ */
+ public static class ViewFilterBuilder {
+
+ //optional parameters
+ private Boolean filterByLambdaActive = false;
+
+ private Boolean removeAttributesActive = false;
+
+ private Function filter;
+
+
+ public ViewFilterBuilder() {
+ }
+
+ public ViewFilterBuilder filterByLambda(Function filter) {
+ this.filterByLambdaActive = true;
+ this.filter = filter;
+ return this;
+ }
+
+ public ViewFilterBuilder removeOwnedUmlAttributes() {
+ this.removeAttributesActive = true;
+ return this;
+ }
+
+ public ViewFilterImpl build() {
+ return new ViewFilterImpl(this);
+ }
+
+
+ }
+
+}
diff --git a/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/views/AbstractBasicView.xtend b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/views/AbstractBasicView.xtend
new file mode 100644
index 000000000..2e26e4f6b
--- /dev/null
+++ b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/views/AbstractBasicView.xtend
@@ -0,0 +1,153 @@
+package tools.vitruv.applications.viewfilter.views;
+
+import org.eclipse.emf.common.notify.Notification
+import org.eclipse.emf.common.notify.Notifier
+import org.eclipse.emf.common.notify.impl.AdapterImpl
+import org.eclipse.emf.common.util.URI
+import org.eclipse.emf.ecore.EObject
+import org.eclipse.emf.ecore.resource.Resource
+import org.eclipse.emf.ecore.resource.ResourceSet
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl
+import org.eclipse.xtend.lib.annotations.Accessors
+import tools.vitruv.change.atomic.hid.HierarchicalId
+import tools.vitruv.change.atomic.uuid.Uuid
+import tools.vitruv.change.composite.description.PropagatedChange
+import tools.vitruv.change.composite.description.VitruviusChange
+import tools.vitruv.change.composite.propagation.ChangePropagationListener
+import tools.vitruv.framework.views.ChangeableViewSource
+import tools.vitruv.framework.views.ViewSelection
+import tools.vitruv.framework.views.ViewSelector
+import tools.vitruv.framework.views.changederivation.StateBasedChangeResolutionStrategy
+
+import static com.google.common.base.Preconditions.checkArgument
+import static com.google.common.base.Preconditions.checkState
+
+import static extension edu.kit.ipd.sdq.commons.util.org.eclipse.emf.ecore.resource.ResourceSetUtil.withGlobalFactories
+import tools.vitruv.applications.viewfilter.util.framework.impl.ModifiableView
+import tools.vitruv.applications.viewfilter.util.framework.impl.ViewCreatingViewType
+
+public abstract class AbstractBasicView implements ChangesetDeterminableView, ModifiableView, ChangePropagationListener {
+ @Accessors(PUBLIC_GETTER, PROTECTED_SETTER)
+ var ViewSelection selection
+ @Accessors(PUBLIC_GETTER, PROTECTED_SETTER)
+ var ViewCreatingViewType extends ViewSelector, HierarchicalId> viewType
+ @Accessors(PUBLIC_GETTER, PROTECTED_SETTER)
+ var ChangeableViewSource viewSource
+ @Accessors(PUBLIC_GETTER)
+ var ResourceSet viewResourceSet
+ boolean modelChanged
+ @Accessors(PUBLIC_SETTER)
+ boolean viewChanged
+ boolean closed
+
+ protected new(ViewCreatingViewType extends ViewSelector, HierarchicalId> viewType, ChangeableViewSource viewSource,
+ ViewSelection selection) {
+ checkArgument(viewType !== null, "view type must not be null")
+ checkArgument(viewSource !== null, "view selection must not be null")
+ checkArgument(selection !== null, "view source must not be null")
+ this.viewType = viewType
+ this.viewSource = viewSource
+ this.selection = selection
+ viewSource.addChangePropagationListener(this)
+ viewResourceSet = new ResourceSetImpl().withGlobalFactories
+ update
+ }
+
+ override getRootObjects() {
+ checkNotClosed()
+ viewResourceSet.resources.map[contents].flatten.toList
+ }
+
+ override isModified() {
+ return viewChanged
+ }
+
+ override isOutdated() {
+ return modelChanged
+ }
+
+ override update() {
+ checkNotClosed()
+ checkState(!isModified, "cannot update from model when view is modified")
+ modelChanged = false
+ viewType.updateView(this)
+ viewChanged = false
+ viewResourceSet.addChangeListeners()
+ }
+
+ override close() throws Exception {
+ if (!closed) {
+ closed = true
+ viewResourceSet.resources.forEach[unload()]
+ viewResourceSet.resources.clear()
+ viewResourceSet.removeChangeListeners()
+ }
+ viewSource.removeChangePropagationListener(this)
+ }
+
+ override isClosed() {
+ return closed
+ }
+
+ override finishedChangePropagation(Iterable propagatedChanges) {
+ modelChanged = true
+ }
+
+ override startedChangePropagation(VitruviusChange changeToPropagate) {
+ // do nothing
+ }
+
+ override void registerRoot(EObject object, URI persistAt) {
+ checkNotClosed()
+ checkArgument(object !== null, "object to register as root must not be null")
+ checkArgument(persistAt !== null, "URI for root to register must not be null")
+ viewResourceSet.createResource(persistAt) => [
+ contents += object
+ ]
+ }
+
+ override void moveRoot(EObject object, URI newLocation) {
+ checkNotClosed()
+ checkArgument(object !== null, "object to move must not be null")
+ checkState(rootObjects.contains(object), "view must contain element %s to move", object)
+ checkArgument(newLocation !== null, "URI for new location of root must not be null")
+ viewResourceSet.resources.findFirst[contents.contains(object)].URI = newLocation
+ }
+
+ override void checkNotClosed() {
+ checkState(!closed, "view is already closed!")
+ }
+
+ private def void addChangeListeners(Notifier notifier) {
+ notifier.eAdapters += new AdapterImpl() {
+ override notifyChanged(Notification message) {
+ viewChanged = true
+ }
+ }
+ switch (notifier) {
+ ResourceSet: notifier.resources.forEach[addChangeListeners()]
+ Resource: notifier.contents.forEach[addChangeListeners()]
+ EObject: notifier.eContents.forEach[addChangeListeners]
+ }
+ }
+
+ private def void removeChangeListeners(ResourceSet resourceSet) {
+ resourceSet.allContents.forEach [
+ eAdapters.clear()
+ ]
+ }
+
+ override modifyContents((ResourceSet)=>void modificationFunction) {
+ modificationFunction.apply(viewResourceSet)
+ }
+
+ override withChangeRecordingTrait() {
+ checkNotClosed()
+ return new ChangeRecordingView(this)
+ }
+
+ override withChangeDerivingTrait(StateBasedChangeResolutionStrategy changeResolutionStrategy) {
+ checkNotClosed()
+ return new ChangeDerivingView(this, changeResolutionStrategy)
+ }
+}
\ No newline at end of file
diff --git a/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/views/BasicFilterView.java b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/views/BasicFilterView.java
new file mode 100644
index 000000000..d4e8cc4f8
--- /dev/null
+++ b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/views/BasicFilterView.java
@@ -0,0 +1,162 @@
+package tools.vitruv.applications.viewfilter.views;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
+
+import tools.vitruv.applications.viewfilter.util.framework.impl.ViewCreatingViewType;
+import tools.vitruv.applications.viewfilter.util.framework.selection.ElementViewSelection;
+import tools.vitruv.applications.viewfilter.viewbuild.ViewFilter;
+import tools.vitruv.change.atomic.hid.HierarchicalId;
+import tools.vitruv.framework.views.ChangeableViewSource;
+import tools.vitruv.framework.views.CommittableView;
+import tools.vitruv.framework.views.ModifiableViewSelection;
+import tools.vitruv.framework.views.ViewSelection;
+import tools.vitruv.framework.views.ViewSelector;
+import tools.vitruv.framework.views.changederivation.StateBasedChangeResolutionStrategy;
+
+public class BasicFilterView extends AbstractBasicView implements FilterableView {
+
+ private final ViewFilter viewFilter;
+
+ private final ViewSelection preFilterSelection;
+
+ private Collection rootObjects;
+
+ private ResourceSet filteredModelsResSet = null;
+
+
+ public BasicFilterView(ViewCreatingViewType extends ViewSelector, HierarchicalId> viewType,
+ ChangeableViewSource viewSource, ViewSelection selection, ViewFilter viewFilter) {
+ super(viewType, viewSource, selection);
+ this.viewFilter = viewFilter;
+ preFilterSelection = selection;
+ update();
+ }
+
+
+ public void update() {
+ if (viewFilter != null) {
+ //only execute if viewFilter has already been set
+ super.update();
+ }
+ }
+
+
+ @Override
+ public void modifyContents(Procedure1 super ResourceSet> modificationFunction) {
+ super.modifyContents(modificationFunction);
+ if (viewFilter != null) {
+ ModifiableViewSelection filteredSelection = filterElementsForSelection();
+ updateRootAndSelectedElements(filteredSelection);
+ }
+ }
+
+
+ @Override
+ public ResourceSet getNonFilteredViewResourceSet() {
+ return super.getViewResourceSet();
+ }
+
+
+ public ResourceSet getViewResourceSet() {
+ if (filteredModelsResSet == null) {
+ filteredModelsResSet = new ResourceSetImpl();
+ Map mapCopy2Original = viewFilter.getMapCopy2Original();
+ Map rootObject2UriMapping = getRootObject2UriMapping();
+ for (EObject copiedRootObject : getRootObjects()) {
+ EObject originalObject = mapCopy2Original.get(copiedRootObject);
+ filteredModelsResSet.createResource(rootObject2UriMapping.get(originalObject)).getContents().add(copiedRootObject);
+ }
+ }
+
+ return filteredModelsResSet;
+ }
+
+
+ public void setViewChanged(boolean value) {
+ super.setViewChanged(value);
+ }
+
+
+
+ protected ModifiableViewSelection filterElementsForSelection() {
+ Collection rootsForFiltering = super.getRootObjects();
+
+ Set filteredElements = viewFilter.filterElements(rootsForFiltering);
+ ModifiableViewSelection elementViewSelection = new ElementViewSelection(filteredElements);
+ filteredElements.forEach(it -> elementViewSelection.setSelected(it, true));
+ return elementViewSelection;
+ }
+
+
+ public Collection getRootObjects() {
+ return Collections.unmodifiableCollection(rootObjects);
+ }
+
+
+ private Map getRootObject2UriMapping() {
+ Map rootObject2UriMapping = new HashMap();
+
+ for (Resource resource : getNonFilteredViewResourceSet().getResources()) {
+ EList contents = resource.getContents();
+ for (EObject content : contents) {
+ rootObject2UriMapping.put(content, resource.getURI());
+ }
+ }
+ return rootObject2UriMapping;
+ }
+
+
+ protected void updateRootAndSelectedElements(ModifiableViewSelection selection) {
+ setRootObjects(selection.getSelectableElements());
+ setSelection(selection);
+ }
+
+
+ public ViewSelection getPreFilterSelection() {
+ return preFilterSelection;
+ }
+
+
+ public ViewSelection getSelection() {
+ return super.getSelection();
+ }
+
+
+ protected void setRootObjects(Collection rootObjects) {
+ this.rootObjects = rootObjects;
+ }
+
+
+
+ @Override
+ public CommittableView withChangeDerivingTrait(StateBasedChangeResolutionStrategy changeResolutionStrategy) {
+ checkNotClosed();
+ return new FilterChangeDerivingView(this, changeResolutionStrategy, viewFilter.getMapCopy2Original());
+ }
+
+
+ @Override
+ public CommittableView withChangeRecordingTrait() {
+ checkNotClosed();
+ return new FilterChangeRecordingView(this, viewFilter.getMapCopy2Original());
+ }
+
+
+ @Override
+ public Map getMapCopy2OriginalObject() {
+ return viewFilter.getMapCopy2Original();
+ }
+
+}
diff --git a/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/views/ChangeDerivingView.xtend b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/views/ChangeDerivingView.xtend
new file mode 100644
index 000000000..e6e12fd01
--- /dev/null
+++ b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/views/ChangeDerivingView.xtend
@@ -0,0 +1,106 @@
+package tools.vitruv.applications.viewfilter.views;
+
+import java.util.ArrayList
+import java.util.HashMap
+import java.util.HashSet
+import org.eclipse.emf.ecore.resource.Resource
+import org.eclipse.emf.ecore.resource.ResourceSet
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl
+import org.eclipse.xtend.lib.annotations.Delegate
+import tools.vitruv.change.atomic.hid.HierarchicalId
+import tools.vitruv.change.composite.description.VitruviusChange
+import tools.vitruv.change.composite.description.VitruviusChangeFactory
+import tools.vitruv.framework.views.CommittableView
+import tools.vitruv.framework.views.View
+import tools.vitruv.framework.views.changederivation.StateBasedChangeResolutionStrategy
+
+import static com.google.common.base.Preconditions.checkArgument
+import static com.google.common.base.Preconditions.checkState
+
+import static extension edu.kit.ipd.sdq.commons.util.org.eclipse.emf.common.util.URIUtil.isPathmap
+import edu.kit.ipd.sdq.commons.util.org.eclipse.emf.ecore.resource.ResourceCopier
+import tools.vitruv.applications.viewfilter.util.framework.impl.ModifiableView
+
+/**
+ * A {@link View} that derives changes based on the changed state of its resources and allows to propagate them
+ * back to the underlying models using the {@link #commitChanges} method.
+ */
+class ChangeDerivingView implements ModifiableView, CommittableView {
+ @Delegate
+ protected AbstractBasicView view
+
+ val StateBasedChangeResolutionStrategy changeResolutionStrategy
+ var ResourceSet originalStateViewResourceSet
+ var HashMap originalStateResourceMapping
+
+ protected new(AbstractBasicView view, StateBasedChangeResolutionStrategy changeResolutionStrategy) {
+ checkArgument(view !== null, "view must not be null")
+ checkState(!view.isModified, "view must not be modified")
+ checkState(!view.isOutdated, "view must not be outdated")
+ checkArgument(changeResolutionStrategy !== null, "change resolution strategy must not be null")
+ this.view = view
+ this.changeResolutionStrategy = changeResolutionStrategy
+ setupReferenceState
+ }
+
+ override update() {
+ closeOriginalState
+ view.update
+ setupReferenceState
+ }
+
+ protected def setupReferenceState() {
+ originalStateViewResourceSet = new ResourceSetImpl
+ ResourceCopier.copyViewResources(view.viewResourceSet.resources, originalStateViewResourceSet)
+ originalStateResourceMapping = new HashMap
+ view.viewResourceSet.resources.forEach[resource | originalStateResourceMapping.put(resource, originalStateViewResourceSet.resources.findFirst[URI === resource.URI])]
+ }
+
+ override commitChanges() {
+ view.checkNotClosed()
+ val changes = new ArrayList()
+ val allResources = new HashSet(originalStateResourceMapping.keySet)
+ allResources.addAll(view.viewResourceSet.resources) // consider newly added resources
+ for (changedResource : allResources.filter[!URI.isPathmap]) {
+ val change = generateChange(changedResource, originalStateResourceMapping.get(changedResource))
+ changes += change
+ }
+ val change = VitruviusChangeFactory.instance.createCompositeChange(changes)
+ view.viewType.commitViewChanges(this, change)
+ view.viewChanged = false
+ }
+
+ override close() throws Exception {
+ if (!isClosed) {
+ closeOriginalState
+ }
+ view.close
+ }
+
+ protected def VitruviusChange generateChange(Resource newState, Resource referenceState) {
+ if (referenceState === null) {
+ return changeResolutionStrategy.getChangeSequenceForCreated(newState)
+ } else if (newState === null) {
+ return changeResolutionStrategy.getChangeSequenceForDeleted(referenceState)
+ } else {
+ return changeResolutionStrategy.getChangeSequenceBetween(newState, referenceState)
+ }
+ }
+
+ private def closeOriginalState() {
+ originalStateViewResourceSet.resources.forEach[unload]
+ originalStateViewResourceSet.resources.clear
+ }
+
+ override withChangeRecordingTrait() {
+ val newView = view.withChangeRecordingTrait
+ closeOriginalState
+ return newView
+ }
+
+ override withChangeDerivingTrait(StateBasedChangeResolutionStrategy changeResolutionStrategy) {
+ val newView = view.withChangeDerivingTrait(changeResolutionStrategy)
+ closeOriginalState
+ return newView
+ }
+}
\ No newline at end of file
diff --git a/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/views/ChangeRecordingView.xtend b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/views/ChangeRecordingView.xtend
new file mode 100644
index 000000000..3dfe6e75a
--- /dev/null
+++ b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/views/ChangeRecordingView.xtend
@@ -0,0 +1,79 @@
+package tools.vitruv.applications.viewfilter.views;
+
+import org.eclipse.xtend.lib.annotations.Delegate
+import tools.vitruv.change.composite.description.VitruviusChangeResolver
+import tools.vitruv.change.composite.recording.ChangeRecorder
+import tools.vitruv.framework.views.CommittableView
+import tools.vitruv.framework.views.View
+import tools.vitruv.framework.views.changederivation.StateBasedChangeResolutionStrategy
+
+import static com.google.common.base.Preconditions.checkArgument
+import static com.google.common.base.Preconditions.checkState
+import tools.vitruv.applications.viewfilter.views.AbstractBasicView
+import tools.vitruv.applications.viewfilter.views.ChangesetDeterminableView
+import tools.vitruv.applications.viewfilter.util.framework.impl.ModifiableView
+
+/**
+ * A {@link View} that records changes to its resources and allows to propagate them
+ * back to the underlying models using the {@link #commitChanges} method.
+ */
+class ChangeRecordingView implements ModifiableView, CommittableView {
+ @Delegate
+ protected ChangesetDeterminableView view
+ protected ChangeRecorder changeRecorder
+
+ protected new(ChangesetDeterminableView view) {
+ checkArgument(view !== null, "view must not be null")
+ checkState(!view.isModified, "view must not be modified")
+ this.view = view
+ setupChangeRecorder
+ }
+
+ override update() {
+ changeRecorder.endRecordingAndClose()
+ view.update()
+ setupChangeRecorder
+ }
+
+ protected def setupChangeRecorder() {
+ changeRecorder = new ChangeRecorder(view.viewResourceSet)
+ changeRecorder.addToRecording(view.viewResourceSet)
+ changeRecorder.beginRecording()
+ }
+
+ override commitChanges() {
+ view.checkNotClosed()
+ val recordedChange = changeRecorder.endRecording()
+ val changeResolver = VitruviusChangeResolver.forHierarchicalIds(view.viewResourceSet)
+ val unresolvedChanges = changeResolver.assignIds(recordedChange)
+ view.viewType.commitViewChanges(this, unresolvedChanges)
+ view.viewChanged = false
+ changeRecorder.beginRecording()
+ }
+
+ override close() throws Exception {
+ if (!isClosed) {
+ changeRecorder.close()
+ }
+ view.close()
+ }
+
+ protected def void endRecordingAndClose(ChangeRecorder recorder) {
+ if (recorder.isRecording) {
+ recorder.endRecording()
+ }
+ recorder.close()
+ }
+
+ override withChangeRecordingTrait() {
+ val newView = view.withChangeRecordingTrait
+ changeRecorder.close
+ return newView
+ }
+
+ override withChangeDerivingTrait(StateBasedChangeResolutionStrategy changeResolutionStrategy) {
+ val newView = view.withChangeDerivingTrait(changeResolutionStrategy)
+ changeRecorder.close
+ return newView
+ }
+}
diff --git a/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/views/ChangesetDeterminableView.java b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/views/ChangesetDeterminableView.java
new file mode 100644
index 000000000..7bac01dbe
--- /dev/null
+++ b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/views/ChangesetDeterminableView.java
@@ -0,0 +1,43 @@
+package tools.vitruv.applications.viewfilter.views;
+
+import org.eclipse.emf.ecore.resource.ResourceSet;
+
+import tools.vitruv.applications.viewfilter.util.framework.impl.ModifiableView;
+import tools.vitruv.applications.viewfilter.util.framework.impl.ViewCreatingViewType;
+import tools.vitruv.change.atomic.hid.HierarchicalId;
+import tools.vitruv.framework.views.ViewSelector;
+
+/**
+ * Instances of this interface can be used to determine changes. These changes can then be used
+ * for further steps like commits.
+ */
+public interface ChangesetDeterminableView extends ModifiableView {
+
+ /**
+ * Returns the {@link ResourceSet} of the {@link ChangesetDeterminableView}
+ *
+ * @return The {@link ResourceSet} object
+ */
+ public ResourceSet getViewResourceSet();
+
+ /**
+ * Ensures that this {@link ChangesetDeterminableView} has not already been closed.
+ */
+ public void checkNotClosed();
+
+ /**
+ * Method returns the {@link ViewType} of the {@link ChangesetDeterminableView} object.
+ *
+ * @return The {@link ViewType}
+ */
+ public ViewCreatingViewType extends ViewSelector, HierarchicalId> getViewType();
+
+ /**
+ * Method sets the marker for changes of this {@link ChangesetDeterminableView} on the
+ * given value.
+ *
+ * @param value The new value for the marker
+ */
+ public void setViewChanged(boolean value);
+
+}
diff --git a/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/views/FilterChangeDerivingView.java b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/views/FilterChangeDerivingView.java
new file mode 100644
index 000000000..9c3d13f2a
--- /dev/null
+++ b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/views/FilterChangeDerivingView.java
@@ -0,0 +1,45 @@
+package tools.vitruv.applications.viewfilter.views;
+
+import java.util.Map;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+
+import tools.vitruv.framework.views.ViewSelection;
+import tools.vitruv.framework.views.changederivation.StateBasedChangeResolutionStrategy;
+
+public class FilterChangeDerivingView extends ChangeDerivingView implements FilterableView {
+
+ private Map mapCopy2OriginalObject;
+
+
+ protected FilterChangeDerivingView(BasicFilterView view,
+ StateBasedChangeResolutionStrategy changeResolutionStrategy, Map mapCopy2OriginalObject) {
+ super(view, changeResolutionStrategy);
+ this.mapCopy2OriginalObject = mapCopy2OriginalObject;
+ }
+
+
+ public ResourceSet getViewResourceSet() {
+ return view.getViewResourceSet();
+ }
+
+ @Override
+ public ViewSelection getPreFilterSelection() {
+ return getViewAsFilterableView().getPreFilterSelection();
+ }
+
+ @Override
+ public Map getMapCopy2OriginalObject() {
+ return mapCopy2OriginalObject;
+ }
+
+ @Override
+ public ResourceSet getNonFilteredViewResourceSet() {
+ return getViewAsFilterableView().getNonFilteredViewResourceSet();
+ }
+
+ private FilterableView getViewAsFilterableView() {
+ return (FilterableView) view;
+ }
+}
diff --git a/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/views/FilterChangeRecordingView.java b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/views/FilterChangeRecordingView.java
new file mode 100644
index 000000000..28b4d2c6a
--- /dev/null
+++ b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/views/FilterChangeRecordingView.java
@@ -0,0 +1,103 @@
+package tools.vitruv.applications.viewfilter.views;
+
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+
+import edu.kit.ipd.sdq.commons.util.org.eclipse.emf.ecore.resource.ResourceCopier;
+import tools.vitruv.change.atomic.EChange;
+import tools.vitruv.change.atomic.hid.HierarchicalId;
+import tools.vitruv.change.composite.description.TransactionalChange;
+import tools.vitruv.change.composite.description.VitruviusChange;
+import tools.vitruv.change.composite.description.VitruviusChangeBackwardsExecutionHelper;
+import tools.vitruv.change.composite.description.VitruviusChangeResolver;
+import tools.vitruv.change.composite.recording.ChangeRecorder;
+import tools.vitruv.framework.views.ViewSelection;
+
+
+public class FilterChangeRecordingView extends ChangeRecordingView implements FilterableView {
+
+ private Map mapCopy2OriginalObject;
+ private TransactionalChange recordedChange = null;
+
+
+ protected FilterChangeRecordingView(BasicFilterView view, Map mapCopy2OriginalObject) {
+ super(view);
+ this.mapCopy2OriginalObject = mapCopy2OriginalObject;
+ }
+
+
+ @Override
+ public List> setupChangeRecorder() {
+ ResourceSet filteredModelsInResourceSet = view.getViewResourceSet();
+ changeRecorder = new ChangeRecorder(filteredModelsInResourceSet);
+ changeRecorder.addToRecording(filteredModelsInResourceSet);
+ ResourceSet resourceSetCopy = new ResourceSetImpl();
+
+ return changeRecorder.beginRecording();
+ }
+
+
+ @Override
+ public void commitChanges() {
+ view.checkNotClosed();
+ recordedChange = changeRecorder.endRecording();
+
+ VitruviusChangeResolver changeResolver = VitruviusChangeResolver.forHierarchicalIds(view.getViewResourceSet());
+ VitruviusChange unresolvedChanges = changeResolver.assignIds(recordedChange);
+ view.getViewType().commitViewChanges(this, unresolvedChanges);
+ view.setViewChanged(false);
+ changeRecorder.beginRecording();
+ }
+
+
+ private FilterableView getViewAsFilterableView() {
+ return (FilterableView) view;
+ }
+
+
+
+ @Override
+ public ViewSelection getPreFilterSelection() {
+ return getViewAsFilterableView().getPreFilterSelection();
+ }
+
+
+ public ResourceSet getViewResourceSet() {
+ return view.getViewResourceSet();
+ }
+
+
+ /**
+ * Executes the current recorded changes backwards. May only be executed when the
+ * changes are currently really applied. This means that the method should not be
+ * executed twice without forward executing the changes in between. Returns the
+ * {@link ResourceSet} afterwards.
+ *
+ * @return The filtered {@link ResourceSet} in the state before the current recorded changes have been applied
+ */
+ public ResourceSet backwardExecuteChangesAndReturnResourceSet() {
+ ResourceSet resourceSet = getViewResourceSet();
+ if (recordedChange != null) {
+ VitruviusChangeBackwardsExecutionHelper.applyBackward(resourceSet, recordedChange);
+ }
+ return resourceSet;
+ }
+
+
+ @Override
+ public ResourceSet getNonFilteredViewResourceSet() {
+ return getViewAsFilterableView().getNonFilteredViewResourceSet();
+ }
+
+
+
+ @Override
+ public Map getMapCopy2OriginalObject() {
+ return mapCopy2OriginalObject;
+ }
+
+}
diff --git a/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/views/FilterableView.java b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/views/FilterableView.java
new file mode 100644
index 000000000..b1ec26f79
--- /dev/null
+++ b/bundles/tools.vitruv.applications.viewfilter/src/tools/vitruv/applications/viewfilter/views/FilterableView.java
@@ -0,0 +1,46 @@
+package tools.vitruv.applications.viewfilter.views;
+
+import java.util.Map;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+
+import tools.vitruv.applications.viewfilter.util.framework.impl.ModifiableView;
+import tools.vitruv.framework.views.ViewSelection;
+
+/**
+ * {@link Views} which implement this interface provide filter functionality. This interface
+ * therefore allows access on the selection of unfiltered models as well as on the unfiltered
+ * {@link ResourceSet}. Notice: To access the filtered models, one should use the common {@link ModifiableView}
+ * or {@link View} interface.
+ * It also provides a mapping from an object in a filtered model to the object in the unfiltered
+ * model, as the objects in the filtered models might be copies of the original objects depending
+ * on the implementation.
+ */
+public interface FilterableView extends ModifiableView {
+
+ /**
+ * Method returns the selection of models in this view before the first filtering. Can be used
+ * to access the unfiltered models which are sources for the actual filtering and need to be
+ * considered.
+ *
+ * @return A viewSelection of unfiltered models
+ */
+ ViewSelection getPreFilterSelection();
+
+ /**
+ * Provides a mapping from an object in a filtered model to the object in the unfiltered
+ * model. The objects in the filtered models might be copies of the original objects depending
+ * on the implementation.
+ *
+ * @return The map containing the mapping
+ */
+ Map getMapCopy2OriginalObject();
+
+ /**
+ * Method returns the {@link ResourceSet} containing all unfiltered models of this view.
+ *
+ * @return The {@link ResourceSet} containing all unfiltered models of this view
+ */
+ ResourceSet getNonFilteredViewResourceSet();
+}
diff --git a/tests/tools.vitruv.applications.pcmjava.javaeditor.tests/.classpath b/bundles/tools.vitruv.views.viewfilter.infostructure.model/.classpath
similarity index 83%
rename from tests/tools.vitruv.applications.pcmjava.javaeditor.tests/.classpath
rename to bundles/tools.vitruv.views.viewfilter.infostructure.model/.classpath
index fe1a20532..c280941ad 100644
--- a/tests/tools.vitruv.applications.pcmjava.javaeditor.tests/.classpath
+++ b/bundles/tools.vitruv.views.viewfilter.infostructure.model/.classpath
@@ -1,11 +1,12 @@
+
+
-
+
-
+
-
diff --git a/bundles/tools.vitruv.views.viewfilter.infostructure.model/.project b/bundles/tools.vitruv.views.viewfilter.infostructure.model/.project
new file mode 100644
index 000000000..f890a98d4
--- /dev/null
+++ b/bundles/tools.vitruv.views.viewfilter.infostructure.model/.project
@@ -0,0 +1,29 @@
+
+
+ tools.vitruv.views.viewfilter.infostructure.model
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.pde.ManifestBuilder
+
+
+
+
+ org.eclipse.pde.SchemaBuilder
+
+
+
+
+
+ org.eclipse.sirius.nature.modelingproject
+ org.eclipse.jdt.core.javanature
+ org.eclipse.pde.PluginNature
+
+
diff --git a/bundles/tools.vitruv.views.viewfilter.infostructure.model/META-INF/MANIFEST.MF b/bundles/tools.vitruv.views.viewfilter.infostructure.model/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..a397b7582
--- /dev/null
+++ b/bundles/tools.vitruv.views.viewfilter.infostructure.model/META-INF/MANIFEST.MF
@@ -0,0 +1,16 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: tools.vitruv.views.viewfilter.infostructure.model;singleton:=true
+Automatic-Module-Name: tools.vitruv.views.viewfilter.infostructure.model
+Bundle-Version: 0.1.0.qualifier
+Bundle-ClassPath: .
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Bundle-RequiredExecutionEnvironment: JavaSE-17
+Export-Package: tools.vitruv.views.viewfilter.infostructure.model.infostructuremodel,
+ tools.vitruv.views.viewfilter.infostructure.model.infostructuremodel.impl,
+ tools.vitruv.views.viewfilter.infostructure.model.infostructuremodel.util
+Require-Bundle: org.eclipse.emf.ecore;visibility:=reexport,
+ org.eclipse.core.runtime
+Bundle-ActivationPolicy: lazy
diff --git a/bundles/tools.vitruv.views.viewfilter.infostructure.model/build.properties b/bundles/tools.vitruv.views.viewfilter.infostructure.model/build.properties
new file mode 100644
index 000000000..697ca9645
--- /dev/null
+++ b/bundles/tools.vitruv.views.viewfilter.infostructure.model/build.properties
@@ -0,0 +1,10 @@
+#
+
+bin.includes = .,\
+ model/,\
+ META-INF/,\
+ plugin.xml,\
+ plugin.properties
+jars.compile.order = .
+source.. = src-gen/
+output.. = bin/
diff --git a/bundles/tools.vitruv.views.viewfilter.infostructure.model/model/infostructuremodel.aird b/bundles/tools.vitruv.views.viewfilter.infostructure.model/model/infostructuremodel.aird
new file mode 100644
index 000000000..960a43122
--- /dev/null
+++ b/bundles/tools.vitruv.views.viewfilter.infostructure.model/model/infostructuremodel.aird
@@ -0,0 +1,59 @@
+
+
+
+ infostructuremodel.ecore
+ infostructuremodel.genmodel
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bundles/tools.vitruv.views.viewfilter.infostructure.model/model/infostructuremodel.ecore b/bundles/tools.vitruv.views.viewfilter.infostructure.model/model/infostructuremodel.ecore
new file mode 100644
index 000000000..194667bad
--- /dev/null
+++ b/bundles/tools.vitruv.views.viewfilter.infostructure.model/model/infostructuremodel.ecore
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/bundles/tools.vitruv.views.viewfilter.infostructure.model/model/infostructuremodel.genmodel b/bundles/tools.vitruv.views.viewfilter.infostructure.model/model/infostructuremodel.genmodel
new file mode 100644
index 000000000..e98c70323
--- /dev/null
+++ b/bundles/tools.vitruv.views.viewfilter.infostructure.model/model/infostructuremodel.genmodel
@@ -0,0 +1,23 @@
+
+
+ infostructuremodel.ecore
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bundles/tools.vitruv.views.viewfilter.infostructure.model/plugin.properties b/bundles/tools.vitruv.views.viewfilter.infostructure.model/plugin.properties
new file mode 100644
index 000000000..032dd38af
--- /dev/null
+++ b/bundles/tools.vitruv.views.viewfilter.infostructure.model/plugin.properties
@@ -0,0 +1,4 @@
+#
+
+pluginName = tools.vitruv.views.viewfilter.infostructure.model
+providerName = www.example.org
diff --git a/bundles/tools.vitruv.views.viewfilter.infostructure.model/plugin.xml b/bundles/tools.vitruv.views.viewfilter.infostructure.model/plugin.xml
new file mode 100644
index 000000000..ad1b09d0d
--- /dev/null
+++ b/bundles/tools.vitruv.views.viewfilter.infostructure.model/plugin.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/features/tools.vitruv.applications.cbs.commonalities.feature/.settings/org.eclipse.core.resources.prefs b/features/tools.vitruv.applications.cbs.commonalities.feature/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 99f26c020..000000000
--- a/features/tools.vitruv.applications.cbs.commonalities.feature/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-encoding/=UTF-8
diff --git a/features/tools.vitruv.applications.pcmjava.feature/.settings/org.eclipse.core.resources.prefs b/features/tools.vitruv.applications.pcmjava.feature/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 99f26c020..000000000
--- a/features/tools.vitruv.applications.pcmjava.feature/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-encoding/=UTF-8
diff --git a/features/tools.vitruv.applications.pcmumlclass.feature/.settings/org.eclipse.core.resources.prefs b/features/tools.vitruv.applications.pcmumlclass.feature/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 99f26c020..000000000
--- a/features/tools.vitruv.applications.pcmumlclass.feature/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-encoding/=UTF-8
diff --git a/features/tools.vitruv.applications.simulinkautosar.feature/.settings/org.eclipse.core.resources.prefs b/features/tools.vitruv.applications.simulinkautosar.feature/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 99f26c020..000000000
--- a/features/tools.vitruv.applications.simulinkautosar.feature/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-encoding/=UTF-8
diff --git a/features/tools.vitruv.applications.umljava.feature/.settings/org.eclipse.core.resources.prefs b/features/tools.vitruv.applications.umljava.feature/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 99f26c020..000000000
--- a/features/tools.vitruv.applications.umljava.feature/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-encoding/=UTF-8
diff --git a/features/tools.vitruv.applications.util.temporary.feature/.settings/org.eclipse.core.resources.prefs b/features/tools.vitruv.applications.util.temporary.feature/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 99f26c020..000000000
--- a/features/tools.vitruv.applications.util.temporary.feature/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-encoding/=UTF-8
diff --git a/releng/tools.vitruv.applications.cbs.updatesite/.settings/org.eclipse.core.resources.prefs b/releng/tools.vitruv.applications.cbs.updatesite/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 99f26c020..000000000
--- a/releng/tools.vitruv.applications.cbs.updatesite/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-encoding/=UTF-8
diff --git a/releng/tools.vitruv.casestudies.dependencywrapper/.classpath b/releng/tools.vitruv.casestudies.dependencywrapper/.classpath
index ac37fb2e4..4e5621a0d 100644
--- a/releng/tools.vitruv.casestudies.dependencywrapper/.classpath
+++ b/releng/tools.vitruv.casestudies.dependencywrapper/.classpath
@@ -2,4 +2,4 @@
-
+
\ No newline at end of file
diff --git a/releng/tools.vitruv.casestudies.dependencywrapper/.settings/org.eclipse.core.resources.prefs b/releng/tools.vitruv.casestudies.dependencywrapper/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 99f26c020..000000000
--- a/releng/tools.vitruv.casestudies.dependencywrapper/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-encoding/=UTF-8
diff --git a/tests/tools.vitruv.applications.SimuLinkAutoSAR.tests/.classpath b/tests/tools.vitruv.applications.SimuLinkAutoSAR.tests/.classpath
index 79b55556c..e2f0d7065 100644
--- a/tests/tools.vitruv.applications.SimuLinkAutoSAR.tests/.classpath
+++ b/tests/tools.vitruv.applications.SimuLinkAutoSAR.tests/.classpath
@@ -13,4 +13,4 @@
-
+
\ No newline at end of file
diff --git a/tests/tools.vitruv.applications.SimuLinkAutoSAR.tests/.settings/org.eclipse.core.resources.prefs b/tests/tools.vitruv.applications.SimuLinkAutoSAR.tests/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 99f26c020..000000000
--- a/tests/tools.vitruv.applications.SimuLinkAutoSAR.tests/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-encoding/=UTF-8
diff --git a/tests/tools.vitruv.applications.SimuLinkAutoSAR.tests/.settings/org.eclipse.m2e.core.prefs b/tests/tools.vitruv.applications.SimuLinkAutoSAR.tests/.settings/org.eclipse.m2e.core.prefs
deleted file mode 100644
index f897a7f1c..000000000
--- a/tests/tools.vitruv.applications.SimuLinkAutoSAR.tests/.settings/org.eclipse.m2e.core.prefs
+++ /dev/null
@@ -1,4 +0,0 @@
-activeProfiles=
-eclipse.preferences.version=1
-resolveWorkspaceProjects=true
-version=1
diff --git a/tests/tools.vitruv.applications.cbs.commonalities.tests/.classpath b/tests/tools.vitruv.applications.cbs.commonalities.tests/.classpath
index 86e2dcf0f..1a7035e6e 100644
--- a/tests/tools.vitruv.applications.cbs.commonalities.tests/.classpath
+++ b/tests/tools.vitruv.applications.cbs.commonalities.tests/.classpath
@@ -1,4 +1,3 @@
-
@@ -15,4 +14,4 @@
-
+
\ No newline at end of file
diff --git a/tests/tools.vitruv.applications.cbs.commonalities.tests/.settings/org.eclipse.core.resources.prefs b/tests/tools.vitruv.applications.cbs.commonalities.tests/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 99f26c020..000000000
--- a/tests/tools.vitruv.applications.cbs.commonalities.tests/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-encoding/=UTF-8
diff --git a/tests/tools.vitruv.applications.cbs.equivalence.tests/.classpath b/tests/tools.vitruv.applications.cbs.equivalence.tests/.classpath
index 5b259b905..199c20882 100644
--- a/tests/tools.vitruv.applications.cbs.equivalence.tests/.classpath
+++ b/tests/tools.vitruv.applications.cbs.equivalence.tests/.classpath
@@ -5,4 +5,4 @@
-
+
\ No newline at end of file
diff --git a/tests/tools.vitruv.applications.cbs.equivalence.tests/.settings/org.eclipse.core.resources.prefs b/tests/tools.vitruv.applications.cbs.equivalence.tests/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 99f26c020..000000000
--- a/tests/tools.vitruv.applications.cbs.equivalence.tests/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-encoding/=UTF-8
diff --git a/tests/tools.vitruv.applications.demo.familiespersons.tests/.settings/org.eclipse.core.resources.prefs b/tests/tools.vitruv.applications.demo.familiespersons.tests/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 99f26c020..000000000
--- a/tests/tools.vitruv.applications.demo.familiespersons.tests/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-encoding/=UTF-8
diff --git a/tests/tools.vitruv.applications.demo.insurancefamilies.tests/.classpath b/tests/tools.vitruv.applications.demo.insurancefamilies.tests/.classpath
index 47de4eea1..c2f3215a6 100644
--- a/tests/tools.vitruv.applications.demo.insurancefamilies.tests/.classpath
+++ b/tests/tools.vitruv.applications.demo.insurancefamilies.tests/.classpath
@@ -13,4 +13,4 @@
-
+
\ No newline at end of file
diff --git a/tests/tools.vitruv.applications.demo.insurancefamilies.tests/.settings/org.eclipse.core.resources.prefs b/tests/tools.vitruv.applications.demo.insurancefamilies.tests/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 99f26c020..000000000
--- a/tests/tools.vitruv.applications.demo.insurancefamilies.tests/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-encoding/=UTF-8
diff --git a/tests/tools.vitruv.applications.demo.insurancepersons.tests/.classpath b/tests/tools.vitruv.applications.demo.insurancepersons.tests/.classpath
index 47de4eea1..c2f3215a6 100644
--- a/tests/tools.vitruv.applications.demo.insurancepersons.tests/.classpath
+++ b/tests/tools.vitruv.applications.demo.insurancepersons.tests/.classpath
@@ -13,4 +13,4 @@
-
+
\ No newline at end of file
diff --git a/tests/tools.vitruv.applications.demo.insurancepersons.tests/.settings/org.eclipse.core.resources.prefs b/tests/tools.vitruv.applications.demo.insurancepersons.tests/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 99f26c020..000000000
--- a/tests/tools.vitruv.applications.demo.insurancepersons.tests/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-encoding/=UTF-8
diff --git a/tests/tools.vitruv.applications.pcmjava.javaeditor.tests/.settings/org.eclipse.core.resources.prefs b/tests/tools.vitruv.applications.pcmjava.javaeditor.tests/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 99f26c020..000000000
--- a/tests/tools.vitruv.applications.pcmjava.javaeditor.tests/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-encoding/=UTF-8
diff --git a/tests/tools.vitruv.applications.pcmjava.tests/.classpath b/tests/tools.vitruv.applications.pcmjava.tests/.classpath
index 58d1a70f1..e31ed6fdd 100644
--- a/tests/tools.vitruv.applications.pcmjava.tests/.classpath
+++ b/tests/tools.vitruv.applications.pcmjava.tests/.classpath
@@ -9,4 +9,4 @@
-
+
\ No newline at end of file
diff --git a/tests/tools.vitruv.applications.pcmjava.tests/.settings/org.eclipse.core.resources.prefs b/tests/tools.vitruv.applications.pcmjava.tests/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 99f26c020..000000000
--- a/tests/tools.vitruv.applications.pcmjava.tests/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-encoding/=UTF-8
diff --git a/tests/tools.vitruv.applications.pcmumlclass.tests/.classpath b/tests/tools.vitruv.applications.pcmumlclass.tests/.classpath
index ef548cb96..30b0b3921 100644
--- a/tests/tools.vitruv.applications.pcmumlclass.tests/.classpath
+++ b/tests/tools.vitruv.applications.pcmumlclass.tests/.classpath
@@ -13,4 +13,4 @@
-
+
\ No newline at end of file
diff --git a/tests/tools.vitruv.applications.pcmumlclass.tests/.settings/org.eclipse.core.resources.prefs b/tests/tools.vitruv.applications.pcmumlclass.tests/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 99f26c020..000000000
--- a/tests/tools.vitruv.applications.pcmumlclass.tests/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-encoding/=UTF-8
diff --git a/tests/tools.vitruv.applications.transitivechange.tests/.classpath b/tests/tools.vitruv.applications.transitivechange.tests/.classpath
index ef548cb96..30b0b3921 100644
--- a/tests/tools.vitruv.applications.transitivechange.tests/.classpath
+++ b/tests/tools.vitruv.applications.transitivechange.tests/.classpath
@@ -13,4 +13,4 @@
-
+
\ No newline at end of file
diff --git a/tests/tools.vitruv.applications.transitivechange.tests/.settings/org.eclipse.core.resources.prefs b/tests/tools.vitruv.applications.transitivechange.tests/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 99f26c020..000000000
--- a/tests/tools.vitruv.applications.transitivechange.tests/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-encoding/=UTF-8
diff --git a/tests/tools.vitruv.applications.umljava.tests/.classpath b/tests/tools.vitruv.applications.umljava.tests/.classpath
index ef548cb96..30b0b3921 100644
--- a/tests/tools.vitruv.applications.umljava.tests/.classpath
+++ b/tests/tools.vitruv.applications.umljava.tests/.classpath
@@ -13,4 +13,4 @@
-
+
\ No newline at end of file
diff --git a/tests/tools.vitruv.applications.umljava.tests/.settings/org.eclipse.core.resources.prefs b/tests/tools.vitruv.applications.umljava.tests/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 99f26c020..000000000
--- a/tests/tools.vitruv.applications.umljava.tests/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-encoding/=UTF-8
diff --git a/tests/tools.vitruv.applications.umljava.tests/src/tools/vitruv/applications/umljava/tests/java2uml/constructionsimulationtest/JavaSourceOrClassFileResourceWithArraysDefaultFactoryImpl.java b/tests/tools.vitruv.applications.umljava.tests/src/tools/vitruv/applications/umljava/tests/java2uml/constructionsimulationtest/JavaSourceOrClassFileResourceWithArraysDefaultFactoryImpl
similarity index 99%
rename from tests/tools.vitruv.applications.umljava.tests/src/tools/vitruv/applications/umljava/tests/java2uml/constructionsimulationtest/JavaSourceOrClassFileResourceWithArraysDefaultFactoryImpl.java
rename to tests/tools.vitruv.applications.umljava.tests/src/tools/vitruv/applications/umljava/tests/java2uml/constructionsimulationtest/JavaSourceOrClassFileResourceWithArraysDefaultFactoryImpl
index a6f1f0598..f28fb4034 100644
--- a/tests/tools.vitruv.applications.umljava.tests/src/tools/vitruv/applications/umljava/tests/java2uml/constructionsimulationtest/JavaSourceOrClassFileResourceWithArraysDefaultFactoryImpl.java
+++ b/tests/tools.vitruv.applications.umljava.tests/src/tools/vitruv/applications/umljava/tests/java2uml/constructionsimulationtest/JavaSourceOrClassFileResourceWithArraysDefaultFactoryImpl
@@ -11,4 +11,4 @@ public class JavaSourceOrClassFileResourceWithArraysDefaultFactoryImpl
public Resource createResource(URI uri) {
return new JavaSourceOrClassFileResourceWithArraysDefault(uri);
}
-}
+}
\ No newline at end of file
diff --git a/tests/tools.vitruv.applications.viewfilter.tests/.classpath b/tests/tools.vitruv.applications.viewfilter.tests/.classpath
new file mode 100644
index 000000000..47de4eea1
--- /dev/null
+++ b/tests/tools.vitruv.applications.viewfilter.tests/.classpath
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/tools.vitruv.applications.viewfilter.tests/.project b/tests/tools.vitruv.applications.viewfilter.tests/.project
new file mode 100644
index 000000000..3b229303c
--- /dev/null
+++ b/tests/tools.vitruv.applications.viewfilter.tests/.project
@@ -0,0 +1,34 @@
+
+
+ tools.vitruv.views.viewfilter.tests
+
+
+
+
+
+ org.eclipse.xtext.ui.shared.xtextBuilder
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.pde.ManifestBuilder
+
+
+
+
+ org.eclipse.pde.SchemaBuilder
+
+
+
+
+
+ org.eclipse.pde.PluginNature
+ org.eclipse.jdt.core.javanature
+ org.eclipse.xtext.ui.shared.xtextNature
+
+
diff --git a/tests/tools.vitruv.applications.viewfilter.tests/META-INF/MANIFEST.MF b/tests/tools.vitruv.applications.viewfilter.tests/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..4df5418a8
--- /dev/null
+++ b/tests/tools.vitruv.applications.viewfilter.tests/META-INF/MANIFEST.MF
@@ -0,0 +1,27 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Vitruv PCM-UML Class Application Tests
+Bundle-SymbolicName: tools.vitruv.views.viewfilter.tests
+Bundle-Version: 3.0.1.qualifier
+Automatic-Module-Name: tools.vitruv.applications.viewfilter.tests
+Bundle-RequiredExecutionEnvironment: JavaSE-17
+Import-Package: org.junit.jupiter.api,
+ org.junit.jupiter.api.extension,
+ tools.vitruv.views.viewfilter.infostructure.model.infostructuremodel
+Require-Bundle: tools.vitruv.testutils.vsum,
+ org.eclipse.emf.compare,
+ org.hamcrest.core,
+ tools.vitruv.applications.pcmumlclass,
+ tools.vitruv.applications.util.temporary,
+ org.eclipse.xtend.lib,
+ edu.kit.ipd.sdq.commons.util.java,
+ org.palladiosimulator.pcm.resources,
+ edu.kit.ipd.sdq.activextendannotations,
+ tools.vitruv.applications.testutility,
+ org.palladiosimulator.pcm,
+ edu.kit.ipd.sdq.commons.util.emf,
+ slf4j.api;bundle-version="2.0.9",
+ org.emftext.language.java;bundle-version="1.4.1",
+ org.eclipse.emf.ecore,
+ tools.vitruv.views.viewfilter
+Bundle-Vendor: vitruv.tools
diff --git a/tests/tools.vitruv.applications.viewfilter.tests/build.properties b/tests/tools.vitruv.applications.viewfilter.tests/build.properties
new file mode 100644
index 000000000..6a209b473
--- /dev/null
+++ b/tests/tools.vitruv.applications.viewfilter.tests/build.properties
@@ -0,0 +1,14 @@
+source.. = src/,\
+ xtend-gen/
+output.. = target/classes/
+bin.includes = META-INF/,\
+ .,\
+ resources/
+additional.bundles = org.palladiosimulator.pcm,\
+ org.palladiosimulator.pcm.resources,\
+ org.eclipse.emf.edit,\
+ org.eclipse.core.expressions,\
+ org.slf4j.api,\
+ ch.qos.logback.core,\
+ ch.qos.logback.classic,\
+ org.eclipse.uml2.uml
diff --git a/tests/tools.vitruv.applications.viewfilter.tests/src/tools/vitruv/applications/viewfilter/tests/FilterAndInfoViewTestFactory.java b/tests/tools.vitruv.applications.viewfilter.tests/src/tools/vitruv/applications/viewfilter/tests/FilterAndInfoViewTestFactory.java
new file mode 100644
index 000000000..f2e5fe9e8
--- /dev/null
+++ b/tests/tools.vitruv.applications.viewfilter.tests/src/tools/vitruv/applications/viewfilter/tests/FilterAndInfoViewTestFactory.java
@@ -0,0 +1,157 @@
+package tools.vitruv.applications.viewfilter.tests;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.uml2.uml.Model;
+import org.eclipse.uml2.uml.NamedElement;
+import org.palladiosimulator.pcm.repository.Repository;
+import org.palladiosimulator.pcm.repository.RepositoryComponent;
+
+import tools.vitruv.applications.viewfilter.util.framework.FilterSupportingViewTypeFactory;
+import tools.vitruv.applications.viewfilter.util.framework.selectors.FilterSupportingViewElementSelector;
+import tools.vitruv.framework.views.CommittableView;
+import tools.vitruv.framework.views.View;
+import tools.vitruv.framework.views.ViewProvider;
+import tools.vitruv.framework.views.ViewSelector;
+import tools.vitruv.framework.views.ViewType;
+import tools.vitruv.framework.views.ViewTypeFactory;
+import tools.vitruv.testutils.TestViewFactory;
+
+public class FilterAndInfoViewTestFactory extends TestViewFactory {
+
+ private ViewProvider viewProvider;
+ ViewType extends ViewSelector> viewType;
+
+ public FilterAndInfoViewTestFactory(ViewProvider viewProvider) {
+ super(viewProvider);
+ this.viewProvider = viewProvider;
+ }
+
+
+ public View createUmlView() {
+ Collection> rootTypes = createCollectionOfRootTypes(Model.class);
+ return createViewOfElements("UML", rootTypes);
+ }
+
+ public View createPcmView() {
+ Collection> rootTypes = createCollectionOfRootTypes(Repository.class);
+ rootTypes.add(RepositoryComponent.class);
+ return createViewOfElements("PCM packages and components", rootTypes);
+ }
+
+ public View createUmlAndPcmClassesView() {
+ Collection> rootTypes = createCollectionOfRootTypes(createCollectionOfRootTypes(RepositoryComponent.class), Model.class);
+ return createViewOfElements("UML and PCM components", rootTypes);
+ }
+
+
+ public View createFilteredUmlView(Function function) {
+ Collection> rootTypes = createCollectionOfRootTypes(Model.class);
+ return createFilteredForNoAttributesViewOfElements("UML", rootTypes, function);
+ }
+
+ public View createFilteredPcmView(Function filterFunction) {
+ Collection> rootTypes = createCollectionOfRootTypes(Repository.class);
+ return createFilteredViewOfElements("PCM", rootTypes, filterFunction);
+ }
+
+
+ public View createCountUmlElementsView(Function filterFunction) {
+ Collection> rootTypes = createCollectionOfRootTypes(Model.class);
+ return createCountUmlClassesInformationView("Information Page", rootTypes, filterFunction);
+
+ }
+
+
+ //--------------Boilerplate code -----------------//
+ //
+
+ public View createViewOfElements(String viewName, Collection> rootTypes) {
+ ViewSelector selector = viewProvider.createSelector(ViewTypeFactory.createIdentityMappingViewType(viewName));
+ selector.getSelectableElements().stream()
+ .filter(element -> rootTypes.stream().anyMatch(it -> it.isInstance(element)))
+ .forEach(element -> selector.setSelected(element, true));
+
+ View view = selector.createView();
+ assertThat("view must not be null", view, not(equalTo(null)));
+ return view;
+ }
+
+
+ public void changeUmlView(Consumer modelModification) throws Exception {
+ changeViewRecordingChanges(createUmlView(), modelModification);
+ }
+
+ /**
+ * Changes the PCM view containing all PCM packages and classes as root elements
+ * according to the given modification function.
+ * Records the performed changes, commits the recorded changes, and closes the view afterwards.
+ * @throws Exception
+ */
+ public void changePcmView(Consumer modelModification) throws Exception {
+ changeViewRecordingChanges(createPcmView(), modelModification);
+ }
+
+
+
+//-------------End of Boilerplate code----------------//
+
+
+ public View createCountUmlClassesInformationView(String viewName, Collection> rootTypes, Function filterFunction) {
+ viewType = FilterSupportingViewTypeFactory.createCountUmlClassesInformationFilterViewViewType(viewName);
+ FilterSupportingViewElementSelector selector = (FilterSupportingViewElementSelector) viewProvider.createSelector(viewType);
+ selector.deselectElementsExceptForRootType(rootTypes);
+ selector.filterModelElementsByLambda(filterFunction);
+ selector.removeOwnedAttributesFromUmlClasses();
+
+ View view = selector.createView();
+ assertThat("view must not be null", view, not(equalTo(null)));
+ return view;
+ }
+
+
+ public View createFilteredForNoAttributesViewOfElements(String viewName, Collection> rootTypes, Function function) {
+ viewType = FilterSupportingViewTypeFactory.createFilterSupportingIdentityMappingViewType(viewName);
+ FilterSupportingViewElementSelector selector = (FilterSupportingViewElementSelector) viewProvider.createSelector(viewType);
+ selector.deselectElementsExceptForRootType(rootTypes);
+ selector.filterModelElementsByLambda(function);
+ selector.removeOwnedAttributesFromUmlClasses();
+
+ View view = selector.createView();
+ assertThat("view must not be null", view, not(equalTo(null)));
+ return view;
+ }
+
+
+ private View createFilteredViewOfElements(String viewName, Collection> rootTypes, Function filterFunction) {
+ viewType = FilterSupportingViewTypeFactory.createFilterSupportingIdentityMappingViewType(viewName);
+ FilterSupportingViewElementSelector selector = (FilterSupportingViewElementSelector) viewProvider.createSelector(viewType);
+ Function function = (EObject object) -> filterFunction.apply(object);
+ selector.deselectElementsExceptForRootType(rootTypes);
+ selector.filterModelElementsByLambda(function);
+
+ View view = selector.createView();
+ assertThat("view must not be null", view, not(equalTo(null)));
+ return view;
+ }
+
+
+ private Collection> createCollectionOfRootTypes(Collection> currentCollection, Class> additionalRootType) {
+ currentCollection.add(additionalRootType);
+ return currentCollection;
+ }
+
+ private Collection> createCollectionOfRootTypes(Class> additionalRootType) {
+ Collection> rootTypes = new LinkedList();
+ rootTypes.add(additionalRootType);
+ return rootTypes;
+ }
+}
diff --git a/tests/tools.vitruv.applications.viewfilter.tests/src/tools/vitruv/applications/viewfilter/tests/InstanceFilterTest.java b/tests/tools.vitruv.applications.viewfilter.tests/src/tools/vitruv/applications/viewfilter/tests/InstanceFilterTest.java
new file mode 100644
index 000000000..11f77448b
--- /dev/null
+++ b/tests/tools.vitruv.applications.viewfilter.tests/src/tools/vitruv/applications/viewfilter/tests/InstanceFilterTest.java
@@ -0,0 +1,538 @@
+package tools.vitruv.applications.viewfilter.tests;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.lang.reflect.InvocationTargetException;
+import java.nio.file.Path;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.TreeIterator;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.uml2.uml.Class;
+import org.eclipse.uml2.uml.Classifier;
+import org.eclipse.uml2.uml.Comment;
+import org.eclipse.uml2.uml.Model;
+import org.eclipse.uml2.uml.NamedElement;
+import org.eclipse.uml2.uml.PackageableElement;
+import org.eclipse.uml2.uml.PrimitiveType;
+import org.eclipse.uml2.uml.UMLFactory;
+import org.eclipse.uml2.uml.internal.impl.ClassImpl;
+import org.eclipse.uml2.uml.internal.impl.ModelImpl;
+import org.eclipse.uml2.uml.internal.impl.PackageImpl;
+import org.eclipse.uml2.uml.internal.impl.PrimitiveTypeImpl;
+import org.eclipse.xtend.lib.annotations.AccessorType;
+import org.eclipse.xtend.lib.annotations.Accessors;
+import org.eclipse.xtext.xbase.lib.CollectionLiterals;
+import org.eclipse.xtext.xbase.lib.Exceptions;
+import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.palladiosimulator.pcm.repository.BasicComponent;
+import org.palladiosimulator.pcm.repository.CompositeDataType;
+import org.palladiosimulator.pcm.repository.Repository;
+import org.palladiosimulator.pcm.repository.RepositoryFactory;
+
+import tools.vitruv.applications.pcmumlclass.CombinedPcmToUmlClassReactionsChangePropagationSpecification;
+import tools.vitruv.applications.pcmumlclass.CombinedUmlClassToPcmReactionsChangePropagationSpecification;
+import tools.vitruv.applications.testutility.uml.UmlQueryUtil;
+import tools.vitruv.applications.viewfilter.utils.PcmQueryUtil;
+import tools.vitruv.applications.viewfilter.utils.PcmUmlClassApplicationTestHelper;
+import tools.vitruv.change.propagation.ChangePropagationSpecification;
+import tools.vitruv.framework.views.CommittableView;
+import tools.vitruv.framework.views.View;
+import tools.vitruv.framework.views.ViewSelection;
+import tools.vitruv.testutils.RegisterMetamodelsInStandalone;
+import tools.vitruv.testutils.ViewBasedVitruvApplicationTest;
+import tools.vitruv.views.viewfilter.infostructure.model.infostructuremodel.InformationStructure;
+import tools.vitruv.views.viewfilter.infostructure.model.infostructuremodel.SingleInformation;
+
+@ExtendWith(RegisterMetamodelsInStandalone.class)
+public class InstanceFilterTest extends ViewBasedVitruvApplicationTest {
+
+ private static final String NESTED_PACKAGE_TEST_NAME = "testNestedPackage";
+
+ @Accessors(AccessorType.PROTECTED_GETTER)
+ private static final String UML_MODEL_NAME = "model";
+
+ @Accessors(AccessorType.PROTECTED_GETTER)
+ private static final String PCM_MODEL_NAME = "Repository";
+
+ private static final String TEST_MODIFIED_CLASS_NAME = "testModifiedClass2";
+
+ private static final String PCM_REPOSITORY_FILE_EXTENSION = "repository";
+
+ @Accessors(AccessorType.PROTECTED_GETTER)
+ private static final String MODEL_FOLDER_NAME = "model";
+
+ @Accessors(AccessorType.PROTECTED_GETTER)
+ private static final String MODEL_FILE_EXTENSION = "uml";
+
+ private static final String PCM_BASIC_COMPONENT_NAME = "Test Basic PCM component 1";
+
+ private static final String UML_MODEL_URI = "1234uri1234";
+
+ @Accessors(AccessorType.PUBLIC_GETTER)
+ private org.eclipse.uml2.uml.Class class1;
+
+ @Accessors(AccessorType.PUBLIC_GETTER)
+ private org.eclipse.uml2.uml.Class class2;
+
+ protected FilterAndInfoViewTestFactory improvedViewTestFactory;
+
+ private Model umlModel;
+
+
+
+ @BeforeEach
+ public void setup() {
+ improvedViewTestFactory = new FilterAndInfoViewTestFactory(getVirtualModel());
+ final Procedure1 setNameFunction = (Model it) -> {
+ it.setName(UML_MODEL_NAME);
+ };
+ createBiggerUmlModel(setNameFunction);
+ }
+
+
+ @Test
+ public void testUmlView() throws NoSuchMethodException, InvocationTargetException, IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
+ View createUmlView = improvedViewTestFactory.createUmlView();
+ Collection rootObjects = createUmlView.getRootObjects();
+ //Expected: Selection should contain ModelImpl, and two SystemImpl. Only the ModelImpl should be selected.
+ //Root Objects should only contain ModelImpl
+ assertEquals(countContainedModelImplInstances(rootObjects), 1);
+ assertEquals(1, rootObjects.size());
+ for (EObject root : rootObjects) {
+ assertTrue(root instanceof ModelImpl);
+ assertEquals(UML_MODEL_URI, ((ModelImpl) root).getURI());
+ }
+ }
+
+
+ @Test
+ public void testCreateFilteredUmlView() {
+ Function function = (EObject object) -> hasNoAttribute(object, "testClass2");
+ View view = improvedViewTestFactory.createFilteredUmlView(function);
+
+ view.update();
+ view.update();
+ Collection rootObjects = view.getRootObjects();
+ assertEquals(rootObjects.size(), 1);
+ //Expected:
+ //Selection: Only ModelImpl with class "testClass2" as only PackagedElement
+ //Root Objects: same structure as in selection
+ for (EObject root : rootObjects) {
+ assertTrue(root instanceof Model);
+ assertTrue(view.getSelection().isViewObjectSelected(root));
+ assertEquals(root.eContents().size(), 1);
+ EObject eObject = root.eContents().get(0);
+ assertTrue(eObject instanceof org.eclipse.uml2.uml.Class);
+ org.eclipse.uml2.uml.Class classObject = (Class) eObject;
+ assertEquals(classObject.getName(), "testClass2");
+ }
+
+ modifyModel();
+ view.update();
+ view.getSelection();
+ //Expected: Selection: Only ModelImpl with two Class Objects, both with the name testClass2 as packagedElements
+ //Root Objects: The same
+ Collection modifiedRootObjects = view.getRootObjects();
+ assertEquals(modifiedRootObjects.size(), 1);
+ for (EObject root : modifiedRootObjects) {
+ assertTrue(root instanceof Model);
+ assertTrue(view.getSelection().isViewObjectSelected(root));
+ assertEquals(root.eContents().size(), 2);
+ for (EObject eObject : root.eContents()) {
+ assertTrue(eObject instanceof org.eclipse.uml2.uml.Class);
+ org.eclipse.uml2.uml.Class classObject = (Class) eObject;
+ assertEquals(classObject.getName(), "testClass2");
+ }
+ }
+ }
+
+
+ @Test
+ public void testCreateFilteredUmlViewWithAdditionalPcmElementsInVsum() {
+ createPcmModel();
+ Function function = (EObject object) -> hasNoAttribute(object, "testClass2");
+
+ View view = improvedViewTestFactory.createFilteredUmlView(function);
+ view.update();
+ view.update();
+ //Expected Selection: Only ModelImpl with class object "testClass2" as only PackagedElement
+ //Root Objects: Same structure as selection
+ Collection rootObjects = view.getRootObjects();
+ assertEquals(rootObjects.size(), 1);
+ for (EObject root : rootObjects) {
+ assertTrue(root instanceof Model);
+ assertTrue(view.getSelection().isViewObjectSelected(root));
+ assertEquals(root.eContents().size(), 1);
+ for (EObject eObject : root.eContents()) {
+ assertTrue(eObject instanceof org.eclipse.uml2.uml.Class);
+ org.eclipse.uml2.uml.Class classObject = (Class) eObject;
+ assertEquals(classObject.getName(), "testClass2");
+ }
+ }
+
+ modifyModel();
+ view.update();
+ view.getSelection();
+ Collection modifiedRootObjects = view.getRootObjects();
+ assertEquals(modifiedRootObjects.size(), 1);
+ for (EObject root : modifiedRootObjects) {
+ assertTrue(root instanceof Model);
+ assertTrue(view.getSelection().isViewObjectSelected(root));
+ assertEquals(root.eContents().size(), 2);
+ for (EObject eObject : root.eContents()) {
+ assertTrue(eObject instanceof org.eclipse.uml2.uml.Class);
+ org.eclipse.uml2.uml.Class classObject = (Class) eObject;
+ assertEquals(classObject.getName(), "testClass2");
+ }
+ }
+
+ view.getViewType();
+ }
+
+
+ @Test
+ public void testPcmView() throws NoSuchMethodException, InvocationTargetException, IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
+ createPcmModel();
+ View createPcmView = improvedViewTestFactory.createPcmView();
+ Collection rootObjects = createPcmView.getRootObjects();
+ ViewSelection selection = createPcmView.getSelection();
+ //Selection should contain 20 elements (0-19) with two RepositoryImpl selected.
+ //Root elements should be two RepositoryImpl
+ assertEquals(2, rootObjects.size());
+ for (EObject root : rootObjects) {
+ assertTrue(root instanceof Repository);
+ }
+ }
+
+
+ @Test
+ public void testCreateFilteredPcmView() {
+ createPcmModel();
+ View view = improvedViewTestFactory.createFilteredPcmView((EObject object) -> hasInstanceName(object, PCM_BASIC_COMPONENT_NAME));
+ view.update();
+ view.update();
+
+ Collection rootObjects = view.getRootObjects();
+ assertEquals(rootObjects.size(), 1);
+ for (EObject root : rootObjects) {
+ assertTrue(root instanceof Repository);
+ assertTrue(view.getSelection().isViewObjectSelected(root));
+ assertEquals(root.eContents().size(), 1);
+ EObject eObject = root.eContents().get(0);
+ assertTrue(eObject instanceof BasicComponent);
+ BasicComponent classObject = (BasicComponent) eObject;
+ assertEquals(PCM_BASIC_COMPONENT_NAME, classObject.getEntityName());
+ }
+ //Expected: Selection: Only RepositoryImpl. Under eSettings is a list which contains the content of PCM_BASIC_COMPONENT_NAME
+ //Root Objects: Identical to Selection but with less null values in irrelevant fields
+ modifyModel();
+ view.update();
+ view.getSelection();
+ // Expected: Selection and Root objects should not have changed
+ Collection modifiedRootObjects = view.getRootObjects();
+ assertEquals(modifiedRootObjects.size(), 1);
+ for (EObject root : modifiedRootObjects) {
+ assertTrue(root instanceof Repository);
+ assertTrue(view.getSelection().isViewObjectSelected(root));
+ assertEquals(root.eContents().size(), 1);
+ EObject eObject = root.eContents().get(0);
+ assertTrue(eObject instanceof BasicComponent);
+ BasicComponent classObject = (BasicComponent) eObject;
+ assertEquals(PCM_BASIC_COMPONENT_NAME, classObject.getEntityName());
+ }
+ }
+
+ @Test
+ public void testCreateCountingView() {
+ Function function = (EObject object) -> hasNoAttribute(object, "testClass2");
+ View view = improvedViewTestFactory.createCountUmlElementsView(function);
+ Assertions.assertNotNull(view.getSelection(), "selection must not be null");
+
+ Collection rootObjects = view.getRootObjects();
+ assertEquals(rootObjects.size(), 1);
+ for (EObject root : rootObjects) {
+ assertTrue(root instanceof InformationStructure);
+ assertTrue(view.getSelection().isViewObjectSelected(root));
+ assertEquals(root.eContents().size(), 1);
+ EObject eObject = root.eContents().get(0);
+ assertTrue(eObject instanceof SingleInformation);
+ SingleInformation singleInformation = (SingleInformation) eObject;
+ assertEquals("Number of elements", singleInformation.getTitle());
+ assertEquals(1, singleInformation.getValue());
+ }
+
+ modifyModel();
+ view.update();
+
+ rootObjects = view.getRootObjects();
+ assertEquals(rootObjects.size(), 1);
+ for (EObject root : rootObjects) {
+ assertTrue(root instanceof InformationStructure);
+ assertTrue(view.getSelection().isViewObjectSelected(root));
+ assertEquals(root.eContents().size(), 1);
+ EObject eObject = root.eContents().get(0);
+ assertTrue(eObject instanceof SingleInformation);
+ SingleInformation singleInformation = (SingleInformation) eObject;
+ assertEquals("Number of elements", singleInformation.getTitle());
+ assertEquals(2, singleInformation.getValue());
+ }
+
+ view.getSelection();
+ }
+
+
+ @Test
+ public void testRenameClassInFilteredView() throws Exception {
+ Function function = (EObject object) -> hasNoAttribute(object, "testClass2");
+ View baselineUnfilteredUmlView = improvedViewTestFactory.createUmlView();
+ View filterView = improvedViewTestFactory.createFilteredUmlView(function);
+
+ improvedViewTestFactory.changeViewRecordingChanges(filterView, (CommittableView view) -> {
+ Model model = getDefaultUmlModel(view);
+ Class testClass2 = UmlQueryUtil.claimClass(model, "testClass2");
+ testClass2.setName(TEST_MODIFIED_CLASS_NAME);
+ });
+
+
+ //Test whether everything worked
+ //Is filtered view in correct state?
+ Collection filteredRootObjects = filterView.getRootObjects();
+ assertEquals(1, filteredRootObjects.size());
+ for (EObject filteredRoot : filteredRootObjects) {
+ EObject classObject = filteredRoot.eContents().get(0);
+ assertTrue(classObject instanceof Class);
+ assertEquals(TEST_MODIFIED_CLASS_NAME, ((Class) classObject).getName());
+ }
+ //Did the update of the vsum work? Is a newly created view in correct state?
+ View secondView = improvedViewTestFactory.createUmlView();
+ Collection newViewRootObjects = secondView.getRootObjects();
+ assertEquals(1, newViewRootObjects.size());
+ for (EObject viewRoot : newViewRootObjects) {
+ assertTrue(viewRoot instanceof Model);
+ if (viewRoot instanceof Model castedViewRoot) {
+ EObject classWithModifiedName = searchEObjectWithGivenNameInUmlModel(castedViewRoot, TEST_MODIFIED_CLASS_NAME);
+ assertTrue(classWithModifiedName != null);
+ assertTrue(classWithModifiedName instanceof Class);
+ EList testPackage = viewRoot.eContents().get(0).eContents();
+ assertEquals(4, testPackage.size());
+ assertEquals(1, testPackage.stream().filter(it -> {return (it instanceof PackageImpl);}).count());
+ assertEquals(2, testPackage.stream().filter(it -> {return (it instanceof ClassImpl);}).count());
+ assertEquals(1, testPackage.stream().filter(it -> {return (it instanceof PrimitiveTypeImpl);}).count());
+ }
+ }
+ }
+
+
+
+
+ protected void createBiggerUmlModel(final Procedure1 super Model> modelInitialization) {
+ try {
+ final Consumer firstChangeUmlFunction = (CommittableView it) -> {
+ umlModel = UMLFactory.eINSTANCE.createModel();
+ createAndRegisterRoot(it, umlModel, this.getUri(getProjectModelPath(UML_MODEL_NAME)));
+ modelInitialization.apply(umlModel);
+ umlModel.setURI(UML_MODEL_URI);
+ };
+ improvedViewTestFactory.changeUmlView(firstChangeUmlFunction);
+
+ getUserInteraction().addNextSingleSelection(1);
+ getUserInteraction().addNextTextInput("model/System.system");
+
+ final Consumer secondChangeUmlFunction = (CommittableView it) -> {
+ org.eclipse.uml2.uml.Package _createPackage = UMLFactory.eINSTANCE.createPackage();
+ Procedure1 setNameFunction = (org.eclipse.uml2.uml.Package it_1) -> {
+ it_1.setName("testPackage");
+ };
+
+ org.eclipse.uml2.uml.Package package1 = UMLFactory.eINSTANCE.createPackage();
+ package1.setName("testPackage");
+
+ class1 = package1.createOwnedClass("testClass1", false);
+
+ getUserInteraction().addNextSingleSelection(1);
+ getUserInteraction().addNextTextInput("model/System.system");
+ org.eclipse.uml2.uml.Package package2 = package1.createNestedPackage(NESTED_PACKAGE_TEST_NAME);
+
+ class2 = package2.createOwnedClass("testClass2", false);
+ EList _packagedElements = getDefaultUmlModel(it).getPackagedElements();
+ _packagedElements.add(package1);
+
+ // create Attribute for class2
+ PrimitiveType stringPrimitiveType = package1.createOwnedPrimitiveType("testPrimitiveType1");
+ class2.createOwnedAttribute("testClass2Attribute", stringPrimitiveType, 0, 1);
+ };
+ improvedViewTestFactory.changeUmlView(secondChangeUmlFunction);
+
+ } catch (Throwable _e) {
+ throw Exceptions.sneakyThrow(_e);
+ }
+ }
+
+ private void modifyModel() {
+ try {
+ getUserInteraction().addNextSingleSelection(1);
+ getUserInteraction().addNextTextInput("model/System.system");
+
+ Consumer changeUmlFunction = (CommittableView it) -> {
+ org.eclipse.uml2.uml.Package package3 = UMLFactory.eINSTANCE.createPackage();
+ package3.setName("testPackage3");
+
+ org.eclipse.uml2.uml.Class class3 = package3.createOwnedClass("testClass3", false);
+ org.eclipse.uml2.uml.Class class4 = package3.createOwnedClass("testClass2", false);
+
+ class2.addKeyword("subsequentlyAddedKeyword");
+
+ final Comment comment = this.class2.createOwnedComment();
+ comment.setBody("testCommentedClass2");
+ String searchedName = "testClass2";
+ comment.addKeyword("bla");
+
+ TreeIterator umlIterator = getDefaultUmlModel(it).eAllContents();
+ org.eclipse.uml2.uml.Class searchedClass = null;
+ while ((searchedClass == null) && (umlIterator.hasNext())) {
+ EObject next = umlIterator.next();
+ if (next instanceof org.eclipse.uml2.uml.Class) {
+ if (searchedName.equals(((Classifier) next).getName())) {
+ searchedClass = (org.eclipse.uml2.uml.Class) next;
+ }
+ }
+ }
+ searchedClass.getOwnedComments().add(comment);
+
+ getDefaultUmlModel(it).getPackagedElements().add(package3);
+ };
+
+ improvedViewTestFactory.changeUmlView(changeUmlFunction);
+ } catch (Throwable _e) {
+ throw Exceptions.sneakyThrow(_e);
+ }
+ }
+
+
+ protected void createPcmModel() {
+
+ getUserInteraction().addNextTextInput(PcmUmlClassApplicationTestHelper.UML_MODEL_FILE);
+ Consumer createPcmRepoFunction = (CommittableView it) -> {
+ Repository repository = RepositoryFactory.eINSTANCE.createRepository();
+ repository.setEntityName(PCM_MODEL_NAME);
+ it.registerRoot(repository, getUri(getPcmProjectModelPath(repository.getEntityName(), PCM_REPOSITORY_FILE_EXTENSION)));
+ };
+
+ try {
+ improvedViewTestFactory.changePcmView(createPcmRepoFunction);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ Consumer changePcmFunction = (CommittableView it) -> {
+ Repository repository = getDefaultPcmRepository(it);
+ BasicComponent createBasicComponent = RepositoryFactory.eINSTANCE.createBasicComponent();
+ createBasicComponent.setEntityName(PCM_BASIC_COMPONENT_NAME);
+ repository.getComponents__Repository().add(createBasicComponent);
+
+ CompositeDataType compositeDataType1 = RepositoryFactory.eINSTANCE.createCompositeDataType();
+ compositeDataType1.setEntityName("testPcmCompositeDataType1");
+ repository.getDataTypes__Repository().add(compositeDataType1);
+
+ };
+
+ try {
+ improvedViewTestFactory.changePcmView(changePcmFunction);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+
+ private boolean hasInstanceName(EObject object, String name) {
+ if (object instanceof org.palladiosimulator.pcm.core.entity.NamedElement) {
+ if (name.equals(((org.palladiosimulator.pcm.core.entity.NamedElement) object).getEntityName())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+ private EObject searchEObjectWithGivenNameInUmlModel(Model model, String searchedName) {
+ TreeIterator umlIterator = model.eAllContents();
+ while (umlIterator.hasNext()) {
+ EObject next = umlIterator.next();
+ if (next instanceof org.eclipse.uml2.uml.Classifier) {
+ if (searchedName.equals(((Classifier) next).getName())) {
+ return next;
+ }
+ }
+ }
+ return null;
+ }
+
+
+ private Path getPcmProjectModelPath(String modelName, String modelFileExtension) {
+ return Path.of("pcm").resolve(modelName + "." + modelFileExtension);
+ }
+
+ protected void createAndRegisterRoot(final View view, final EObject rootObject, final URI persistenceUri) {
+ view.registerRoot(rootObject, persistenceUri);
+ }
+
+ protected Path getProjectModelPath(final String modelName) {
+ return Path.of(MODEL_FOLDER_NAME).resolve(((modelName + ".") + MODEL_FILE_EXTENSION));
+ }
+
+ protected Model getDefaultUmlModel(final View view) {
+ return UmlQueryUtil.claimUmlModel(view, UML_MODEL_NAME);
+ }
+
+ private Repository getDefaultPcmRepository(View view) {
+ return PcmQueryUtil.claimPcmRepository(view, PCM_MODEL_NAME);
+ }
+
+ @Override
+ protected Iterable extends ChangePropagationSpecification> getChangePropagationSpecifications() {
+ CombinedPcmToUmlClassReactionsChangePropagationSpecification _combinedPcmToUmlClassReactionsChangePropagationSpecification = new CombinedPcmToUmlClassReactionsChangePropagationSpecification();
+ CombinedUmlClassToPcmReactionsChangePropagationSpecification _combinedUmlClassToPcmReactionsChangePropagationSpecification = new CombinedUmlClassToPcmReactionsChangePropagationSpecification();
+ return Collections.unmodifiableList(
+ CollectionLiterals.newArrayList(
+ _combinedPcmToUmlClassReactionsChangePropagationSpecification,
+ _combinedUmlClassToPcmReactionsChangePropagationSpecification));
+ }
+
+
+ private int countContainedModelImplInstances(Collection collection) {
+ int count = 0;
+ Iterator iterator = collection.iterator();
+ while(iterator.hasNext()) {
+ EObject next = iterator.next();
+ if (next instanceof ModelImpl) {
+ count++;
+ }
+ }
+ return count;
+ }
+
+
+ private boolean hasNoAttribute(EObject object, String name) {
+ if (object instanceof org.eclipse.uml2.uml.Class) {
+ if (object instanceof NamedElement) {
+ if (name.equals(((NamedElement) object).getName())) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/tests/tools.vitruv.applications.viewfilter.tests/src/tools/vitruv/applications/viewfilter/utils/FluentUMLClassBuilder.java b/tests/tools.vitruv.applications.viewfilter.tests/src/tools/vitruv/applications/viewfilter/utils/FluentUMLClassBuilder.java
new file mode 100644
index 000000000..91c903d5f
--- /dev/null
+++ b/tests/tools.vitruv.applications.viewfilter.tests/src/tools/vitruv/applications/viewfilter/utils/FluentUMLClassBuilder.java
@@ -0,0 +1,63 @@
+package tools.vitruv.applications.viewfilter.utils;
+
+import java.util.List;
+
+import org.eclipse.emf.common.util.BasicEList;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.uml2.uml.Class;
+import org.eclipse.uml2.uml.Classifier;
+import org.eclipse.uml2.uml.Interface;
+import org.eclipse.uml2.uml.Type;
+import org.eclipse.uml2.uml.UMLFactory;
+
+import edu.kit.ipd.sdq.commons.util.java.Pair;
+
+public class FluentUMLClassBuilder {
+ private final Class result;
+
+ public FluentUMLClassBuilder(String name, boolean isFinal) {
+ result = UMLFactory.eINSTANCE.createClass();
+ result.setName(name);
+ result.setIsFinalSpecialization(isFinal);
+ }
+
+ public FluentUMLClassBuilder addDefaultConstructor() {
+ result.createOwnedOperation(result.getName(), new BasicEList<>(), new BasicEList<>());
+ return this;
+ }
+
+ public FluentUMLClassBuilder addParameterizedConstructor(List> parameters) {
+ EList parameterNames = new BasicEList<>();
+ EList parameterTypes = new BasicEList<>();
+ parameters.forEach(parameter -> {
+ parameterNames.add(parameter.get0());
+ parameterTypes.add(parameter.get1());
+ });
+ result.createOwnedOperation(result.getName(), parameterNames, parameterTypes);
+ return this;
+ }
+
+ public FluentUMLClassBuilder addAttribute(String name, Type type) {
+ result.createOwnedAttribute(name, type);
+ return this;
+ }
+
+ public FluentUMLClassBuilder addAttribute(String name, Type type, int lower, int upper) {
+ result.createOwnedAttribute(name, type, lower, upper);
+ return this;
+ }
+
+ public FluentUMLClassBuilder addGeneralization(Classifier parentClassifier) {
+ result.createGeneralization(parentClassifier);
+ return this;
+ }
+
+ public FluentUMLClassBuilder addInterfaceRealization(String name, Interface realizedInterface) {
+ result.createInterfaceRealization(name, realizedInterface);
+ return this;
+ }
+
+ public Class build() {
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/tests/tools.vitruv.applications.viewfilter.tests/src/tools/vitruv/applications/viewfilter/utils/FluentUMLPackageBuilder.java b/tests/tools.vitruv.applications.viewfilter.tests/src/tools/vitruv/applications/viewfilter/utils/FluentUMLPackageBuilder.java
new file mode 100644
index 000000000..eba0c86c4
--- /dev/null
+++ b/tests/tools.vitruv.applications.viewfilter.tests/src/tools/vitruv/applications/viewfilter/utils/FluentUMLPackageBuilder.java
@@ -0,0 +1,32 @@
+package tools.vitruv.applications.viewfilter.utils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.uml2.uml.Package;
+import org.eclipse.uml2.uml.PackageableElement;
+import org.eclipse.uml2.uml.UMLFactory;
+
+public class FluentUMLPackageBuilder {
+
+ private final String name;
+ private final List packagedElements = new ArrayList<>();
+
+ public FluentUMLPackageBuilder(String name) {
+ this.name = name;
+ }
+
+ public FluentUMLPackageBuilder addPackagedElement(PackageableElement element) {
+ this.packagedElements.add(element);
+ return this;
+ }
+
+ public Package build() {
+ Package result = UMLFactory.eINSTANCE.createPackage();
+
+ result.setName(name);
+ result.getPackagedElements().addAll(packagedElements);
+
+ return result;
+ }
+}
diff --git a/tests/tools.vitruv.applications.viewfilter.tests/src/tools/vitruv/applications/viewfilter/utils/PcmQueryUtil.xtend b/tests/tools.vitruv.applications.viewfilter.tests/src/tools/vitruv/applications/viewfilter/utils/PcmQueryUtil.xtend
new file mode 100644
index 000000000..a0f4014e4
--- /dev/null
+++ b/tests/tools.vitruv.applications.viewfilter.tests/src/tools/vitruv/applications/viewfilter/utils/PcmQueryUtil.xtend
@@ -0,0 +1,28 @@
+package tools.vitruv.applications.viewfilter.utils
+
+import edu.kit.ipd.sdq.activextendannotations.Utility
+import tools.vitruv.framework.views.View
+import org.palladiosimulator.pcm.repository.Repository
+import org.palladiosimulator.pcm.system.System
+import static extension edu.kit.ipd.sdq.commons.util.java.lang.IterableUtil.claimOne
+
+@Utility
+class PcmQueryUtil {
+
+ static def getPcmSystem(View view) {
+ view.getRootObjects(System)
+ }
+
+ static def getPcmRepository(View view) {
+ view.getRootObjects(Repository)
+ }
+
+ static def claimPcmRepository(View view, String packageName) {
+ var list = getPcmRepository(view).iterator.filter[it.entityName.equals(packageName)].toList
+ getPcmRepository(view).iterator.filter[it.entityName.equals(packageName)].toIterable.claimOne
+ }
+
+ static def claimPcmSystem(View view) {
+ getPcmSystem(view).claimOne
+ }
+}
\ No newline at end of file
diff --git a/tests/tools.vitruv.applications.viewfilter.tests/src/tools/vitruv/applications/viewfilter/utils/PcmUmlClassApplicationTestHelper.xtend b/tests/tools.vitruv.applications.viewfilter.tests/src/tools/vitruv/applications/viewfilter/utils/PcmUmlClassApplicationTestHelper.xtend
new file mode 100644
index 000000000..a327d91ba
--- /dev/null
+++ b/tests/tools.vitruv.applications.viewfilter.tests/src/tools/vitruv/applications/viewfilter/utils/PcmUmlClassApplicationTestHelper.xtend
@@ -0,0 +1,23 @@
+package tools.vitruv.applications.viewfilter.utils
+
+class PcmUmlClassApplicationTestHelper {
+
+ public static val IMPL_SUFFIX = "Impl"
+
+ public static val COMPOSITE_DATATYPE_NAME = "TestCompositeType"
+ public static val COMPOSITE_DATATYPE_NAME_2 = "TestCompositeType_2"
+
+ public static val COMPONENT_NAME_USC = "TestComponent"
+ public static val COMPONENT_NAME_LSC = "testComponent"
+ public static val COMPONENT_NAME_2_USC = "TestComponent_2"
+ public static val COMPONENT_NAME_2_LSC = "testComponent_2"
+
+ public static final String MODEL_DIRECTORY = "model";
+ public static final String PCM_REPOSITORY_FILE_NAME = "Repository";
+ public static final String UML_MODEL_FILE_NAME = PCM_REPOSITORY_FILE_NAME;
+ public static final String UML_EXTENSION = ".uml";
+
+
+ public static val UML_MODEL_FILE = MODEL_DIRECTORY + "/" + UML_MODEL_FILE_NAME +
+ UML_EXTENSION
+}
\ No newline at end of file