From 0ad653026e8128f0482c203c5699532ee40ac1a9 Mon Sep 17 00:00:00 2001 From: Csaba Debreceni Date: Wed, 11 Nov 2020 12:18:44 +0100 Subject: [PATCH 1/4] Disable filtering the feature _representation #63 --- .../com/incquerylabs/v4md/internal/MagicDrawProjectScope.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/internal/MagicDrawProjectScope.java b/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/internal/MagicDrawProjectScope.java index bbb8121..aeaec0b 100644 --- a/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/internal/MagicDrawProjectScope.java +++ b/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/internal/MagicDrawProjectScope.java @@ -42,7 +42,7 @@ private static boolean isReferenceToBeFiltered(EReference reference) { String name = reference.getName(); return (reference.isContainment() && name.contains("_from_")) || - name.startsWith("_"); + (!name.equals("_representation") && name.startsWith("_")); } static Stream getProjectModels(Project projectModel) { From 31a44201bd0725344ce1896503136777c41ebd0c Mon Sep 17 00:00:00 2001 From: Csaba Debreceni Date: Thu, 12 Nov 2020 10:50:35 +0100 Subject: [PATCH 2/4] Using env. option to enable diagram indexing #63 --- .../V4MDSpecificEnvironmentOptionsGroup.java | 39 +++++++- .../incquerylabs/v4md/ViatraQueryAdapter.java | 5 +- .../v4md/internal/MagicDrawProjectScope.java | 90 +++++++++++++------ 3 files changed, 104 insertions(+), 30 deletions(-) diff --git a/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/V4MDSpecificEnvironmentOptionsGroup.java b/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/V4MDSpecificEnvironmentOptionsGroup.java index 3d73507..fb51820 100644 --- a/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/V4MDSpecificEnvironmentOptionsGroup.java +++ b/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/V4MDSpecificEnvironmentOptionsGroup.java @@ -29,9 +29,14 @@ public class V4MDSpecificEnvironmentOptionsGroup extends AbstractPropertyOptionsGroup implements EnvironmentChangeListener { private static final String V4MD_DEVELOPER_MODE_REQUIRED = "Developer Mode is required. "; + private static final String V4MD_GROUP_ADVANCED_NAME = "Advanced"; private static final String V4MD_GROUP_DEBUGGING_NAME = "Debugging"; private static final String V4MD_GROUP_ID = "V4MD"; private static final String V4MD_GROUP_NAME = "V4MD"; + public static final String INDEX_DIAGRAM_ID = "INDEX_DIAGRAM_ID"; + private static final String INDEX_DIAGRAM_NAME = "Enable Diagram Content Indexing"; + private static final String INDEX_DIAGRAM_DESCRIPTION = "By default, contents of the diagrams are not indexed. When diagram content indexing is enabled, diagram related queries can be defined. However, performance issues may occur due to the fact that more elements need to be indexed. After changing the property, you have to reload the currently open projects."; + private static final String INDEX_DIAGRAM_DESCRIPTION_ID = "INDEX_DIAGRAM_DESCRIPTION_ID"; public static final String USE_EMPTY_QUERY_SCOPE_ID = "USE_EMPTY_QUERY_SCOPE"; private static final String USE_EMPTY_QUERY_SCOPE_NAME = "Disable Model Indexing"; private static final String USE_EMPTY_QUERY_SCOPE_DESCRIPTION = "For debugging purposes, this property disables model indexing by V4MD and all queries will return an empty result. After changing the property, you have to reload the currently open projects."; @@ -77,7 +82,8 @@ public void loadOptions(Style style, boolean paramBoolean) { @Override public void setDefaultValues() { super.setDefaultValues(); - createUseEmptyQueryScope(false); + createDiagramContentIndexingProperty(false); + createUseEmptyQueryScopeProperty(false); setEditability(getProperty(USE_EMPTY_QUERY_SCOPE_ID)); } @@ -100,7 +106,7 @@ public boolean isEmptyQueryScopeRequired() { return returnValue; } - public void createUseEmptyQueryScope(boolean value) { + public void createUseEmptyQueryScopeProperty(boolean value) { Property emptyScopeProperty = new BooleanProperty(USE_EMPTY_QUERY_SCOPE_ID, value); emptyScopeProperty.setGroup(V4MD_GROUP_DEBUGGING_NAME); emptyScopeProperty.setResourceProvider(new PropertyResourceProvider() { @@ -117,6 +123,35 @@ public String getString(String key, Property property) { addProperty(emptyScopeProperty, USE_EMPTY_QUERY_SCOPE_DESCRIPTION_ID); } + @Used + public boolean isDiagramContentIndexingEnabled() { + + Property p = getProperty(INDEX_DIAGRAM_ID); + if (p == null) { + return false; // This property is not yet set. + } + + Boolean returnValue = (Boolean) p.getValue(); + return returnValue; + } + + public void createDiagramContentIndexingProperty(boolean value) { + Property emptyScopeProperty = new BooleanProperty(INDEX_DIAGRAM_ID, value); + emptyScopeProperty.setGroup(V4MD_GROUP_ADVANCED_NAME); + emptyScopeProperty.setResourceProvider(new PropertyResourceProvider() { + + @Override + public String getString(String key, Property property) { + if (Objects.equals(INDEX_DIAGRAM_ID, key)) + return INDEX_DIAGRAM_NAME; + if (Objects.equals(INDEX_DIAGRAM_DESCRIPTION_ID, key)) + return INDEX_DIAGRAM_DESCRIPTION; + return key; + } + }); + addProperty(emptyScopeProperty, INDEX_DIAGRAM_DESCRIPTION_ID); + } + private void setEditability(@CheckForNull Property p) { if(p == null) return; diff --git a/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/ViatraQueryAdapter.java b/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/ViatraQueryAdapter.java index c88a466..1143f8f 100644 --- a/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/ViatraQueryAdapter.java +++ b/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/ViatraQueryAdapter.java @@ -331,6 +331,9 @@ private static MagicDrawProjectScope createMagicDrawProjectScope(Project project if(V4MDSpecificEnvironmentOptionsGroup.getCurrentGroup().isEmptyQueryScopeRequired()) { return MagicDrawProjectScope.createMagicDrawEmptyProjectScope(project); } - return new MagicDrawProjectScope(project, ViatraQueryAdapterOptions.getInstance().isEnableEngineProfiling(), notifiers); + + boolean enableDiagramContentIndexing = V4MDSpecificEnvironmentOptionsGroup.getCurrentGroup().isDiagramContentIndexingEnabled(); + boolean enableProfiler = ViatraQueryAdapterOptions.getInstance().isEnableEngineProfiling(); + return new MagicDrawProjectScope(project, enableProfiler, enableDiagramContentIndexing, notifiers); } } diff --git a/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/internal/MagicDrawProjectScope.java b/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/internal/MagicDrawProjectScope.java index aeaec0b..a2ac437 100644 --- a/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/internal/MagicDrawProjectScope.java +++ b/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/internal/MagicDrawProjectScope.java @@ -31,55 +31,88 @@ public class MagicDrawProjectScope extends EMFScope { private List listeners = new ArrayList<>(); private boolean useEmptyQueryScope = false; - // XXX Omitting references can cause semantic errors (so far we are in the clear though) - // these references are only present in UML profiles, typically their contents are equal to the original references inherited from the UML type hierarchy, however there are some cases when this might not be the case. - private static final BaseIndexOptions BASE_OPTIONS = new BaseIndexOptions() - .withFeatureFilterConfiguration(reference -> reference instanceof EReference && isReferenceToBeFiltered((EReference) reference)) + // XXX Omitting references can cause semantic errors (so far we are in the clear + // though) + // these references are only present in UML profiles, typically their contents + // are equal to the original references inherited from the UML type hierarchy, + // however there are some cases when this might not be the case. + private static final BaseIndexOptions BASE_OPTIONS = new BaseIndexOptions().withFeatureFilterConfiguration( + reference -> reference instanceof EReference && isReferenceToBeFiltered((EReference) reference, false)) .withStrictNotificationMode(false); - private static final BaseIndexOptions BASE_OPTIONS_WITH_PROFILER = BASE_OPTIONS.withIndexProfilerMode(ProfilerMode.START_DISABLED); - - private static boolean isReferenceToBeFiltered(EReference reference) { + private static final BaseIndexOptions BASE_OPTIONS_ENABLE_DIAGRAM = new BaseIndexOptions() + .withFeatureFilterConfiguration( + reference -> reference instanceof EReference && isReferenceToBeFiltered((EReference) reference, true)) + .withStrictNotificationMode(false); + private static final BaseIndexOptions BASE_OPTIONS_WITH_PROFILER = BASE_OPTIONS + .withIndexProfilerMode(ProfilerMode.START_DISABLED); + private static final BaseIndexOptions BASE_OPTIONS_ENABLE_DIAGRAM_WITH_PROFILER = BASE_OPTIONS_ENABLE_DIAGRAM + .withIndexProfilerMode(ProfilerMode.START_DISABLED); + + private static boolean isReferenceToBeFiltered(EReference reference, boolean enableDiagramContentIndexing) { String name = reference.getName(); - return (reference.isContainment() && name.contains("_from_")) - || - (!name.equals("_representation") && name.startsWith("_")); + if (reference.isContainment() && name.contains("_from_")) { + return true; + } else if (enableDiagramContentIndexing && !name.equals("_representation")) { + /* + * "_representation" is a special feature of the MagicDraw metamodel that + * describes the containment of diagram related representation elements + */ + return false; + } else if (name.startsWith("_")) { + return true; + } + return false; + } + + static BaseIndexOptions getBaseIndexOptions(boolean enableProfiler, boolean enableDiagramContentIndexing) { + if(enableProfiler) { + if(enableDiagramContentIndexing) + return BASE_OPTIONS_ENABLE_DIAGRAM_WITH_PROFILER; + return BASE_OPTIONS_WITH_PROFILER; + } else { + if(enableDiagramContentIndexing) + return BASE_OPTIONS_ENABLE_DIAGRAM; + return BASE_OPTIONS; + } } static Stream getProjectModels(Project projectModel) { Package primaryModel = projectModel.getPrimaryModel(); return projectModel.getModels().stream().filter(pkg -> pkg == primaryModel || !EcoreUtil.isAncestor(primaryModel, pkg)); } - + static Stream getCustomNotifiers(Notifier... notifiers) { return Arrays.stream(notifiers); } - + /** * A special constructor that provides the ability to create empty scope. */ private MagicDrawProjectScope(Project project) { - super(new ResourceSetImpl(), BASE_OPTIONS); //Mocking a dummy notifier + super(new ResourceSetImpl(), BASE_OPTIONS); // Mocking a dummy notifier this.project = project; this.customNotifiers = new Notifier[0]; this.useEmptyQueryScope = true; } - + /** - * Returns a special empty project scope associated to the given project where only a dummy notifier is indexed. + * Returns a special empty project scope associated to the given project where + * only a dummy notifier is indexed. + * * @param project associated to the empty scope * @return a special empty project scope */ public static MagicDrawProjectScope createMagicDrawEmptyProjectScope(Project project) { return new MagicDrawProjectScope(project); } - + public MagicDrawProjectScope(Project project, Notifier... notifiers) { - this(project, false, notifiers); + this(project, false, false, notifiers); } - - public MagicDrawProjectScope(Project project, boolean enableProfiler, Notifier... notifiers) { + + public MagicDrawProjectScope(Project project, boolean enableProfiler, boolean enableDiagramContentIndexing, Notifier... notifiers) { super(Stream.concat(getProjectModels(project), getCustomNotifiers(notifiers)).collect(Collectors.toSet()), - enableProfiler ? BASE_OPTIONS_WITH_PROFILER : BASE_OPTIONS); + getBaseIndexOptions(enableProfiler, enableDiagramContentIndexing)); this.project = project; this.customNotifiers = notifiers; } @@ -93,25 +126,28 @@ protected IEngineContext createEngineContext(ViatraQueryEngine engine, IIndexing Logger logger) { return new MagicDrawProjectEngineContext(this, errorListener, logger, useEmptyQueryScope); } - + public void projectStructureUpdated() { for (IProjectChangedListener listener : listeners) { listener.modelSetUpdated(); } } - + Stream getProjectModels() { return getProjectModels(project); } - + Stream getCustomNotifiers() { return getCustomNotifiers(customNotifiers); } - + public static MagicDrawProjectNavigationHelper extractNavigationHelper(ViatraQueryEngine engine) { final QueryScope scope = engine.getScope(); - if (scope instanceof MagicDrawProjectScope) - return (MagicDrawProjectNavigationHelper) ((EMFBaseIndexWrapper)AdvancedViatraQueryEngine.from(engine).getBaseIndex()).getNavigationHelper(); - else throw new IllegalArgumentException("Cannot extract EMF base index from VIATRA Query engine instantiated on non-EMF scope " + scope); + if (scope instanceof MagicDrawProjectScope) + return (MagicDrawProjectNavigationHelper) ((EMFBaseIndexWrapper) AdvancedViatraQueryEngine.from(engine) + .getBaseIndex()).getNavigationHelper(); + else + throw new IllegalArgumentException( + "Cannot extract EMF base index from VIATRA Query engine instantiated on non-EMF scope " + scope); } } From cd5c6b95e9bd44a052c86b8e69a46442012b508e Mon Sep 17 00:00:00 2001 From: Csaba Debreceni Date: Fri, 13 Nov 2020 13:30:01 +0100 Subject: [PATCH 3/4] Fix condition in filtering #63 --- .../com/incquerylabs/v4md/internal/MagicDrawProjectScope.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/internal/MagicDrawProjectScope.java b/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/internal/MagicDrawProjectScope.java index a2ac437..4f16a5a 100644 --- a/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/internal/MagicDrawProjectScope.java +++ b/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/internal/MagicDrawProjectScope.java @@ -52,7 +52,7 @@ private static boolean isReferenceToBeFiltered(EReference reference, boolean ena String name = reference.getName(); if (reference.isContainment() && name.contains("_from_")) { return true; - } else if (enableDiagramContentIndexing && !name.equals("_representation")) { + } else if (enableDiagramContentIndexing && name.equals("_representation")) { /* * "_representation" is a special feature of the MagicDraw metamodel that * describes the containment of diagram related representation elements From 75b9f328d73085362611d99e83430fa51bdf1072 Mon Sep 17 00:00:00 2001 From: Csaba Debreceni Date: Fri, 13 Nov 2020 13:32:56 +0100 Subject: [PATCH 4/4] Provide logging for init MDPScope and env options #63 --- .../incquerylabs/v4md/V4MDSpecificEnvironmentOptionsGroup.java | 3 +++ .../src/main/com/incquerylabs/v4md/ViatraQueryAdapter.java | 1 + 2 files changed, 4 insertions(+) diff --git a/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/V4MDSpecificEnvironmentOptionsGroup.java b/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/V4MDSpecificEnvironmentOptionsGroup.java index fb51820..bad6aae 100644 --- a/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/V4MDSpecificEnvironmentOptionsGroup.java +++ b/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/V4MDSpecificEnvironmentOptionsGroup.java @@ -128,10 +128,12 @@ public boolean isDiagramContentIndexingEnabled() { Property p = getProperty(INDEX_DIAGRAM_ID); if (p == null) { + logger.info("Diagram Content Indexing property is not yet set."); return false; // This property is not yet set. } Boolean returnValue = (Boolean) p.getValue(); + logger.info("Diagram Content Indexing property is currently set to " + returnValue.toString() + "."); return returnValue; } @@ -150,6 +152,7 @@ public String getString(String key, Property property) { } }); addProperty(emptyScopeProperty, INDEX_DIAGRAM_DESCRIPTION_ID); + logger.info("Diagram Content Indexing property is set to default."); } private void setEditability(@CheckForNull Property p) { diff --git a/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/ViatraQueryAdapter.java b/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/ViatraQueryAdapter.java index 1143f8f..3cc1dc1 100644 --- a/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/ViatraQueryAdapter.java +++ b/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/ViatraQueryAdapter.java @@ -334,6 +334,7 @@ private static MagicDrawProjectScope createMagicDrawProjectScope(Project project boolean enableDiagramContentIndexing = V4MDSpecificEnvironmentOptionsGroup.getCurrentGroup().isDiagramContentIndexingEnabled(); boolean enableProfiler = ViatraQueryAdapterOptions.getInstance().isEnableEngineProfiling(); + LOGGER.info("Initializing MagicDrawProject Scope with parameters enableProfiler=" + enableProfiler +" enableDiagramContentIndexing=" + enableDiagramContentIndexing); return new MagicDrawProjectScope(project, enableProfiler, enableDiagramContentIndexing, notifiers); } }