001    package com.thaiopensource.relaxng.util;
002    
003    import com.thaiopensource.util.OptionParser;
004    import com.thaiopensource.util.PropertyMapBuilder;
005    import com.thaiopensource.util.Localizer;
006    import com.thaiopensource.validate.ValidateProperty;
007    import com.thaiopensource.validate.ValidationDriver;
008    import com.thaiopensource.validate.rng.RngProperty;
009    import com.thaiopensource.xml.sax.ErrorHandlerImpl;
010    import org.xml.sax.SAXException;
011    import org.relaxng.datatype.helpers.DatatypeLibraryLoader;
012    
013    import java.io.BufferedWriter;
014    import java.io.File;
015    import java.io.FileOutputStream;
016    import java.io.IOException;
017    import java.io.OutputStreamWriter;
018    
019    class TestDriver {
020      static public void main(String[] args) throws IOException {
021        System.exit(new TestDriver().doMain(args));
022      }
023    
024      private ValidationDriver driver;
025      private ErrorHandlerImpl eh;
026      private Localizer localizer = new Localizer(TestDriver.class);
027      private int nTests = 0;
028    
029      public int doMain(String[] args) throws IOException {
030        long startTime = System.currentTimeMillis();
031        eh = new ErrorHandlerImpl(System.out);
032        OptionParser op = new OptionParser("i", args);
033        PropertyMapBuilder properties = new PropertyMapBuilder();
034        // This is an optimization.  It ensures that all SchemaReaders share a
035        // single DatatypeLibraryLoader.
036        RngProperty.DATATYPE_LIBRARY_FACTORY.put(properties, new DatatypeLibraryLoader());
037        try {
038          while (op.moveToNextOption()) {
039            switch (op.getOptionChar()) {
040            case 'i':
041              RngProperty.CHECK_ID_IDREF.add(properties);
042              break;
043            }
044          }
045        }
046        catch (OptionParser.InvalidOptionException e) {
047          eh.print(localizer.message("invalid_option", op.getOptionCharString()));
048          return 2;
049        }
050        catch (OptionParser.MissingArgumentException e) {
051          eh.print(localizer.message("option_missing_argument", op.getOptionCharString()));
052          return 2;
053        }
054        args = op.getRemainingArgs();
055        eh = new ErrorHandlerImpl(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(args[0]))));
056        ValidateProperty.ERROR_HANDLER.put(properties, eh);
057        driver = new ValidationDriver(properties.toPropertyMap());
058        int result = 0;
059        for (int i = 1; i < args.length; i++) {
060          int n = runTestSuite(new File(args[i]));
061          if (n > result)
062            result = n;
063        }
064        System.err.println("Number of tests: " + nTests);
065        System.err.println("Elapsed time: " + (System.currentTimeMillis() - startTime));
066        eh.close();
067        return result;
068      }
069    
070      private static final String CORRECT_SCHEMA_NAME = "c.rng";
071      private static final String INCORRECT_SCHEMA_NAME = "i.rng";
072      private static final String VALID_INSTANCE_SUFFIX = ".v.xml";
073      private static final String INVALID_INSTANCE_SUFFIX = ".i.xml";
074      
075      public int runTestSuite(File dir) throws IOException {
076        int result = 0;
077        String[] subdirs = dir.list();
078        for (int i = 0; i < subdirs.length; i++) {
079          File subdir = new File(dir, subdirs[i]);
080          if (subdir.isDirectory()) {
081            int n = runTestCase(subdir);
082            if (n > result)
083              result = n;
084          }
085        }
086        return result;
087      }
088    
089      private int runTestCase(File dir) throws IOException {
090        File f = new File(dir, INCORRECT_SCHEMA_NAME);
091        if (f.exists()) {
092          if (loadSchema(f)) {
093            failed(f);
094            return 1;
095          }
096          return 0;
097        }
098        f = new File(dir, CORRECT_SCHEMA_NAME);
099        if (!f.exists())
100          return 0;
101        if (!loadSchema(f)) {
102          failed(f);
103          return 1;
104        }
105        String[] files = dir.list();
106        int result = 0;
107        for (int i = 0; i < files.length; i++) {
108          if (files[i].endsWith(VALID_INSTANCE_SUFFIX)) {
109            f = new File(dir, files[i]);
110            if (!validateInstance(f)) {
111              failed(f);
112              result = 1;
113            }
114          }
115          else if (files[i].endsWith(INVALID_INSTANCE_SUFFIX)) {
116            f = new File(dir, files[i]);
117            if (validateInstance(f)) {
118              failed(f);
119              result = 1;
120            }
121          }
122        }
123        return result;
124      }
125    
126      private static void failed(File f) {
127        System.err.println("Failed: " + f.toString());
128      }
129    
130      private boolean loadSchema(File schema) throws IOException {
131        nTests++;
132        try {
133          if (driver.loadSchema(ValidationDriver.fileInputSource(schema)))
134            return true;
135        }
136        catch (SAXException e) {
137          eh.printException(e);
138        }
139        return false;
140      }
141    
142      private boolean validateInstance(File instance) throws IOException {
143        nTests++;
144        try {
145          if (driver.validate(ValidationDriver.fileInputSource(instance)))
146            return true;
147        }
148        catch (SAXException e) {
149          eh.printException(e);
150        }
151        return false;
152      }
153    }