Skip to content

Commit

Permalink
Using env. option to enable diagram indexing #63
Browse files Browse the repository at this point in the history
  • Loading branch information
debrecenics committed Nov 12, 2020
1 parent 0ad6530 commit 31a4420
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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.";
Expand Down Expand Up @@ -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));
}

Expand All @@ -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() {
Expand All @@ -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;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,55 +31,88 @@ public class MagicDrawProjectScope extends EMFScope {
private List<IProjectChangedListener> 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<? extends Notifier> getProjectModels(Project projectModel) {
Package primaryModel = projectModel.getPrimaryModel();
return projectModel.getModels().stream().filter(pkg -> pkg == primaryModel || !EcoreUtil.isAncestor(primaryModel, pkg));
}

static Stream<Notifier> 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;
}
Expand All @@ -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<? extends Notifier> getProjectModels() {
return getProjectModels(project);
}

Stream<Notifier> 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);
}
}

0 comments on commit 31a4420

Please sign in to comment.