0001: package net.refractions.udig.validation.ui;
0002:
0003: import java.beans.IntrospectionException;
0004: import java.io.File;
0005: import java.io.FileNotFoundException;
0006: import java.io.FileReader;
0007: import java.io.FileWriter;
0008: import java.io.IOException;
0009: import java.io.Writer;
0010: import java.lang.reflect.InvocationTargetException;
0011: import java.net.URL;
0012: import java.text.MessageFormat;
0013: import java.util.ArrayList;
0014: import java.util.Iterator;
0015: import java.util.List;
0016: import java.util.Map;
0017:
0018: import net.refractions.udig.issues.IIssuesManager;
0019: import net.refractions.udig.issues.IssueConstants;
0020: import net.refractions.udig.project.ILayer;
0021: import net.refractions.udig.project.IMap;
0022: import net.refractions.udig.project.ui.ApplicationGIS;
0023: import net.refractions.udig.ui.PlatformGIS;
0024: import net.refractions.udig.ui.graphics.TableSettings;
0025: import net.refractions.udig.ui.graphics.TableUtils;
0026: import net.refractions.udig.validation.DTOUtils;
0027: import net.refractions.udig.validation.GenericValidationResults;
0028: import net.refractions.udig.validation.ImageConstants;
0029: import net.refractions.udig.validation.Images;
0030: import net.refractions.udig.validation.ValidationPlugin;
0031: import net.refractions.udig.validation.ValidationProcessor;
0032: import net.refractions.udig.validation.internal.Messages;
0033:
0034: import org.eclipse.core.runtime.IProgressMonitor;
0035: import org.eclipse.core.runtime.IStatus;
0036: import org.eclipse.core.runtime.NullProgressMonitor;
0037: import org.eclipse.core.runtime.Platform;
0038: import org.eclipse.core.runtime.SubProgressMonitor;
0039: import org.eclipse.jface.dialogs.IDialogConstants;
0040: import org.eclipse.jface.dialogs.MessageDialog;
0041: import org.eclipse.jface.dialogs.TitleAreaDialog;
0042: import org.eclipse.jface.operation.IRunnableWithProgress;
0043: import org.eclipse.jface.resource.ImageDescriptor;
0044: import org.eclipse.jface.viewers.CellEditor;
0045: import org.eclipse.jface.viewers.CheckStateChangedEvent;
0046: import org.eclipse.jface.viewers.CheckboxTreeViewer;
0047: import org.eclipse.jface.viewers.ColumnWeightData;
0048: import org.eclipse.jface.viewers.ICellModifier;
0049: import org.eclipse.jface.viewers.ICheckStateListener;
0050: import org.eclipse.jface.viewers.ISelection;
0051: import org.eclipse.jface.viewers.ISelectionChangedListener;
0052: import org.eclipse.jface.viewers.SelectionChangedEvent;
0053: import org.eclipse.jface.viewers.StructuredSelection;
0054: import org.eclipse.jface.viewers.TableLayout;
0055: import org.eclipse.jface.viewers.TableViewer;
0056: import org.eclipse.jface.wizard.ProgressMonitorPart;
0057: import org.eclipse.swt.SWT;
0058: import org.eclipse.swt.custom.SashForm;
0059: import org.eclipse.swt.events.DisposeEvent;
0060: import org.eclipse.swt.events.DisposeListener;
0061: import org.eclipse.swt.events.ModifyEvent;
0062: import org.eclipse.swt.events.ModifyListener;
0063: import org.eclipse.swt.events.SelectionAdapter;
0064: import org.eclipse.swt.events.SelectionEvent;
0065: import org.eclipse.swt.events.SelectionListener;
0066: import org.eclipse.swt.graphics.Cursor;
0067: import org.eclipse.swt.graphics.Font;
0068: import org.eclipse.swt.layout.GridData;
0069: import org.eclipse.swt.layout.GridLayout;
0070: import org.eclipse.swt.widgets.Button;
0071: import org.eclipse.swt.widgets.Composite;
0072: import org.eclipse.swt.widgets.Control;
0073: import org.eclipse.swt.widgets.Display;
0074: import org.eclipse.swt.widgets.Event;
0075: import org.eclipse.swt.widgets.FileDialog;
0076: import org.eclipse.swt.widgets.Label;
0077: import org.eclipse.swt.widgets.Listener;
0078: import org.eclipse.swt.widgets.MessageBox;
0079: import org.eclipse.swt.widgets.Shell;
0080: import org.eclipse.swt.widgets.Table;
0081: import org.eclipse.swt.widgets.TableColumn;
0082: import org.eclipse.swt.widgets.TableItem;
0083: import org.eclipse.swt.widgets.Text;
0084: import org.eclipse.ui.PartInitException;
0085: import org.eclipse.ui.PlatformUI;
0086: import org.eclipse.ui.model.WorkbenchViewerSorter;
0087: import org.geotools.feature.FeatureType;
0088: import org.geotools.validation.Validation;
0089: import org.geotools.validation.dto.ArgumentDTO;
0090: import org.geotools.validation.dto.PlugInDTO;
0091: import org.geotools.validation.dto.TestDTO;
0092: import org.geotools.validation.dto.TestSuiteDTO;
0093: import org.geotools.validation.xml.ValidationException;
0094: import org.geotools.validation.xml.XMLReader;
0095: import org.geotools.validation.xml.XMLWriter;
0096:
0097: public class ValidationDialog extends TitleAreaDialog {
0098:
0099: /**
0100: * Constant to use as the key for storing the validation processor on the
0101: * blackboard (for saving the state of the validation dialog box)
0102: */
0103: public static final String BLACKBOARD_KEY = "net.refractions.udig.validation"; //$NON-NLS-1$
0104:
0105: private Button newButton;
0106: private Button deleteButton;
0107: private Button exportButton;
0108: private Button importButton;
0109: private Button runButton;
0110: private Button cancelButton;
0111: private Composite buttonComposite;
0112: private SelectionListener closeListener;
0113: private SelectionListener cancelListener;
0114: private Text nameText;
0115: private Text descText;
0116: private TableViewer tableViewer;
0117: private TableSettings tableSettings;
0118: private CheckboxTreeViewer treeViewer;
0119: private ValidationTreeContentProvider contentProvider = null;
0120:
0121: private ProgressMonitorPart progressMonitorPart;
0122: private Object selectedTreeItem;
0123: private ValidationProcessor processor;
0124:
0125: /** The key (name) of the testSuite in use (usually there will only be a
0126: * single testSuite, and this is its name). */
0127: private String defaultTestSuite;
0128:
0129: /** If a layer was selected to get to this dialog, it is the default testSuite.
0130: * Otherwise the value is "" or even "*". */
0131: private String defaultTypeRef = ""; //$NON-NLS-1$
0132: private Display display;
0133:
0134: private static String[] typeRefs;
0135: private static String[] layerNames;
0136:
0137: //private ILayer[] layers;
0138:
0139: public ValidationDialog(Shell parentShell, ILayer[] layers) {
0140: this (parentShell);
0141: // determine the defaultTypeRef (from the first selected layer)
0142: String dsID = layers[0].getSchema().getNamespace().toString();
0143: String typeName = layers[0].getName();
0144: defaultTypeRef = dsID + ":" + typeName; //$NON-NLS-1$
0145: //this.layers = layers;
0146: display = parentShell.getDisplay();
0147:
0148: cancelListener = new SelectionListener() {
0149:
0150: public void widgetSelected(SelectionEvent e) {
0151: // a test is running and the user just hit cancel
0152: // cancel the progress monitor
0153: progressMonitorPart.setCanceled(true);
0154: cancelButton.setEnabled(false);
0155: }
0156:
0157: public void widgetDefaultSelected(SelectionEvent e) {
0158: widgetSelected(e);
0159: }
0160:
0161: };
0162: }
0163:
0164: protected ValidationDialog(Shell parentShell) {
0165: super (parentShell);
0166: setShellStyle(SWT.DIALOG_TRIM | SWT.RESIZE
0167: | SWT.APPLICATION_MODAL | getDefaultOrientation());
0168: setBlockOnOpen(true);
0169: }
0170:
0171: public ValidationDialog getDialog() {
0172: return this ;
0173: }
0174:
0175: public Button getCancelButton() {
0176: return cancelButton;
0177: }
0178:
0179: @Override
0180: protected Control createButtonBar(Composite parent) {
0181: Composite composite = new Composite(parent, SWT.FILL);
0182: GridLayout layout = new GridLayout();
0183: layout.numColumns = 2;
0184: layout.makeColumnsEqualWidth = true;
0185: layout.marginWidth = 0; // no spacing here, it's purely a container
0186: layout.marginHeight = 0;
0187: layout.horizontalSpacing = 0;
0188: layout.verticalSpacing = 0;
0189: composite.setLayout(layout);
0190: GridData data = new GridData(SWT.FILL, SWT.CENTER, true, false);
0191: composite.setLayoutData(data);
0192: composite.setFont(parent.getFont());
0193:
0194: // create 2 composites in the composite with left and right aligns
0195: Composite leftComp = new Composite(composite, SWT.LEFT);
0196: layout = new GridLayout();
0197: layout.numColumns = 2;
0198: layout.makeColumnsEqualWidth = true;
0199: layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
0200: layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
0201: layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
0202: layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
0203: leftComp.setLayout(layout);
0204: data = new GridData(SWT.LEFT, SWT.NONE, true, false);
0205: leftComp.setLayoutData(data);
0206: leftComp.setFont(parent.getFont());
0207:
0208: Composite rightComp = new Composite(composite, SWT.RIGHT);
0209: layout = new GridLayout();
0210: layout.numColumns = 2;
0211: layout.makeColumnsEqualWidth = true;
0212: layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
0213: layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
0214: layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
0215: layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
0216: rightComp.setLayout(layout);
0217: data = new GridData(SWT.RIGHT, SWT.NONE, true, false);
0218: rightComp.setLayoutData(data);
0219: rightComp.setFont(parent.getFont());
0220:
0221: // Add the buttons
0222: importButton = new Button(leftComp, SWT.PUSH);
0223: importButton.setFont(parent.getFont());
0224: importButton.setText(Messages.ValidationDialog_import);
0225: importButton.setEnabled(true);
0226: importButton.addSelectionListener(new ImportSuiteListener());
0227: setButtonLayoutData(importButton);
0228:
0229: exportButton = new Button(leftComp, SWT.PUSH);
0230: exportButton.setFont(parent.getFont());
0231: exportButton.setText(Messages.ValidationDialog_export);
0232: exportButton.setEnabled(false);
0233: exportButton.addSelectionListener(new ExportSuiteListener());
0234: setButtonLayoutData(exportButton);
0235:
0236: runButton = new Button(rightComp, SWT.PUSH);
0237: runButton.setFont(parent.getFont());
0238: runButton.setText(Messages.ValidationDialog_run);
0239: runButton.setEnabled(false);
0240: runButton.addSelectionListener(new RunTestsListener());
0241: setButtonLayoutData(runButton);
0242:
0243: cancelButton = new Button(rightComp, SWT.PUSH);
0244: cancelButton.setText(IDialogConstants.CLOSE_LABEL);
0245: cancelButton.setFont(parent.getFont());
0246: cancelButton.setData(new Integer(IDialogConstants.CANCEL_ID));
0247: closeListener = new SelectionAdapter() {
0248: public void widgetSelected(SelectionEvent event) {
0249: // nothing is happening and the user hit cancel (close)
0250: buttonPressed(((Integer) event.widget.getData())
0251: .intValue());
0252: }
0253: };
0254: // cancelListener = new SelectionListener() {
0255: //
0256: // public void widgetSelected( SelectionEvent e ) {
0257: // // a test is running and the user just hit cancel
0258: // // cancel the progress monitor
0259: // progressMonitorPart.setCanceled(true);
0260: // cancelButton.setEnabled(false);
0261: // }
0262: //
0263: // public void widgetDefaultSelected( SelectionEvent e ) {
0264: // widgetSelected(e);
0265: // }
0266: //
0267: // };
0268: cancelButton.addSelectionListener(closeListener);
0269: setButtonLayoutData(cancelButton);
0270:
0271: return composite;
0272: }
0273:
0274: @Override
0275: protected void createButtonsForButtonBar(Composite parent) {
0276: }
0277:
0278: @Override
0279: protected Control createDialogArea(Composite parent) {
0280: Composite composite = new Composite(parent, SWT.NONE);
0281: setTitle(Messages.ValidationDialog_title);
0282: setMessage(""); //$NON-NLS-1$
0283: ImageDescriptor image = Images
0284: .getDescriptor(ImageConstants.IMAGE_WIZBAN);
0285: if (image != null)
0286: setTitleImage(image.createImage());
0287:
0288: GridData gd;
0289: gd = new GridData(SWT.FILL, SWT.FILL, true, true);
0290: composite.setLayoutData(gd);
0291: GridLayout topLayout = new GridLayout(1, false);
0292: topLayout.marginHeight = 0;
0293: topLayout.marginWidth = 0;
0294: composite.setLayout(topLayout);
0295:
0296: // Create the SashForm that contains the selection area on the left,
0297: // and the edit area on the right
0298: SashForm sashForm = new SashForm(composite, SWT.FILL);
0299: sashForm.setOrientation(SWT.HORIZONTAL);
0300: gd = new GridData(SWT.FILL, SWT.FILL, true, true);
0301: sashForm.setLayoutData(gd);
0302: sashForm.setFont(parent.getFont());
0303:
0304: // Build the validation selection area and put it into the composite.
0305: Composite validationSelectionArea;
0306: try {
0307: validationSelectionArea = createValidationSelectionArea(sashForm);
0308: } catch (Exception e) {
0309: // TODO Handle Exception
0310: throw (RuntimeException) new RuntimeException()
0311: .initCause(e);
0312: }
0313: gd = new GridData(SWT.FILL, SWT.FILL, true, true);
0314: validationSelectionArea.setLayoutData(gd);
0315:
0316: // Build the validation edit area and put it into the composite.
0317: Composite editAreaComp = createValidationEditArea(sashForm);
0318: gd = new GridData(SWT.FILL, SWT.FILL, true, true);
0319: editAreaComp.setLayoutData(gd);
0320:
0321: // add the progress bar
0322: GridLayout pmlayout = new GridLayout();
0323: pmlayout.numColumns = 1;
0324: progressMonitorPart = createProgressMonitorPart(composite,
0325: pmlayout);
0326: progressMonitorPart.setLayoutData(new GridData(
0327: GridData.FILL_HORIZONTAL));
0328: progressMonitorPart.setVisible(false);
0329:
0330: // Build the separator line that demarcates the button bar
0331: Label separator = new Label(composite, SWT.HORIZONTAL
0332: | SWT.SEPARATOR);
0333: gd = new GridData(SWT.FILL, SWT.NONE, true, false);
0334: // gd.horizontalSpan = 2;
0335: separator.setLayoutData(gd);
0336:
0337: parent.layout(true);
0338: applyDialogFont(parent);
0339:
0340: // create a resize listener
0341: composite.addListener(SWT.Resize, new Listener() {
0342:
0343: public void handleEvent(Event event) {
0344: resizeTable();
0345: // FIXME: possibly move this listener to the table.resize event
0346: }
0347:
0348: });
0349:
0350: composite.addDisposeListener(new DisposeListener() {
0351:
0352: public void widgetDisposed(DisposeEvent e) {
0353: // find the Map
0354: IMap map = ApplicationGIS.getActiveMap();
0355: saveDialogState(processor, map);
0356: }
0357:
0358: });
0359:
0360: return composite;
0361: }
0362:
0363: /**
0364: * Creates the validation test suite selection area of the dialog. This area displays a tree of
0365: * validations that the user may select and modify. The first tier of the tree contains the
0366: * available validation plugins, and the second tier contains instances of the test.
0367: *
0368: * @return the composite used for the validations selection area
0369: * @throws Exception
0370: */
0371: protected Composite createValidationSelectionArea(Composite parent)
0372: throws Exception {
0373: Font font = parent.getFont();
0374: Composite comp = new Composite(parent, SWT.NONE);
0375: GridLayout layout = new GridLayout(1, false);
0376: layout.marginHeight = 5;
0377: layout.marginWidth = 5;
0378: comp.setLayout(layout);
0379: comp.setFont(font);
0380:
0381: Label treeLabel = new Label(comp, SWT.NONE);
0382: treeLabel.setFont(font);
0383: treeLabel.setText(Messages.ValidationDialog_validations);
0384: GridData labelData = new GridData();
0385: treeLabel.setLayoutData(labelData);
0386:
0387: ValidationProcessor tempProcessor = loadDialogState(ApplicationGIS
0388: .getActiveMap());
0389: if (tempProcessor == null) {
0390: processor = createProcessor(null, null);
0391: defaultTestSuite = "testSuite1"; //$NON-NLS-1$
0392: } else {
0393: processor = tempProcessor;
0394: if (processor.getTestSuiteDTOs().size() == 1) {
0395: // a single testSuite exists, grab its name
0396: defaultTestSuite = (String) processor
0397: .getTestSuiteDTOs().keySet().toArray()[0];
0398: } else if (processor.getTestSuiteDTOs().size() == 0) {
0399: // there is no... testSuite, create one
0400: processor = createProcessor(null, null);
0401: defaultTestSuite = "testSuite1"; //$NON-NLS-1$
0402: } else {
0403: // there are multiple testSuites, choose the largest one
0404: String this TestSuite = ""; //$NON-NLS-1$
0405: int mostTests = -1;
0406: for (Iterator i = processor.getTestSuiteDTOs().keySet()
0407: .iterator(); i.hasNext();) {
0408: Object this Key = i.next();
0409: int numTests = ((TestSuiteDTO) processor
0410: .getTestSuiteDTOs().get(this Key))
0411: .getTests().size();
0412: if (numTests > mostTests) {
0413: mostTests = numTests;
0414: this TestSuite = (String) this Key;
0415: }
0416: }
0417: defaultTestSuite = this TestSuite;
0418: }
0419: }
0420:
0421: // create the treeViewer (list of possible validations (plugins) + prepared tests)
0422: treeViewer = new CheckboxTreeViewer(comp);
0423: treeViewer.setLabelProvider(new ValidationTreeLabelProvider());
0424: treeViewer.setSorter(new WorkbenchViewerSorter());
0425: contentProvider = new ValidationTreeContentProvider();
0426: treeViewer.setContentProvider(contentProvider);
0427: treeViewer.addCheckStateListener(new ICheckStateListener() {
0428: public void checkStateChanged(CheckStateChangedEvent event) {
0429: Object element = event.getElement();
0430: Object[] children = contentProvider
0431: .getChildren(element);
0432: if (children != null && children.length > 0) {
0433: // parent element was modified, adjust the children accordingly
0434: for (int i = 0; i < children.length; i++) {
0435: treeViewer.setChecked(children[i], event
0436: .getChecked());
0437: }
0438: // all children are in the same state, therefore the parent is not grayed
0439: treeViewer.setGrayed(element, false);
0440: }
0441:
0442: Object parent = contentProvider.getParent(element);
0443: if (parent != null) {
0444: // child element was modified
0445: Object[] siblings = contentProvider
0446: .getChildren(parent);
0447: boolean oneSiblingChecked = false;
0448: boolean allSiblingsChecked = true;
0449: for (int i = 0; i < siblings.length; i++) {
0450: if (treeViewer.getChecked(siblings[i])) {
0451: oneSiblingChecked = true;
0452: } else {
0453: allSiblingsChecked = false;
0454: }
0455: }
0456: if (allSiblingsChecked) { // mark parent checked and NOT grayed out
0457: treeViewer.setGrayed(parent, false);
0458: treeViewer.setChecked(parent, true);
0459: } else {
0460: if (oneSiblingChecked) { // mark parent checked and grayed out
0461: treeViewer.setGrayChecked(parent, true);
0462: } else { // mark parent NOT checked
0463: treeViewer.setGrayChecked(parent, false);
0464: }
0465: }
0466: }
0467: }
0468: });
0469:
0470: // populate the tree
0471: treeViewer.setInput(processor);
0472: treeViewer.expandAll();
0473:
0474: Control control = treeViewer.getControl();
0475: GridData gd = new GridData(GridData.FILL_BOTH);
0476: gd.heightHint = 250; // initial height of treeViewer (in pixels?)
0477: gd.verticalSpan = 3;
0478: control.setLayoutData(gd);
0479: control.setFont(font);
0480:
0481: // composite to hold the new/delete/save/... buttons
0482: buttonComposite = new Composite(comp, SWT.NONE);
0483: gd = new GridData(GridData.FILL_HORIZONTAL);
0484: gd.widthHint = 200;
0485: buttonComposite.setLayoutData(gd);
0486: buttonComposite.setFont(comp.getFont());
0487:
0488: GridLayout buttonLayout = new GridLayout(2, false);
0489: buttonComposite.setLayout(buttonLayout);
0490:
0491: // construct the new validation test button
0492: newButton = new Button(buttonComposite, SWT.PUSH);
0493: newButton.setFont(parent.getFont());
0494: newButton.setText(Messages.ValidationDialog_new);
0495: newButton.setEnabled(false);
0496: newButton.addSelectionListener(new NewTestListener());
0497: setButtonLayoutData(newButton);
0498:
0499: // construct the delete validation test button
0500: deleteButton = new Button(buttonComposite, SWT.PUSH);
0501: deleteButton.setFont(parent.getFont());
0502: deleteButton.setText(Messages.ValidationDialog_delete);
0503: deleteButton.setEnabled(false);
0504: deleteButton.addSelectionListener(new DeleteTestListener());
0505: setButtonLayoutData(deleteButton);
0506:
0507: // construct treeViewer listener
0508: treeViewer
0509: .addSelectionChangedListener(new ISelectionChangedListener() {
0510:
0511: public void selectionChanged(
0512: SelectionChangedEvent event) {
0513: if (!event.getSelection().isEmpty()) {
0514: StructuredSelection selection = (StructuredSelection) event
0515: .getSelection();
0516: if (selection.size() == 1) {
0517: Object element = selection
0518: .getFirstElement();
0519: selectedTreeItem = element; //record the current selection so other events can figure out who is selected
0520: if (element instanceof TestDTO) { //test instance was selected
0521: newButton.setEnabled(false);
0522: deleteButton.setEnabled(true);
0523: nameText
0524: .setText(((TestDTO) element)
0525: .getName());
0526: nameText.setEditable(true);
0527: descText
0528: .setText(((TestDTO) element)
0529: .getDescription());
0530: descText.setEditable(true);
0531: tableViewer.setInput(element); // pass the args (inside the testDTO)
0532: tableViewer.getControl()
0533: .setEnabled(true);
0534: resizeTable();
0535: } else if (element instanceof PlugInDTO) { //validation parent (plugin) was selection
0536: newButton.setEnabled(true);
0537: deleteButton.setEnabled(false);
0538: nameText
0539: .setText(((PlugInDTO) selection
0540: .getFirstElement())
0541: .getName());
0542: nameText.setEditable(false);
0543: descText
0544: .setText(((PlugInDTO) selection
0545: .getFirstElement())
0546: .getDescription());
0547: descText.setEditable(false);
0548: tableViewer.setInput(null); //hide arguments
0549: tableViewer.getControl()
0550: .setEnabled(false);
0551: } else { // this shouldn't be called
0552: newButton.setEnabled(false);
0553: deleteButton.setEnabled(false);
0554: nameText.setText(""); //$NON-NLS-1$
0555: nameText.setEditable(false);
0556: descText.setText(""); //$NON-NLS-1$
0557: descText.setEditable(false);
0558: tableViewer.setInput(null); //hide arguments
0559: tableViewer.getControl()
0560: .setEnabled(false);
0561: }
0562:
0563: } else { //more than one selection was made
0564: selectedTreeItem = null;
0565: newButton.setEnabled(false);
0566: deleteButton.setEnabled(false);
0567: nameText.setEditable(false);
0568: descText.setEditable(false);
0569: tableViewer.setInput(null); //hide arguments
0570: tableViewer.getControl().setEnabled(
0571: false);
0572: }
0573: updateButtons();
0574: }
0575: }
0576:
0577: });
0578:
0579: treeViewer.addCheckStateListener(new ICheckStateListener() {
0580:
0581: public void checkStateChanged(CheckStateChangedEvent event) {
0582: updateButtons();
0583:
0584: if (event.getElement() instanceof PlugInDTO) {
0585: if (event.getChecked()) {
0586: //select the parent if is not already
0587: ISelection selection;
0588: if (selectedTreeItem != event.getElement()) {
0589: selection = new StructuredSelection(event
0590: .getElement());
0591: treeViewer.setSelection(selection);
0592: }
0593: //automatically create a child if none exist
0594: if (!contentProvider
0595: .hasChildren(selectedTreeItem)) {
0596: TestDTO newTest = addTest();
0597: selection = new StructuredSelection(newTest);
0598: treeViewer.setSelection(selection);
0599: }
0600: }
0601: }
0602: }
0603:
0604: });
0605:
0606: return comp;
0607: }
0608:
0609: /**
0610: * Creates the validations edit area of the dialog. This area displays the name and description
0611: * of the validation test currently selected. Instances of plugins may only be viewed, while
0612: * instances of validation tests (within the testSuite) may be modified.
0613: *
0614: * @return the composite used for launch configuration editing
0615: */
0616: protected Composite createValidationEditArea(Composite parent) {
0617: // create a composite to place our form objects into
0618: Font font = parent.getFont();
0619: Composite comp = new Composite(parent, SWT.NONE);
0620: // setSelectionArea(comp);
0621: GridLayout layout = new GridLayout(1, false);
0622: layout.marginHeight = 5;
0623: layout.marginWidth = 5;
0624: comp.setLayout(layout);
0625: comp.setFont(font);
0626:
0627: // create the "name" label
0628: Label nameLabel = new Label(comp, SWT.TOP | SWT.LEFT);
0629: nameLabel.setFont(font);
0630: nameLabel.setText(Messages.ValidationDialog_name);
0631: GridData gd = new GridData();
0632: nameLabel.setLayoutData(gd);
0633:
0634: // create the "name" text box
0635: nameText = new Text(comp, SWT.BORDER | SWT.SINGLE | SWT.FILL);
0636: gd = new GridData(SWT.FILL, SWT.TOP, true, false);
0637: nameText.setLayoutData(gd);
0638: nameText.addModifyListener(new NameModifiedListener());
0639:
0640: // create the "description" label
0641: Label descLabel = new Label(comp, SWT.TOP | SWT.LEFT);
0642: descLabel.setFont(font);
0643: descLabel.setText(Messages.ValidationDialog_description);
0644: gd = new GridData();
0645: nameLabel.setLayoutData(gd);
0646:
0647: // create the "description" text box
0648: descText = new Text(comp, SWT.BORDER | SWT.MULTI | SWT.WRAP
0649: | SWT.V_SCROLL);
0650: gd = new GridData(SWT.FILL, SWT.TOP, true, false);
0651: gd.heightHint = 60;
0652: descText.setLayoutData(gd);
0653: descText.addModifyListener(new DescModifiedListener());
0654:
0655: // create a new table object
0656: Table table = new Table(comp, SWT.BORDER | SWT.V_SCROLL
0657: | SWT.FULL_SELECTION | SWT.RESIZE);
0658:
0659: // create a tableViewer containing the table
0660: tableViewer = createTable(table);
0661: tableViewer
0662: .setContentProvider(new ValidationTableContentProvider());
0663: tableViewer
0664: .setLabelProvider(new ValidationTableLabelProvider());
0665: tableViewer.setInput(null);
0666:
0667: Control control = tableViewer.getControl();
0668: gd = new GridData(GridData.FILL_BOTH);
0669: gd.heightHint = 200; // initial height of treeViewer (in pixels?)
0670: control.setLayoutData(gd);
0671: control.setFont(font);
0672:
0673: tableViewer.setCellModifier(new CellModifiedListener());
0674:
0675: CellEditor[] editors = new CellEditor[2];
0676: editors[0] = null;
0677: Object[] allLayers = ApplicationGIS.getActiveMap()
0678: .getMapLayers().toArray();
0679:
0680: ArrayList<String> typeRefsList = new ArrayList<String>();
0681: ArrayList<String> layerNamesList = new ArrayList<String>();
0682:
0683: typeRefsList.add(""); //$NON-NLS-1$
0684: layerNamesList.add(""); //$NON-NLS-1$
0685: typeRefsList.add("*"); //$NON-NLS-1$
0686: layerNamesList.add("*"); //$NON-NLS-1$
0687:
0688: for (int i = 0; i < allLayers.length; i++) {
0689: ILayer this Layer = (ILayer) allLayers[i];
0690: FeatureType schema = this Layer.getSchema();
0691: if (schema == null)
0692: continue;
0693:
0694: String dsID = schema.getNamespace().toString();
0695: String typeName = this Layer.getName();
0696:
0697: if (dsID == null || typeName == null)
0698: continue;
0699:
0700: typeRefsList.add(dsID + ":" + typeName); //$NON-NLS-1$
0701: layerNamesList.add(typeName);
0702: }
0703:
0704: typeRefs = typeRefsList
0705: .toArray(new String[typeRefsList.size()]);
0706: layerNames = layerNamesList.toArray(new String[layerNamesList
0707: .size()]);
0708:
0709: // create the text/combo cell editor
0710: editors[1] = new AmbiguousCellEditor((Composite) table, table,
0711: layerNamesList, typeRefsList);
0712: // only the layer names will show up in the combo, but typeRef is the real value
0713:
0714: tableViewer.setCellEditors(editors);
0715: // note: Argument and Value below are internal tags, not labels
0716: tableViewer.setColumnProperties(new String[] {
0717: "Argument", "Value" }); //$NON-NLS-1$//$NON-NLS-2$
0718:
0719: // create a table settings object and configure it
0720: tableSettings = new TableSettings(table);
0721: tableSettings.setColumnMin(0, 65);
0722:
0723: return comp;
0724: }
0725:
0726: protected TableViewer createTable(Table table) {
0727: TableViewer tableViewer = new TableViewer(table);
0728:
0729: TableLayout layout = new TableLayout();
0730: layout.addColumnData(new ColumnWeightData(50, 65, true));
0731: TableColumn nameColumn = new TableColumn(table, SWT.LEFT);
0732: nameColumn.setText(Messages.ValidationDialog_argument);
0733: nameColumn.setWidth(65);
0734: layout.addColumnData(new ColumnWeightData(50, 75, true));
0735: table.setLayout(layout);
0736: TableColumn valColumn = new TableColumn(table, SWT.LEFT);
0737: valColumn.setText(Messages.ValidationDialog_value);
0738: valColumn.setWidth(75);
0739: table.setHeaderVisible(true);
0740: table.setLinesVisible(true);
0741:
0742: return tableViewer;
0743: }
0744:
0745: /**
0746: * Create the progress monitor part in the receiver.
0747: *
0748: * @param composite
0749: * @param pmlayout
0750: * @return ProgressMonitorPart
0751: */
0752: protected ProgressMonitorPart createProgressMonitorPart(
0753: Composite composite, GridLayout pmlayout) {
0754: return new ProgressMonitorPart(composite, pmlayout, SWT.DEFAULT) {
0755: String currentTask = null;
0756: boolean lockedUI = false;
0757:
0758: /*
0759: * (non-Javadoc)
0760: *
0761: * @see org.eclipse.jface.wizard.ProgressMonitorPart#setBlocked(org.eclipse.core.runtime.IStatus)
0762: */
0763: public void setBlocked(IStatus reason) {
0764: super .setBlocked(reason);
0765: if (!lockedUI)// Do not show blocked if we are locking the UI
0766: getBlockedHandler().showBlocked(getShell(), this ,
0767: reason, currentTask);
0768: }
0769:
0770: /*
0771: * (non-Javadoc)
0772: *
0773: * @see org.eclipse.jface.wizard.ProgressMonitorPart#clearBlocked()
0774: */
0775: public void clearBlocked() {
0776: super .clearBlocked();
0777: if (!lockedUI)// Do not clear if we never set it
0778: getBlockedHandler().clearBlocked();
0779: }
0780:
0781: /*
0782: * (non-Javadoc)
0783: *
0784: * @see org.eclipse.jface.wizard.ProgressMonitorPart#beginTask(java.lang.String, int)
0785: */
0786: public void beginTask(String name, int totalWork) {
0787: super .beginTask(name, totalWork);
0788: currentTask = name;
0789: }
0790:
0791: /*
0792: * (non-Javadoc)
0793: *
0794: * @see org.eclipse.jface.wizard.ProgressMonitorPart#setTaskName(java.lang.String)
0795: */
0796: public void setTaskName(String name) {
0797: super .setTaskName(name);
0798: currentTask = name;
0799: }
0800:
0801: /*
0802: * (non-Javadoc)
0803: *
0804: * @see org.eclipse.jface.wizard.ProgressMonitorPart#subTask(java.lang.String)
0805: */
0806: public void subTask(String name) {
0807: super .subTask(name);
0808: // If we haven't got anything yet use this value for more context
0809: if (currentTask == null)
0810: currentTask = name;
0811: }
0812: };
0813: }
0814:
0815: //TODO: implement runValidationTestsOptimized
0816:
0817: private GenericValidationResults[] runValidationTestsUnOptimized(
0818: IProgressMonitor monitor, Object[] element)
0819: throws Exception {
0820: //wander through the tree and run each enabled test in the processor individually
0821: //filter out the pluginDTOs, leaving only the TestDTOs
0822: List<TestDTO> tests = new ArrayList<TestDTO>();
0823: for (int i = 0; i < element.length; i++) {
0824: if (element[i] instanceof TestDTO) {
0825: tests.add((TestDTO) element[i]);
0826: }
0827: }
0828:
0829: if (monitor == null)
0830: monitor = new NullProgressMonitor();
0831: monitor.beginTask(Messages.ValidationDialog_validating
0832: + Messages.ValidationDialog_ellipsis,
0833: (tests.size() * 11) + 2);
0834: //update the Lookup Maps
0835: processor.updateFVLookup();
0836: //processor.updateIVLookup();
0837: monitor.worked(1);
0838:
0839: //TODO: ensure typeRefs are copied
0840:
0841: //monitor.beginTask("Running Tests", tests.size());
0842:
0843: //FIXME: use the selected map rather than layer[0]
0844: ILayer[] layers = (ILayer[]) ApplicationGIS.getActiveMap()
0845: .getMapLayers().toArray();
0846:
0847: //perform feature tests
0848: GenericValidationResults[] results = new GenericValidationResults[tests
0849: .size()];
0850:
0851: //open the issues list
0852: openIssuesList();
0853: monitor.worked(1);
0854:
0855: for (int i = 0; i < tests.size(); i++) {
0856: results[i] = new GenericValidationResults();
0857: //check for cancellation
0858: if (monitor.isCanceled()) {
0859: break;
0860: }
0861: //proceed
0862: String testName = tests.get(i).getName();
0863: //TODO: run as either feature or integrity test
0864: monitor.subTask(""); //$NON-NLS-1$
0865: monitor.setTaskName(Messages.ValidationDialog_validating
0866: + " " + testName
0867: + Messages.ValidationDialog_ellipsis);
0868: SubProgressMonitor subMonitor = new SubProgressMonitor(
0869: monitor, 10);
0870: processor.runFeatureTest(testName, layers, results[i],
0871: subMonitor);
0872: //processor.runIntegrityTest(test.getName(), layers, results[i], monitor);
0873:
0874: //check for cancellation again...
0875: if (subMonitor.isCanceled()) {
0876: monitor.setCanceled(true);
0877: }
0878: if (monitor.isCanceled()) {
0879: break;
0880: }
0881: //add to issues list
0882: monitor.subTask(MessageFormat.format(
0883: Messages.ValidationDialog_populating, testName));
0884: IIssuesManager.defaultInstance.getIssuesList().addAll(
0885: results[i].issues);
0886: monitor.worked(1);
0887: }
0888: monitor.done();
0889: return results;
0890: }
0891:
0892: /**
0893: * Based on the name of the argument, this function determines if it is a
0894: * typeRef or not.
0895: *
0896: * @param argName
0897: * @return
0898: */
0899: public static boolean isTypeRef(String argName) {
0900: if (argName.toLowerCase().contains("typeref"))return true; //$NON-NLS-1$
0901: else
0902: return false;
0903: }
0904:
0905: public static String getTypeRefLayer(String typeRef) {
0906: for (int i = 0; i < typeRefs.length; i++) {
0907: if (typeRefs[i].equals(typeRef)) {
0908: return layerNames[i];
0909: }
0910: }
0911: return null;
0912: }
0913:
0914: /**
0915: * Creates a validation processor. Both parameters may be null.
0916: *
0917: * @param pluginsDir
0918: * @param testSuiteFile
0919: * @return
0920: * @throws Exception
0921: */
0922: private ValidationProcessor createProcessor(File pluginsDir,
0923: File testSuiteFile) throws Exception {
0924: if (pluginsDir == null) {
0925: URL pluginURL = ValidationPlugin.getDefault().getBundle()
0926: .getResource("plugins"); //$NON-NLS-1$
0927: String pluginsPath = Platform.asLocalURL(pluginURL)
0928: .getFile();
0929: // String pluginsPath = FileLocator.toFileURL(pluginURL).getFile();
0930: pluginsDir = new File(pluginsPath);
0931: }
0932: return new ValidationProcessor(pluginsDir, testSuiteFile);
0933: }
0934:
0935: /**
0936: * Resizes the table columns to behave better.
0937: *
0938: * @param table
0939: */
0940: private void resizeTable() {
0941: Table table = tableViewer.getTable();
0942: TableUtils.resizeColumns(table, tableSettings,
0943: TableUtils.MODE_LAZY);
0944: }
0945:
0946: /**
0947: * Sets the given cursor for all shells currently active
0948: * for this window's display.
0949: *
0950: * @param c the cursor
0951: */
0952: private void setDisplayCursor(Cursor c) {
0953: Shell[] shells = display.getShells();
0954: for (int i = 0; i < shells.length; i++)
0955: shells[i].setCursor(c);
0956: }
0957:
0958: /** Enables/Disables the buttons as appropriate */
0959: private void updateButtons() {
0960: //check to see if any tests exist in the testSuite
0961: boolean testsExist;
0962: testsExist = processor.testsExist(defaultTestSuite);
0963: exportButton.setEnabled(testsExist);
0964: //only allow tests to be run when at least one is enabled
0965: boolean testsEnabled = false;
0966: if (testsExist) {
0967: Object[] elements = treeViewer.getCheckedElements();
0968: for (int i = 0; i < elements.length; i++) {
0969: if (elements[i] instanceof TestDTO) {
0970: testsEnabled = true;
0971: break;
0972: }
0973: }
0974: }
0975: runButton.setEnabled(testsEnabled);
0976: if (treeViewer.getSelection().isEmpty()) {
0977: newButton.setEnabled(false);
0978: deleteButton.setEnabled(false);
0979: }
0980: //clear the message bar (validation complete)
0981: setMessage(""); //$NON-NLS-1$
0982: }
0983:
0984: private void openIssuesList() throws PartInitException {
0985: if (Display.getCurrent() != null)
0986: try {
0987: PlatformUI.getWorkbench().getActiveWorkbenchWindow()
0988: .getActivePage().showView(
0989: IssueConstants.VIEW_ID);
0990: } catch (PartInitException e) {
0991: ValidationPlugin.log("error opening issues view", e); //$NON-NLS-1$
0992: }
0993: else {
0994: display.asyncExec(new Runnable() {
0995: public void run() {
0996: try {
0997: PlatformUI.getWorkbench()
0998: .getActiveWorkbenchWindow()
0999: .getActivePage().showView(
1000: IssueConstants.VIEW_ID);
1001: } catch (PartInitException e) {
1002: ValidationPlugin.log(
1003: "error opening issues view", e); //$NON-NLS-1$
1004: }
1005: }
1006: });
1007: }
1008:
1009: }
1010:
1011: private class DescModifiedListener implements ModifyListener {
1012: /**
1013: * Saves changes made to the description field
1014: */
1015: public void modifyText(ModifyEvent e) {
1016: //ensure this is a validation test description (plugin descriptions cannot be modified)
1017: if (selectedTreeItem instanceof TestDTO) {
1018: //save the text
1019: TestDTO treeItem = ((TestDTO) selectedTreeItem);
1020: treeItem.setDescription(descText.getText());
1021: }
1022: }
1023: }
1024:
1025: private class CellModifiedListener implements ICellModifier {
1026: public boolean canModify(Object element, String property) {
1027: return true;
1028: }
1029:
1030: public Object getValue(Object element, String property) {
1031: if (property.equals("Argument")) //$NON-NLS-1$
1032: return ((ArgumentDTO) element).getName();
1033: else {
1034: Object value = ((ArgumentDTO) element).getValue();
1035: //on read of arg value: null --> ""
1036: //on write of arg value: "" --> null
1037: if (value == null)
1038: return ""; //$NON-NLS-1$
1039: else
1040: return value;
1041: }
1042: }
1043:
1044: public void modify(Object element, String property, Object value) {
1045: if (property.equals("Value")) { //$NON-NLS-1$
1046: //store the new value in the testSuite
1047: TableItem tableItem = (TableItem) element;
1048: ArgumentDTO arg = (ArgumentDTO) tableItem.getData();
1049: if (value instanceof Integer) { //comboBox
1050: if (value.equals(-1))
1051: arg.setValue(""); //$NON-NLS-1$
1052: else {
1053: int val = (Integer) value;
1054: arg.setValue(typeRefs[val]);
1055: }
1056: } else if (value instanceof String) { //textBox
1057: //on read of arg value: null --> ""
1058: //on write of arg value: "" --> null
1059: if (value.equals(""))arg.setValue(null); //$NON-NLS-1$
1060: else
1061: arg.setValue(value);
1062: }
1063: tableViewer.refresh();
1064: //update the argument value in the validation test lookups (FV and IV)
1065: try {
1066: processor.setArg((TestDTO) selectedTreeItem, arg);
1067: } catch (ValidationException e) {
1068: // TODO Handle ValidationException
1069: throw (RuntimeException) new RuntimeException()
1070: .initCause(e);
1071: } catch (IntrospectionException e) {
1072: // TODO Handle IntrospectionException
1073: throw (RuntimeException) new RuntimeException()
1074: .initCause(e);
1075: }
1076: }
1077: }
1078: }
1079:
1080: private class NameModifiedListener implements ModifyListener {
1081: /**
1082: * Saves changes made to the name field
1083: */
1084: public void modifyText(ModifyEvent e) {
1085: //ensure this is a validation test description (plugin descriptions cannot be modified)
1086: if (selectedTreeItem instanceof TestDTO) {
1087: //save the text
1088: TestDTO treeItem = ((TestDTO) selectedTreeItem);
1089: boolean renameSuccess = processor.renameValidation(
1090: treeItem.getName(), nameText.getText(),
1091: defaultTestSuite);
1092: if (renameSuccess) {
1093: treeViewer.refresh();
1094: getDialog().setErrorMessage(null);
1095: } else {
1096: //user tried to create 2 identical test names -- complain.
1097: getDialog().setErrorMessage(
1098: Messages.ValidationDialog_nonUniqueTest);
1099: }
1100: }
1101: }
1102: }
1103:
1104: private TestDTO addTest() {
1105: Object selection = selectedTreeItem;
1106: TestDTO this Test = null;
1107: //plugin is selected?
1108: if (selection instanceof PlugInDTO) {
1109: // create a new validation test object
1110: PlugInDTO plugin = (PlugInDTO) selection;
1111: Validation newTest = null;
1112: try {
1113: newTest = processor.createValidation(plugin);
1114: } catch (Exception e1) {
1115: // log the exception and return
1116: MessageDialog
1117: .openError(
1118: PlatformUI.getWorkbench()
1119: .getActiveWorkbenchWindow()
1120: .getShell(),
1121: "Exception Occurred", e1.getClass().toString() + " " + e1.getMessage()); //$NON-NLS-1$//$NON-NLS-2$
1122: ValidationPlugin.log(e1.getMessage(), e1);
1123: return null;
1124: }
1125: // determine which TestSuiteDTO to use (for now, use the default)
1126: String testSuiteDTOKey = defaultTestSuite;
1127: // add the validation to the processor (creates a testDTO
1128: // and adds the validation to the appropriate lookup)
1129: processor.addValidation(newTest, plugin, testSuiteDTOKey);
1130: // if a defaultTypeRef exists, set any typeRefs to that value
1131: if ((defaultTypeRef != null) && defaultTypeRef.length() > 0) {
1132: this Test = (TestDTO) processor.getTests().get(
1133: newTest.getName());
1134: Map args = this Test.getArgs();
1135: for (Iterator i = args.keySet().iterator(); i.hasNext();) {
1136: ArgumentDTO arg = (ArgumentDTO) args.get(i.next());
1137: String argName = arg.getName();
1138: //is it a typeRef?
1139: if (isTypeRef(argName)) {
1140: //is it empty?
1141: if (arg.getValue() == null
1142: || arg.getValue().toString().length() == 0) {
1143: arg.setValue(defaultTypeRef);
1144: }
1145: }
1146: }
1147: }
1148: //if the current item is not expanded, expand it to show the new item
1149: if (!treeViewer.getExpandedState(selectedTreeItem)) {
1150: treeViewer.setExpandedState(selectedTreeItem, true);
1151: }
1152: //if the current parent test is checked and not grayed, check off the new test
1153: if (treeViewer.getChecked(selectedTreeItem)
1154: && !treeViewer.getGrayed(selectedTreeItem)) {
1155: treeViewer.setChecked(this Test, true);
1156: }
1157: //refresh
1158: treeViewer.refresh();
1159: updateButtons();
1160: }
1161: return this Test;
1162: }
1163:
1164: private class NewTestListener implements SelectionListener {
1165: public void widgetSelected(SelectionEvent e) {
1166: addTest();
1167: }
1168:
1169: public void widgetDefaultSelected(SelectionEvent e) {
1170: widgetSelected(e);
1171: }
1172:
1173: }
1174:
1175: private class DeleteTestListener implements SelectionListener {
1176: public void widgetSelected(SelectionEvent e) {
1177: Object selection = selectedTreeItem;
1178: //a test is selected?
1179: if (selection instanceof TestDTO) {
1180: //find the validation, given the TestDTO
1181: TestDTO test = (TestDTO) selection;
1182: //delete the validation test
1183: processor.removeValidation(test);
1184: treeViewer.refresh();
1185: updateButtons();
1186: }
1187: }
1188:
1189: public void widgetDefaultSelected(SelectionEvent e) {
1190: widgetSelected(e);
1191: }
1192: }
1193:
1194: private class RunTestsListener implements SelectionListener {
1195:
1196: GenericValidationResults[] results = new GenericValidationResults[0];
1197:
1198: public void widgetSelected(final SelectionEvent e) {
1199: final Object[] element = treeViewer.getCheckedElements();
1200:
1201: IRunnableWithProgress process = new IRunnableWithProgress() {
1202: public void run(final IProgressMonitor monitor)
1203: throws InvocationTargetException,
1204: InterruptedException {
1205: try {
1206: results = runValidationTestsUnOptimized(
1207: monitor, element);
1208: } catch (Exception e) {
1209: monitor.setCanceled(true);
1210: ValidationPlugin.log(
1211: "Error running validation Tests", e); //$NON-NLS-1$
1212: }
1213: }
1214: };
1215:
1216: Control focusControl = null;
1217: Cursor arrowCursor = null;
1218: Cursor waitCursor = null;
1219: try {
1220: focusControl = display.getFocusControl();
1221: progressMonitorPart.setVisible(true);
1222: runButton.setEnabled(false);
1223: cancelButton.removeSelectionListener(closeListener);
1224: cancelButton.addSelectionListener(cancelListener);
1225: waitCursor = new Cursor(display, SWT.CURSOR_WAIT);
1226: setDisplayCursor(waitCursor);
1227: // Set the arrow cursor to the cancel component.
1228: arrowCursor = new Cursor(display, SWT.CURSOR_ARROW);
1229: cancelButton.setText(IDialogConstants.CANCEL_LABEL);
1230: cancelButton.setCursor(arrowCursor);
1231: cancelButton.setFocus();
1232: setMessage("Validation in progress...");
1233: PlatformGIS.runBlockingOperation(process,
1234: progressMonitorPart);
1235: //progressMonitorPart.setVisible(false);
1236: } catch (InvocationTargetException e1) {
1237: // TODO Handle InvocationTargetException
1238: throw (RuntimeException) new RuntimeException()
1239: .initCause(e1);
1240: } catch (InterruptedException e1) {
1241: // TODO Handle InterruptedException
1242: throw (RuntimeException) new RuntimeException()
1243: .initCause(e1);
1244: } finally {
1245: //restore listeners
1246: cancelButton.removeSelectionListener(cancelListener);
1247: cancelButton.addSelectionListener(closeListener);
1248: cancelButton.setText(IDialogConstants.CLOSE_LABEL);
1249: //fix cursors
1250: setDisplayCursor(null);
1251: cancelButton.setCursor(null);
1252: waitCursor.dispose();
1253: waitCursor = null;
1254: arrowCursor.dispose();
1255: arrowCursor = null;
1256: //enable buttons
1257: cancelButton.setEnabled(true);
1258: runButton.setEnabled(true);
1259: //display response
1260: if (progressMonitorPart.isCanceled()) {
1261: setMessage("Validation was canceled");
1262: progressMonitorPart.setCanceled(false);
1263: } else {
1264: int failures = 0;
1265: int warnings = 0;
1266: if (results != null) {
1267: for (int i = 0; i < results.length; i++) {
1268: if (results[i] != null) {
1269: failures += results[i].failedFeatures
1270: .size();
1271: warnings += results[i].warningFeatures
1272: .size();
1273: }
1274: }
1275: }
1276: setMessage("Validation complete, " + failures
1277: + " failures and " + warnings
1278: + " warnings found.");
1279: }
1280: focusControl.setFocus();
1281: }
1282: }
1283:
1284: public void widgetDefaultSelected(SelectionEvent e) {
1285: widgetSelected(e);
1286: }
1287:
1288: }
1289:
1290: private class ImportSuiteListener implements SelectionListener {
1291: public void widgetSelected(SelectionEvent e) {
1292: //determine the file we want to open
1293: String fileName = null;
1294: //spawn a dialog and choose which file to import
1295: Display display = Display.getCurrent();
1296: if (display == null) { // not on the ui thread?
1297: display = Display.getDefault();
1298: }
1299: FileDialog importDialog = new FileDialog(display
1300: .getActiveShell(), SWT.OPEN);
1301:
1302: //final IPath homepath = Platform.getLocation();
1303: //exportDialog.setFilterPath(homepath.toOSString());
1304: importDialog.setFilterNames(new String[] {
1305: Messages.ValidationDialog_filesXML,
1306: Messages.ValidationDialog_filesAll });
1307: importDialog.setFilterExtensions(new String[] {
1308: "*.xml", "*.*" }); //$NON-NLS-1$ //$NON-NLS-2$
1309:
1310: boolean done = false;
1311: while (!done) {
1312: fileName = importDialog.open();
1313: if (fileName == null) {
1314: done = true;
1315: return;
1316: } else {
1317: // User has selected a file; see if it already exists
1318: File file = new File(fileName);
1319: if (!file.exists()) {
1320: // The file does not exist; yell at the user and try again
1321: MessageBox mb = new MessageBox(importDialog
1322: .getParent(), SWT.ICON_ERROR | SWT.OK);
1323: mb
1324: .setMessage(fileName
1325: + Messages.ValidationDialog_fileNotExist);
1326: mb.open();
1327: } else {
1328: // File exists, so we're good to go
1329: done = true;
1330: }
1331: }
1332: }
1333:
1334: //read the file
1335: FileReader reader;
1336: try {
1337: reader = new FileReader(fileName);
1338: } catch (FileNotFoundException e3) {
1339: MessageDialog.openError(PlatformUI.getWorkbench()
1340: .getActiveWorkbenchWindow().getShell(),
1341: Messages.ValidationDialog_fileNotFound, e3
1342: .toString());
1343: ValidationPlugin.log(e3.toString()); //log the error, but don't throw the exception
1344: return;
1345: }
1346: TestSuiteDTO newDTO;
1347: try {
1348: newDTO = XMLReader.readTestSuite(fileName, reader,
1349: processor.getPluginDTOs());
1350: } catch (ValidationException e3) {
1351: String errorMsg = e3.toString();
1352: MessageDialog.openError(PlatformUI.getWorkbench()
1353: .getActiveWorkbenchWindow().getShell(),
1354: "Exception Occurred", errorMsg); //$NON-NLS-1$
1355: ValidationPlugin.log(errorMsg, e3);
1356: return;
1357: }
1358: try {
1359: reader.close();
1360: } catch (IOException e2) {
1361: MessageDialog.openError(PlatformUI.getWorkbench()
1362: .getActiveWorkbenchWindow().getShell(),
1363: "Exception Occurred", e2.toString()); //$NON-NLS-1$
1364: ValidationPlugin.log(e2.toString(), e2);
1365: return;
1366: }
1367: //get the existing testSuites
1368: Map<String, TestSuiteDTO> suites = processor
1369: .getTestSuiteDTOs();
1370: //ensure there is at least one test in the new testSuite
1371: if (newDTO.getTests().size() == 0) {
1372: //nothing to see here, move along
1373: return;
1374: }
1375: //if no testSuites exist, just copy the new one directly in
1376: if (suites.size() == 0) {
1377: suites.put(newDTO.getName(), newDTO);
1378: defaultTestSuite = newDTO.getName();
1379: //does the testSuite exist? if so, add the new tests to the existing one
1380: } else if (suites.containsKey(newDTO.getName())) {
1381: //ensure the current testSuite is selected
1382: defaultTestSuite = newDTO.getName();
1383: //get the existing testSuite
1384: TestSuiteDTO testSuite = (TestSuiteDTO) suites
1385: .get(defaultTestSuite);
1386: //move the tests to the existing testSuite
1387: testSuite = processor.moveTests(testSuite, newDTO
1388: .getTests(), false);
1389: suites.put(defaultTestSuite, testSuite); //overwrite the suite
1390: //a test Suite exists, but it isn't this one; put the new tests into the existing testSuite
1391: } else {
1392: TestSuiteDTO testSuite = (TestSuiteDTO) suites
1393: .get(defaultTestSuite);
1394: Map<String, TestDTO> tests = newDTO.getTests();
1395: testSuite = processor
1396: .moveTests(testSuite, tests, false);
1397: suites.put(defaultTestSuite, testSuite); //overwrite the suite with new map of tests
1398: }
1399: //do multiple testSuites exist? if so, merge them
1400: while (suites.size() > 1) {
1401: //find the first testSuite which isn't the defaultTestSuite
1402: Object key = null;
1403: for (Iterator i = suites.keySet().iterator(); i
1404: .hasNext();) {
1405: Object this Key = i.next();
1406: if (!(this Key.equals(defaultTestSuite))) {
1407: key = this Key;
1408: break;
1409: }
1410: }
1411: if (key != null) {
1412: TestSuiteDTO alphaSuite = (TestSuiteDTO) suites
1413: .get(defaultTestSuite);
1414: TestSuiteDTO betaSuite = (TestSuiteDTO) suites
1415: .get(key);
1416: alphaSuite = processor.moveTests(alphaSuite,
1417: betaSuite.getTests(), false);
1418: suites.remove(key); //bye betaSuite!
1419: suites.put(defaultTestSuite, alphaSuite); //overwrite the suite (alphaSuite has now assimilated betaSuite)
1420: }
1421: }
1422: //all done; save the Map of testSuites and refresh the Tree
1423: processor.setTestSuiteDTOs(suites);
1424: treeViewer.refresh();
1425: updateButtons();
1426: }
1427:
1428: public void widgetDefaultSelected(SelectionEvent e) {
1429: widgetSelected(e);
1430: }
1431: }
1432:
1433: private class ExportSuiteListener implements SelectionListener {
1434: public void widgetSelected(SelectionEvent e) {
1435: Display display = Display.getCurrent();
1436: if (display == null) { // not on the ui thread?
1437: display = Display.getDefault();
1438: }
1439: //grab the testSuite we want to save
1440: TestSuiteDTO testSuite = (TestSuiteDTO) processor
1441: .getTestSuiteDTOs().get(defaultTestSuite);
1442: //testSuite is empty?
1443: if (testSuite.getTests().size() == 0) {
1444: MessageBox mb = new MessageBox(
1445: display.getActiveShell(), SWT.ICON_ERROR
1446: | SWT.OK);
1447: mb.setMessage(Messages.ValidationDialog_noSuitePre
1448: + defaultTestSuite
1449: + Messages.ValidationDialog_noSuiteSuf);
1450: mb.open();
1451: return;
1452: }
1453: //check the testSuite to ensure that none of the arguments of a test are null
1454: if (!DTOUtils.noNullArguments(testSuite))
1455: return;
1456: //select the file to export to
1457: String fileName = null;
1458: //spawn a dialog and choose which file to export to
1459: FileDialog exportDialog = new FileDialog(display
1460: .getActiveShell(), SWT.SAVE);
1461:
1462: //final IPath homepath = Platform.getLocation();
1463: //exportDialog.setFilterPath(homepath.toOSString());
1464: exportDialog.setFilterNames(new String[] {
1465: Messages.ValidationDialog_filesXML,
1466: Messages.ValidationDialog_filesAll });
1467: exportDialog.setFilterExtensions(new String[] {
1468: "*.xml", "*.*" }); //$NON-NLS-1$ //$NON-NLS-2$
1469:
1470: boolean done = false;
1471: while (!done) {
1472: fileName = exportDialog.open();
1473: if (fileName == null) {
1474: done = true;
1475: return;
1476: } else {
1477: // User has selected a file; see if it already exists
1478: File file = new File(fileName);
1479: if (file.exists()) {
1480: // The file already exists; asks for confirmation
1481: MessageBox mb = new MessageBox(exportDialog
1482: .getParent(), SWT.ICON_WARNING
1483: | SWT.YES | SWT.NO);
1484:
1485: mb.setMessage(fileName
1486: + Messages.ValidationDialog_fileExists);
1487:
1488: // If they click Yes, we're done and we drop out. If
1489: // they click No, we redisplay the File Dialog
1490: done = mb.open() == SWT.YES;
1491: } else {
1492: // File does not exist, so we're good to go
1493: done = true;
1494: }
1495: }
1496: }
1497:
1498: //construct a writer
1499: Writer writer;
1500: try {
1501: writer = new FileWriter(fileName, false);
1502: } catch (IOException e1) {
1503: // TODO Handle IOException
1504: throw (RuntimeException) new RuntimeException()
1505: .initCause(e1);
1506: }
1507: //write the file
1508: XMLWriter.writeTestSuite(testSuite, writer);
1509: }
1510:
1511: public void widgetDefaultSelected(SelectionEvent e) {
1512: widgetSelected(e);
1513: }
1514: }
1515:
1516: /**
1517: * Retrieves the ValidationProcessor object from the blackboard, or null if one does not exist.
1518: *
1519: * @param map
1520: * @return
1521: */
1522: private ValidationProcessor loadDialogState(IMap map) {
1523: Object currentState = map.getBlackboard().get(BLACKBOARD_KEY);
1524: if (currentState instanceof ValidationProcessor)
1525: return (ValidationProcessor) currentState;
1526: else
1527: return null;
1528: }
1529:
1530: /**
1531: * Saves the ValidationProcessor object on the blackboard, so we can restore
1532: * the state of the validation dialog the next time the dialog is opened.
1533: *
1534: * @param validationProcessor
1535: * @param map
1536: */
1537: private void saveDialogState(
1538: ValidationProcessor validationProcessor, IMap map) {
1539: map.getBlackboard().put(BLACKBOARD_KEY, validationProcessor);
1540: }
1541: }
|