sernet.verinice.iso27k.rcp.ISMView.java Source code

Java tutorial

Introduction

Here is the source code for sernet.verinice.iso27k.rcp.ISMView.java

Source

/*******************************************************************************
 * Copyright (c) 2009 Daniel Murygin <dm[at]sernet[dot]de>.
 * 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 Lesser 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:
 *     Daniel <dm[at]sernet[dot]de> - initial API and implementation
 ******************************************************************************/
package sernet.verinice.iso27k.rcp;

import java.util.List;

import org.apache.log4j.Logger;
import org.eclipse.core.resources.WorkspaceJob;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.viewers.DecoratingLabelProvider;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.FileTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IPartListener2;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.part.DrillDownAdapter;

import sernet.gs.ui.rcp.main.Activator;
import sernet.gs.ui.rcp.main.ExceptionUtil;
import sernet.gs.ui.rcp.main.ImageCache;
import sernet.gs.ui.rcp.main.actions.ShowAccessControlEditAction;
import sernet.gs.ui.rcp.main.actions.ShowBulkEditAction;
import sernet.gs.ui.rcp.main.bsi.actions.NaturalizeAction;
import sernet.gs.ui.rcp.main.bsi.dnd.BSIModelViewDragListener;
import sernet.gs.ui.rcp.main.bsi.dnd.BSIModelViewDropListener;
import sernet.gs.ui.rcp.main.bsi.dnd.transfer.BausteinUmsetzungTransfer;
import sernet.gs.ui.rcp.main.bsi.dnd.transfer.IBSIStrukturElementTransfer;
import sernet.gs.ui.rcp.main.bsi.dnd.transfer.IGSModelElementTransfer;
import sernet.gs.ui.rcp.main.bsi.dnd.transfer.ISO27kElementTransfer;
import sernet.gs.ui.rcp.main.bsi.dnd.transfer.ISO27kGroupTransfer;
import sernet.gs.ui.rcp.main.bsi.dnd.transfer.ItemTransfer;
import sernet.gs.ui.rcp.main.bsi.editors.AttachmentEditor;
import sernet.gs.ui.rcp.main.bsi.editors.AttachmentEditorInput;
import sernet.gs.ui.rcp.main.bsi.editors.BSIElementEditorInput;
import sernet.gs.ui.rcp.main.bsi.editors.EditorFactory;
import sernet.gs.ui.rcp.main.common.model.CnAElementFactory;
import sernet.gs.ui.rcp.main.common.model.CnAElementHome;
import sernet.gs.ui.rcp.main.common.model.IModelLoadListener;
import sernet.gs.ui.rcp.main.preferences.PreferenceConstants;
import sernet.gs.ui.rcp.main.service.ServiceFactory;
import sernet.verinice.interfaces.ActionRightIDs;
import sernet.verinice.interfaces.ICommandService;
import sernet.verinice.iso27k.rcp.action.AddGroup;
import sernet.verinice.iso27k.rcp.action.BSIModelDropPerformer;
import sernet.verinice.iso27k.rcp.action.CollapseAction;
import sernet.verinice.iso27k.rcp.action.ControlDropPerformer;
import sernet.verinice.iso27k.rcp.action.ExpandAction;
import sernet.verinice.iso27k.rcp.action.FileDropPerformer;
import sernet.verinice.iso27k.rcp.action.HideEmptyFilter;
import sernet.verinice.iso27k.rcp.action.ISMViewFilter;
import sernet.verinice.iso27k.rcp.action.MetaDropAdapter;
import sernet.verinice.model.bsi.Attachment;
import sernet.verinice.model.bsi.BSIModel;
import sernet.verinice.model.common.CnATreeElement;
import sernet.verinice.model.common.TagParameter;
import sernet.verinice.model.common.TypeParameter;
import sernet.verinice.model.iso27k.Asset;
import sernet.verinice.model.iso27k.AssetGroup;
import sernet.verinice.model.iso27k.Audit;
import sernet.verinice.model.iso27k.AuditGroup;
import sernet.verinice.model.iso27k.Control;
import sernet.verinice.model.iso27k.ControlGroup;
import sernet.verinice.model.iso27k.Document;
import sernet.verinice.model.iso27k.DocumentGroup;
import sernet.verinice.model.iso27k.Evidence;
import sernet.verinice.model.iso27k.EvidenceGroup;
import sernet.verinice.model.iso27k.ExceptionGroup;
import sernet.verinice.model.iso27k.Finding;
import sernet.verinice.model.iso27k.FindingGroup;
import sernet.verinice.model.iso27k.IISO27KModelListener;
import sernet.verinice.model.iso27k.IISO27kElement;
import sernet.verinice.model.iso27k.ISO27KModel;
import sernet.verinice.model.iso27k.Incident;
import sernet.verinice.model.iso27k.IncidentGroup;
import sernet.verinice.model.iso27k.IncidentScenario;
import sernet.verinice.model.iso27k.IncidentScenarioGroup;
import sernet.verinice.model.iso27k.Interview;
import sernet.verinice.model.iso27k.InterviewGroup;
import sernet.verinice.model.iso27k.Organization;
import sernet.verinice.model.iso27k.PersonGroup;
import sernet.verinice.model.iso27k.PersonIso;
import sernet.verinice.model.iso27k.ProcessGroup;
import sernet.verinice.model.iso27k.Record;
import sernet.verinice.model.iso27k.RecordGroup;
import sernet.verinice.model.iso27k.Requirement;
import sernet.verinice.model.iso27k.RequirementGroup;
import sernet.verinice.model.iso27k.Response;
import sernet.verinice.model.iso27k.ResponseGroup;
import sernet.verinice.model.iso27k.Threat;
import sernet.verinice.model.iso27k.ThreatGroup;
import sernet.verinice.model.iso27k.Vulnerability;
import sernet.verinice.model.iso27k.VulnerabilityGroup;
import sernet.verinice.rcp.RightsEnabledView;
import sernet.verinice.rcp.tree.ElementManager;
import sernet.verinice.rcp.tree.TreeContentProvider;
import sernet.verinice.rcp.tree.TreeLabelProvider;
import sernet.verinice.rcp.tree.TreeUpdateListener;

/**
 * @author Daniel Murygin <dm[at]sernet[dot]de>
 *
 */
public class ISMView extends RightsEnabledView implements ILinkedWithEditorView {

    private static final Logger LOG = Logger.getLogger(ISMView.class);

    public static final String ID = "sernet.verinice.iso27k.rcp.ISMView"; //$NON-NLS-1$

    private static int operations = DND.DROP_COPY | DND.DROP_MOVE;

    protected TreeViewer viewer;

    private TreeContentProvider contentProvider;
    private ElementManager elementManager;

    private DrillDownAdapter drillDownAdapter;

    private Action doubleClickAction;

    private ShowBulkEditAction bulkEditAction;

    private ExpandAction expandAction;

    private CollapseAction collapseAction;

    private Action expandAllAction;

    private Action collapseAllAction;

    private Action linkWithEditorAction;

    private IPartListener2 linkWithEditorPartListener = new LinkWithEditorPartListener(this);

    private ISMViewFilter filterAction;

    private MetaDropAdapter metaDropAdapter;

    private ShowAccessControlEditAction accessControlEditAction;

    private NaturalizeAction naturalizeAction;

    private IModelLoadListener modelLoadListener;

    private Object mutex = new Object();

    private IISO27KModelListener modelUpdateListener;

    private boolean linkingActive = false;

    private ICommandService commandService;

    public ISMView() {
        super();
        elementManager = new ElementManager();
    }

    @Override
    public String getRightID() {
        return ActionRightIDs.ISMVIEW;
    }

    /* (non-Javadoc)
      * @see sernet.verinice.rcp.RightsEnabledView#getViewId()
      */
    @Override
    public String getViewId() {
        return ID;
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
     */
    @Override
    public void createPartControl(final Composite parent) {
        super.createPartControl(parent);
        try {
            initView(parent);
            startInitDataJob();
        } catch (Exception e) {
            LOG.error("Error while creating organization view", e); //$NON-NLS-1$
            ExceptionUtil.log(e, Messages.ISMView_2);
        }
    }

    /**
     * @param parent
     */
    protected void initView(Composite parent) {
        IWorkbench workbench = getSite().getWorkbenchWindow().getWorkbench();
        if (CnAElementFactory.getInstance().isIsoModelLoaded()) {
            CnAElementFactory.getInstance().reloadModelFromDatabase();
        }

        contentProvider = new TreeContentProvider(elementManager);
        viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
        drillDownAdapter = new DrillDownAdapter(viewer);
        viewer.getTree().setLayoutData(new GridData(GridData.FILL_BOTH));
        viewer.setContentProvider(contentProvider);
        viewer.setLabelProvider(
                new DecoratingLabelProvider(new TreeLabelProvider(), workbench.getDecoratorManager()));
        toggleLinking(Activator.getDefault().getPreferenceStore().getBoolean(PreferenceConstants.LINK_TO_EDITOR));

        getSite().setSelectionProvider(viewer);
        hookContextMenu();
        makeActions();
        addActions();
        fillToolBar();
        hookDNDListeners();

        getSite().getPage().addPartListener(linkWithEditorPartListener);
    }

    /**
    * 
    */
    protected void startInitDataJob() {
        if (LOG.isDebugEnabled()) {
            LOG.debug("ISMview: startInitDataJob"); //$NON-NLS-1$
        }
        WorkspaceJob initDataJob = new WorkspaceJob(Messages.ISMView_InitData) {
            @Override
            public IStatus runInWorkspace(final IProgressMonitor monitor) {
                IStatus status = Status.OK_STATUS;
                try {
                    monitor.beginTask(Messages.ISMView_InitData, IProgressMonitor.UNKNOWN);
                    initData();
                } catch (Exception e) {
                    LOG.error("Error while loading data.", e); //$NON-NLS-1$
                    status = new Status(Status.ERROR, "sernet.gs.ui.rcp.main", Messages.ISMView_4, e); //$NON-NLS-1$
                } finally {
                    monitor.done();
                }
                return status;
            }
        };
        JobScheduler.scheduleInitJob(initDataJob);
    }

    protected void initData() {
        if (LOG.isDebugEnabled()) {
            LOG.debug("ISMVIEW: initData"); //$NON-NLS-1$
        }
        synchronized (mutex) {
            if (CnAElementFactory.isIsoModelLoaded()) {
                if (modelUpdateListener == null) {
                    // modellistener should only be created once!
                    if (LOG.isDebugEnabled()) {
                        Logger.getLogger(this.getClass()).debug("Creating modelUpdateListener for ISMView."); //$NON-NLS-1$
                    }
                    modelUpdateListener = new TreeUpdateListener(viewer, elementManager);
                    CnAElementFactory.getInstance().getISO27kModel().addISO27KModelListener(modelUpdateListener);
                    Display.getDefault().syncExec(new Runnable() {
                        @Override
                        public void run() {
                            setInput(CnAElementFactory.getInstance().getISO27kModel());
                        }
                    });
                }
            } else if (modelLoadListener == null) {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("ISMView No model loaded, adding model load listener."); //$NON-NLS-1$
                }
                // model is not loaded yet: add a listener to load data when it's loaded
                modelLoadListener = new IModelLoadListener() {

                    @Override
                    public void closed(BSIModel model) {
                        // nothing to do
                    }

                    @Override
                    public void loaded(BSIModel model) {
                        // nothing to do
                    }

                    @Override
                    public void loaded(ISO27KModel model) {
                        startInitDataJob();
                    }

                };
                CnAElementFactory.getInstance().addLoadListener(modelLoadListener);

            }
        }
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.part.WorkbenchPart#dispose()
     */
    @Override
    public void dispose() {
        elementManager.clearCache();
        if (CnAElementFactory.isIsoModelLoaded()) {
            CnAElementFactory.getInstance().getISO27kModel().removeISO27KModelListener(modelUpdateListener);
        }
        CnAElementFactory.getInstance().removeLoadListener(modelLoadListener);
        getSite().getPage().removePartListener(linkWithEditorPartListener);
        super.dispose();
    }

    public void setInput(ISO27KModel model) {
        viewer.setInput(model);
    }

    public void setInput(List<Organization> organizationList) {
        viewer.setInput(organizationList);
    }

    public void setInput(Organization organization) {
        viewer.setInput(organization);
    }

    private void makeActions() {
        ControlDropPerformer controlDropAdapter;
        BSIModelViewDropListener bsiDropAdapter;
        doubleClickAction = new Action() {
            @Override
            public void run() {
                if (viewer.getSelection() instanceof IStructuredSelection) {
                    Object sel = ((IStructuredSelection) viewer.getSelection()).getFirstElement();
                    EditorFactory.getInstance().updateAndOpenObject(sel);
                }
            }
        };

        bulkEditAction = new ShowBulkEditAction(getViewSite().getWorkbenchWindow(), Messages.ISMView_6);

        // TODO: remove comments
        expandAction = new ExpandAction(viewer, contentProvider);
        expandAction.setText(Messages.ISMView_7);
        expandAction.setImageDescriptor(ImageCache.getInstance().getImageDescriptor(ImageCache.EXPANDALL));

        collapseAction = new CollapseAction(viewer);
        collapseAction.setText(Messages.ISMView_8);
        collapseAction.setImageDescriptor(ImageCache.getInstance().getImageDescriptor(ImageCache.COLLAPSEALL));

        expandAllAction = new Action() {
            @Override
            public void run() {
                expandAll();
            }
        };
        expandAllAction.setText(Messages.ISMView_9);
        expandAllAction.setImageDescriptor(ImageCache.getInstance().getImageDescriptor(ImageCache.EXPANDALL));

        collapseAllAction = new Action() {
            @Override
            public void run() {
                viewer.collapseAll();
            }
        };
        collapseAllAction.setText(Messages.ISMView_10);
        collapseAllAction.setImageDescriptor(ImageCache.getInstance().getImageDescriptor(ImageCache.COLLAPSEALL));

        HideEmptyFilter hideEmptyFilter = createHideEmptyFilter();
        TypeParameter typeParameter = createTypeParameter();
        TagParameter tagParameter = new TagParameter();
        filterAction = new ISMViewFilter(viewer, Messages.ISMView_12, tagParameter, hideEmptyFilter, typeParameter);

        elementManager.addParameter(tagParameter);
        if (typeParameter != null) {
            elementManager.addParameter(typeParameter);
        }

        metaDropAdapter = new MetaDropAdapter(viewer);
        controlDropAdapter = new ControlDropPerformer(viewer);
        bsiDropAdapter = new BSIModelViewDropListener(viewer);
        BSIModelDropPerformer bsi2IsmDropAdapter = new BSIModelDropPerformer(viewer);
        FileDropPerformer fileDropPerformer = new FileDropPerformer(viewer);
        metaDropAdapter.addAdapter(controlDropAdapter);
        metaDropAdapter.addAdapter(bsiDropAdapter);

        metaDropAdapter.addAdapter(bsi2IsmDropAdapter);
        metaDropAdapter.addAdapter(fileDropPerformer);

        accessControlEditAction = new ShowAccessControlEditAction(getViewSite().getWorkbenchWindow(),
                Messages.ISMView_11);

        naturalizeAction = new NaturalizeAction(getViewSite().getWorkbenchWindow());

        linkWithEditorAction = new Action(Messages.ISMView_5, IAction.AS_CHECK_BOX) {
            @Override
            public void run() {
                toggleLinking(isChecked());
            }
        };
        linkWithEditorAction.setChecked(isLinkingActive());
        linkWithEditorAction.setImageDescriptor(ImageCache.getInstance().getImageDescriptor(ImageCache.LINKED));

    }

    /**
     * Override this in subclasses to hide empty groups
     * on startup.
     * 
     * @return a HideEmptyFilter
     */
    protected HideEmptyFilter createHideEmptyFilter() {
        return new HideEmptyFilter(viewer);
    }

    /**
     * Override this in subclasses to hide empty groups
     * on startup.
     * 
     * @return a {@link TypeParameter}
     */
    protected TypeParameter createTypeParameter() {
        return new TypeParameter();
    }

    protected void fillToolBar() {
        IActionBars bars = getViewSite().getActionBars();
        IToolBarManager manager = bars.getToolBarManager();
        manager.add(expandAllAction);
        manager.add(collapseAllAction);
        drillDownAdapter.addNavigationActions(manager);
        manager.add(filterAction);
        manager.add(linkWithEditorAction);
    }

    private void hookContextMenu() {
        MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
        menuMgr.setRemoveAllWhenShown(true);
        menuMgr.addMenuListener(new IMenuListener() {
            @Override
            public void menuAboutToShow(IMenuManager manager) {
                fillContextMenu(manager);
            }
        });
        Menu menu = menuMgr.createContextMenu(viewer.getControl());

        viewer.getControl().setMenu(menu);
        getSite().registerContextMenu(menuMgr, viewer);
    }

    private void hookDNDListeners() {
        Transfer[] dragTypes = new Transfer[] { ISO27kElementTransfer.getInstance(),
                ISO27kGroupTransfer.getInstance() };
        Transfer[] dropTypes = new Transfer[] { IGSModelElementTransfer.getInstance(),
                BausteinUmsetzungTransfer.getInstance(), ItemTransfer.getInstance(),
                ISO27kElementTransfer.getInstance(), ISO27kGroupTransfer.getInstance(),
                IBSIStrukturElementTransfer.getInstance(), FileTransfer.getInstance() };

        viewer.addDragSupport(operations, dragTypes, new BSIModelViewDragListener(viewer));
        viewer.addDropSupport(operations, dropTypes, metaDropAdapter);

    }

    protected void expandAll() {
        viewer.expandAll();
    }

    private void addActions() {
        viewer.addDoubleClickListener(new IDoubleClickListener() {
            @Override
            public void doubleClick(DoubleClickEvent event) {
                doubleClickAction.run();
            }
        });

        viewer.addSelectionChangedListener(expandAction);
        viewer.addSelectionChangedListener(collapseAction);
    }

    /**
     * @param manager
     */
    protected void fillContextMenu(IMenuManager manager) {
        ISelection selection = viewer.getSelection();
        if (selection instanceof IStructuredSelection && ((IStructuredSelection) selection).size() == 1) {
            Object sel = ((IStructuredSelection) selection).getFirstElement();
            if (sel instanceof Organization) {
                Organization element = (Organization) sel;
                if (CnAElementHome.getInstance().isNewChildAllowed(element)) {
                    MenuManager submenuNew = new MenuManager("&New", "content/new"); //$NON-NLS-1$ //$NON-NLS-2$
                    submenuNew.add(new AddGroup(element, AssetGroup.TYPE_ID, Asset.TYPE_ID));
                    submenuNew.add(new AddGroup(element, AuditGroup.TYPE_ID, Audit.TYPE_ID));
                    submenuNew.add(new AddGroup(element, ControlGroup.TYPE_ID, Control.TYPE_ID));
                    submenuNew.add(new AddGroup(element, DocumentGroup.TYPE_ID, Document.TYPE_ID));
                    submenuNew.add(new AddGroup(element, EvidenceGroup.TYPE_ID, Evidence.TYPE_ID));
                    submenuNew.add(new AddGroup(element, ExceptionGroup.TYPE_ID,
                            sernet.verinice.model.iso27k.Exception.TYPE_ID));
                    submenuNew.add(new AddGroup(element, FindingGroup.TYPE_ID, Finding.TYPE_ID));
                    submenuNew.add(new AddGroup(element, IncidentGroup.TYPE_ID, Incident.TYPE_ID));
                    submenuNew.add(new AddGroup(element, IncidentScenarioGroup.TYPE_ID, IncidentScenario.TYPE_ID));
                    submenuNew.add(new AddGroup(element, InterviewGroup.TYPE_ID, Interview.TYPE_ID));
                    submenuNew.add(new AddGroup(element, PersonGroup.TYPE_ID, PersonIso.TYPE_ID));
                    submenuNew.add(new AddGroup(element, ProcessGroup.TYPE_ID,
                            sernet.verinice.model.iso27k.Process.TYPE_ID));
                    submenuNew.add(new AddGroup(element, RecordGroup.TYPE_ID, Record.TYPE_ID));
                    submenuNew.add(new AddGroup(element, RequirementGroup.TYPE_ID, Requirement.TYPE_ID));
                    submenuNew.add(new AddGroup(element, ResponseGroup.TYPE_ID, Response.TYPE_ID));
                    submenuNew.add(new AddGroup(element, ThreatGroup.TYPE_ID, Threat.TYPE_ID));
                    submenuNew.add(new AddGroup(element, VulnerabilityGroup.TYPE_ID, Vulnerability.TYPE_ID));
                    manager.add(submenuNew);
                }
            }
        }

        manager.add(new GroupMarker("content")); //$NON-NLS-1$
        manager.add(new Separator());
        manager.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
        manager.add(new Separator());
        manager.add(new GroupMarker("special")); //$NON-NLS-1$
        manager.add(bulkEditAction);
        manager.add(accessControlEditAction);
        manager.add(naturalizeAction);
        manager.add(new Separator());
        manager.add(expandAction);
        manager.add(collapseAction);
        drillDownAdapter.addNavigationActions(manager);
    }

    /* (non-Javadoc)
     * @see sernet.verinice.iso27k.rcp.ILinkedWithEditorView#editorActivated(org.eclipse.ui.IEditorPart)
     */
    @Override
    public void editorActivated(IEditorPart editor) {
        if (!isLinkingActive() || !getViewSite().getPage().isPartVisible(this)) {
            return;
        }
        CnATreeElement element = BSIElementEditorInput.extractElement(editor);
        if (element == null && editor.getEditorInput() instanceof AttachmentEditorInput) {
            element = getElementFromAttachment(editor);

        }
        if (!(element instanceof IISO27kElement)) {
            return;
        }

        if (LOG.isDebugEnabled()) {
            LOG.debug("Element in editor: " + element.getUuid()); //$NON-NLS-1$
            LOG.debug("Expanding tree now to show element..."); //$NON-NLS-1$
        }
        if (element != null) {
            viewer.setSelection(new StructuredSelection(element), true);
        } else {
            return;
        }

        if (LOG.isDebugEnabled()) {
            LOG.debug("Tree is expanded."); //$NON-NLS-1$
        }
    }

    /**
     * gets Element that is referenced by attachment shown by editor
     * @param editor - ({@link AttachmentEditor}) Editor of {@link Attachment}
     * @return {@link CnATreeElement}
     */
    private CnATreeElement getElementFromAttachment(IEditorPart editor) {
        return AttachmentEditorInput.extractCnaTreeElement(editor);
    }

    protected void toggleLinking(boolean checked) {
        this.linkingActive = checked;
        if (checked) {
            editorActivated(getSite().getPage().getActiveEditor());
        }
    }

    protected boolean isLinkingActive() {
        return linkingActive;
    }

    /**
     * Passing the focus request to the viewer's control.
     * 
     * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
     */
    @Override
    public void setFocus() {
        viewer.getControl().setFocus();
    }

    public ICommandService getCommandService() {
        if (commandService == null) {
            commandService = createCommandService();
        }
        return commandService;
    }

    private ICommandService createCommandService() {
        return ServiceFactory.lookupCommandService();
    }
}