com.windowtester.examples.gef.uml.editor.ClassDiagramEditor.java Source code

Java tutorial

Introduction

Here is the source code for com.windowtester.examples.gef.uml.editor.ClassDiagramEditor.java

Source

/*******************************************************************************
 * Copyright (c) 2004, 2005 Elias Volanakis 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:
 * Elias Volanakis - initial API and implementation
*******************************************************************************/
package com.windowtester.examples.gef.uml.editor;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.EventObject;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.gef.DefaultEditDomain;
import org.eclipse.gef.EditPartViewer;
import org.eclipse.gef.GraphicalViewer;
import org.eclipse.gef.RootEditPart;
import org.eclipse.gef.dnd.TemplateTransferDragSourceListener;
import org.eclipse.gef.dnd.TemplateTransferDropTargetListener;
import org.eclipse.gef.editparts.ScalableFreeformRootEditPart;
import org.eclipse.gef.palette.PaletteRoot;
import org.eclipse.gef.requests.CreationFactory;
import org.eclipse.gef.requests.SimpleFactory;
import org.eclipse.gef.ui.actions.ActionRegistry;
import org.eclipse.gef.ui.palette.PaletteViewer;
import org.eclipse.gef.ui.palette.PaletteViewerProvider;
import org.eclipse.gef.ui.parts.ContentOutlinePage;
import org.eclipse.gef.ui.parts.GraphicalEditorWithFlyoutPalette;
import org.eclipse.gef.ui.parts.GraphicalViewerKeyHandler;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.util.TransferDropTargetListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
import org.eclipse.ui.dialogs.SaveAsDialog;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.part.IPageSite;
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;

import com.windowtester.examples.gef.uml.model.ClassDiagram;
import com.windowtester.examples.gef.uml.model.ClassElement;
import com.windowtester.examples.gef.uml.parts.ClassDiagramEditPartFactory;

/**
 * A graphical editor with flyout palette that can edit .cd files. The
 * binding between the .shapes file extension and this editor is done in
 * plugin.xml
 * 
 * @author Elias Volanakis
 * @author Phil Quitslund
 */
public class ClassDiagramEditor extends GraphicalEditorWithFlyoutPalette {

    /** This is the root of the editor's model. */
    private ClassDiagram diagram;
    /** Palette component, holding the tools and shapes. */
    private static PaletteRoot PALETTE_MODEL;

    /** the overview outline page */
    private OverviewOutlinePage overviewOutlinePage;

    /** Create a new ClassDiagramEditor instance. This is called by the Workspace. */
    public ClassDiagramEditor() {
        setEditDomain(new DefaultEditDomain(this));
    }

    /**
     * Configure the graphical viewer before it receives contents.
     * <p>
     * This is the place to choose an appropriate RootEditPart and
     * EditPartFactory for your editor. The RootEditPart determines the behavior
     * of the editor's "work-area". For example, GEF includes zoomable and
     * scrollable root edit parts. The EditPartFactory maps model elements to
     * edit parts (controllers).
     * </p>
     * 
     * @see org.eclipse.gef.ui.parts.GraphicalEditor#configureGraphicalViewer()
     */
    protected void configureGraphicalViewer() {
        super.configureGraphicalViewer();

        GraphicalViewer viewer = getGraphicalViewer();
        viewer.setEditPartFactory(new ClassDiagramEditPartFactory());
        viewer.setRootEditPart(new ScalableFreeformRootEditPart());
        viewer.setKeyHandler(new GraphicalViewerKeyHandler(viewer));

        // configure the context menu provider
        //      ContextMenuProvider cmProvider = new ShapesEditorContextMenuProvider(
        //            viewer, getActionRegistry());
        //      viewer.setContextMenu(cmProvider);
        //      getSite().registerContextMenu(cmProvider, viewer);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.gef.ui.parts.GraphicalEditor#commandStackChanged(java.util.EventObject)
     */
    public void commandStackChanged(EventObject event) {
        firePropertyChange(IEditorPart.PROP_DIRTY);
        super.commandStackChanged(event);
    }

    private void createOutputStream(OutputStream os) throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(os);
        oos.writeObject(getModel());
        oos.close();
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.gef.ui.parts.GraphicalEditorWithFlyoutPalette#createPaletteViewerProvider()
     */
    protected PaletteViewerProvider createPaletteViewerProvider() {
        return new PaletteViewerProvider(getEditDomain()) {
            protected void configurePaletteViewer(PaletteViewer viewer) {
                super.configurePaletteViewer(viewer);
                // create a drag source listener for this palette viewer
                // together with an appropriate transfer drop target listener,
                // this will enable
                // model element creation by dragging a
                // CombinatedTemplateCreationEntries
                // from the palette into the editor
                // @see ClassDiagramEditor#createTransferDropTargetListener()
                viewer.addDragSourceListener(new TemplateTransferDragSourceListener(viewer));
            }
        };
    }

    /**
     * Create a transfer drop target listener. When using a
     * CombinedTemplateCreationEntry tool in the palette, this will enable model
     * element creation by dragging from the palette.
     * 
     * @see #createPaletteViewerProvider()
     */
    private TransferDropTargetListener createTransferDropTargetListener() {
        return new TemplateTransferDropTargetListener(getGraphicalViewer()) {
            protected CreationFactory getFactory(Object template) {
                if (template == ClassElement.class)
                    return new ClassCreationFactory();
                return new SimpleFactory((Class<?>) template);
            }
        };
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.ISaveablePart#doSave(org.eclipse.core.runtime.IProgressMonitor)
     */
    public void doSave(IProgressMonitor monitor) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        try {
            createOutputStream(out);
            IFile file = ((IFileEditorInput) getEditorInput()).getFile();
            file.setContents(new ByteArrayInputStream(out.toByteArray()), true, false, // dont keep history
                    monitor); // progress monitor
            getCommandStack().markSaveLocation();
        } catch (CoreException ce) {
            ce.printStackTrace();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.ISaveablePart#doSaveAs()
     */
    public void doSaveAs() {
        // Show a SaveAs dialog
        Shell shell = getSite().getWorkbenchWindow().getShell();
        SaveAsDialog dialog = new SaveAsDialog(shell);
        dialog.setOriginalFile(((IFileEditorInput) getEditorInput()).getFile());
        dialog.open();

        IPath path = dialog.getResult();
        if (path != null) {
            // try to save the editor's contents under a different file name
            final IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
            try {
                new ProgressMonitorDialog(shell).run(false, // don't fork
                        false, // not cancelable
                        new WorkspaceModifyOperation() { // run this
                            // operation
                            public void execute(final IProgressMonitor monitor) {
                                try {
                                    ByteArrayOutputStream out = new ByteArrayOutputStream();
                                    createOutputStream(out);
                                    file.create(new ByteArrayInputStream(out.toByteArray()), // contents
                                            true, // keep saving, even if
                                            // IFile is out of sync with
                                            // the Workspace
                                            monitor); // progress monitor
                                } catch (CoreException ce) {
                                    ce.printStackTrace();
                                } catch (IOException ioe) {
                                    ioe.printStackTrace();
                                }
                            }
                        });
                // set input to the new file
                setInput(new FileEditorInput(file));
                getCommandStack().markSaveLocation();
            } catch (InterruptedException ie) {
                // should not happen, since the monitor dialog is not cancelable
                ie.printStackTrace();
            } catch (InvocationTargetException ite) {
                ite.printStackTrace();
            }
        }
    }

    @SuppressWarnings("unchecked")
    public Object getAdapter(Class type) {
        //      if (type == IContentOutlinePage.class)
        //         return new ShapesOutlinePage(new TreeViewer());
        if (type == IContentOutlinePage.class)
            return getOverviewOutlinePage();
        return super.getAdapter(type);
    }

    ClassDiagram getModel() {
        return diagram;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.gef.ui.parts.GraphicalEditorWithFlyoutPalette#getPaletteRoot()
     */
    protected PaletteRoot getPaletteRoot() {
        if (PALETTE_MODEL == null)
            PALETTE_MODEL = ClassDiagramEditorPaletteFactory.createPalette();
        return PALETTE_MODEL;
    }

    private void handleLoadException(Exception e) {
        System.err.println("** Load failed. Using default model. **");
        e.printStackTrace();
        diagram = new ClassDiagram();
    }

    /**
     * Set up the editor's inital content (after creation).
     * 
     * @see org.eclipse.gef.ui.parts.GraphicalEditorWithFlyoutPalette#initializeGraphicalViewer()
     */
    protected void initializeGraphicalViewer() {
        super.initializeGraphicalViewer();
        GraphicalViewer viewer = getGraphicalViewer();
        viewer.setContents(getModel()); // set the contents of this editor

        // listen for dropped parts
        viewer.addDropTargetListener(createTransferDropTargetListener());
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.ISaveablePart#isSaveAsAllowed()
     */
    public boolean isSaveAsAllowed() {
        return true;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.part.EditorPart#setInput(org.eclipse.ui.IEditorInput)
     */
    protected void setInput(IEditorInput input) {
        super.setInput(input);
        try {
            IFile file = ((IFileEditorInput) input).getFile();
            ObjectInputStream in = new ObjectInputStream(file.getContents());
            diagram = (ClassDiagram) in.readObject();
            in.close();
            setPartName(file.getName());
        } catch (IOException e) {
            handleLoadException(e);
        } catch (CoreException e) {
            handleLoadException(e);
        } catch (ClassNotFoundException e) {
            handleLoadException(e);
        }
    }

    /**
     * Creates an outline pagebook for this editor.
     */
    public class ShapesOutlinePage extends ContentOutlinePage {
        /**
         * Create a new outline page for the shapes editor.
         * 
         * @param viewer
         *            a viewer (TreeViewer instance) used for this outline page
         * @throws IllegalArgumentException
         *             if editor is null
         */
        public ShapesOutlinePage(EditPartViewer viewer) {
            super(viewer);
        }

        /*
         * (non-Javadoc)
         * 
         * @see org.eclipse.ui.part.IPage#createControl(org.eclipse.swt.widgets.Composite)
         */
        public void createControl(Composite parent) {
            // create outline viewer page
            getViewer().createControl(parent);
            // configure outline viewer
            getViewer().setEditDomain(getEditDomain());
            getViewer().setEditPartFactory(new ClassDiagramEditPartFactory());
            // configure & add context menu to viewer
            //         ContextMenuProvider cmProvider = new ShapesEditorContextMenuProvider(
            //               getViewer(), getActionRegistry());
            //         getViewer().setContextMenu(cmProvider);
            //         getSite().registerContextMenu(
            //               "org.eclipse.gef.examples.shapes.outline.contextmenu",
            //               cmProvider, getSite().getSelectionProvider());
            // hook outline viewer
            getSelectionSynchronizer().addViewer(getViewer());
            // initialize outline viewer with model
            getViewer().setContents(getModel());
            // show outline viewer
        }

        /*
         * (non-Javadoc)
         * 
         * @see org.eclipse.ui.part.IPage#dispose()
         */
        public void dispose() {
            // unhook outline viewer
            getSelectionSynchronizer().removeViewer(getViewer());
            // dispose
            super.dispose();
        }

        /*
         * (non-Javadoc)
         * 
         * @see org.eclipse.ui.part.IPage#getControl()
         */
        public Control getControl() {
            return getViewer().getControl();
        }

        /**
         * @see org.eclipse.ui.part.IPageBookViewPage#init(org.eclipse.ui.part.IPageSite)
         */
        public void init(IPageSite pageSite) {
            super.init(pageSite);
            ActionRegistry registry = getActionRegistry();
            IActionBars bars = pageSite.getActionBars();
            String id = ActionFactory.UNDO.getId();
            bars.setGlobalActionHandler(id, registry.getAction(id));
            id = ActionFactory.REDO.getId();
            bars.setGlobalActionHandler(id, registry.getAction(id));
            id = ActionFactory.DELETE.getId();
            bars.setGlobalActionHandler(id, registry.getAction(id));
        }
    }

    protected OverviewOutlinePage getOverviewOutlinePage() {
        if (null == overviewOutlinePage && null != getGraphicalViewer()) {
            RootEditPart rootEditPart = getGraphicalViewer().getRootEditPart();
            if (rootEditPart instanceof ScalableFreeformRootEditPart) {
                overviewOutlinePage = new OverviewOutlinePage((ScalableFreeformRootEditPart) rootEditPart);
            }
        }

        return overviewOutlinePage;
    }

    /* $codepro.preprocessor.if version <= 3.1 $ 
        
    //Necessary for Eclipse 3.1
    protected org.eclipse.gef.ui.palette.FlyoutPaletteComposite.FlyoutPreferences getPalettePreferences() {
       // TODO what should be returned here?
       return null;
    }
    $codepro.preprocessor.endif $ */

}