Source Code Cross Referenced for Element.java in  » Cache » ehcache » net » sf » ehcache » 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 » Cache » ehcache » net.sf.ehcache 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /**
002:         *  Copyright 2003-2007 Luck Consulting Pty Ltd
003:         *
004:         *  Licensed under the Apache License, Version 2.0 (the "License");
005:         *  you may not use this file except in compliance with the License.
006:         *  You may obtain a copy of the License at
007:         *
008:         *      http://www.apache.org/licenses/LICENSE-2.0
009:         *
010:         *  Unless required by applicable law or agreed to in writing, software
011:         *  distributed under the License is distributed on an "AS IS" BASIS,
012:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013:         *  See the License for the specific language governing permissions and
014:         *  limitations under the License.
015:         */package net.sf.ehcache;
016:
017:        import org.apache.commons.logging.Log;
018:        import org.apache.commons.logging.LogFactory;
019:
020:        import java.io.ByteArrayInputStream;
021:        import java.io.ByteArrayOutputStream;
022:        import java.io.IOException;
023:        import java.io.ObjectInputStream;
024:        import java.io.ObjectOutputStream;
025:        import java.io.Serializable;
026:
027:        /**
028:         * A Cache Element, consisting of a key, value and attributes.
029:         * <p/>
030:         * From ehcache-1.2, Elements can have keys and values that are Serializable or Objects. To preserve backward
031:         * compatibility, special accessor methods for Object keys and values are provided: {@link #getObjectKey()} and
032:         * {@link #getObjectValue()}. If placing Objects in ehcache, developers must use the new getObject... methods to
033:         * avoid CacheExceptions. The get... methods are reserved for Serializable keys and values.
034:         *
035:         * @author Greg Luck
036:         * @version $Id: Element.java 525 2007-07-31 22:41:54Z gregluck $
037:         * @noinspection SerializableHasSerializationMethods
038:         */
039:        public final class Element implements  Serializable, Cloneable {
040:            /**
041:             * serial version
042:             * Updated for version 1.2 and again for 1.2.1
043:             */
044:            private static final long serialVersionUID = 3343087714201120157L;
045:
046:            private static final Log LOG = LogFactory.getLog(Element.class
047:                    .getName());
048:
049:            private static final long ONE_SECOND = 1000L;
050:
051:            /**
052:             * the cache key.
053:             */
054:            private final Object key;
055:
056:            /**
057:             * the value.
058:             */
059:            private Object value;
060:
061:            /**
062:             * version of the element. System.currentTimeMillis() is used to compute version for updated elements. That
063:             * way, the actual version of the updated element does not need to be checked.
064:             */
065:            private long version;
066:
067:            /**
068:             * The creation time.
069:             */
070:            private long creationTime;
071:
072:            /**
073:             * The last access time.
074:             */
075:            private long lastAccessTime;
076:
077:            /**
078:             * The next to last access time. Used by the expiry mechanism
079:             */
080:            private long nextToLastAccessTime;
081:
082:            /**
083:             * The number of times the element was hit.
084:             */
085:            private long hitCount;
086:
087:            /**
088:             * The amount of time for the element to live, in seconds. 0 indicates unlimited.
089:             */
090:            private int timeToLive;
091:
092:            /**
093:             * The amount of time for the element to idle, in seconds. 0 indicates unlimited.
094:             */
095:            private int timeToIdle;
096:
097:            /**
098:             * If there is an Element in the Cache and it is replaced with a new Element for the same key,
099:             * then both the version number and lastUpdateTime should be updated to reflect that. The creation time
100:             * will be the creation time of the new Element, not the original one, so that TTL concepts still work.
101:             */
102:            private long lastUpdateTime;
103:
104:            /**
105:             * Whether the element is eternal, i.e. never expires.
106:             */
107:            private boolean eternal;
108:
109:            /**
110:             * Whether any combination of eternal, TTL or TTI has been set.
111:             */
112:            private boolean lifespanSet;
113:
114:            /**
115:             * A full constructor.
116:             * <p/>
117:             * Creation time is set to the current time. Last Access Time and Previous To Last Access Time
118:             * are not set.
119:             *
120:             * @since .4
121:             */
122:            public Element(Serializable key, Serializable value, long version) {
123:                this ((Object) key, (Object) value, version);
124:
125:            }
126:
127:            /**
128:             * A full constructor.
129:             * <p/>
130:             * Creation time is set to the current time. Last Access Time and Previous To Last Access Time
131:             * are not set.
132:             *
133:             * @since 1.2
134:             */
135:            public Element(Object key, Object value, long version) {
136:                this .key = key;
137:                this .value = value;
138:                this .version = version;
139:                creationTime = System.currentTimeMillis();
140:                hitCount = 0;
141:            }
142:
143:            /**
144:             * A full constructor.
145:             *
146:             * @since 1.3
147:             */
148:            public Element(Object key, Object value, long version,
149:                    long creationTime, long lastAccessTime,
150:                    long nextToLastAccessTime, long lastUpdateTime,
151:                    long hitCount) {
152:                this .key = key;
153:                this .value = value;
154:                this .version = version;
155:                this .creationTime = creationTime;
156:                this .lastAccessTime = lastAccessTime;
157:                this .nextToLastAccessTime = nextToLastAccessTime;
158:                this .lastUpdateTime = lastUpdateTime;
159:                this .hitCount = hitCount;
160:            }
161:
162:            /**
163:             * Constructor.
164:             *
165:             * @param key
166:             * @param value
167:             */
168:            public Element(Serializable key, Serializable value) {
169:                this ((Object) key, (Object) value, 1L);
170:            }
171:
172:            /**
173:             * Constructor.
174:             *
175:             * @param key
176:             * @param value
177:             * @since 1.2
178:             */
179:            public Element(Object key, Object value) {
180:                this (key, value, 1L);
181:            }
182:
183:            /**
184:             * Gets the key attribute of the Element object.
185:             *
186:             * @return The key value. If the key is not Serializable, null is returned and an info log message emitted
187:             * @see #getObjectKey()
188:             */
189:            public final Serializable getKey() {
190:                Serializable keyAsSerializable;
191:                try {
192:                    keyAsSerializable = (Serializable) key;
193:                } catch (Exception e) {
194:                    throw new CacheException(
195:                            "The key "
196:                                    + key
197:                                    + " is not Serializable. Consider using Element#getObjectKey()");
198:                }
199:                return keyAsSerializable;
200:            }
201:
202:            /**
203:             * Gets the key attribute of the Element object.
204:             * <p/>
205:             * This method is provided for those wishing to use ehcache as a memory only cache
206:             * and enables retrieval of non-Serializable values from elements.
207:             *
208:             * @return The key as an Object. i.e no restriction is placed on it
209:             * @see #getKey()
210:             */
211:            public final Object getObjectKey() {
212:                return key;
213:            }
214:
215:            /**
216:             * Gets the value attribute of the Element object.
217:             *
218:             * @return The value which must be Serializable. If not use {@link #getObjectValue}. If the value is not Serializable, null is returned and an info log message emitted
219:             * @see #getObjectValue()
220:             */
221:            public final Serializable getValue() {
222:                Serializable valueAsSerializable;
223:                try {
224:                    valueAsSerializable = (Serializable) value;
225:                } catch (Exception e) {
226:                    throw new CacheException(
227:                            "The value "
228:                                    + value
229:                                    + " for key "
230:                                    + key
231:                                    + " is not Serializable. Consider using Element#getObjectKey()");
232:                }
233:                return valueAsSerializable;
234:            }
235:
236:            /**
237:             * Gets the value attribute of the Element object as an Object.
238:             * <p/>
239:             * This method is provided for those wishing to use ehcache as a memory only cache
240:             * and enables retrieval of non-Serializable values from elements.
241:             *
242:             * @return The value as an Object.  i.e no restriction is placed on it
243:             * @see #getValue()
244:             * @since 1.2
245:             */
246:            public final Object getObjectValue() {
247:                return value;
248:            }
249:
250:            /**
251:             * Equals comparison with another element, based on the key.
252:             */
253:            public final boolean equals(Object object) {
254:                if (object == null || !(object instanceof  Element)) {
255:                    return false;
256:                }
257:
258:                Element element = (Element) object;
259:                if (key == null || element.getObjectKey() == null) {
260:                    return false;
261:                }
262:
263:                return key.equals(element.getObjectKey());
264:            }
265:
266:            /**
267:             * Sets time to Live
268:             *
269:             * @param timeToLiveSeconds the number of seconds to live
270:             */
271:            public void setTimeToLive(int timeToLiveSeconds) {
272:                this .timeToLive = timeToLiveSeconds;
273:                lifespanSet = true;
274:            }
275:
276:            /**
277:             * Sets time to idle
278:             *
279:             * @param timeToIdleSeconds the number of seconds to idle
280:             */
281:            public void setTimeToIdle(int timeToIdleSeconds) {
282:                this .timeToIdle = timeToIdleSeconds;
283:                lifespanSet = true;
284:            }
285:
286:            /**
287:             * Gets the hascode, based on the key.
288:             */
289:            public final int hashCode() {
290:                return key.hashCode();
291:            }
292:
293:            /**
294:             * Sets the version attribute of the ElementAttributes object.
295:             *
296:             * @param version The new version value
297:             */
298:            public final void setVersion(long version) {
299:                this .version = version;
300:            }
301:
302:            /**
303:             * Gets the creationTime attribute of the ElementAttributes object.
304:             *
305:             * @return The creationTime value
306:             */
307:            public final long getCreationTime() {
308:                return creationTime;
309:            }
310:
311:            /**
312:             * Sets the creationTime attribute of the ElementAttributes object.
313:             */
314:            public final void setCreateTime() {
315:                creationTime = System.currentTimeMillis();
316:            }
317:
318:            /**
319:             * Gets the version attribute of the ElementAttributes object.
320:             *
321:             * @return The version value
322:             */
323:            public final long getVersion() {
324:                return version;
325:            }
326:
327:            /**
328:             * Gets the last access time.
329:             * Access means a get. So a newly created {@link Element}
330:             * will have a last access time equal to its create time.
331:             */
332:            public final long getLastAccessTime() {
333:                return lastAccessTime;
334:            }
335:
336:            /**
337:             * Gets the next to last access time.
338:             *
339:             * @see #getLastAccessTime()
340:             */
341:            public final long getNextToLastAccessTime() {
342:                return nextToLastAccessTime;
343:            }
344:
345:            /**
346:             * Gets the hit count on this element.
347:             */
348:            public final long getHitCount() {
349:                return hitCount;
350:            }
351:
352:            /**
353:             * Resets the hit count to 0 and the last access time to 0.
354:             */
355:            public final void resetAccessStatistics() {
356:                lastAccessTime = 0;
357:                nextToLastAccessTime = 0;
358:                hitCount = 0;
359:            }
360:
361:            /**
362:             * Sets the last access time to now.
363:             */
364:            public final void updateAccessStatistics() {
365:                nextToLastAccessTime = lastAccessTime;
366:                lastAccessTime = System.currentTimeMillis();
367:                hitCount++;
368:            }
369:
370:            /**
371:             * Sets the last access time to now.
372:             */
373:            public final void updateUpdateStatistics() {
374:                lastUpdateTime = System.currentTimeMillis();
375:                version = lastUpdateTime;
376:            }
377:
378:            /**
379:             * Returns a {@link String} representation of the {@link Element}.
380:             */
381:            public final String toString() {
382:                StringBuffer sb = new StringBuffer();
383:
384:                sb.append("[ key = ").append(key).append(", value=").append(
385:                        value).append(", version=").append(version).append(
386:                        ", hitCount=").append(hitCount).append(
387:                        ", CreationTime = ").append(this .getCreationTime())
388:                        .append(", LastAccessTime = ").append(
389:                                this .getLastAccessTime()).append(" ]");
390:
391:                return sb.toString();
392:            }
393:
394:            /**
395:             * Clones an Element. A completely new object is created, with no common references with the
396:             * existing one.
397:             * <p/>
398:             * This method will not work unless the Object is Serializable
399:             * <p/>
400:             * Warning: This can be very slow on large object graphs. If you use this method
401:             * you should write a performance test to verify suitability.
402:             *
403:             * @return a new {@link Element}, with exactly the same field values as the one it was cloned from.
404:             * @throws CloneNotSupportedException
405:             */
406:            public final Object clone() throws CloneNotSupportedException {
407:                //Not used. Just to get code inspectors to shut up
408:                super .clone();
409:
410:                Element element = new Element(deepCopy(key), deepCopy(value),
411:                        version);
412:                element.creationTime = creationTime;
413:                element.lastAccessTime = lastAccessTime;
414:                element.nextToLastAccessTime = nextToLastAccessTime;
415:                element.hitCount = hitCount;
416:                return element;
417:            }
418:
419:            private Object deepCopy(Object oldValue) {
420:                Serializable newValue = null;
421:                ByteArrayOutputStream bout = new ByteArrayOutputStream();
422:                ObjectOutputStream oos = null;
423:                ObjectInputStream ois = null;
424:                try {
425:                    oos = new ObjectOutputStream(bout);
426:                    oos.writeObject(oldValue);
427:                    ByteArrayInputStream bin = new ByteArrayInputStream(bout
428:                            .toByteArray());
429:                    ois = new ObjectInputStream(bin);
430:                    newValue = (Serializable) ois.readObject();
431:                } catch (IOException e) {
432:                    LOG
433:                            .error("Error cloning Element with key "
434:                                    + key
435:                                    + " during serialization and deserialization of value");
436:                } catch (ClassNotFoundException e) {
437:                    LOG
438:                            .error("Error cloning Element with key "
439:                                    + key
440:                                    + " during serialization and deserialization of value");
441:                } finally {
442:                    try {
443:                        if (oos != null) {
444:                            oos.close();
445:                        }
446:                        if (ois != null) {
447:                            ois.close();
448:                        }
449:                    } catch (Exception e) {
450:                        LOG.error("Error closing Stream");
451:                    }
452:                }
453:                return newValue;
454:            }
455:
456:            /**
457:             * The size of this object in serialized form. This is not the same
458:             * thing as the memory size, which is JVM dependent. Relative values should be meaningful,
459:             * however.
460:             * <p/>
461:             * Warning: This method can be <b>very slow</b> for values which contain large object graphs.
462:             * <p/>
463:             * If the key or value of the Element is not Serializable, an error will be logged and 0 will be returned.
464:             * @return The serialized size in bytes
465:             */
466:            public final long getSerializedSize() {
467:
468:                if (!isSerializable()) {
469:                    return 0;
470:                }
471:                long size = 0;
472:                ByteArrayOutputStream bout = new ByteArrayOutputStream();
473:                ObjectOutputStream oos = null;
474:                try {
475:                    oos = new ObjectOutputStream(bout);
476:                    oos.writeObject(this );
477:                    size = bout.size();
478:                    return size;
479:                } catch (IOException e) {
480:                    LOG
481:                            .debug("Error measuring element size for element with key "
482:                                    + key + ". Cause was: " + e.getMessage());
483:                } finally {
484:                    try {
485:                        if (oos != null) {
486:                            oos.close();
487:                        }
488:                    } catch (Exception e) {
489:                        LOG.error("Error closing ObjectOutputStream");
490:                    }
491:                }
492:
493:                return size;
494:            }
495:
496:            /**
497:             * Whether the element may be Serialized.
498:             * <p/>
499:             * While Element implements Serializable, it is possible to create non Serializable elements
500:             * for use in MemoryStores. This method checks that an instance of Element really is Serializable
501:             * and will not throw a NonSerializableException if Serialized.
502:             *
503:             * @return true if the element is Serializable
504:             * @since 1.2
505:             */
506:            public final boolean isSerializable() {
507:                return key instanceof  Serializable
508:                        && value instanceof  Serializable;
509:            }
510:
511:            /**
512:             * Whether the element's key may be Serialized.
513:             * <p/>
514:             * While Element implements Serializable, it is possible to create non Serializable elements and/or
515:             * non Serializable keys for use in MemoryStores.
516:             * <p/>
517:             * This method checks that an instance of an Element's key really is Serializable
518:             * and will not throw a NonSerializableException if Serialized.
519:             *
520:             * @return true if the element's key is Serializable
521:             * @since 1.2
522:             */
523:            public final boolean isKeySerializable() {
524:                return key instanceof  Serializable;
525:            }
526:
527:            /**
528:             * If there is an Element in the Cache and it is replaced with a new Element for the same key,
529:             * then both the version number and lastUpdateTime should be updated to reflect that. The creation time
530:             * will be the creation time of the new Element, not the original one, so that TTL concepts still work.
531:             *
532:             * @return the time when the last update occured. If this is the original Element, the time will be null
533:             */
534:            public long getLastUpdateTime() {
535:                return lastUpdateTime;
536:            }
537:
538:            /**
539:             * An element is expired if the expiration time as given by {@link #getExpirationTime()} is in the past.
540:             *
541:             * @return true if the Element is expired, otherwise false. If no lifespan has been set for the Element it is
542:             *         considered not able to expire.
543:             * @see #getExpirationTime()
544:             */
545:            public boolean isExpired() {
546:                if (!lifespanSet) {
547:                    return false;
548:                }
549:
550:                long now = System.currentTimeMillis();
551:                long expirationTime = getExpirationTime();
552:
553:                return now > expirationTime;
554:            }
555:
556:            /**
557:             * Returns the expiration time based on time to live. If this element also has a time to idle setting, the expiry
558:             * time will vary depending on whether the element is accessed.
559:             *
560:             * @return the time to expiration
561:             */
562:            public long getExpirationTime() {
563:
564:                if (!lifespanSet || eternal
565:                        || (timeToLive == 0 && timeToIdle == 0)) {
566:                    return Long.MAX_VALUE;
567:                }
568:
569:                long expirationTime = 0;
570:                long ttlExpiry = creationTime + timeToLive * ONE_SECOND;
571:
572:                long mostRecentTime = Math.max(creationTime,
573:                        nextToLastAccessTime);
574:                long ttiExpiry = mostRecentTime + timeToIdle * ONE_SECOND;
575:
576:                if (timeToLive != 0 && (timeToIdle == 0 || lastAccessTime == 0)) {
577:                    expirationTime = ttlExpiry;
578:                } else if (timeToLive == 0) {
579:                    expirationTime = ttiExpiry;
580:                } else {
581:                    expirationTime = Math.min(ttlExpiry, ttiExpiry);
582:                }
583:                return expirationTime;
584:            }
585:
586:            /**
587:             * @return true if the element is eternal
588:             */
589:            public boolean isEternal() {
590:                return eternal;
591:            }
592:
593:            /**
594:             * Sets whether the element is eternal.
595:             *
596:             * @param eternal
597:             */
598:            public void setEternal(boolean eternal) {
599:                this .eternal = eternal;
600:                lifespanSet = true;
601:            }
602:
603:            /**
604:             * Whether any combination of eternal, TTL or TTI has been set.
605:             *
606:             * @return true if set.
607:             */
608:            public boolean isLifespanSet() {
609:                return lifespanSet;
610:            }
611:
612:            /**
613:             * @return the time to live, in seconds
614:             */
615:            public int getTimeToLive() {
616:                return timeToLive;
617:            }
618:
619:            /**
620:             * @return the time to idle, in seconds
621:             */
622:            public int getTimeToIdle() {
623:                return timeToIdle;
624:            }
625:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.