001/** 002 * 003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. 004 * 005 * This library is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU Lesser General Public 007 * License as published by the Free Software Foundation; either 008 * version 2.1 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public 016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 017 * 018 **/ 019package lucee.runtime.text.xml; 020 021import java.io.IOException; 022 023import lucee.commons.lang.StringUtil; 024import lucee.runtime.exp.XMLException; 025import lucee.runtime.op.Caster; 026import lucee.runtime.type.Array; 027import lucee.runtime.type.ArrayImpl; 028import lucee.runtime.type.Struct; 029import lucee.runtime.type.StructImpl; 030 031import org.xml.sax.InputSource; 032import org.xml.sax.SAXException; 033import org.xml.sax.SAXParseException; 034import org.xml.sax.XMLReader; 035 036 037 038public class XMLValidator extends XMLEntityResolverDefaultHandler { 039 040 @Override 041 public InputSource resolveEntity(String publicID, String systemID) 042 throws SAXException { 043 //print.out(publicID+":"+systemID); 044 return super.resolveEntity(publicID, systemID); 045 } 046 047 private Array warnings; 048 private Array errors; 049 private Array fatals; 050 private boolean hasErrors; 051 private String strSchema; 052 053 public XMLValidator(InputSource validator, String strSchema) { 054 super(validator); 055 this.strSchema=strSchema; 056 } 057 058 059 private void release() { 060 warnings=null; 061 errors=null; 062 fatals=null; 063 hasErrors=false; 064 } 065 066 @Override 067 public void warning(SAXParseException spe) { 068 log(spe,"Warning",warnings); 069 } 070 071 @Override 072 public void error(SAXParseException spe) { 073 hasErrors=true; 074 log(spe,"Error",errors); 075 } 076 077 @Override 078 public void fatalError(SAXParseException spe) throws SAXException { 079 hasErrors=true; 080 log(spe,"Fatal Error",fatals); 081 } 082 083 private void log(SAXParseException spe, String type,Array array) { 084 StringBuffer sb = new StringBuffer("["+type+"] "); 085 086 String id = spe.getSystemId(); 087 if(!StringUtil.isEmpty(id)) { 088 int li=id.lastIndexOf('/'); 089 if(li!=-1)sb.append(id.substring(li+1)); 090 else sb.append(id); 091 } 092 sb.append(':'); 093 sb.append(spe.getLineNumber()); 094 sb.append(':'); 095 sb.append(spe.getColumnNumber()); 096 sb.append(": "); 097 sb.append(spe.getMessage()); 098 sb.append(" "); 099 array.appendEL(sb.toString()); 100 } 101 102 public Struct validate(InputSource xml) throws XMLException { 103 warnings=new ArrayImpl(); 104 errors=new ArrayImpl(); 105 fatals=new ArrayImpl(); 106 107 try { 108 XMLReader parser = XMLUtil.createXMLReader("org.apache.xerces.parsers.SAXParser"); 109 parser.setContentHandler(this); 110 parser.setErrorHandler(this); 111 parser.setEntityResolver(this); 112 parser.setFeature("http://xml.org/sax/features/validation", true); 113 parser.setFeature("http://apache.org/xml/features/validation/schema", true); 114 parser.setFeature("http://apache.org/xml/features/validation/schema-full-checking", true); 115 //if(!validateNamespace) 116 if(!StringUtil.isEmpty(strSchema)) 117 parser.setProperty("http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation", strSchema); 118 parser.parse(xml); 119 } 120 catch(SAXException e) { } 121 catch(IOException e){ 122 123 throw new XMLException(e.getMessage()); 124 } 125 126 // result 127 Struct result = new StructImpl(); 128 result.setEL("warnings", warnings); 129 result.setEL("errors", errors); 130 result.setEL("fatalerrors", fatals); 131 result.setEL("status", Caster.toBoolean(!hasErrors)); 132 release(); 133 return result; 134 } 135 136}