]> gerrit.simantics Code Review - simantics/platform.git/commitdiff
Rid TypicalPropertyTester of database read transactions 52/3352/3
authorTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Thu, 17 Oct 2019 07:52:39 +0000 (10:52 +0300)
committerjsimomaa <jani.simomaa@gmail.com>
Thu, 17 Oct 2019 08:13:28 +0000 (11:13 +0300)
After this, the normal workbench invocations of TypicalPropertyTester no
longer perform any database transactions to do their work. DiagramViewer
now has built-in support for doing the required queries based on
IDiagram hints alone.

gitlab #399

Change-Id: I0dcebcc871f72c16d58a932704c16398df9dd900

bundles/org.simantics.db.common/src/org/simantics/db/common/request/ResourceSetURIs.java [new file with mode: 0644]
bundles/org.simantics.db.common/src/org/simantics/db/common/request/TypeURIs.java [new file with mode: 0644]
bundles/org.simantics.diagram/src/org/simantics/diagram/ui/DiagramModelHints.java
bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/DiagramViewer.java
bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/HasDiagramSourceListener.java [new file with mode: 0644]
bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/handlers/e4/SyncCurrentTypicalInstanceWithTemplate.java
bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/handlers/e4/SyncCurrentTypicalTemplateToInstances.java
bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/property/TypicalPropertyTester.java

diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/request/ResourceSetURIs.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/request/ResourceSetURIs.java
new file mode 100644 (file)
index 0000000..0cc29e1
--- /dev/null
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Semantum Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.db.common.request;
+
+import java.util.Collections;
+import java.util.Set;
+
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.exception.DatabaseException;
+
+import gnu.trove.set.hash.THashSet;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.41.0, 1.35.2
+ */
+public class ResourceSetURIs extends UnaryRead<Set<Resource>, Set<String>> {
+
+    public ResourceSetURIs(Set<Resource> set) {
+        super(set);
+    }
+
+    @Override
+    public Set<String> perform(ReadGraph graph) throws DatabaseException {
+        if (parameter == null || parameter.isEmpty())
+            return Collections.emptySet();
+
+        Set<String> result = new THashSet<String>(parameter.size());
+        for (Resource r : parameter) {
+            String uri = graph.getPossibleURI(r);
+            if (uri != null)
+                result.add(uri);
+        }
+
+        return result;
+    }
+
+}
\ No newline at end of file
diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/request/TypeURIs.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/request/TypeURIs.java
new file mode 100644 (file)
index 0000000..bc8222b
--- /dev/null
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Semantum Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.db.common.request;
+
+import java.util.Set;
+
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.exception.DatabaseException;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.41.0, 1.35.2
+ */
+public class TypeURIs extends ResourceRead<Set<String>> {
+
+    public TypeURIs(Resource r) {
+        super(r);
+    }
+
+    @Override
+    public Set<String> perform(ReadGraph graph) throws DatabaseException {
+        Set<Resource> types = graph.getTypes(resource);
+        return graph.syncRequest(new ResourceSetURIs(types));
+    }
+
+}
\ No newline at end of file
index e410edb2a46f1e7b8fa28a06e3658573ac1361ec..84a25f2de4654eb489bed7460f8a5e1cd8f91c2a 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2019 Association for Decentralized Information Management
  * in Industry THTH ry.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
@@ -8,9 +8,12 @@
  *
  * Contributors:
  *     VTT Technical Research Centre of Finland - initial API and implementation
+ *     Semantum Oy - gitlab #399
  *******************************************************************************/
 package org.simantics.diagram.ui;
 
+import java.util.Set;
+
 import org.simantics.db.Resource;
 import org.simantics.db.UndoContext;
 import org.simantics.db.common.ResourceArray;
@@ -40,6 +43,29 @@ public class DiagramModelHints {
 
     public static final Key KEY_DIAGRAM_RESOURCE_ARRAY = new KeyOf(ResourceArray.class, "DIAGRAM_RESOURCE_ARRAY");
 
+    /**
+     * Holds a value of Set<String> which should contain the type {@link Resource}
+     * URIs of all the types of the diagram resource. This allows doing
+     * type-checking for the diagram based on pure string instead of having to do
+     * database transactions to check types.
+     */
+    public static final Key KEY_DIAGRAM_RESOURCE_TYPE_URIS = new KeyOf(Set.class, "DIAGRAM_RESOURCE_TYPE_URIS");
+
+    /**
+     * Holds a value of Set<String> which should contain the type {@link Resource}
+     * URIs of all the types of the composite resource mapped to the diagram
+     * resource. This allows doing type-checking for the diagram based on pure
+     * string instead of having to do database transactions to check types.
+     */
+    public static final Key KEY_MAPPED_COMPOSITE_RESOURCE_TYPE_URIS = new KeyOf(Set.class, "MAPPED_DIAGRAM_COMPOSITE_RESOURCE_TYPE_URIS");
+
+    /**
+     * Set to the object value if the current diagram editor has a single
+     * statement/object for the {@link ModelingResources#URIs#HasDiagramSource}
+     * relation.
+     */
+    public static final Key KEY_HAS_DIAGRAM_SOURCE = new KeyOf(Resource.class, "MOD.HasDiagramSource");
+
     /**
      * A hint for defining and extra pass for loading/initializing an element
      * after the current pass. It is possible to request for infinitely many
index e773a7a639b181cd46c1cce60d2794eae9c9dc52..a0f504030675d1b9129a6548550ef524b8f762fe 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2013 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2019 Association for Decentralized Information Management
  * in Industry THTH ry.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
@@ -8,7 +8,7 @@
  *
  * Contributors:
  *     VTT Technical Research Centre of Finland - initial API and implementation
- *     Semantum Oy - issue #4384
+ *     Semantum Oy - issue #4384, gitlab #399
  *******************************************************************************/
 package org.simantics.modeling.ui.diagramEditor;
 
@@ -41,9 +41,11 @@ import org.simantics.db.Resource;
 import org.simantics.db.Session;
 import org.simantics.db.WriteGraph;
 import org.simantics.db.common.primitiverequest.PossibleAdapter;
+import org.simantics.db.common.primitiverequest.PossibleObject;
 import org.simantics.db.common.procedure.adapter.ListenerDelegate;
 import org.simantics.db.common.procedure.adapter.ListenerSupport;
 import org.simantics.db.common.request.ParametrizedRead;
+import org.simantics.db.common.request.TypeURIs;
 import org.simantics.db.common.request.WriteRequest;
 import org.simantics.db.common.utils.CommonDBUtils;
 import org.simantics.db.common.utils.TagUtil;
@@ -104,6 +106,7 @@ import org.simantics.g2d.diagram.participant.ZOrderHandler;
 import org.simantics.g2d.diagram.participant.pointertool.PointerInteractor;
 import org.simantics.g2d.element.ElementClassProviders;
 import org.simantics.g2d.element.ElementClasses;
+import org.simantics.g2d.element.ElementUtils;
 import org.simantics.g2d.element.IElement;
 import org.simantics.g2d.element.IElementClassProvider;
 import org.simantics.g2d.element.handler.impl.StaticObjectAdapter;
@@ -184,7 +187,7 @@ public class DiagramViewer
         void doSetTitleToolTip(String name);
     }
 
-    public static final String                     DIAGRAMMING_CONTEXT      = "org.simantics.modeling.ui.diagramming"; //$NON-NLS-1$
+    public static final String                      DIAGRAMMING_CONTEXT      = "org.simantics.modeling.ui.diagramming"; //$NON-NLS-1$
     private static final String                     PREFERENCE_VIRTUAL_GRAPH = "preferences"; //$NON-NLS-1$
 
     private static final boolean                    PROFILE                  = false;
@@ -233,6 +236,7 @@ public class DiagramViewer
     protected GridSnapAdvisor            snapAdvisor;
 
     private RuntimeDiagramManager        runtimeDiagramManager;
+    private HasDiagramSourceListener     hasDiagramSourceListener;
 
     /**
      * Set externally in
@@ -631,14 +635,35 @@ public class DiagramViewer
      * @throws DatabaseException
      */
     protected IDiagram loadDiagram(IProgressMonitor monitor, Resource diagram, IHintContext initialHints) throws DatabaseException {
-       RuntimeDiagramManager rtdm = runtimeDiagramManager;
-       Resource runtimeDiagram = rtdm != null ? rtdm.getRuntimeDiagram() : null;
-       IDiagramLoader loader = synchronizer;
-       if (rtdm == null || runtimeDiagram == null || loader == null)
-               return null;
-        IDiagram d = sessionContext.getSession().syncRequest(
-                DiagramRequests.loadDiagram(monitor, getResourceInput2().getModel(null), diagram,
-                        runtimeDiagram, null, loader, initialHints));
+        RuntimeDiagramManager rtdm = runtimeDiagramManager;
+        Resource runtimeDiagram = rtdm != null ? rtdm.getRuntimeDiagram() : null;
+        IDiagramLoader loader = synchronizer;
+        if (rtdm == null || runtimeDiagram == null || loader == null)
+            return null;
+        IDiagram d = sessionContext.getSession().syncRequest((Read<IDiagram>) graph -> {
+            IDiagram result = DiagramRequests.loadDiagram(monitor, getResourceInput2().getModel(null), diagram,
+                    runtimeDiagram, null, loader, initialHints).perform(graph);
+
+            // #399: Enable certain PropertyTester implementation without database transactions
+            ModelingResources MOD = ModelingResources.getInstance(graph);
+            Resource composite = graph.getPossibleObject(diagram, MOD.DiagramToComposite);
+            result.setHint(
+                    DiagramModelHints.KEY_DIAGRAM_RESOURCE_TYPE_URIS,
+                    graph.syncRequest(new TypeURIs(diagram)));
+            result.setHint(
+                    DiagramModelHints.KEY_MAPPED_COMPOSITE_RESOURCE_TYPE_URIS,
+                    composite != null ? graph.syncRequest(new TypeURIs(composite)) : Collections.emptySet());
+
+            Resource diagramSource = graph.syncRequest(
+                    new PossibleObject(diagram, MOD.HasDiagramSource),
+                    hasDiagramSourceListener = new HasDiagramSourceListener(sourceDiagramContainer));
+            ElementUtils.setOrRemoveHint(
+                    result, 
+                    DiagramModelHints.KEY_HAS_DIAGRAM_SOURCE,
+                    diagramSource);
+
+            return result;
+        });
         return d;
     }
 
@@ -923,6 +948,12 @@ public class DiagramViewer
         }
 
         disposed = true;
+
+        if (hasDiagramSourceListener != null) {
+            hasDiagramSourceListener.dispose();
+            hasDiagramSourceListener = null;
+        }
+
         if (activation != null) {
             activation.deactivate();
             activation = null;
diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/HasDiagramSourceListener.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/HasDiagramSourceListener.java
new file mode 100644 (file)
index 0000000..c787367
--- /dev/null
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Semantum Oy - initial API and implementation, gitlab #399
+ *******************************************************************************/
+package org.simantics.modeling.ui.diagramEditor;
+
+import org.simantics.db.Resource;
+import org.simantics.db.common.procedure.adapter.DisposableListener;
+import org.simantics.diagram.ui.DiagramModelHints;
+import org.simantics.g2d.diagram.IDiagram;
+import org.simantics.g2d.element.ElementUtils;
+import org.simantics.utils.DataContainer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.41.0, 1.35.2
+ * @see gitlab #399
+ */
+class HasDiagramSourceListener extends DisposableListener<Resource> {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(HasDiagramSourceListener.class);
+
+    private DataContainer<IDiagram> diagramContainer;
+
+    public HasDiagramSourceListener(DataContainer<IDiagram> diagramContainer) {
+        this.diagramContainer = diagramContainer;
+    }
+
+    @Override
+    public void execute(Resource source) {
+        DataContainer<IDiagram> c = diagramContainer;
+        IDiagram d = c != null ? diagramContainer.get() : null;
+        if (d != null) {
+            ElementUtils.setOrRemoveHint(d, DiagramModelHints.KEY_HAS_DIAGRAM_SOURCE, source);
+        }
+    }
+
+    @Override
+    public void exception(Throwable t) {
+        LOGGER.error("Received unexpected exception", t);
+    }
+
+    @Override
+    public void dispose() {
+        super.dispose();
+        diagramContainer = null;
+    }
+
+}
index 714e72eb6c05b7ee19637ff533bc2f6630c5a3ac..fb6b31382579bebdd62181170fbaa80092a1d30c 100644 (file)
@@ -46,8 +46,7 @@ public class SyncCurrentTypicalInstanceWithTemplate {
         if (DatabaseJob.inProgress())
             return false;
         if (activeEditor.getEditorInput() instanceof IResourceEditorInput) {
-            IResourceEditorInput input = (IResourceEditorInput) activeEditor.getEditorInput();
-            return TypicalPropertyTester.isTypicalInstanceEditor(Simantics.getSession(), input.getResource());
+            return TypicalPropertyTester.isTypicalInstanceEditor(activeEditor);
         } else {
             return false;
         }
index bbafb03e0ce201b530166609745ac243fcdd3fd8..9fc604c6f879f497b0319c15559072e7c9dc473e 100644 (file)
@@ -45,8 +45,7 @@ public class SyncCurrentTypicalTemplateToInstances {
         if (DatabaseJob.inProgress())
             return false;
         if (activeEditor.getEditorInput() instanceof IResourceEditorInput) {
-            IResourceEditorInput input = (IResourceEditorInput) activeEditor.getEditorInput();
-            return TypicalPropertyTester.isTypicalMasterEditor(Simantics.getSession(), input.getResource());
+            return TypicalPropertyTester.isTypicalMasterEditor(activeEditor);
         } else {
             return false;
         }
index 679647a724de548f444ef596be59f4ddef17ed3f..b222d23e4038816e4b70d0dfb98a241c242cb72f 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2012 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2019 Association for Decentralized Information Management
  * in Industry THTH ry.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
@@ -8,26 +8,31 @@
  *
  * Contributors:
  *     VTT Technical Research Centre of Finland - initial API and implementation
+ *     Semantum Oy - gitlab #399
  *******************************************************************************/
 package org.simantics.modeling.ui.property;
 
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Set;
+
 import org.eclipse.core.expressions.PropertyTester;
-import org.eclipse.ui.IEditorInput;
+import org.eclipse.core.runtime.IAdaptable;
 import org.eclipse.ui.IEditorPart;
-import org.simantics.DatabaseJob;
 import org.simantics.Simantics;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.RequestProcessor;
 import org.simantics.db.Resource;
-import org.simantics.db.Session;
 import org.simantics.db.common.request.UniqueRead;
 import org.simantics.db.common.utils.RequestUtil;
 import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.request.Read;
 import org.simantics.diagram.stubs.DiagramResource;
+import org.simantics.diagram.ui.DiagramModelHints;
+import org.simantics.g2d.diagram.IDiagram;
 import org.simantics.modeling.ModelingResources;
+import org.simantics.modeling.ui.diagramEditor.DiagramViewer;
 import org.simantics.ui.SimanticsUI;
-import org.simantics.ui.workbench.IResourceEditorInput;
-import org.simantics.utils.ui.ErrorLogger;
 
 /**
  * @author Tuukka Lehtonen
@@ -49,74 +54,90 @@ public class TypicalPropertyTester extends PropertyTester {
     public boolean test(final Object receiver, final String property, final Object[] args, final Object expectedValue) {
         //System.out.println("TEST: " + receiver + ", " + property + ", " + Arrays.toString(args) + ", " + expectedValue);
 
-        try {
-            Session session = Simantics.peekSession();
-            if (session == null)
-                return false;
-
-            if (!(receiver instanceof IEditorPart))
-                return false;
-            IEditorPart editor = (IEditorPart) receiver;
-            IEditorInput in = editor.getEditorInput();
-            if (!(in instanceof IResourceEditorInput))
-                return false;
-            IResourceEditorInput input = (IResourceEditorInput) in;
-            final Resource inputResource = input.getResource();
-
-            if (DatabaseJob.inProgress()) {
-                // See Apros issue #9115
-                // Return true because it is often possible that the database
-                // will be busy when these properties are tested. In such cases
-                // the handlers/menu contributions using these tests would
-                // become disabled unless we return true here. It is up to the
-                // handlers to also make sure that their input is valid.
-                return true;
-            }
+        if (!(receiver instanceof IEditorPart))
+            return false;
 
-            if (IS_TYPICAL_MASTER_EDITOR.equals(property)) {
-                return isTypicalMasterEditor(session, inputResource);
-            } else if (IS_TYPICAL_INSTANCE_EDITOR.equals(property)) {
-                return isTypicalInstanceEditor(session, inputResource);
-            }
-        } catch (DatabaseException | InterruptedException e) {
-            ErrorLogger.defaultLogError(e);
+        if (IS_TYPICAL_MASTER_EDITOR.equals(property)) {
+            return isTypicalMasterEditor((IEditorPart) receiver);
+        } else if (IS_TYPICAL_INSTANCE_EDITOR.equals(property)) {
+            return isTypicalInstanceEditor((IEditorPart) receiver);
         }
 
         return false;
     }
 
-    public static boolean isTypicalMasterEditor(RequestProcessor processor, final Resource editorInputResource) throws DatabaseException, InterruptedException {
+    private static IDiagram getDiagram(IAdaptable editor) {
+        DiagramViewer viewer = editor.getAdapter(DiagramViewer.class);
+        return viewer != null ? viewer.getAdapter(IDiagram.class) : null;
+    }
+
+    private static Set<String> getDiagramMappedCompositeTypes(IDiagram diagram) {
+        Set<String> result = diagram != null ? diagram.getHint(DiagramModelHints.KEY_MAPPED_COMPOSITE_RESOURCE_TYPE_URIS) : null;
+        return result != null ? result :  Collections.emptySet();
+    }
+
+    private static Set<String> getDiagramMappedCompositeTypes(IAdaptable editor) {
+        return getDiagramMappedCompositeTypes( getDiagram(editor) );
+    }
+
+    public static boolean isTypicalMasterEditor(IAdaptable editor) {
+        Set<String> types = getDiagramMappedCompositeTypes(editor);
+        return types.contains(ModelingResources.URIs.MasterTypicalCompositeType);
+    }
+
+    private static boolean hasDiagramSource(IDiagram diagram) {
+        return diagram.getHint(DiagramModelHints.KEY_HAS_DIAGRAM_SOURCE) != null;
+    }
+
+    public static boolean isTypicalInstanceEditor(IAdaptable editor) {
+        IDiagram diagram = getDiagram(editor);
+        if (diagram == null)
+            return false;
+        Set<String> types = getDiagramMappedCompositeTypes(diagram);
+        return !types.contains(ModelingResources.URIs.MasterTypicalCompositeType)
+                && types.contains(ModelingResources.URIs.TypicalComposite)
+                && hasDiagramSource(diagram);
+    }
+
+    private static boolean timeoutingRead(RequestProcessor processor, Read<Boolean> read) throws DatabaseException, InterruptedException {
         return RequestUtil.trySyncRequest(
                 Simantics.getSession(),
                 SimanticsUI.UI_THREAD_REQUEST_START_TIMEOUT,
                 SimanticsUI.UI_THREAD_REQUEST_EXECUTION_TIMEOUT,
                 false,
-                new UniqueRead<Boolean>() {
+                read);
+    }
+
+    public static boolean isTypicalMasterEditor(RequestProcessor processor, Resource editorInputResource) throws DatabaseException, InterruptedException {
+        return timeoutingRead(processor, new UniqueRead<Boolean>() {
             @Override
             public Boolean perform(ReadGraph graph) throws DatabaseException {
-                ModelingResources MOD = ModelingResources.getInstance(graph);
-                Resource composite = graph.getPossibleObject(editorInputResource, MOD.DiagramToComposite);
-                return composite != null
-                        && graph.isInstanceOf(composite, MOD.MasterTypicalCompositeType);
+                return isTypicalMasterEditor(graph, editorInputResource);
             }
         });
     }
 
-    public static boolean isTypicalInstanceEditor(RequestProcessor processor, final Resource editorInputResource) throws DatabaseException, InterruptedException {
-        return RequestUtil.trySyncRequest(
-                Simantics.getSession(),
-                SimanticsUI.UI_THREAD_REQUEST_START_TIMEOUT,
-                SimanticsUI.UI_THREAD_REQUEST_EXECUTION_TIMEOUT,
-                false,
-                new UniqueRead<Boolean>() {
+    public static boolean isTypicalInstanceEditor(RequestProcessor processor, Resource editorInputResource) throws DatabaseException, InterruptedException {
+        return timeoutingRead(processor, new UniqueRead<Boolean>() {
             @Override
             public Boolean perform(ReadGraph graph) throws DatabaseException {
-                DiagramResource DIA = DiagramResource.getInstance(graph);
-                ModelingResources MOD = ModelingResources.getInstance(graph);
-                return graph.isInstanceOf(editorInputResource, DIA.Diagram)
-                        && graph.hasStatement(editorInputResource, MOD.HasDiagramSource);
+                return isTypicalInstanceEditor(graph, editorInputResource);
             }
         });
     }
 
+    public static boolean isTypicalMasterEditor(ReadGraph graph, Resource editorInputResource) throws DatabaseException {
+        ModelingResources MOD = ModelingResources.getInstance(graph);
+        Resource composite = graph.getPossibleObject(editorInputResource, MOD.DiagramToComposite);
+        return composite != null
+                && graph.isInstanceOf(composite, MOD.MasterTypicalCompositeType);
+    }
+
+    public static boolean isTypicalInstanceEditor(ReadGraph graph, Resource editorInputResource) throws DatabaseException {
+        DiagramResource DIA = DiagramResource.getInstance(graph);
+        ModelingResources MOD = ModelingResources.getInstance(graph);
+        return graph.isInstanceOf(editorInputResource, DIA.Diagram)
+                && graph.hasStatement(editorInputResource, MOD.HasDiagramSource);
+    }
+
 }