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 import org.xml.sax.helpers.XMLReaderFactory; 012 013 import railo.commons.io.IOUtil; 014 import railo.commons.io.res.Resource; 015 import railo.runtime.PageContext; 016 import railo.runtime.engine.ThreadLocalPageContext; 017 import railo.runtime.exp.PageException; 018 import railo.runtime.op.Caster; 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 = XMLReaderFactory.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 /** 107 * @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int) 108 */ 109 public void characters(char[] ch, int start, int length) throws SAXException { 110 sbBody.append(ch,start,length); 111 } 112 113 /** 114 * @see org.xml.sax.ErrorHandler#error(org.xml.sax.SAXParseException) 115 */ 116 public void error(SAXParseException e) throws SAXException { 117 error(Caster.toPageException(e)); 118 } 119 /** 120 * @see org.xml.sax.ErrorHandler#fatalError(org.xml.sax.SAXParseException) 121 */ 122 public void fatalError(SAXParseException e) throws SAXException { 123 error(Caster.toPageException(e)); 124 } 125 /** 126 * @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes) 127 */ 128 public void startElement(String uri, String localName, String qName, 129 Attributes attributes) throws SAXException { 130 sbBody=new StringBuffer(); 131 att = toStruct(attributes); 132 call(startElement,new Object[]{uri,localName,qName,att}); 133 } 134 135 /** 136 * @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, java.lang.String) 137 */ 138 public void endElement(String uri, String localName, String qName) throws SAXException { 139 call(body,new Object[]{sbBody.toString()}); 140 call(endElement,new Object[]{uri,localName,qName,att}); 141 } 142 143 /** 144 * @see org.xml.sax.helpers.DefaultHandler#startDocument() 145 */ 146 public void startDocument() throws SAXException { 147 call(startDocument,ArrayUtil.OBJECT_EMPTY); 148 } 149 150 /** 151 * @see org.xml.sax.helpers.DefaultHandler#endDocument() 152 */ 153 public void endDocument() throws SAXException { 154 call(endDocument,ArrayUtil.OBJECT_EMPTY); 155 } 156 157 /** 158 * call a user defined function 159 * @param udf 160 * @param arguments 161 */ 162 private void call(UDF udf, Object[] arguments) { 163 try { 164 udf.call(pc,arguments,false); 165 } catch (PageException pe) { 166 error(pe); 167 } 168 } 169 170 /** 171 * call back error function if a error occour 172 * @param pe 173 */ 174 private void error(PageException pe) { 175 try { 176 // TLPC 177 pc=ThreadLocalPageContext.get(pc); 178 error.call(pc,new Object[]{pe.getCatchBlock(pc)},false); 179 } 180 catch (PageException e) {} 181 } 182 183 /** 184 * cast a Attributes object to a Struct 185 * @param att 186 * @return Attributes as Struct 187 */ 188 private Struct toStruct(Attributes att) { 189 int len=att.getLength(); 190 Struct sct=new StructImpl(); 191 for(int i=0;i<len;i++) { 192 sct.setEL(att.getQName(i),att.getValue(i)); 193 } 194 return sct; 195 } 196 }