001 package railo.runtime.cache.eh.remote.rest.sax; 002 003 import java.io.IOException; 004 import java.io.InputStream; 005 import java.io.Reader; 006 007 import org.xml.sax.Attributes; 008 import org.xml.sax.InputSource; 009 import org.xml.sax.SAXException; 010 import org.xml.sax.XMLReader; 011 import org.xml.sax.helpers.DefaultHandler; 012 import org.xml.sax.helpers.XMLReaderFactory; 013 014 import railo.loader.util.Util; 015 016 public class CacheFactory extends DefaultHandler { 017 018 public final static String DEFAULT_SAX_PARSER="org.apache.xerces.parsers.SAXParser"; 019 020 private XMLReader xmlReader; 021 022 protected String inside; 023 protected StringBuffer content=new StringBuffer(); 024 025 private boolean insideCacheConfiguration; 026 027 private CacheConfiguration cc=new CacheConfiguration(); 028 private CacheStatistics cs=new CacheStatistics(); 029 030 private boolean insideStatistics; 031 032 //private boolean insideError; 033 //private boolean insideMessage; 034 035 036 037 /** 038 * Privater Konstruktor, der als Eingabe die TLD als File Objekt erh�lt. 039 * @param saxParser String Klassenpfad zum Sax Parser. 040 * @param file File Objekt auf die TLD. 041 * @throws IOException 042 * @throws SAXException 043 */ 044 public CacheFactory(InputStream in) throws IOException, SAXException { 045 super(); 046 init(in); 047 } 048 049 /** 050 * Generelle Initialisierungsmetode der Konstruktoren. 051 * @param saxParser String Klassenpfad zum Sax Parser. 052 * @param is InputStream auf die TLD. 053 * @throws SAXException 054 * @throws IOException 055 */ 056 protected void init(InputStream in) throws IOException, SAXException { 057 Reader r=null; 058 try { 059 InputSource is=new InputSource(in); 060 061 xmlReader=XMLReaderFactory.createXMLReader(DEFAULT_SAX_PARSER); 062 xmlReader.setContentHandler(this); 063 xmlReader.setErrorHandler(this); 064 xmlReader.parse(is); 065 066 } 067 finally { 068 Util.closeEL(r); 069 } 070 } 071 072 /** 073 * Geerbte Methode von org.xml.sax.ContentHandler, 074 * wird bei durchparsen des XML, beim Auftreten eines Start-Tag aufgerufen. 075 * 076 * @see org.xml.sax.ContentHandler#startElement(String, String, String, Attributes) 077 */ 078 public final void startElement(String uri, String name, String qName, Attributes atts) { 079 inside=qName; 080 081 if(qName.equalsIgnoreCase("cacheConfiguration")) insideCacheConfiguration=true; 082 else if(qName.equalsIgnoreCase("statistics")) insideStatistics=true; 083 084 //doStartElement(uri, name, qName, atts); 085 } 086 087 088 089 090 /** 091 * Geerbte Methode von org.xml.sax.ContentHandler, 092 * wird bei durchparsen des XML, beim auftreten eines End-Tag aufgerufen. 093 * 094 * @see org.xml.sax.ContentHandler#endElement(String, String, String) 095 */ 096 public final void endElement(String uri, String name, String qName) throws SAXException { 097 _setContent(content.toString().trim()); 098 content=new StringBuffer(); 099 inside=""; 100 101 if(qName.equalsIgnoreCase("cacheConfiguration")) insideCacheConfiguration=false; 102 else if(qName.equalsIgnoreCase("statistics")) insideStatistics=false; 103 //doEndElement(uri, name, qName); 104 } 105 106 107 108 private void _setContent(String value) throws SAXException { 109 110 /*if(insideError && insideMessage) { 111 throw new SAXException(value); 112 }*/ 113 setContent(value); 114 115 } 116 117 protected void setContent(String value) throws SAXException { 118 if(insideCacheConfiguration) { 119 if("clearOnFlush".equalsIgnoreCase(inside)) 120 cc.setClearOnFlush(toBooleanValue(value,true)); 121 else if("diskExpiryThreadIntervalSeconds".equalsIgnoreCase(inside)) 122 cc.setDiskExpiryThreadIntervalSeconds(toInt(value,0)); 123 else if("diskPersistent".equalsIgnoreCase(inside)) 124 cc.setDiskPersistent(toBooleanValue(value,false)); 125 else if("diskSpoolBufferSizeMB".equalsIgnoreCase(inside)) 126 cc.setDiskSpoolBufferSize(toInt(value,0)*1024L*1024L); 127 else if("eternal".equalsIgnoreCase(inside)) 128 cc.setEternal(toBooleanValue(value,false)); 129 else if("maxElementsInMemory".equalsIgnoreCase(inside)) 130 cc.setMaxElementsInMemory(toInt(value,0)); 131 else if("maxElementsOnDisk".equalsIgnoreCase(inside)) 132 cc.setMaxElementsOnDisk(toInt(value,0)); 133 else if("name".equalsIgnoreCase(inside)) 134 cc.setName(value); 135 else if("overflowToDisk".equalsIgnoreCase(inside)) 136 cc.setOverflowToDisk(toBooleanValue(value,true)); 137 else if("timeToIdleSeconds".equalsIgnoreCase(inside)) 138 cc.setTimeToIdleSeconds(toInt(value,0)); 139 else if("timeToLiveSeconds".equalsIgnoreCase(inside)) 140 cc.setTimeToLiveSeconds(toInt(value,0)); 141 } 142 else if(insideStatistics){ 143 if("averageGetTime".equalsIgnoreCase(inside)) 144 cs.setAverageGetTime(toDoubleValue(value,0)); 145 else if("cacheHits".equalsIgnoreCase(inside)) 146 cs.setCacheHits(toInt(value,0)); 147 else if("diskStoreSize".equalsIgnoreCase(inside)) 148 cs.setDiskStoreSize(toInt(value,0)); 149 else if("evictionCount".equalsIgnoreCase(inside)) 150 cs.setEvictionCount(toInt(value,0)); 151 else if("inMemoryHits".equalsIgnoreCase(inside)) 152 cs.setInMemoryHits(toInt(value,0)); 153 else if("memoryStoreSize".equalsIgnoreCase(inside)) 154 cs.setMemoryStoreSize(toInt(value,0)); 155 else if("misses".equalsIgnoreCase(inside)) 156 cs.setMisses(toInt(value,0)); 157 else if("onDiskHits".equalsIgnoreCase(inside)) 158 cs.setOnDiskHits(toInt(value,0)); 159 else if("size".equalsIgnoreCase(inside)) 160 cs.setSize(toInt(value,0)); 161 else if("statisticsAccuracy".equalsIgnoreCase(inside)) 162 cs.setStatisticsAccuracy(value); 163 } 164 else{ 165 //System.err.println(inside+":"+value); 166 } 167 } 168 169 170 /** 171 * Geerbte Methode von org.xml.sax.ContentHandler, 172 * wird bei durchparsen des XML, zum einlesen des Content eines Body Element aufgerufen. 173 * 174 * @see org.xml.sax.ContentHandler#characters(char[], int, int) 175 */ 176 public void characters (char ch[], int start, int length) { 177 content.append(new String(ch,start,length)); 178 } 179 180 181 182 /** 183 * @return the cc 184 */ 185 public CacheConfiguration getCacheConfiguration() { 186 return cc; 187 } 188 189 private boolean toBooleanValue(String str, boolean defaultValue) { 190 str=str.trim().toLowerCase(); 191 if("true".equalsIgnoreCase(str)) return true; 192 else if("false".equalsIgnoreCase(str)) return false; 193 return defaultValue; 194 } 195 196 197 private double toDoubleValue(String str, int defaultValue) { 198 try{ 199 return Double.parseDouble(str); 200 } 201 catch(Throwable t){ 202 return defaultValue; 203 } 204 } 205 private int toInt(String str, int defaultValue) { 206 try{ 207 return Integer.parseInt(str); 208 } 209 catch(Throwable t){ 210 return defaultValue; 211 } 212 } 213 214 public CacheMeta getMeta() { 215 return new CacheMeta(cc,cs); 216 } 217 }