001: /* uDig - User Friendly Desktop Internet GIS client
002: * http://udig.refractions.net
003: * (C) 2004, Refractions Research Inc.
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation;
008: * version 2.1 of the License.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: */
015: package net.refractions.udig.validation;
016:
017: import java.beans.IntrospectionException;
018: import java.beans.PropertyDescriptor;
019: import java.io.File;
020: import java.lang.reflect.InvocationTargetException;
021: import java.net.URI;
022: import java.util.ArrayList;
023: import java.util.HashMap;
024: import java.util.HashSet;
025: import java.util.Iterator;
026: import java.util.Map;
027: import java.util.Set;
028:
029: import net.refractions.udig.project.ILayer;
030:
031: import org.eclipse.core.runtime.IProgressMonitor;
032: import org.eclipse.jface.dialogs.MessageDialog;
033: import org.eclipse.ui.PlatformUI;
034: import org.geotools.data.FeatureReader;
035: import org.geotools.data.FeatureSource;
036: import org.geotools.feature.Feature;
037: import org.geotools.feature.FeatureCollection;
038: import org.geotools.feature.FeatureType;
039: import org.geotools.validation.FeatureValidation;
040: import org.geotools.validation.IntegrityValidation;
041: import org.geotools.validation.PlugIn;
042: import org.geotools.validation.Validation;
043: import org.geotools.validation.ValidationResults;
044: import org.geotools.validation.dto.ArgumentDTO;
045: import org.geotools.validation.dto.PlugInDTO;
046: import org.geotools.validation.dto.TestDTO;
047: import org.geotools.validation.dto.TestSuiteDTO;
048: import org.geotools.validation.xml.ValidationException;
049: import org.geotools.validation.xml.XMLReader;
050:
051: import com.vividsolutions.jts.geom.Envelope;
052:
053: /**
054: * Subclass for the geotools ValidationProcessor, with added methods which allow
055: * for tree navigation, etc. For the most part, this adds more baggage to the
056: * class so the Validation Dialog can get information out of it.
057: * <p>
058: *
059: * </p>
060: *
061: * @author chorner
062: * @since 1.0.1
063: * @see org.geotools.validation.ValidationProcessor
064: */
065: public class ValidationProcessor extends
066: org.geotools.validation.ValidationProcessor {
067: final Object ANYTYPENAME = new Object(); //copy of the ANYTYPENAME object
068:
069: private Map<String, PlugInDTO> pluginDTOs;
070: private Map<String, TestSuiteDTO> testSuiteDTOs;
071:
072: private Map<String, ArgumentDTO> allArgs;
073:
074: /**
075: * Constructor for the udig ValidationProcessor subclass. The plugins
076: * parameter is required, but the testSuites var may be a null File object
077: * (a blank testSuite will be created).
078: *
079: * @param pluginsDir
080: * (directory containing pluginSchema xml files)
081: * @param testSuites
082: * (testSuite file or a directory)
083: * @throws Exception
084: */
085: public ValidationProcessor(File pluginsDir, File testSuiteFile)
086: throws Exception {
087: super ();
088: //load the pluginSchema files
089: Map<String, PlugInDTO> pluginDTOs = XMLReader
090: .loadPlugIns(pluginsDir);
091: //load or create the testSuite
092: Map<String, TestSuiteDTO> testSuiteDTOs;
093: boolean fileExists = true;
094: if (testSuiteFile == null)
095: fileExists = false;
096: else if (testSuiteFile.exists())
097: fileExists = false;
098: if (fileExists) {
099: testSuiteDTOs = XMLReader.loadValidations(testSuiteFile,
100: pluginDTOs);
101: } else {
102: //construct a map for DTO testSuites (empty)
103: testSuiteDTOs = new HashMap<String, TestSuiteDTO>();
104: TestSuiteDTO testSuite1 = new TestSuiteDTO();
105: testSuite1.setName("testSuite1"); //$NON-NLS-1$
106: testSuite1.setDescription(""); //$NON-NLS-1$
107: //create an empty map of tests (required!)
108: Map emptyTestsMap = new HashMap();
109: testSuite1.setTests(emptyTestsMap);
110: //store it
111: testSuiteDTOs.put("testSuite1", testSuite1); //$NON-NLS-1$
112: }
113: //save the plugins and testSuites for future use
114: this .pluginDTOs = pluginDTOs;
115: this .testSuiteDTOs = testSuiteDTOs;
116: //load the ValidationProcessor
117: load(pluginDTOs, testSuiteDTOs);
118: }
119:
120: /**
121: * Adds a testDTO validation to the testSuiteDTO, and calls addValidation
122: * from the superclass.
123: *
124: * @param validation
125: * FeatureValidation object
126: * @param testSuiteDTOKey
127: * ID object (the key of the testSuiteDTO as referenced in
128: * testSuiteDTOs)
129: * @see org.geotools.validation.ValidationProcessor.addValidation
130: */
131: public void addValidation(Validation validation, PlugInDTO plugin,
132: Object testSuiteDTOKey) {
133: //call the appropriate superclass method to add the validation to the feature/integrity lookup
134: if (validation instanceof FeatureValidation) {
135: FeatureValidation FV = (FeatureValidation) validation;
136: super .addValidation(FV);
137: } else if (validation instanceof IntegrityValidation) {
138: IntegrityValidation IV = (IntegrityValidation) validation;
139: super .addValidation(IV);
140: }
141: //ensure that a plugin is present
142: if (plugin == null) {
143: String errorMsg = "Validation plugin '" + validation.getName() + "' not found"; //$NON-NLS-1$ //$NON-NLS-2$
144: MessageDialog.openError(PlatformUI.getWorkbench()
145: .getActiveWorkbenchWindow().getShell(),
146: "Problem Occurred", errorMsg); //$NON-NLS-1$
147: ValidationPlugin.log(errorMsg, new ValidationException());
148: return;
149: }
150: //create a testDTO containing the new validation test and args
151: TestDTO newTest = new TestDTO();
152: //set the name, desc, plugin, and args
153: newTest.setName(validation.getName());
154: newTest.setDescription(validation.getDescription());
155: newTest.setPlugIn(plugin);
156: //create a copy of the map and args
157: //note: this copies the args from the PlugInDTO
158: //Map oldArgs = plugin.getArgs();
159: Map<String, ArgumentDTO> oldArgs = allArgs;
160: Map<String, ArgumentDTO> newArgs = new HashMap<String, ArgumentDTO>();
161: for (Iterator i = oldArgs.keySet().iterator(); i.hasNext();) {
162: ArgumentDTO oldArg = (ArgumentDTO) oldArgs.get(i.next());
163: ArgumentDTO newArg = (ArgumentDTO) oldArg.clone();
164: newArgs.put(newArg.getName(), newArg);
165: }
166: //store the new args
167: newTest.setArgs(newArgs);
168: //add the new test to the appropriate testSuite
169: Map<String, TestDTO> tests = ((TestSuiteDTO) testSuiteDTOs
170: .get(testSuiteDTOKey)).getTests();
171: tests.put(newTest.getName(), newTest);
172: ((TestSuiteDTO) testSuiteDTOs.get(testSuiteDTOKey))
173: .setTests(tests);
174: }
175:
176: public boolean renameValidation(String oldKey, String newKey,
177: Object testSuiteDTOKey) {
178: Map<String, TestDTO> tests = ((TestSuiteDTO) testSuiteDTOs
179: .get(testSuiteDTOKey)).getTests();
180: if (oldKey.equals(newKey))
181: return true; //no change
182: if (tests.containsKey(newKey))
183: return false; //duplicate key -- abort!
184: TestDTO test = tests.remove(oldKey);
185: test.setName(newKey);
186: tests.put(newKey, test);
187: return true;
188: }
189:
190: /**
191: * Removes a validation from its testSuiteDTO and from the FV/IV Lookups
192: *
193: * @param validation
194: */
195: public void removeValidation(TestDTO test) {
196: String testName = test.getName();
197: //PlugInDTO plugin = test.getPlugIn();
198: //remove from FVLookup
199: Map FVLookup = featureLookup;
200: for (Iterator i = FVLookup.keySet().iterator(); i.hasNext();) {
201: Object something;
202: Object currentItem = i.next();
203: something = FVLookup.get(currentItem);
204: if (something != null) {
205: ArrayList tests = (ArrayList) something;
206: for (Object this Test : tests) {
207: Validation this Validation = (Validation) this Test;
208: if (this Validation.getName().equalsIgnoreCase(
209: testName)) {
210: featureLookup.remove(currentItem);
211: }
212: }
213: }
214: }
215: //remove from IVLookup
216: Map IVLookup = integrityLookup;
217: for (Iterator i = IVLookup.keySet().iterator(); i.hasNext();) {
218: Object something;
219: Object currentItem = i.next();
220: something = IVLookup.get(currentItem);
221: if (something != null) {
222: ArrayList tests = (ArrayList) something;
223: for (Object this Test : tests) {
224: Validation this Validation = (Validation) this Test;
225: if (this Validation.getName().equalsIgnoreCase(
226: testName)) {
227: integrityLookup.remove(currentItem);
228: }
229: }
230: }
231: }
232: //remove from all testSuites
233: Map oldTests;
234: Map newTests; // = new HashMap();
235: //for each testSuite
236: for (Iterator i = testSuiteDTOs.keySet().iterator(); i
237: .hasNext();) {
238: TestSuiteDTO testSuite = (TestSuiteDTO) testSuiteDTOs.get(i
239: .next());
240: oldTests = testSuite.getTests();
241: newTests = new HashMap(testSuite.getTests()); //create a new copy of the object, so we can modify it
242: //for each test
243: for (Iterator j = ((HashMap) oldTests).keySet().iterator(); j
244: .hasNext();) {
245: Object testKey = j.next();
246: TestDTO currentTest = (TestDTO) oldTests.get(testKey);
247: if (currentTest.equals(test)) {
248: newTests.remove(testKey); //this is the test we want to delete
249: }
250: }
251: testSuite.setTests(newTests); //save the modified map of tests in the testSuite
252: }
253: }
254:
255: /**
256: * Runs a single feature validation test
257: *
258: * @param testName
259: * @param layers
260: * @param results
261: * @param monitor
262: * @throws Exception
263: */
264: public void runFeatureTest(Object testName, ILayer[] layers,
265: ValidationResults results, IProgressMonitor monitor)
266: throws Exception {
267:
268: // get the validator from testKey
269: FeatureValidation validator = null;
270: // (navigate through the featureLookup until we find an instance of the test)
271: for (Iterator i = featureLookup.keySet().iterator(); i
272: .hasNext();) {
273: ArrayList testList = (ArrayList) featureLookup
274: .get(i.next());
275: // iterate through each item in the list
276: for (Object this Test : testList) {
277: Validation test = (Validation) this Test;
278: // this is the matching validation for the given test
279: if (test.getName().equals(testName)) {
280: validator = (FeatureValidation) test;
281: break;
282: }
283: }
284: }
285:
286: // run the test
287: if (validator != null) // if we found the test
288: {
289: results.setValidation(validator);
290: //get a list of typeRefs to figure out which layers to run the test on
291: String[] typeRefs = validator.getTypeRefs();
292: if (typeRefs == null) {
293: //unfortunately, ALL typeRefs = null; we'll override that for now
294: typeRefs = new String[1];
295: typeRefs[0] = "*"; //$NON-NLS-1$
296: // } else if (typeRefs.length == 0) {
297: // return; //TODO: add messageBox "there are no typeRefs!"
298: }
299: Set<ILayer> relevantLayers = new HashSet<ILayer>();
300: for (int i = 0; i < typeRefs.length; i++) {
301: String typeRef = (String) typeRefs[i];
302: if (typeRef.equals("") || (typeRef.equals("*"))) { //$NON-NLS-1$//$NON-NLS-2$
303: //wildcard (I assume); add all layers to the relevantLayers and break
304: for (int j = 0; j < layers.length; j++) {
305: ILayer this Layer = layers[j];
306: relevantLayers.add(this Layer);
307: }
308: break;
309: }
310: //find the layer that matches the typeRef
311: for (int j = 0; j < layers.length; j++) {
312: ILayer this Layer = layers[j];
313: //make the typeRef
314: FeatureType schema = this Layer.getSchema();
315: if (schema == null)
316: continue;
317:
318: String dataStoreID = schema.getNamespace()
319: .toString();
320: String this TypeRef = dataStoreID
321: + ":" + schema.getTypeName(); //$NON-NLS-1$
322: //if the typeRefs match, add the layer to our set
323: if (this TypeRef.equals(typeRef)) {
324: relevantLayers.add(this Layer);
325: break;
326: }
327: }
328: }
329:
330: //for each relevant layer
331: for (Iterator k = relevantLayers.iterator(); k.hasNext();) {
332: ILayer this Layer = (ILayer) k.next();
333: //get the FeatureType
334: FeatureType type = this Layer.getSchema();
335: //create a FeatureReader (collection.reader)
336: FeatureSource source;
337: source = this Layer.getResource(FeatureSource.class,
338: monitor);
339: FeatureCollection collection = source.getFeatures();
340: //hmm... pretty pictures or efficiency?
341: int count = collection.getCount();
342: monitor.beginTask("", count); //$NON-NLS-1$
343: FeatureReader reader = collection.reader();
344: // iterate through each feature and run the test on it
345: int position = 0;
346: while (reader.hasNext()) {
347: //check for the cancel button
348: if (monitor.isCanceled()) {
349: reader.close();
350: break;
351: }
352: //validate this feature
353: monitor.subTask(++position + "/" + count); //$NON-NLS-1$
354: Feature feature = (Feature) reader.next();
355: try {
356: validator.validate(feature, type, results);
357: } catch (Throwable e) {
358: results.error(feature, e.getMessage());
359: }
360: monitor.worked(1);
361: }
362: reader.close();
363: }
364: }
365: }
366:
367: /**
368: * Runs a single integrity validation test
369: *
370: * @param testName
371: * @param layers
372: * @param results
373: * @param monitor
374: * @throws Exception
375: */
376: public void runIntegrityTest(Object testName, ILayer[] layers,
377: ValidationResults results, IProgressMonitor monitor)
378: throws Exception {
379:
380: // get the validator from testKey
381: IntegrityValidation validator = null;
382: // (navigate through the featureLookup until we find an instance of the test)
383: for (Iterator i = integrityLookup.keySet().iterator(); i
384: .hasNext();) {
385: ArrayList testList = (ArrayList) integrityLookup.get(i
386: .next());
387: // iterate through each item in the list
388: for (Object this Test : testList) {
389: Validation test = (Validation) this Test;
390: // this is the matching validation for the given test
391: if (test.getName().equals(testName)) {
392: validator = (IntegrityValidation) test;
393: break;
394: }
395: }
396: }
397: if (validator != null) // if we found the test
398: {
399: results.setValidation(validator);
400: Envelope envelope = layers[0].getMap().getViewportModel()
401: .getBounds();
402: FeatureSource source;
403: URI nameSpace;
404: String typeName;
405: Map<String, FeatureSource> stores = new HashMap<String, FeatureSource>();
406: for (int i = 0; i < layers.length; i++) {
407: nameSpace = layers[i].getSchema().getNamespace();
408: typeName = layers[i].getSchema().getTypeName();
409: source = layers[i].getResource(FeatureSource.class,
410: monitor);
411: String typeRef = nameSpace.toString() + ":" + typeName; //$NON-NLS-1$
412: stores.put(typeRef, source);
413: }
414: // run the test
415: validator.validate(stores, envelope, results);
416: }
417: }
418:
419: /**
420: * Runs all feature tests by iterating through the list of layers, and
421: * calling runFeatureTests() on each layer.
422: *
423: * @see org.geotools.validation.ValidationProcessor runFeatureTests()
424: *
425: * @param layers
426: * @param results
427: * @param monitor
428: * @throws Exception
429: */
430: public void runAllFeatureTests(ILayer[] layers,
431: ValidationResults results, IProgressMonitor monitor)
432: throws Exception {
433:
434: //for each layer
435: for (int i = 0; i < layers.length; i++) {
436: ILayer this Layer = layers[i];
437:
438: //get the dataStoreID
439: String dataStoreID = this Layer.getSchema().getNamespace()
440: .toString();
441:
442: //get the FeatureType
443: FeatureType type = this Layer.getSchema();
444:
445: //create a FeatureReader (collection.reader)
446: FeatureSource source;
447: source = this Layer
448: .getResource(FeatureSource.class, monitor);
449: FeatureCollection collection = source.getFeatures();
450:
451: //run the tests on this layer
452: runFeatureTests(dataStoreID, type, collection.reader(),
453: results);
454: }
455: }
456:
457: /**
458: * Runs all integrity tests (prepares and calls runIntegrityTests)
459: *
460: * @see org.geotools.validation.ValidationProcessor runIntegrityTests()
461: *
462: * @param layers
463: * @param results
464: * @param monitor
465: * @throws Exception
466: */
467: public void runAllIntegrityTests(ILayer[] layers,
468: ValidationResults results, IProgressMonitor monitor)
469: throws Exception {
470:
471: //FIXME: take Map as input rather than layer(s)?
472: Envelope envelope = layers[0].getMap().getViewportModel()
473: .getBounds();
474: FeatureSource source;
475: URI nameSpace;
476: String typeName;
477: Map<String, FeatureSource> stores = new HashMap<String, FeatureSource>();
478: Set<String> typeRefs = new HashSet<String>();
479: for (int i = 0; i < layers.length; i++) {
480: nameSpace = layers[i].getSchema().getNamespace();
481: typeName = layers[i].getSchema().getTypeName();
482: source = layers[i]
483: .getResource(FeatureSource.class, monitor);
484: //map = dataStoreID:typeName
485: String typeRef = nameSpace.toString() + ":" + typeName; //$NON-NLS-1$
486: stores.put(typeRef, source);
487: typeRefs.add(typeRef);
488: }
489:
490: //run the tests
491: runIntegrityTests(typeRefs, stores, envelope, results);
492: }
493:
494: /**
495: * Creates a new validation test of the correct type when passed the plugInDTO.
496: *
497: * @param plugin
498: * @return
499: * @throws ValidationException
500: * @throws ClassNotFoundException
501: */
502: public Validation createValidation(PlugInDTO dto)
503: throws ValidationException, ClassNotFoundException {
504: //create a PlugIn from a PlugInDTO
505: Class plugInClass = null;
506: plugInClass = Class.forName(dto.getClassName());
507: PlugIn plugIn = new PlugIn(dto.getName(), plugInClass, dto
508: .getDescription(), dto.getArgs());
509: // copy the arguments over to the new object
510: // NOTE: this may not be necessary, but we've cloned each argument and
511: // hashmap here to ensure each new validation has its own unique argument
512: // (and are not accidentally shared).
513: Map<String, ArgumentDTO> oldArgs = dto.getArgs();
514: Map<String, ArgumentDTO> newArgs = new HashMap<String, ArgumentDTO>();
515: for (Iterator i = oldArgs.keySet().iterator(); i.hasNext();) {
516: ArgumentDTO oldArg = (ArgumentDTO) oldArgs.get(i.next());
517: ArgumentDTO newArg = (ArgumentDTO) oldArg.clone();
518: newArgs.put(newArg.getName(), newArg);
519: }
520: // we have the default args, but we'll scan the complete list of args
521: // and add any that are missing
522: Map allArgs = plugIn.getPropertyMap();
523: for (Iterator i = allArgs.keySet().iterator(); i.hasNext();) {
524: Object this Arg = allArgs.get(i.next());
525:
526: if (this Arg instanceof PropertyDescriptor) {
527: PropertyDescriptor this Element = ((PropertyDescriptor) this Arg);
528: String argName = this Element.getName();
529: Object argValue = this Element.getValue(argName);
530: // add keys to the map which do not contain "name", "description", or an existing key
531: if (!(newArgs.containsKey(argName))
532: && !(argName.equals("name")) && !(argName.equals("description"))) { //$NON-NLS-1$//$NON-NLS-2$
533: ArgumentDTO newArg = new ArgumentDTO();
534: newArg.setName(argName);
535: newArg.setValue(argValue);
536: newArgs.put(newArg.getName(), newArg);
537: }
538: }
539: }
540: //store the complete list of Args for future use (will be overwritten by the latest test creation)
541: this .allArgs = newArgs;
542: //create a new validation
543: Validation validation = plugIn.createValidation(getUniqueName(
544: getTests(), "Test"), dto.getDescription(), newArgs); //$NON-NLS-1$
545: return validation;
546: }
547:
548: /**
549: * Regenerates the FV Lookup Map based on the contents of the testSuite
550: *
551: */
552: public void updateFVLookup() {
553: //get all validation tests from the featureLookup
554: Set<Validation> validations = new HashSet<Validation>();
555: for (Iterator i = featureLookup.keySet().iterator(); i
556: .hasNext();) {
557: ArrayList list = (ArrayList) featureLookup.get(i.next());
558: for (int j = 0; j < list.size(); j++) {
559: Validation test = (Validation) list.get(j);
560: validations.add(test);
561: }
562: }
563:
564: //clear the FV Lookup
565: featureLookup.clear();
566:
567: //add each test to the Lookup (again)
568: for (Iterator i = validations.iterator(); i.hasNext();) {
569: Validation validation = (Validation) i.next();
570: if (validation instanceof FeatureValidation) {
571: //FeatureValidation FV = (FeatureValidation) validation;
572: //addToFVLookup(FV); // <-- this is the proper way to do this
573:
574: //NOTE: code below is a verbatim copy of addToFVLookup(), which is private
575: //TODO: change org.geotools.validation.ValidationProcessor.addToFVLookup() to public or protected?
576: String[] featureTypeList = validation.getTypeRefs();
577:
578: if (featureTypeList == Validation.ALL) // if null (ALL)
579: {
580: ArrayList<Validation> tests = (ArrayList) featureLookup
581: .get(ANYTYPENAME);
582:
583: if (tests == null) { // if an ALL test doesn't exist yet
584: tests = new ArrayList<Validation>(); // create it
585: }
586:
587: tests.add(validation);
588: featureLookup.put(ANYTYPENAME, tests); // add the ALL test
589: // to it
590: } else // a non ALL FeatureTypeInfo validation
591: {
592: for (int j = 0; j < featureTypeList.length; j++) {
593: ArrayList<Validation> tests = (ArrayList) featureLookup
594: .get(featureTypeList[j]);
595: if (tests == null) { // if this FeatureTypeInfo doesn't have a validation test yet
596: tests = new ArrayList(); // put it in the list
597: }
598: tests.add(validation);
599: featureLookup.put(featureTypeList[j], tests); // add a validation to it
600: }
601: }
602: }
603: }
604: }
605:
606: public void updateIVLookup() {
607: // get all validation tests from the integrityLookup
608: Set<Validation> validations = new HashSet<Validation>();
609: for (Iterator i = integrityLookup.keySet().iterator(); i
610: .hasNext();) {
611: ArrayList list = (ArrayList) integrityLookup.get(i.next());
612: for (int j = 0; j < list.size(); j++) {
613: Validation test = (Validation) list.get(j);
614: validations.add(test);
615: }
616: }
617:
618: // clear the IV Lookup
619: integrityLookup.clear();
620:
621: // add each test to the Lookup (again)
622: for (Iterator i = validations.iterator(); i.hasNext();) {
623: Validation validation = (Validation) i.next();
624: if (validation instanceof IntegrityValidation) {
625: // IntegrityValidation IV = (IntegrityValidation) validation;
626: // addToIVLookup(IV); // <-- this is the proper way to do this
627:
628: // NOTE: code below is a verbatim copy of addToIVLookup(), which is private
629: // TODO: change org.geotools.validation.ValidationProcessor.addToIVLookup() to public or protected?
630: String[] integrityTypeList = validation.getTypeRefs();
631:
632: if (integrityTypeList == Validation.ALL) // if null (ALL)
633: {
634: ArrayList<Validation> tests = (ArrayList) integrityLookup
635: .get(ANYTYPENAME);
636: if (tests == null) { // if an ALL test doesn't exist yet
637: tests = new ArrayList<Validation>(); // create it
638: }
639: tests.add(validation);
640: integrityLookup.put(ANYTYPENAME, tests); // add the ALL test to it
641: } else {
642: for (int j = 0; j < integrityTypeList.length; j++) {
643: ArrayList<Validation> tests = (ArrayList) integrityLookup
644: .get(integrityTypeList[j]);
645: if (tests == null) { // if this FeatureTypeInfo doesn't have a validation test yet
646: tests = new ArrayList<Validation>(); // put it in the list
647: }
648: tests.add(validation);
649: integrityLookup
650: .put(integrityTypeList[j], tests); // add a validation to it
651: }
652: }
653: }
654: }
655: }
656:
657: /**
658: * Returns a unique name for an automatically generated Test (Test1, Test2,
659: * etc), or where labelPrefix is typically "Test"
660: *
661: * @param allItems
662: * @param labelPrefix
663: * @return
664: */
665: public String getUniqueName(Map allItems, String labelPrefix) {
666: String currentName;
667: for (int i = 1; i < 10000; i++) {
668: //check to see if Test{i} is in use
669: currentName = labelPrefix + i;
670: if (!allItems.containsKey(currentName)) {
671: return currentName;
672: }
673: }
674: return null;
675: }
676:
677: /**
678: * Places a Map of tests one-by-one into a TestSuiteDTO. If an equal test
679: * already exists in the testSuite, it is ignored.
680: *
681: * @param suite
682: * @param tests
683: * @param allDupes
684: * @return
685: */
686: public TestSuiteDTO moveTests(TestSuiteDTO suite,
687: Map<String, TestDTO> tests, boolean allowDupes) {
688: Map<String, TestDTO> someTests = tests; //tests which are to be moved
689: Map<String, TestDTO> allTests = suite.getTests(); //list of tests already in the suite
690: //for each test
691: for (Iterator i = someTests.keySet().iterator(); i.hasNext();) {
692: //clone the test
693: TestDTO currentTest = new TestDTO((TestDTO) someTests.get(i
694: .next()));
695: //if the current test does not exist, add it
696: if (!(allTests.containsKey(currentTest.getName()))) {
697: allTests.put(currentTest.getName(), currentTest);
698: //if the current test does exist, rename if not identical (or allowDupes is true)
699: } else if (allowDupes
700: || !(allTests.get(currentTest.getName())
701: .equals(currentTest))) {
702: String newName = getUniqueName(tests, "Test"); //$NON-NLS-1$
703: currentTest.setName(newName);
704: allTests.put(currentTest.getName(), currentTest);
705: }
706: }
707: suite.setTests(allTests);
708: return suite;
709: }
710:
711: /**
712: * Returns a Set (HashSet) of plugins (validation tests) available.
713: */
714: public Set getPlugins() {
715: HashMap hashMap = (HashMap) pluginDTOs;
716: Set<PlugInDTO> plugins = new HashSet<PlugInDTO>();
717: for (Iterator i = hashMap.keySet().iterator(); i.hasNext();) {
718: PlugInDTO plugin = (PlugInDTO) hashMap.get(i.next());
719: plugins.add(plugin);
720: }
721: return plugins;
722: }
723:
724: /**
725: * Returns a complete list of available tests (all testSuites are merged)
726: *
727: * @return Map of tests
728: */
729: public Map getTests() {
730: Map<String, TestDTO> testMap = new HashMap<String, TestDTO>();
731: //for each testSuite
732: for (Iterator i = testSuiteDTOs.keySet().iterator(); i
733: .hasNext();) {
734: TestSuiteDTO testSuite = (TestSuiteDTO) testSuiteDTOs.get(i
735: .next());
736: //for each test
737: for (Iterator j = ((HashMap) testSuite.getTests()).keySet()
738: .iterator(); j.hasNext();) {
739: TestDTO currentTest = (TestDTO) testSuite.getTests()
740: .get(j.next());
741: testMap.put(currentTest.getName(), currentTest);
742: }
743: }
744: return testMap;
745: }
746:
747: /**
748: * Returns an array of tests relevant to the plugin
749: *
750: * @param plugin
751: * @return
752: */
753: public Object[] getTests(Object plugin) {
754: Set<TestDTO> testSet = new HashSet<TestDTO>();
755: //for each testSuite
756: for (Iterator i = testSuiteDTOs.keySet().iterator(); i
757: .hasNext();) {
758: TestSuiteDTO testSuite = (TestSuiteDTO) testSuiteDTOs.get(i
759: .next());
760: //for each test
761: for (Iterator j = ((HashMap) testSuite.getTests()).keySet()
762: .iterator(); j.hasNext();) {
763: TestDTO currentTest = (TestDTO) testSuite.getTests()
764: .get(j.next());
765: PlugInDTO this Plugin = (PlugInDTO) plugin;
766: // matching plugin?
767: if (currentTest.getPlugIn().equals(this Plugin)) {
768: testSet.add(currentTest);
769: }
770: }
771: }
772: return testSet.toArray();
773: }
774:
775: /**
776: * Determines if a given testSuite contains any tests or not.
777: *
778: * @param testSuiteKey
779: * @return
780: */
781: public boolean testsExist(Object testSuiteKey) {
782: TestSuiteDTO testSuite = (TestSuiteDTO) testSuiteDTOs
783: .get(testSuiteKey);
784: if (testSuite.getTests().size() > 0)
785: return true;
786: else
787: return false;
788: }
789:
790: public void setArg(TestDTO test, ArgumentDTO arg)
791: throws ValidationException, IntrospectionException {
792: Map FVLookup = featureLookup;
793: Map<String, Object> args = new HashMap<String, Object>();
794: args.put(arg.getName(), arg.getValue()); //value = argDTO or Object?
795: //iterate through each item in the map (should contain a single ArrayList)
796: for (Iterator i = FVLookup.keySet().iterator(); i.hasNext();) {
797: ArrayList testList = (ArrayList) FVLookup.get(i.next());
798: //iterate through each item in the list
799: for (Object this Test : testList) {
800: Validation validation = (Validation) this Test;
801: // this is the matching validation for the given test
802: if (validation.getName().equals(test.getName())) {
803: //create a property descriptor containing the argument name and plugin class
804: PropertyDescriptor property = new PropertyDescriptor(
805: arg.getName(), validation.getClass());
806: if (property == null) {
807: // error here
808: continue;
809: }
810: //store the value of the argument in the property descriptor
811: try {
812: property.getWriteMethod().invoke(validation,
813: new Object[] { arg.getValue() });
814: } catch (IllegalArgumentException e) {
815: String val = arg.getValue() == null ? arg
816: .getValue().toString() : "null"; //$NON-NLS-1$
817: throw new ValidationException(
818: "test failed to configure " //$NON-NLS-1$
819: + validation.getClass()
820: .getSimpleName()
821: + " " + arg.getName() + " " + val, e); //$NON-NLS-1$ //$NON-NLS-2$
822: } catch (IllegalAccessException e) {
823: String val = arg.getValue() == null ? arg
824: .getValue().toString() : "null"; //$NON-NLS-1$
825: throw new ValidationException(
826: "test failed to configure " //$NON-NLS-1$
827: + validation.getClass()
828: .getSimpleName()
829: + " " + arg.getName() + " " + val, e); //$NON-NLS-1$ //$NON-NLS-2$
830: } catch (InvocationTargetException e) {
831: String val = arg.getValue() == null ? arg
832: .getValue().toString() : "null"; //$NON-NLS-1$
833: throw new ValidationException(
834: "test failed to configure " //$NON-NLS-1$
835: + validation.getClass()
836: .getSimpleName()
837: + " " + arg.getName() + " " + val, e); //$NON-NLS-1$ //$NON-NLS-2$
838: }
839: }
840: }
841: }
842: }
843:
844: public Map getPluginDTOs() {
845: return pluginDTOs;
846: }
847:
848: public void setPluginDTOs(Map<String, PlugInDTO> pluginDTOs) {
849: this .pluginDTOs = pluginDTOs;
850: }
851:
852: public Map<String, TestSuiteDTO> getTestSuiteDTOs() {
853: return testSuiteDTOs;
854: }
855:
856: public void setTestSuiteDTOs(Map<String, TestSuiteDTO> testSuiteDTOs) {
857: this.testSuiteDTOs = testSuiteDTOs;
858: }
859:
860: }
|