openjpa-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From p..@apache.org
Subject svn commit: r640685 [8/14] - in /openjpa/trunk: ./ openjpa-all/ openjpa-jdbc-5/ openjpa-jdbc/ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ openjpa-jdbc/src/main/java/org/apache/open...
Date Tue, 25 Mar 2008 03:38:02 GMT
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedStateManager.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedStateManager.java?rev=640685&r1=640684&r2=640685&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedStateManager.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedStateManager.java Mon Mar 24 20:37:56 2008
@@ -1,947 +1,947 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.kernel;
-
-import java.io.IOException;
-import java.io.ObjectOutput;
-import java.io.Serializable;
-import java.util.BitSet;
-import java.util.Collection;
-import java.util.Map;
-
-import org.apache.openjpa.enhance.PersistenceCapable;
-import org.apache.openjpa.enhance.StateManager;
-import org.apache.openjpa.lib.util.Localizer;
-import org.apache.openjpa.lib.util.concurrent.ReentrantLock;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.meta.FieldMetaData;
-import org.apache.openjpa.meta.JavaTypes;
-import org.apache.openjpa.meta.ValueMetaData;
-import org.apache.openjpa.util.Exceptions;
-import org.apache.openjpa.util.Proxy;
-import org.apache.openjpa.util.UnsupportedException;
-import org.apache.openjpa.util.ImplHelper;
-
-/**
- * Internal state manager for detached instances. Does not fully
- * implement {@link OpenJPAStateManager} contract to allow for serialization.
- *
- * @author Steve Kim
- * @nojavadoc
- */
-public class DetachedStateManager
-    extends AttachStrategy
-    implements OpenJPAStateManager, Serializable {
-
-    private static final Localizer _loc = Localizer.forPackage
-        (DetachedStateManager.class);
-
-    private final PersistenceCapable _pc;
-    private final boolean _embedded;
-    private final boolean _access;
-    private final BitSet _loaded;
-    private final BitSet _dirty;
-    private final Object _oid;
-    private final Object _version;
-    private final ReentrantLock _lock;
-
-    /**
-     * Constructor.
-     *
-     * @param pc the managed instance
-     * @param sm the instance's state manager
-     * @param load the set of detached field indexes
-     * @param access whether to allow access to unloaded fields
-     * @param multithreaded whether the instance will be used concurrently
-     * by multiple threads
-     */
-    public DetachedStateManager(PersistenceCapable pc, OpenJPAStateManager sm,
-        BitSet load, boolean access, boolean multithreaded) {
-        _pc = pc;
-        _embedded = sm.isEmbedded();
-        _loaded = load;
-        _access = access;
-        _dirty = new BitSet(_loaded.length());
-        _oid = sm.fetchObjectId();
-        _version = sm.getVersion();
-        if (multithreaded)
-            _lock = new ReentrantLock();
-        else
-            _lock = null;
-    }
-
-    /////////////////////////////////
-    // AttachStrategy implementation
-    /////////////////////////////////
-
-    public Object attach(AttachManager manager, Object toAttach,
-        ClassMetaData meta, PersistenceCapable into, OpenJPAStateManager owner,
-        ValueMetaData ownerMeta, boolean explicit) {
-        BrokerImpl broker = manager.getBroker();
-        StateManagerImpl sm;
-        if (_embedded) {
-            if (_dirty.length () > 0)
-                owner.dirty(ownerMeta.getFieldMetaData().getIndex());
-            sm = (StateManagerImpl) broker.embed(_pc, _oid, owner, ownerMeta);
-            ImplHelper.toPersistenceCapable(toAttach, broker.getConfiguration())
-                .pcReplaceStateManager(this);
-        } else {
-            PCState state = (_dirty.length() > 0) ? PCState.PDIRTY
-                : PCState.PCLEAN;
-            sm = (StateManagerImpl) broker.copy(this, state);
-        }
-        PersistenceCapable pc = sm.getPersistenceCapable();
-        manager.setAttachedCopy(toAttach, pc);
-
-        manager.fireBeforeAttach(toAttach, meta);
-
-        // pre-load for efficiency: current field values for restore, dependent
-        // for delete
-        FieldMetaData[] fields = meta.getFields();
-        int restore = broker.getRestoreState();
-        if (_dirty.length() > 0) {
-            BitSet load = new BitSet(fields.length);
-            for (int i = 0; i < fields.length; i++) {
-                if (!_dirty.get(i))
-                    continue;
-
-                switch (fields[i].getDeclaredTypeCode()) {
-                    case JavaTypes.ARRAY:
-                    case JavaTypes.COLLECTION:
-                        if (restore == RestoreState.RESTORE_ALL
-                            || fields[i].getElement().getCascadeDelete()
-                            == ValueMetaData.CASCADE_AUTO)
-                            load.set(i);
-                        break;
-                    case JavaTypes.MAP:
-                        if (restore == RestoreState.RESTORE_ALL
-                            || fields[i].getElement().getCascadeDelete()
-                            == ValueMetaData.CASCADE_AUTO
-                            || fields[i].getKey().getCascadeDelete()
-                            == ValueMetaData.CASCADE_AUTO)
-                            load.set(i);
-                        break;
-                    default:
-                        if (restore != RestoreState.RESTORE_NONE
-                            || fields[i].getCascadeDelete()
-                            == ValueMetaData.CASCADE_AUTO)
-                            load.set(i);
-                }
-            }
-            FetchConfiguration fc = broker.getFetchConfiguration();
-            sm.loadFields(load, fc, fc.getWriteLockLevel(), null);
-        }        
-        Object origVersion = sm.getVersion();
-        sm.setVersion(_version);
-
-        BitSet loaded = sm.getLoaded();
-        int set = StateManager.SET_ATTACH;
-        for (int i = 0; i < fields.length; i++) {
-            if (!_loaded.get(i))
-                continue;
-            // don't reload already loaded non-mutable objects
-            if (!_dirty.get(i) && loaded.get(i) && ignoreLoaded(fields[i]))
-                continue;
-
-            provideField(i);
-            switch (fields[i].getDeclaredTypeCode()) {
-                case JavaTypes.BOOLEAN:
-                    if (_dirty.get(i))
-                        sm.settingBooleanField(pc, i,
-                            (loaded.get(i)) && sm.fetchBooleanField(i),
-                            longval == 1, set);
-                    else
-                        sm.storeBooleanField(i, longval == 1);
-                    break;
-                case JavaTypes.BYTE:
-                    if (_dirty.get(i))
-                        sm.settingByteField(pc, i, (!loaded.get(i)) ? (byte) 0
-                            : sm.fetchByteField(i), (byte) longval, set);
-                    else
-                        sm.storeByteField(i, (byte) longval);
-                    break;
-                case JavaTypes.CHAR:
-                    if (_dirty.get(i))
-                        sm.settingCharField(pc, i, (!loaded.get(i)) ? (char) 0
-                            : sm.fetchCharField(i), (char) longval, set);
-                    else
-                        sm.storeCharField(i, (char) longval);
-                    break;
-                case JavaTypes.INT:
-                    if (_dirty.get(i))
-                        sm.settingIntField(pc, i, (!loaded.get(i)) ? 0
-                            : sm.fetchIntField(i), (int) longval, set);
-                    else
-                        sm.storeIntField(i, (int) longval);
-                    break;
-                case JavaTypes.LONG:
-                    if (_dirty.get(i))
-                        sm.settingLongField(pc, i, (!loaded.get(i)) ? 0L
-                            : sm.fetchLongField(i), longval, set);
-                    else
-                        sm.storeLongField(i, longval);
-                    break;
-                case JavaTypes.SHORT:
-                    if (_dirty.get(i))
-                        sm.settingShortField(pc, i, (!loaded.get(i)) ? (short) 0
-                            : sm.fetchShortField(i), (short) longval, set);
-                    else
-                        sm.storeShortField(i, (short) longval);
-                    break;
-                case JavaTypes.FLOAT:
-                    if (_dirty.get(i))
-                        sm.settingFloatField(pc, i, (!loaded.get(i)) ? 0F
-                            : sm.fetchFloatField(i), (float) dblval, set);
-                    else
-                        sm.storeFloatField(i, (float) dblval);
-                    break;
-                case JavaTypes.DOUBLE:
-                    if (_dirty.get(i))
-                        sm.settingDoubleField(pc, i, (!loaded.get(i)) ? 0D
-                            : sm.fetchDoubleField(i), dblval, set);
-                    else
-                        sm.storeDoubleField(i, dblval);
-                    break;
-                case JavaTypes.STRING:
-                    if (_dirty.get(i))
-                        sm.settingStringField(pc, i, (!loaded.get(i)) ? null
-                            : sm.fetchStringField(i), (String) objval, set);
-                    else
-                        sm.storeStringField(i, (String) objval);
-                    objval = null;
-                    break;
-                case JavaTypes.PC:
-                case JavaTypes.PC_UNTYPED:
-                    if (fields[i].getCascadeAttach() == ValueMetaData
-                        .CASCADE_NONE)
-                        objval = getReference(manager, objval, sm, fields[i]);
-                    else {
-                        PersistenceCapable toPC = null;
-                        if (objval != null && fields[i].isEmbeddedPC())
-                            toPC = ImplHelper.toPersistenceCapable(objval,
-                                broker.getConfiguration());
-                        objval = manager.attach(objval, toPC, sm, fields[i],
-                            false);
-                    }
-                    if (_dirty.get(i))
-                        sm.settingObjectField(pc, i, (!loaded.get(i)) ? null
-                            : sm.fetchObjectField(i), objval, set);
-                    else
-                        sm.storeObjectField(i, objval);
-                    objval = null;
-                    break;
-                case JavaTypes.COLLECTION:
-                    Collection coll = (Collection) objval;
-                    objval = null;
-                    if (coll != null)
-                        coll = attachCollection(manager, coll, sm, fields[i]);
-                    if (_dirty.get(i))
-                        sm.settingObjectField(pc, i, (!loaded.get(i)) ? null
-                            : sm.fetchObjectField(i), coll, set);
-                    else
-                        sm.storeObjectField(i, coll);
-                    break;
-                case JavaTypes.MAP:
-                    Map map = (Map) objval;
-                    objval = null;
-                    if (map != null)
-                        map = attachMap(manager, map, sm, fields[i]);
-                    if (_dirty.get(i))
-                        sm.settingObjectField(pc, i, (!loaded.get(i)) ? null
-                            : sm.fetchObjectField(i), map, set);
-                    else
-                        sm.storeObjectField(i, map);
-                    break;
-                default:
-                    if (_dirty.get(i))
-                        sm.settingObjectField(pc, i, (!loaded.get(i)) ? null
-                            : sm.fetchObjectField(i), objval, set);
-                    else
-                        sm.storeObjectField(i, objval);
-                    objval = null;
-            }
-        }
-        pc.pcReplaceStateManager(sm);
-
-        // if we were clean at least make sure a version check is done to
-        // prevent using old state
-        if (!sm.isVersionCheckRequired() && broker.isActive()
-            && _version != origVersion && (origVersion == null 
-            || broker.getStoreManager().compareVersion(sm, _version, 
-            origVersion) != StoreManager.VERSION_SAME)) {
-            broker.transactional(sm.getManagedInstance(), false, 
-                manager.getBehavior());
-        }
-
-        return sm.getManagedInstance();
-    }
-
-    protected Object getDetachedObjectId(AttachManager manager,
-        Object toAttach) {
-        return _oid;
-    }
-
-    void provideField(int field) {
-        _pc.pcProvideField(field);
-    }
-
-    protected void provideField(Object toAttach, StateManagerImpl sm,
-        int field) {
-        provideField(field);
-    }
-
-    /**
-     * Ignore if the field is not dirty but loaded
-     */
-    protected static boolean ignoreLoaded(FieldMetaData fmd) {
-        switch (fmd.getTypeCode()) {
-            case JavaTypes.BOOLEAN:
-            case JavaTypes.BOOLEAN_OBJ:
-            case JavaTypes.BYTE:
-            case JavaTypes.BYTE_OBJ:
-            case JavaTypes.INT:
-            case JavaTypes.INT_OBJ:
-            case JavaTypes.LONG:
-            case JavaTypes.LONG_OBJ:
-            case JavaTypes.SHORT:
-            case JavaTypes.SHORT_OBJ:
-            case JavaTypes.DOUBLE:
-            case JavaTypes.DOUBLE_OBJ:
-            case JavaTypes.FLOAT:
-            case JavaTypes.FLOAT_OBJ:
-            case JavaTypes.CHAR:
-            case JavaTypes.CHAR_OBJ:
-            case JavaTypes.STRING:
-                return true;
-        }
-        return false;
-    }
-
-    ///////////////////////////////
-    // StateManager implementation
-    ///////////////////////////////
-
-    public Object getGenericContext() {
-        return null;
-    }
-
-    public Object getPCPrimaryKey(Object oid, int field) {
-        throw new UnsupportedOperationException();
-    }
-
-    public StateManager replaceStateManager(StateManager sm) {
-        return sm;
-    }
-
-    public Object getVersion() {
-        return _version;
-    }
-
-    public void setVersion(Object version) {
-        throw new UnsupportedException();
-    }
-
-    public boolean isDirty() {
-        return _dirty.length() != 0;
-    }
-
-    public boolean isTransactional() {
-        return false;
-    }
-
-    public boolean isPersistent() {
-        return false;
-    }
-
-    public boolean isNew() {
-        return false;
-    }
-
-    public boolean isDeleted() {
-        return false;
-    }
-
-    public boolean isDetached() {
-        return true;
-    }
-
-    public boolean isVersionUpdateRequired() {
-        return false;
-    }
-
-    public boolean isVersionCheckRequired() {
-        return false;
-    }
-
-    public void dirty(String field) {
-        // should we store ClassMetaData?
-        throw new UnsupportedException();
-    }
-
-    public Object fetchObjectId() {
-        return _oid;
-    }
-
-    public void accessingField(int idx) {
-        if (!_access && !_loaded.get(idx))
-        	// do not access the pc fields by implictly invoking _pc.toString()
-        	// may cause infinite loop if again tries to access unloaded field 
-            throw new IllegalStateException(_loc.get("unloaded-detached",
-               Exceptions.toString(_pc)).getMessage());
-    }
-
-    public boolean serializing() {
-        return false;
-    }
-
-    public boolean writeDetached(ObjectOutput out)
-        throws IOException {
-        out.writeObject(_pc.pcGetDetachedState());
-        out.writeObject(this);
-        return false;
-    }
-
-    public void proxyDetachedDeserialized(int idx) {
-        lock();
-        try {
-            _pc.pcProvideField(idx);
-            if (objval instanceof Proxy)
-                ((Proxy) objval).setOwner(this, idx);
-            objval = null;
-        } finally {
-            unlock();
-        }
-    }
-
-    public void settingBooleanField(PersistenceCapable pc, int idx,
-        boolean cur, boolean next, int set) {
-        accessingField(idx);
-        if (cur == next || !_loaded.get(idx))
-            return;
-        lock();
-        try {
-            _dirty.set(idx);
-            longval = next ? 1 : 0;
-            pc.pcReplaceField(idx);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void settingCharField(PersistenceCapable pc, int idx, char cur,
-        char next, int set) {
-        accessingField(idx);
-        if (cur == next || !_loaded.get(idx))
-            return;
-        lock();
-        try {
-            _dirty.set(idx);
-            longval = next;
-            pc.pcReplaceField(idx);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void settingByteField(PersistenceCapable pc, int idx, byte cur,
-        byte next, int set) {
-        accessingField(idx);
-        if (cur == next || !_loaded.get(idx))
-            return;
-        lock();
-        try {
-            _dirty.set(idx);
-            longval = next;
-            pc.pcReplaceField(idx);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void settingShortField(PersistenceCapable pc, int idx, short cur,
-        short next, int set) {
-        accessingField(idx);
-        if (cur == next || !_loaded.get(idx))
-            return;
-        lock();
-        try {
-            _dirty.set(idx);
-            longval = next;
-            pc.pcReplaceField(idx);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void settingIntField(PersistenceCapable pc, int idx, int cur,
-        int next, int set) {
-        accessingField(idx);
-        if (cur == next || !_loaded.get(idx))
-            return;
-        lock();
-        try {
-            _dirty.set(idx);
-            longval = next;
-            pc.pcReplaceField(idx);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void settingLongField(PersistenceCapable pc, int idx, long cur,
-        long next, int set) {
-        accessingField(idx);
-        if (cur == next || !_loaded.get(idx))
-            return;
-        lock();
-        try {
-            _dirty.set(idx);
-            longval = next;
-            pc.pcReplaceField(idx);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void settingFloatField(PersistenceCapable pc, int idx, float cur,
-        float next, int set) {
-        accessingField(idx);
-        if (cur == next || !_loaded.get(idx))
-            return;
-        lock();
-        try {
-            _dirty.set(idx);
-            dblval = next;
-            pc.pcReplaceField(idx);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void settingDoubleField(PersistenceCapable pc, int idx, double cur,
-        double next, int set) {
-        accessingField(idx);
-        if (cur == next || !_loaded.get(idx))
-            return;
-        lock();
-        try {
-            _dirty.set(idx);
-            dblval = next;
-            pc.pcReplaceField(idx);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void settingStringField(PersistenceCapable pc, int idx, String cur,
-        String next, int set) {
-        accessingField(idx);
-        if (cur == next || (cur != null && cur.equals(next))
-                || !_loaded.get(idx))
-            return;
-        lock();
-        try {
-            _dirty.set(idx);
-            objval = next;
-            pc.pcReplaceField(idx);
-        } finally {
-            unlock();
-            objval = null;
-        }
-    }
-
-    public void settingObjectField(PersistenceCapable pc, int idx, Object cur,
-        Object next, int set) {
-        accessingField(idx);
-        if (cur == next || !_loaded.get(idx))
-            return;
-        lock();
-        try {
-            _dirty.set(idx);
-            objval = next;
-            pc.pcReplaceField(idx);
-        } finally {
-            unlock();
-            objval = null;
-        }
-    }
-
-    public void providedBooleanField(PersistenceCapable pc, int idx,
-        boolean cur) {
-        longval = cur ? 1 : 0;
-    }
-
-    public void providedCharField(PersistenceCapable pc, int idx, char cur) {
-        longval = cur;
-    }
-
-    public void providedByteField(PersistenceCapable pc, int idx, byte cur) {
-        longval = cur;
-    }
-
-    public void providedShortField(PersistenceCapable pc, int idx, short cur) {
-        longval = cur;
-    }
-
-    public void providedIntField(PersistenceCapable pc, int idx, int cur) {
-        longval = cur;
-    }
-
-    public void providedLongField(PersistenceCapable pc, int idx, long cur) {
-        longval = cur;
-    }
-
-    public void providedFloatField(PersistenceCapable pc, int idx, float cur) {
-        dblval = cur;
-    }
-
-    public void providedDoubleField(PersistenceCapable pc, int idx,
-        double cur) {
-        dblval = cur;
-    }
-
-    public void providedStringField(PersistenceCapable pc, int idx,
-        String cur) {
-        objval = cur;
-    }
-
-    public void providedObjectField(PersistenceCapable pc, int idx,
-        Object cur) {
-        objval = cur;
-    }
-
-    public boolean replaceBooleanField(PersistenceCapable pc, int idx) {
-        return longval == 1;
-    }
-
-    public char replaceCharField(PersistenceCapable pc, int idx) {
-        return (char) longval;
-    }
-
-    public byte replaceByteField(PersistenceCapable pc, int idx) {
-        return (byte) longval;
-    }
-
-    public short replaceShortField(PersistenceCapable pc, int idx) {
-        return (short) longval;
-    }
-
-    public int replaceIntField(PersistenceCapable pc, int idx) {
-        return (int) longval;
-    }
-
-    public long replaceLongField(PersistenceCapable pc, int idx) {
-        return longval;
-    }
-
-    public float replaceFloatField(PersistenceCapable pc, int idx) {
-        return (float) dblval;
-    }
-
-    public double replaceDoubleField(PersistenceCapable pc, int idx) {
-        return dblval;
-    }
-
-    public String replaceStringField(PersistenceCapable pc, int idx) {
-        String str = (String) objval;
-        objval = null;
-        return str;
-    }
-
-    public Object replaceObjectField(PersistenceCapable pc, int idx) {
-        Object ret = objval;
-        objval = null;
-        return ret;
-    }
-
-    //////////////////////////////////////
-    // OpenJPAStateManager implementation
-    //////////////////////////////////////
-
-    public void initialize(Class forType, PCState state) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void load(FetchConfiguration fetch) {
-        throw new UnsupportedOperationException();
-    }
-
-    public Object getManagedInstance() {
-        return _pc;
-    }
-
-    public PersistenceCapable getPersistenceCapable() {
-        return _pc;
-    }
-
-    public ClassMetaData getMetaData() {
-        throw new UnsupportedOperationException();
-    }
-
-    public OpenJPAStateManager getOwner() {
-        throw new UnsupportedOperationException();
-    }
-
-    public int getOwnerIndex() {
-        throw new UnsupportedOperationException();
-    }
-
-    public boolean isEmbedded() {
-        return _embedded;
-    }
-
-    public boolean isFlushed() {
-        throw new UnsupportedOperationException();
-    }
-
-    public boolean isFlushedDirty() {
-        throw new UnsupportedOperationException();
-    }
-
-    public boolean isProvisional() {
-        throw new UnsupportedOperationException();
-    }
-
-    public BitSet getLoaded() {
-        return _loaded;
-    }
-
-    public BitSet getDirty() {
-        return _dirty;
-    }
-
-    public BitSet getFlushed() {
-        throw new UnsupportedOperationException();
-    }
-
-    public BitSet getUnloaded(FetchConfiguration fetch) {
-        throw new UnsupportedOperationException();
-    }
-
-    public Object newProxy(int field) {
-        throw new UnsupportedOperationException();
-    }
-
-    public Object newFieldProxy(int field) {
-        throw new UnsupportedOperationException();
-    }
-
-    public boolean isDefaultValue(int field) {
-        throw new UnsupportedOperationException();
-    }
-
-    public StoreContext getContext() {
-        return null;
-    }
-
-    public PCState getPCState() {
-        throw new UnsupportedOperationException();
-    }
-
-    public Object getObjectId() {
-        return _oid;
-    }
-
-    public void setObjectId(Object oid) {
-        throw new UnsupportedOperationException();
-    }
-
-    public boolean assignObjectId(boolean flush) {
-        return true;
-    }
-
-    public Object getId() {
-        return getObjectId();
-    }
-
-    public Object getLock() {
-        throw new UnsupportedOperationException();
-    }
-
-    public void setLock(Object lock) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void setNextVersion(Object version) {
-        throw new UnsupportedOperationException();
-    }
-
-    public Object getImplData() {
-        throw new UnsupportedOperationException();
-    }
-
-    public Object setImplData(Object data, boolean cacheable) {
-        throw new UnsupportedOperationException();
-    }
-
-    public boolean isImplDataCacheable() {
-        return false;
-    }
-
-    public Object getImplData(int field) {
-        throw new UnsupportedOperationException();
-    }
-
-    public Object setImplData(int field, Object data) {
-        throw new UnsupportedOperationException();
-    }
-
-    public boolean isImplDataCacheable(int field) {
-        throw new UnsupportedOperationException();
-    }
-
-    public Object getIntermediate(int field) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void setIntermediate(int field, Object data) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void removed(int field, Object removed, boolean key) {
-        dirty(field);
-    }
-
-    public boolean beforeRefresh(boolean all) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void dirty(int field) {
-        lock();
-        try {
-            _dirty.set(field);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void storeBoolean(int field, boolean extVal) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void storeByte(int field, byte extVal) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void storeChar(int field, char extVal) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void storeInt(int field, int extVal) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void storeShort(int field, short extVal) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void storeLong(int field, long extVal) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void storeFloat(int field, float extVal) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void storeDouble(int field, double extVal) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void storeString(int field, String extVal) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void storeObject(int field, Object extVal) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void store(int field, Object extVal) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void storeField(int field, Object value) {
-        throw new UnsupportedOperationException();
-    }
-
-    public boolean fetchBoolean(int field) {
-        throw new UnsupportedOperationException();
-    }
-
-    public byte fetchByte(int field) {
-        throw new UnsupportedOperationException();
-    }
-
-    public char fetchChar(int field) {
-        throw new UnsupportedOperationException();
-    }
-
-    public short fetchShort(int field) {
-        throw new UnsupportedOperationException();
-    }
-
-    public int fetchInt(int field) {
-        throw new UnsupportedOperationException();
-    }
-
-    public long fetchLong(int field) {
-        throw new UnsupportedOperationException();
-    }
-
-    public float fetchFloat(int field) {
-        throw new UnsupportedOperationException();
-    }
-
-    public double fetchDouble(int field) {
-        throw new UnsupportedOperationException();
-    }
-
-    public String fetchString(int field) {
-        throw new UnsupportedOperationException();
-    }
-
-    public Object fetchObject(int field) {
-        throw new UnsupportedOperationException();
-    }
-
-    public Object fetch(int field) {
-        throw new UnsupportedOperationException();
-    }
-
-    public Object fetchField(int field, boolean transitions) {
-        throw new UnsupportedOperationException();
-    }
-
-    public Object fetchInitialField(int field) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void setRemote(int field, Object value) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void lock() {
-        if (_lock != null)
-            _lock.lock();
-    }
-
-    public void unlock() {
-        if (_lock != null)
-            _lock.unlock();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.kernel;
+
+import java.io.IOException;
+import java.io.ObjectOutput;
+import java.io.Serializable;
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.openjpa.enhance.PersistenceCapable;
+import org.apache.openjpa.enhance.StateManager;
+import org.apache.openjpa.lib.util.Localizer;
+import java.util.concurrent.locks.ReentrantLock;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.FieldMetaData;
+import org.apache.openjpa.meta.JavaTypes;
+import org.apache.openjpa.meta.ValueMetaData;
+import org.apache.openjpa.util.Exceptions;
+import org.apache.openjpa.util.Proxy;
+import org.apache.openjpa.util.UnsupportedException;
+import org.apache.openjpa.util.ImplHelper;
+
+/**
+ * Internal state manager for detached instances. Does not fully
+ * implement {@link OpenJPAStateManager} contract to allow for serialization.
+ *
+ * @author Steve Kim
+ * @nojavadoc
+ */
+public class DetachedStateManager
+    extends AttachStrategy
+    implements OpenJPAStateManager, Serializable {
+
+    private static final Localizer _loc = Localizer.forPackage
+        (DetachedStateManager.class);
+
+    private final PersistenceCapable _pc;
+    private final boolean _embedded;
+    private final boolean _access;
+    private final BitSet _loaded;
+    private final BitSet _dirty;
+    private final Object _oid;
+    private final Object _version;
+    private final ReentrantLock _lock;
+
+    /**
+     * Constructor.
+     *
+     * @param pc the managed instance
+     * @param sm the instance's state manager
+     * @param load the set of detached field indexes
+     * @param access whether to allow access to unloaded fields
+     * @param multithreaded whether the instance will be used concurrently
+     * by multiple threads
+     */
+    public DetachedStateManager(PersistenceCapable pc, OpenJPAStateManager sm,
+        BitSet load, boolean access, boolean multithreaded) {
+        _pc = pc;
+        _embedded = sm.isEmbedded();
+        _loaded = load;
+        _access = access;
+        _dirty = new BitSet(_loaded.length());
+        _oid = sm.fetchObjectId();
+        _version = sm.getVersion();
+        if (multithreaded)
+            _lock = new ReentrantLock();
+        else
+            _lock = null;
+    }
+
+    /////////////////////////////////
+    // AttachStrategy implementation
+    /////////////////////////////////
+
+    public Object attach(AttachManager manager, Object toAttach,
+        ClassMetaData meta, PersistenceCapable into, OpenJPAStateManager owner,
+        ValueMetaData ownerMeta, boolean explicit) {
+        BrokerImpl broker = manager.getBroker();
+        StateManagerImpl sm;
+        if (_embedded) {
+            if (_dirty.length () > 0)
+                owner.dirty(ownerMeta.getFieldMetaData().getIndex());
+            sm = (StateManagerImpl) broker.embed(_pc, _oid, owner, ownerMeta);
+            ImplHelper.toPersistenceCapable(toAttach, broker.getConfiguration())
+                .pcReplaceStateManager(this);
+        } else {
+            PCState state = (_dirty.length() > 0) ? PCState.PDIRTY
+                : PCState.PCLEAN;
+            sm = (StateManagerImpl) broker.copy(this, state);
+        }
+        PersistenceCapable pc = sm.getPersistenceCapable();
+        manager.setAttachedCopy(toAttach, pc);
+
+        manager.fireBeforeAttach(toAttach, meta);
+
+        // pre-load for efficiency: current field values for restore, dependent
+        // for delete
+        FieldMetaData[] fields = meta.getFields();
+        int restore = broker.getRestoreState();
+        if (_dirty.length() > 0) {
+            BitSet load = new BitSet(fields.length);
+            for (int i = 0; i < fields.length; i++) {
+                if (!_dirty.get(i))
+                    continue;
+
+                switch (fields[i].getDeclaredTypeCode()) {
+                    case JavaTypes.ARRAY:
+                    case JavaTypes.COLLECTION:
+                        if (restore == RestoreState.RESTORE_ALL
+                            || fields[i].getElement().getCascadeDelete()
+                            == ValueMetaData.CASCADE_AUTO)
+                            load.set(i);
+                        break;
+                    case JavaTypes.MAP:
+                        if (restore == RestoreState.RESTORE_ALL
+                            || fields[i].getElement().getCascadeDelete()
+                            == ValueMetaData.CASCADE_AUTO
+                            || fields[i].getKey().getCascadeDelete()
+                            == ValueMetaData.CASCADE_AUTO)
+                            load.set(i);
+                        break;
+                    default:
+                        if (restore != RestoreState.RESTORE_NONE
+                            || fields[i].getCascadeDelete()
+                            == ValueMetaData.CASCADE_AUTO)
+                            load.set(i);
+                }
+            }
+            FetchConfiguration fc = broker.getFetchConfiguration();
+            sm.loadFields(load, fc, fc.getWriteLockLevel(), null);
+        }        
+        Object origVersion = sm.getVersion();
+        sm.setVersion(_version);
+
+        BitSet loaded = sm.getLoaded();
+        int set = StateManager.SET_ATTACH;
+        for (int i = 0; i < fields.length; i++) {
+            if (!_loaded.get(i))
+                continue;
+            // don't reload already loaded non-mutable objects
+            if (!_dirty.get(i) && loaded.get(i) && ignoreLoaded(fields[i]))
+                continue;
+
+            provideField(i);
+            switch (fields[i].getDeclaredTypeCode()) {
+                case JavaTypes.BOOLEAN:
+                    if (_dirty.get(i))
+                        sm.settingBooleanField(pc, i,
+                            (loaded.get(i)) && sm.fetchBooleanField(i),
+                            longval == 1, set);
+                    else
+                        sm.storeBooleanField(i, longval == 1);
+                    break;
+                case JavaTypes.BYTE:
+                    if (_dirty.get(i))
+                        sm.settingByteField(pc, i, (!loaded.get(i)) ? (byte) 0
+                            : sm.fetchByteField(i), (byte) longval, set);
+                    else
+                        sm.storeByteField(i, (byte) longval);
+                    break;
+                case JavaTypes.CHAR:
+                    if (_dirty.get(i))
+                        sm.settingCharField(pc, i, (!loaded.get(i)) ? (char) 0
+                            : sm.fetchCharField(i), (char) longval, set);
+                    else
+                        sm.storeCharField(i, (char) longval);
+                    break;
+                case JavaTypes.INT:
+                    if (_dirty.get(i))
+                        sm.settingIntField(pc, i, (!loaded.get(i)) ? 0
+                            : sm.fetchIntField(i), (int) longval, set);
+                    else
+                        sm.storeIntField(i, (int) longval);
+                    break;
+                case JavaTypes.LONG:
+                    if (_dirty.get(i))
+                        sm.settingLongField(pc, i, (!loaded.get(i)) ? 0L
+                            : sm.fetchLongField(i), longval, set);
+                    else
+                        sm.storeLongField(i, longval);
+                    break;
+                case JavaTypes.SHORT:
+                    if (_dirty.get(i))
+                        sm.settingShortField(pc, i, (!loaded.get(i)) ? (short) 0
+                            : sm.fetchShortField(i), (short) longval, set);
+                    else
+                        sm.storeShortField(i, (short) longval);
+                    break;
+                case JavaTypes.FLOAT:
+                    if (_dirty.get(i))
+                        sm.settingFloatField(pc, i, (!loaded.get(i)) ? 0F
+                            : sm.fetchFloatField(i), (float) dblval, set);
+                    else
+                        sm.storeFloatField(i, (float) dblval);
+                    break;
+                case JavaTypes.DOUBLE:
+                    if (_dirty.get(i))
+                        sm.settingDoubleField(pc, i, (!loaded.get(i)) ? 0D
+                            : sm.fetchDoubleField(i), dblval, set);
+                    else
+                        sm.storeDoubleField(i, dblval);
+                    break;
+                case JavaTypes.STRING:
+                    if (_dirty.get(i))
+                        sm.settingStringField(pc, i, (!loaded.get(i)) ? null
+                            : sm.fetchStringField(i), (String) objval, set);
+                    else
+                        sm.storeStringField(i, (String) objval);
+                    objval = null;
+                    break;
+                case JavaTypes.PC:
+                case JavaTypes.PC_UNTYPED:
+                    if (fields[i].getCascadeAttach() == ValueMetaData
+                        .CASCADE_NONE)
+                        objval = getReference(manager, objval, sm, fields[i]);
+                    else {
+                        PersistenceCapable toPC = null;
+                        if (objval != null && fields[i].isEmbeddedPC())
+                            toPC = ImplHelper.toPersistenceCapable(objval,
+                                broker.getConfiguration());
+                        objval = manager.attach(objval, toPC, sm, fields[i],
+                            false);
+                    }
+                    if (_dirty.get(i))
+                        sm.settingObjectField(pc, i, (!loaded.get(i)) ? null
+                            : sm.fetchObjectField(i), objval, set);
+                    else
+                        sm.storeObjectField(i, objval);
+                    objval = null;
+                    break;
+                case JavaTypes.COLLECTION:
+                    Collection coll = (Collection) objval;
+                    objval = null;
+                    if (coll != null)
+                        coll = attachCollection(manager, coll, sm, fields[i]);
+                    if (_dirty.get(i))
+                        sm.settingObjectField(pc, i, (!loaded.get(i)) ? null
+                            : sm.fetchObjectField(i), coll, set);
+                    else
+                        sm.storeObjectField(i, coll);
+                    break;
+                case JavaTypes.MAP:
+                    Map map = (Map) objval;
+                    objval = null;
+                    if (map != null)
+                        map = attachMap(manager, map, sm, fields[i]);
+                    if (_dirty.get(i))
+                        sm.settingObjectField(pc, i, (!loaded.get(i)) ? null
+                            : sm.fetchObjectField(i), map, set);
+                    else
+                        sm.storeObjectField(i, map);
+                    break;
+                default:
+                    if (_dirty.get(i))
+                        sm.settingObjectField(pc, i, (!loaded.get(i)) ? null
+                            : sm.fetchObjectField(i), objval, set);
+                    else
+                        sm.storeObjectField(i, objval);
+                    objval = null;
+            }
+        }
+        pc.pcReplaceStateManager(sm);
+
+        // if we were clean at least make sure a version check is done to
+        // prevent using old state
+        if (!sm.isVersionCheckRequired() && broker.isActive()
+            && _version != origVersion && (origVersion == null 
+            || broker.getStoreManager().compareVersion(sm, _version, 
+            origVersion) != StoreManager.VERSION_SAME)) {
+            broker.transactional(sm.getManagedInstance(), false, 
+                manager.getBehavior());
+        }
+
+        return sm.getManagedInstance();
+    }
+
+    protected Object getDetachedObjectId(AttachManager manager,
+        Object toAttach) {
+        return _oid;
+    }
+
+    void provideField(int field) {
+        _pc.pcProvideField(field);
+    }
+
+    protected void provideField(Object toAttach, StateManagerImpl sm,
+        int field) {
+        provideField(field);
+    }
+
+    /**
+     * Ignore if the field is not dirty but loaded
+     */
+    protected static boolean ignoreLoaded(FieldMetaData fmd) {
+        switch (fmd.getTypeCode()) {
+            case JavaTypes.BOOLEAN:
+            case JavaTypes.BOOLEAN_OBJ:
+            case JavaTypes.BYTE:
+            case JavaTypes.BYTE_OBJ:
+            case JavaTypes.INT:
+            case JavaTypes.INT_OBJ:
+            case JavaTypes.LONG:
+            case JavaTypes.LONG_OBJ:
+            case JavaTypes.SHORT:
+            case JavaTypes.SHORT_OBJ:
+            case JavaTypes.DOUBLE:
+            case JavaTypes.DOUBLE_OBJ:
+            case JavaTypes.FLOAT:
+            case JavaTypes.FLOAT_OBJ:
+            case JavaTypes.CHAR:
+            case JavaTypes.CHAR_OBJ:
+            case JavaTypes.STRING:
+                return true;
+        }
+        return false;
+    }
+
+    ///////////////////////////////
+    // StateManager implementation
+    ///////////////////////////////
+
+    public Object getGenericContext() {
+        return null;
+    }
+
+    public Object getPCPrimaryKey(Object oid, int field) {
+        throw new UnsupportedOperationException();
+    }
+
+    public StateManager replaceStateManager(StateManager sm) {
+        return sm;
+    }
+
+    public Object getVersion() {
+        return _version;
+    }
+
+    public void setVersion(Object version) {
+        throw new UnsupportedException();
+    }
+
+    public boolean isDirty() {
+        return _dirty.length() != 0;
+    }
+
+    public boolean isTransactional() {
+        return false;
+    }
+
+    public boolean isPersistent() {
+        return false;
+    }
+
+    public boolean isNew() {
+        return false;
+    }
+
+    public boolean isDeleted() {
+        return false;
+    }
+
+    public boolean isDetached() {
+        return true;
+    }
+
+    public boolean isVersionUpdateRequired() {
+        return false;
+    }
+
+    public boolean isVersionCheckRequired() {
+        return false;
+    }
+
+    public void dirty(String field) {
+        // should we store ClassMetaData?
+        throw new UnsupportedException();
+    }
+
+    public Object fetchObjectId() {
+        return _oid;
+    }
+
+    public void accessingField(int idx) {
+        if (!_access && !_loaded.get(idx))
+        	// do not access the pc fields by implictly invoking _pc.toString()
+        	// may cause infinite loop if again tries to access unloaded field 
+            throw new IllegalStateException(_loc.get("unloaded-detached",
+               Exceptions.toString(_pc)).getMessage());
+    }
+
+    public boolean serializing() {
+        return false;
+    }
+
+    public boolean writeDetached(ObjectOutput out)
+        throws IOException {
+        out.writeObject(_pc.pcGetDetachedState());
+        out.writeObject(this);
+        return false;
+    }
+
+    public void proxyDetachedDeserialized(int idx) {
+        lock();
+        try {
+            _pc.pcProvideField(idx);
+            if (objval instanceof Proxy)
+                ((Proxy) objval).setOwner(this, idx);
+            objval = null;
+        } finally {
+            unlock();
+        }
+    }
+
+    public void settingBooleanField(PersistenceCapable pc, int idx,
+        boolean cur, boolean next, int set) {
+        accessingField(idx);
+        if (cur == next || !_loaded.get(idx))
+            return;
+        lock();
+        try {
+            _dirty.set(idx);
+            longval = next ? 1 : 0;
+            pc.pcReplaceField(idx);
+        } finally {
+            unlock();
+        }
+    }
+
+    public void settingCharField(PersistenceCapable pc, int idx, char cur,
+        char next, int set) {
+        accessingField(idx);
+        if (cur == next || !_loaded.get(idx))
+            return;
+        lock();
+        try {
+            _dirty.set(idx);
+            longval = next;
+            pc.pcReplaceField(idx);
+        } finally {
+            unlock();
+        }
+    }
+
+    public void settingByteField(PersistenceCapable pc, int idx, byte cur,
+        byte next, int set) {
+        accessingField(idx);
+        if (cur == next || !_loaded.get(idx))
+            return;
+        lock();
+        try {
+            _dirty.set(idx);
+            longval = next;
+            pc.pcReplaceField(idx);
+        } finally {
+            unlock();
+        }
+    }
+
+    public void settingShortField(PersistenceCapable pc, int idx, short cur,
+        short next, int set) {
+        accessingField(idx);
+        if (cur == next || !_loaded.get(idx))
+            return;
+        lock();
+        try {
+            _dirty.set(idx);
+            longval = next;
+            pc.pcReplaceField(idx);
+        } finally {
+            unlock();
+        }
+    }
+
+    public void settingIntField(PersistenceCapable pc, int idx, int cur,
+        int next, int set) {
+        accessingField(idx);
+        if (cur == next || !_loaded.get(idx))
+            return;
+        lock();
+        try {
+            _dirty.set(idx);
+            longval = next;
+            pc.pcReplaceField(idx);
+        } finally {
+            unlock();
+        }
+    }
+
+    public void settingLongField(PersistenceCapable pc, int idx, long cur,
+        long next, int set) {
+        accessingField(idx);
+        if (cur == next || !_loaded.get(idx))
+            return;
+        lock();
+        try {
+            _dirty.set(idx);
+            longval = next;
+            pc.pcReplaceField(idx);
+        } finally {
+            unlock();
+        }
+    }
+
+    public void settingFloatField(PersistenceCapable pc, int idx, float cur,
+        float next, int set) {
+        accessingField(idx);
+        if (cur == next || !_loaded.get(idx))
+            return;
+        lock();
+        try {
+            _dirty.set(idx);
+            dblval = next;
+            pc.pcReplaceField(idx);
+        } finally {
+            unlock();
+        }
+    }
+
+    public void settingDoubleField(PersistenceCapable pc, int idx, double cur,
+        double next, int set) {
+        accessingField(idx);
+        if (cur == next || !_loaded.get(idx))
+            return;
+        lock();
+        try {
+            _dirty.set(idx);
+            dblval = next;
+            pc.pcReplaceField(idx);
+        } finally {
+            unlock();
+        }
+    }
+
+    public void settingStringField(PersistenceCapable pc, int idx, String cur,
+        String next, int set) {
+        accessingField(idx);
+        if (cur == next || (cur != null && cur.equals(next))
+                || !_loaded.get(idx))
+            return;
+        lock();
+        try {
+            _dirty.set(idx);
+            objval = next;
+            pc.pcReplaceField(idx);
+        } finally {
+            unlock();
+            objval = null;
+        }
+    }
+
+    public void settingObjectField(PersistenceCapable pc, int idx, Object cur,
+        Object next, int set) {
+        accessingField(idx);
+        if (cur == next || !_loaded.get(idx))
+            return;
+        lock();
+        try {
+            _dirty.set(idx);
+            objval = next;
+            pc.pcReplaceField(idx);
+        } finally {
+            unlock();
+            objval = null;
+        }
+    }
+
+    public void providedBooleanField(PersistenceCapable pc, int idx,
+        boolean cur) {
+        longval = cur ? 1 : 0;
+    }
+
+    public void providedCharField(PersistenceCapable pc, int idx, char cur) {
+        longval = cur;
+    }
+
+    public void providedByteField(PersistenceCapable pc, int idx, byte cur) {
+        longval = cur;
+    }
+
+    public void providedShortField(PersistenceCapable pc, int idx, short cur) {
+        longval = cur;
+    }
+
+    public void providedIntField(PersistenceCapable pc, int idx, int cur) {
+        longval = cur;
+    }
+
+    public void providedLongField(PersistenceCapable pc, int idx, long cur) {
+        longval = cur;
+    }
+
+    public void providedFloatField(PersistenceCapable pc, int idx, float cur) {
+        dblval = cur;
+    }
+
+    public void providedDoubleField(PersistenceCapable pc, int idx,
+        double cur) {
+        dblval = cur;
+    }
+
+    public void providedStringField(PersistenceCapable pc, int idx,
+        String cur) {
+        objval = cur;
+    }
+
+    public void providedObjectField(PersistenceCapable pc, int idx,
+        Object cur) {
+        objval = cur;
+    }
+
+    public boolean replaceBooleanField(PersistenceCapable pc, int idx) {
+        return longval == 1;
+    }
+
+    public char replaceCharField(PersistenceCapable pc, int idx) {
+        return (char) longval;
+    }
+
+    public byte replaceByteField(PersistenceCapable pc, int idx) {
+        return (byte) longval;
+    }
+
+    public short replaceShortField(PersistenceCapable pc, int idx) {
+        return (short) longval;
+    }
+
+    public int replaceIntField(PersistenceCapable pc, int idx) {
+        return (int) longval;
+    }
+
+    public long replaceLongField(PersistenceCapable pc, int idx) {
+        return longval;
+    }
+
+    public float replaceFloatField(PersistenceCapable pc, int idx) {
+        return (float) dblval;
+    }
+
+    public double replaceDoubleField(PersistenceCapable pc, int idx) {
+        return dblval;
+    }
+
+    public String replaceStringField(PersistenceCapable pc, int idx) {
+        String str = (String) objval;
+        objval = null;
+        return str;
+    }
+
+    public Object replaceObjectField(PersistenceCapable pc, int idx) {
+        Object ret = objval;
+        objval = null;
+        return ret;
+    }
+
+    //////////////////////////////////////
+    // OpenJPAStateManager implementation
+    //////////////////////////////////////
+
+    public void initialize(Class forType, PCState state) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void load(FetchConfiguration fetch) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Object getManagedInstance() {
+        return _pc;
+    }
+
+    public PersistenceCapable getPersistenceCapable() {
+        return _pc;
+    }
+
+    public ClassMetaData getMetaData() {
+        throw new UnsupportedOperationException();
+    }
+
+    public OpenJPAStateManager getOwner() {
+        throw new UnsupportedOperationException();
+    }
+
+    public int getOwnerIndex() {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean isEmbedded() {
+        return _embedded;
+    }
+
+    public boolean isFlushed() {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean isFlushedDirty() {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean isProvisional() {
+        throw new UnsupportedOperationException();
+    }
+
+    public BitSet getLoaded() {
+        return _loaded;
+    }
+
+    public BitSet getDirty() {
+        return _dirty;
+    }
+
+    public BitSet getFlushed() {
+        throw new UnsupportedOperationException();
+    }
+
+    public BitSet getUnloaded(FetchConfiguration fetch) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Object newProxy(int field) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Object newFieldProxy(int field) {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean isDefaultValue(int field) {
+        throw new UnsupportedOperationException();
+    }
+
+    public StoreContext getContext() {
+        return null;
+    }
+
+    public PCState getPCState() {
+        throw new UnsupportedOperationException();
+    }
+
+    public Object getObjectId() {
+        return _oid;
+    }
+
+    public void setObjectId(Object oid) {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean assignObjectId(boolean flush) {
+        return true;
+    }
+
+    public Object getId() {
+        return getObjectId();
+    }
+
+    public Object getLock() {
+        throw new UnsupportedOperationException();
+    }
+
+    public void setLock(Object lock) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void setNextVersion(Object version) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Object getImplData() {
+        throw new UnsupportedOperationException();
+    }
+
+    public Object setImplData(Object data, boolean cacheable) {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean isImplDataCacheable() {
+        return false;
+    }
+
+    public Object getImplData(int field) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Object setImplData(int field, Object data) {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean isImplDataCacheable(int field) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Object getIntermediate(int field) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void setIntermediate(int field, Object data) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void removed(int field, Object removed, boolean key) {
+        dirty(field);
+    }
+
+    public boolean beforeRefresh(boolean all) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void dirty(int field) {
+        lock();
+        try {
+            _dirty.set(field);
+        } finally {
+            unlock();
+        }
+    }
+
+    public void storeBoolean(int field, boolean extVal) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void storeByte(int field, byte extVal) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void storeChar(int field, char extVal) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void storeInt(int field, int extVal) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void storeShort(int field, short extVal) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void storeLong(int field, long extVal) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void storeFloat(int field, float extVal) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void storeDouble(int field, double extVal) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void storeString(int field, String extVal) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void storeObject(int field, Object extVal) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void store(int field, Object extVal) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void storeField(int field, Object value) {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean fetchBoolean(int field) {
+        throw new UnsupportedOperationException();
+    }
+
+    public byte fetchByte(int field) {
+        throw new UnsupportedOperationException();
+    }
+
+    public char fetchChar(int field) {
+        throw new UnsupportedOperationException();
+    }
+
+    public short fetchShort(int field) {
+        throw new UnsupportedOperationException();
+    }
+
+    public int fetchInt(int field) {
+        throw new UnsupportedOperationException();
+    }
+
+    public long fetchLong(int field) {
+        throw new UnsupportedOperationException();
+    }
+
+    public float fetchFloat(int field) {
+        throw new UnsupportedOperationException();
+    }
+
+    public double fetchDouble(int field) {
+        throw new UnsupportedOperationException();
+    }
+
+    public String fetchString(int field) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Object fetchObject(int field) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Object fetch(int field) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Object fetchField(int field, boolean transitions) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Object fetchInitialField(int field) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void setRemote(int field, Object value) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void lock() {
+        if (_lock != null)
+            _lock.lock();
+    }
+
+    public void unlock() {
+        if (_lock != null)
+            _lock.unlock();
+    }
+}

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ExtentImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ExtentImpl.java?rev=640685&r1=640684&r2=640685&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ExtentImpl.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ExtentImpl.java Mon Mar 24 20:37:56 2008
@@ -1,353 +1,353 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-package org.apache.openjpa.kernel;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.NoSuchElementException;
-
-import org.apache.commons.collections.Predicate;
-import org.apache.commons.collections.iterators.FilterIterator;
-import org.apache.commons.collections.iterators.IteratorChain;
-import org.apache.openjpa.lib.rop.ResultObjectProvider;
-import org.apache.openjpa.lib.rop.ResultObjectProviderIterator;
-import org.apache.openjpa.lib.util.Closeable;
-import org.apache.openjpa.lib.util.ReferenceHashSet;
-import org.apache.openjpa.lib.util.concurrent.ReentrantLock;
-import org.apache.openjpa.meta.ClassMetaData;
-import org.apache.openjpa.meta.MetaDataRepository;
-import org.apache.openjpa.util.GeneralException;
-import org.apache.openjpa.util.ImplHelper;
-import org.apache.openjpa.util.OpenJPAException;
-
-/**
- * Representation of all members of a persistent class.
- *
- * @author Abe White
- * @author Patrick Linskey
- * @nojavadoc
- */
-public class ExtentImpl
-    implements Extent {
-
-    private static final ClassMetaData[] EMPTY_METAS = new ClassMetaData[0];
-
-    private final Broker _broker;
-    private final Class _type;
-    private final boolean _subs;
-    private final FetchConfiguration _fc;
-    private final ReentrantLock _lock;
-    private boolean _ignore = false;
-
-    // set of open iterators
-    private ReferenceHashSet _openItrs = null;
-
-    /**
-     * Constructor.
-     *
-     * @param broker the owning broker
-     * @param type the candidate class
-     * @param subs whether subclasses are included in the extent
-     */
-    ExtentImpl(Broker broker, Class type, boolean subs,
-        FetchConfiguration fetch) {
-        _broker = broker;
-        _type = type;
-        _subs = subs;
-        if (fetch != null)
-            _fc = fetch;
-        else
-            _fc = (FetchConfiguration) broker.getFetchConfiguration().clone();
-        _ignore = broker.getIgnoreChanges();
-        if (broker.getMultithreaded())
-            _lock = new ReentrantLock();
-        else
-            _lock = null;
-    }
-
-    public FetchConfiguration getFetchConfiguration() {
-        return _fc;
-    }
-
-    public boolean getIgnoreChanges() {
-        return _ignore;
-    }
-
-    public void setIgnoreChanges(boolean ignoreChanges) {
-        _broker.assertOpen();
-        _ignore = ignoreChanges;
-    }
-
-    public List list() {
-        List list = new ArrayList();
-        Iterator itr = iterator();
-        try {
-            while (itr.hasNext())
-                list.add(itr.next());
-            return list;
-        } finally {
-            ImplHelper.close(itr);
-        }
-    }
-
-    public Iterator iterator() {
-        _broker.assertNontransactionalRead();
-        CloseableIterator citr = null;
-        try {
-            // create an iterator chain; add pnew objects if transactional
-            CloseableIteratorChain chain = new CloseableIteratorChain();
-            boolean trans = !_ignore && _broker.isActive();
-            if (trans)
-                chain.addIterator(new FilterNewIterator());
-
-            // add database iterators for each implementing class
-            MetaDataRepository repos = _broker.getConfiguration().
-                getMetaDataRepositoryInstance();
-            ClassMetaData meta = repos.getMetaData(_type,
-                _broker.getClassLoader(), false);
-
-            ClassMetaData[] metas;
-            if (meta != null && (!_subs || !meta.isManagedInterface())
-                && (meta.isMapped() || (_subs
-                && meta.getMappedPCSubclassMetaDatas().length > 0)))
-                metas = new ClassMetaData[]{ meta };
-            else if (_subs && (meta == null || meta.isManagedInterface()))
-                metas = repos.getImplementorMetaDatas(_type,
-                    _broker.getClassLoader(), false);
-            else
-                metas = EMPTY_METAS;
-
-            ResultObjectProvider rop;
-            for (int i = 0; i < metas.length; i++) {
-                rop = _broker.getStoreManager().executeExtent(metas[i],
-                    _subs, _fc);
-                if (rop != null)
-                    chain.addIterator(new ResultObjectProviderIterator(rop));
-            }
-
-            // filter deleted objects if transactional
-            if (trans)
-                citr = new FilterDeletedIterator(chain);
-            else
-                citr = chain;
-            citr.setRemoveOnClose(this);
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (RuntimeException re) {
-            throw new GeneralException(re);
-        }
-
-        lock();
-        try {
-            if (_openItrs == null)
-                _openItrs = new ReferenceHashSet(ReferenceHashSet.WEAK);
-            _openItrs.add(citr);
-        } finally {
-            unlock();
-        }
-        return citr;
-    }
-
-    public Broker getBroker() {
-        return _broker;
-    }
-
-    public Class getElementType() {
-        return _type;
-    }
-
-    public boolean hasSubclasses() {
-        return _subs;
-    }
-
-    public void closeAll() {
-        if (_openItrs == null)
-            return;
-
-        lock();
-        try {
-            CloseableIterator citr;
-            for (Iterator itr = _openItrs.iterator(); itr.hasNext();) {
-                citr = (CloseableIterator) itr.next();
-                citr.setRemoveOnClose(null);
-                try {
-                    citr.close();
-                } catch (Exception e) {
-                }
-            }
-            _openItrs.clear();
-        } catch (OpenJPAException ke) {
-            throw ke;
-        } catch (RuntimeException re) {
-            throw new GeneralException(re);
-        } finally {
-            unlock();
-        }
-    }
-
-    public void lock() {
-        if (_lock != null)
-            _lock.lock();
-    }
-
-    public void unlock() {
-        if (_lock != null)
-            _lock.unlock();
-    }
-
-    /**
-     * Closeable iterator.
-     */
-    private static interface CloseableIterator
-        extends Closeable, Iterator {
-
-        /**
-         * Set the extent to remove self from on close.
-         */
-        public void setRemoveOnClose(ExtentImpl extent);
-    }
-
-    /**
-     * Closeable {@link IteratorChain}.
-     */
-    private static class CloseableIteratorChain
-        extends IteratorChain
-        implements CloseableIterator {
-
-        private ExtentImpl _extent = null;
-        private boolean _closed = false;
-
-        public boolean hasNext() {
-            return (_closed) ? false : super.hasNext();
-        }
-
-        public Object next() {
-            if (_closed)
-                throw new NoSuchElementException();
-            return super.next();
-        }
-
-        public void remove() {
-            throw new UnsupportedOperationException();
-        }
-
-        public void setRemoveOnClose(ExtentImpl extent) {
-            _extent = extent;
-        }
-
-        public void close()
-            throws Exception {
-            if (_extent != null && _extent._openItrs != null) {
-                _extent.lock();
-                try {
-                    _extent._openItrs.remove(this);
-                } finally {
-                    _extent.unlock();
-                }
-            }
-
-            _closed = true;
-            for (Iterator itr = getIterators().iterator(); itr.hasNext();)
-                ((Closeable) itr.next()).close();
-        }
-    }
-
-    /**
-     * {@link FilterIterator} that skips deleted objects.
-     */
-    private static class FilterDeletedIterator
-        extends FilterIterator
-        implements CloseableIterator, Predicate {
-
-        private ExtentImpl _extent = null;
-        private boolean _closed = false;
-
-        public FilterDeletedIterator(Iterator itr) {
-            super(itr);
-            setPredicate(this);
-        }
-
-        public boolean hasNext() {
-            return (_closed) ? false : super.hasNext();
-        }
-
-        public Object next() {
-            if (_closed)
-                throw new NoSuchElementException();
-            return super.next();
-        }
-
-        public void remove() {
-            throw new UnsupportedOperationException();
-        }
-
-        public void setRemoveOnClose(ExtentImpl extent) {
-            _extent = extent;
-        }
-
-        public void close()
-            throws Exception {
-            if (_extent != null && _extent._openItrs != null) {
-                _extent.lock();
-                try {
-                    _extent._openItrs.remove(this);
-                } finally {
-                    _extent.unlock();
-                }
-            }
-
-            _closed = true;
-            ((Closeable) getIterator()).close();
-        }
-
-        public boolean evaluate(Object o) {
-            return !_extent._broker.isDeleted(o);
-        }
-    }
-
-    /**
-     * Iterator over all new objects in this extent. This iterator is always
-     * wrapped, so it doesn't need to keep track of whether it's closed.
-     */
-    private class FilterNewIterator
-        extends FilterIterator
-        implements Closeable, Predicate {
-
-        public FilterNewIterator() {
-            super(_broker.getTransactionalObjects().iterator());
-            setPredicate(this);
-        }
-
-        public void close() {
-        }
-
-        public boolean evaluate(Object o) {
-            if (!_broker.isNew(o))
-                return false;
-
-            Class type = o.getClass();
-            if (!_subs && type != _type)
-                return false;
-            if (_subs && !_type.isAssignableFrom(type))
-                return false;
-            return true;
-		}
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.kernel;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+import org.apache.commons.collections.Predicate;
+import org.apache.commons.collections.iterators.FilterIterator;
+import org.apache.commons.collections.iterators.IteratorChain;
+import org.apache.openjpa.lib.rop.ResultObjectProvider;
+import org.apache.openjpa.lib.rop.ResultObjectProviderIterator;
+import org.apache.openjpa.lib.util.Closeable;
+import org.apache.openjpa.lib.util.ReferenceHashSet;
+import java.util.concurrent.locks.ReentrantLock;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.MetaDataRepository;
+import org.apache.openjpa.util.GeneralException;
+import org.apache.openjpa.util.ImplHelper;
+import org.apache.openjpa.util.OpenJPAException;
+
+/**
+ * Representation of all members of a persistent class.
+ *
+ * @author Abe White
+ * @author Patrick Linskey
+ * @nojavadoc
+ */
+public class ExtentImpl
+    implements Extent {
+
+    private static final ClassMetaData[] EMPTY_METAS = new ClassMetaData[0];
+
+    private final Broker _broker;
+    private final Class _type;
+    private final boolean _subs;
+    private final FetchConfiguration _fc;
+    private final ReentrantLock _lock;
+    private boolean _ignore = false;
+
+    // set of open iterators
+    private ReferenceHashSet _openItrs = null;
+
+    /**
+     * Constructor.
+     *
+     * @param broker the owning broker
+     * @param type the candidate class
+     * @param subs whether subclasses are included in the extent
+     */
+    ExtentImpl(Broker broker, Class type, boolean subs,
+        FetchConfiguration fetch) {
+        _broker = broker;
+        _type = type;
+        _subs = subs;
+        if (fetch != null)
+            _fc = fetch;
+        else
+            _fc = (FetchConfiguration) broker.getFetchConfiguration().clone();
+        _ignore = broker.getIgnoreChanges();
+        if (broker.getMultithreaded())
+            _lock = new ReentrantLock();
+        else
+            _lock = null;
+    }
+
+    public FetchConfiguration getFetchConfiguration() {
+        return _fc;
+    }
+
+    public boolean getIgnoreChanges() {
+        return _ignore;
+    }
+
+    public void setIgnoreChanges(boolean ignoreChanges) {
+        _broker.assertOpen();
+        _ignore = ignoreChanges;
+    }
+
+    public List list() {
+        List list = new ArrayList();
+        Iterator itr = iterator();
+        try {
+            while (itr.hasNext())
+                list.add(itr.next());
+            return list;
+        } finally {
+            ImplHelper.close(itr);
+        }
+    }
+
+    public Iterator iterator() {
+        _broker.assertNontransactionalRead();
+        CloseableIterator citr = null;
+        try {
+            // create an iterator chain; add pnew objects if transactional
+            CloseableIteratorChain chain = new CloseableIteratorChain();
+            boolean trans = !_ignore && _broker.isActive();
+            if (trans)
+                chain.addIterator(new FilterNewIterator());
+
+            // add database iterators for each implementing class
+            MetaDataRepository repos = _broker.getConfiguration().
+                getMetaDataRepositoryInstance();
+            ClassMetaData meta = repos.getMetaData(_type,
+                _broker.getClassLoader(), false);
+
+            ClassMetaData[] metas;
+            if (meta != null && (!_subs || !meta.isManagedInterface())
+                && (meta.isMapped() || (_subs
+                && meta.getMappedPCSubclassMetaDatas().length > 0)))
+                metas = new ClassMetaData[]{ meta };
+            else if (_subs && (meta == null || meta.isManagedInterface()))
+                metas = repos.getImplementorMetaDatas(_type,
+                    _broker.getClassLoader(), false);
+            else
+                metas = EMPTY_METAS;
+
+            ResultObjectProvider rop;
+            for (int i = 0; i < metas.length; i++) {
+                rop = _broker.getStoreManager().executeExtent(metas[i],
+                    _subs, _fc);
+                if (rop != null)
+                    chain.addIterator(new ResultObjectProviderIterator(rop));
+            }
+
+            // filter deleted objects if transactional
+            if (trans)
+                citr = new FilterDeletedIterator(chain);
+            else
+                citr = chain;
+            citr.setRemoveOnClose(this);
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (RuntimeException re) {
+            throw new GeneralException(re);
+        }
+
+        lock();
+        try {
+            if (_openItrs == null)
+                _openItrs = new ReferenceHashSet(ReferenceHashSet.WEAK);
+            _openItrs.add(citr);
+        } finally {
+            unlock();
+        }
+        return citr;
+    }
+
+    public Broker getBroker() {
+        return _broker;
+    }
+
+    public Class getElementType() {
+        return _type;
+    }
+
+    public boolean hasSubclasses() {
+        return _subs;
+    }
+
+    public void closeAll() {
+        if (_openItrs == null)
+            return;
+
+        lock();
+        try {
+            CloseableIterator citr;
+            for (Iterator itr = _openItrs.iterator(); itr.hasNext();) {
+                citr = (CloseableIterator) itr.next();
+                citr.setRemoveOnClose(null);
+                try {
+                    citr.close();
+                } catch (Exception e) {
+                }
+            }
+            _openItrs.clear();
+        } catch (OpenJPAException ke) {
+            throw ke;
+        } catch (RuntimeException re) {
+            throw new GeneralException(re);
+        } finally {
+            unlock();
+        }
+    }
+
+    public void lock() {
+        if (_lock != null)
+            _lock.lock();
+    }
+
+    public void unlock() {
+        if (_lock != null)
+            _lock.unlock();
+    }
+
+    /**
+     * Closeable iterator.
+     */
+    private static interface CloseableIterator
+        extends Closeable, Iterator {
+
+        /**
+         * Set the extent to remove self from on close.
+         */
+        public void setRemoveOnClose(ExtentImpl extent);
+    }
+
+    /**
+     * Closeable {@link IteratorChain}.
+     */
+    private static class CloseableIteratorChain
+        extends IteratorChain
+        implements CloseableIterator {
+
+        private ExtentImpl _extent = null;
+        private boolean _closed = false;
+
+        public boolean hasNext() {
+            return (_closed) ? false : super.hasNext();
+        }
+
+        public Object next() {
+            if (_closed)
+                throw new NoSuchElementException();
+            return super.next();
+        }
+
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+
+        public void setRemoveOnClose(ExtentImpl extent) {
+            _extent = extent;
+        }
+
+        public void close()
+            throws Exception {
+            if (_extent != null && _extent._openItrs != null) {
+                _extent.lock();
+                try {
+                    _extent._openItrs.remove(this);
+                } finally {
+                    _extent.unlock();
+                }
+            }
+
+            _closed = true;
+            for (Iterator itr = getIterators().iterator(); itr.hasNext();)
+                ((Closeable) itr.next()).close();
+        }
+    }
+
+    /**
+     * {@link FilterIterator} that skips deleted objects.
+     */
+    private static class FilterDeletedIterator
+        extends FilterIterator
+        implements CloseableIterator, Predicate {
+
+        private ExtentImpl _extent = null;
+        private boolean _closed = false;
+
+        public FilterDeletedIterator(Iterator itr) {
+            super(itr);
+            setPredicate(this);
+        }
+
+        public boolean hasNext() {
+            return (_closed) ? false : super.hasNext();
+        }
+
+        public Object next() {
+            if (_closed)
+                throw new NoSuchElementException();
+            return super.next();
+        }
+
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+
+        public void setRemoveOnClose(ExtentImpl extent) {
+            _extent = extent;
+        }
+
+        public void close()
+            throws Exception {
+            if (_extent != null && _extent._openItrs != null) {
+                _extent.lock();
+                try {
+                    _extent._openItrs.remove(this);
+                } finally {
+                    _extent.unlock();
+                }
+            }
+
+            _closed = true;
+            ((Closeable) getIterator()).close();
+        }
+
+        public boolean evaluate(Object o) {
+            return !_extent._broker.isDeleted(o);
+        }
+    }
+
+    /**
+     * Iterator over all new objects in this extent. This iterator is always
+     * wrapped, so it doesn't need to keep track of whether it's closed.
+     */
+    private class FilterNewIterator
+        extends FilterIterator
+        implements Closeable, Predicate {
+
+        public FilterNewIterator() {
+            super(_broker.getTransactionalObjects().iterator());
+            setPredicate(this);
+        }
+
+        public void close() {
+        }
+
+        public boolean evaluate(Object o) {
+            if (!_broker.isNew(o))
+                return false;
+
+            Class type = o.getClass();
+            if (!_subs && type != _type)
+                return false;
+            if (_subs && !_type.isAssignableFrom(type))
+                return false;
+            return true;
+		}
+	}
+}



Mime
View raw message