com.twinsoft.convertigo.eclipse.views.schema.SchemaView.java Source code

Java tutorial

Introduction

Here is the source code for com.twinsoft.convertigo.eclipse.views.schema.SchemaView.java

Source

/*
 * Copyright (c) 2001-2011 Convertigo SA.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License
 * as published by the Free Software Foundation; either version 3
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see<http://www.gnu.org/licenses/>.
 *
 * $URL$
 * $Author$
 * $Revision$
 * $Date$
 */

package com.twinsoft.convertigo.eclipse.views.schema;

import java.io.IOException;
import java.util.Iterator;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

import org.apache.ws.commons.schema.XmlSchema;
import org.apache.ws.commons.schema.XmlSchemaCollection;
import org.apache.ws.commons.schema.XmlSchemaObject;
import org.eclipse.jface.viewers.IElementComparer;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

import com.twinsoft.convertigo.beans.core.DatabaseObject;
import com.twinsoft.convertigo.eclipse.ConvertigoPlugin;
import com.twinsoft.convertigo.eclipse.editors.connector.htmlconnector.TwsDomTree;
import com.twinsoft.convertigo.eclipse.swt.SwtUtils;
import com.twinsoft.convertigo.eclipse.views.projectexplorer.ProjectExplorerView;
import com.twinsoft.convertigo.eclipse.views.projectexplorer.TreeObjectEvent;
import com.twinsoft.convertigo.eclipse.views.projectexplorer.TreeObjectListener;
import com.twinsoft.convertigo.eclipse.views.projectexplorer.model.DatabaseObjectTreeObject;
import com.twinsoft.convertigo.eclipse.views.schema.SchemaViewContentProvider.Root;
import com.twinsoft.convertigo.engine.Engine;
import com.twinsoft.convertigo.engine.SchemaManager.Option;
import com.twinsoft.convertigo.engine.enums.SchemaMeta;
import com.twinsoft.convertigo.engine.util.EngineListenerHelper;
import com.twinsoft.convertigo.engine.util.XmlSchemaUtils;

public class SchemaView extends ViewPart implements IPartListener, ISelectionListener, TreeObjectListener {
    private Composite content;
    private TreeViewer schemaTreeViewer;
    private ISelection schemaTreeViewerSelection;
    private TreePath[] schemaTreeViewerExpandedTreePaths;
    private TreeViewer nodeTreeViewer;
    private ISelection nodeTreeViewerSelection;
    private TreePath[] nodeTreeViewerExpandedTreePaths;
    private TwsDomTree domTree;

    private Label message;
    private ToolItem autoRefresh;
    private ToolItem autoValidate;
    private ToolItem internalSchema;

    private boolean needRefresh;
    private boolean needValidate;
    private String projectName;

    private Thread workingThread;
    private Queue<Runnable> tasks = new ConcurrentLinkedQueue<Runnable>();
    private EngineListenerHelper engineListener = new EngineListenerHelper() {

        @Override
        public void documentGenerated(final Document document) {
            final Element documentElement = document.getDocumentElement();
            if (documentElement != null) {
                String project = documentElement.getAttribute("project");
                if (project != null && project.equals(projectName)) {
                    String sequence = documentElement.getAttribute("sequence");
                    String connector = documentElement.getAttribute("connector");
                    String transaction = documentElement.getAttribute("transaction");
                    final String requestableName = sequence != null && sequence.length() > 0 ? sequence
                            : connector + "__" + transaction;

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

                            public void run() {
                                message.setForeground(
                                        Display.getCurrent().getSystemColor(SWT.COLOR_WIDGET_FOREGROUND));
                                message.setText("Waiting for " + projectName + " " + requestableName
                                        + " XML response validation");
                            }

                        });

                        tasks.add(new Runnable() {

                            public void run() {
                                final Exception[] exception = { null };
                                try {
                                    Engine.theApp.schemaManager.validateResponse(projectName, requestableName,
                                            document);
                                } catch (SAXException e) {
                                    exception[0] = e;
                                }

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

                                    public void run() {
                                        if (message != null && !message.isDisposed()) {
                                            if (exception[0] == null) {
                                                message.setForeground(
                                                        Display.getCurrent().getSystemColor(SWT.COLOR_DARK_GREEN));
                                                message.setText("The " + projectName + " " + requestableName
                                                        + " XML response is valid.");
                                            } else {
                                                message.setForeground(
                                                        Display.getCurrent().getSystemColor(SWT.COLOR_DARK_RED));
                                                message.setText("The " + projectName + " " + requestableName
                                                        + " XML response is invalid : "
                                                        + exception[0].toString()/*exception[0].getMessage()*/);
                                            }
                                            content.layout(true);
                                        }
                                    }

                                });
                            }

                        });
                    } else {
                        Display.getDefault().asyncExec(new Runnable() {

                            public void run() {
                                message.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_DARK_GREEN));
                                message.setText("'" + projectName + "' schema generated.");
                            }

                        });
                    }
                }
            }
        }

    };

    public SchemaView() {
    }

    @Override
    public void createPartControl(Composite parent) {
        workingThread = new Thread(new Runnable() {

            public void run() {
                while (workingThread != null) {

                    try {
                        Runnable task = null;
                        synchronized (workingThread) {
                            task = tasks.poll();
                            if (task == null) {
                                workingThread.wait(5000);
                            }
                        }
                        if (task != null) {
                            task.run();
                        }
                    } catch (Throwable e) {
                        System.err.println("Exception in " + projectName);
                        e.printStackTrace();
                    }
                }
            }

        });
        workingThread.setName("SchemaViewThread");
        workingThread.start();

        makeUI(content = new Composite(parent, SWT.NONE));

        getSite().getPage().addSelectionListener(this);

        PlatformUI.getWorkbench().getActiveWorkbenchWindow().getPartService().addPartListener(this);

        ConvertigoPlugin.runAtStartup(new Runnable() {

            @Override
            public void run() {
                Engine.theApp.addEngineListener(engineListener);
            }

        });
    }

    private void makeUI(Composite content) {
        content.setLayout(SwtUtils.newGridLayout(1, false, 0, 0, 0, 0));

        // TOP TOOLBAR
        Composite composite = new Composite(content, SWT.BORDER);
        composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

        composite.setLayout(SwtUtils.newGridLayout(2, false, 0, 0, 0, 0));
        composite.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_LIST_BACKGROUND));

        ToolBar toolbar = new ToolBar(composite, SWT.NONE);

        ToolItem toolItem = new ToolItem(toolbar, SWT.PUSH);
        setToolItemIcon(toolItem, "icons/studio/refresh.gif", "R", "Refresh");
        toolItem.addSelectionListener(new SelectionListener() {

            public void widgetSelected(SelectionEvent e) {
                needRefresh = true;
                Engine.theApp.schemaManager.clearCache(projectName);
                updateSchema((IStructuredSelection) ConvertigoPlugin.getDefault().getProjectExplorerView().viewer
                        .getSelection());
            }

            public void widgetDefaultSelected(SelectionEvent e) {
            }

        });

        toolItem = autoRefresh = new ToolItem(toolbar, SWT.CHECK);
        setToolItemIcon(toolItem, "icons/studio/refresh.d.gif", "AR", "Toggle auto refresh");
        toolItem.setSelection(true);

        toolItem = autoValidate = new ToolItem(toolbar, SWT.CHECK);
        setToolItemIcon(toolItem, "icons/studio/validate.gif", "AV", "Toggle auto validate");
        toolItem.setSelection(false);
        toolItem.addSelectionListener(new SelectionListener() {

            public void widgetSelected(SelectionEvent e) {
                needValidate = autoValidate.getSelection();
            }

            public void widgetDefaultSelected(SelectionEvent e) {
            }

        });

        toolItem = internalSchema = new ToolItem(toolbar, SWT.CHECK);
        setToolItemIcon(toolItem, "icons/studio/pretty_print.gif", "IS", "Toggle internal schema");
        toolItem.addSelectionListener(new SelectionListener() {

            public void widgetSelected(SelectionEvent e) {
                needRefresh = true;
                updateSchema((IStructuredSelection) ConvertigoPlugin.getDefault().getProjectExplorerView().viewer
                        .getSelection());
            }

            public void widgetDefaultSelected(SelectionEvent e) {
            }

        });

        message = new Label(composite, SWT.WRAP);
        message.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        message.setText("No schema to generate");

        // MAIN SASH FORM
        SashForm sashForm = new SashForm(content, SWT.NONE);
        sashForm.setOrientation(SWT.HORIZONTAL);
        sashForm.setLayoutData(new GridData(GridData.FILL_BOTH));

        // SCHEMA PANE
        schemaTreeViewer = makeTreeViewer(sashForm);
        schemaTreeViewer.setContentProvider(new SchemaViewContentProvider(3));
        schemaTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
            public void selectionChanged(SelectionChangedEvent event) {
                Object firstElement = ((IStructuredSelection) event.getSelection()).getFirstElement();
                if (firstElement instanceof XmlSchemaObject
                        && (nodeTreeViewer.getInput() == null
                                || ((Root) nodeTreeViewer.getInput()).get() != firstElement)
                        && !(firstElement instanceof XmlSchema)) {
                    nodeTreeViewer.setInput(SchemaViewContentProvider.newRoot(firstElement));

                    if (nodeTreeViewerExpandedTreePaths != null && nodeTreeViewerExpandedTreePaths.length > 0) {
                        nodeTreeViewer.setExpandedTreePaths(nodeTreeViewerExpandedTreePaths);
                        nodeTreeViewer.setSelection(nodeTreeViewerSelection);
                        nodeTreeViewerExpandedTreePaths = null;
                        nodeTreeViewerSelection = null;
                    } else {
                        nodeTreeViewer.expandToLevel(5);
                        domTree.fillDomTree(XmlSchemaUtils.getDomInstance((XmlSchemaObject) firstElement));
                    }
                }
            }
        });

        // DETAIL PANE
        nodeTreeViewer = makeTreeViewer(sashForm);
        nodeTreeViewer.setContentProvider(new SchemaViewContentProvider());
        nodeTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
            public void selectionChanged(SelectionChangedEvent event) {
                Object firstElement = ((IStructuredSelection) event.getSelection()).getFirstElement();
                if (firstElement instanceof XmlSchemaObject && !(firstElement instanceof XmlSchema)) {
                    domTree.fillDomTree(XmlSchemaUtils.getDomInstance((XmlSchemaObject) firstElement));
                }
            }
        });

        // DOM PANE
        composite = new Composite(sashForm, SWT.NONE);
        composite.setLayoutData(new GridData(GridData.FILL_BOTH));
        composite.setLayout(SwtUtils.newGridLayout(1, false, 0, 0, 0, 0));

        toolbar = new ToolBar(composite, SWT.NONE);
        toolbar.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

        toolItem = new ToolItem(toolbar, SWT.PUSH);
        setToolItemIcon(toolItem, "icons/studio/collapse_all_nodes.gif", "C", "Collapse all");
        toolItem.addSelectionListener(new SelectionListener() {

            @Override
            public void widgetSelected(SelectionEvent e) {
                domTree.collapseAll();
            }

            @Override
            public void widgetDefaultSelected(SelectionEvent e) {
            }
        });

        toolItem = new ToolItem(toolbar, SWT.PUSH);
        setToolItemIcon(toolItem, "icons/studio/expand_all_nodes.gif", "E", "Expand all");
        toolItem.addSelectionListener(new SelectionListener() {

            @Override
            public void widgetSelected(SelectionEvent e) {
                domTree.expandAll();
            }

            @Override
            public void widgetDefaultSelected(SelectionEvent e) {
            }
        });

        domTree = new TwsDomTree(composite, SWT.BORDER);
        domTree.setLayoutData(new GridData(GridData.FILL_BOTH));
    }

    @Override
    public void dispose() {
        workingThread = null;
        try {
            getSite().getPage().removeSelectionListener(this);
            Engine.theApp.removeEngineListener(engineListener);
            PlatformUI.getWorkbench().getActiveWorkbenchWindow().getPartService().removePartListener(this);
        } catch (Exception e) {
        }
        ;
        content.dispose();
        super.dispose();
    }

    @Override
    public void setFocus() {
        schemaTreeViewer.getControl().setFocus();
    }

    public void selectionChanged(IWorkbenchPart part, ISelection selection) {
        if (selection instanceof IStructuredSelection && part instanceof ProjectExplorerView) {
            if (autoRefresh.getSelection()) {
                updateSchema((IStructuredSelection) selection);
            }
        }
    }

    public void partOpened(IWorkbenchPart part) {
        if (part instanceof ProjectExplorerView) {
            ((ProjectExplorerView) part).addTreeObjectListener(this);
        }
    }

    public void partClosed(IWorkbenchPart part) {
        if (part instanceof ProjectExplorerView) {
            ((ProjectExplorerView) part).removeTreeObjectListener(this);
        }
    }

    public void partBroughtToTop(IWorkbenchPart part) {
    }

    public void partActivated(IWorkbenchPart part) {
        if (part instanceof ProjectExplorerView) {
            ((ProjectExplorerView) part).addTreeObjectListener(this);
        }
    }

    public void partDeactivated(IWorkbenchPart part) {
    }

    public void treeObjectAdded(TreeObjectEvent treeObjectEvent) {
        needRefresh = true;
    }

    public void treeObjectPropertyChanged(TreeObjectEvent treeObjectEvent) {
        needRefresh = true;
    }

    public void treeObjectRemoved(TreeObjectEvent treeObjectEvent) {
        needRefresh = true;
    }

    private void setToolItemIcon(ToolItem toolItem, String iconPath, String text, String tooltip) {
        try {
            toolItem.setImage(ConvertigoPlugin.getDefault().getStudioIcon(iconPath));
        } catch (IOException e1) {
            toolItem.setText(text);
        }
        toolItem.setToolTipText(tooltip);
    }

    private TreeViewer makeTreeViewer(Composite parent) {
        Composite composite = new Composite(parent, SWT.NONE);
        composite.setLayoutData(new GridData(GridData.FILL_BOTH));
        composite.setLayout(SwtUtils.newGridLayout(1, false, 0, 0, 0, 0));

        ToolBar toolbar = new ToolBar(composite, SWT.NONE);
        toolbar.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

        final TreeViewer treeViewer = new TreeViewer(composite);

        ToolItem toolItem = new ToolItem(toolbar, SWT.PUSH);
        setToolItemIcon(toolItem, "icons/studio/collapse_all_nodes.gif", "C", "Collapse all");

        toolItem.addSelectionListener(new SelectionListener() {

            public void widgetSelected(SelectionEvent e) {
                treeViewer.collapseAll();
            }

            public void widgetDefaultSelected(SelectionEvent e) {
            }
        });

        toolItem = new ToolItem(toolbar, SWT.PUSH);
        setToolItemIcon(toolItem, "icons/studio/expand_all_nodes.gif", "E", "Expand all");

        toolItem.addSelectionListener(new SelectionListener() {

            public void widgetSelected(SelectionEvent e) {
                treeViewer.expandToLevel(50);
            }

            public void widgetDefaultSelected(SelectionEvent e) {
            }
        });

        treeViewer.getTree().setLayoutData(new GridData(GridData.FILL_BOTH));
        treeViewer.setLabelProvider(SchemaViewContentProvider.decoratingLabelProvider);
        treeViewer.setComparer(new IElementComparer() {

            public int hashCode(Object element) {
                String txt = SchemaViewContentProvider.decoratingLabelProvider.getText(element);
                int hash = txt.hashCode();
                if (element instanceof XmlSchemaObject) {
                    Iterator<DatabaseObject> ref = SchemaMeta
                            .getReferencedDatabaseObjects((XmlSchemaObject) element).iterator();
                    if (ref.hasNext()) {
                        hash += ref.next().hashCode();
                    }
                }
                return hash;
            }

            public boolean equals(Object a, Object b) {
                boolean ret = false;
                if (a != null && b != null && a.getClass().equals(b.getClass())) {
                    String aTxt = SchemaViewContentProvider.decoratingLabelProvider.getText(a);
                    String bTxt = SchemaViewContentProvider.decoratingLabelProvider.getText(b);
                    if (aTxt.equals(bTxt)) {
                        if (a instanceof XmlSchemaObject) {
                            Iterator<DatabaseObject> aRef = SchemaMeta
                                    .getReferencedDatabaseObjects((XmlSchemaObject) a).iterator();
                            Iterator<DatabaseObject> bRef = SchemaMeta
                                    .getReferencedDatabaseObjects((XmlSchemaObject) b).iterator();
                            if (aRef.hasNext() && bRef.hasNext()) {
                                ret = aRef.next() == bRef.next();
                            }
                        } else {
                            ret = true;
                        }
                    }
                }
                return ret;
            }
        });
        return treeViewer;
    }

    private void updateSchema(IStructuredSelection selection) {
        Object firstElement = selection.getFirstElement();
        if (firstElement instanceof DatabaseObjectTreeObject) {
            DatabaseObjectTreeObject dboTreeObject = (DatabaseObjectTreeObject) firstElement;
            String currentProjectName = dboTreeObject.getProjectTreeObject().getName();
            if (needRefresh || (projectName == null) || (!projectName.equals(currentProjectName))) {
                needRefresh = false;
                projectName = currentProjectName;

                schemaTreeViewerExpandedTreePaths = schemaTreeViewer.getExpandedTreePaths();
                schemaTreeViewerSelection = schemaTreeViewer.getSelection();

                nodeTreeViewerExpandedTreePaths = nodeTreeViewer.getExpandedTreePaths();
                nodeTreeViewerSelection = nodeTreeViewer.getSelection();

                schemaTreeViewer.setInput(null);
                nodeTreeViewer.setInput(null);
                domTree.fillDomTree(null);
                message.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_WIDGET_FOREGROUND));
                message.setText("Waiting for the " + projectName + " schema generation...");

                final boolean fullSchema = internalSchema.getSelection();

                synchronized (workingThread) {
                    tasks.add(new Runnable() {

                        public void run() {
                            try {
                                final XmlSchemaCollection xmlSchemaCollection = Engine.theApp.schemaManager
                                        .getSchemasForProject(projectName, fullSchema ? Option.fullSchema : null);

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

                                    public void run() {
                                        schemaTreeViewer.setInput(xmlSchemaCollection);

                                        if (schemaTreeViewerExpandedTreePaths != null
                                                && schemaTreeViewerExpandedTreePaths.length > 0) {
                                            schemaTreeViewer
                                                    .setExpandedTreePaths(schemaTreeViewerExpandedTreePaths);
                                            schemaTreeViewer.setSelection(schemaTreeViewerSelection);
                                            schemaTreeViewerExpandedTreePaths = null;
                                            schemaTreeViewerSelection = null;
                                        } else {
                                            schemaTreeViewer.expandToLevel(3);
                                        }
                                    }

                                });

                                if (needValidate) {
                                    final Exception[] exception = { null };
                                    try {
                                        XmlSchemaUtils.validate(xmlSchemaCollection);
                                    } catch (SAXException e) {
                                        exception[0] = e;
                                    }

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

                                        public void run() {
                                            if (exception[0] == null) {
                                                message.setForeground(
                                                        Display.getCurrent().getSystemColor(SWT.COLOR_DARK_GREEN));
                                                message.setText("The " + projectName + " schema is valid.");
                                            } else {
                                                message.setForeground(
                                                        Display.getCurrent().getSystemColor(SWT.COLOR_DARK_RED));
                                                message.setText("The " + projectName + " schema is invalid : "
                                                        + exception[0].toString()/*getMessage()*/);
                                            }
                                            content.layout(true);
                                        }

                                    });
                                } else {
                                    Display.getDefault().asyncExec(new Runnable() {

                                        public void run() {
                                            message.setForeground(
                                                    Display.getCurrent().getSystemColor(SWT.COLOR_DARK_GREEN));
                                            message.setText("'" + projectName + "' schema generated.");
                                            content.layout(true);
                                        }

                                    });
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    });
                    workingThread.notify();
                }
            }
        }
    }
}