source: MDService2/trunk/MDService2/src/eu/clarin/cmdi/mdservice/action/Cache.java @ 655

Last change on this file since 655 was 655, checked in by vronk, 14 years ago

renamed document_counter to cacheindex_doc in Cache + added its path to .properties. added collection2htmlpage-view.

File size: 12.1 KB
Line 
1package eu.clarin.cmdi.mdservice.action;
2
3import java.io.*;
4import java.net.MalformedURLException;
5import java.net.URL;
6/*import java.io.BufferedWriter;
7import java.io.File;
8import java.io.FileInputStream;
9import java.io.FileNotFoundException;
10import java.io.FileReader;
11import java.io.FileWriter;
12import java.io.IOException;
13import java.io.InputStream;
14import java.io.Writer;
15*/
16import java.util.Date;
17import java.text.DateFormat;
18import java.text.SimpleDateFormat;
19import java.util.Calendar;
20 
21import javax.xml.*;
22import javax.xml.parsers.*;
23import javax.xml.transform.*;
24import javax.xml.transform.sax.*;
25import javax.xml.transform.stream.*;import javax.xml.transform.dom.*;
26import javax.xml.xpath.*;
27
28import org.w3c.dom.*;
29import org.xml.sax.SAXException;
30import org.xml.sax.InputSource;
31
32
33import eu.clarin.cmdi.mdservice.action.Admin;
34import eu.clarin.cmdi.mdservice.model.Query;
35
36/**
37 * This is a rudimentary caching mechanism.
38 * serializes the inputstream to a file (identifier => filename)
39 * and returns the inpustream based on the identifier
40 * @author master
41 *
42 */
43/* TODO: necessary to maintain own index
44 * for resolution of IDs to filenames
45 */
46
47
48public class Cache {
49        public static String PREFIX = "xc_";
50       
51        private static Cache singleton;
52        private String cachepath; 
53        private String cacheindex_path;
54        private static Integer cachecounter;
55        private static final Integer start_cache = 1;
56       
57        private static Document cacheindex_doc;
58       
59        public Cache () {               
60                cachepath = Admin.getConfig().getProperty("cache.path");
61                cacheindex_path = cachepath + Admin.getConfig().getProperty("cacheindex.file");
62                cachecounter = initCachecounter();
63        }
64       
65        public static Cache getCache() {
66                if (singleton == null) {
67                        singleton = new Cache();
68                } 
69                return singleton;
70        }
71
72        protected void finalize() throws Throwable {       
73            try {               
74                updateCachecounter();
75            } catch(Exception e) {
76            }       
77            finally {           
78                super.finalize();
79                //more code can be written here as per need of application             
80            }
81        }
82       
83        /**
84         * here the external key for the data gets cache-internal counter-id assigned
85         * which is also returned back
86         * can be used (as shorthand instead of the (long) external key) from outside to retrieve the data.
87         * This is primarily meant to be able to reuse the recordset-data, when reading one record. 
88         * @param id
89         * @param instream
90         * @return
91         */
92        public String putInCache(String key_info, InputStream instream) {
93
94                Admin.notifyUser("CACHE.putInCache:"+key_info);
95                Integer c = getCounter();
96                String xc;
97               
98               
99                //update xml_structure
100                Element e = cacheindex_doc.createElement("f");
101                //Attr attr = cacheindex_doc.createAttribute("id");
102                //attr.setValue(c.toString());
103                //e.setNamedItem(attr);
104                e.setAttribute("id", c.toString());
105                String[] key_array = key_info.split("-");
106               
107                e.setAttribute("type", key_array[0]);
108                if (key_array.length > 1){
109                        String query_str;
110                        if (key_array[0].equals("recordset")){
111                                query_str = transformQuery(key_array[1]);
112                        } else {
113                                query_str = key_array[1];
114                        }
115                        e.setAttribute("query", query_str);
116                }else{
117                        e.setAttribute("query", "");
118                }
119                if (key_array.length > 2){
120                        e.setAttribute("collection", key_array[2]);
121                }else{
122                        e.setAttribute("collection", "");
123                }
124
125                DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd:hh-mm-ss");
126                e.setAttribute("date", dateFormat.format(new Date()).toString());
127                cacheindex_doc.getFirstChild().appendChild(e);
128               
129                // update XML-counter
130            //Admin.writeToFile(formPath(id + xc),instream);
131               
132                updateCachecounter();
133               
134                xc = PREFIX + key_array[0] + "_" + c.toString();
135                Admin.notifyUser("CACHE.putInCache.filename:" + xc + ".xml");
136                Admin.writeToFile(cachepath + xc + ".xml",instream);
137               
138            return xc;
139        }
140       
141       
142        public InputStream getFromCache(String key_info) {
143                   
144               
145                   File f = new File (formPath(key_info));
146                   Admin.notifyUser("CACHE.getFromCache:"+key_info);
147                   
148                    if (f.exists()) { // read from file to InputStream;
149                        Admin.notifyUser("CACHE.getFromCache.fromfile:"+f.getName());
150                        InputStream instream;
151                                try {
152                                        instream = new FileInputStream(f); 
153
154                                        return instream;
155                                } catch (FileNotFoundException e) {
156                                        // TODO Auto-generated catch block
157                                        e.printStackTrace();
158                                        return null;
159                                }
160                       
161                    } else { //not cached, my dear
162                        Admin.notifyUser("CACHE.getFromCache: NOT CACHED");
163                        return null;
164                    }       
165        }
166 
167        private String transformQuery (String str) {
168                String transformed;
169                Query query;
170               
171                query = new Query(str,"recordset","");
172                if (query.isStatus(Query.PARSEERROR)) {
173                        Admin.notifyUser("Cache.transformQuery.PARSEERROR:" + query.getMsg());
174                        // pass this bad news to the client
175                        //setUserMsg(query.getMsg());
176                        transformed = "";
177                } else {
178                        try {
179                                transformed =  query.toURLParam();
180                                transformed = transformed.replace("'", "__qqqqq__");
181                                //Admin.notifyUser("CACHE.transformQuery:"+transformed);
182                        } catch (MalformedURLException e) {
183                                // TODO Auto-generated catch block
184                                e.printStackTrace();
185                                transformed = "";
186                        }
187                }
188                return transformed;
189        }
190       
191         //TODO: sanitize-key
192        public String formPath (String key_info) {
193                String id="";
194                String path="";
195                String xpath_expr="";
196               
197                String[] key_array = key_info.split("-");
198                String query_str;
199               
200                if(key_array.length > 1){
201                        if (key_array[0].equals("recordset")){
202                                query_str = transformQuery(key_array[1]);       
203                        }
204                        else {
205                                query_str = key_array[1];
206                        }
207                } else {
208                        query_str = "";
209                }
210                xpath_expr = "//index/f[@type='" + key_array[0] + "'";
211                xpath_expr = xpath_expr + " and @query='"+query_str+"'";
212               
213                if (key_array.length > 2){
214                        xpath_expr = xpath_expr + "and @collection='"+key_array[2]+"']";
215                }else{
216                        xpath_expr = xpath_expr + " and @collection='']";
217                }
218               
219                //Admin.notifyUser("formPath:xpath:"+xpath_expr);
220                //creating an XPathFactory:
221        XPathFactory factory = XPathFactory.newInstance();
222        //using this factory to create an XPath object:
223        XPath xpath = factory.newXPath();
224        //XPath object created compiles the XPath expression:
225        XPathExpression expr;
226                try {
227                        expr = xpath.compile(xpath_expr);
228                        //expression is evaluated with respect to a certain context node which is doc.
229                Object result = expr.evaluate(cacheindex_doc, XPathConstants.NODESET);
230                NodeList list = (NodeList) result;
231                if (list.getLength() > 0) {
232                        id = list.item(0).getAttributes().getNamedItem("id").getNodeValue();
233                        path = cachepath + PREFIX + key_array[0] + "_"+id + ".xml";
234                }  else if (list.getLength() > 1){
235                        //Admin.notifyUser("formPath:!!!:multiple paths:"+key_info);
236                       
237                }
238               
239                } catch (XPathExpressionException e) {
240                        // TODO Auto-generated catch block
241                        e.printStackTrace();
242                }
243               
244            return path;
245        }
246       
247        public Integer getCounter () {
248                cachecounter = cachecounter +1 ;
249                return cachecounter;
250        }
251       
252        /**
253         * read counter-integer from file in cache
254         * or start that file
255         * @return
256         */
257        public Integer initCachecounter() {
258               
259                Integer counter = start_cache;
260                boolean init=false;
261                String fname = cacheindex_path;
262                File f = new File (fname);
263               
264                //Admin.notifyUser("initCacheCounter");
265                if (!f.exists()) {
266                                // create new  counter document
267                                DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
268                        DocumentBuilder docBuilder;
269                                try {
270                                        docBuilder = docFactory.newDocumentBuilder();
271                                        cacheindex_doc = docBuilder.newDocument();
272                                        // append root tag <index >
273                                        Element root = (Element) cacheindex_doc.createElement("index");
274                                        root.setAttribute("idcounter", "1");
275                                        cacheindex_doc.appendChild(root);
276                                        writeCachecounter(counter);
277                                       
278                                        //Admin.notifyUser("new document");
279                                } catch (ParserConfigurationException e) {
280                                        // TODO Auto-generated catch block
281                                        e.printStackTrace();
282                                }
283                               
284                        //} catch (IOException e2) {
285                        //      Admin.notifyUser("ERROR creating cache counter");
286                        //      e2.printStackTrace();
287                        //}
288            }
289                else {
290                        try {
291                               
292                        DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
293                        DocumentBuilder docBuilder;
294                                try {
295                                        docBuilder = docFactory.newDocumentBuilder();               
296                                        try {
297                                                        cacheindex_doc = docBuilder.parse(fname);
298                                        } catch (SAXException e) {
299                                                        // TODO Auto-generated catch block
300                                                       
301                                                        e.printStackTrace();
302                                        }
303                                } catch (ParserConfigurationException e) {
304                                                // TODO Auto-generated catch block
305                                                e.printStackTrace();
306                                }
307                               
308                         //read counter
309                         counter = new Integer(cacheindex_doc.getFirstChild().getAttributes().getNamedItem("idcounter").getNodeValue());
310                         init = true;
311                    }  catch (IOException ex){
312                        //Admin.notifyUser("initCacheCounter:" + ex.toString());
313                        ex.printStackTrace();
314                    }
315                }
316               
317            return counter;
318            /*
319              //use buffering, reading one line at a time
320              //FileReader always assumes default encoding is OK!
321                BufferedReader input =  new BufferedReader(new FileReader(f));
322                        try {
323                                String line = null; //not declared within while loop
324                        /*
325                        * readLine is a bit quirky :
326                        * it returns the content of a line MINUS the newline.
327                        * it returns null only for the END of the stream.
328                        * it returns an empty String if two newlines appear in a row.
329                        *
330                        try {
331                                        if (( line = input.readLine()) != null){
332                                                try {
333                                                        counter = new Integer(line);
334                                                } catch (NumberFormatException e) {
335                                                // if not a number, write a number
336                                                        init=true;     
337                                                } 
338                                        } else {
339                                                init=true;
340                                        }
341                                } catch (IOException e) {
342                                        init=true;
343                                }
344                       
345                        if (init) {                                                     
346                            writeCachecounter( start_cache);                                   
347                        }
348                       
349                } finally {
350                input.close();
351             }   
352             */         
353        }
354
355        public void updateCachecounter () {
356            writeCachecounter( cachecounter);
357        }
358        public void writeCachecounter (Integer i) {             
359               
360                // first update <index idcounter>
361                cacheindex_doc.getFirstChild().getAttributes().getNamedItem("idcounter").setNodeValue(i.toString());
362               
363                //Admin.notifyUser("writeCacheCounter:" + i.toString());
364                // write xml
365                Transformer transformer;
366                try {
367                        transformer = TransformerFactory.newInstance().newTransformer();
368                        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
369
370                        //initialize StreamResult with File object to save to file
371                        StreamResult result = new StreamResult(new StringWriter());
372                        DOMSource source = new DOMSource(cacheindex_doc);
373                        try {
374                                transformer.transform(source, result);
375                        } catch (TransformerException e1) {
376                                // TODO Auto-generated catch block
377                                e1.printStackTrace();
378                        }
379
380                        String xmlString = result.getWriter().toString();
381                        //Admin.notifyUser("writeCacheCounter:" + xmlString);
382                        //Admin.writeToFile("", result);
383
384
385                        File f = new File (cacheindex_path);
386                        FileWriter fw;
387                        try {
388                                fw = new FileWriter(f);
389                                try {
390                                        fw.write(xmlString);
391                                        fw.close();
392                                } catch (IOException e) {
393                                        // TODO Auto-generated catch block
394                                        e.printStackTrace();
395                                }       
396                        } catch (IOException e) {
397                                // TODO Auto-generated catch block
398                                e.printStackTrace();
399                        }
400                } catch (TransformerConfigurationException e2) {
401                        // TODO Auto-generated catch block
402                        e2.printStackTrace();
403                } catch (TransformerFactoryConfigurationError e2) {
404                        // TODO Auto-generated catch block
405                        e2.printStackTrace();
406                }
407               
408                       
409
410                /*
411                File f = new File (Admin.getConfig().getProperty("cache.path") + "counter.txt");
412           
413                try {
414                        Writer output = new BufferedWriter(new FileWriter(f));         
415              //FileWriter always assumes default encoding is OK!
416                        try {
417                                output.write( i);
418                        } finally {
419                                output.close();
420                        }       
421                } catch (IOException e) {
422                        // TODO Auto-generated catch block
423                        e.printStackTrace();
424                }
425                */
426        }
427}
Note: See TracBrowser for help on using the repository browser.