com.netxforge.netxstudio.screens.editing.CDOEditingService.java Source code

Java tutorial

Introduction

Here is the source code for com.netxforge.netxstudio.screens.editing.CDOEditingService.java

Source

/*******************************************************************************
 * Copyright (c) May 10, 2011 NetXForge.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *  You should have received a copy of the GNU Lesser General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>
 *
 * Contributors:
 *    Christophe Bouhier - initial API and implementation and/or initial documentation
 *******************************************************************************/
package com.netxforge.netxstudio.screens.editing;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.CDOState;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.eresource.util.EresourceAdapterFactory;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.util.CDOUtil;
import org.eclipse.emf.cdo.util.CommitException;
import org.eclipse.emf.cdo.view.CDOView;
import org.eclipse.emf.common.command.BasicCommandStack;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.ui.viewer.IViewerProvider;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.util.EcoreUtil.Copier;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.provider.ItemProviderAdapter;
import org.eclipse.emf.spi.cdo.FSMUtil;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.net4j.util.event.IListener;
import org.eclipse.swt.widgets.Display;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
import com.netxforge.base.cdo.CDO;
import com.netxforge.base.cdo.ICDOData;
import com.netxforge.base.data.IBaseData;
import com.netxforge.editing.base.impl.EMFEditingService;
import com.netxforge.netxstudio.common.model.StudioUtils;
import com.netxforge.netxstudio.generics.GenericsPackage;
import com.netxforge.netxstudio.generics.Person;
import com.netxforge.netxstudio.generics.Role;
import com.netxforge.netxstudio.generics.provider.GenericsItemProviderAdapterFactory;
import com.netxforge.netxstudio.geo.provider.GeoItemProviderAdapterFactory;
import com.netxforge.netxstudio.library.LibraryPackage;
import com.netxforge.netxstudio.library.NodeType;
import com.netxforge.netxstudio.library.provider.LibraryItemProviderAdapterFactory;
import com.netxforge.netxstudio.metrics.provider.MetricsItemProviderAdapterFactory;
import com.netxforge.netxstudio.operators.Node;
import com.netxforge.netxstudio.operators.OperatorsPackage;
import com.netxforge.netxstudio.operators.provider.OperatorsItemProviderAdapterFactory;
import com.netxforge.netxstudio.protocols.provider.ProtocolsItemProviderAdapterFactory;
import com.netxforge.netxstudio.provider.NetxstudioItemProviderAdapterFactory;
import com.netxforge.netxstudio.scheduling.provider.SchedulingItemProviderAdapterFactory;
import com.netxforge.netxstudio.screens.editing.dawn.DawnEMFEditorSupport;
import com.netxforge.netxstudio.screens.editing.dawn.IDawnEditor;
import com.netxforge.netxstudio.screens.editing.dawn.IDawnEditorSupport;
import com.netxforge.netxstudio.screens.editing.internal.EditingActivator;
import com.netxforge.netxstudio.services.provider.ServicesItemProviderAdapterFactory;
import com.netxforge.screens.editing.base.AbstractScreensViewPart;
import com.netxforge.screens.editing.base.IScreen;
import com.netxforge.screens.editing.base.IScreenProvider;

/**
 * For the lifetime of this service, we keep various editing facilities. We also
 * proxy to various other services, like a data and validation service.
 * 
 * @author Christophe Bouhier christophe.bouhier@netxforge.com
 * 
 */
public class CDOEditingService extends EMFEditingService
        implements ICDOEditingService, IDawnEditor, IViewerProvider, IScreenProvider {

    /**
     * Our editor support for Dawn.
     */
    private DawnEMFEditorSupport dawnEditorSupport;

    @Inject
    public CDOEditingService(ICDOData data) {
        super(data);
        dawnEditorSupport = new DawnEMFEditorSupport(this);
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.netxforge.netxstudio.screens.editing.dawn.IDawnEditor#getView()
     */
    public CDOView getView() {
        return dawnEditorSupport.getView();
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.netxforge.netxstudio.screens.editing.dawn.IDawnEditor#
     * getDawnEditorSupport()
     */
    public IDawnEditorSupport getDawnEditorSupport() {
        return dawnEditorSupport;
    }

    @Override
    public EditingDomain getEditingDomain() {
        if (domain == null) {
            BasicCommandStack commandStack = new BasicCommandStack();
            domain = new ScreensAdapterFactoryEditingDomain(getAdapterFactory(), commandStack);
        }
        return domain;
    }

    @Override
    public void doSave(IProgressMonitor monitor) {

        // save could be triggered from
        CDOView view = dawnEditorSupport.getView();
        if (view instanceof CDOTransaction) {

            if (view.isDirty()) {
                StudioUtils.cdoDumpDirtyObject((CDOTransaction) view);
            }

            if (((CDOTransaction) view).hasConflict()) {
                MessageDialog dialog = new MessageDialog(Display.getDefault().getActiveShell(), "Conflict", null,
                        "There is a conflict with another user. Would you like to rollback your current transaction?",
                        MessageDialog.QUESTION, new String[] { "yes", "no", "Cancel" }, 1);
                switch (dialog.open()) {
                case 0: // yes
                    ((IDawnEditor) this).getDawnEditorSupport().rollback();
                    break;
                case 1: // no
                    break;
                default: // cancel
                    break;
                }
            } else {
                // this.doSaveHistory(monitor);
                IRunnableWithProgress operation = doGetSaveOperation(monitor);
                if (operation == null)
                    return;
                try {
                    // This runs the options, and shows progress.
                    new ProgressMonitorDialog(Display.getDefault().getActiveShell()).run(true, false, operation);

                    // Refresh the necessary state.
                    ((BasicCommandStack) getEditingDomain().getCommandStack()).saveIsDone();

                } catch (Exception exception) {

                }
            }
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.netxforge.netxstudio.screens.editing.IEditingService#initScreen(int)
     */
    public Resource getData(int feature) {

        // Check if we have a view already.
        if (this.getView() != null) {
            // check if we can create the resource from the current view.
        }

        @SuppressWarnings("deprecation")
        Resource res = getCDOData().getResource(this.getEditingDomain().getResourceSet(), feature);

        if (res instanceof CDOResource) {
            dawnEditorSupport.setView(((CDOResource) res).cdoView());
            dawnEditorSupport.registerListeners();
        }
        return res;
    }

    public ICDOData getCDOData() {
        IBaseData data = getData();
        if (data instanceof ICDOData) {
            return (ICDOData) data;
        }
        throw new IllegalStateException("Expected instanceof ICDOData");
    }

    public Resource getData(EClass clazz) {

        sessionStillValid();
        Resource res = getCDOData().getResource(this.getEditingDomain().getResourceSet(), clazz);

        if (res instanceof CDOResource) {
            // we could fail adding listeners, as these might already exist.
            CDOView cdoView = ((CDOResource) res).cdoView();
            dawnEditorSupport.setView(cdoView);
            dawnEditorSupport.registerListeners();
        }

        return res;
    }

    public List<Resource> getData(String path) {
        // Check if we have a view already.
        sessionStillValid();
        List<Resource> resources = getCDOData().getResources(this.getEditingDomain().getResourceSet(), path);

        if (resources != null && resources.size() > 0) {
            dawnEditorSupport.setView(((CDOResource) resources.get(0)).cdoView());

            dawnEditorSupport.registerListeners();
        }
        return resources;
    }

    public void disposeData() {
        // Will dispose for all resources in the resource set.
        // We need a copy, as we will removing from the resourceset.
        ImmutableList<Resource> list = ImmutableList
                .copyOf(this.getEditingDomain().getResourceSet().getResources());

        for (Resource res : list) {
            disposeData(res);
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.netxforge.netxstudio.screens.editing.IEditingService#tearDownScreen
     * (int)
     */
    private void disposeData(Resource res) {

        if (res instanceof CDOResource) {
            CDOView v = dawnEditorSupport.getView();

            CDOResource cdoRes = (CDOResource) res;
            if (cdoRes.cdoView().equals(v)) {
                // Unload has no effect.
                if (cdoRes.isLoaded()) {
                    cdoRes.unload();
                }

                // Closes the view before de-registrating the listners to get
                // lifecycle notifications.
                dawnEditorSupport.close();

                // Clean up listeners.
                IListener[] listeners = cdoRes.cdoView().getListeners();
                if (listeners != null) {
                    for (IListener l : listeners) {
                        cdoRes.cdoView().removeListener(l);
                    }
                }
            }

        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.emf.common.ui.viewer.IViewerProvider#getViewer()
     */
    public Viewer getViewer() {
        return this.delegateViewerProvider.getViewer();
    }

    public IScreen getScreen() {
        return this.delegateScreenProvider.getScreen();
    }

    public IScreen[] getScreens() {
        return this.delegateScreenProvider.getScreens();
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.netxforge.netxstudio.screens.editing.IEditingService#isDirty()
     */
    public boolean isDirty() {

        boolean result = false;

        // CB 19-12-2011, disable dirty state for the editing domain, this will
        // force usage of
        // save link, when we deal with a detached object. (As a operations on a
        // detached object are not marked dirty in
        // in the CDO View).

        // boolean result = ((BasicCommandStack) getEditingDomain()
        // .getCommandStack()).isSaveNeeded();

        // Note views get dirty when invalidated ! state proxy.

        if (this.getView() != null) {
            boolean viewDirty = this.getView().isDirty();
            if (EditingActivator.DEBUG && viewDirty) {
                printDirtyState();
            }
            result |= viewDirty;
        }

        // Check the standalone transaction for dirtyness...
        CDOTransaction transaction = getCDOData().getTransaction();
        if (transaction != null) {
            boolean transactionDirty = transaction.isDirty();
            if (EditingActivator.DEBUG && transactionDirty) {
                printDirtyState(transaction);
            }
            if (transactionDirty) {
                result |= true;
            }
        }

        return result;
    }

    /*
     * Print the dirty state (If in debugging mode only).
     */
    private void printDirtyState() {
        EditingActivator.TRACE.trace(EditingActivator.TRACE_EDITING_OPTION, " Requesting dirty state");
        CDOView view = this.getView();
        printDirtyState(view);
    }

    private void printDirtyState(CDOView view) {
        if (view instanceof CDOTransaction) {
            CDOTransaction transaction = (CDOTransaction) view;
            Map<CDOID, CDOObject> dirtyObjects = transaction.getDirtyObjects();
            for (CDOID id : dirtyObjects.keySet()) {
                CDOObject cdoObject = dirtyObjects.get(id);
                EditingActivator.TRACE.trace(EditingActivator.TRACE_EDITING_OPTION,
                        "dirty object=" + cdoObject.cdoID().toURIFragment() + " , state=" + cdoObject.cdoState()
                                + ", rev=" + cdoObject.cdoRevision() + " , dangling state="
                                + cdoObject.cdoID().isDangling());
            }
        }
    }

    /**
     * Return the data status for this service.
     * 
     * @return
     */
    public String printDataStatus() {
        return getCDOData().toString();
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.netxforge.netxstudio.screens.editing.dawn.IDawnEditor#setDirty()
     */
    public void setDirty() {
        dawnEditorSupport.setDirty(true);
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.netxforge.netxstudio.screens.editing.IEditingService#doSave(org.eclipse
     * .core.runtime.IProgressMonitor)
     */
    public IRunnableWithProgress doGetSaveOperation(IProgressMonitor monitor) {
        final Map<Object, Object> saveOptions = new HashMap<Object, Object>();
        saveOptions.put(Resource.OPTION_SAVE_ONLY_IF_CHANGED, Resource.OPTION_SAVE_ONLY_IF_CHANGED_MEMORY_BUFFER);

        // Do the work within an operation because this is a long running
        // activity that modifies the workbench.
        IRunnableWithProgress operation = new IRunnableWithProgress() {
            // This is the method that gets invoked when the operation runs.
            public void run(IProgressMonitor monitor) {
                // Save the resources to the file system.
                try {
                    monitor.beginTask("Saving all Objects", 100);

                    // FIXME, REVISION HANDLING WITH NEW STORE.
                    // monitor.subTask("Copy history");
                    // saveHistory();
                    monitor.worked(50);
                    monitor.subTask("Committing transaction from regular view");
                    CDOTransaction transaction = getView() instanceof CDOTransaction ? (CDOTransaction) getView()
                            : null;
                    if (transaction != null) {
                        commitRegular(monitor, transaction);
                    }
                    monitor.subTask("Committing transaction from regular view");
                    transaction = getCDOData().getTransaction();
                    if (transaction != null) {
                        commitRegular(monitor, transaction);
                    }

                    monitor.done();
                } catch (Exception e) {
                    e.printStackTrace();
                    // List of possible exceptions.

                    // MessageDialog.openError(Display.getDefault()
                    // .getActiveShell(), "Error saving object",
                    // "Error saving, rolling back. ");
                    if (EditingActivator.DEBUG) {
                        System.out.println("Can't save, rolling back");
                    }

                    ((IDawnEditor) CDOEditingService.this).getDawnEditorSupport().rollback();
                }
            }
        };

        return operation;
    }

    @SuppressWarnings("unused")
    private void saveRegular(IProgressMonitor monitor, final Map<Object, Object> saveOptions) throws IOException {
        boolean first = true;
        for (Resource resource : getEditingDomain().getResourceSet().getResources()) {

            if ((first || !resource.getContents().isEmpty()) && !getEditingDomain().isReadOnly(resource)) {

                if (resource instanceof CDOResource) {
                    CDOResource cdoRes = (CDOResource) resource;
                    CDOState cdoState = cdoRes.cdoState();
                    CDOView cdoView = cdoRes.cdoView();

                    // Print saving state.
                    if (EditingActivator.DEBUG) {
                        EditingActivator.TRACE.trace(EditingActivator.TRACE_EDITING_OPTION,
                                "Saving resource: " + cdoRes.getURI().toString() + ", state=" + cdoState.name());

                    }

                    if (cdoView instanceof CDOTransaction) {
                        Map<CDOID, CDOObject> dirtyObjects = ((CDOTransaction) cdoView).getDirtyObjects();
                        String subMsg = "Saving resource: " + cdoRes.getPath() + " object count="
                                + dirtyObjects.size();
                        monitor.subTask(subMsg);
                    }

                }

                resource.save(saveOptions);
                first = false;
            }
        }
    }

    private void commitRegular(IProgressMonitor monitor, CDOTransaction transaction) throws CommitException {

        if (EditingActivator.DEBUG) {
            EditingActivator.TRACE.trace(EditingActivator.TRACE_EDITING_OPTION, "Commit transaction: "
                    + transaction.getViewID() + " last time update" + new Date(transaction.getLastUpdateTime()));

            if (transaction.isDirty()) {
                Map<CDOID, CDOObject> dirtyObjects = transaction.getDirtyObjects();

                for (CDOID id : dirtyObjects.keySet()) {
                    CDOObject cdoObject = dirtyObjects.get(id);
                    EditingActivator.TRACE.trace(EditingActivator.TRACE_EDITING_OPTION,
                            "-- dirty object=" + cdoObject.cdoID().toURIFragment() + " , state="
                                    + cdoObject.cdoState() + ", rev=" + cdoObject.cdoRevision()
                                    + " , dangling state=" + cdoObject.cdoID().isDangling());

                    // CB, this forces all CDO Objects to be read, as our
                    // cdoObject could be the root resource.
                    // "/" when a child resource is created!
                    // TreeIterator<EObject> eAllContents = cdoObject
                    // .eAllContents();
                    // while (eAllContents.hasNext()) {
                    // CDOObject next = (CDOObject) eAllContents.next();
                    // System.out.println("-- content object="
                    // + next.cdoID().toURIFragment() + " , state=" +
                    // next.cdoState() +", rev="
                    // + next.cdoRevision() + " , dangling state="
                    // + next.cdoID().isDangling() );
                    // }
                }
            }
        }

        if (monitor != null) {
            Map<CDOID, CDOObject> dirtyObjects = transaction.getDirtyObjects();
            String subMsg = "Committing transaction: " + transaction.getViewID() + " object count="
                    + dirtyObjects.size();
            monitor.subTask(subMsg);

        }
        transaction.setCommitComment(ICDOData.CLIENT_COMMIT_COMMENT);
        transaction.commit();

    }

    /**
     * Save a history of objects of type Node or NodeType We can't save an
     * initial copy when the state is NEW, as no CDOID will exist yet, and this
     * is what we base the Resource Name on. (We append the CDOID to the default
     * object resource name).
     */
    @SuppressWarnings("unused")
    private void saveHistory() {
        ImmutableList<Resource> copyOf = ImmutableList.copyOf(getEditingDomain().getResourceSet().getResources());
        for (Resource resource : copyOf) {
            // Walk through the objects in the resource.
            if (resource instanceof CDOResource) {
                CDOResource cdoRes = (CDOResource) resource;
                if (cdoRes.cdoView() instanceof CDOTransaction) {
                    CDOTransaction cdoTransaction = (CDOTransaction) cdoRes.cdoView();
                    Map<CDOID, CDOObject> dirtyObjects = cdoTransaction.getDirtyObjects();

                    cdoTransaction.getNewObjects();

                    if (dirtyObjects.size() > 0) {

                        // Create a copy, to avoid concurrency issues.
                        ImmutableList<CDOObject> dirtyObjectsList = ImmutableList.copyOf(dirtyObjects.values());

                        EClass hint;
                        if ((hint = shouldHaveHistory(cdoRes)) != null) {

                            // Build a cache of unique nodetypes.
                            // Use the node type as the point of reference.
                            // the copy will resolve either NodeType or Node
                            // depending
                            // on the hint.
                            List<NodeType> uniqueNodeTypes = Lists.newArrayList();

                            for (CDOObject cdoObject : dirtyObjectsList) {

                                NodeType resolveNodeType = null;
                                if (hint == LibraryPackage.Literals.NODE_TYPE) {
                                    resolveNodeType = StudioUtils.resolveParentNodeType(cdoObject);
                                } else if (hint == OperatorsPackage.Literals.NODE) {
                                    if (cdoObject.eClass() == OperatorsPackage.Literals.NODE) {
                                        resolveNodeType = ((Node) cdoObject).getNodeType();
                                    } else {
                                        resolveNodeType = StudioUtils.resolveParentNodeType(cdoObject);
                                    }
                                }
                                if (resolveNodeType != null && !uniqueNodeTypes.contains(resolveNodeType)) {
                                    uniqueNodeTypes.add(resolveNodeType);
                                }
                            }

                            for (CDOObject cdoObject : uniqueNodeTypes) {
                                if (hint == LibraryPackage.Literals.NODE_TYPE) {
                                    doCopyNodeTypeToHistoryResource(cdoObject);
                                } else if (hint == OperatorsPackage.Literals.NODE) {
                                    doCopyNodeToHistoryResource(cdoObject);
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * Static acceptor for EClasses which should have a history.
     * 
     * @param resource
     * @return
     */
    public EClass shouldHaveHistory(Resource resource) {
        String name = ((CDOResource) resource).getName();
        if (name.equals(LibraryPackage.Literals.NODE_TYPE.getName())) {
            return LibraryPackage.Literals.NODE_TYPE;
        }
        if (name.equals(OperatorsPackage.Literals.OPERATOR.getName())) {
            return OperatorsPackage.Literals.NODE;
        }
        return null;
    }

    /**
     * Creates a copy of the target object, and stores is in a resource which is
     * named as the object class_the OID number.
     * 
     * As we use the current resource set to hold the history resource, this
     * will automaticly be saved when saving the actual resource later on.
     * 
     * @param target
     */
    public void doCopyNodeTypeToHistoryResource(CDOObject target) {

        target = StudioUtils.resolveParentNodeType(target);
        if (target == null || !(target instanceof NodeType)) {
            return;
        }
        this.doCopyTarget(target);
    }

    /**
     * Creates a copy of the target object, and stores is in a resource which is
     * named as the object class_the OID number.
     * 
     * As we use the current resource set to hold the history resource, this
     * will automaticly be saved when saving the actual resource later on.
     * 
     * @param target
     */
    public void doCopyNodeToHistoryResource(CDOObject target) {
        target = StudioUtils.nodeFor(target);
        if (target == null || !(target instanceof Node)) {
            return;
        }
        this.doCopyTarget(target);
    }

    private void doCopyTarget(CDOObject target) {
        String affectedPath = this.resolveHistoricalResourceName(target);
        if (affectedPath != null) {
            URI uri = URI.createURI(affectedPath);
            // Write a new version.
            Resource historyResource = getCDOData().getResource(this.getEditingDomain().getResourceSet(), uri);

            // We make a copy, using a custom copier, as we don't want to copy
            // the references.
            Copier copier = new EcoreUtil.Copier();
            CDOObject copyOfTarget = (CDOObject) copier.copy(target);
            historyResource.getContents().add(copyOfTarget);
        }
    }

    /*
     * Delegate to ModelUtils. (non-Javadoc)
     * 
     * @see com.netxforge.netxstudio.screens.editing.IEditingService#
     * resolveHistoricalResourceName(java.lang.Object)
     */
    public String resolveHistoricalResourceName(Object object) {
        return CDO.resolveHistoricalResourceName(object);
    }

    public void sessionStillValid() {
        try {
            getCDOData().getSession();
        } catch (final IllegalStateException ise) {

            Display.getDefault().asyncExec(new Runnable() {

                public void run() {
                    // Session is dead, we should close.
                    MessageDialog.openError(Display.getDefault().getActiveShell(), "Connection to server lost",
                            "There is currently no connection with the Server"
                                    + "\nPlease exit and try to login again to re-establish the connection");
                    throw ise;
                }

            });
        }
    }

    public void handleStale(final EObject source, final EStructuralFeature feature, final int index,
            final CDOID target) {

        Display.getDefault().asyncExec(new Runnable() {

            public void run() {
                // Session is dead, we should close.
                MessageDialog.openError(Display.getDefault().getActiveShell(),
                        "Trying to load nong-existing object",
                        "Source Object: " + StudioUtils.printModelObject(source) + "\n" + "Reference: "
                                + feature.getName() + "\n" + "Index: " + index + "\n" + "ID of targeted object: "
                                + target + "\n"
                                + "this will happens when a referenced object is deleted and potential references"
                                + "to it are not removed.\n"
                                + "Now attempting to clean this reference, please retry your previous action"

                );

                CDOUtil.cleanStaleReference(source, feature, index);

            }

        });
    }

    /**
     * An {@link AdapterFactory} which can produce the model specific
     * {@link ItemProviderAdapter adapters}
     * 
     * @return
     */
    public static AdapterFactory getAdapterFactory() {

        // FIXME Use the registry to obtain a model Adapter Factory. Remove the
        // model dependencies.
        // Registry instance =
        // ComposedAdapterFactory.Descriptor.Registry.INSTANCE;

        ComposedAdapterFactory emfEditAdapterFactory = (ComposedAdapterFactory) AbstractScreensViewPart
                .getAdapterFactory();

        emfEditAdapterFactory.addAdapterFactory(new EresourceAdapterFactory());
        emfEditAdapterFactory.addAdapterFactory(new GenericsItemProviderAdapterFactory());
        emfEditAdapterFactory.addAdapterFactory(new ServicesItemProviderAdapterFactory());
        emfEditAdapterFactory.addAdapterFactory(new LibraryItemProviderAdapterFactory());
        emfEditAdapterFactory.addAdapterFactory(new MetricsItemProviderAdapterFactory());
        emfEditAdapterFactory.addAdapterFactory(new ProtocolsItemProviderAdapterFactory());
        emfEditAdapterFactory.addAdapterFactory(new OperatorsItemProviderAdapterFactory());
        emfEditAdapterFactory.addAdapterFactory(new GeoItemProviderAdapterFactory());
        emfEditAdapterFactory.addAdapterFactory(new SchedulingItemProviderAdapterFactory());
        emfEditAdapterFactory.addAdapterFactory(new NetxstudioItemProviderAdapterFactory());
        return emfEditAdapterFactory;
    }

    /**
     * A set of objects is alive when the {@link CDOObject} is
     * 
     */
    public boolean isDataAlive(Object[] objects) {
        for (Object o : objects) {
            if (o instanceof CDOObject) {
                CDOObject cdoO = (CDOObject) o;
                if (FSMUtil.isInvalid(cdoO)) {
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * Delegation to injected IDataService
     */
    public Role getCurrentRole() {
        String currentUser = getCDOData().getSessionUserID();
        Resource resource = getCDOData().getResource(GenericsPackage.Literals.PERSON);
        final List<Person> people = new StudioUtils.CollectionForObjects<Person>()
                .collectionForObjects(resource.getContents());
        Role r = StudioUtils.roleForUserWithName(currentUser, people);
        return r;
    }

    /**
     * Delegation to injected IDataService
     */
    public String getServer() {
        return getCDOData().getServer();
    }

    @Override
    public void activate(Object source) {
        super.activate(source);
    }

    @Override
    public void deactivate(Object source) {
        disposeData();
        getCDOData().deactivate(this);
        super.deactivate(source);
    }

}