001: /*
002: * Copyright (c) 1998 - 2005 Versant Corporation
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * Versant Corporation - initial API and implementation
010: */
011: package com.versant.core.jdo.sco.detached;
012:
013: import com.versant.core.jdo.VersantStateManager;
014: import com.versant.core.common.VersantFieldMetaData;
015: import com.versant.core.jdo.sco.VersantSimpleSCO;
016: import com.versant.core.jdo.sco.MapData;
017: import com.versant.core.jdo.VersantStateManager;
018:
019: import javax.jdo.spi.PersistenceCapable;
020: import java.io.Serializable;
021: import java.util.*;
022:
023: public class DetachSCOHashMap extends HashMap implements Serializable,
024: VersantSimpleSCO {
025:
026: private PersistenceCapable owner;
027: private VersantStateManager stateManager;
028: private int fieldNo;
029:
030: private DetachSCOHashMap(PersistenceCapable owner,
031: VersantFieldMetaData fmd) {
032: this .owner = owner;
033: this .fieldNo = fmd.getManagedFieldNo();
034: }
035:
036: public DetachSCOHashMap(PersistenceCapable owner,
037: VersantStateManager stateManager, VersantFieldMetaData fmd,
038: Map beforeMap) {
039: this (owner, fmd);
040: putAll(beforeMap);
041: this .stateManager = stateManager;
042: }
043:
044: public DetachSCOHashMap(PersistenceCapable owner,
045: VersantStateManager stateManager, VersantFieldMetaData fmd,
046: MapData mapData) {
047: this (owner, fmd);
048: int n = mapData.entryCount;
049: Object[] keys = mapData.keys;
050: Object[] values = mapData.values;
051: for (int i = 0; i < n; i++) {
052: put(keys[i], values[i]);
053: }
054: this .stateManager = stateManager;
055: }
056:
057: public Set keySet() {
058: final Set kSet = super .keySet();
059: final class TmpKeySet extends AbstractSet {
060:
061: Set delegateSet = kSet;
062:
063: public Iterator iterator() {
064: return delegateSet.iterator();
065: }
066:
067: public int size() {
068: return delegateSet.size();
069: }
070:
071: public boolean contains(Object o) {
072: return containsKey(o);
073: }
074:
075: public void clear() {
076: delegateSet.clear();
077: }
078:
079: public boolean remove(Object o) {
080: Object removed = DetachSCOHashMap.this .remove(o);
081: return removed != null;
082: }
083: }
084: return new TmpKeySet();
085: }
086:
087: public Object remove(Object key) {
088: return checkModified(super .remove(key));
089: }
090:
091: public Object put(Object key, Object value) {
092: makeDirty();
093: return super .put(key, value);
094: }
095:
096: public void putAll(Map t) {
097: makeDirty();
098: super .putAll(t);
099: }
100:
101: public void clear() {
102: final int size = size();
103: super .clear();
104: if (size != 0)
105: makeDirty();
106: }
107:
108: private void makeDirty() {
109: if (stateManager != null && owner != null) {
110: stateManager.makeDirty(owner, fieldNo);
111: }
112: }
113:
114: private Object checkModified(Object obj) {
115: if (obj != null) {
116: makeDirty();
117: }
118: return obj;
119: }
120:
121: public void makeTransient() {
122: owner = null;
123: stateManager = null;
124: }
125: }
|