package railo.runtime.cache.eh.remote.rest.sax;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import railo.loader.util.Util;
import railo.runtime.text.xml.XMLUtil;
public class CacheFactory extends DefaultHandler {
public final static String DEFAULT_SAX_PARSER="org.apache.xerces.parsers.SAXParser";
private XMLReader xmlReader;
protected String inside;
protected StringBuffer content=new StringBuffer();
private boolean insideCacheConfiguration;
private CacheConfiguration cc=new CacheConfiguration();
private CacheStatistics cs=new CacheStatistics();
private boolean insideStatistics;
//private boolean insideError;
//private boolean insideMessage;
/**
* Privater Konstruktor, der als Eingabe die TLD als File Objekt erhaelt.
* @param saxParser String Klassenpfad zum Sax Parser.
* @param file File Objekt auf die TLD.
* @throws IOException
* @throws SAXException
*/
public CacheFactory(InputStream in) throws IOException, SAXException {
super();
init(in);
}
/**
* Generelle Initialisierungsmetode der Konstruktoren.
* @param saxParser String Klassenpfad zum Sax Parser.
* @param is InputStream auf die TLD.
* @throws SAXException
* @throws IOException
*/
protected void init(InputStream in) throws IOException, SAXException {
Reader r=null;
try {
InputSource is=new InputSource(in);
xmlReader=XMLUtil.createXMLReader(DEFAULT_SAX_PARSER);
xmlReader.setContentHandler(this);
xmlReader.setErrorHandler(this);
xmlReader.parse(is);
}
finally {
Util.closeEL(r);
}
}
@Override
public final void startElement(String uri, String name, String qName, Attributes atts) {
inside=qName;
if(qName.equalsIgnoreCase("cacheConfiguration")) insideCacheConfiguration=true;
else if(qName.equalsIgnoreCase("statistics")) insideStatistics=true;
//doStartElement(uri, name, qName, atts);
}
@Override
public final void endElement(String uri, String name, String qName) throws SAXException {
_setContent(content.toString().trim());
content=new StringBuffer();
inside="";
if(qName.equalsIgnoreCase("cacheConfiguration")) insideCacheConfiguration=false;
else if(qName.equalsIgnoreCase("statistics")) insideStatistics=false;
//doEndElement(uri, name, qName);
}
private void _setContent(String value) {
/*if(insideError && insideMessage) {
throw new SAXException(value);
}*/
setContent(value);
}
protected void setContent(String value) {
if(insideCacheConfiguration) {
if("clearOnFlush".equalsIgnoreCase(inside))
cc.setClearOnFlush(toBooleanValue(value,true));
else if("diskExpiryThreadIntervalSeconds".equalsIgnoreCase(inside))
cc.setDiskExpiryThreadIntervalSeconds(toInt(value,0));
else if("diskPersistent".equalsIgnoreCase(inside))
cc.setDiskPersistent(toBooleanValue(value,false));
else if("diskSpoolBufferSizeMB".equalsIgnoreCase(inside))
cc.setDiskSpoolBufferSize(toInt(value,0)*1024L*1024L);
else if("eternal".equalsIgnoreCase(inside))
cc.setEternal(toBooleanValue(value,false));
else if("maxElementsInMemory".equalsIgnoreCase(inside))
cc.setMaxElementsInMemory(toInt(value,0));
else if("maxElementsOnDisk".equalsIgnoreCase(inside))
cc.setMaxElementsOnDisk(toInt(value,0));
else if("name".equalsIgnoreCase(inside))
cc.setName(value);
else if("overflowToDisk".equalsIgnoreCase(inside))
cc.setOverflowToDisk(toBooleanValue(value,true));
else if("timeToIdleSeconds".equalsIgnoreCase(inside))
cc.setTimeToIdleSeconds(toInt(value,0));
else if("timeToLiveSeconds".equalsIgnoreCase(inside))
cc.setTimeToLiveSeconds(toInt(value,0));
}
else if(insideStatistics){
if("averageGetTime".equalsIgnoreCase(inside))
cs.setAverageGetTime(toDoubleValue(value,0));
else if("cacheHits".equalsIgnoreCase(inside))
cs.setCacheHits(toInt(value,0));
else if("diskStoreSize".equalsIgnoreCase(inside))
cs.setDiskStoreSize(toInt(value,0));
else if("evictionCount".equalsIgnoreCase(inside))
cs.setEvictionCount(toInt(value,0));
else if("inMemoryHits".equalsIgnoreCase(inside))
cs.setInMemoryHits(toInt(value,0));
else if("memoryStoreSize".equalsIgnoreCase(inside))
cs.setMemoryStoreSize(toInt(value,0));
else if("misses".equalsIgnoreCase(inside))
cs.setMisses(toInt(value,0));
else if("onDiskHits".equalsIgnoreCase(inside))
cs.setOnDiskHits(toInt(value,0));
else if("size".equalsIgnoreCase(inside))
cs.setSize(toInt(value,0));
else if("statisticsAccuracy".equalsIgnoreCase(inside))
cs.setStatisticsAccuracy(value);
}
else{
//System.err.println(inside+":"+value);
}
}
@Override
public void characters (char ch[], int start, int length) {
content.append(new String(ch,start,length));
}
/**
* @return the cc
*/
public CacheConfiguration getCacheConfiguration() {
return cc;
}
private boolean toBooleanValue(String str, boolean defaultValue) {
str=str.trim().toLowerCase();
if("true".equalsIgnoreCase(str)) return true;
else if("false".equalsIgnoreCase(str)) return false;
return defaultValue;
}
private double toDoubleValue(String str, int defaultValue) {
try{
return Double.parseDouble(str);
}
catch(Throwable t){
return defaultValue;
}
}
private int toInt(String str, int defaultValue) {
try{
return Integer.parseInt(str);
}
catch(Throwable t){
return defaultValue;
}
}
public CacheMeta getMeta() {
return new CacheMeta(cc,cs);
}
}