/*****************************************************************************
* Copyright (c) 2008 CEA LIST.
*
*
* 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:
* Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
* <a href="mailto:thomas.szadel@atosorigin.com">Thomas Szadel</a>: Code simplification and NPE
* management.
*
*****************************************************************************/
package org.eclipse.papyrus.infra.core.utils;
import static org.eclipse.papyrus.infra.core.Activator.log;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramEditor;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.papyrus.infra.core.editor.BackboneException;
import org.eclipse.papyrus.infra.core.editor.CoreMultiDiagramEditor;
import org.eclipse.papyrus.infra.core.editor.IMultiDiagramEditor;
import org.eclipse.papyrus.infra.core.resource.sasheditor.DiModelUtils;
import org.eclipse.papyrus.infra.core.sasheditor.contentprovider.IPageMngr;
import org.eclipse.papyrus.infra.core.sasheditor.contentprovider.ISashWindowsContentProvider;
import org.eclipse.papyrus.infra.core.sasheditor.di.contentprovider.DiSashModelMngr;
import org.eclipse.papyrus.infra.core.sasheditor.di.contentprovider.TransactionalDiSashModelMngr;
import org.eclipse.papyrus.infra.core.sasheditor.editor.IPage;
import org.eclipse.papyrus.infra.core.sasheditor.editor.ISashWindowsContainer;
import org.eclipse.papyrus.infra.core.services.ServiceException;
import org.eclipse.papyrus.infra.core.services.ServiceNotFoundException;
import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
/**
* Set of utility methods for the CoreEditor. <br>
* WARNING : Some of these methods rely on
* PlatformUI.getWorkbench().getActiveWorkbenchWindow()getActivePage() to lookup
* for shared objects owned by the main editor. This doesn't work during the
* initialization of the main editor because the main editor is not yet
* registered in the Eclipse workbench. This can lead to a null or an exception,
* and sometime this can lead to getting the shared object of another main
* editor !
*
* @author cedric dumoulin
* @author <a href="mailto:thomas.szadel@atosorigin.com">Thomas Szadel</a>
*/
// FIXME throws Exception (eg: NotFoundException) instead of null
public class EditorUtils {
/**
* Gets the {@link IMultiDiagramEditor} interface of the a Eclipse active
* editor, if possible, or null if not possible. <br>
* WARNING - This method doesn't work during the initialization of the main
* editor. See note in class doc. <br>
* This method return null if there is no active editor, or if the editor is
* not instance of IMultiDiagramEditor. <br>
* This method is designed to be used by ui actions that interact with the
* active editor. <br>
* This method should not be used during the editor initialization phase. <br>
* In any case, a check should be done on the returned value that can be
* null. Usage of this method is discouraged. Use {@link #getMultiDiagramEditorChecked()} instead.
*
*
* @return Get the current {@link IMultiDiagramEditor} or null if not found.
*/
public static IMultiDiagramEditor getMultiDiagramEditor() {
// Lookup ServiceRegistry
IWorkbenchWindow workbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
if(workbenchWindow == null) {
return null;
}
IWorkbenchPage page = workbenchWindow.getActivePage();
if(page == null) {
return null;
}
IEditorPart editor = page.getActiveEditor();
if(editor instanceof IMultiDiagramEditor) {
return (IMultiDiagramEditor)editor;
} else {
return null;
}
}
/**
* Gets the {@link IMultiDiagramEditor} interface of the a Eclipse active
* editor, if possible, or throw an exception if not possible. <br>
* WARNING - This method throw an exception during the initialization of the
* main editor. This method throws an exception if there is no active
* editor, or if the editor is not instance of IMultiDiagramEditor. <br>
* This method is designed to be used by ui actions that interact with the
* active editor. <br>
*
*
* @return Get the current {@link IMultiDiagramEditor} or null if not found.
* @throws BackboneException
* If it is not possible to get an instanceof {@link IMultiDiagramEditor}
*/
public static IMultiDiagramEditor getMultiDiagramEditorChecked() throws BackboneException {
IEditorPart editor;
try {
editor = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor();
} catch (NullPointerException e) {
// Can't get the active editor
throw new BackboneException("Can't get the current Eclipse Active Editor: There is no active editor at this time.");
}
if(editor instanceof IMultiDiagramEditor) {
return (IMultiDiagramEditor)editor;
} else {
throw new BackboneException("Can't get an Active Editor instance of IMultiDiagramEditor. (actual type:" + editor.getClass().getName() + ")");
}
}
/**
* Gets the opened multi-diagram editors.
*
* @return The opened {@link IMultiDiagramEditor} or null if an error
* occured.
*/
public static IMultiDiagramEditor[] getMultiDiagramEditors() {
// Lookup ServiceRegistry
IWorkbenchWindow workbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
if(workbenchWindow == null) {
return null;
}
IWorkbenchPage page = workbenchWindow.getActivePage();
if(page == null) {
return null;
}
List<IMultiDiagramEditor> list = new ArrayList<IMultiDiagramEditor>();
for(IEditorReference editorRef : page.getEditorReferences()) {
IEditorPart editorPart = editorRef.getEditor(false);
if(editorPart instanceof IMultiDiagramEditor) {
list.add((IMultiDiagramEditor)editorPart);
}
}
return list.toArray(new IMultiDiagramEditor[list.size()]);
}
/**
* Returns the editors that are related to to given file.<BR>
*
* @param file
* The file (model, di or notation).
* @return The associated editors.
*/
public static IMultiDiagramEditor[] getRelatedEditors(IFile file) {
// Get the DI file
IFile diFile = DiModelUtils.getRelatedDiFile(file);
if(diFile == null || !diFile.exists()) {
return new IMultiDiagramEditor[0];
}
IMultiDiagramEditor[] openedEditors = EditorUtils.getMultiDiagramEditors();
if(openedEditors == null) {
return new IMultiDiagramEditor[0];
}
List<IMultiDiagramEditor> list = new ArrayList<IMultiDiagramEditor>(openedEditors.length);
for(IMultiDiagramEditor editorPart : openedEditors) {
if(editorPart.getEditorInput() instanceof IFileEditorInput && diFile.equals(((IFileEditorInput)editorPart.getEditorInput()).getFile())) {
list.add(editorPart);
}
}
return list.toArray(new IMultiDiagramEditor[list.size()]);
}
/**
* Get the {@link ServicesRegistry}of the currently active eclipse editor. <br>
* WARNING - This method doesn't work during the initialization of the main
* editor. See note in class doc. <br>
* This method return null if the ServicesRegistry can not be found. <br>
* This method is designed to be used by ui actions that interact with the
* active editor. <br>
* This method should not be used during the editor initialization phase. <br>
* In any case, a check should be done on the returned value that can be
* null. An alternative is to use {@link #getServiceRegistryChecked()} and
* to catch the exception. <br>
* It is preferable to retrieve the ServiceRegistry from elsewhere whenever
* it is possible. <br>
* In GMF EditParts or EditPolicies, the ServiceRegistry can be retrieved
* with methods from
* org.eclipse.papyrus.uml.diagram.common.util.ServiceUtilsForGMF
*
* <br>
* WARNING: This method can return null if there is no Active Editor. This
* happen during the editor initialization, especially when there is no
* other editor opened.
*
* @return The {@link ServicesRegistry} or null if not found.
* @deprecated Check
* modeling/org.eclipse.mdt.papyrus/trunk/doc/DevelopperDocuments
* /cookbook/PapyrusCookBook.odt and use one of the replacement:
* <ul>
* <li>org.eclipse.papyrus.infra.core.utils.ServiceUtils</li>
* <li>
* org.eclipse.papyrus.uml.diagram.common.util.ServiceUtilsForGMF</li>
* <li>
* org.eclipse.papyrus.infra.core.utils.ServiceUtilsForActionHandlers (to be used with care !)</li>
* </ul>
*/
static public ServicesRegistry getServiceRegistry() {
// Lookup ServiceRegistry
IMultiDiagramEditor editor = getMultiDiagramEditor();
return editor == null ? null : (ServicesRegistry)editor.getAdapter(ServicesRegistry.class);
}
/**
* Get the service registry of the currently active main editor. <br>
* WARNING - This method doesn't work during the initialization of the main
* editor. See note in class doc.
*
* @return The {@link ServicesRegistry} or null if not found.
* @throws ServiceException
* If an error occurs.
* @deprecated Check
* modeling/org.eclipse.mdt.papyrus/trunk/doc/DevelopperDocuments
* /cookbook/PapyrusCookBook.odt and use one of the replacement:
* <ul>
* <li>org.eclipse.papyrus.infra.core.utils.ServiceUtils</li>
* <li>
* org.eclipse.papyrus.uml.diagram.common.util.ServiceUtilsForGMF</li>
* <li>
* org.eclipse.papyrus.infra.core.utils.ServiceUtilsForActionHandlers (to be used with care !)</li>
* </ul>
*/
static public ServicesRegistry getServiceRegistryChecked() throws ServiceException {
// Lookup ServiceRegistry
IMultiDiagramEditor editor = getMultiDiagramEditor();
if(editor == null) {
throw new ServiceException("Can't get ServiceRegistry");
}
return (ServicesRegistry)editor.getAdapter(ServicesRegistry.class);
}
/**
* Get the ISashWindowsContentProvider of the active Eclipse Editor, if
* possible. <br>
* This method return null if the ServiceRegistry can not be found or if an
* error occur. <br>
* This method is designed to be used by ui actions that interact with the
* active editor. <br>
* This method should not be used during the editor initialization phase. <br>
* In any case, a check should be done on the returned value that can be
* null. <br>
*
* @return the ISashWindowsContentProvider from the main editor or null if
* not found.
* @deprecated Check
* modeling/org.eclipse.mdt.papyrus/trunk/doc/DevelopperDocuments
* /cookbook/PapyrusCookBook.odt and use one of the replacement:
* <ul>
* <li>org.eclipse.papyrus.infra.core.utils.ServiceUtils</li>
* <li>
* org.eclipse.papyrus.uml.diagram.common.util.ServiceUtilsForGMF</li>
* <li>
* org.eclipse.papyrus.infra.core.utils.ServiceUtilsForActionHandlers (to be used with care !)</li>
* </ul>
*/
static public ISashWindowsContentProvider getISashWindowsContentProvider() {
try {
return getServiceRegistryChecked().getService(ISashWindowsContentProvider.class);
} catch (ServiceException e) {
// The contract says that we return null if not found
return null;
}
}
/**
* Get the ISashWindowsContentProvider of the active Eclipse Editor, if
* possible. <br>
* This method return null if the ServiceRegistry can not be found or if an
* error occur. <br>
* This method is designed to be used by ui actions that interact with the
* active editor. <br>
* This method should not be used during the editor initialization phase. <br>
* In any case, a check should be done on the returned value that can be
* null.
*
* @return the ISashWindowsContentProvider from the main editor or null if
* not found.
* @deprecated Check
* modeling/org.eclipse.mdt.papyrus/trunk/doc/DevelopperDocuments
* /cookbook/PapyrusCookBook.odt and use one of the replacement:
* <ul>
* <li>org.eclipse.papyrus.infra.core.utils.ServiceUtils</li>
* <li>
* org.eclipse.papyrus.uml.diagram.common.util.ServiceUtilsForGMF</li>
* <li>
* org.eclipse.papyrus.infra.core.utils.ServiceUtilsForActionHandlers (to be used with care !)</li>
* </ul>
*/
public static IPageMngr getIPageMngr() {
try {
return getServiceRegistryChecked().getService(IPageMngr.class);
} catch (ServiceException e) {
// The contract says that we return null if not found
return null;
}
}
/**
* Get the Eclipse ActiveEditor.
*
* @return The active {@link CoreMultiDiagramEditor} or null if not found.
* @deprecated Use {@link EditorUtils#getMultiDiagramEditor()}
*/
@Deprecated
protected static IEditorPart getWorkbenchActiveEditor() {
IMultiDiagramEditor editorPart = getMultiDiagramEditor();
if(editorPart instanceof CoreMultiDiagramEditor) {
return editorPart;
} else {
return null;
}
}
/**
* Create an instance of IPageMngr acting on the provided resource. This
* instance is suitable to add, remove, close or open diagrams.
*
* @param diResource
* @return The non transactional implementation of IPageMngr
*/
public static IPageMngr getIPageMngr(Resource diResource) {
return DiSashModelMngr.createIPageMngr(diResource);
}
/**
* Create an instance of IPageMngr acting on the provided resource. This
* instance is suitable to add, remove, close or open diagrams.
*
* @param diResource
* @param editingDomain
*
* @return The transactional implementation of IPageMngr
*/
public static IPageMngr getTransactionalIPageMngr(Resource diResource, TransactionalEditingDomain editingDomain) {
return TransactionalDiSashModelMngr.createIPageMngr(diResource, editingDomain);
}
/**
* Lookup the currently active Diagram from the Papyrus editor. Return the
* current Diagram or null if none is active. <br>
* WARNING - This method doesn't work during the initialization of the main
* editor. See note in class doc. <br>
* This method return null if the ServicesRegistry can not be found. <br>
* TODO This method introduce dependency on GMF. It can be moved to a GMF
* plugin.
*
* @return The active diagram or null if not found.
*
* @deprecated The core do make suppositions about the type of nested
* Editors, GMF stuff should be moved in GMF projects. In many
* case, {@link #lookupActiveNestedIEditor()} can be used.
*/
public static Diagram lookupEditorActiveDiagram() {
DiagramEditor diagEditor = lookupActiveDiagramEditor();
return diagEditor == null ? null : diagEditor.getDiagram();
}
/**
* Lookup the currently active Diagram from the Papyrus editor. Return the
* current Diagram or null if none is active. <br>
* WARNING - This method doesn't work during the initialization of the main
* editor. See note in class doc. <br>
* This method return null if the ServicesRegistry can not be found. <br>
* TODO This method introduce dependency on GMF. It can be moved to a GMF
* plugin.
*
* @return the active diagram editor or null if not found.
*
* @deprecated The core do make suppositions about the type of nested
* Editors, GMF stuff should be moved in GMF projects. In many
* case, {@link #lookupActiveNestedIEditor()} can be used.
*/
public static DiagramEditor lookupActiveDiagramEditor() {
// Get the active page within the sashcontainer
IEditorPart activeEditor = lookupActiveNestedIEditor();
// Check if it is a GMF DiagramEditor
if(activeEditor instanceof DiagramEditor) {
return ((DiagramEditor)activeEditor);
} else {
// Not found
return null;
}
}
/**
* Lookup the currently active {@link IEditorPart} from the Papyrus editor.
* Return the current nested editor part, or null if it can not be found. <br>
* WARNING - This method doesn't work during the initialization of the main
* editor. See note in class doc. <br>
* This method return null if the ServicesRegistry can not be found. <br>
* This method is designed to be used by ui actions that interact with the
* active editor. <br>
* This method should not be used during the editor initialization phase. <br>
* In any case, a check should be done on the returned value that can be
* null. An alternative is to use
* serviceRegistry.getService(ISashWindowsContainer
* .class).getActiveEditor(); <br>
* It is preferable to retrieve the ServiceRegistry from elsewhere whenever
* it is possible. <br>
*
*
* @return
* @deprecated Check
* modeling/org.eclipse.mdt.papyrus/trunk/doc/DevelopperDocuments
* /cookbook/PapyrusCookBook.odt and use one of the replacement:
* <ul>
* <li>org.eclipse.papyrus.infra.core.utils.ServiceUtils</li>
* <li>
* org.eclipse.papyrus.uml.diagram.common.util.ServiceUtilsForGMF</li>
* <li>
* org.eclipse.papyrus.infra.core.utils.ServiceUtilsForActionHandlers (to be used with care !)</li>
* </ul>
*/
public static IEditorPart lookupActiveNestedIEditor() {
// Get the sashwindow container
ISashWindowsContainer container = getSashWindowContainer();
// Get the active page within the sashcontainer
return container == null ? null : container.getActiveEditor();
}
/**
* Lookup the currently active IEditor in the SashSystem. If the currently
* eclipse active editor doesn't contains a {@link ISashWindowsContainer},
* return null. If the current SashSystem page is not a IEditor, return
* null. <br>
* WARNING - This method doesn't work during the initialization of the main
* editor. See note in class doc. <br>
* This method return null if the ServicesRegistry can not be found. <br>
* This method is designed to be used by ui actions that interact with the
* active editor. <br>
* This method should not be used during the editor initialization phase. <br>
* In any case, a check should be done on the returned value that can be
* null. An alternative is to use
* serviceRegistry.getService(ISashWindowsContainer
* .class).getActiveSashWindowsPage(); <br>
* It is preferable to retrieve the ServiceRegistry from elsewhere whenever
* it is possible.
*
* @return
* @deprecated Check
* modeling/org.eclipse.mdt.papyrus/trunk/doc/DevelopperDocuments
* /cookbook/PapyrusCookBook.odt and use one of the replacement:
* <ul>
* <li>org.eclipse.papyrus.infra.core.utils.ServiceUtils</li>
* <li>
* org.eclipse.papyrus.uml.diagram.common.util.ServiceUtilsForGMF</li>
* <li>
* org.eclipse.papyrus.infra.core.utils.ServiceUtilsForActionHandlers (to be used with care !)</li>
* </ul>
*/
public static IPage lookupActiveNestedPage() {
// Get the sashwindow container
ISashWindowsContainer container = getSashWindowContainer();
// Get the active page within the sashcontainer
return container == null ? null : container.getActiveSashWindowsPage();
}
/**
*
* @return
*/
private static ISashWindowsContainer getSashWindowContainer() {
try {
return getServiceRegistryChecked().getService(ISashWindowsContainer.class);
} catch (ServiceException e) {
// The contract says that we return null if not found
return null;
}
}
/**
* Gets the di resource set.
*
* @return Get the current {@link DiResourceSet} or null if not found.
* @deprecated Check
* modeling/org.eclipse.mdt.papyrus/trunk/doc/DevelopperDocuments
* /cookbook/PapyrusCookBook.odt and use one of the replacement:
* <ul>
* <li>org.eclipse.papyrus.infra.core.utils.ServiceUtils</li>
* <li>
* org.eclipse.papyrus.uml.diagram.common.util.ServiceUtilsForGMF</li>
* <li>
* org.eclipse.papyrus.infra.core.utils.ServiceUtilsForActionHandlers (to be used with care !)</li>
* </ul>
*/
public static DiResourceSet getDiResourceSet() {
try {
ServicesRegistry registry = getServiceRegistry();
return registry == null ? null : registry.getService(DiResourceSet.class);
} catch (ServiceException e) {
log.error(e);
}
return null;
}
/**
* Gets the {@link TransactionalEditingDomain} of the current active Eclipse
* Editor. This method should be used only when it is sure that the active
* editor exist, and that you want the EditingDomain of this editor. <br>
* This method return null if the TransactionalEditingDomain can not be
* found. <br>
* This method is designed to be used by ui actions that interact with the
* active editor. <br>
* This method should not be used during the editor initialization phase. <br>
* In any case, a check should be done on the returned value that can be
* null. An alternative is to use {@link #getTransactionalEditingDomainChecked()} and to catch the
* exception. <br>
* It is preferable to use {@link #getTransactionalEditingDomain(ServicesRegistry)} whenever it is
* possible. <br>
* In GMF EditParts or EditPolicies, the ServiceRegistry can be retrieved
* with methods from
* org.eclipse.papyrus.uml.diagram.common.util.DiagramCoreServiceUtils <br>
* WARNING: This method can return null if there is no Active Editor. This
* happen during the editor initialization, especially when there is no
* other editor opened.
*
* @return Get the current {@link TransactionalEditingDomain} or null if not
* found
* @deprecated Check
* modeling/org.eclipse.mdt.papyrus/trunk/doc/DevelopperDocuments
* /cookbook/PapyrusCookBook.odt and use one of the replacement:
* <ul>
* <li>org.eclipse.papyrus.infra.core.utils.ServiceUtils</li>
* <li>
* org.eclipse.papyrus.uml.diagram.common.util.ServiceUtilsForGMF</li>
* <li>
* org.eclipse.papyrus.infra.core.utils.ServiceUtilsForActionHandlers (to be used with care !)</li>
* </ul>
*/
public static TransactionalEditingDomain getTransactionalEditingDomain() {
try {
ServicesRegistry registry = getServiceRegistry();
return registry == null ? null : registry.getService(TransactionalEditingDomain.class);
} catch (IllegalStateException e) {
// Registry can't be found, do nothing.
} catch (ServiceException e) {
log.error(e);
}
return null;
}
/**
* Gets the {@link TransactionalEditingDomain} of the current active Eclipse
* Editor. This method should be used only when it is sure that the active
* editor exist, and that you want the EditingDomain of this editor. <br>
* This method is designed to be used by ui actions that interact with the
* active editor. <br>
* This method should not be used during the editor initialization phase. <br>
* It is preferable to use {@link #getTransactionalEditingDomain(ServicesRegistry)} whenever it is
* possible. <br>
* This method throw a {@link ServiceException} if the
* TransactionalEditingDomain can not be found. <br>
* In GMF EditParts or EditPolicies, the ServiceRegistry can be retrieved
* with methods from
* org.eclipse.papyrus.uml.diagram.common.util.DiagramCoreServiceUtils
*
*
* WARNING: This method throws an exception when no Active Editor is found.
* This happen during the editor initialization, especially when there is no
* other editor opened.
*
* @return Get the current {@link TransactionalEditingDomain}
* @throws ServiceException
* @throws ServiceNotFoundException
* @deprecated Check
* modeling/org.eclipse.mdt.papyrus/trunk/doc/DevelopperDocuments
* /cookbook/PapyrusCookBook.odt and use one of the replacement:
* <ul>
* <li>org.eclipse.papyrus.infra.core.utils.ServiceUtils</li>
* <li>
* org.eclipse.papyrus.uml.diagram.common.util.ServiceUtilsForGMF</li>
* <li>
* org.eclipse.papyrus.infra.core.utils.ServiceUtilsForActionHandlers (to be used with care !)</li>
* </ul>
*/
public static TransactionalEditingDomain getTransactionalEditingDomainChecked() throws ServiceException {
try {
ServicesRegistry registry = getServiceRegistryChecked();
return registry.getService(TransactionalEditingDomain.class);
} catch (IllegalStateException e) {
throw new ServiceException(e);
} catch (Exception e) {
throw new ServiceException(e);
}
}
/**
* Gets the {@link TransactionalEditingDomain} registered in the {@link ServicesRegistry}.
*
* @param servicesRegistry
* @return
* @deprecated Check
* modeling/org.eclipse.mdt.papyrus/trunk/doc/DevelopperDocuments
* /cookbook/PapyrusCookBook.odt and use one of the replacement:
* <ul>
* <li>org.eclipse.papyrus.infra.core.utils.ServiceUtils</li>
* </ul>
*/
public static TransactionalEditingDomain getTransactionalEditingDomain(ServicesRegistry registry) {
try {
return registry.getService(TransactionalEditingDomain.class);
} catch (IllegalStateException e) {
// Registry can't be found, do nothing.
} catch (ServiceException e) {
log.error(e);
}
return null;
}
/**
* Gets the {@link TransactionalEditingDomain} registered in the {@link ServicesRegistry}.
*
* @param servicesRegistry
* @return
* @throws ServiceException
* If the TransactionalEditingDomain can not be found.
* @deprecated Check
* modeling/org.eclipse.mdt.papyrus/trunk/doc/DevelopperDocuments
* /cookbook/PapyrusCookBook.odt and use one of the replacement:
* <ul>
* <li>org.eclipse.papyrus.infra.core.utils.ServiceUtils</li>
* </ul>
*/
public static TransactionalEditingDomain getTransactionalEditingDomainChecked(ServicesRegistry registry) throws ServiceException {
return registry.getService(TransactionalEditingDomain.class);
}
}