001 package railo.runtime.helpers; 002 003 import java.io.InputStream; 004 005 import org.xml.sax.Attributes; 006 import org.xml.sax.InputSource; 007 import org.xml.sax.SAXException; 008 import org.xml.sax.SAXParseException; 009 import org.xml.sax.XMLReader; 010 import org.xml.sax.helpers.DefaultHandler; 011 012 import railo.commons.io.IOUtil; 013 import railo.commons.io.res.Resource; 014 import railo.runtime.PageContext; 015 import railo.runtime.engine.ThreadLocalPageContext; 016 import railo.runtime.exp.PageException; 017 import railo.runtime.op.Caster; 018 import railo.runtime.text.xml.XMLUtil; 019 import railo.runtime.type.Struct; 020 import railo.runtime.type.StructImpl; 021 import railo.runtime.type.UDF; 022 import railo.runtime.type.util.ArrayUtil; 023 024 025 026 /** 027 * Sax Parse with callback to CFC Methods 028 */ 029 public final class XMLEventParser extends DefaultHandler { 030 031 private UDF startDocument; 032 private UDF startElement; 033 private UDF body; 034 private UDF endElement; 035 private UDF endDocument; 036 private UDF error; 037 038 private StringBuffer sbBody; 039 private PageContext pc; 040 private Struct att; 041 /** 042 * Field <code>DEFAULT_SAX_PARSER</code> 043 */ 044 public final static String DEFAULT_SAX_PARSER="org.apache.xerces.parsers.SAXParser"; 045 046 /** 047 * constructor of the class 048 * @param pc 049 * @param startDocument 050 * @param startElement 051 * @param body 052 * @param endElement 053 * @param endDocument 054 * @param error 055 */ 056 public XMLEventParser( 057 PageContext pc, 058 UDF startDocument, 059 UDF startElement, 060 UDF body, 061 UDF endElement, 062 UDF endDocument, 063 UDF error) { 064 065 this.pc=pc; 066 this.startDocument=startDocument; 067 this.startElement=startElement; 068 this.body=body; 069 this.endElement=endElement; 070 this.endDocument=endDocument; 071 this.error=error; 072 073 } 074 075 /** 076 * start execution of the parser 077 * @param xmlFile 078 * @throws PageException 079 */ 080 public void start(Resource xmlFile) throws PageException { 081 start(xmlFile,DEFAULT_SAX_PARSER); 082 } 083 084 /** 085 * start execution of the parser 086 * @param xmlFile 087 * @param saxParserCass 088 * @throws PageException 089 */ 090 public void start(Resource xmlFile,String saxParserCass) throws PageException { 091 InputStream is=null; 092 try { 093 XMLReader xmlReader = XMLUtil.createXMLReader(saxParserCass); 094 xmlReader.setContentHandler(this); 095 xmlReader.setErrorHandler(this); 096 xmlReader.parse(new InputSource(is=IOUtil.toBufferedInputStream(xmlFile.getInputStream()))); 097 } catch (Exception e) { 098 throw Caster.toPageException(e); 099 } 100 finally { 101 IOUtil.closeEL(is); 102 } 103 104 } 105 106 @Override 107 public void characters(char[] ch, int start, int length) throws SAXException { 108 sbBody.append(ch,start,length); 109 } 110 111 @Override 112 public void error(SAXParseException e) throws SAXException { 113 error(Caster.toPageException(e)); 114 } 115 @Override 116 public void fatalError(SAXParseException e) throws SAXException { 117 error(Caster.toPageException(e)); 118 } 119 @Override 120 public void startElement(String uri, String localName, String qName, 121 Attributes attributes) throws SAXException { 122 sbBody=new StringBuffer(); 123 att = toStruct(attributes); 124 call(startElement,new Object[]{uri,localName,qName,att}); 125 } 126 127 @Override 128 public void endElement(String uri, String localName, String qName) throws SAXException { 129 call(body,new Object[]{sbBody.toString()}); 130 call(endElement,new Object[]{uri,localName,qName,att}); 131 } 132 133 @Override 134 public void startDocument() throws SAXException { 135 call(startDocument,ArrayUtil.OBJECT_EMPTY); 136 } 137 138 @Override 139 public void endDocument() throws SAXException { 140 call(endDocument,ArrayUtil.OBJECT_EMPTY); 141 } 142 143 /** 144 * call a user defined function 145 * @param udf 146 * @param arguments 147 */ 148 private void call(UDF udf, Object[] arguments) { 149 try { 150 udf.call(pc,arguments,false); 151 } catch (PageException pe) { 152 error(pe); 153 } 154 } 155 156 /** 157 * call back error function if a error occour 158 * @param pe 159 */ 160 private void error(PageException pe) { 161 try { 162 // TLPC 163 pc=ThreadLocalPageContext.get(pc); 164 error.call(pc,new Object[]{pe.getCatchBlock(pc)},false); 165 } 166 catch (PageException e) {} 167 } 168 169 /** 170 * cast a Attributes object to a Struct 171 * @param att 172 * @return Attributes as Struct 173 */ 174 private Struct toStruct(Attributes att) { 175 int len=att.getLength(); 176 Struct sct=new StructImpl(); 177 for(int i=0;i<len;i++) { 178 sct.setEL(att.getQName(i),att.getValue(i)); 179 } 180 return sct; 181 } 182 }