com.byterefinery.rmbench.export.ModelCompareEditorInput.java Source code

Java tutorial

Introduction

Here is the source code for com.byterefinery.rmbench.export.ModelCompareEditorInput.java

Source

/*
 * created 18.10.2005
 *
 * Copyright 2009, ByteRefinery
 * 
 * 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
 * 
 * $Id: ModelCompareEditorInput.java 669 2007-10-27 08:23:31Z cse $
 */
package com.byterefinery.rmbench.export;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;

import org.eclipse.compare.CompareConfiguration;
import org.eclipse.compare.CompareEditorInput;
import org.eclipse.compare.structuremergeviewer.DiffNode;
import org.eclipse.compare.structuremergeviewer.Differencer;
import org.eclipse.compare.structuremergeviewer.IDiffElement;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IStorageEditorInput;
import org.eclipse.ui.PlatformUI;

import com.byterefinery.rmbench.RMBenchPlugin;
import com.byterefinery.rmbench.dialogs.ExceptionDialog;
import com.byterefinery.rmbench.exceptions.SystemException;
import com.byterefinery.rmbench.export.diff.IDBComparisonNode;
import com.byterefinery.rmbench.export.diff.IModelComparisonNode;
import com.byterefinery.rmbench.export.diff.StructureNode;
import com.byterefinery.rmbench.external.IDDLFormatter;
import com.byterefinery.rmbench.external.IDDLGenerator;
import com.byterefinery.rmbench.external.IDDLScript;
import com.byterefinery.rmbench.external.IDatabaseInfo;
import com.byterefinery.rmbench.model.Model;
import com.byterefinery.rmbench.model.dbimport.DBModel;

/**
 * Editor input for use in exporting a RMBench model to a database. Although this subclasses
 * a class from the eclipse compare framework, it is used in a slightly non-standard way.
 * 
 * @author cse
 */
public class ModelCompareEditorInput extends CompareEditorInput implements IStorageEditorInput {

    private final Model model;
    private final DBModel dbmodel;

    private final IDDLGenerator generator;
    private final IDDLScript script;
    private final IDDLFormatter formatter;
    private final boolean generateDrop;
    private final boolean ignoreCase;

    private Storage storage = new Storage();
    private final Shell shell;

    /**
     * @param model model to export
     * @param dbmodel database model to export to
     * @param ddlGenerator a ready configured DDL generator
     * @param drop true if SQL DROP statements should be generated for elements found 
     * in the database but not in the model  
     * @param shell the parent shell for error & connection dialogs
     */
    public ModelCompareEditorInput(Model model, DBModel dbmodel, IDDLGenerator generator, IDDLFormatter formatter,
            IDDLScript script, boolean generateDrop, boolean ignoreCase, Shell shell) {

        super(createCompareConfiguration());
        this.model = model;
        this.dbmodel = dbmodel;
        this.shell = shell;
        this.generator = generator;
        this.script = script;
        this.formatter = formatter;
        this.ignoreCase = ignoreCase;
        this.generateDrop = generateDrop;
    }

    public Model getModel() {
        return model;
    }

    /**
     * unused method
     * @throws UnsupportedOperationException
     */
    public Viewer createDiffViewer(Composite parent) {
        throw new UnsupportedOperationException();
    }

    /**
     * Perform the model comparison, displaying error dialogs if the comparison fails or 
     * no differences are found. 
     * 
     * @return true if successful
     */
    public boolean compareResultOK() {
        try {
            PlatformUI.getWorkbench().getProgressService().run(true, false, this);

            String message = getMessage();
            if (message != null) {
                MessageDialog.openError(shell, Messages.CompareInput_compareFailed, message);
                return false;
            }

            if (dbmodel.isLoaded() && getCompareResult() == null) {
                MessageDialog.openInformation(shell, Messages.CompareInput_DialogTitle,
                        Messages.CompareInput_noDifferences);
                return false;
            }

            return true;

        } catch (InterruptedException x) {
            // cancelled by user        
        } catch (InvocationTargetException x) {
            RMBenchPlugin.logError(x.getTargetException());
            String msg = x.getTargetException().getMessage();
            if (msg == null)
                msg = x.getTargetException().getClass().getName();
            ExceptionDialog.openError(shell, Messages.CompareInput_compareFailed,
                    SystemException.getStatus(x.getTargetException(), msg));
        }
        return false;
    }

    private static CompareConfiguration createCompareConfiguration() {
        CompareConfiguration config = new CompareConfiguration();
        config.setProperty(CompareConfiguration.SHOW_PSEUDO_CONFLICTS, Boolean.TRUE);
        return config;
    }

    protected Object prepareInput(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {

        monitor.beginTask(Messages.CompareInput_beginTask, IProgressMonitor.UNKNOWN);
        setTitle(Messages.CompareInput_Title);

        try {
            monitor.subTask(Messages.CompareInput_subtaskLoad);
            if (!dbmodel.load(shell))
                return null;

            //create diff node trees for both models
            StructureNode left = new com.byterefinery.rmbench.export.diff.model.ModelNode(model,
                    dbmodel.getPublicSchemaNames());
            StructureNode right = new com.byterefinery.rmbench.export.diff.db.ModelNode(dbmodel.getName(),
                    dbmodel.getSchemas());
            if (ignoreCase) {
                left.setIgnoreCase(true);
                right.setIgnoreCase(true);
            }

            //run the differ over the 2 trees
            Differencer diff = new Differencer();
            return diff.findDifferences(false, monitor, null, null, left, right);
        } catch (Exception ex) {
            throw new InvocationTargetException(ex);
        } finally {
            monitor.done();
        }
    }

    /**
     * @return the statement terminator used by the underlying script
     */
    public String getStatementTerminator() {
        return script.getStatementTerminator();
    }

    private void generateDDL(DiffNode node) {

        IDiffElement[] diffElements = node.getChildren();

        for (int i = 0; i < diffElements.length; i++) {
            DiffNode childNode = (DiffNode) diffElements[i];
            switch (childNode.getKind()) {
            case Differencer.ADDITION: {
                if (generateDrop)
                    ((IDBComparisonNode) childNode.getRight()).generateDropDDL(generator, script);
                break;
            }
            case Differencer.DELETION: {
                ((IModelComparisonNode) childNode.getLeft()).generateCreateDDL(generator, script);
                break;
            }
            case Differencer.CHANGE: {
                IModelComparisonNode modelNode = (IModelComparisonNode) childNode.getLeft();
                if (modelNode.getValue() != null) {
                    IDBComparisonNode dbNode = (IDBComparisonNode) childNode.getRight();
                    modelNode.generateAlterDDL(generator, dbNode.getElement(), script);
                }
                break;
            }
            }
            generateDDL((DiffNode) diffElements[i]);
        }
    }

    public IDatabaseInfo getModelDatabaseInfo() {
        return model.getDatabaseInfo();
    }

    public IStorage getStorage() {
        return storage;
    }

    public void reset() {
        try {
            script.reset();
            storage.generateContents();
        } catch (CoreException e) {
            RMBenchPlugin.logError(e);
        }
    }

    private class Storage implements IStorage {

        private byte[] ddl;

        public InputStream getContents() throws CoreException {
            if (ddl == null) {
                generateContents();
            }
            return new ByteArrayInputStream(ddl);
        }

        public void generateContents() throws CoreException {
            DiffNode diffNode = (DiffNode) getCompareResult();
            if (diffNode == null)
                throw new CoreException(SystemException.getStatus(null, "compare result not set"));

            generateDDL(diffNode);
            ddl = script.generate(formatter).getBytes();
        }

        public IPath getFullPath() {
            return null;
        }

        public String getName() {
            return ModelCompareEditorInput.this.getName();
        }

        public boolean isReadOnly() {
            return false;
        }

        @SuppressWarnings("rawtypes")
        public Object getAdapter(Class adapter) {
            return null;
        }
    }
}