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 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 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 createFilterSupportingIdentityMappingViewType(String name) { + return new FilterSupportingIdentityMappingViewType(name); + + } + + + public static ViewType 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 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 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 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 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 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 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 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 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