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}