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