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