/*******************************************************************************
 * Copyright (c) 2008, 2017 THALES GLOBAL SERVICES and others.
 * 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:
 *    Obeo - initial API and implementation
 *******************************************************************************/
package org.eclipse.sirius.ui.tools.internal.editor;

import java.text.MessageFormat;
import java.util.Collection;
import java.util.Collections;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.ui.URIEditorInput;
import org.eclipse.emf.common.ui.viewer.IViewerProvider;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.domain.IEditingDomainProvider;
import org.eclipse.emf.edit.ui.action.EditingDomainActionBarContributor;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.sirius.business.api.dialect.command.RefreshRepresentationsCommand;
import org.eclipse.sirius.business.api.preferences.SiriusPreferencesKeys;
import org.eclipse.sirius.business.api.query.URIQuery;
import org.eclipse.sirius.business.api.session.Session;
import org.eclipse.sirius.business.api.session.SessionListener;
import org.eclipse.sirius.business.api.session.SessionManager;
import org.eclipse.sirius.business.api.session.SessionManagerListener;
import org.eclipse.sirius.business.api.session.SessionStatus;
import org.eclipse.sirius.common.ui.SiriusTransPlugin;
import org.eclipse.sirius.common.ui.tools.api.util.EclipseUIUtil;
import org.eclipse.sirius.ecore.extender.business.api.accessor.ModelAccessor;
import org.eclipse.sirius.ecore.extender.business.api.permission.IAuthorityListener;
import org.eclipse.sirius.ecore.extender.business.api.permission.IPermissionAuthority;
import org.eclipse.sirius.ecore.extender.business.api.permission.LockStatus;
import org.eclipse.sirius.ecore.extender.business.api.permission.PermissionAuthorityRegistry;
import org.eclipse.sirius.tools.api.command.ICommandFactory;
import org.eclipse.sirius.tools.api.permission.DRepresentationPermissionStatusListener;
import org.eclipse.sirius.tools.api.permission.DRepresentationPermissionStatusQuery;
import org.eclipse.sirius.ui.business.api.dialect.DialectEditor;
import org.eclipse.sirius.ui.business.api.dialect.DialectEditorDialogFactory;
import org.eclipse.sirius.ui.business.api.dialect.DialectUIManager;
import org.eclipse.sirius.ui.business.api.session.IEditingSession;
import org.eclipse.sirius.ui.business.api.session.SessionEditorInput;
import org.eclipse.sirius.ui.business.api.session.SessionUIManager;
import org.eclipse.sirius.ui.business.internal.dialect.TreeEditorDialogFactory;
import org.eclipse.sirius.ui.tools.api.properties.DTablePropertySheetpage;
import org.eclipse.sirius.viewpoint.DRepresentation;
import org.eclipse.sirius.viewpoint.DSemanticDecorator;
import org.eclipse.sirius.viewpoint.SiriusPlugin;
import org.eclipse.sirius.viewpoint.provider.Messages;
import org.eclipse.sirius.viewpoint.provider.SiriusEditPlugin;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorRegistry;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IPageListener;
import org.eclipse.ui.IReusableEditor;
import org.eclipse.ui.ISaveablePart2;
import org.eclipse.ui.ISaveablesSource;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.Saveable;
import org.eclipse.ui.part.EditorPart;
import org.eclipse.ui.views.properties.IPropertySheetPage;
import org.eclipse.ui.views.properties.tabbed.ITabbedPropertySheetPageContributor;

/**
 * Provides generic support for DTable and DTree editors. <BR>
 * Clients may extend this class.
 * 
 * @author <a href="mailto:laurent.redor@obeo.fr">Laurent Redor</a>
 */
public abstract class AbstractDTreeEditor extends EditorPart
        implements DialectEditor, IViewerProvider, ITabbedPropertySheetPageContributor, IEditingDomainProvider, IReusableEditor, SessionListener, ISaveablesSource, IPageListener {

    /**
     * This class has the responsibility to open the editing session
     * corresponding to a session added to the session manager and attaching to
     * it the current editor so it can be handled correctly.
     * 
     * @author <a href="mailto:pierre.guilet@obeo.fr">Pierre Guilet</a>
     *
     */
    private static final class SessionHandlingForEditor extends SessionManagerListener.Stub {
        private AbstractDTreeEditor editor;

        SessionHandlingForEditor(AbstractDTreeEditor editor) {
            this.editor = editor;
        }

        @Override
        public void notifyAddSession(final Session newSession) {

            /* we want to be notified only once */
            final IEditingSession editingSession = SessionUIManager.INSTANCE.getOrCreateUISession(newSession);
            if (!editingSession.isOpen()) {
                editingSession.open();
                editingSession.attachEditor(editor);
                // important to remove the reference to the editor because this
                // listener is still referenced by Eclipse ContextService when
                // the editor is closed causing a leak.
                editor = null;
                /* remove this listener */
                SessionManager.INSTANCE.removeSessionsListener(this);
            }

        }
    }

    /** The PERMISSION_GRANTED_TO_CURRENT_USER_EXCLUSIVELY icon descriptor. */
    private static final ImageDescriptor LOCK_BY_ME_IMAGE_DESCRIPTOR = SiriusEditPlugin.Implementation
            .getBundledImageDescriptor("icons/full/decorator/permission_granted_to_current_user_exclusively.gif"); //$NON-NLS-1$

    /** The PERMISSION_GRANTED_TO_CURRENT_USER_EXCLUSIVELY icon descriptor. */
    private static final ImageDescriptor LOCK_BY_OTHER_IMAGE_DESCRIPTOR = SiriusEditPlugin.Implementation.getBundledImageDescriptor("icons/full/decorator/permission_denied.gif"); //$NON-NLS-1$

    private static final ImageDescriptor NO_WRITE_PERMISSION_IMAGE_DESCRIPTOR = SiriusEditPlugin.Implementation.getBundledImageDescriptor("icons/full/decorator/permission_no_write.gif");; //$NON-NLS-1$

    /**
     * This is the one adapter factory used for providing views of the model.
     */
    protected AdapterFactory adapterFactory;

    /**
     * Model accessor.
     */
    protected ModelAccessor accessor;

    /**
     * The tree viewer manager.
     */
    protected AbstractDTableViewerManager treeViewerManager;

    /** The control of this editor. */
    protected Control control;

    /**
     * The session.
     */
    protected Session session;

    /**
     * To increase performance we stop the update of the corresponding
     * propertySheetPage during the refresh of the DTable.
     */
    protected boolean propertiesUpdateEnabled;

    /**
     * .
     */
    protected boolean isClosing;

    /**
     * Property sheet page.
     */
    protected DTablePropertySheetpage currentPropertySheetpage;

    /** the EMF command factory provider. */
    protected ICommandFactory emfCommandFactory;

    /**
     * SessionManagerListener.
     */
    protected final SessionManagerListener sessionManagerListener = new SessionHandlingForEditor(this);

    /**
     * The DialectEditorDialogFactory.
     */
    protected DialectEditorDialogFactory myDialogFactory = new TreeEditorDialogFactory(this);

    /**
     * The {@link UndoRedoActionHandler} used to provide appropriate undo and
     * redo Action Handlers to this editor.
     */
    protected UndoRedoActionHandler undoRedoActionHandler;

    /** Singleton instance of the initial Image for the NO_LOCK status. */
    protected Image initialTitleImage;

    /** Singleton instance of the Image for the REPRESENTATION_FROZEN status. */
    protected Image frozenRepresentationImage;

    /** The {@link IAuthorityListener}. */
    private IAuthorityListener dRepresentationLockStatusListener;

    /** Singleton instance of the Image for the LOCK_BY_ME status */
    private Image lockByMeImage;

    /** Singleton instance of the Image for the LOCK_BY_OTHER status */
    private Image lockByOtherImage;

    /**
     * Singleton instance of the image when DRepresentation has no write
     * permission
     */
    private Image noWritePermissionImage;

    private int choice = ISaveablePart2.DEFAULT;

    /**
     * Default constructor.
     */
    public AbstractDTreeEditor() {
        super();
        emfCommandFactory = null;
    }

    /**
     * Editor picture.
     * 
     * @return initial image editor
     */
    public abstract Image getInitialImage();

    /**
     * Get lazily the Image for the LOCK_BY_ME status.
     * 
     * @return the Image for the LOCK_BY_ME status
     */
    protected Image getLockByMeImage() {
        if (lockByMeImage == null || lockByMeImage.isDisposed()) {
            lockByMeImage = SiriusEditPlugin.getPlugin().getImage(LOCK_BY_ME_IMAGE_DESCRIPTOR);
        }
        return lockByMeImage;
    }

    /**
     * Get lazily the Image for the LOCK_BY_OTHER status.
     * 
     * @return the Image for the LOCK_BY_OTHER status
     */
    protected Image getLockByOtherImage() {
        if (lockByOtherImage == null || lockByOtherImage.isDisposed()) {
            lockByOtherImage = SiriusEditPlugin.getPlugin().getImage(LOCK_BY_OTHER_IMAGE_DESCRIPTOR);
        }
        return lockByOtherImage;
    }

    /**
     * Lazily gets the image when there is no write permission of the
     * DRepresentation.
     * 
     * @return the image when there is no write permission of the
     *         DRepresentation.
     */
    protected Image getNoWritePermissionImage() {
        if (noWritePermissionImage == null || noWritePermissionImage.isDisposed()) {
            noWritePermissionImage = SiriusEditPlugin.getPlugin().getImage(NO_WRITE_PERMISSION_IMAGE_DESCRIPTOR);
        }
        return noWritePermissionImage;
    }

    /**
     * Get lazily the Image for the REPRESENTATION_FROZEN state.
     * 
     * @return the Image for the REPRESENTATION_FROZEN state
     */
    public abstract Image getFrozenRepresentationImage();

    @Override
    public TransactionalEditingDomain getEditingDomain() {
        return session != null ? session.getTransactionalEditingDomain() : null;
    }

    public IActionBars getActionBars() {
        return ((EditingDomainActionBarContributor) getEditorSite().getActionBarContributor()).getActionBars();
    }

    /**
     * Performs the save and handles errors appropriately.
     * 
     * @param overwrite
     *            indicates whether or not overwriting is allowed
     * @param progressMonitor
     *            the monitor in which to run the operation
     * 
     */
    protected void performSave(final boolean overwrite, final IProgressMonitor progressMonitor) {
        session.save(progressMonitor);
    }

    /**
     * Tells if the {@link Resource} associated to the specified
     * <code>editorInput</code> exists or not.
     * 
     * @param editorInput
     *            the specifed {@link IEditorInput}
     * @return false if the {@link Resource} associated to the specified
     *         <code>editorInput</code> exists, true else
     */
    protected boolean isDeleted(final IEditorInput editorInput) {
        boolean isDeleted = false;
        if (getRepresentation() != null) {
            final Resource sessionResource = getRepresentation().eResource();
            if (sessionResource != null) {
                URI sessionResourceURI = sessionResource.getURI();
                boolean sessionResourceExists = sessionResource.getResourceSet().getURIConverter().exists(sessionResourceURI, Collections.emptyMap());
                // WORKAROUND with collab plugins
                if (!sessionResourceExists && new URIQuery(sessionResourceURI).isInMemoryURI()) {
                    isDeleted = false;
                } else {
                    isDeleted = !sessionResourceExists;
                }
            }
        }
        return isDeleted;
    }

    /**
     * We have to take care of the case when Eclipse starts up with a session
     * and diagram already open. see bug #1217
     * 
     * {@inheritDoc}
     */
    @Override
    public void init(final IEditorSite site, final IEditorInput input) throws PartInitException {
        setSite(site);

        final Collection<Session> sessions = SessionManager.INSTANCE.getSessions();

        /*
         * we are during eclipse boot, we are not trying to close the editor
         */
        if (sessions.isEmpty() && (!isClosing)) {
            SessionManager.INSTANCE.addSessionsListener(sessionManagerListener);
        }
        isClosing = false;

        if (input instanceof SessionEditorInput) {
            SessionEditorInput sessionEditorInput = (SessionEditorInput) input;
            final URI uri = sessionEditorInput.getURI();
            this.session = sessionEditorInput.getSession();
            if (session != null) {
                setRepresentation(uri, false);
            }
        } else if (input instanceof URIEditorInput) {
            /* This happens when Eclipse is launched with an open tree editor */
            final URI uri = ((URIEditorInput) input).getURI();
            setRepresentation(uri, true);
        }

        setInput(input);

        if (session != null) {
            session.addListener(this);
            configureCommandFactoryProviders();

            IEditingSession uiSession = SessionUIManager.INSTANCE.getOrCreateUISession(this.session);
            uiSession.open();
            uiSession.attachEditor(this);
            setAccessor(SiriusPlugin.getDefault().getModelAccessorRegistry().getModelAccessor(getRepresentation()));
        }

        DRepresentation representation = getRepresentation();
        if (representation != null) {
            /* Update title. Semantic table could have been renamed */
            notify(PROP_TITLE);

            initialTitleImage = getTitleImage();
        }
    }

    /**
     * Configure and set the command factory.
     */
    protected abstract void configureCommandFactoryProviders();

    /**
     * Initialize {@link IPermissionAuthority} and the title image if the Table
     * is already locked by the current user before opening.
     * 
     * @param representation
     *            the {@link DSemanticDecorator} that is opening.
     */
    protected void initPermissionAuthority(DSemanticDecorator representation) {
        // This IPermissionAuthority is added only on shared
        // representations.
        IPermissionAuthority permissionAuthority = PermissionAuthorityRegistry.getDefault().getPermissionAuthority(representation.getTarget());
        dRepresentationLockStatusListener = new DRepresentationPermissionStatusListener(representation, this);
        permissionAuthority.addAuthorityListener(dRepresentationLockStatusListener);

        if (!permissionAuthority.canEditInstance(this.getRepresentation())) {
            notify(SessionListener.REPRESENTATION_EDITION_PERMISSION_DENIED);
        } else if (LockStatus.LOCKED_BY_ME.equals(permissionAuthority.getLockStatus(representation))) {
            notify(SessionListener.REPRESENTATION_EDITION_PERMISSION_GRANTED_TO_CURRENT_USER_EXCLUSIVELY);
        }
    }

    /**
     * Open the session.
     * 
     * @param rootElement
     *            the representation
     */
    protected void getSession(final DSemanticDecorator rootElement) {
        session = SessionManager.INSTANCE.getSession(rootElement.getTarget());
        if (session == null) {
            SiriusTransPlugin.getPlugin().error(MessageFormat.format(Messages.AbstractDTreeEditor_noSessionError, rootElement), null);
        }
    }

    @Override
    public boolean isDirty() {
        return session != null && session.getStatus() == SessionStatus.DIRTY;
    }

    @Override
    public boolean isSaveAsAllowed() {
        return false;
    }

    @Override
    public void setFocus() {
        if (treeViewerManager != null) {
            // Resolve proxy model after aird reload.
            DRepresentation representation = getRepresentation();
            boolean representationProxyDetected = false;
            if (representation != null && representation.eIsProxy() && session != null) {
                representationProxyDetected = true;
                IEditorInput editorInput = getEditorInput();
                if (editorInput instanceof URIEditorInput) {
                    URIEditorInput sessionEditorInput = (URIEditorInput) editorInput;
                    final URI uri = sessionEditorInput.getURI();
                    setRepresentation(uri, false);
                    IEditingSession uiSession = SessionUIManager.INSTANCE.getUISession(session);

                    // Get the new representation
                    representation = getRepresentation();
                    if (uiSession != null && representation != null) {
                        // Reinit dialect editor closer and other
                        // IEditingSession mechanisms.
                        uiSession.detachEditor(this);
                        uiSession.attachEditor(this);
                    }

                    // Reinit the lock status listener.
                    IPermissionAuthority permissionAuthority = PermissionAuthorityRegistry.getDefault().getPermissionAuthority(representation);
                    if (representation instanceof DSemanticDecorator && permissionAuthority != null && dRepresentationLockStatusListener != null) {
                        permissionAuthority.removeAuthorityListener(dRepresentationLockStatusListener);
                        initPermissionAuthority((DSemanticDecorator) representation);
                    }
                }
            }

            checkSemanticAssociation();

            if (representationProxyDetected) {
                updateEditorAfterAirdResourceReload();
            }
            /*
             * A regression in Kepler can cause an NPE inside the
             * treeViewerManager.getControl().setFocus() below. The guard
             * condition is a workaround, which seems to fix the problem (or at
             * least the symptom) in our tests. See
             * https://bugs.eclipse.org/bugs/show_bug.cgi?id=378846#c16
             */
            AbstractDTreeViewer viewer = treeViewerManager.getTreeViewer();
            if (viewer != null && viewer.getTree() != null && viewer.getTree().getTopItem() != null) {
                treeViewerManager.getControl().setFocus();
            }
            setEclipseWindowTitle();

        } else if (control != null) {
            control.setFocus();
        }
    }

    /**
     * Update all needed editor elements after an Aird resource reload like
     * {@link Tree} or {@link AbstractDTableViewerManager} referencing previous
     * Aird elements as proxies.
     */
    protected abstract void updateEditorAfterAirdResourceReload();

    /**
     * Retrieve and set the representation from the given URI.
     * 
     * @param uri
     *            the URI to resolve.
     * @param loadOnDemand
     *            whether to create and load the resource, if it doesn't already
     *            exists.
     */
    protected abstract void setRepresentation(URI uri, boolean loadOnDemand);

    /**
     * Close this editor if root element has been removed.
     */
    protected void checkSemanticAssociation() {
        DRepresentation representation = getRepresentation();
        boolean shouldClose = representation == null || representation.eResource() == null;
        if (!shouldClose && representation instanceof DSemanticDecorator) {
            EObject semanticTarget = ((DSemanticDecorator) representation).getTarget();
            shouldClose = semanticTarget == null || semanticTarget.eResource() == null;
        }

        if (shouldClose) {
            /*
             * The element has been deleted, we should close the editor
             */
            myDialogFactory.editorWillBeClosedInformationDialog(getSite().getShell());
            DialectUIManager.INSTANCE.closeEditor(this, false);
        }
    }

    /**
     * Updates the title of the eclipse window.
     */
    protected void setEclipseWindowTitle() {
        // Updates the title of the eclipse window.
        // Removes the xmi id if the selected element and replace it with the
        // name of the tab.
        String title = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell().getText();
        final int end = title.lastIndexOf(".aird#"); //$NON-NLS-1$
        if (end > -1) {
            title = MessageFormat.format(Messages.AbstractDTreeEditor_eclipseWindowTitle, title.substring(0, end + 6) + this.getPartName());
            PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell().setText(title);
        }
    }

    /**
     * Retrieves the descriptor for this editor.
     * 
     * @return the editor descriptor
     */
    protected final IEditorDescriptor getEditorDescriptor() {
        final IEditorRegistry editorRegistry = PlatformUI.getWorkbench().getEditorRegistry();
        final IEditorDescriptor editorDesc = editorRegistry.findEditor(getSite().getId());
        return editorDesc;
    }

    @Override
    public boolean needsRefresh(int propId) {
        boolean result = false;
        if (propId == DialectEditor.PROP_REFRESH) {
            if (isAutoRefresh()) {
                result = true;
            }
        } else if (propId == DialectEditor.PROP_FORCE_REFRESH) {
            result = true;
        }
        return result;
    }

    /**
     * Launch refresh on representation.
     */
    protected abstract void launchRefresh();

    @Override
    public Object getAdapter(@SuppressWarnings("rawtypes") final Class type) {
        Object result = super.getAdapter(type);
        if (result == null) {
            if (type == IPropertySheetPage.class) {
                IPropertySheetPage contributedPage = SiriusEditPlugin.getPlugin().getPropertySheetPage(this, getContributorId());
                if (contributedPage != null) {
                    currentPropertySheetpage = null;
                    result = contributedPage;
                } else {
                    currentPropertySheetpage = new DTablePropertySheetpage(this);
                    result = currentPropertySheetpage;
                }
            } else if (type == EditingDomain.class) {
                result = getEditingDomain();
            }
        }
        return result;
    }

    /**
     * Do a refresh of the properties view if it's activated.
     */
    public void forceRefreshProperties() {
        if (currentPropertySheetpage != null && currentPropertySheetpage.getControl() != null && !currentPropertySheetpage.getControl().isDisposed()) {
            currentPropertySheetpage.refresh();
        }
    }

    @Override
    public Viewer getViewer() {
        Viewer viewer = null;
        if (treeViewerManager != null) {
            viewer = treeViewerManager.getTreeViewer();
        }
        return viewer;
    }

    public AbstractDTableViewerManager getTableViewer() {
        return treeViewerManager;
    }

    /**
     * return accessor.
     * 
     * @return the accessor
     */
    public ModelAccessor getAccessor() {
        return accessor;
    }

    @Override
    public void dispose() {
        if (control != null) {
            control.dispose();
            control = null;
        }
        if (dRepresentationLockStatusListener != null) {
            IPermissionAuthority permissionAuthority = PermissionAuthorityRegistry.getDefault().getPermissionAuthority(getRepresentation());
            permissionAuthority.removeAuthorityListener(dRepresentationLockStatusListener);
            dRepresentationLockStatusListener = null;
        }

        isClosing = true;
        SessionManager.INSTANCE.removeSessionsListener(sessionManagerListener);

        // Disposing the UndoredoActionHandler
        if (this.undoRedoActionHandler != null) {
            this.undoRedoActionHandler.dispose();
        }
        undoRedoActionHandler = null;
        super.dispose();
        if (getTableViewer() != null) {
            getTableViewer().dispose();
        }
        treeViewerManager = null;
        // We need to perform the detachEditor after having disposed the viewer
        // and the editor input to avoid a refresh. A refresh can occurs in the
        // case where the detach triggers the reload of the modified resources
        // (if choice == ISaveablePart2.NO)
        if (session != null) {
            session.removeListener(this);
            final IEditingSession sess = SessionUIManager.INSTANCE.getUISession(session);
            if (sess != null) {
                sess.detachEditor(this, choice == ISaveablePart2.NO);
            }
            session = null;
        }
        adapterFactory = null;
        accessor = null;
        currentPropertySheetpage = null;
        emfCommandFactory = null;
        myDialogFactory = null;
    }

    @Override
    public void setInput(final IEditorInput input) {
        super.setInput(input);
        // Set the context for the command stack (See
        // org.eclipse.gmf.runtime.diagram.ui.partsDiagramEditor.setInput for
        // details)
        // configureTableEditDomain();

        Viewer viewer = getViewer();
        if (viewer != null) {
            viewer.refresh();
        }

        // Update the tab's icon according to LockStatus
        DRepresentation representation = getRepresentation();
        if (representation instanceof DSemanticDecorator) {
            DSemanticDecorator dSemanticDecorator = (DSemanticDecorator) representation;
            DRepresentationPermissionStatusQuery dRepresentationPermissionStatusQuery = new DRepresentationPermissionStatusQuery(dSemanticDecorator);
            IPermissionAuthority permissionAuthority = PermissionAuthorityRegistry.getDefault().getPermissionAuthority(dSemanticDecorator);
            LockStatus lockStatus = LockStatus.NOT_LOCKED;
            LockStatus dSemanticDecoratorLockStatus = permissionAuthority.getLockStatus(dSemanticDecorator);
            if (dSemanticDecoratorLockStatus != LockStatus.NOT_LOCKED) {
                lockStatus = dSemanticDecoratorLockStatus;
            }
            int associatedSessionListenerEvent = dRepresentationPermissionStatusQuery.getAssociatedSessionListenerEvent(lockStatus);
            notify(associatedSessionListenerEvent);
        }

    }

    public AdapterFactory getAdapterFactory() {
        return adapterFactory;
    }

    /**
     * Set the update status.
     * 
     * @param enabled
     *            the updateEnabled to set
     */
    public void enablePropertiesUpdate(final boolean enabled) {
        propertiesUpdateEnabled = enabled;
    }

    /**
     * Get the update status.
     * 
     * @return the update status
     */
    public boolean isPropertiesUpdateEnabled() {
        return propertiesUpdateEnabled;
    }

    @Override
    public void notify(final int changeKind) {
        AbstractDTreeEditorSessionListenerDelegate abstractDTreeEditorSessionListenerDelegate = new AbstractDTreeEditorSessionListenerDelegate(this, changeKind);
        if (Display.getCurrent() == null) {
            EclipseUIUtil.displayAsyncExec(abstractDTreeEditorSessionListenerDelegate);
        } else {
            abstractDTreeEditorSessionListenerDelegate.run();
        }
    }

    /**
     * Overridden to change the visibility of the inherited method.
     * 
     * {@inheritDoc}
     */
    @Override
    public void setTitleImage(Image titleImage) {
        if (!getTitleImage().equals(titleImage)) {
            super.setTitleImage(titleImage);
        }
    }

    /**
     * Update a property.
     * 
     * @param notificationKind
     *            the kind of property changed
     */
    protected void firePropertyChangeInUIThread(final int notificationKind) {
        if (notificationKind == PROP_TITLE) {
            setPartName(getRepresentation().getName());
        }
        firePropertyChange(notificationKind);
    }

    protected IEditingSession getUISession() {
        return SessionUIManager.INSTANCE.getUISession(session);
    }

    @Override
    public boolean isSaveOnCloseNeeded() {
        /*
         * No call to editingSession.needToBeSavedOnClose(this) here to allow
         * close all detection.
         */
        return isDirty();
    }

    /**
     * .
     * 
     * @return if is auto refresh
     */
    protected boolean isAutoRefresh() {
        boolean autoRefresh = false;
        try {
            autoRefresh = Platform.getPreferencesService().getBoolean(SiriusPlugin.ID, SiriusPreferencesKeys.PREF_AUTO_REFRESH.name(), autoRefresh, null);
        } catch (final IllegalArgumentException e) {
            SiriusTransPlugin.getPlugin().getLog().log(new Status(IStatus.ERROR, SiriusTransPlugin.PLUGIN_ID, IStatus.OK, e.getMessage(), e));
        }
        return autoRefresh;
    }

    @Override
    public void setDialogFactory(DialectEditorDialogFactory dialogFactory) {
        myDialogFactory = dialogFactory;
    }

    @Override
    public Saveable[] getSaveables() {
        if (session != null && session.isOpen()) {
            IEditingSession uiSession = getUISession();
            if (uiSession instanceof ISaveablesSource) {
                return ((ISaveablesSource) uiSession).getSaveables();
            }
        }
        return new Saveable[0];
    }

    @Override
    public Saveable[] getActiveSaveables() {
        return getSaveables();
    }

    @Override
    public int promptToSaveOnClose() {
        choice = ISaveablePart2.DEFAULT;
        if (session != null && session.isOpen()) {
            IEditingSession uiSession = SessionUIManager.INSTANCE.getUISession(session);
            // Close all && Still open elsewhere detection.
            if (uiSession != null && uiSession.needToBeSavedOnClose(this)) {
                choice = uiSession.promptToSaveOnClose();
            }
        }

        return choice;
    }

    @Override
    public void createPartControl(Composite parent) {
        // setting up a UndoActionHandler
        // and a RedoActionHandler to avoid
        // issues with Undo and Redo
        setUpUndoRedoActionHandler();
    }

    @Override
    public void pageOpened(IWorkbenchPage page) {

    }

    @Override
    public void pageActivated(IWorkbenchPage page) {
        // As the page has been activated, we now can create the
        // UndoRedoActionHandler
        setUpUndoRedoActionHandler();
    }

    @Override
    public void pageClosed(IWorkbenchPage page) {

    }

    /**
     * Initializes an UndoRedoActionHandler, which purpose is to provide
     * appropriate undo and redo Action Handlers to this editor.
     */
    protected void setUpUndoRedoActionHandler() {
        // Undo/Redo Issues with Trees and Tables
        IWorkbenchWindow workbenchWindow = getEditorSite().getWorkbenchWindow();
        if (workbenchWindow != null) {
            IWorkbenchPage part = workbenchWindow.getActivePage();
            if (part != null) {
                undoRedoActionHandler = new UndoRedoActionHandler(this.getEditingDomain(), getEditorSite());
            }
        }
        // If the UndoRedoActionHandler was not create
        if (undoRedoActionHandler == null) {
            // We register the current editor as listening the page opening
            // The UndoRedoActionHandler will be created whenever the page will
            // open
            getEditorSite().getWorkbenchWindow().addPageListener(this);
        }
    }

    /**
     * Indicates if the given TreeItem list contains (at any level) the given
     * element. If it's the case, returns the TreeItem containing this element.
     * 
     * @param items
     *            the TreeItems to look into
     * @param element
     *            the searched element
     * @return the TreeItem containing the searched element if one found, null
     *         otherwise
     */
    protected TreeItem contains(TreeItem[] items, Object element) {
        TreeItem searchedTreeItem = null;
        for (int i = 0; i < items.length && (searchedTreeItem == null); i++) {
            if ((items[i].getData() != null) && items[i].getData().equals(element)) {
                searchedTreeItem = items[i];
            }
            if (searchedTreeItem == null) {
                searchedTreeItem = contains(items[i].getItems(), element);
            }
        }
        return searchedTreeItem;
    }

    @Override
    public DialectEditorDialogFactory getDialogFactory() {
        return myDialogFactory;
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.eclipse.sirius.business.api.componentization.ViewpointRegistryListener2#modelerDesciptionFilesLoaded()
     */
    protected void modelerDescriptionFilesLoaded() {
        if (isAutoRefresh()) {
            Job refreshJob = new Job(Messages.AbstractDTreeEditor_modelerDescriptionFilesLoadedJob) {
                @Override
                protected IStatus run(IProgressMonitor monitor) {
                    getEditingDomain().getCommandStack().execute(new RefreshRepresentationsCommand(getEditingDomain(), monitor, getRepresentation()));
                    return Status.OK_STATUS;
                }
            };
            refreshJob.schedule();
        }
    }

    /**
     * Set the accessor.
     * 
     * @param accessor
     *            the accessor to set
     */
    protected void setAccessor(ModelAccessor accessor) {
        this.accessor = accessor;
    }
}
