sernet.gs.ui.rcp.main.bsi.views.BsiModelView.java Source code

Java tutorial

Introduction

Here is the source code for sernet.gs.ui.rcp.main.bsi.views.BsiModelView.java

Source

/*******************************************************************************
 * Copyright (c) 2009 Alexander Koderman <ak[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:
 *     Alexander Koderman <ak[at]sernet[dot]de> - initial API and implementation
 ******************************************************************************/

package sernet.gs.ui.rcp.main.bsi.views;

import java.util.ArrayList;
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.dialogs.MessageDialog;
import org.eclipse.jface.viewers.DecoratingLabelProvider;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Shell;
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.PlatformUI;
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.Perspective;
import sernet.gs.ui.rcp.main.actions.GSMBasicSecurityCheckAction;
import sernet.gs.ui.rcp.main.actions.ShowAccessControlEditAction;
import sernet.gs.ui.rcp.main.actions.ShowBulkEditAction;
import sernet.gs.ui.rcp.main.actions.ShowKonsolidatorAction;
import sernet.gs.ui.rcp.main.bsi.actions.BausteinZuordnungAction;
import sernet.gs.ui.rcp.main.bsi.actions.GSMBausteinZuordnungAction;
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.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.bsi.filter.BSIModelElementFilter;
import sernet.gs.ui.rcp.main.bsi.filter.LebenszyklusPropertyFilter;
import sernet.gs.ui.rcp.main.bsi.filter.MassnahmenSiegelFilter;
import sernet.gs.ui.rcp.main.bsi.filter.MassnahmenUmsetzungFilter;
import sernet.gs.ui.rcp.main.bsi.filter.ObjektLebenszyklusPropertyFilter;
import sernet.gs.ui.rcp.main.bsi.filter.TagFilter;
import sernet.gs.ui.rcp.main.bsi.risikoanalyse.wizard.RiskAnalysisWizard;
import sernet.gs.ui.rcp.main.bsi.views.actions.BSIModelViewFilterAction;
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.common.model.NullModel;
import sernet.gs.ui.rcp.main.preferences.PreferenceConstants;
import sernet.gs.ui.rcp.main.service.ServiceFactory;
import sernet.gs.ui.rcp.main.service.crudcommands.LoadCnAElementByType;
import sernet.verinice.interfaces.ActionRightIDs;
import sernet.verinice.interfaces.CommandException;
import sernet.verinice.iso27k.rcp.ILinkedWithEditorView;
import sernet.verinice.iso27k.rcp.JobScheduler;
import sernet.verinice.iso27k.rcp.LinkWithEditorPartListener;
import sernet.verinice.model.bsi.Attachment;
import sernet.verinice.model.bsi.BSIModel;
import sernet.verinice.model.bsi.BausteinUmsetzung;
import sernet.verinice.model.bsi.IBSIStrukturElement;
import sernet.verinice.model.bsi.MassnahmenUmsetzung;
import sernet.verinice.model.bsi.risikoanalyse.FinishedRiskAnalysis;
import sernet.verinice.model.common.CnATreeElement;
import sernet.verinice.model.ds.IDatenschutzElement;
import sernet.verinice.model.iso27k.ISO27KModel;
import sernet.verinice.rcp.IAttachedToPerspective;
import sernet.verinice.rcp.RightsEnabledView;
import sernet.verinice.rcp.tree.ElementManager;
import sernet.verinice.rcp.tree.TreeContentProvider;
import sernet.verinice.rcp.tree.TreeUpdateListener;

/**
 * View for a tree structure, representing the data model for modeling an IT
 * Baseline Protection implementation comprising IT Networks, associated
 * Controls, Risk Analysis's etc.
 * 
 * @author koderman[at]sernet[dot]de *
 */
public class BsiModelView extends RightsEnabledView implements IAttachedToPerspective, ILinkedWithEditorView {

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

    public static final String ID = "sernet.gs.ui.rcp.main.views.bsimodelview"; //$NON-NLS-1$

    private Action doubleClickAction;

    private DrillDownAdapter drillDownAdapter;

    private BSIModel model;

    private TreeViewer viewer;

    private BSIModelViewFilterAction filterAction;

    private ElementManager elementManager;

    private Action expandAllAction;

    private Action collapseAction;

    private Action linkWithEditorAction;

    private ShowBulkEditAction bulkEditAction;

    private ShowAccessControlEditAction accessControlEditAction;

    private NaturalizeAction naturalizeAction;

    private Action selectEqualsAction;

    private ShowKonsolidatorAction konsolidatorAction;

    private GSMBasicSecurityCheckAction gsmbasicsecuritycheckAction;

    private BausteinZuordnungAction bausteinZuordnungAction;

    private GSMBausteinZuordnungAction gsmbausteinZuordnungAction;

    private IModelLoadListener modelLoadListener;

    private TreeUpdateListener bsiModelListener;

    private boolean linkingActive = false;

    private IPartListener2 linkWithEditorPartListener = new LinkWithEditorPartListener(this);

    public BsiModelView() {

        elementManager = new ElementManager();
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.part.WorkbenchPart#dispose()
     */
    @Override
    public void dispose() {
        model.removeBSIModelListener(bsiModelListener);
        CnAElementFactory.getInstance().removeLoadListener(modelLoadListener);
        getSite().getPage().removePartListener(linkWithEditorPartListener);
        super.dispose();
    }

    public void setNullModel() {
        model = new NullModel();

        refreshModelAsync();

    }

    private void refreshModelAsync() {

        Display.getDefault().asyncExec(new Runnable() {
            @Override
            public void run() {
                try {
                    viewer.setInput(model);
                    viewer.refresh();
                } catch (Exception e) {
                    ExceptionUtil.log(e, Messages.BsiModelView_18);
                }
            }
        });
    }

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

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

    private void addBSIFilter() {
        viewer.addFilter(new ViewerFilter() {
            @Override
            public boolean select(Viewer viewer, Object parentElement, Object element) {
                if (element instanceof IDatenschutzElement) {
                    return false;
                }
                return true;
            }

        });
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.
     * widgets.Composite)
     */
    @Override
    public void createPartControl(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.BsiModelView_7);
        }

        loadItBaselineProtectionCatalogs();
    }

    private void initView(Composite parent) {
        IWorkbench workbench = getSite().getWorkbenchWindow().getWorkbench();

        viewer = new TreeViewer(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI);
        drillDownAdapter = new DrillDownAdapter(viewer);

        TreeContentProvider contentProvider = new TreeContentProvider(elementManager);
        viewer.setContentProvider(contentProvider);

        viewer.setLabelProvider(
                new DecoratingLabelProvider(new BSIModelViewLabelProvider(), workbench.getDecoratorManager()));
        viewer.setSorter(new CnAElementByTitelSorter());
        toggleLinking(Activator.getDefault().getPreferenceStore().getBoolean(PreferenceConstants.LINK_TO_EDITOR));

        getSite().setSelectionProvider(viewer);
        makeActions();
        createPullDownMenu();
        hookContextMenu();
        hookDoubleClickAction();
        hookDNDListeners();
        addBSIFilter();
        fillLocalToolBar();
        getSite().getPage().addPartListener(linkWithEditorPartListener);
        setNullModel();
    }

    protected void startInitDataJob() {
        WorkspaceJob initDataJob = new WorkspaceJob(Messages.BsiModelView_5) {
            @Override
            public IStatus runInWorkspace(final IProgressMonitor monitor) {
                IStatus status = Status.OK_STATUS;
                try {
                    monitor.beginTask(Messages.BsiModelView_5, 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", //$NON-NLS-1$
                            Messages.BsiModelView_9, e);
                } finally {
                    monitor.done();
                }
                return status;
            }
        };
        JobScheduler.scheduleInitJob(initDataJob);
    }

    private void initData() {
        if (CnAElementFactory.isModelLoaded()) {
            setModel(CnAElementFactory.getLoadedModel());
        } else if (modelLoadListener == null) {
            // model is not loaded yet: add a listener to load data when it's
            // laoded
            modelLoadListener = new IModelLoadListener() {
                @Override
                public void closed(BSIModel model) {
                    // nothing to do
                }

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

                @Override
                public void loaded(ISO27KModel model) {
                    // nothing to do            
                }
            };
            CnAElementFactory.getInstance().addLoadListener(modelLoadListener);
        }
    }

    private static void loadItBaselineProtectionCatalogs() {
        WorkspaceJob job = new OpenCataloguesJob(Messages.BSIMassnahmenView_0);
        JobScheduler.scheduleInitJob(job);
    }

    private void fillContextMenu(IMenuManager manager) {
        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(selectEqualsAction);
        selectEqualsAction.setEnabled(bausteinSelected());
        manager.add(konsolidatorAction);
        manager.add(gsmbasicsecuritycheckAction);
        manager.add(bausteinZuordnungAction);
        manager.add(gsmbausteinZuordnungAction);

        manager.add(new Separator());
        drillDownAdapter.addNavigationActions(manager);
        manager.add(expandAllAction);
        manager.add(collapseAction);
    }

    private boolean bausteinSelected() {
        IStructuredSelection sel = (IStructuredSelection) viewer.getSelection();
        if (!sel.isEmpty() && sel.size() == 1 && sel.getFirstElement() instanceof BausteinUmsetzung) {
            return true;
        }
        return false;
    }

    private void fillLocalToolBar() {
        IActionBars bars = getViewSite().getActionBars();
        IToolBarManager manager = bars.getToolBarManager();
        manager.add(this.filterAction);
        manager.add(new Separator());
        drillDownAdapter.addNavigationActions(manager);
        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[] dropTypes = new Transfer[] { IGSModelElementTransfer.getInstance(),
                BausteinUmsetzungTransfer.getInstance(), IBSIStrukturElementTransfer.getInstance() };
        Transfer[] dragTypes = new Transfer[] { IBSIStrukturElementTransfer.getInstance(),
                BausteinUmsetzungTransfer.getInstance() };

        int operations = DND.DROP_COPY | DND.DROP_MOVE;
        viewer.addDropSupport(operations, dropTypes, new BSIModelViewDropListener(viewer));
        viewer.addDragSupport(operations, dragTypes, new BSIModelViewDragListener(viewer));
    }

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

    private void makeActions() {

        final int newSelDefaultSize = 10;
        selectEqualsAction = new Action() {

            @Override
            public void run() {

                IStructuredSelection sel = (IStructuredSelection) viewer.getSelection();
                Object o = sel.getFirstElement();
                if (o instanceof BausteinUmsetzung) {
                    BausteinUmsetzung sourceBst = (BausteinUmsetzung) o;
                    ArrayList<BausteinUmsetzung> newsel = new ArrayList<>(newSelDefaultSize);
                    newsel.add(sourceBst);

                    try {
                        LoadCnAElementByType<BausteinUmsetzung> command = new LoadCnAElementByType<BausteinUmsetzung>(
                                BausteinUmsetzung.class);
                        command = ServiceFactory.lookupCommandService().executeCommand(command);
                        List<BausteinUmsetzung> bausteine = command.getElements();

                        for (BausteinUmsetzung bst : bausteine) {
                            if (bst.getKapitel().equals(sourceBst.getKapitel())) {
                                newsel.add(bst);
                            }
                        }
                    } catch (CommandException e) {
                        ExceptionUtil.log(e, ""); //$NON-NLS-1$
                    }

                    viewer.setSelection(new StructuredSelection(newsel));
                }
            }
        };
        selectEqualsAction.setText(Messages.BsiModelView_11);

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

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

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

        konsolidatorAction = new ShowKonsolidatorAction(getViewSite().getWorkbenchWindow(),
                Messages.BsiModelView_15);

        gsmbasicsecuritycheckAction = new GSMBasicSecurityCheckAction(getViewSite().getWorkbenchWindow(),
                Messages.BsiModelView_19);

        bausteinZuordnungAction = new BausteinZuordnungAction(getViewSite().getWorkbenchWindow());

        gsmbausteinZuordnungAction = new GSMBausteinZuordnungAction(getViewSite().getWorkbenchWindow());

        doubleClickAction = new Action() {

            @Override
            public void run() {

                Object sel = ((IStructuredSelection) viewer.getSelection()).getFirstElement();

                if (sel instanceof FinishedRiskAnalysis) {
                    FinishedRiskAnalysis analysis = (FinishedRiskAnalysis) sel;
                    if (CnAElementHome.getInstance().isWriteAllowed(analysis)) {
                        RiskAnalysisWizard wizard = new RiskAnalysisWizard(analysis.getParent(), analysis);
                        wizard.init(PlatformUI.getWorkbench(), null);
                        WizardDialog wizDialog = new org.eclipse.jface.wizard.WizardDialog(new Shell(), wizard);
                        wizDialog.setPageSize(wizard.getWidth(), wizard.getHeight());

                        wizDialog.open();
                    } else {
                        MessageDialog.openError(viewer.getTree().getShell(), Messages.BsiModelView_RA_0,
                                Messages.BsiModelView_RA_1);
                    }
                } else {
                    EditorFactory.getInstance().updateAndOpenObject(sel);
                }
            }
        };

        BSIModelElementFilter modelElementFilter = new BSIModelElementFilter(viewer);

        filterAction = new BSIModelViewFilterAction(Messages.BsiModelView_3, new MassnahmenUmsetzungFilter(viewer),
                new MassnahmenSiegelFilter(viewer), new LebenszyklusPropertyFilter(viewer),
                new ObjektLebenszyklusPropertyFilter(viewer), modelElementFilter, new TagFilter(viewer));

        expandAllAction = new Action() {

            @Override
            public void run() {

                expandAll();
            }
        };
        expandAllAction.setText(Messages.BsiModelView_16);
        expandAllAction.setImageDescriptor(ImageCache.getInstance().getImageDescriptor(ImageCache.EXPANDALL));

        collapseAction = new Action() {

            @Override
            public void run() {

                viewer.collapseAll();
            }
        };
        collapseAction.setText(Messages.BsiModelView_17);
        collapseAction.setImageDescriptor(ImageCache.getInstance().getImageDescriptor(ImageCache.COLLAPSEALL));

        linkWithEditorAction = new Action(Messages.BsiModelView_6, IAction.AS_CHECK_BOX) {

            @Override
            public void run() {

                toggleLinking(isChecked());
            }
        };
        linkWithEditorAction.setChecked(isLinkingActive());
        linkWithEditorAction.setImageDescriptor(ImageCache.getInstance().getImageDescriptor(ImageCache.LINKED));
    }

    protected void buildBausteinUmsetzung(BausteinUmsetzung sourceBst) {

        final int newSelDefaultSize = 10;

        ArrayList<BausteinUmsetzung> newsel = new ArrayList<>(newSelDefaultSize);
        newsel.add(sourceBst);
        try {
            LoadCnAElementByType<BausteinUmsetzung> command = new LoadCnAElementByType<>(BausteinUmsetzung.class);
            command = ServiceFactory.lookupCommandService().executeCommand(command);
            List<BausteinUmsetzung> bausteine = command.getElements();

            for (BausteinUmsetzung bst : bausteine) {
                if (bst.getKapitel().equals(sourceBst.getKapitel())) {
                    newsel.add(bst);
                }
            }

        } catch (CommandException e) {
            ExceptionUtil.log(e, ""); //$NON-NLS-1$
        }

        viewer.setSelection(new StructuredSelection(newsel));
    }

    private void expandAll() {

        // TODO: do this a new thread and show user a progress bar
        viewer.expandAll();
    }

    /**
     * Passing the focus request to the viewer's control.
     */
    @Override
    public void setFocus() {
        viewer.getControl().setFocus();
    }

    private void createPullDownMenu() {
        IMenuManager menuManager = getViewSite().getActionBars().getMenuManager();
        menuManager.add(filterAction);
        menuManager.add(expandAllAction);
        menuManager.add(collapseAction);

        menuManager.add(new Separator());
    }

    public void setModel(BSIModel newModel) {

        // create listener only once:
        if (bsiModelListener == null) {
            bsiModelListener = new TreeUpdateListener(viewer, elementManager);
        }

        if (model != null) {
            // remove listener from old model:
            model.removeBSIModelListener(bsiModelListener);
        }

        this.model = newModel;
        model.addBSIModelListener(bsiModelListener);

        refreshModelAsync();

    }

    public IStructuredSelection getSelection() {
        return (IStructuredSelection) viewer.getSelection();
    }

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

    /*
     * (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) {
            element = getElementFromAttachment(editor);
        }
        if (element != null && ((element instanceof IBSIStrukturElement) || (element instanceof MassnahmenUmsetzung)
                || (element instanceof BausteinUmsetzung))) {
            viewer.setSelection(new StructuredSelection(element), true);
        }
        return;
    }

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

    protected boolean isLinkingActive() {
        return linkingActive;
    }

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