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    }