Source Code Cross Referenced for HashMap.java in  » Database-ORM » TJDO » com » triactive » jdo » sco » 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 » Database ORM » TJDO » com.triactive.jdo.sco 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2004 (C) TJDO.
003:         * All rights reserved.
004:         *
005:         * This software is distributed under the terms of the TJDO License version 1.0.
006:         * See the terms of the TJDO License in the documentation provided with this software.
007:         *
008:         * $Id: HashMap.java,v 1.3 2004/01/18 19:15:30 jackknifebarber Exp $
009:         */
010:
011:        package com.triactive.jdo.sco;
012:
013:        import com.triactive.jdo.PersistenceManager;
014:        import com.triactive.jdo.SCO;
015:        import com.triactive.jdo.StateManager;
016:        import com.triactive.jdo.store.Query;
017:        import com.triactive.jdo.store.Queryable;
018:        import com.triactive.jdo.store.QueryStatement;
019:        import com.triactive.jdo.store.MapStore;
020:        import java.io.ObjectStreamException;
021:        import java.util.AbstractSet;
022:        import java.util.ArrayList;
023:        import java.util.Collection;
024:        import java.util.ConcurrentModificationException;
025:        import java.util.Iterator;
026:        import java.util.Map;
027:        import java.util.Map.Entry;
028:        import java.util.Set;
029:        import javax.jdo.JDOFatalInternalException;
030:        import javax.jdo.JDOHelper;
031:        import org.apache.log4j.Category;
032:
033:        /**
034:         * A mutable second-class HashMap object.
035:         * <p>
036:         * SCO fields declared as type java.util.Map or java.util.HashMap are populated
037:         * with objects of this type whenever the owning object is actively being
038:         * managed by a state manager.
039:         * <p>
040:         * While an SCO HashMap is owned it is considered either <dfn>transient</dfn> or
041:         * <dfn>persistent</dfn> according to whether its owner is in a transient or
042:         * persistent state.
043:         * <p>
044:         * While the owner/map is <em>transient</em>:
045:         * <ol>
046:         *   <li>
047:         *   Entries are restricted to be of the designated key &amp; value type.
048:         *   </li>
049:         *   <li>
050:         *   All write operations cause the corresponding field in the owner to be
051:         *   marked dirty.
052:         *   </li>
053:         * </ol>
054:         * <p>
055:         * In addition to the above, while the owner/map is <em>persistent</em>:
056:         * <ol>
057:         *   <li>
058:         *   The contents of the map may or may not be fully loaded in memory.
059:         *   If they are loaded within a transaction they are considered "up-to-date"
060:         *   only until the next update of the data store.
061:         *   </li>
062:         *   <li>
063:         *   Some read operations (get(), size(), isEmpty(), containsKey(),
064:         *   containsValue()) "pass through" directly to the database if the memory
065:         *   contents are not up-to-date.
066:         *   This avoids an expensive load from the data store for operations that
067:         *   don't necessarily involve the entire map.
068:         *   All other read operations by nature must access the entire map and so
069:         *   they always load the contents, or reload them if they are not up-to-date.
070:         *   </li>
071:         *   <li>
072:         *   All write operations <em>always</em> pass through directly to the database,
073:         *   although the memory copy is also updated.
074:         *   No write operation requires the contents to be loaded.
075:         *   </li>
076:         * </ol>
077:         * <p>
078:         * An instance of this class is always associated with a backing store, although
079:         * the store is only used when the map is persistent.
080:         * <p>
081:         * The map disconnects from its owner when {@link #unsetOwner} is called.
082:         * This occurs automatically in a variety of scenarios, such as when the object
083:         * is cloned or when its owning object (the one whose Map field refers to it)
084:         * transitions to a unmanaged state.
085:         * When a disconnect occurs the object subsequently behaves as a normal HashMap.
086:         * Subsequent changes affect only the memory contents.
087:         * Once disconnected from its owner an instance can never be reconnected.
088:         *
089:         * @author <a href="mailto:mmartin5@austin.rr.com">Mike Martin</a>
090:         * @version $Revision: 1.3 $
091:         */
092:
093:        public class HashMap extends java.util.HashMap implements  SCOMap,
094:                Cloneable {
095:            private static final Category LOG = Category
096:                    .getInstance(HashMap.class);
097:
098:            private transient Object owner;
099:            private transient PersistenceManager pm;
100:            private transient StateManager ownerSM;
101:            private transient String fieldName;
102:            private transient MapStore mapStore;
103:            private transient boolean isPersistent;
104:            private transient boolean isLoaded; // invariant: !isPersistent -> isLoaded
105:            private transient int expectedDSModCount = 0;
106:            private transient volatile int modCount = 0;
107:
108:            private void init(Object owner, String fieldName, MapStore mapStore) {
109:                this .owner = owner;
110:                this .pm = (PersistenceManager) JDOHelper
111:                        .getPersistenceManager(owner);
112:                this .ownerSM = pm.findStateManager(owner);
113:                this .fieldName = fieldName;
114:                this .mapStore = mapStore;
115:                this .isPersistent = JDOHelper.isPersistent(owner);
116:            }
117:
118:            /**
119:             * Constructs an SCO HashMap representing an existing persistent map.
120:             * The map's contents are initially not loaded.
121:             *
122:             * @param owner
123:             *      The object that owns this second-class object.
124:             * @param fieldName
125:             *      The fieldName in the owning object.
126:             * @param mapStore
127:             *      The backing store for this map.
128:             */
129:
130:            public HashMap(Object owner, String fieldName, MapStore mapStore) {
131:                init(owner, fieldName, mapStore);
132:
133:                if (!isPersistent)
134:                    throw new JDOFatalInternalException(
135:                            "Wrong constructor called, owner object is transient");
136:
137:                isLoaded = false;
138:            }
139:
140:            /**
141:             * Constructs an SCO HashMap having the specified initial contents.
142:             * <p>
143:             * If the owning object is already persistent it is assumed its field is
144:             * being assigned an entirely new value.
145:             * The existing map contents are cleared in the data store and the new
146:             * contents are added.
147:             *
148:             * @param owner
149:             *      The object that owns this second-class object.
150:             * @param fieldName
151:             *      The fieldName in the owning object.
152:             * @param mapStore
153:             *      The backing store for this map.
154:             * @param value
155:             *      The initial contents of the map.
156:             */
157:
158:            public HashMap(Object owner, String fieldName, MapStore mapStore,
159:                    Map value) {
160:                init(owner, fieldName, mapStore);
161:
162:                if (isPersistent) {
163:                    clearPersistent();
164:                    putAllPersistent(value);
165:                } else
166:                    putAllInternal(value);
167:
168:                setIsLoaded();
169:            }
170:
171:            private void setIsLoaded() {
172:                isLoaded = true;
173:                expectedDSModCount = pm.dataStoreModifyCount();
174:            }
175:
176:            private boolean upToDate() {
177:                if (!isPersistent)
178:                    return true;
179:                else if (!isLoaded)
180:                    return false;
181:                else if (!pm.currentTransaction().isActive())
182:                    return true;
183:                else {
184:                    /*
185:                     * When loaded up from the store within a transaction, we're only
186:                     * considered up-to-date until the next data store update.
187:                     */
188:                    return pm.dataStoreModifyCount() == expectedDSModCount;
189:                }
190:            }
191:
192:            public Object getOwner() {
193:                return owner;
194:            }
195:
196:            public String getFieldName() {
197:                return fieldName;
198:            }
199:
200:            public Class getKeyType() {
201:                return mapStore.getKeyType();
202:            }
203:
204:            public Class getValueType() {
205:                return mapStore.getValueType();
206:            }
207:
208:            public boolean allowsNullValues() {
209:                return mapStore.allowsNullValues();
210:            }
211:
212:            public void makeDirty() {
213:                ++modCount;
214:
215:                /*
216:                 * Even though all write operations pass through, the owning object must
217:                 * be marked dirty so that the proper state change occurs and its
218:                 * jdoPreStore() gets called properly.
219:                 */
220:                if (owner != null)
221:                    JDOHelper.makeDirty(owner, fieldName);
222:            }
223:
224:            public void applyUpdates() {
225:                /*
226:                 * If we're already persistent there's nothing to do because all writes
227:                 * immediately pass through.  If we're not then all the elements need
228:                 * to be added to the store.
229:                 */
230:                if (!isPersistent) {
231:                    mapStore.putAll(ownerSM, this );
232:                    isPersistent = true;
233:                    expectedDSModCount = pm.dataStoreModifyCount();
234:
235:                    if (LOG.isDebugEnabled())
236:                        LOG.debug(toLogString() + " is now persistent");
237:                }
238:            }
239:
240:            public void unsetOwner() {
241:                if (owner != null) {
242:                    owner = null;
243:                    ownerSM = null;
244:                    fieldName = null;
245:                    isPersistent = false;
246:
247:                    if (LOG.isDebugEnabled())
248:                        LOG.debug(toLogString() + " is now unowned");
249:                }
250:            }
251:
252:            /**
253:             * Creates and returns a copy of this object.
254:             *
255:             * <P>Mutable second-class Objects are required to provide a public
256:             * clone method in order to allow for copying PersistenceCapable
257:             * objects. In contrast to Object.clone(), this method must not throw a
258:             * CloneNotSupportedException.
259:             */
260:
261:            public Object clone() {
262:                Object obj = super .clone();
263:
264:                ((HashMap) obj).unsetOwner();
265:
266:                return obj;
267:            }
268:
269:            private synchronized void load() {
270:                if (!upToDate()) {
271:                    if (LOG.isDebugEnabled())
272:                        LOG.debug(toLogString() + " loading from storage");
273:
274:                    Map contents = mapStore.load(ownerSM);
275:                    clearInternal();
276:                    putAllInternal(contents);
277:                    setIsLoaded();
278:                }
279:            }
280:
281:            private Set entrySetInternal() {
282:                return super .entrySet();
283:            }
284:
285:            private Object putInternal(Object key, Object value) {
286:                return super .put(key, value);
287:            }
288:
289:            private void putAllInternal(Map m) {
290:                Iterator i = m.entrySet().iterator();
291:
292:                while (i.hasNext()) {
293:                    Entry e = (Entry) i.next();
294:                    super .put(e.getKey(), e.getValue());
295:                }
296:            }
297:
298:            private Object removeInternal(Object key) {
299:                return super .remove(key);
300:            }
301:
302:            private void clearInternal() {
303:                super .clear();
304:            }
305:
306:            private Object getPersistent(Object key) {
307:                if (isPersistent) {
308:                    Object value = mapStore.get(ownerSM, key);
309:                    putInternal(key, value);
310:                    return value;
311:                } else
312:                    return super .get(key);
313:            }
314:
315:            private Object putPersistent(Object key, Object value) {
316:                if (isPersistent) {
317:                    putInternal(key, value);
318:                    return mapStore.put(ownerSM, key, value);
319:                } else
320:                    return putInternal(key, value);
321:            }
322:
323:            private void putAllPersistent(Map m) {
324:                SCOHelper.assertAllValidEntries(this , m);
325:
326:                if (isPersistent)
327:                    mapStore.putAll(ownerSM, m);
328:
329:                putAllInternal(m);
330:            }
331:
332:            private Object removePersistent(Object key) {
333:                if (isPersistent) {
334:                    removeInternal(key);
335:                    return mapStore.remove(ownerSM, key);
336:                } else
337:                    return removeInternal(key);
338:            }
339:
340:            private void clearPersistent() {
341:                if (isPersistent) {
342:                    mapStore.clear(ownerSM);
343:                    setIsLoaded();
344:                }
345:
346:                clearInternal();
347:            }
348:
349:            public int size() {
350:                return upToDate() ? super .size() : mapStore.size(ownerSM);
351:            }
352:
353:            public boolean isEmpty() {
354:                return upToDate() ? super .isEmpty() : mapStore.isEmpty(ownerSM);
355:            }
356:
357:            public boolean containsKey(Object key) {
358:                if (!SCOHelper.isValidKey(this , key))
359:                    return false;
360:
361:                return upToDate() ? super .containsKey(key) : mapStore
362:                        .containsKey(ownerSM, key);
363:            }
364:
365:            public boolean containsValue(Object value) {
366:                if (!SCOHelper.isValidValue(this , value))
367:                    return false;
368:
369:                return upToDate() ? super .containsValue(value) : mapStore
370:                        .containsValue(ownerSM, value);
371:            }
372:
373:            private boolean containsEntry(Entry entry) {
374:                Object key = entry.getKey();
375:                Object value = entry.getValue();
376:
377:                if (!SCOHelper.isValidKey(this , key))
378:                    return false;
379:                if (!SCOHelper.isValidValue(this , value))
380:                    return false;
381:
382:                if (upToDate()) {
383:                    Object resValue = super .get(key);
384:
385:                    return super .containsKey(key)
386:                            && (value == null ? resValue == null : value
387:                                    .equals(resValue));
388:                } else
389:                    return mapStore.containsEntry(ownerSM, key, value);
390:            }
391:
392:            public Object get(Object key) {
393:                SCOHelper.assertIsValidKey(this , key);
394:
395:                return upToDate() ? super .get(key) : getPersistent(key);
396:            }
397:
398:            public Object put(Object key, Object value) {
399:                SCOHelper.assertIsValidKey(this , key);
400:                SCOHelper.assertIsValidValue(this , value);
401:
402:                makeDirty();
403:                return putPersistent(key, value);
404:            }
405:
406:            public void putAll(Map m) {
407:                SCOHelper.assertAllValidEntries(this , m);
408:
409:                makeDirty();
410:                putAllPersistent(m);
411:            }
412:
413:            public Object remove(Object key) {
414:                if (!SCOHelper.isValidKey(this , key))
415:                    return null;
416:
417:                makeDirty();
418:                return removePersistent(key);
419:            }
420:
421:            private boolean removeEntry(Entry entry) {
422:                Object key = entry.getKey();
423:                Object value = entry.getValue();
424:
425:                if (!SCOHelper.isValidKey(this , key))
426:                    return false;
427:                if (!SCOHelper.isValidValue(this , value))
428:                    return false;
429:
430:                makeDirty();
431:                boolean modified = false;
432:
433:                if (isPersistent) {
434:                    modified = mapStore.removeEntry(ownerSM, key, value);
435:
436:                    if (modified)
437:                        removeInternal(key);
438:                } else {
439:                    if (containsKey(key)) {
440:                        Object resValue = super .get(key);
441:
442:                        if (value == null ? resValue == null : value
443:                                .equals(resValue)) {
444:                            removeInternal(key);
445:                            modified = true;
446:                        }
447:                    }
448:                }
449:
450:                return modified;
451:            }
452:
453:            public void clear() {
454:                makeDirty();
455:                clearPersistent();
456:            }
457:
458:            public Set keySet() {
459:                return new KeySetView();
460:            }
461:
462:            public Collection values() {
463:                return new ValuesView();
464:            }
465:
466:            public Set entrySet() {
467:                return new EntrySetView();
468:            }
469:
470:            public boolean equals(Object o) {
471:                load();
472:                return super .equals(o);
473:            }
474:
475:            public int hashCode() {
476:                load();
477:                return super .hashCode();
478:            }
479:
480:            public String toString() {
481:                load();
482:                return super .toString();
483:            }
484:
485:            private String toLogString() {
486:                return SCOHelper.toLogString(this );
487:            }
488:
489:            /**
490:             * Replaces the object to be serialized with a java.util.HashMap object.
491:             * Invoked by the serialization mechanism to obtain an alternative object
492:             * to be used when writing an object to the stream.
493:             *
494:             * @return
495:             *      The <code>HashMap</code> to be serialized instead of this object.
496:             */
497:
498:            protected Object writeReplace() throws ObjectStreamException {
499:                return new java.util.HashMap(this );
500:            }
501:
502:            private abstract class SetView extends AbstractSet implements 
503:                    Queryable {
504:                public int size() {
505:                    return HashMap.this .size();
506:                }
507:
508:                public void clear() {
509:                    HashMap.this .clear();
510:                }
511:
512:                protected abstract Queryable storageQuery();
513:
514:                private void assertIsPersistent() {
515:                    if (!isPersistent)
516:                        throw new QueryUnownedSCOException(HashMap.this );
517:                }
518:
519:                public Class getCandidateClass() {
520:                    assertIsPersistent();
521:                    return storageQuery().getCandidateClass();
522:                }
523:
524:                public QueryStatement newQueryStatement(Class candidateClass) {
525:                    assertIsPersistent();
526:                    return storageQuery().newQueryStatement(candidateClass);
527:                }
528:
529:                public Query.ResultObjectFactory newResultObjectFactory(
530:                        QueryStatement stmt) {
531:                    assertIsPersistent();
532:                    return storageQuery().newResultObjectFactory(stmt);
533:                }
534:            }
535:
536:            private class KeySetView extends SetView {
537:                public Iterator iterator() {
538:                    load();
539:                    return new KeyIterator();
540:                }
541:
542:                public boolean contains(Object o) {
543:                    return containsKey(o);
544:                }
545:
546:                public boolean remove(Object o) {
547:                    return HashMap.this .remove(o) != null;
548:                }
549:
550:                protected Queryable storageQuery() {
551:                    return mapStore.keySetQuery(ownerSM);
552:                }
553:            }
554:
555:            private class ValuesView extends SetView {
556:                public Iterator iterator() {
557:                    load();
558:                    return new ValueIterator();
559:                }
560:
561:                public boolean contains(Object o) {
562:                    return containsValue(o);
563:                }
564:
565:                protected Queryable storageQuery() {
566:                    return mapStore.valuesQuery(ownerSM);
567:                }
568:            }
569:
570:            private class EntrySetView extends SetView {
571:                public Iterator iterator() {
572:                    load();
573:                    return new EntryIterator();
574:                }
575:
576:                public boolean contains(Object o) {
577:                    if (!(o instanceof  Entry))
578:                        return false;
579:                    else
580:                        return containsEntry((Entry) o);
581:                }
582:
583:                public boolean remove(Object o) {
584:                    if (!(o instanceof  Entry))
585:                        return false;
586:                    else
587:                        return removeEntry((Entry) o);
588:                }
589:
590:                protected Queryable storageQuery() {
591:                    return mapStore.entrySetQuery(ownerSM);
592:                }
593:            }
594:
595:            private abstract class MapIterator implements  Iterator {
596:                private final Iterator iter = new ArrayList(entrySetInternal())
597:                        .iterator();
598:                private Entry last = null;
599:                private int expectedModCount = modCount;
600:
601:                public boolean hasNext() {
602:                    return iter.hasNext();
603:                }
604:
605:                protected Entry nextEntry() {
606:                    if (modCount != expectedModCount)
607:                        throw new ConcurrentModificationException();
608:
609:                    return last = (Entry) iter.next();
610:                }
611:
612:                public void remove() {
613:                    if (last == null)
614:                        throw new IllegalStateException();
615:                    if (modCount != expectedModCount)
616:                        throw new ConcurrentModificationException();
617:
618:                    makeDirty();
619:                    removePersistent(last.getKey());
620:                    last = null;
621:                    expectedModCount = modCount;
622:                }
623:            }
624:
625:            private class KeyIterator extends MapIterator {
626:                public Object next() {
627:                    return nextEntry().getKey();
628:                }
629:            }
630:
631:            private class ValueIterator extends MapIterator {
632:                public Object next() {
633:                    return nextEntry().getValue();
634:                }
635:            }
636:
637:            private class EntryIterator extends MapIterator {
638:                public Object next() {
639:                    return nextEntry();
640:                }
641:            }
642:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.