001    
002    /*
003     * $RCSfile: ValidateXMLSchema.java,v $ 
004     *
005     * Created on May 18, 2004, 11:30 AM
006     *
007     * This file is part of the STAR Scheduler.
008     * Copyright (c) 2003-2006 STAR Collaboration - Brookhaven National Laboratory
009     *
010     * STAR Scheduler is free software; you can redistribute it and/or modify
011     * it under the terms of the GNU General Public License as published by
012     * the Free Software Foundation; either version 2 of the License, or
013     * (at your option) any later version.
014     *
015     * STAR Scheduler is distributed in the hope that it will be useful,
016     * but WITHOUT ANY WARRANTY; without even the implied warranty of
017     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
018     * GNU General Public License for more details.
019     *
020     * You should have received a copy of the GNU General Public License
021     * along with STAR Scheduler; if not, write to the Free Software
022     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
023     */
024    
025    package gov.bnl.star.offline.scheduler.request;
026    
027    import java.io.*;
028    import javax.xml.parsers.SAXParserFactory;
029    
030    import org.iso_relax.dispatcher.Dispatcher;
031    import org.iso_relax.dispatcher.SchemaProvider;
032    import org.iso_relax.dispatcher.impl.DispatcherImpl;
033    import org.xml.sax.EntityResolver;
034    import org.xml.sax.InputSource;
035    import org.xml.sax.SAXException;
036    import org.xml.sax.SAXParseException;
037    import org.xml.sax.XMLReader;
038    
039    import com.sun.msv.grammar.Grammar;
040    import com.sun.msv.grammar.xmlschema.XMLSchemaGrammar;
041    import com.sun.msv.reader.util.GrammarLoader;
042    import com.sun.msv.util.Util;
043    import com.sun.msv.verifier.Verifier;
044    import com.sun.msv.verifier.identity.IDConstraintChecker;
045    import com.sun.msv.driver.textui.*;
046    
047    /**
048     * Compares the user's xml request to an XML schema for validation. Line error are printed to the screen.
049     * @author  Levente Hajdu
050     **/
051    public class ValidateXMLSchema {
052            
053        static SAXParserFactory factory;
054        static private String JDLSchema = "schema/SUMS_UJDL.xsd";
055        static private String RDLSchema = "schema/RDL.xsd";
056        static private int minFileSize = 10;
057    
058        //For stand alone testting    
059        public static void main(String[] no_string) throws Exception {
060            ValidateXMLSchema validator = new ValidateXMLSchema();
061            //A test file to test ValidateXMLSchema
062            validator.TestFile(
063                "C:\\Documents and Settings\\Levente Hajdu\\Desktop\\msv-20030225\\in.xml",
064                RequestType.JDL); 
065        }
066        
067       /**
068        * Perform XML schema validation
069        * @param xml XML request
070        * @param requestType request type: JDL, RDL
071        */
072        public boolean TestFile(String xml, int requestType) {
073              
074            System.out.print("\nAnalyzing XML...");
075                    
076            // test if file size bigger then zero bites
077            long len = xml.length();
078            if (len == 0)
079                System.out.println("Warning... request file is empty!!!"); 
080            else if (len < minFileSize)
081                System.out.println("Warning... request file size is only "
082                                   + len +" byte(s)!!!");
083    
084            EntityResolver entityResolver = null;
085            factory = SAXParserFactory.newInstance();
086            factory.setNamespaceAware(true);
087            factory.setValidating(false);
088                    
089            // parse schema
090            //--------------------
091            Grammar grammar = null;
092                    
093            // load the schema
094            String schemaFile;
095            switch (requestType) {
096                case RequestType.JDL:
097                    schemaFile = JDLSchema;
098                    break;
099                case RequestType.RDL:
100                    schemaFile = RDLSchema;
101                    break;
102                default:
103                    return false;
104            }
105    
106            try {
107                InputStream is = ValidateXMLSchema.class.getClassLoader().getResourceAsStream(
108                        schemaFile);
109                GrammarLoader loader = new GrammarLoader();
110                InputSource ips = new InputSource();
111                ips.setByteStream(is);
112                grammar = loader.parse(ips);
113                        
114                // set various parameters
115                loader.setController( new DebugController(false,false,entityResolver) );
116                loader.setSAXParserFactory(factory);
117                loader.setStrictCheck(false);
118    
119            } catch (SAXParseException spe) {
120                if (Debug.debug)
121                    spe.getException().printStackTrace();
122                System.out.println("SAX Parse Error: " + spe);
123                return false;
124            } catch (Exception e) {
125                if (Debug.debug)
126                    e.printStackTrace();
127                System.out.println("Parse Error: " + e);
128                return false;
129            }
130                            
131            long parsingTime = System.currentTimeMillis();
132                    
133            // validate documents
134            //--------------------
135            DocumentVerifier verifier;
136            verifier = new XMLSchemaVerifier( (XMLSchemaGrammar)grammar );
137                    
138            // System.out.println( localize( MSG_VALIDATING, xml) );
139    
140            boolean result = false;
141            StringReader sr = new StringReader(xml);
142            InputSource source = new InputSource(sr);
143    
144            try {
145                XMLReader reader = factory.newSAXParser().getXMLReader();
146                if (entityResolver != null)
147                    reader.setEntityResolver(entityResolver);
148                reader.setErrorHandler( new ReportErrorHandler() );
149                result = verifier.verify(reader, source, true);
150            } catch( com.sun.msv.verifier.ValidationUnrecoverableException vv ) {
151                System.out.println(vv);
152            } catch( SAXParseException se ) {
153                System.out.println("SAXException in ValidateXMLSchema.java");
154                if ( se.getException()!=null )
155                    se.getException().printStackTrace();
156            } catch( Exception e ) {
157                e.printStackTrace();
158                System.out.println("Exception in ValidateXMLSchema.java");
159            }
160    
161            if (result)
162                System.out.print("XML OK");
163                    
164            System.out.print("\n");
165            return result;
166        }
167        
168        /** acts as a function closure to validate a document. */
169        private interface DocumentVerifier {
170            boolean verify( XMLReader p, InputSource instance, boolean usePanicMode ) throws Exception;
171        }
172            
173        /** validates a document by using divide &amp; validate framework. */
174        private static class RELAXNSVerifier implements DocumentVerifier {
175            private final SchemaProvider sp;
176                    
177            RELAXNSVerifier( SchemaProvider sp ) { this.sp=sp; }
178                    
179            public boolean verify( XMLReader p, InputSource instance, boolean panicMode ) throws Exception {
180                Dispatcher dispatcher = new DispatcherImpl(sp);
181                dispatcher.attachXMLReader(p);
182                ReportErrorHandler errorHandler = new ReportErrorHandler();
183                dispatcher.setErrorHandler( errorHandler );
184                p.parse(instance);
185                return !errorHandler.hadError;
186            }
187        } 
188            
189    
190        private static class XMLSchemaVerifier implements DocumentVerifier {
191            private final XMLSchemaGrammar grammar;
192                    
193            XMLSchemaVerifier( XMLSchemaGrammar grammar ) { this.grammar = grammar; }
194    
195            public boolean verify( XMLReader p, InputSource instance, boolean panicMode ) throws Exception {
196                ReportErrorHandler reh = new ReportErrorHandler();
197                Verifier v = new IDConstraintChecker( grammar, reh );
198                v.setPanicMode(panicMode);
199                    
200                p.setDTDHandler(v);
201                p.setContentHandler(v);
202                p.setErrorHandler(reh);
203                    
204                p.parse( instance );
205                return v.isValid();
206            }
207        }
208    
209        public static String localize( String propertyName, Object[] inputFiles ) {
210            String format = java.util.ResourceBundle.getBundle(
211                "com.sun.msv.driver.textui.Messages").getString(propertyName);
212                return java.text.MessageFormat.format(format, inputFiles );
213        }
214    
215        public static String localize( String prop ) {
216            return localize(prop,null); 
217        }
218    
219        public static String localize( String prop, Object inputFile1 ) {
220            return localize(prop,new Object[]{inputFile1}); 
221        }
222    
223        public static String localize( String prop, Object inputFile1, Object inputFile2 )
224        { 
225            return localize(prop,new Object[]{inputFile1,inputFile2}); 
226        }
227            
228        public static final String MSG_VALIDATING = "Driver.Validating";
229        public static final String MSG_VALID = "Driver.Valid";
230        public static final String MSG_INVALID = "Driver.Invalid";
231        public static final String MSG_BAILOUT = "Driver.BailOut";
232    
233    }