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 }