001    package railo.runtime.text.xml;
002    
003    import java.io.IOException;
004    
005    import org.xml.sax.InputSource;
006    import org.xml.sax.SAXException;
007    import org.xml.sax.SAXParseException;
008    import org.xml.sax.XMLReader;
009    import org.xml.sax.helpers.XMLReaderFactory;
010    
011    import railo.commons.lang.StringUtil;
012    import railo.runtime.exp.XMLException;
013    import railo.runtime.op.Caster;
014    import railo.runtime.type.Array;
015    import railo.runtime.type.ArrayImpl;
016    import railo.runtime.type.Struct;
017    import railo.runtime.type.StructImpl;
018    
019    
020    
021    public class XMLValidator extends XMLEntityResolverDefaultHandler {
022    
023            /**
024             * @see railo.runtime.text.xml.XMLEntityResolverDefaultHandler#resolveEntity(java.lang.String, java.lang.String)
025             */
026            public InputSource resolveEntity(String publicID, String systemID)
027                            throws SAXException {
028                    //print.out(publicID+":"+systemID);
029                    return super.resolveEntity(publicID, systemID);
030            }
031    
032            private Array warnings;
033            private Array errors;
034            private Array fatals;
035            private boolean hasErrors;
036            private String strSchema;
037    
038            public XMLValidator(InputSource validator, String strSchema) {
039                    super(validator);
040                    this.strSchema=strSchema;
041            }
042            
043    
044            private void release() {
045                    warnings=null;
046                    errors=null;
047                    fatals=null;
048                    hasErrors=false;
049            }
050            
051        /**
052         * @see org.xml.sax.helpers.DefaultHandler#warning(org.xml.sax.SAXParseException)
053         */
054        public void warning(SAXParseException spe)  {
055            log(spe,"Warning",warnings);
056        }
057            
058            /**
059             * @see org.xml.sax.helpers.DefaultHandler#error(org.xml.sax.SAXParseException)
060             */
061            public void error(SAXParseException spe) {
062                    hasErrors=true;
063            log(spe,"Error",errors);
064        }
065    
066        /**
067         * @see org.xml.sax.helpers.DefaultHandler#fatalError(org.xml.sax.SAXParseException)
068         */
069        public void fatalError(SAXParseException spe) throws SAXException   {
070                    hasErrors=true;
071            log(spe,"Fatal Error",fatals);
072        }
073        
074        private void log(SAXParseException spe, String type,Array array)    {
075            StringBuffer sb = new StringBuffer("["+type+"] ");
076            
077            String id = spe.getSystemId();
078            if(!StringUtil.isEmpty(id)) {
079                    int li=id.lastIndexOf('/');
080                    if(li!=-1)sb.append(id.substring(li+1));
081                    else sb.append(id);
082            }
083            sb.append(':');
084            sb.append(spe.getLineNumber());
085            sb.append(':');
086            sb.append(spe.getColumnNumber());
087            sb.append(": ");
088            sb.append(spe.getMessage());
089            sb.append(" ");
090            array.appendEL(sb.toString());
091        }
092        
093            public Struct validate(InputSource xml) throws XMLException {
094                    warnings=new ArrayImpl();
095                    errors=new ArrayImpl();
096                    fatals=new ArrayImpl();
097                    
098                    try {
099                XMLReader parser = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser");
100                parser.setContentHandler(this);
101                parser.setErrorHandler(this);
102                parser.setEntityResolver(this);
103                parser.setFeature("http://xml.org/sax/features/validation", true);
104                parser.setFeature("http://apache.org/xml/features/validation/schema", true);
105                parser.setFeature("http://apache.org/xml/features/validation/schema-full-checking", true);
106                //if(!validateNamespace)
107                if(!StringUtil.isEmpty(strSchema))
108                    parser.setProperty("http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation", strSchema);
109                parser.parse(xml);
110            }
111            catch(SAXException e) { }
112            catch(IOException e){
113                    
114                    throw new XMLException(e.getMessage());
115            }
116            
117            // result
118            Struct result = new StructImpl();
119            result.setEL("warnings", warnings);
120            result.setEL("errors", errors);
121            result.setEL("fatalerrors", fatals);
122            result.setEL("status", Caster.toBoolean(!hasErrors));
123            release();
124            return result;
125            }
126    
127    }