1.1 restoration
[mir.git] / source / mir / generator / tal / CachingFileLoader.java
1 /*
2  * Copyright (C) 2001, 2002 The Mir-coders group
3  *
4  * This file is part of Mir.
5  *
6  * Mir is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * Mir is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Mir; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  * In addition, as a special exception, The Mir-coders gives permission to link
21  * the code of this program with  any library licensed under the Apache Software License,
22  * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
23  * (or with modified versions of the above that use the same license as the above),
24  * and distribute linked combinations including the two.  You must obey the
25  * GNU General Public License in all respects for all of the code used other than
26  * the above mentioned libraries.  If you modify this file, you may extend this
27  * exception to your version of the file, but you are not obligated to do so.
28  * If you do not wish to do so, delete this exception statement from your version.
29  */
30
31 package mir.generator.tal;
32
33 import java.io.BufferedInputStream;
34 import java.io.File;
35 import java.io.FileInputStream;
36 import java.io.FileNotFoundException;
37 import java.io.InputStream;
38 import java.util.ArrayList;
39 import java.util.HashMap;
40 import java.util.List;
41 import java.util.Map;
42
43 public class CachingFileLoader {
44   private Map cachedObjects;
45   private List history;
46   private int capacity;
47   private CachedFileObjectFactory factory;
48
49   public CachingFileLoader(int aCapacity, CachedFileObjectFactory aFactory) {
50     capacity = aCapacity;
51     cachedObjects = new HashMap();
52     history = new ArrayList();
53     factory = aFactory;
54   }
55
56   private void cacheObject(String aFilename, long aLastModified, Object anObject) {
57     synchronized (this) {
58       history.remove(aFilename);
59       history.add(aFilename);
60       while (history.size()>capacity && history.size()>0) {
61         history.remove(0);
62       }
63       cachedObjects.put(aFilename, new CachedObject(aFilename, aLastModified, anObject));
64     }
65   }
66
67   private Object constructObject(String aFilename) throws FileNotFoundException {
68     File file = new File(aFilename);
69     BufferedInputStream inputStream = new BufferedInputStream(
70       new FileInputStream(file), 8192);
71     try {
72       Object result = factory.constructObject(inputStream);
73       cacheObject(aFilename, file.lastModified(), result);
74
75       return result;
76     }
77     finally {
78       try {
79         inputStream.close();
80       }
81       catch (Throwable t) {
82       }
83     }
84   }
85
86   private void revatilize(String aFilename) {
87     synchronized (this) {
88       history.remove(aFilename);
89       history.add(aFilename);
90     }
91   }
92
93   private class CachedObject {
94     private String filename;
95     private long lastModified;
96     private Object object;
97
98     public CachedObject(String aFilename, long aLastModified, Object anObject) {
99       filename = aFilename;
100       lastModified = aLastModified;
101       object = anObject;
102     }
103
104     public Object getObject() {
105       return object;
106     }
107
108     public String getFilename() {
109       return filename;
110     }
111
112     public long getLastModified() {
113       return lastModified;
114     }
115   }
116
117   public Object retrieveFile(String aFilename) throws FileNotFoundException {
118     synchronized (this) {
119       if (!cachedObjects.containsKey(aFilename)) {
120         return constructObject(aFilename);
121       }
122
123       CachedObject cachedObject = (CachedObject) cachedObjects.get(aFilename);
124       File file = new File(aFilename);
125       if (file.lastModified() != cachedObject.getLastModified()) {
126         return constructObject(aFilename);
127       }
128
129       revatilize(aFilename);
130
131       return cachedObject.getObject();
132     }
133   }
134
135   public interface CachedFileObjectFactory {
136     Object constructObject(InputStream aStream);
137   }
138 }