Source Code Cross Referenced for CacheItem.java in  » Content-Management-System » riotfamily » org » riotfamily » cachius » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Content Management System » riotfamily » org.riotfamily.cachius 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* ***** BEGIN LICENSE BLOCK *****
002:         * Version: MPL 1.1
003:         * The contents of this file are subject to the Mozilla Public License Version
004:         * 1.1 (the "License"); you may not use this file except in compliance with
005:         * the License. You may obtain a copy of the License at
006:         * http://www.mozilla.org/MPL/
007:         * 
008:         * Software distributed under the License is distributed on an "AS IS" basis,
009:         * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
010:         * for the specific language governing rights and limitations under the
011:         * License.
012:         * 
013:         * The Original Code is Riot.
014:         * 
015:         * The Initial Developer of the Original Code is
016:         * Neteye GmbH.
017:         * Portions created by the Initial Developer are Copyright (C) 2006
018:         * the Initial Developer. All Rights Reserved.
019:         * 
020:         * Contributor(s):
021:         *   Felix Gnass [fgnass at neteye dot de]
022:         * 
023:         * ***** END LICENSE BLOCK ***** */
024:        package org.riotfamily.cachius;
025:
026:        import java.io.BufferedInputStream;
027:        import java.io.BufferedReader;
028:        import java.io.File;
029:        import java.io.FileInputStream;
030:        import java.io.FileNotFoundException;
031:        import java.io.FileOutputStream;
032:        import java.io.IOException;
033:        import java.io.InputStream;
034:        import java.io.InputStreamReader;
035:        import java.io.ObjectInputStream;
036:        import java.io.OutputStream;
037:        import java.io.OutputStreamWriter;
038:        import java.io.Reader;
039:        import java.io.Serializable;
040:        import java.io.UnsupportedEncodingException;
041:        import java.io.Writer;
042:        import java.util.Map;
043:        import java.util.Set;
044:        import java.util.zip.GZIPOutputStream;
045:
046:        import javax.servlet.http.HttpServletResponse;
047:
048:        import org.apache.commons.logging.Log;
049:        import org.apache.commons.logging.LogFactory;
050:        import org.riotfamily.cachius.support.Cookies;
051:        import org.riotfamily.cachius.support.Headers;
052:        import org.riotfamily.cachius.support.ReaderWriterLock;
053:        import org.riotfamily.cachius.support.TokenFilterWriter;
054:        import org.riotfamily.common.io.IOUtils;
055:        import org.springframework.util.FileCopyUtils;
056:
057:        /**
058:         * Representation of cached item that is backed by a file. The captured 
059:         * HTTP headers are kept in memory and are serialized by the default java 
060:         * serialization mechanism. The actual content is read from a file to avoid 
061:         * the overhead of object deserialization on each request.
062:         * <br>
063:         * If URL rewriting is used to track the session, the sessionId is
064:         * replaced by a special token in the cache file. When such an item is
065:         * send to a client, the token is replaced with the current sessionId.
066:         * <br>
067:         * If the sessionId comes from a cookie or the controller outputs binary data,
068:         * a direct stream copy is performed instead of using Readers/Writers to 
069:         * improve performance.
070:         *
071:         * @author Felix Gnass
072:         */
073:        class CacheItem implements  Serializable {
074:
075:            private static final String ITEM_PREFIX = "item";
076:
077:            private static final String ITEM_SUFFIX = "";
078:
079:            private static final long NOT_YET = -1L;
080:
081:            private static final String FILE_ENCODING = "UTF-8";
082:
083:            private Log log = LogFactory.getLog(CacheItem.class);
084:
085:            /** The key used for lookups */
086:            private String key;
087:
088:            /** Set of tags to categorize the item */
089:            private Set tags;
090:
091:            /** Flag indicating whether session IDs are filtered */
092:            private boolean filterSessionId;
093:
094:            /** The file containing the actual data */
095:            private File file;
096:
097:            /** The Content-Type of the cached data */
098:            private String contentType;
099:
100:            /** Captured HTTP headers that will be sent */
101:            private Headers headers;
102:
103:            /** Captured cookies that will be sent */
104:            private Cookies cookies;
105:
106:            /** Map with extra properties */
107:            private Map properties;
108:
109:            /** Flag indicating whether the content is binary or character data */
110:            private boolean binary = true;
111:
112:            /** 
113:             * Reader/writer lock to prevent concurrent threads from updating
114:             * the cached content while others are reading.
115:             */
116:            private transient ReaderWriterLock lock = new ReaderWriterLock();
117:
118:            /** Time of the last usage */
119:            private long lastUsed;
120:
121:            /** Time of the last modification */
122:            private long lastModified;
123:
124:            /** Time of the last up-to-date check */
125:            private long lastCheck;
126:
127:            /** Whether to set Content-Length header or not */
128:            private boolean setContentLength;
129:
130:            /**
131:             * Creates a new CacheItem with the given key in the specified directory.
132:             */
133:            protected CacheItem(String key, File cacheDir) throws IOException {
134:                this .key = key;
135:                file = File.createTempFile(ITEM_PREFIX, ITEM_SUFFIX, cacheDir);
136:                lastModified = NOT_YET;
137:            }
138:
139:            /**
140:             * Returns the key.
141:             */
142:            protected String getKey() {
143:                return key;
144:            }
145:
146:            /**
147:             * Sets tags which can be used to look up the item for invalidation.
148:             */
149:            protected void setTags(Set tags) {
150:                this .tags = tags;
151:            }
152:
153:            /**
154:             * Returns the item's tags.
155:             */
156:            public Set getTags() {
157:                return this .tags;
158:            }
159:
160:            /**
161:             * Returns whether the item is new. An item is considered as new if the
162:             * {@link #getLastModified() lastModified} timestamp is set to 
163:             * {@value #NOT_YET}.  
164:             */
165:            protected boolean isNew() {
166:                return lastModified == NOT_YET;
167:            }
168:
169:            /**
170:             * Sets the lastUsed timestamp to the current time.
171:             */
172:            protected void touch() {
173:                this .lastUsed = System.currentTimeMillis();
174:            }
175:
176:            /**
177:             * Returns the last usage time.
178:             */
179:            public long getLastUsed() {
180:                return this .lastUsed;
181:            }
182:
183:            /**
184:             * Returns the last modification time.
185:             */
186:            protected long getLastModified() {
187:                return lastModified;
188:            }
189:
190:            /**
191:             * Sets the last modification time.
192:             */
193:            protected void setLastModified(long lastModified) {
194:                this .lastModified = lastModified;
195:            }
196:
197:            /**
198:             * Invalidates the item by setting the {@link #setLastModified(long) 
199:             * lastModified} timestamp to {@value #NOT_YET}.
200:             */
201:            protected void invalidate() {
202:                lastModified = NOT_YET;
203:            }
204:
205:            /**
206:             * Returns the time when the last up-to-date check was performed.
207:             */
208:            protected long getLastCheck() {
209:                return this .lastCheck;
210:            }
211:
212:            /**
213:             * Sets the time of the last up-to-date check.
214:             */
215:            protected void setLastCheck(long lastCheck) {
216:                this .lastCheck = lastCheck;
217:            }
218:
219:            /**
220:             * Checks whether the cache file exists an is a regular file.
221:             */
222:            protected boolean exists() {
223:                return file != null && file.isFile();
224:            }
225:
226:            /**
227:             * Returns the size of the cached data in bytes.
228:             */
229:            protected int getSize() {
230:                return file != null ? (int) file.length() : 0;
231:            }
232:
233:            /**
234:             * Sets the Content-Type.
235:             */
236:            protected void setContentType(String contentType) {
237:                this .contentType = contentType;
238:            }
239:
240:            /**
241:             * Sets whether a Content-Length header should be set.
242:             */
243:            public void setSetContentLength(boolean setContentLength) {
244:                this .setContentLength = setContentLength;
245:            }
246:
247:            /**
248:             * Sets HTTP headers. 
249:             */
250:            protected void setHeaders(Headers headers) {
251:                this .headers = headers;
252:            }
253:
254:            /**
255:             * Sets cookies.
256:             */
257:            protected void setCookies(Cookies cookies) {
258:                this .cookies = cookies;
259:            }
260:
261:            /**
262:             * Sets shared properties.
263:             * @see org.riotfamily.common.web.collaboration.SharedProperties
264:             */
265:            protected void setProperties(Map properties) {
266:                this .properties = properties;
267:            }
268:
269:            /**
270:             * Returns the properties.
271:             */
272:            public Map getProperties() {
273:                return properties;
274:            }
275:
276:            /**
277:             * Returns the lock. 
278:             */
279:            protected ReaderWriterLock getLock() {
280:                return this .lock;
281:            }
282:
283:            /**
284:             * Sets whether to filter jsessionid tokens.
285:             */
286:            protected void setFilterSessionId(boolean filterSessionId) {
287:                this .filterSessionId = filterSessionId;
288:            }
289:
290:            protected Writer getWriter(String sessionId)
291:                    throws UnsupportedEncodingException, FileNotFoundException {
292:
293:                binary = false;
294:                Writer writer = new OutputStreamWriter(getOutputStream(),
295:                        FILE_ENCODING);
296:                if (filterSessionId) {
297:                    writer = new TokenFilterWriter(sessionId, "${jsessionid}",
298:                            writer);
299:                }
300:                return writer;
301:            }
302:
303:            protected OutputStream getOutputStream()
304:                    throws FileNotFoundException {
305:                return new FileOutputStream(file);
306:            }
307:
308:            protected void gzipContent() throws IOException {
309:                InputStream in = new BufferedInputStream(new FileInputStream(
310:                        file));
311:                File zipFile = new File(file.getParentFile(), file.getName()
312:                        + ".gz");
313:                OutputStream out = new GZIPOutputStream(new FileOutputStream(
314:                        zipFile));
315:                FileCopyUtils.copy(in, out);
316:                binary = true;
317:                file.delete();
318:                zipFile.renameTo(file);
319:            }
320:
321:            protected void writeTo(HttpServletResponse response,
322:                    String sessionId) throws IOException {
323:
324:                try {
325:                    if (contentType != null) {
326:                        response.setContentType(contentType);
327:                    }
328:                    if (headers != null) {
329:                        headers.addToResponse(response);
330:                    }
331:                    if (cookies != null) {
332:                        cookies.addToResponse(response);
333:                    }
334:                    int contentLength = getSize();
335:                    if (contentLength > 0) {
336:                        if (setContentLength) {
337:                            response.setContentLength(contentLength);
338:                        }
339:                        if (binary) {
340:                            InputStream in = new BufferedInputStream(
341:                                    new FileInputStream(file));
342:
343:                            IOUtils.copy(in, response.getOutputStream());
344:                        } else {
345:                            Reader in = new BufferedReader(
346:                                    new InputStreamReader(new FileInputStream(
347:                                            file), FILE_ENCODING));
348:
349:                            Writer out = response.getWriter();
350:                            if (filterSessionId) {
351:                                out = new TokenFilterWriter("${jsessionid}",
352:                                        sessionId, out);
353:                            }
354:
355:                            IOUtils.copy(in, out);
356:                        }
357:                    }
358:                } catch (FileNotFoundException e) {
359:                    log
360:                            .warn("Cache file not found. Invalidating item to trigger "
361:                                    + "an update on the next request.");
362:
363:                    invalidate();
364:                }
365:            }
366:
367:            protected void delete() {
368:                try {
369:                    lock.lockForWriting();
370:                    if (file.exists()) {
371:                        if (!file.delete()) {
372:                            log.warn("Failed to delete cache file: " + file);
373:                        }
374:                    }
375:                } finally {
376:                    lock.releaseWriterLock();
377:                }
378:            }
379:
380:            /**
381:             * Calls <code>in.defaultReadObject()</code> and creates a new lock.
382:             */
383:            private void readObject(ObjectInputStream in) throws IOException,
384:                    ClassNotFoundException {
385:
386:                in.defaultReadObject();
387:                lock = new ReaderWriterLock();
388:            }
389:
390:            public int hashCode() {
391:                return key.hashCode();
392:            }
393:
394:            public boolean equals(Object obj) {
395:                if (obj == this ) {
396:                    return true;
397:                }
398:                if (obj instanceof  CacheItem) {
399:                    CacheItem other = (CacheItem) obj;
400:                    return key.equals(other.key);
401:                }
402:                return false;
403:            }
404:
405:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.