Source Code Cross Referenced for HashMapTC.java in  » Net » Terracotta » java » util » 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 » Net » Terracotta » java.util 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003:         * notice. All rights reserved.
004:         */
005:        package java.util;
006:
007:        import com.tc.object.ObjectID;
008:        import com.tc.object.SerializationUtil;
009:        import com.tc.object.TCObject;
010:        import com.tc.object.bytecode.Clearable;
011:        import com.tc.object.bytecode.Manageable;
012:        import com.tc.object.bytecode.ManagerUtil;
013:        import com.tc.object.bytecode.TCMap;
014:        import com.tc.object.bytecode.hook.impl.Util;
015:        import com.tc.util.Assert;
016:
017:        /*
018:         * This class will be merged with java.lang.HashMap in the bootjar. This HashMap can store ObjectIDs instead of Objects
019:         * to save memory and transparently fault Objects as needed. It can also clear references.
020:         */
021:        public class HashMapTC extends HashMap implements  TCMap, Manageable,
022:                Clearable {
023:
024:            // General Rules to follow in this class
025:            // 1) Values could be ObjectIDs. In shared mode, always do a lookup before returning to outside world.
026:            // 2) If you do a lookup, try to store back the actual object into the Map if the key is available.
027:            // 3) Be careful about existing iterators. It shouldn't throw exception because of (2)
028:            // 4) When you do so, call markAccessed() to make the cache eviction correct
029:            // 5) Check write access before any shared changed
030:            // 6) Call logical Invoke before changing internal state so that NonPortableExceptions don't modify state.
031:            //
032:
033:            // TODO:: markAccessed()
034:            private volatile transient TCObject $__tc_MANAGED;
035:            private boolean evictionEnabled = true;
036:
037:            public void clear() {
038:                if (__tc_isManaged()) {
039:                    synchronized (__tc_managed().getResolveLock()) {
040:                        ManagerUtil.checkWriteAccess(this );
041:                        ManagerUtil.logicalInvoke(this ,
042:                                SerializationUtil.CLEAR_SIGNATURE,
043:                                new Object[0]);
044:                        super .clear();
045:                    }
046:                } else {
047:                    super .clear();
048:                }
049:            }
050:
051:            public boolean containsKey(Object key) {
052:                // XXX:: Keys can't be ObjectIDs as of Now.
053:                if (__tc_isManaged()) {
054:                    synchronized (__tc_managed().getResolveLock()) {
055:                        // Just to have proper memory boundary
056:                        return super .containsKey(key);
057:                    }
058:                } else {
059:                    return super .containsKey(key);
060:                }
061:            }
062:
063:            /*
064:             * This method is overridden in LinkedHashMap. so any change here needs to be propagated to LinkedHashMap too.
065:             */
066:            public boolean containsValue(Object value) {
067:                if (__tc_isManaged()) {
068:                    synchronized (__tc_managed().getResolveLock()) {
069:                        if (value != null) {
070:                            // XXX:: This is tied closely to HashMap implementation which calls equals on the passed value rather than the
071:                            // other way around
072:                            return super .containsValue(new ValueWrapper(value));
073:                        } else {
074:                            // It is a little weird to do this like this, o well...
075:                            return super .containsValue(value)
076:                                    || super .containsValue(ObjectID.NULL_ID);
077:                        }
078:                    }
079:                } else {
080:                    return super .containsValue(value);
081:                }
082:            }
083:
084:            // XXX: This uses entrySet iterator and since we fix that, this should work.
085:            public boolean equals(Object o) {
086:                return super .equals(o);
087:            }
088:
089:            /*
090:             * This method is overridden in LinkedHashMapTC. so any change here needs to be propagated to LinkedHashMapTC too.
091:             * XXX:: This method uses getEntry instead of a get and put to avoid changing the modCount in shared mode
092:             */
093:            public Object get(Object key) {
094:                if (__tc_isManaged()) {
095:                    synchronized (__tc_managed().getResolveLock()) {
096:                        Map.Entry e = getEntry(key);
097:                        return lookUpAndStoreIfNecessary(e);
098:                    }
099:                } else {
100:                    return super .get(key);
101:                }
102:            }
103:
104:            private Object lookUpAndStoreIfNecessary(Map.Entry e) {
105:                if (e == null)
106:                    return null;
107:                Object value = e.getValue();
108:                if (value instanceof  ObjectID) {
109:                    Object newVal = ManagerUtil.lookupObject((ObjectID) value);
110:                    e.setValue(newVal);
111:                    return newVal;
112:                }
113:                return value;
114:            }
115:
116:            private static Object lookUpIfNecessary(Object o) {
117:                if (o instanceof  ObjectID) {
118:                    return ManagerUtil.lookupObject((ObjectID) o);
119:                }
120:                return o;
121:            }
122:
123:            private Object lookUpFaultBreadthIfNecessary(Object o) {
124:                if (o instanceof  ObjectID) {
125:                    return ManagerUtil.lookupObjectWithParentContext(
126:                            (ObjectID) o, __tc_managed().getObjectID());
127:                }
128:                return o;
129:            }
130:
131:            // XXX: This uses entrySet iterator and since we fix that, this should work.
132:            public int hashCode() {
133:                return super .hashCode();
134:            }
135:
136:            public boolean isEmpty() {
137:                if (__tc_isManaged()) {
138:                    synchronized (__tc_managed().getResolveLock()) {
139:                        // Just to have proper memory boundary
140:                        return super .isEmpty();
141:                    }
142:                } else {
143:                    return super .isEmpty();
144:                }
145:            }
146:
147:            public void putAll(Map map) {
148:                super .putAll(map);
149:            }
150:
151:            public Object remove(Object key) {
152:                if (__tc_isManaged()) {
153:                    // Managed Version
154:                    synchronized (__tc_managed().getResolveLock()) {
155:                        ManagerUtil.checkWriteAccess(this );
156:
157:                        Entry entry = removeEntryForKey(key);
158:                        if (entry == null) {
159:                            return null;
160:                        }
161:
162:                        ManagerUtil
163:                                .logicalInvoke(
164:                                        this ,
165:                                        SerializationUtil.REMOVE_ENTRY_FOR_KEY_SIGNATURE,
166:                                        new Object[] { entry.getKey() });
167:
168:                        return lookUpIfNecessary(entry.getValue());
169:                    }
170:                } else {
171:                    return super .remove(key);
172:                }
173:            }
174:
175:            /**
176:             * This method is only to be invoked from the applicator thread. This method does not need to check if the map is
177:             * managed as it will always be managed when called by the applicator thread. In addition, this method does not need
178:             * to be synchronized under getResolveLock() as the applicator thread is already under the scope of such
179:             * synchronization.
180:             */
181:            public void __tc_applicator_remove(Object key) {
182:                super .remove(key);
183:            }
184:
185:            /**
186:             * This method is to be invoked when one needs a remove to get broadcast, but do not want to fault in the value of a
187:             * map entry.
188:             */
189:            public void __tc_remove_logical(Object key) {
190:                if (__tc_isManaged()) {
191:                    // Managed Version
192:                    synchronized (__tc_managed().getResolveLock()) {
193:                        ManagerUtil.checkWriteAccess(this );
194:
195:                        ManagerUtil.checkWriteAccess(this );
196:
197:                        Entry entry = removeEntryForKey(key);
198:                        if (entry == null) {
199:                            return;
200:                        }
201:
202:                        ManagerUtil
203:                                .logicalInvoke(
204:                                        this ,
205:                                        SerializationUtil.REMOVE_ENTRY_FOR_KEY_SIGNATURE,
206:                                        new Object[] { entry.getKey() });
207:
208:                        return;
209:                    }
210:                } else {
211:                    super .remove(key);
212:                }
213:            }
214:
215:            public Collection __tc_getAllEntriesSnapshot() {
216:                if (__tc_isManaged()) {
217:                    synchronized (__tc_managed().getResolveLock()) {
218:                        return __tc_getAllEntriesSnapshotInternal();
219:                    }
220:                } else {
221:                    return __tc_getAllEntriesSnapshotInternal();
222:                }
223:            }
224:
225:            public synchronized Collection __tc_getAllEntriesSnapshotInternal() {
226:                Set entrySet = super .entrySet();
227:                return new ArrayList(entrySet);
228:            }
229:
230:            public Collection __tc_getAllLocalEntriesSnapshot() {
231:                if (__tc_isManaged()) {
232:                    synchronized (__tc_managed().getResolveLock()) {
233:                        return __tc_getAllLocalEntriesSnapshotInternal();
234:                    }
235:                } else {
236:                    return __tc_getAllLocalEntriesSnapshotInternal();
237:                }
238:            }
239:
240:            private Collection __tc_getAllLocalEntriesSnapshotInternal() {
241:                Set entrySet = super .entrySet();
242:                int entrySetSize = entrySet.size();
243:                if (entrySetSize == 0) {
244:                    return Collections.EMPTY_LIST;
245:                }
246:
247:                Object[] tmp = new Object[entrySetSize];
248:                int index = -1;
249:                for (Iterator i = entrySet.iterator(); i.hasNext();) {
250:                    Map.Entry e = (Map.Entry) i.next();
251:                    if (!(e.getValue() instanceof  ObjectID)) {
252:                        index++;
253:                        tmp[index] = e;
254:                    }
255:                }
256:
257:                if (index < 0) {
258:                    return Collections.EMPTY_LIST;
259:                }
260:                Object[] rv = new Object[index + 1];
261:                System.arraycopy(tmp, 0, rv, 0, index + 1);
262:                return Arrays.asList(rv);
263:            }
264:
265:            public Object clone() {
266:                Manageable clone = (Manageable) super .clone();
267:                return Util.fixTCObjectReferenceOfClonedObject(this , clone);
268:            }
269:
270:            /*
271:             * This method needs to call logicalInvoke before modifying the local state to avoid inconsistency when throwing
272:             * NonPortableExceptions TODO:: provide special method for the applicator
273:             */
274:            public Object put(Object key, Object value) {
275:                if (__tc_isManaged()) {
276:                    synchronized (__tc_managed().getResolveLock()) {
277:                        ManagerUtil.checkWriteAccess(this );
278:                        // It sucks todo two lookups
279:                        HashMap.Entry e = getEntry(key);
280:                        if (e == null) {
281:                            // New mapping
282:                            ManagerUtil.logicalInvoke(this ,
283:                                    SerializationUtil.PUT_SIGNATURE,
284:                                    new Object[] { key, value });
285:                            return lookUpIfNecessary(super .put(key, value));
286:                        } else {
287:                            // without this, LinkedHashMap will not function properly
288:                            e.recordAccess(this );
289:
290:                            // Replacing old mapping
291:                            Object old = lookUpIfNecessary(e.getValue());
292:                            if (value != old) {
293:                                ManagerUtil.logicalInvoke(this ,
294:                                        SerializationUtil.PUT_SIGNATURE,
295:                                        new Object[] { e.getKey(), value });
296:                                e.setValue(value);
297:                            }
298:                            return old;
299:                        }
300:                    }
301:                } else {
302:                    return super .put(key, value);
303:                }
304:            }
305:
306:            /**
307:             * This method is only to be invoked from the applicator thread. This method does not need to check if the map is
308:             * managed as it will always be managed when called by the applicator thread. In addition, this method does not need
309:             * to be synchronized under getResolveLock() as the applicator thread is already under the scope of such
310:             * synchronization.
311:             */
312:            public void __tc_applicator_put(Object key, Object value) {
313:                super .put(key, value);
314:            }
315:
316:            public int size() {
317:                if (__tc_isManaged()) {
318:                    synchronized (__tc_managed().getResolveLock()) {
319:                        // Just to have proper memory boundary
320:                        return super .size();
321:                    }
322:                } else {
323:                    return super .size();
324:                }
325:            }
326:
327:            public String toString() {
328:                return super .toString();
329:            }
330:
331:            public Set keySet() {
332:                return new KeySetWrapper(super .keySet());
333:            }
334:
335:            public Collection values() {
336:                return new ValuesCollectionWrapper(super .values());
337:            }
338:
339:            public Set entrySet() {
340:                return nonOverridableEntrySet();
341:            }
342:
343:            private final Set nonOverridableEntrySet() {
344:                return new EntrySetWrapper(super .entrySet());
345:            }
346:
347:            /**
348:             * Clearable interface - called by CacheManager thru TCObjectLogical
349:             */
350:            public int __tc_clearReferences(int toClear) {
351:                if (!__tc_isManaged()) {
352:                    throw new AssertionError(
353:                            "clearReferences() called on Unmanaged Map");
354:                }
355:                synchronized (__tc_managed().getResolveLock()) {
356:                    int cleared = 0;
357:                    for (Iterator i = super .entrySet().iterator(); i.hasNext()
358:                            && toClear > cleared;) {
359:                        Map.Entry e = (Map.Entry) i.next();
360:                        if (e.getValue() instanceof  Manageable) {
361:                            Manageable m = (Manageable) e.getValue();
362:                            TCObject tcObject = m.__tc_managed();
363:                            if (tcObject != null
364:                                    && !tcObject.recentlyAccessed()) {
365:                                e.setValue(tcObject.getObjectID());
366:                                cleared++;
367:                            }
368:                        }
369:                    }
370:                    return cleared;
371:                }
372:            }
373:
374:            public boolean isEvictionEnabled() {
375:                return evictionEnabled;
376:            }
377:
378:            public void setEvictionEnabled(boolean enabled) {
379:                evictionEnabled = enabled;
380:            }
381:
382:            public void __tc_managed(TCObject tcObject) {
383:                $__tc_MANAGED = tcObject;
384:            }
385:
386:            public TCObject __tc_managed() {
387:                return $__tc_MANAGED;
388:            }
389:
390:            public boolean __tc_isManaged() {
391:                // TCObject tcManaged = $__tc_MANAGED;
392:                // return (tcManaged != null && (tcManaged instanceof TCObjectPhysical || tcManaged instanceof TCObjectLogical));
393:                return $__tc_MANAGED != null;
394:            }
395:
396:            /*
397:             * This wrapper depends on the fact that key.equals() gets called on the wrapper instead of the other way around
398:             */
399:            static class ValueWrapper {
400:
401:                private final Object value;
402:
403:                public ValueWrapper(Object value) {
404:                    this .value = value;
405:                }
406:
407:                public int hashCode() {
408:                    return value.hashCode();
409:                }
410:
411:                public boolean equals(Object o) {
412:                    Object pojo = lookUpIfNecessary(o); // XXX:: This is not stored in the Map since we dont know the key
413:                    return pojo == value || value.equals(pojo);
414:                }
415:            }
416:
417:            private class EntryWrapper implements  Map.Entry {
418:
419:                private final Map.Entry entry;
420:
421:                public EntryWrapper(Map.Entry entry) {
422:                    this .entry = entry;
423:                }
424:
425:                public Object getKey() {
426:                    if (__tc_isManaged()) {
427:                        synchronized (__tc_managed().getResolveLock()) {
428:                            return entry.getKey();
429:                        }
430:                    } else {
431:                        return entry.getKey();
432:                    }
433:                }
434:
435:                // XXX:: This method has the side effect of looking up the object and setting the value in the Managed case.
436:                public Object getValue() {
437:                    if (__tc_isManaged()) {
438:                        synchronized (__tc_managed().getResolveLock()) {
439:                            Object value = lookUpIfNecessary(entry.getValue());
440:                            if (entry.getValue() != value) {
441:                                entry.setValue(value);
442:                            }
443:                            return value;
444:                        }
445:                    } else {
446:                        return entry.getValue();
447:                    }
448:                }
449:
450:                // This method not only does a faulting on this value, but depending on the fault depth, it faults peer objects too.
451:                public Object getValueFaultBreadth() {
452:                    Assert.assertFalse(entry instanceof  EntryWrapper);
453:                    if (__tc_isManaged()) {
454:                        synchronized (__tc_managed().getResolveLock()) {
455:                            Object value = lookUpFaultBreadthIfNecessary(entry
456:                                    .getValue());
457:                            if (entry.getValue() != value) {
458:                                entry.setValue(value);
459:                            }
460:                            return value;
461:                        }
462:                    } else {
463:                        return entry.getValue();
464:                    }
465:                }
466:
467:                /*
468:                 * Even though we do a lookup of oldVal after we change the value in the transaction, DGC will not be able to kick
469:                 * the oldVal out since the transaction is not committed.
470:                 */
471:                public Object setValue(Object value) {
472:                    if (__tc_isManaged()) {
473:                        synchronized (__tc_managed().getResolveLock()) {
474:                            ManagerUtil.checkWriteAccess(HashMapTC.this );
475:                            ManagerUtil.logicalInvoke(HashMapTC.this ,
476:                                    SerializationUtil.PUT_SIGNATURE,
477:                                    new Object[] { entry.getKey(), value });
478:                            Object oldVal = entry.setValue(value);
479:                            return lookUpIfNecessary(oldVal);
480:                        }
481:                    } else {
482:                        return entry.setValue(value);
483:                    }
484:                }
485:
486:                public boolean equals(Object o) {
487:                    if (__tc_isManaged()) {
488:                        synchronized (__tc_managed().getResolveLock()) {
489:                            // XXX:: make sure value is lookedup
490:                            getValue();
491:                            return entry.equals(o);
492:                        }
493:                    } else {
494:                        return entry.equals(o);
495:                    }
496:                }
497:
498:                public int hashCode() {
499:                    if (__tc_isManaged()) {
500:                        synchronized (__tc_managed().getResolveLock()) {
501:                            // XXX:: make sure value is lookedup
502:                            getValue();
503:                            return entry.hashCode();
504:                        }
505:                    } else {
506:                        return entry.hashCode();
507:                    }
508:                }
509:
510:            }
511:
512:            private class EntrySetWrapper extends AbstractSet {
513:
514:                private final Set entries;
515:
516:                public EntrySetWrapper(Set entries) {
517:                    this .entries = entries;
518:                }
519:
520:                public void clear() {
521:                    HashMapTC.this .clear();
522:                }
523:
524:                // Has to take care of ObjectIDs
525:                public boolean contains(Object o) {
526:                    if (__tc_isManaged()) {
527:                        synchronized (__tc_managed().getResolveLock()) {
528:                            if (!(o instanceof  Map.Entry))
529:                                return false;
530:                            Map.Entry e = (Map.Entry) o;
531:                            Object key = e.getKey();
532:                            if (!HashMapTC.this .containsKey(key)) {
533:                                return false;
534:                            }
535:                            Object value = HashMapTC.this .get(key);
536:                            return value == e.getValue()
537:                                    || (value != null && value.equals(e
538:                                            .getValue()));
539:                        }
540:                    } else {
541:                        return entries.contains(o);
542:                    }
543:                }
544:
545:                public Iterator iterator() {
546:                    return new EntriesIterator(entries.iterator());
547:                }
548:
549:                public boolean remove(Object o) {
550:                    if (__tc_isManaged()) {
551:                        synchronized (__tc_managed().getResolveLock()) {
552:                            if (!(o instanceof  Map.Entry))
553:                                return false;
554:                            Map.Entry e = (Map.Entry) o;
555:                            Object key = e.getKey();
556:                            int sizeB4 = size();
557:                            HashMapTC.this .remove(key);
558:                            return (sizeB4 != size());
559:                        }
560:                    } else {
561:                        return entries.remove(o);
562:                    }
563:                }
564:
565:                public int size() {
566:                    return HashMapTC.this .size();
567:                }
568:
569:            }
570:
571:            // These wrapper object are needed only for giving proper memory boundary to size() calls.
572:            private class KeySetWrapper extends AbstractSet {
573:
574:                private final Set _keySet;
575:
576:                public KeySetWrapper(Set keySet) {
577:                    this ._keySet = keySet;
578:                }
579:
580:                public void clear() {
581:                    HashMapTC.this .clear();
582:                }
583:
584:                public boolean contains(Object o) {
585:                    if (__tc_isManaged()) {
586:                        synchronized (__tc_managed().getResolveLock()) {
587:                            return _keySet.contains(o);
588:                        }
589:                    } else {
590:                        return _keySet.contains(o);
591:                    }
592:                }
593:
594:                public Iterator iterator() {
595:                    return new KeysIterator(HashMapTC.this 
596:                            .nonOverridableEntrySet().iterator());
597:                }
598:
599:                public boolean remove(Object o) {
600:                    if (__tc_isManaged()) {
601:                        synchronized (__tc_managed().getResolveLock()) {
602:                            // Managed version
603:                            int sizeB4 = size();
604:                            HashMapTC.this .remove(o);
605:                            return (size() != sizeB4);
606:                        }
607:                    } else {
608:                        return _keySet.remove(o);
609:                    }
610:                }
611:
612:                public int size() {
613:                    return HashMapTC.this .size();
614:                }
615:
616:            }
617:
618:            private class ValuesCollectionWrapper extends AbstractCollection {
619:
620:                private final Collection _values;
621:
622:                public ValuesCollectionWrapper(Collection values) {
623:                    this ._values = values;
624:                }
625:
626:                public void clear() {
627:                    HashMapTC.this .clear();
628:                }
629:
630:                public boolean contains(Object o) {
631:                    if (__tc_isManaged()) {
632:                        synchronized (__tc_managed().getResolveLock()) {
633:                            // Managed version
634:                            if (o != null) {
635:                                return _values.contains(new ValueWrapper(o));
636:                            } else {
637:                                return _values.contains(o);
638:                            }
639:                        }
640:                    } else {
641:                        return _values.contains(o);
642:                    }
643:                }
644:
645:                public Iterator iterator() {
646:                    return new ValuesIterator(HashMapTC.this 
647:                            .nonOverridableEntrySet().iterator());
648:                }
649:
650:                public int size() {
651:                    return HashMapTC.this .size();
652:                }
653:
654:            }
655:
656:            private class EntriesIterator implements  Iterator {
657:
658:                private final Iterator iterator;
659:                private Map.Entry currentEntry;
660:
661:                public EntriesIterator(Iterator iterator) {
662:                    this .iterator = iterator;
663:                }
664:
665:                public boolean hasNext() {
666:                    if (__tc_isManaged()) {
667:                        synchronized (__tc_managed().getResolveLock()) {
668:                            return iterator.hasNext();
669:                        }
670:                    } else {
671:                        return iterator.hasNext();
672:                    }
673:                }
674:
675:                public Object next() {
676:                    currentEntry = nextEntry();
677:                    if (currentEntry instanceof  EntryWrapper) {
678:                        // This check is here since this class is extended by ValuesIterator too.
679:                        return currentEntry;
680:                    } else {
681:                        return new EntryWrapper(currentEntry);
682:                    }
683:                }
684:
685:                protected Map.Entry nextEntry() {
686:                    if (__tc_isManaged()) {
687:                        synchronized (__tc_managed().getResolveLock()) {
688:                            return (Map.Entry) iterator.next();
689:                        }
690:                    } else {
691:                        return (Map.Entry) iterator.next();
692:                    }
693:                }
694:
695:                public void remove() {
696:                    if (__tc_isManaged()) {
697:                        synchronized (__tc_managed().getResolveLock()) {
698:                            ManagerUtil.checkWriteAccess(HashMapTC.this );
699:                            iterator.remove();
700:                            ManagerUtil
701:                                    .logicalInvoke(
702:                                            HashMapTC.this ,
703:                                            SerializationUtil.REMOVE_ENTRY_FOR_KEY_SIGNATURE,
704:                                            new Object[] { currentEntry
705:                                                    .getKey() });
706:                        }
707:                    } else {
708:                        iterator.remove();
709:                    }
710:                }
711:            }
712:
713:            private class KeysIterator extends EntriesIterator {
714:
715:                public KeysIterator(Iterator iterator) {
716:                    super (iterator);
717:                }
718:
719:                public Object next() {
720:                    Map.Entry e = (Map.Entry) super .next();
721:                    return e.getKey();
722:                }
723:            }
724:
725:            private class ValuesIterator extends EntriesIterator {
726:
727:                public ValuesIterator(Iterator iterator) {
728:                    super (iterator);
729:                }
730:
731:                public Object next() {
732:                    Map.Entry e = (Map.Entry) super .next();
733:                    if (e instanceof  EntryWrapper) {
734:                        EntryWrapper ew = (EntryWrapper) e;
735:                        return ew.getValueFaultBreadth();
736:                    }
737:                    return e.getValue();
738:                }
739:
740:            }
741:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.