Package org.locationtech.udig.validation.ui

Source Code of org.locationtech.udig.validation.ui.ValidationDialog

/* uDig - User Friendly Desktop Internet GIS client
* http://udig.refractions.net
* (C) 2004, Refractions Research Inc.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* (http://www.eclipse.org/legal/epl-v10.html), and the Refractions BSD
* License v1.0 (http://udig.refractions.net/files/bsd3-v10.html).
*/
package org.locationtech.udig.validation.ui;

import java.beans.IntrospectionException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.locationtech.udig.issues.IIssuesManager;
import org.locationtech.udig.issues.IssueConstants;
import org.locationtech.udig.project.ILayer;
import org.locationtech.udig.project.IMap;
import org.locationtech.udig.project.ui.ApplicationGIS;
import org.locationtech.udig.ui.PlatformGIS;
import org.locationtech.udig.ui.graphics.TableSettings;
import org.locationtech.udig.ui.graphics.TableUtils;
import org.locationtech.udig.validation.DTOUtils;
import org.locationtech.udig.validation.GenericValidationResults;
import org.locationtech.udig.validation.ImageConstants;
import org.locationtech.udig.validation.ValidationPlugin;
import org.locationtech.udig.validation.ValidationProcessor;
import org.locationtech.udig.validation.internal.Messages;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.wizard.ProgressMonitorPart;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.model.WorkbenchViewerSorter;
import org.geotools.validation.Validation;
import org.geotools.validation.dto.ArgumentDTO;
import org.geotools.validation.dto.PlugInDTO;
import org.geotools.validation.dto.TestDTO;
import org.geotools.validation.dto.TestSuiteDTO;
import org.geotools.validation.xml.ValidationException;
import org.geotools.validation.xml.XMLReader;
import org.geotools.validation.xml.XMLWriter;
import org.opengis.feature.simple.SimpleFeatureType;

public class ValidationDialog extends TitleAreaDialog {
   
    /**
     * Constant to use as the key for storing the validation processor on the
     * blackboard (for saving the state of the validation dialog box)
     */
    public static final String BLACKBOARD_KEY = "org.locationtech.udig.validation"; //$NON-NLS-1$
   
    private Button newButton;
    private Button deleteButton;
    private Button exportButton;
    private Button importButton;
    private Button runButton;
    private Button cancelButton;
    private Composite buttonComposite;
    private SelectionListener closeListener;
    private SelectionListener cancelListener;
    private Text nameText;
    private Text descText;
    private TableViewer tableViewer;
    private TableSettings tableSettings;
    private CheckboxTreeViewer treeViewer;
    private ValidationTreeContentProvider contentProvider = null;
   
    private ProgressMonitorPart progressMonitorPart;
    private Object selectedTreeItem;
    private ValidationProcessor processor;

    /** The key (name) of the testSuite in use (usually there will only be a
     *  single testSuite, and this is its name). */
    private String defaultTestSuite;
   
    /** If a layer was selected to get to this dialog, it is the default testSuite.
     *  Otherwise the value is "" or even "*". */
    private String defaultTypeRef = ""; //$NON-NLS-1$
    private Display display;
   
    private static String[] typeRefs;
    private static String[] layerNames;
    //private ILayer[] layers;

    public ValidationDialog(Shell parentShell, ILayer[] layers) {
        this(parentShell);
        // determine the defaultTypeRef (from the first selected layer)
        String dsID = layers[0].getSchema().getName().getNamespaceURI();
        String typeName = layers[0].getName();
        defaultTypeRef = dsID+":"+typeName; //$NON-NLS-1$
        //this.layers = layers;
        display = parentShell.getDisplay();
       
        cancelListener = new SelectionListener() {

            public void widgetSelected( SelectionEvent e ) {
                // a test is running and the user just hit cancel
                // cancel the progress monitor
                progressMonitorPart.setCanceled(true);
                cancelButton.setEnabled(false);
            }

            public void widgetDefaultSelected( SelectionEvent e ) {
                widgetSelected(e);
            }
           
        };
    }
   
    protected ValidationDialog(Shell parentShell) {
        super(parentShell);
        setShellStyle(SWT.DIALOG_TRIM | SWT.RESIZE | SWT.APPLICATION_MODAL | getDefaultOrientation());
        setBlockOnOpen(true);
    }
   
    public ValidationDialog getDialog() {
        return this;  
    }
   
    public Button getCancelButton() {
        return cancelButton;
    }
   
    @Override
    protected Control createButtonBar(Composite parent) {
        Composite composite = new Composite(parent, SWT.FILL);
        GridLayout layout = new GridLayout();
        layout.numColumns = 2;
        layout.makeColumnsEqualWidth = true;
        layout.marginWidth = 0; // no spacing here, it's purely a container
        layout.marginHeight = 0;
        layout.horizontalSpacing = 0;
        layout.verticalSpacing = 0;
        composite.setLayout(layout);
        GridData data = new GridData(SWT.FILL, SWT.CENTER, true, false);
        composite.setLayoutData(data);
        composite.setFont(parent.getFont());
       
        // create 2 composites in the composite with left and right aligns
        Composite leftComp = new Composite(composite, SWT.LEFT);
        layout = new GridLayout();
        layout.numColumns = 2;
        layout.makeColumnsEqualWidth = true;
        layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
        layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
        layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
        layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
        leftComp.setLayout(layout);
        data = new GridData(SWT.LEFT, SWT.NONE, true, false);
        leftComp.setLayoutData(data);
        leftComp.setFont(parent.getFont());

        Composite rightComp = new Composite(composite, SWT.RIGHT);
        layout = new GridLayout();
        layout.numColumns = 2;
        layout.makeColumnsEqualWidth = true;
        layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
        layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
        layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
        layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
        rightComp.setLayout(layout);
        data = new GridData(SWT.RIGHT, SWT.NONE, true, false);
        rightComp.setLayoutData(data);
        rightComp.setFont(parent.getFont());
       
        // Add the buttons
        importButton = new Button(leftComp, SWT.PUSH);
        importButton.setFont(parent.getFont());
        importButton.setText(Messages.ValidationDialog_import);
        importButton.setEnabled(true);
        importButton.addSelectionListener(new ImportSuiteListener());
        setButtonLayoutData(importButton);

        exportButton = new Button(leftComp, SWT.PUSH);
        exportButton.setFont(parent.getFont());
        exportButton.setText(Messages.ValidationDialog_export);
        exportButton.setEnabled(false);
        exportButton.addSelectionListener(new ExportSuiteListener());
        setButtonLayoutData(exportButton);
       
        runButton = new Button(rightComp, SWT.PUSH);
        runButton.setFont(parent.getFont());
        runButton.setText(Messages.ValidationDialog_run);
        runButton.setEnabled(false);
        runButton.addSelectionListener(new RunTestsListener());
        setButtonLayoutData(runButton);
       
        cancelButton = new Button(rightComp, SWT.PUSH);
        cancelButton.setText(IDialogConstants.CLOSE_LABEL);
        cancelButton.setFont(parent.getFont());
        cancelButton.setData(new Integer(IDialogConstants.CANCEL_ID));
        closeListener = new SelectionAdapter() {
            public void widgetSelected(SelectionEvent event) {
                // nothing is happening and the user hit cancel (close)
                buttonPressed(((Integer) event.widget.getData()).intValue());
            }
        };
//        cancelListener = new SelectionListener() {
//
//            public void widgetSelected( SelectionEvent e ) {
//                // a test is running and the user just hit cancel
//                // cancel the progress monitor
//                progressMonitorPart.setCanceled(true);
//                cancelButton.setEnabled(false);
//            }
//
//            public void widgetDefaultSelected( SelectionEvent e ) {
//                widgetSelected(e);
//            }
//           
//        };
        cancelButton.addSelectionListener(closeListener);
        setButtonLayoutData(cancelButton);
       
        return composite;
    }

    @Override
    protected void createButtonsForButtonBar(Composite parent) {
    }

    @Override
    protected Control createDialogArea( Composite parent ) {
        Composite composite = new Composite(parent, SWT.NONE);
        setTitle(Messages.ValidationDialog_title);
        setMessage(""); //$NON-NLS-1$
        ImageDescriptor image = ValidationPlugin.getDefault().getImageDescriptor(ImageConstants.IMAGE_WIZBAN);
        if (image != null) setTitleImage(image.createImage());

        GridData gd;
        gd = new GridData(SWT.FILL, SWT.FILL, true, true);
        composite.setLayoutData(gd);
        GridLayout topLayout = new GridLayout(1, false);
        topLayout.marginHeight = 0;
        topLayout.marginWidth = 0;
        composite.setLayout(topLayout);
       
        // Create the SashForm that contains the selection area on the left,
        // and the edit area on the right
        SashForm sashForm = new SashForm(composite, SWT.FILL);
        sashForm.setOrientation(SWT.HORIZONTAL);
        gd = new GridData(SWT.FILL, SWT.FILL, true, true);
        sashForm.setLayoutData(gd);
        sashForm.setFont(parent.getFont());
       
        // Build the validation selection area and put it into the composite.
        Composite validationSelectionArea;
        try {
            validationSelectionArea = createValidationSelectionArea(sashForm);
        } catch (Exception e) {
            // TODO Handle Exception
            throw (RuntimeException) new RuntimeException( ).initCause( e );
        }
        gd = new GridData(SWT.FILL, SWT.FILL, true, true);
        validationSelectionArea.setLayoutData(gd);
       
        // Build the validation edit area and put it into the composite.
        Composite editAreaComp = createValidationEditArea(sashForm);
        gd = new GridData(SWT.FILL, SWT.FILL, true, true);
        editAreaComp.setLayoutData(gd);

        // add the progress bar
        GridLayout pmlayout = new GridLayout();
        pmlayout.numColumns = 1;
        progressMonitorPart = createProgressMonitorPart(composite, pmlayout);
        progressMonitorPart
                .setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        progressMonitorPart.setVisible(false);

        // Build the separator line that demarcates the button bar
        Label separator = new Label(composite, SWT.HORIZONTAL | SWT.SEPARATOR);
        gd = new GridData(SWT.FILL, SWT.NONE, true, false);
        // gd.horizontalSpan = 2;
        separator.setLayoutData(gd);
       
        parent.layout(true);
        applyDialogFont(parent);
       
        // create a resize listener
        composite.addListener(SWT.Resize, new Listener() {

            public void handleEvent(Event event) {
                resizeTable();
                // FIXME: possibly move this listener to the table.resize event
            }
           
        });
       
        composite.addDisposeListener(new DisposeListener() {

            public void widgetDisposed(DisposeEvent e) {
                // find the Map
                IMap map = ApplicationGIS.getActiveMap();
                saveDialogState(processor, map);
            }
           
        });
       
        return composite;
    }

    /**
     * Creates the validation test suite selection area of the dialog. This area displays a tree of
     * validations that the user may select and modify. The first tier of the tree contains the
     * available validation plugins, and the second tier contains instances of the test.
     *
     * @return the composite used for the validations selection area
     * @throws Exception
     */
    protected Composite createValidationSelectionArea(Composite parent) throws Exception {
        Font font = parent.getFont();
        Composite comp = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout(1, false);
        layout.marginHeight = 5;
        layout.marginWidth = 5;
        comp.setLayout(layout);
        comp.setFont(font);
       
        Label treeLabel = new Label(comp, SWT.NONE);
        treeLabel.setFont(font);
        treeLabel.setText(Messages.ValidationDialog_validations);
        GridData labelData = new GridData();
        treeLabel.setLayoutData(labelData);
       
        ValidationProcessor tempProcessor = loadDialogState(ApplicationGIS.getActiveMap());
        if (tempProcessor == null) {
            processor = createProcessor(null, null);
            defaultTestSuite = "testSuite1"; //$NON-NLS-1$
        } else {
            processor = tempProcessor;
            if (processor.getTestSuiteDTOs().size() == 1) {
                // a single testSuite exists, grab its name
                defaultTestSuite = (String) processor.getTestSuiteDTOs().keySet().toArray()[0];
            } else if (processor.getTestSuiteDTOs().size() == 0) {
                // there is no... testSuite, create one
                processor = createProcessor(null, null);
                defaultTestSuite = "testSuite1"; //$NON-NLS-1$
            } else {
                // there are multiple testSuites, choose the largest one
                String thisTestSuite = ""; //$NON-NLS-1$
                int mostTests = -1;
                for (Iterator i = processor.getTestSuiteDTOs().keySet().iterator(); i.hasNext();) {
                    Object thisKey = i.next();
                    int numTests = ((TestSuiteDTO) processor.getTestSuiteDTOs().get(thisKey)).getTests().size();
                    if (numTests > mostTests) {
                        mostTests = numTests;
                        thisTestSuite = (String) thisKey;
                    }
                }
                defaultTestSuite = thisTestSuite;
            }
        }
   
        // create the treeViewer (list of possible validations (plugins) + prepared tests)
        treeViewer = new CheckboxTreeViewer(comp);
        treeViewer.setLabelProvider(new ValidationTreeLabelProvider());
        treeViewer.setSorter(new WorkbenchViewerSorter());
        contentProvider = new ValidationTreeContentProvider();
        treeViewer.setContentProvider(contentProvider);
        treeViewer.addCheckStateListener(new ICheckStateListener(){
            public void checkStateChanged( CheckStateChangedEvent event ) {
                Object element = event.getElement();
                Object[] children = contentProvider.getChildren(element);
                if (children != null && children.length > 0) {
                    // parent element was modified, adjust the children accordingly
                    for( int i = 0; i < children.length; i++ ) {
                        treeViewer.setChecked(children[i], event.getChecked());
                    }
                    // all children are in the same state, therefore the parent is not grayed
                    treeViewer.setGrayed(element, false);
                }
   
                Object parent = contentProvider.getParent(element);
                if (parent != null) {
                    // child element was modified
                    Object[] siblings = contentProvider.getChildren(parent);
                    boolean oneSiblingChecked = false;
                    boolean allSiblingsChecked = true;
                    for (int i = 0; i < siblings.length; i++) {
                        if (treeViewer.getChecked(siblings[i])) {
                            oneSiblingChecked = true;
                        } else {
                            allSiblingsChecked = false;
                        }
                    }
                    if (allSiblingsChecked) { // mark parent checked and NOT grayed out
                        treeViewer.setGrayed(parent, false);
                        treeViewer.setChecked(parent, true);
                    } else {
                        if (oneSiblingChecked) { // mark parent checked and grayed out
                            treeViewer.setGrayChecked(parent, true);
                        } else { // mark parent NOT checked
                            treeViewer.setGrayChecked(parent, false);
                        }
                    }
                }                       
            }
        });
   
        // populate the tree
        treeViewer.setInput(processor);
        treeViewer.expandAll();
   
        Control control = treeViewer.getControl();
        GridData gd = new GridData(GridData.FILL_BOTH);
        gd.heightHint = 250; // initial height of treeViewer (in pixels?)
        gd.verticalSpan = 3;
        control.setLayoutData(gd);
        control.setFont(font);
       
        // composite to hold the new/delete/save/... buttons
        buttonComposite = new Composite(comp, SWT.NONE);
        gd = new GridData(GridData.FILL_HORIZONTAL);
        gd.widthHint = 200;
        buttonComposite.setLayoutData(gd);
        buttonComposite.setFont(comp.getFont());
       
        GridLayout buttonLayout = new GridLayout(2, false);
        buttonComposite.setLayout(buttonLayout);
       
        // construct the new validation test button
        newButton = new Button(buttonComposite, SWT.PUSH);
        newButton.setFont(parent.getFont());
        newButton.setText(Messages.ValidationDialog_new);
        newButton.setEnabled(false);
        newButton.addSelectionListener(new NewTestListener());
        setButtonLayoutData(newButton);
   
        // construct the delete validation test button
        deleteButton = new Button(buttonComposite, SWT.PUSH);
        deleteButton.setFont(parent.getFont());
        deleteButton.setText(Messages.ValidationDialog_delete);
        deleteButton.setEnabled(false);
        deleteButton.addSelectionListener(new DeleteTestListener());
        setButtonLayoutData(deleteButton);
   
        // construct treeViewer listener
        treeViewer.addSelectionChangedListener(new ISelectionChangedListener() {

            public void selectionChanged( SelectionChangedEvent event ) {
                if (!event.getSelection().isEmpty()) {
                    StructuredSelection selection = (StructuredSelection) event.getSelection();
                    if (selection.size() == 1) {
                        Object element = selection.getFirstElement();
                        selectedTreeItem = element; //record the current selection so other events can figure out who is selected
                        if (element instanceof TestDTO) { //test instance was selected
                            newButton.setEnabled(false);
                            deleteButton.setEnabled(true);
                            nameText.setText(((TestDTO) element).getName());
                            nameText.setEditable(true);
                            descText.setText(((TestDTO) element).getDescription());
                            descText.setEditable(true);
                            tableViewer.setInput(element); // pass the args (inside the testDTO)
                            tableViewer.getControl().setEnabled(true);
                            resizeTable();
                        } else if (element instanceof PlugInDTO) { //validation parent (plugin) was selection
                            newButton.setEnabled(true);
                            deleteButton.setEnabled(false);
                            nameText.setText(((PlugInDTO) selection.getFirstElement()).getName());
                            nameText.setEditable(false);
                            descText.setText(((PlugInDTO) selection.getFirstElement()).getDescription());
                            descText.setEditable(false);
                            tableViewer.setInput(null); //hide arguments
                            tableViewer.getControl().setEnabled(false);
                        } else { // this shouldn't be called
                            newButton.setEnabled(false);
                            deleteButton.setEnabled(false);
                            nameText.setText(""); //$NON-NLS-1$
                            nameText.setEditable(false);
                            descText.setText(""); //$NON-NLS-1$
                            descText.setEditable(false);
                            tableViewer.setInput(null); //hide arguments
                            tableViewer.getControl().setEnabled(false);
                        }
                       
                    } else { //more than one selection was made
                        selectedTreeItem = null;
                        newButton.setEnabled(false);
                        deleteButton.setEnabled(false);
                        nameText.setEditable(false);
                        descText.setEditable(false);
                        tableViewer.setInput(null); //hide arguments
                        tableViewer.getControl().setEnabled(false);
                    }
                    updateButtons();
                }
            }

        });

        treeViewer.addCheckStateListener(new ICheckStateListener() {

            public void checkStateChanged( CheckStateChangedEvent event ) {
                updateButtons();
               
                if (event.getElement() instanceof PlugInDTO) {
                    if (event.getChecked()) {
                        //select the parent if is not already
                        ISelection selection;
                        if (selectedTreeItem != event.getElement()) {
                            selection = new StructuredSelection(event.getElement());
                            treeViewer.setSelection(selection);
                        }
                        //automatically create a child if none exist
                        if (!contentProvider.hasChildren(selectedTreeItem)) {
                            TestDTO newTest = addTest();
                            selection = new StructuredSelection(newTest);
                            treeViewer.setSelection(selection);
                        }
                    }
                }
            }
           
        });
       
        return comp;
    }

    /**
     * Creates the validations edit area of the dialog. This area displays the name and description
     * of the validation test currently selected. Instances of plugins may only be viewed, while
     * instances of validation tests (within the testSuite) may be modified.
     *
     * @return the composite used for launch configuration editing
     */
    protected Composite createValidationEditArea(Composite parent) {
        // create a composite to place our form objects into
        Font font = parent.getFont();
        Composite comp = new Composite(parent, SWT.NONE);
        // setSelectionArea(comp);
        GridLayout layout = new GridLayout(1, false);
        layout.marginHeight = 5;
        layout.marginWidth = 5;
        comp.setLayout(layout);
        comp.setFont(font);
       
        // create the "name" label
        Label nameLabel = new Label(comp, SWT.TOP | SWT.LEFT);
        nameLabel.setFont(font);
        nameLabel.setText(Messages.ValidationDialog_name);
        GridData gd = new GridData();
        nameLabel.setLayoutData(gd);
       
        // create the "name" text box
        nameText = new Text(comp, SWT.BORDER | SWT.SINGLE | SWT.FILL);
        gd = new GridData( SWT.FILL, SWT.TOP , true, false);
        nameText.setLayoutData(gd);
        nameText.addModifyListener(new NameModifiedListener());
       
        // create the "description" label
        Label descLabel = new Label(comp, SWT.TOP | SWT.LEFT);
        descLabel.setFont(font);
        descLabel.setText(Messages.ValidationDialog_description);
        gd = new GridData();
        nameLabel.setLayoutData(gd);
       
        // create the "description" text box
        descText = new Text(comp, SWT.BORDER | SWT.MULTI | SWT.WRAP | SWT.V_SCROLL);
        gd = new GridData(SWT.FILL, SWT.TOP, true, false);
        gd.heightHint = 60;
        descText.setLayoutData(gd);
        descText.addModifyListener(new DescModifiedListener());
       
        // create a new table object
        Table table = new Table(comp, SWT.BORDER | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.RESIZE);
       
        // create a tableViewer containing the table
        tableViewer = createTable(table);
        tableViewer.setContentProvider(new ValidationTableContentProvider());
        tableViewer.setLabelProvider(new ValidationTableLabelProvider());
        tableViewer.setInput(null);
       
        Control control = tableViewer.getControl();
        gd = new GridData(GridData.FILL_BOTH);
        gd.heightHint = 200; // initial height of treeViewer (in pixels?)
        control.setLayoutData(gd);
        control.setFont(font);
   
        tableViewer.setCellModifier(new CellModifiedListener());
   
        CellEditor[] editors = new CellEditor[2];
        editors[0] = null;
        Object[] allLayers = ApplicationGIS.getActiveMap().getMapLayers().toArray();
       
        ArrayList<String> typeRefsList = new ArrayList<String>();
        ArrayList<String> layerNamesList = new ArrayList<String>();
       
        typeRefsList.add(""); //$NON-NLS-1$
        layerNamesList.add(""); //$NON-NLS-1$
        typeRefsList.add("*"); //$NON-NLS-1$
        layerNamesList.add("*"); //$NON-NLS-1$
       
        for (int i = 0; i < allLayers.length; i++) {
            ILayer thisLayer = (ILayer) allLayers[i];
            SimpleFeatureType schema = thisLayer.getSchema();
            if( schema==null )
                continue;
           
            String dsID = schema.getName().getNamespaceURI();
            String typeName = thisLayer.getName();
           
            if(dsID == null || typeName == null)
              continue;
           
            typeRefsList.add(dsID+":"+typeName); //$NON-NLS-1$
            layerNamesList.add(typeName);
        }
       
        typeRefs = typeRefsList.toArray(new String[typeRefsList.size()]);
        layerNames = layerNamesList.toArray(new String[layerNamesList.size()]);
       
        // create the text/combo cell editor
        editors[1] = new AmbiguousCellEditor((Composite)table, table, layerNamesList, typeRefsList);
        // only the layer names will show up in the combo, but typeRef is the real value
               
        tableViewer.setCellEditors(editors);
        // note: Argument and Value below are internal tags, not labels
        tableViewer.setColumnProperties(new String[] { "Argument", "Value"})//$NON-NLS-1$//$NON-NLS-2$
       
        // create a table settings object and configure it
        tableSettings = new TableSettings(table);
        tableSettings.setColumnMin(0, 65);
       
        return comp;
    }

    protected TableViewer createTable(Table table) {
        TableViewer tableViewer = new TableViewer(table);
   
        TableLayout layout = new TableLayout();
        layout.addColumnData(new ColumnWeightData(50, 65, true));
        TableColumn nameColumn = new TableColumn(table, SWT.LEFT);
        nameColumn.setText(Messages.ValidationDialog_argument);
        nameColumn.setWidth(65);
        layout.addColumnData(new ColumnWeightData(50, 75, true));
        table.setLayout(layout);
        TableColumn valColumn = new TableColumn(table, SWT.LEFT);
        valColumn.setText(Messages.ValidationDialog_value);
        valColumn.setWidth(75);
        table.setHeaderVisible(true);
        table.setLinesVisible(true);
   
        return tableViewer;
    }
   
    /**
     * Create the progress monitor part in the receiver.
     *
     * @param composite
     * @param pmlayout
     * @return ProgressMonitorPart
     */
    protected ProgressMonitorPart createProgressMonitorPart(
            Composite composite, GridLayout pmlayout) {
        return new ProgressMonitorPart(composite, pmlayout, SWT.DEFAULT) {
            String currentTask = null;
            boolean lockedUI = false;
           
            /*
             * (non-Javadoc)
             *
             * @see org.eclipse.jface.wizard.ProgressMonitorPart#setBlocked(org.eclipse.core.runtime.IStatus)
             */
            public void setBlocked(IStatus reason) {
                super.setBlocked(reason);
                if (!lockedUI)// Do not show blocked if we are locking the UI
                    getBlockedHandler().showBlocked(getShell(), this, reason,
                            currentTask);
            }

            /*
             * (non-Javadoc)
             *
             * @see org.eclipse.jface.wizard.ProgressMonitorPart#clearBlocked()
             */
            public void clearBlocked() {
                super.clearBlocked();
                if (!lockedUI)// Do not clear if we never set it
                    getBlockedHandler().clearBlocked();
            }

            /*
             * (non-Javadoc)
             *
             * @see org.eclipse.jface.wizard.ProgressMonitorPart#beginTask(java.lang.String, int)
             */
            public void beginTask(String name, int totalWork) {
                super.beginTask(name, totalWork);
                currentTask = name;
            }

            /*
             * (non-Javadoc)
             *
             * @see org.eclipse.jface.wizard.ProgressMonitorPart#setTaskName(java.lang.String)
             */
            public void setTaskName(String name) {
                super.setTaskName(name);
                currentTask = name;
            }

            /*
             * (non-Javadoc)
             *
             * @see org.eclipse.jface.wizard.ProgressMonitorPart#subTask(java.lang.String)
             */
            public void subTask(String name) {
                super.subTask(name);
                // If we haven't got anything yet use this value for more context
                if (currentTask == null)
                    currentTask = name;
            }
        };
    }
   
    //TODO: implement runValidationTestsOptimized
   
    private GenericValidationResults[] runValidationTestsUnOptimized(IProgressMonitor monitor, Object[] element) throws Exception {
        //wander through the tree and run each enabled test in the processor individually
        //filter out the pluginDTOs, leaving only the TestDTOs
        List<TestDTO> tests = new ArrayList<TestDTO>();
        for (int i = 0; i < element.length; i++) {
            if (element[i] instanceof TestDTO) {
                tests.add((TestDTO) element[i]);
            }
        }
       
        if (monitor == null) monitor = new NullProgressMonitor();
        monitor.beginTask(Messages.ValidationDialog_validating +
                          Messages.ValidationDialog_ellipsis, (tests.size() * 11) + 2);
        //update the Lookup Maps
        processor.updateFVLookup();
        //processor.updateIVLookup();
        monitor.worked(1);

        //TODO: ensure typeRefs are copied

        //monitor.beginTask("Running Tests", tests.size());

        //FIXME: use the selected map rather than layer[0]
        ILayer[] layers = (ILayer[]) ApplicationGIS.getActiveMap().getMapLayers().toArray();

        //perform feature tests
        GenericValidationResults[] results = new GenericValidationResults[tests.size()];
       
        //open the issues list
        openIssuesList();
        monitor.worked(1);

        for (int i = 0; i < tests.size(); i++) {
            results[i] = new GenericValidationResults();
            //check for cancellation
            if (monitor.isCanceled()) {
                break;
            }
            //proceed
            String testName = tests.get(i).getName();
            //TODO: run as either feature or integrity test
            monitor.subTask(""); //$NON-NLS-1$
            monitor.setTaskName(Messages.ValidationDialog_validating + " " + testName 
                    + Messages.ValidationDialog_ellipsis);
            SubProgressMonitor subMonitor = new SubProgressMonitor(monitor, 10);
            processor.runFeatureTest(testName, layers, results[i], subMonitor);
            //processor.runIntegrityTest(test.getName(), layers, results[i], monitor);

            //check for cancellation again...
            if (subMonitor.isCanceled()) {
                monitor.setCanceled(true);
            }
            if (monitor.isCanceled()) {
                break;
            }
            //add to issues list
            monitor.subTask(MessageFormat.format(Messages.ValidationDialog_populating, testName));
            IIssuesManager.defaultInstance.getIssuesList().addAll(results[i].issues);
            monitor.worked(1);
        }
        monitor.done();
        return results;
    }

    /**
     * Based on the name of the argument, this function determines if it is a
     * typeRef or not.
     *
     * @param argName
     * @return
     */
    public static boolean isTypeRef(String argName) {
        if (argName.toLowerCase().contains("typeref")) return true; //$NON-NLS-1$
        else return false;
    }
   
    public static String getTypeRefLayer(String typeRef) {
        for (int i = 0; i < typeRefs.length; i++) {
            if (typeRefs[i].equals(typeRef)) {
                return layerNames[i];
            }
        }
        return null;
    }
   
    /**
     * Creates a validation processor. Both parameters may be null.
     *
     * @param pluginsDir
     * @param testSuiteFile
     * @return
     * @throws Exception
     */
    private ValidationProcessor createProcessor(File pluginsDir, File testSuiteFile) throws Exception {
        if (pluginsDir == null) {
            URL pluginURL = ValidationPlugin.getDefault().getBundle().getResource("plugins"); //$NON-NLS-1$
            String pluginsPath = Platform.asLocalURL(pluginURL).getFile();
//            String pluginsPath = FileLocator.toFileURL(pluginURL).getFile();
            pluginsDir = new File(pluginsPath);
        }
        return new ValidationProcessor(pluginsDir, testSuiteFile);
    }

    /**
     * Resizes the table columns to behave better.
     *
     * @param table
     */
    private void resizeTable() {
        Table table = tableViewer.getTable();
        TableUtils.resizeColumns(table, tableSettings, TableUtils.MODE_LAZY);
    }

    /**
     * Sets the given cursor for all shells currently active
     * for this window's display.
     *
     * @param c the cursor
     */
    private void setDisplayCursor(Cursor c) {
        Shell[] shells = display.getShells();
        for (int i = 0; i < shells.length; i++)
            shells[i].setCursor(c);
    }

    /** Enables/Disables the buttons as appropriate */
    private void updateButtons() {
        //check to see if any tests exist in the testSuite
        boolean testsExist;
        testsExist = processor.testsExist(defaultTestSuite);
        exportButton.setEnabled(testsExist);
        //only allow tests to be run when at least one is enabled
        boolean testsEnabled = false;
        if (testsExist) {
            Object[] elements = treeViewer.getCheckedElements();
            for (int i = 0; i < elements.length; i++) {
                if (elements[i] instanceof TestDTO) {
                    testsEnabled = true;
                    break;
                }
            }
        }
        runButton.setEnabled(testsEnabled);
        if (treeViewer.getSelection().isEmpty()) {
            newButton.setEnabled(false);
            deleteButton.setEnabled(false);
        }
        //clear the message bar (validation complete)
        setMessage(""); //$NON-NLS-1$
    }

    private void openIssuesList() throws PartInitException {
        if( Display.getCurrent()!=null)
            try{
                PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().showView(IssueConstants.VIEW_ID);
            } catch (PartInitException e) {
                ValidationPlugin.log("error opening issues view", e); //$NON-NLS-1$
            }
        else{
            display.asyncExec(new Runnable(){
                public void run() {
                    try {
                        PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().showView(IssueConstants.VIEW_ID);
                    } catch (PartInitException e) {
                        ValidationPlugin.log("error opening issues view", e); //$NON-NLS-1$
                    }
                }
            });
        }
           
    }

    private class DescModifiedListener implements ModifyListener {
        /**
         * Saves changes made to the description field
         */
        public void modifyText(ModifyEvent e) {
            //ensure this is a validation test description (plugin descriptions cannot be modified)
            if (selectedTreeItem instanceof TestDTO) {
                //save the text
                TestDTO treeItem = ((TestDTO) selectedTreeItem);
                treeItem.setDescription(descText.getText());
            }
        }
    }
   
    private class CellModifiedListener implements ICellModifier {
        public boolean canModify(Object element, String property) {
            return true;
        }

        public Object getValue(Object element, String property) {
            if (property.equals("Argument")) //$NON-NLS-1$
                return ((ArgumentDTO) element).getName();
            else {
                Object value = ((ArgumentDTO) element).getValue();
                //on read of arg value: null --> ""
                //on write of arg value:  "" --> null
                if (value == null) return ""; //$NON-NLS-1$
                else return value;
            }
        }

        public void modify(Object element, String property, Object value) {
            if (property.equals("Value")) { //$NON-NLS-1$
                //store the new value in the testSuite
                TableItem tableItem = (TableItem) element;
                ArgumentDTO arg = (ArgumentDTO) tableItem.getData();
                if (value instanceof Integer) { //comboBox
                    if (value.equals(-1)) arg.setValue(""); //$NON-NLS-1$
                    else {
                        int val = (Integer) value;
                        arg.setValue(typeRefs[val]);
                    }
                } else if (value instanceof String) { //textBox
                    //on read of arg value: null --> ""
                    //on write of arg value:  "" --> null
                    if (value.equals("")) arg.setValue(null); //$NON-NLS-1$
                    else arg.setValue(value);
                }
                tableViewer.refresh();
                //update the argument value in the validation test lookups (FV and IV)
                try {
                    processor.setArg((TestDTO) selectedTreeItem, arg);
                } catch (ValidationException e) {
                    // TODO Handle ValidationException
                    throw (RuntimeException) new RuntimeException( ).initCause( e );
                } catch (IntrospectionException e) {
                    // TODO Handle IntrospectionException
                    throw (RuntimeException) new RuntimeException( ).initCause( e );
                }
            }
        }
    }

    private class NameModifiedListener implements ModifyListener {
        /**
         * Saves changes made to the name field
         */
        public void modifyText(ModifyEvent e) {
            //ensure this is a validation test description (plugin descriptions cannot be modified)
            if (selectedTreeItem instanceof TestDTO) {
                //save the text
                TestDTO treeItem = ((TestDTO) selectedTreeItem);
                boolean renameSuccess = processor.renameValidation(treeItem.getName(), nameText.getText(), defaultTestSuite);
                if (renameSuccess) {
                    treeViewer.refresh();
                    getDialog().setErrorMessage(null);
                } else {
                    //user tried to create 2 identical test names -- complain.
                    getDialog().setErrorMessage(Messages.ValidationDialog_nonUniqueTest);
                }
            }
        }
    }

    private TestDTO addTest() {
        Object selection = selectedTreeItem;
        TestDTO thisTest = null;
        //plugin is selected?
        if (selection instanceof PlugInDTO) {
            // create a new validation test object
            PlugInDTO plugin = (PlugInDTO) selection;
            Validation newTest = null;
            try {
                newTest = processor.createValidation(plugin);
            } catch (Exception e1) {
                // log the exception and return
                MessageDialog
                        .openError(
                                PlatformUI.getWorkbench()
                                        .getActiveWorkbenchWindow()
                                        .getShell(),
                                "Exception Occurred", e1.getClass().toString() + " " + e1.getMessage())//$NON-NLS-1$//$NON-NLS-2$
                ValidationPlugin.log(e1.getMessage(), e1);
                return null;
            }
            // determine which TestSuiteDTO to use (for now, use the default)
            String testSuiteDTOKey = defaultTestSuite;
            // add the validation to the processor (creates a testDTO
            // and adds the validation to the appropriate lookup)
            processor.addValidation(newTest, plugin, testSuiteDTOKey);
            // if a defaultTypeRef exists, set any typeRefs to that value
            if ((defaultTypeRef != null) && defaultTypeRef.length() > 0) {
                thisTest = (TestDTO) processor.getTests().get(newTest.getName());
                Map args = thisTest.getArgs();
                for (Iterator i = args.keySet().iterator(); i.hasNext();) {
                    ArgumentDTO arg = (ArgumentDTO) args.get(i.next());
                    String argName = arg.getName();
                    //is it a typeRef?
                    if (isTypeRef(argName)) {
                        //is it empty?
                        if (arg.getValue() == null || arg.getValue().toString().length() == 0) {
                            arg.setValue(defaultTypeRef);
                        }
                    }
                }
            }
            //if the current item is not expanded, expand it to show the new item
            if (!treeViewer.getExpandedState(selectedTreeItem)) {
                treeViewer.setExpandedState(selectedTreeItem, true);
            }
            //if the current parent test is checked and not grayed, check off the new test
            if (treeViewer.getChecked(selectedTreeItem) && !treeViewer.getGrayed(selectedTreeItem)) {
                treeViewer.setChecked(thisTest, true);
            }
            //refresh
            treeViewer.refresh();
            updateButtons();
        }
        return thisTest;
    }
   
    private class NewTestListener implements SelectionListener {
        public void widgetSelected(SelectionEvent e) {
            addTest();
        }

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

    }

    private class DeleteTestListener implements SelectionListener {
        public void widgetSelected(SelectionEvent e) {
            Object selection = selectedTreeItem;
            //a test is selected?
            if (selection instanceof TestDTO) {
                //find the validation, given the TestDTO
                TestDTO test = (TestDTO) selection;
                //delete the validation test
                processor.removeValidation(test);
                treeViewer.refresh();
                updateButtons();
            }
        }

        public void widgetDefaultSelected(SelectionEvent e) {
            widgetSelected(e);
        }
    }
   
    private class RunTestsListener implements SelectionListener {

        GenericValidationResults[] results = new GenericValidationResults[0];
       
        public void widgetSelected( final SelectionEvent e ) {
            final Object[] element = treeViewer.getCheckedElements();

            IRunnableWithProgress process = new IRunnableWithProgress(){
                public void run( final IProgressMonitor monitor ) throws InvocationTargetException,
                        InterruptedException {
                    try {
                        results = runValidationTestsUnOptimized(monitor, element);
                    } catch (Exception e) {
                        monitor.setCanceled(true);
                        ValidationPlugin.log("Error running validation Tests", e); //$NON-NLS-1$
                    }
                }
            };
           
            Control focusControl = null;
            Cursor arrowCursor = null;
            Cursor waitCursor = null;
            try {
                focusControl = display.getFocusControl();
                progressMonitorPart.setVisible(true);
                runButton.setEnabled(false);
                cancelButton.removeSelectionListener(closeListener);
                cancelButton.addSelectionListener(cancelListener);
                waitCursor = new Cursor(display, SWT.CURSOR_WAIT);
                setDisplayCursor(waitCursor);
                // Set the arrow cursor to the cancel component.
                arrowCursor = new Cursor(display, SWT.CURSOR_ARROW);
                cancelButton.setText(IDialogConstants.CANCEL_LABEL);
                cancelButton.setCursor(arrowCursor);
                cancelButton.setFocus();
                setMessage("Validation in progress...");
                PlatformGIS.runBlockingOperation(process, progressMonitorPart);
                //progressMonitorPart.setVisible(false);
            } catch (InvocationTargetException e1) {
                // TODO Handle InvocationTargetException
                throw (RuntimeException) new RuntimeException( ).initCause( e1 );
            } catch (InterruptedException e1) {
                // TODO Handle InterruptedException
                throw (RuntimeException) new RuntimeException( ).initCause( e1 );
            } finally {
                //restore listeners
                cancelButton.removeSelectionListener(cancelListener);
                cancelButton.addSelectionListener(closeListener);
                cancelButton.setText(IDialogConstants.CLOSE_LABEL);
                //fix cursors
                setDisplayCursor(null);
                cancelButton.setCursor(null);
                waitCursor.dispose();
                waitCursor = null;
                arrowCursor.dispose();
                arrowCursor = null;
                //enable buttons
                cancelButton.setEnabled(true);
                runButton.setEnabled(true);
                //display response
                if (progressMonitorPart.isCanceled()) {
                    setMessage("Validation was canceled");
                    progressMonitorPart.setCanceled(false);
                } else {
                    int failures = 0;
                    int warnings = 0;
                    if (results != null) {
                        for( int i = 0; i < results.length; i++ ) {
                            if (results[i] != null) {
                                failures += results[i].failedFeatures.size();
                                warnings += results[i].warningFeatures.size();
                            }
                        }                       
                    }
                    setMessage("Validation complete, " + failures + " failures and " + warnings + " warnings found.");
                }
                focusControl.setFocus();
            }
        }

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

    private class ImportSuiteListener implements SelectionListener {
        public void widgetSelected(SelectionEvent e) {
            //determine the file we want to open
            String fileName = null;
            //spawn a dialog and choose which file to import
            Display display = Display.getCurrent();
            if (display == null) { // not on the ui thread?
                display = Display.getDefault();
            }
            FileDialog importDialog = new FileDialog(display.getActiveShell(), SWT.OPEN);

            //final IPath homepath = Platform.getLocation();
            //exportDialog.setFilterPath(homepath.toOSString());
            importDialog.setFilterNames (new String [] {Messages.ValidationDialog_filesXML, Messages.ValidationDialog_filesAll})
            importDialog.setFilterExtensions (new String [] {"*.xml", "*.*"}); //$NON-NLS-1$ //$NON-NLS-2$

            boolean done = false;
            while (!done) {
                fileName = importDialog.open();
                if (fileName == null) {
                    done = true;
                    return;
                } else {
                    // User has selected a file; see if it already exists
                    File file = new File(fileName);
                    if (!file.exists()) {
                        // The file does not exist; yell at the user and try again
                        MessageBox mb = new MessageBox(importDialog.getParent(), SWT.ICON_ERROR | SWT.OK);
                        mb.setMessage(fileName + Messages.ValidationDialog_fileNotExist);
                        mb.open();
                    } else {
                        // File exists, so we're good to go
                        done = true;
                    }
                }
            }

            //read the file
            FileReader reader;
            try {
                reader = new FileReader(fileName);
            } catch (FileNotFoundException e3) {
                MessageDialog.openError(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),Messages.ValidationDialog_fileNotFound, e3.toString());
                ValidationPlugin.log(e3.toString()); //log the error, but don't throw the exception
                return;
            }
            TestSuiteDTO newDTO;
            try {
                newDTO = XMLReader.readTestSuite(fileName, reader, processor.getPluginDTOs());
            } catch (ValidationException e3) {
                String errorMsg = e3.toString();
                MessageDialog.openError(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),"Exception Occurred", errorMsg); //$NON-NLS-1$
                ValidationPlugin.log(errorMsg, e3);
                return;
            }
            try {
                reader.close();
            } catch (IOException e2) {
                MessageDialog.openError(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),"Exception Occurred", e2.toString()); //$NON-NLS-1$
                ValidationPlugin.log(e2.toString(), e2);
                return;
            }
            //get the existing testSuites
            Map<String, TestSuiteDTO> suites = processor.getTestSuiteDTOs();
            //ensure there is at least one test in the new testSuite
            if (newDTO.getTests().size() == 0) {
                //nothing to see here, move along
                return;
            }
            //if no testSuites exist, just copy the new one directly in
            if (suites.size() == 0) {
                suites.put(newDTO.getName(), newDTO);                       
                defaultTestSuite = newDTO.getName();
            //does the testSuite exist? if so, add the new tests to the existing one
            } else if (suites.containsKey(newDTO.getName())) {
                //ensure the current testSuite is selected
                defaultTestSuite = newDTO.getName();
                //get the existing testSuite
                TestSuiteDTO testSuite = (TestSuiteDTO) suites.get(defaultTestSuite);
                //move the tests to the existing testSuite
                testSuite = processor.moveTests(testSuite, newDTO.getTests(), false);
                suites.put(defaultTestSuite, testSuite); //overwrite the suite
            //a test Suite exists, but it isn't this one; put the new tests into the existing testSuite
            } else {
                TestSuiteDTO testSuite = (TestSuiteDTO) suites.get(defaultTestSuite);
                Map<String, TestDTO> tests = newDTO.getTests();
                testSuite = processor.moveTests(testSuite, tests, false);
                suites.put(defaultTestSuite, testSuite); //overwrite the suite with new map of tests
            }
            //do multiple testSuites exist? if so, merge them
            while (suites.size() > 1) {
                //find the first testSuite which isn't the defaultTestSuite
                Object key = null;
                for (Iterator i = suites.keySet().iterator(); i.hasNext();) {
                    Object thisKey = i.next();
                    if (!(thisKey.equals(defaultTestSuite))) {
                        key = thisKey;
                        break;
                    }
                }
                if (key != null) {
                    TestSuiteDTO alphaSuite = (TestSuiteDTO) suites.get(defaultTestSuite);
                    TestSuiteDTO betaSuite = (TestSuiteDTO) suites.get(key);
                    alphaSuite = processor.moveTests(alphaSuite, betaSuite.getTests(), false);
                    suites.remove(key); //bye betaSuite!
                    suites.put(defaultTestSuite, alphaSuite); //overwrite the suite (alphaSuite has now assimilated betaSuite)
                }
            }
            //all done; save the Map of testSuites and refresh the Tree
            processor.setTestSuiteDTOs(suites);
            treeViewer.refresh();
            updateButtons();
        }
        public void widgetDefaultSelected(SelectionEvent e) {
            widgetSelected(e);
        }
    }
   
    private class ExportSuiteListener implements SelectionListener {
        public void widgetSelected(SelectionEvent e) {
            Display display = Display.getCurrent();
            if (display == null) { // not on the ui thread?
                display = Display.getDefault();
            }
            //grab the testSuite we want to save
            TestSuiteDTO testSuite = (TestSuiteDTO) processor.getTestSuiteDTOs().get(defaultTestSuite);
            //testSuite is empty?
            if (testSuite.getTests().size() == 0) {
                MessageBox mb = new MessageBox( display.getActiveShell(), SWT.ICON_ERROR  | SWT.OK);
                mb.setMessage(Messages.ValidationDialog_noSuitePre+defaultTestSuite+Messages.ValidationDialog_noSuiteSuf)
                mb.open();
                return;
            }
            //check the testSuite to ensure that none of the arguments of a test are null
            if (!DTOUtils.noNullArguments(testSuite)) return;
            //select the file to export to
            String fileName = null;
            //spawn a dialog and choose which file to export to
            FileDialog exportDialog = new FileDialog(display.getActiveShell(), SWT.SAVE);

            //final IPath homepath = Platform.getLocation();
            //exportDialog.setFilterPath(homepath.toOSString());
            exportDialog.setFilterNames (new String [] {Messages.ValidationDialog_filesXML, Messages.ValidationDialog_filesAll})
            exportDialog.setFilterExtensions (new String [] {"*.xml", "*.*"}); //$NON-NLS-1$ //$NON-NLS-2$

            boolean done = false;
            while (!done) {
                fileName = exportDialog.open();
                if (fileName == null) {
                  done = true;
                  return;
                } else {
                  // User has selected a file; see if it already exists
                  File file = new File(fileName);
                  if (file.exists()) {
                    // The file already exists; asks for confirmation
                    MessageBox mb = new MessageBox(exportDialog.getParent(), SWT.ICON_WARNING
                        | SWT.YES | SWT.NO);
   
                    mb.setMessage(fileName + Messages.ValidationDialog_fileExists);
   
                    // If they click Yes, we're done and we drop out. If
                    // they click No, we redisplay the File Dialog
                    done = mb.open() == SWT.YES;
                  } else {
                    // File does not exist, so we're good to go
                    done = true;
                  }
                }
            }
           
            //construct a writer
            Writer writer;
            try {
                writer = new FileWriter(fileName, false);
            } catch (IOException e1) {
                // TODO Handle IOException
                throw (RuntimeException) new RuntimeException().initCause(e1);
            }
            //write the file
            XMLWriter.writeTestSuite(testSuite, writer);
        }
   
        public void widgetDefaultSelected(SelectionEvent e) {
            widgetSelected(e);
        }
    }

    /**
     * Retrieves the ValidationProcessor object from the blackboard, or null if one does not exist.
     *
     * @param map
     * @return
     */
    private ValidationProcessor loadDialogState(IMap map) {
        Object currentState = map.getBlackboard().get(BLACKBOARD_KEY);
        if (currentState instanceof ValidationProcessor)
            return (ValidationProcessor) currentState;
        else
            return null;
    }
   
    /**
     * Saves the ValidationProcessor object on the blackboard, so we can restore
     * the state of the validation dialog the next time the dialog is opened.
     *
     * @param validationProcessor
     * @param map
     */
    private void saveDialogState(ValidationProcessor validationProcessor, IMap map) {
        map.getBlackboard().put(BLACKBOARD_KEY, validationProcessor);
    }
}
TOP

Related Classes of org.locationtech.udig.validation.ui.ValidationDialog

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.