Return-Path: Delivered-To: apmail-openjpa-dev-archive@www.apache.org Received: (qmail 10022 invoked from network); 30 Sep 2008 20:06:18 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 30 Sep 2008 20:06:18 -0000 Received: (qmail 37064 invoked by uid 500); 30 Sep 2008 20:06:16 -0000 Delivered-To: apmail-openjpa-dev-archive@openjpa.apache.org Received: (qmail 37045 invoked by uid 500); 30 Sep 2008 20:06:16 -0000 Mailing-List: contact dev-help@openjpa.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@openjpa.apache.org Delivered-To: mailing list dev@openjpa.apache.org Received: (qmail 37034 invoked by uid 99); 30 Sep 2008 20:06:16 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 30 Sep 2008 13:06:16 -0700 X-ASF-Spam-Status: No, hits=-4.0 required=10.0 tests=RCVD_IN_DNSWL_MED,SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: local policy) Received: from [192.18.43.133] (HELO sca-es-mail-2.sun.com) (192.18.43.133) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 30 Sep 2008 20:05:14 +0000 Received: from fe-sfbay-10.sun.com ([192.18.43.129]) by sca-es-mail-2.sun.com (8.13.7+Sun/8.12.9) with ESMTP id m8UK5meG001224 for ; Tue, 30 Sep 2008 13:05:48 -0700 (PDT) Received: from conversion-daemon.fe-sfbay-10.sun.com by fe-sfbay-10.sun.com (Sun Java System Messaging Server 6.2-8.04 (built Feb 28 2007)) id <0K8000C01VUKQF00@fe-sfbay-10.sun.com> (original mail from Craig.Russell@Sun.COM) for dev@openjpa.apache.org; Tue, 30 Sep 2008 13:05:48 -0700 (PDT) Received: from dhcp-usca14-133-243.SFBay.Sun.COM ([129.145.133.243]) by fe-sfbay-10.sun.com (Sun Java System Messaging Server 6.2-8.04 (built Feb 28 2007)) with ESMTPSA id <0K80008Z0YHFLM30@fe-sfbay-10.sun.com> for dev@openjpa.apache.org; Tue, 30 Sep 2008 13:05:39 -0700 (PDT) Date: Tue, 30 Sep 2008 13:05:38 -0700 From: Craig L Russell Subject: Re: svn commit: r700563 [2/3] - in /openjpa/trunk: openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbedded.java In-reply-to: <20080930194212.131E02388A08@eris.apache.org> Sender: Craig.Russell@Sun.COM To: dev@openjpa.apache.org Message-id: <7D42FF78-9B63-4530-B7B3-672481CF9856@SUN.com> MIME-version: 1.0 X-Mailer: Apple Mail (2.929.2) Content-type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha1; boundary=Apple-Mail-95--315197212 References: <20080930194212.131E02388A08@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org --Apple-Mail-95--315197212 Content-Type: text/plain; charset=US-ASCII; format=flowed; delsp=yes Content-Transfer-Encoding: 7bit What went wrong? This diff is impossible. Line ending issues? Did you svn diff before committing? Craig On Sep 30, 2008, at 12:42 PM, jrbauer@apache.org wrote: > > Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/ > openjpa/kernel/StateManagerImpl.java > URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java?rev=700563&r1=700562&r2=700563&view=diff > = > = > = > = > = > = > = > = > ====================================================================== > --- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/ > kernel/StateManagerImpl.java (original) > +++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/ > kernel/StateManagerImpl.java Tue Sep 30 12:42:11 2008 > @@ -1,3258 +1,3259 @@ > -/* > - * 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.NotSerializableException; > -import java.io.ObjectInputStream; > -import java.io.ObjectOutput; > -import java.io.ObjectOutputStream; > -import java.io.Serializable; > -import java.lang.reflect.Modifier; > -import java.util.ArrayList; > -import java.util.Arrays; > -import java.util.BitSet; > -import java.util.Calendar; > -import java.util.Comparator; > -import java.util.Date; > -import java.util.HashMap; > -import java.util.Iterator; > -import java.util.TimeZone; > - > -import org.apache.commons.lang.StringUtils; > -import org.apache.openjpa.conf.OpenJPAConfiguration; > -import org.apache.openjpa.enhance.DynamicPersistenceCapable; > -import org.apache.openjpa.enhance.FieldManager; > -import org.apache.openjpa.enhance.ManagedInstanceProvider; > -import org.apache.openjpa.enhance.PCRegistry; > -import org.apache.openjpa.enhance.PersistenceCapable; > -import org.apache.openjpa.enhance.RedefinitionHelper; > -import org.apache.openjpa.enhance.StateManager; > -import org.apache.openjpa.event.LifecycleEvent; > -import org.apache.openjpa.event.LifecycleEventManager; > -import org.apache.openjpa.lib.util.Localizer; > -import org.apache.openjpa.meta.ClassMetaData; > -import org.apache.openjpa.meta.FetchGroup; > -import org.apache.openjpa.meta.FieldMetaData; > -import org.apache.openjpa.meta.JavaTypes; > -import org.apache.openjpa.meta.UpdateStrategies; > -import org.apache.openjpa.meta.ValueMetaData; > -import org.apache.openjpa.meta.ValueStrategies; > -import org.apache.openjpa.util.ApplicationIds; > -import org.apache.openjpa.util.Exceptions; > -import org.apache.openjpa.util.ImplHelper; > -import org.apache.openjpa.util.InternalException; > -import org.apache.openjpa.util.InvalidStateException; > -import org.apache.openjpa.util.ObjectNotFoundException; > -import org.apache.openjpa.util.OpenJPAId; > -import org.apache.openjpa.util.ProxyManager; > -import org.apache.openjpa.util.RuntimeExceptionTranslator; > -import org.apache.openjpa.util.UserException; > -import serp.util.Numbers; > - > -/** > - * Implementation of the {@link OpenJPAStateManager} interface for > use > - * with this runtime. Each state manager manages the state of a > single > - * persistence capable instance. The state manager is also > responsible for > - * all communications about the instance to the {@link StoreManager}. > - * The state manager uses the State pattern in both its > interaction with > - * the governed instance and its interaction with the broker. > - * In its interactions with the persistence capable instance, it > uses the > - * {@link FieldManager} interface. Similarly, when interacting with > the > - * broker, it uses the {@link PCState} singleton that represents > - * the current lifecycle state of the instance. > - * > - * @author Abe White > - */ > -public class StateManagerImpl > - implements OpenJPAStateManager, Serializable { > - > - public static final int LOAD_FGS = 0; > - public static final int LOAD_ALL = 1; > - public static final int LOAD_SERIALIZE = 2; > - > - private static final int FLAG_SAVE = 2 << 0; > - private static final int FLAG_DEREF = 2 << 1; > - private static final int FLAG_LOADED = 2 << 2; > - private static final int FLAG_READ_LOCKED = 2 << 3; > - private static final int FLAG_WRITE_LOCKED = 2 << 4; > - private static final int FLAG_OID_ASSIGNED = 2 << 5; > - private static final int FLAG_LOADING = 2 << 6; > - private static final int FLAG_PRE_DELETING = 2 << 7; > - private static final int FLAG_FLUSHED = 2 << 8; > - private static final int FLAG_PRE_FLUSHED = 2 << 9; > - private static final int FLAG_FLUSHED_DIRTY = 2 << 10; > - private static final int FLAG_IMPL_CACHE = 2 << 11; > - private static final int FLAG_INVERSES = 2 << 12; > - private static final int FLAG_NO_UNPROXY = 2 << 13; > - private static final int FLAG_VERSION_CHECK = 2 << 14; > - private static final int FLAG_VERSION_UPDATE = 2 << 15; > - private static final int FLAG_DETACHING = 2 << 16; > - > - private static final Localizer _loc = Localizer.forPackage > - (StateManagerImpl.class); > - > - // information about the instance > - private transient PersistenceCapable _pc = null; > - private transient ClassMetaData _meta = null; > - private BitSet _loaded = null; > - private BitSet _dirty = null; > - private BitSet _flush = null; > - private int _flags = 0; > - > - // id is the state manager identity; oid is the persistent > identity. oid > - // may be null for embedded and transient-transactional objects > or new > - // instances that haven't been assigned an oid. id is > reassigned to oid > - // on successful oid assignment (or flush completion if > assignment is > - // during flush) > - private Object _id = null; > - private Object _oid = null; > - > - // the managing persistence manager and lifecycle state > - private transient BrokerImpl _broker; // this is serialized > specially > - private PCState _state = PCState.TRANSIENT; > - > - // the current and last loaded version indicators, and the lock > object > - private Object _version = null; > - private Object _loadVersion = null; > - private Object _lock = null; > - private int _readLockLevel = -1; > - private int _writeLockLevel = -1; > - > - // delegates when providing/replacing instance data > - private SingleFieldManager _single = null; > - private SaveFieldManager _saved = null; > - private FieldManager _fm = null; > - > - // impldata; field impldata and intermediate data share the > same array > - private Object _impl = null; > - private Object[] _fieldImpl = null; > - > - // information about the owner of this instance, if it is > embedded > - private StateManagerImpl _owner = null; > - private int _ownerIndex = -1; > - > - /** > - * Constructor; supply id, type metadata, and owning > persistence manager. > - */ > - protected StateManagerImpl(Object id, ClassMetaData meta, > - BrokerImpl broker) { > - _id = id; > - _meta = meta; > - _broker = broker; > - _single = new SingleFieldManager(this, broker); > - > - if (_meta.getIdentityType() == ClassMetaData.ID_UNKNOWN) > - throw new UserException(_loc.get("meta-unknownid", > _meta)); > - } > - > - /** > - * Set the owning state and field if this is an embedded > instance. > - */ > - void setOwner(StateManagerImpl owner, ValueMetaData ownerMeta) { > - _owner = owner; > - _ownerIndex = ownerMeta.getFieldMetaData().getIndex(); > - } > - > - /** > - * Whether this state manager is in the middle of a load. > - */ > - boolean isLoading() { > - return (_flags & FLAG_LOADING) > 0; > - } > - > - /** > - * Whether this state manager is in the middle of a load > initiated > - * by outside code; for any internal methods that cause > loading, the > - * loading flag is set automatically. > - */ > - void setLoading(boolean loading) { > - if (loading) > - _flags |= FLAG_LOADING; > - else > - _flags &= ~FLAG_LOADING; > - } > - > - /** > - * Set or reset the lifecycle state of the managed instance. If > the > - * transactional state of the instance changes, it will be > enlisted/ > - * delisted from the current transaction as necessary. The given > - * state will be initialized after being set. If the given state > - * is the same as the current state, this method will have no > effect. > - */ > - private void setPCState(PCState state) { > - if (_state == state) > - return; > - > - lock(); > - try { > - // notify the store manager that we're changing states; > can veto > - _broker.getStoreManager().beforeStateChange(this, > _state, state); > - > - // replace state > - boolean wasDeleted = _state.isDeleted(); > - boolean wasDirty = _state.isDirty(); > - boolean wasPending = _state.isPendingTransactional(); > - _state = state; > - > - // enlist/delist from transaction > - if (_state.isTransactional()) { > - _broker.addToTransaction(this); > - if (_state.isDeleted() != wasDeleted) > - _broker.setDirty(this, !wasDirty || isFlushed()); > - else if (_state.isDirty() && !wasDirty) > - _broker.setDirty(this, true); > - } else if (!wasPending && > _state.isPendingTransactional()) > - _broker.addToPendingTransaction(this); > - else if (wasPending && !_state.isPendingTransactional()) > - _broker.removeFromPendingTransaction(this); > - else > - _broker.removeFromTransaction(this); > - > - // initialize > - _state.initialize(this); > - if (_state.isDeleted() && !wasDeleted) > - fireLifecycleEvent(LifecycleEvent.AFTER_DELETE); > - } finally { > - unlock(); > - } > - } > - > - ////////////////////////////////////// > - // OpenJPAStateManager implementation > - ////////////////////////////////////// > - > - public void initialize(Class cls, PCState state) { > - // check to see if our current object id instance is the > - // correct id type for the specified class; this is for cases > - // when we have an application id hierarchy and we had set > the > - // metadata to a superclass id -- the subclass' id may be a > - // different class, so we need to reset it > - if (_meta.getDescribedType() != cls) { > - ClassMetaData sub = _meta.getRepository().getMetaData > - (cls, _broker.getClassLoader(), true); > - if (_oid != null) { > - if (_meta.getIdentityType() == > ClassMetaData.ID_DATASTORE) > - _oid = > _broker.getStoreManager().copyDataStoreId(_oid, > - sub); > - else if (_meta.isOpenJPAIdentity()) > - _oid = ApplicationIds.copy(_oid, sub); > - else if (sub.getObjectIdType() != > _meta.getObjectIdType()) { > - Object[] pkFields = > ApplicationIds.toPKValues(_oid, _meta); > - _oid = ApplicationIds.fromPKValues(pkFields, > sub); > - } > - } > - _meta = sub; > - } > - > - PersistenceCapable inst = PCRegistry.newInstance(cls, this, > _oid, true); > - if (inst == null) { > - // the instance was null: check to see if the instance is > - // abstract (as can sometimes be the case when the > - // class discriminator strategy is not configured > correctly) > - if (Modifier.isAbstract(cls.getModifiers())) > - throw new UserException(_loc.get("instantiate- > abstract", > - cls.getName(), _oid)); > - throw new InternalException(); > - } > - > - initialize(inst, state); > - } > - > - /** > - * Initialize with the given instance and state. > - */ > - protected void initialize(PersistenceCapable pc, PCState state) { > - if (pc == null) > - throw new UserException(_loc.get("init-null-pc", _meta)); > - if (pc.pcGetStateManager() != null && > pc.pcGetStateManager() != this) > - throw new UserException(_loc.get("init-sm-pc", > - Exceptions.toString(pc))).setFailedObject(pc); > - pc.pcReplaceStateManager(this); > - > - FieldMetaData[] fmds = _meta.getFields(); > - _loaded = new BitSet(fmds.length); > - _flush = new BitSet(fmds.length); > - _dirty = new BitSet(fmds.length); > - > - for (int i = 0; i < fmds.length; i++) { > - // mark primary key and non-persistent fields as loaded > - if (fmds[i].isPrimaryKey() > - || fmds[i].getManagement() != > fmds[i].MANAGE_PERSISTENT) > - _loaded.set(i); > - > - // record whether there are any managed inverse fields > - if (_broker.getInverseManager() != null > - && fmds[i].getInverseMetaDatas().length > 0) > - _flags |= FLAG_INVERSES; > - } > - > - pc.pcSetDetachedState(null); > - _pc = pc; > - > - if (_oid instanceof OpenJPAId) > - ((OpenJPAId) > _oid).setManagedInstanceType(_meta.getDescribedType()); > - > - // initialize our state and add ourselves to the broker's > cache > - setPCState(state); > - if (_broker.getStateManagerImplById(getObjectId(), false) > == null) { > - _broker.setStateManager(_id, this, BrokerImpl.STATUS_INIT); > - } > - if (state == PCState.PNEW) > - fireLifecycleEvent(LifecycleEvent.AFTER_PERSIST); > - > - // if this is a non-tracking PC, add a hard ref to the > appropriate data > - // sets and give it an opportunity to make a state snapshot. > - if (!isIntercepting()) { > - saveFields(true); > - if (!isNew()) > - RedefinitionHelper.assignLazyLoadProxies(this); > - } > - } > - > - /** > - * Whether or not data access in this instance is intercepted. > This differs > - * from {@link ClassMetaData#isIntercepting()} in that it > checks for > - * property access + subclassing in addition to the > redefinition / > - * enhancement checks. > - * > - * @since 1.0.0 > - */ > - public boolean isIntercepting() { > - if (getMetaData().isIntercepting()) > - return true; > - if (getMetaData().getAccessType() != > ClassMetaData.ACCESS_FIELD > - && _pc instanceof DynamicPersistenceCapable) > - return true; > - > - return false; > - } > - > - /** > - * Fire the given lifecycle event to all listeners. > - */ > - private boolean fireLifecycleEvent(int type) { > - return _broker.fireLifecycleEvent(getManagedInstance(), null, > - _meta, type); > - } > - > - public void load(FetchConfiguration fetch) { > - load(fetch, LOAD_FGS, null, null, false); > - } > - > - /** > - * Load the state of this instance based on the given fetch > configuration > - * and load mode. Return true if any data was loaded, false > otherwise. > - */ > - protected boolean load(FetchConfiguration fetch, int loadMode, > - BitSet exclude, Object sdata, boolean forWrite) { > - if (!forWrite && (!isPersistent() || isNew() || isDeleted())) > - return false; > - > - // if any fields being loaded, do state transitions for read > - BitSet fields = getUnloadedInternal(fetch, loadMode, > exclude); > - boolean active = _broker.isActive(); > - if (!forWrite && fields != null) > - beforeRead(-1); > - > - // call load even if no fields are being loaded, because it > takes > - // care of checking if the DFG is loaded, making sure > version info > - // is loaded, etc > - int lockLevel = calculateLockLevel(active, forWrite, fetch); > - boolean ret = loadFields(fields, fetch, lockLevel, sdata); > - obtainLocks(active, forWrite, lockLevel, fetch, sdata); > - return ret; > - } > - > - public Object getManagedInstance() { > - if (_pc instanceof ManagedInstanceProvider) > - return ((ManagedInstanceProvider) > _pc).getManagedInstance(); > - else > - return _pc; > - } > - > - public PersistenceCapable getPersistenceCapable() { > - return _pc; > - } > - > - public ClassMetaData getMetaData() { > - return _meta; > - } > - > - public OpenJPAStateManager getOwner() { > - return _owner; > - } > - > - public int getOwnerIndex() { > - return _ownerIndex; > - } > - > - public boolean isEmbedded() { > - return _owner != null; > - } > - > - public boolean isFlushed() { > - return (_flags & FLAG_FLUSHED) > 0; > - } > - > - public boolean isFlushedDirty() { > - return (_flags & FLAG_FLUSHED_DIRTY) > 0; > - } > - > - public BitSet getLoaded() { > - return _loaded; > - } > - > - public BitSet getFlushed() { > - return _flush; > - } > - > - public BitSet getDirty() { > - return _dirty; > - } > - > - public BitSet getUnloaded(FetchConfiguration fetch) { > - // collect fields to load from data store based on fetch > configuration > - BitSet fields = getUnloadedInternal(fetch, LOAD_FGS, null); > - return (fields == null) ? new BitSet(0) : fields; > - } > - > - /** > - * Internal version of {@link OpenJPAStateManager#getUnloaded} > that avoids > - * creating an empty bit set by returning null when there are > no unloaded > - * fields. > - */ > - private BitSet getUnloadedInternal(FetchConfiguration fetch, > int mode, > - BitSet exclude) { > - if (exclude == StoreContext.EXCLUDE_ALL) > - return null; > - > - BitSet fields = null; > - FieldMetaData[] fmds = _meta.getFields(); > - boolean load; > - for (int i = 0; i < fmds.length; i++) { > - if (_loaded.get(i) || (exclude != null && > exclude.get(i))) > - continue; > - > - switch (mode) { > - case LOAD_SERIALIZE: > - load = !fmds[i].isTransient(); > - break; > - case LOAD_FGS: > - load = fetch == null || > fetch.requiresFetch(fmds[i]) > - != FetchConfiguration.FETCH_NONE; > - break; > - default: // LOAD_ALL > - load = true; > - } > - > - if (load) { > - if (fields == null) > - fields = new BitSet(fmds.length); > - fields.set(i); > - } > - } > - return fields; > - } > - > - public StoreContext getContext() { > - return _broker; > - } > - > - /** > - * Managing broker. > - */ > - BrokerImpl getBroker() { > - return _broker; > - } > - > - public Object getId() { > - return _id; > - } > - > - public Object getObjectId() { > - StateManagerImpl sm = this; > - while (sm.getOwner() != null) > - sm = (StateManagerImpl) sm.getOwner(); > - return sm._oid; > - } > - > - public void setObjectId(Object oid) { > - _oid = oid; > - if (_pc != null && oid instanceof OpenJPAId) > - ((OpenJPAId) > oid).setManagedInstanceType(_meta.getDescribedType()); > - } > - > - public boolean assignObjectId(boolean flush) { > - lock(); > - try { > - return assignObjectId(flush, false); > - } finally { > - unlock(); > - } > - } > - > - /** > - * Ask store manager to assign our oid, optionally flushing and > - * optionally recaching on the new oid. > - */ > - boolean assignObjectId(boolean flush, boolean preFlushing) { > - if (_oid != null || isEmbedded() || !isPersistent()) > - return true; > - > - if (_broker.getStoreManager().assignObjectId(this, > preFlushing)) { > - if (!preFlushing) > - assertObjectIdAssigned(true); > - } else if (flush) > - _broker.flush(); > - else > - return false; > - return true; > - } > - > - /** > - * Make sure we were assigned an oid, and perform actions to > make it > - * permanent. > - * > - * @param recache whether to recache ourself on the new oid > - */ > - private void assertObjectIdAssigned(boolean recache) { > - if (!isNew() || isDeleted() || isProvisional() > - || (_flags & FLAG_OID_ASSIGNED) != 0) > - return; > - if (_oid == null) { > - if (_meta.getIdentityType() == > ClassMetaData.ID_DATASTORE) > - throw new InternalException(Exceptions.toString > - (getManagedInstance())); > - _oid = ApplicationIds.create(_pc, _meta); > - } > - > - Object orig = _id; > - _id = _oid; > - if (recache) { > - try { > - _broker.setStateManager(orig, this, > - BrokerImpl.STATUS_OID_ASSIGN); > - } catch (RuntimeException re) { > - _id = orig; > - _oid = null; > - throw re; > - } > - } > - _flags |= FLAG_OID_ASSIGNED; > - } > - > - /** > - * Assign the proper generated value to the given field based > on its > - * value-strategy. > - */ > - private boolean assignField(int field, boolean preFlushing) { > - OpenJPAStateManager sm = this; > - while (sm.isEmbedded()) > - sm = sm.getOwner(); > - if (!sm.isNew() || sm.isFlushed() || sm.isDeleted()) > - return false; > - > - // special-case oid fields, which require us to look inside > the oid > - // object > - FieldMetaData fmd = _meta.getField(field); > - if (fmd.getDeclaredTypeCode() == JavaTypes.OID) { > - // try to shortcut if possible > - if (_oid != null || isEmbedded() || !isPersistent()) > - return true; > - > - // check embedded fields of oid for value strategy + > default value > - FieldMetaData[] pks = > fmd.getEmbeddedMetaData().getFields(); > - OpenJPAStateManager oidsm = null; > - boolean assign = false; > - for (int i = 0; !assign && i < pks.length; i++) { > - if (pks[i].getValueStrategy() == > ValueStrategies.NONE) > - continue; > - if (oidsm == null) > - oidsm = new > ObjectIdStateManager(fetchObjectField(field), > - this, fmd); > - assign = oidsm.isDefaultValue(i); > - } > - return assign && assignObjectId(!preFlushing, > preFlushing); > - } > - > - // Just return if there's no value generation strategy > - if (fmd.getValueStrategy() == ValueStrategies.NONE) > - return false; > - > - // Throw exception if field already has a value assigned. > - // @GeneratedValue overrides POJO initial values and setter > methods > - if (!fmd.isValueGenerated() && !isDefaultValue(field)) > - throw new InvalidStateException(_loc.get( > - "existing-value-override-excep", > fmd.getFullName(false))); > - > - // for primary key fields, assign the object id and recache > so that > - // to the user, so it looks like the oid always matches the > pk fields > - if (fmd.isPrimaryKey() && !isEmbedded()) > - return assignObjectId(!preFlushing, preFlushing); > - > - // for other fields just assign the field or flush if needed > - if (_broker.getStoreManager().assignField(this, field, > preFlushing)) { > - fmd.setValueGenerated(true); > - return true; > - } > - if (!preFlushing) > - _broker.flush(); > - return !preFlushing; > - } > - > - public Object getLock() { > - return _lock; > - } > - > - public void setLock(Object lock) { > - _lock = lock; > - } > - > - public Object getVersion() { > - return _version; > - } > - > - public void setVersion(Object version) { > - _loadVersion = version; > - assignVersionField(version); > - } > - > - Object getLoadVersion() { > - return _loadVersion; > - } > - > - public void setNextVersion(Object version) { > - assignVersionField(version); > - } > - > - private void assignVersionField(Object version) { > - _version = version; > - FieldMetaData vfield = _meta.getVersionField(); > - if (vfield != null) > - store(vfield.getIndex(), JavaTypes.convert(version, > - vfield.getTypeCode())); > - } > - > - public PCState getPCState() { > - return _state; > - } > - > - public synchronized Object getImplData() { > - return _impl; > - } > - > - public synchronized Object setImplData(Object data, boolean > cacheable) { > - Object old = _impl; > - _impl = data; > - if (cacheable && data != null) > - _flags |= FLAG_IMPL_CACHE; > - else > - _flags &= ~FLAG_IMPL_CACHE; > - return old; > - } > - > - public boolean isImplDataCacheable() { > - return (_flags & FLAG_IMPL_CACHE) != 0; > - } > - > - public Object getImplData(int field) { > - return getExtraFieldData(field, true); > - } > - > - public Object setImplData(int field, Object data) { > - return setExtraFieldData(field, data, true); > - } > - > - public synchronized boolean isImplDataCacheable(int field) { > - if (_fieldImpl == null || !_loaded.get(field)) > - return false; > - if (_meta.getField(field).usesImplData() != null) > - return false; > - int idx = _meta.getExtraFieldDataIndex(field); > - return idx != -1 && _fieldImpl[idx] != null; > - } > - > - public Object getIntermediate(int field) { > - return getExtraFieldData(field, false); > - } > - > - public void setIntermediate(int field, Object data) { > - setExtraFieldData(field, data, false); > - } > - > - /** > - * Return the data from the proper index of the extra field > data array. > - */ > - private synchronized Object getExtraFieldData(int field, > boolean isLoaded) { > - // only return the field data if the field is in the right > loaded > - // state; otherwise we might return intermediate for impl > data or > - // vice versa > - if (_fieldImpl == null || _loaded.get(field) != isLoaded) > - return null; > - int idx = _meta.getExtraFieldDataIndex(field); > - return (idx == -1) ? null : _fieldImpl[idx]; > - } > - > - /** > - * Set the data from to proper index of the extra field data > array. > - */ > - private synchronized Object setExtraFieldData(int field, Object > data, > - boolean loaded) { > - int idx = _meta.getExtraFieldDataIndex(field); > - if (idx == -1) > - throw new > InternalException(String.valueOf(_meta.getField(field))); > - > - Object old = (_fieldImpl == null) ? null : _fieldImpl[idx]; > - if (data != null) { > - // cannot set if field in wrong loaded state > - if (_loaded.get(field) != loaded) > - throw new > InternalException(String.valueOf(_meta.getField > - (field))); > - > - // set data > - if (_fieldImpl == null) > - _fieldImpl = new > Object[_meta.getExtraFieldDataLength()]; > - _fieldImpl[idx] = data; > - } else if (_fieldImpl != null && _loaded.get(field) == > loaded) > - _fieldImpl[idx] = null; > - return old; > - } > - > - public Object fetch(int field) { > - Object val = fetchField(field, false); > - return _meta.getField(field).getExternalValue(val, _broker); > - } > - > - public Object fetchField(int field, boolean transitions) { > - FieldMetaData fmd = _meta.getField(field); > - if (fmd == null) > - throw new UserException(_loc.get("no-field", > - String.valueOf(field), > getManagedInstance().getClass())). > - setFailedObject(getManagedInstance()); > - > - // do normal state transitions > - if (!fmd.isPrimaryKey() && transitions) > - accessingField(field); > - > - switch (fmd.getDeclaredTypeCode()) { > - case JavaTypes.STRING: > - return fetchStringField(field); > - case JavaTypes.OBJECT: > - return fetchObjectField(field); > - case JavaTypes.BOOLEAN: > - return (fetchBooleanField(field)) ? Boolean.TRUE > - : Boolean.FALSE; > - case JavaTypes.BYTE: > - return new Byte(fetchByteField(field)); > - case JavaTypes.CHAR: > - return new Character(fetchCharField(field)); > - case JavaTypes.DOUBLE: > - return new Double(fetchDoubleField(field)); > - case JavaTypes.FLOAT: > - return new Float(fetchFloatField(field)); > - case JavaTypes.INT: > - return Numbers.valueOf(fetchIntField(field)); > - case JavaTypes.LONG: > - return Numbers.valueOf(fetchLongField(field)); > - case JavaTypes.SHORT: > - return new Short(fetchShortField(field)); > - default: > - return fetchObjectField(field); > - } > - } > - > - public void store(int field, Object val) { > - val = _meta.getField(field).getFieldValue(val, _broker); > - storeField(field, val); > - } > - > - public void storeField(int field, Object val) { > - storeField(field, val, this); > - } > - > - /** > - *

Checks whether or not _pc is dirty. In the > cases where > - * field tracking is not happening (see below), this method > will do a > - * state comparison to find whether _pc is dirty, > and will > - * update this instance with this information. In the cases > where field > - * tracking is happening, this method is a no-op.

> - * > - *

Fields are tracked for all classes that are run through > the OpenJPA > - * enhancer prior to or during deployment, and all classes > (enhanced or > - * unenhanced) in a Java 6 environment or newer.

> - * > - *

In a Java 5 VM or older: > - *
- instances of unenhanced classes that use > - * property access and obey the property access limitations are > tracked > - * when the instances are loaded from the database by OpenJPA, > and are > - * not tracked when the instances are created by application > code. > - *
- instances of unenhanced classes that use field access > are > - * never tracked.

> - * > - * @since 1.0.0 > - */ > - public void dirtyCheck() { > - if (!needsDirtyCheck()) > - return; > - > - SaveFieldManager saved = getSaveFieldManager(); > - if (saved == null) > - throw new InternalException(_loc.get("no-saved-fields", > - getMetaData().getDescribedType().getName())); > - > - FieldMetaData[] fmds = getMetaData().getFields(); > - for (int i = 0; i < fmds.length; i++) { > - // pk and version fields cannot be mutated; don't mark > them > - // as such. ##### validate? > - if (!fmds[i].isPrimaryKey() && !fmds[i].isVersion() > - && _loaded.get(i)) { > - if (!saved.isFieldEqual(i, fetch(i))) { > - dirty(i); > - } > - } > - } > - } > - > - private boolean needsDirtyCheck() { > - if (isIntercepting()) > - return false; > - if (isDeleted()) > - return false; > - if (isNew() && !isFlushed()) > - return false; > - return true; > - } > - > - public Object fetchInitialField(int field) { > - FieldMetaData fmd = _meta.getField(field); > - if (_broker.getRestoreState() == RestoreState.RESTORE_NONE > - && ((_flags & FLAG_INVERSES) == 0 > - || fmd.getInverseMetaDatas().length == 0)) > - throw new InvalidStateException(_loc.get("restore- > unset")); > - > - switch (fmd.getDeclaredTypeCode()) { > - case JavaTypes.DATE: > - case JavaTypes.CALENDAR: > - case JavaTypes.ARRAY: > - case JavaTypes.COLLECTION: > - case JavaTypes.MAP: > - case JavaTypes.OBJECT: > - // if we're not saving mutable types, throw an > exception > - if (_broker.getRestoreState() != > RestoreState.RESTORE_ALL > - && ((_flags & FLAG_INVERSES) == 0 > - || fmd.getInverseMetaDatas().length == 0)) > - throw new InvalidStateException(_loc.get > - ("mutable-restore-unset")); > - } > - > - lock(); > - try { > - if (_saved == null || !_loaded.get(field) || ! > _dirty.get(field)) > - return fetchField(field, false); > - > - // if the field is dirty but we never loaded it, we > can't restore it > - if (_saved.getUnloaded().get(field)) > - throw new InvalidStateException(_loc.get("initial- > unloaded", > - fmd)); > - > - provideField(_saved.getState(), _single, field); > - return fetchField(_single, fmd); > - } finally { > - unlock(); > - } > - } > - > - /** > - * Fetch the specified field from the specified field manager, > wrapping it > - * in an object if it's a primitive. A field should be provided > to the > - * field manager before this call is made. > - */ > - private static Object fetchField(FieldManager fm, FieldMetaData > fmd) { > - int field = fmd.getIndex(); > - switch (fmd.getDeclaredTypeCode()) { > - case JavaTypes.BOOLEAN: > - return (fm.fetchBooleanField(field)) ? Boolean.TRUE > - : Boolean.FALSE; > - case JavaTypes.BYTE: > - return new Byte(fm.fetchByteField(field)); > - case JavaTypes.CHAR: > - return new Character(fm.fetchCharField(field)); > - case JavaTypes.DOUBLE: > - return new Double(fm.fetchDoubleField(field)); > - case JavaTypes.FLOAT: > - return new Float(fm.fetchFloatField(field)); > - case JavaTypes.INT: > - return Numbers.valueOf(fm.fetchIntField(field)); > - case JavaTypes.LONG: > - return Numbers.valueOf(fm.fetchLongField(field)); > - case JavaTypes.SHORT: > - return new Short(fm.fetchShortField(field)); > - case JavaTypes.STRING: > - return fm.fetchStringField(field); > - default: > - return fm.fetchObjectField(field); > - } > - } > - > - public void setRemote(int field, Object value) { > - lock(); > - try { > - Boolean stat = dirty(field, Boolean.FALSE, false); > - storeField(field, value, _single); > - replaceField(_pc, _single, field); > - postDirty(stat); > - } finally { > - unlock(); > - } > - } > - > - //////////////////////// > - // Lifecycle operations > - //////////////////////// > - > - /** > - * Notification that the object is about to be accessed. > - * > - * @param field the field number being read, or -1 if not a > single > - * field read > - */ > - void beforeRead(int field) { > - // allow unmediated reads of primary key fields > - if (field != -1 && _meta.getField(field).isPrimaryKey()) > - return; > - > - if (_broker.isActive() && !_broker.isTransactionEnding()) { > - if (_broker.getOptimistic()) > - setPCState(_state.beforeOptimisticRead(this, field)); > - else > - setPCState(_state.beforeRead(this, field)); > - } else if (_broker.getNontransactionalRead()) > - setPCState(_state.beforeNontransactionalRead(this, > field)); > - else > - throw new InvalidStateException(_loc.get("non-trans- > read")). > - setFailedObject(getManagedInstance()); > - } > - > - /** > - * Delegates to the current state. > - * > - * @see PCState#beforeFlush > - */ > - void beforeFlush(int reason, OpCallbacks call) { > - _state.beforeFlush(this, reason == > BrokerImpl.FLUSH_LOGICAL, call); > - } > - > - /** > - * Delegates to the current state. > - * > - * @see PCState#flush > - */ > - void afterFlush(int reason) { > - // nothing happens when we flush non-persistent states > - if (!isPersistent()) > - return; > - > - if (reason != BrokerImpl.FLUSH_ROLLBACK > - && reason != BrokerImpl.FLUSH_LOGICAL) { > - // analyze previous state for later > - boolean wasNew = isNew(); > - boolean wasFlushed = isFlushed(); > - boolean wasDeleted = isDeleted(); > - > - // all dirty fields were flushed > - _flush.or(_dirty); > - > - // important to set flushed bit after calling > _state.flush so > - // that the state can tell whether this is the first > flush > - setPCState(_state.flush(this)); > - _flags |= FLAG_FLUSHED; > - _flags &= ~FLAG_FLUSHED_DIRTY; > - > - _flags &= ~FLAG_VERSION_CHECK; > - _flags &= ~FLAG_VERSION_UPDATE; > - > - // if this was an inc flush during which we had our > identity > - // assigned, tell the broker to cache us under our > final oid > - if (reason == BrokerImpl.FLUSH_INC) > - assertObjectIdAssigned(true); > - > - // if this object was stored with preFlush, do post- > store callback > - if ((_flags & FLAG_PRE_FLUSHED) > 0) > - fireLifecycleEvent(LifecycleEvent.AFTER_STORE); > - > - // do post-update as needed > - if (wasNew && !wasFlushed) > - > fireLifecycleEvent(LifecycleEvent.AFTER_PERSIST_PERFORMED); > - else if (wasDeleted) > - > fireLifecycleEvent(LifecycleEvent.AFTER_DELETE_PERFORMED); > - else > - // updates and new-flushed with changes > - > fireLifecycleEvent(LifecycleEvent.AFTER_UPDATE_PERFORMED); > - } else if (reason == BrokerImpl.FLUSH_ROLLBACK) { > - // revert to last loaded version and original oid > - assignVersionField(_loadVersion); > - if (isNew() && (_flags & FLAG_OID_ASSIGNED) == 0) > - _oid = null; > - } > - _flags &= ~FLAG_PRE_FLUSHED; > - } > - > - /** > - * Delegates to the current state after checking the value > - * of the RetainState flag. > - * > - * @see PCState#commit > - * @see PCState#commitRetain > - */ > - void commit() { > - // release locks before oid updated > - releaseLocks(); > - > - // update version and oid information > - setVersion(_version); > - _flags &= ~FLAG_FLUSHED; > - _flags &= ~FLAG_FLUSHED_DIRTY; > - > - Object orig = _id; > - assertObjectIdAssigned(false); > - > - boolean wasNew = isNew() && !isDeleted() && !isProvisional(); > - if (_broker.getRetainState()) > - setPCState(_state.commitRetain(this)); > - else > - setPCState(_state.commit(this)); > - > - // ask the broker to re-cache us if we were new previously > - if (wasNew) > - _broker.setStateManager(orig, this, > BrokerImpl.STATUS_COMMIT_NEW); > - } > - > - /** > - * Delegates to the current state after checking the value > - * of the RetainState flag. > - * > - * @see PCState#rollback > - * @see PCState#rollbackRestore > - */ > - void rollback() { > - // release locks > - releaseLocks(); > - _flags &= ~FLAG_FLUSHED; > - _flags &= ~FLAG_FLUSHED_DIRTY; > - afterFlush(BrokerImpl.FLUSH_ROLLBACK); > - > - if (_broker.getRestoreState() != RestoreState.RESTORE_NONE) > - setPCState(_state.rollbackRestore(this)); > - else > - setPCState(_state.rollback(this)); > - } > - > - /** > - * Rollback state of the managed instance to the given savepoint. > - */ > - void rollbackToSavepoint(SavepointFieldManager savepoint) { > - _state = savepoint.getPCState(); > - BitSet loaded = savepoint.getLoaded(); > - for (int i = 0, len = loaded.length(); i < len; i++) { > - if (loaded.get(i) && savepoint.restoreField(i)) { > - provideField(savepoint.getCopy(), savepoint, i); > - replaceField(_pc, savepoint, i); > - } > - } > - _loaded = loaded; > - _dirty = savepoint.getDirty(); > - _flush = savepoint.getFlushed(); > - _version = savepoint.getVersion(); > - _loadVersion = savepoint.getLoadVersion(); > - } > - > - /** > - * Delegates to the current state. > - * > - * @see PCState#persist > - * @see Broker#persist > - */ > - void persist() { > - setPCState(_state.persist(this)); > - } > - > - /** > - * Delegates to the current state. > - * > - * @see PCState#delete > - * @see Broker#delete > - */ > - void delete() { > - setPCState(_state.delete(this)); > - } > - > - /** > - * Delegates to the current state. > - * > - * @see PCState#nontransactional > - * @see Broker#nontransactional > - */ > - void nontransactional() { > - setPCState(_state.nontransactional(this)); > - } > - > - /** > - * Delegates to the current state. > - * > - * @see PCState#transactional > - * @see Broker#transactional > - */ > - void transactional() { > - setPCState(_state.transactional(this)); > - } > - > - /** > - * Delegates to the current state. > - * > - * @see PCState#nonprovisional > - */ > - void nonprovisional(boolean logical, OpCallbacks call) { > - setPCState(_state.nonprovisional(this, logical, call)); > - } > - > - /** > - * Delegates to the current state. > - * > - * @see PCState#release > - * @see Broker#release > - */ > - void release(boolean unproxy) { > - release(unproxy, false); > - } > - > - void release(boolean unproxy, boolean force) { > - // optimization for detach-in-place special case when > fields are > - // already (un)proxied correctly > - if (!unproxy) > - _flags |= FLAG_NO_UNPROXY; > - try { > - if (force) > - setPCState(PCState.TRANSIENT); > - else > - setPCState(_state.release(this)); > - } finally { > - _flags &= ~FLAG_NO_UNPROXY; > - } > - } > - > - /** > - * Delegates to the current state. > - * > - * @see PCState#evict > - * @see Broker#evict > - */ > - void evict() { > - setPCState(_state.evict(this)); > - } > - > - /** > - * Gather relations reachable from values using > - * {@link ValueMetaData#CASCADE_IMMEDIATE}. > - */ > - void gatherCascadeRefresh(OpCallbacks call) { > - FieldMetaData[] fmds = _meta.getFields(); > - for (int i = 0; i < fmds.length; i++) { > - if (!_loaded.get(i)) > - continue; > - > - if (fmds[i].getCascadeRefresh() == > ValueMetaData.CASCADE_IMMEDIATE > - || fmds[i].getKey().getCascadeRefresh() > - == ValueMetaData.CASCADE_IMMEDIATE > - || fmds[i].getElement().getCascadeRefresh() > - == ValueMetaData.CASCADE_IMMEDIATE) { > - _single.storeObjectField(i, fetchField(i, false)); > - _single.gatherCascadeRefresh(call); > - _single.clear(); > - } > - } > - } > - > - public boolean beforeRefresh(boolean refreshAll) { > - // note: all logic placed here rather than in the states for > - // optimization; this method public b/c used by remote > package > - > - // nothing to do for non persistent or new unflushed > instances > - if (!isPersistent() || (isNew() && !isFlushed())) > - return false; > - > - lock(); > - try { > - // if dirty need to clear fields > - if (isDirty()) { > - clearFields(); > - return true; > - } > - > - // if some fields have been loaded but the instance is > out of > - // date or this is part of a refreshAll() and we don't > want to > - // take the extra hit to see if the instance is out of > date, clear > - if (_loaded.length() > 0 && (refreshAll || isEmbedded() > - || !syncVersion(null))) { > - Object version = _version; > - clearFields(); > - > - // if syncVersion just replaced the version, reset it > - if (!refreshAll && !isEmbedded()) > - setVersion(version); > - return true; > - } > - return false; > - } finally { > - unlock(); > - } > - } > - > - /** > - * Perform state transitions after refresh. This method is only > - * called if {@link #beforeRefresh} returns true. > - */ > - void afterRefresh() { > - lock(); > - try { > - // transition to clean or nontransactional depending on > trans status > - if (!_broker.isActive()) > - setPCState(_state.afterNontransactionalRefresh()); > - else if (_broker.getOptimistic()) > - setPCState(_state.afterOptimisticRefresh()); > - else > - setPCState(_state.afterRefresh()); > - } finally { > - unlock(); > - } > - } > - > - /** > - * Mark this object as a dereferenced dependent object. > - */ > - void setDereferencedDependent(boolean deref, boolean notify) { > - if (!deref && (_flags & FLAG_DEREF) > 0) { > - if (notify) > - _broker.removeDereferencedDependent(this); > - _flags &= ~FLAG_DEREF; > - } else if (deref && (_flags & FLAG_DEREF) == 0) { > - _flags |= FLAG_DEREF; > - if (notify) > - _broker.addDereferencedDependent(this); > - } > - } > - > - /////////// > - // Locking > - /////////// > - > - /** > - * Notification that we've been read-locked. Pass in the level > at which > - * we were locked and the level at which we should write lock > ourselves > - * on dirty. > - */ > - void readLocked(int readLockLevel, int writeLockLevel) { > - // make sure object is added to transaction so lock will get > - // cleared on commit/rollback > - if (readLockLevel != LockLevels.LOCK_NONE) > - transactional(); > - > - _readLockLevel = readLockLevel; > - _writeLockLevel = writeLockLevel; > - _flags |= FLAG_READ_LOCKED; > - _flags &= ~FLAG_WRITE_LOCKED; > - } > - > - /** > - * Return the lock level to use when loading state. > - */ > - private int calculateLockLevel(boolean active, boolean forWrite, > - FetchConfiguration fetch) { > - if (!active) > - return LockLevels.LOCK_NONE; > - if (fetch == null) > - fetch = _broker.getFetchConfiguration(); > - > - if (_readLockLevel == -1) > - _readLockLevel = fetch.getReadLockLevel(); > - if (_writeLockLevel == -1) > - _writeLockLevel = fetch.getWriteLockLevel(); > - return (forWrite) ? _writeLockLevel : _readLockLevel; > - } > - > - /** > - * Make sure we're locked at the given level. > - */ > - private void obtainLocks(boolean active, boolean forWrite, int > lockLevel, > - FetchConfiguration fetch, Object sdata) { > - if (!active) > - return; > - > - // if we haven't been locked yet, lock now at the given level > - int flag = (forWrite) ? FLAG_WRITE_LOCKED : FLAG_READ_LOCKED; > - if ((_flags & flag) == 0) { > - // make sure object is added to transaction so lock > will get > - // cleared on commit/rollback > - if (lockLevel != LockLevels.LOCK_NONE) > - transactional(); > - > - if (fetch == null) > - fetch = _broker.getFetchConfiguration(); > - _broker.getLockManager().lock(this, lockLevel, > - fetch.getLockTimeout(), sdata); > - _flags |= FLAG_READ_LOCKED; > - _flags |= flag; > - } > - } > - > - /** > - * Release locks. > - */ > - private void releaseLocks() { > - if (_lock != null) > - _broker.getLockManager().release(this); > - _readLockLevel = -1; > - _writeLockLevel = -1; > - _flags &= ~FLAG_READ_LOCKED; > - _flags &= ~FLAG_WRITE_LOCKED; > - } > - > - //////////////////////////////////////////// > - // Implementation of StateManager interface > - //////////////////////////////////////////// > - > - /** > - * @return whether or not unloaded fields should be closed. > - */ > - public boolean serializing() { > - // if the broker is in the midst of a serialization, then > no special > - // handling should be performed on the instance, and no > subsequent > - // load should happen > - if (_broker.isSerializing()) > - return false; > - > - try { > - if (_meta.isDetachable()) > - return DetachManager.preSerialize(this); > - > - load(_broker.getFetchConfiguration(), LOAD_SERIALIZE, > null, null, > - false); > - return false; > - } catch (RuntimeException re) { > - throw translate(re); > - } > - } > - > - public boolean writeDetached(ObjectOutput out) > - throws IOException { > - BitSet idxs = new BitSet(_meta.getFields().length); > - lock(); > - try { > - boolean detsm = DetachManager.writeDetachedState(this, > out, idxs); > - if (detsm) > - _flags |= FLAG_DETACHING; > - > - FieldMetaData[] fmds = _meta.getFields(); > - for (int i = 0; i < fmds.length; i++) { > - if (fmds[i].isTransient()) > - continue; > - provideField(_pc, _single, i); > - _single.serialize(out, !idxs.get(i)); > - _single.clear(); > - } > - return true; > - } catch (RuntimeException re) { > - throw translate(re); > - } finally { > - _flags &= ~FLAG_DETACHING; > - unlock(); > - } > - } > - > - public void proxyDetachedDeserialized(int idx) { > - // we don't serialize state manager impls > - throw new InternalException(); > - } > - > - public boolean isTransactional() { > - // special case for TCLEAN, which we want to appear non- > trans to > - // internal code, but which publicly should be transactional > - return _state == PCState.TCLEAN || _state.isTransactional(); > - } > - > - public boolean isPendingTransactional() { > - return _state.isPendingTransactional(); > - } > - > - public boolean isProvisional() { > - return _state.isProvisional(); > - } > - > - public boolean isPersistent() { > - return _state.isPersistent(); > - } > - > - public boolean isNew() { > - return _state.isNew(); > - } > - > - public boolean isDeleted() { > - return _state.isDeleted(); > - } > - > - public boolean isDirty() { > - return _state.isDirty(); > - } > - > - public boolean isDetached() { > - return (_flags & FLAG_DETACHING) != 0; > - } > - > - public Object getGenericContext() { > - return _broker; > - } > - > - public Object fetchObjectId() { > - try { > - assignObjectId(true); > - if (_oid == null || !_broker.getConfiguration(). > - getCompatibilityInstance().getCopyObjectIds()) > - return _oid; > - > - if (_meta.getIdentityType() == > ClassMetaData.ID_DATASTORE) > - return > _broker.getStoreManager().copyDataStoreId(_oid, _meta); > - return ApplicationIds.copy(_oid, _meta); > - } catch (RuntimeException re) { > - throw translate(re); > - } > - } > - > - public Object getPCPrimaryKey(Object oid, int field) { > - FieldMetaData fmd = _meta.getField(field); > - Object pk = ApplicationIds.get(oid, fmd); > - if (pk == null) > - return null; > - > - ClassMetaData relmeta = fmd.getDeclaredTypeMetaData(); > - pk = ApplicationIds.wrap(relmeta, pk); > - if (relmeta.getIdentityType() == ClassMetaData.ID_DATASTORE > - && fmd.getObjectIdFieldTypeCode() == JavaTypes.LONG) > - pk = _broker.getStoreManager().newDataStoreId(pk, > relmeta); > - else if (relmeta.getIdentityType() == > ClassMetaData.ID_APPLICATION > - && fmd.getObjectIdFieldType() != > relmeta.getObjectIdType()) > - pk = ApplicationIds.fromPKValues(new Object[] { pk }, > relmeta); > - return _broker.find(pk, false, null); > - } > - > - public byte replaceFlags() { > - // we always use load required so that we can detect when > objects > - // are touched for locking or making transactional > - return PersistenceCapable.LOAD_REQUIRED; > - } > - > - public StateManager replaceStateManager(StateManager sm) { > - return sm; > - } > - > - public void accessingField(int field) { > - // possibly change state > - try { > - beforeRead(field); > - beforeAccessField(field); > - } catch (RuntimeException re) { > - throw translate(re); > - } > - } > - > - /** > - * Load the given field before access. > - */ > - protected void beforeAccessField(int field) { > - lock(); > - try { > - boolean active = _broker.isActive(); > - int lockLevel = calculateLockLevel(active, false, null); > - if (!_loaded.get(field)) > - loadField(field, lockLevel, false, true); > - else > - assignField(field, false); > - obtainLocks(active, false, lockLevel, null, null); > - } catch (RuntimeException re) { > - throw translate(re); > - } finally { > - unlock(); > - } > - } > - > - public void dirty(String field) { > - FieldMetaData fmd = _meta.getField(field); > - if (fmd == null) > - throw translate(new UserException(_loc.get("no-field", > field, > - ImplHelper.getManagedInstance(_pc).getClass())) > - .setFailedObject(getManagedInstance())); > - > - dirty(fmd.getIndex(), null, true); > - } > - > - public void dirty(int field) { > - dirty(field, null, true); > - } > - > - /** > - * Make the given field dirty. > - * > - * @param mutate if null, may be an SCO mutation; if true, is > certainly > - * a mutation (or at least treat as one) > - * @return {@link Boolean#FALSE} if this instance was already > dirty, > - * null if it was dirty but not since flush, and > - * {@link Boolean#TRUE} if it was not dirty > - */ > - private Boolean dirty(int field, Boolean mutate, boolean > loadFetchGroup) { > - boolean locked = false; > - boolean newFlush = false; > - boolean clean = false; > - try { > - FieldMetaData fmd = _meta.getField(field); > - if (!isNew() || isFlushed()) { > - if (fmd.getUpdateStrategy() == > UpdateStrategies.RESTRICT) > - throw new InvalidStateException(_loc.get > - ("update-restrict", fmd)); > - if (fmd.getUpdateStrategy() == > UpdateStrategies.IGNORE) > - return Boolean.FALSE; > - } > - > - if (isEmbedded()) { > - // notify owner of change > - _owner.dirty(_ownerIndex, Boolean.TRUE, > loadFetchGroup); > - } > - > - // is this a direct mutation of an sco field? > - if (mutate == null) { > - switch (fmd.getDeclaredTypeCode()) { > - case JavaTypes.COLLECTION: > - case JavaTypes.MAP: > - case JavaTypes.ARRAY: > - case JavaTypes.DATE: > - case JavaTypes.CALENDAR: > - case JavaTypes.OBJECT: > - mutate = Boolean.TRUE; > - break; > - case JavaTypes.PC: > - mutate = > - (fmd.isEmbedded()) ? Boolean.TRUE : > Boolean.FALSE; > - break; > - default: > - mutate = Boolean.FALSE; // not sco > - } > - } > - > - // possibly change state > - boolean active = _broker.isActive(); > - clean = !_state.isDirty(); // intentional direct access > - > - // fire event fast before state change. > - if (clean) > - fireLifecycleEvent(LifecycleEvent.BEFORE_DIRTY); > - if (active) { > - if (_broker.getOptimistic()) > - setPCState(_state.beforeOptimisticWrite(this, > field, > - mutate.booleanValue())); > - else > - setPCState(_state.beforeWrite(this, field, > - mutate.booleanValue())); > - } else if (fmd.getManagement() == > FieldMetaData.MANAGE_PERSISTENT) { > - if (isPersistent() && ! > _broker.getNontransactionalWrite()) > - throw new InvalidStateException(_loc.get > - ("non-trans-write")).setFailedObject > - (getManagedInstance()); > - > - setPCState(_state.beforeNontransactionalWrite(this, > field, > - mutate.booleanValue())); > - } > - > - if ((_flags & FLAG_FLUSHED) != 0) { > - newFlush = (_flags & FLAG_FLUSHED_DIRTY) == 0; > - _flags |= FLAG_FLUSHED_DIRTY; > - } > - > - lock(); > - locked = true; > - > - // note that the field is in need of flushing again, > and tell the > - // broker too > - _flush.clear(field); > - _broker.setDirty(this, newFlush && !clean); > - > - // save the field for rollback if needed > - saveField(field); > - > - // dirty the field and mark loaded; load fetch group if > needed > - int lockLevel = calculateLockLevel(active, true, null); > - if (!_dirty.get(field)) { > - setLoaded(field, true); > - _dirty.set(field); > - > - // make sure the field's fetch group is loaded > - if (loadFetchGroup && isPersistent() > - && fmd.getManagement() == fmd.MANAGE_PERSISTENT) > - loadField(field, lockLevel, true, true); > - } > - obtainLocks(active, true, lockLevel, null, null); > - } catch (RuntimeException re) { > - throw translate(re); > - } finally { > - if (locked) > - unlock(); > - } > - > - if (clean) > - return Boolean.TRUE; > - if (newFlush) { > - // this event can be fired later cause we're already > dirty. > - fireLifecycleEvent(LifecycleEvent.BEFORE_DIRTY_FLUSHED); > - return null; > - } > - return Boolean.FALSE; > - } > - > - /** > - * Fire post-dirty events after field value changes. > - * > - * @param status return value from {@link #dirty(int, Boolean, > boolean)} > - */ > - private void postDirty(Boolean status) { > - if (Boolean.TRUE.equals(status)) > - fireLifecycleEvent(LifecycleEvent.AFTER_DIRTY); > - else if (status == null) > - fireLifecycleEvent(LifecycleEvent.AFTER_DIRTY_FLUSHED); > - } > - > - public void removed(int field, Object removed, boolean key) { > - if (removed == null) > - return; > - > - try { > - // dereference dependent fields, delete embedded > - FieldMetaData fmd = _meta.getField(field); > - ValueMetaData vmd = (key) ? fmd.getKey() : > fmd.getElement(); > - if (vmd.isEmbeddedPC()) > - _single.delete(vmd, removed, null); > - else if (vmd.getCascadeDelete() == > ValueMetaData.CASCADE_AUTO) > - _single.dereferenceDependent(removed); > - } catch (RuntimeException re) { > - throw translate(re); > - } > - } > - > - public Object newProxy(int field) { > - FieldMetaData fmd = _meta.getField(field); > - if (!fmd.isExternalized()) > - return newFieldProxy(field); > - > - switch (fmd.getTypeCode()) { > - case JavaTypes.DATE: > - if (fmd.getDeclaredType() == java.sql.Date.class) > - return new > java.sql.Date(System.currentTimeMillis()); > - if (fmd.getDeclaredType() == > java.sql.Timestamp.class) > - return new > java.sql.Timestamp(System.currentTimeMillis()); > - if (fmd.getDeclaredType() == java.sql.Time.class) > - return new > java.sql.Time(System.currentTimeMillis()); > - return new Date(); > - case JavaTypes.CALENDAR: > - return Calendar.getInstance(); > - case JavaTypes.COLLECTION: > - return new ArrayList(); > - case JavaTypes.MAP: > - return new HashMap(); > - } > - return null; > - } > - > - public Object newFieldProxy(int field) { > - FieldMetaData fmd = _meta.getField(field); > - ProxyManager mgr = _broker.getConfiguration(). > - getProxyManagerInstance(); > - Object init = fmd.getInitializer(); > - > - switch (fmd.getDeclaredTypeCode()) { > - case JavaTypes.DATE: > - return mgr.newDateProxy(fmd.getDeclaredType()); > - case JavaTypes.CALENDAR: > - return mgr.newCalendarProxy(fmd.getDeclaredType(), > - init instanceof TimeZone ? (TimeZone) init : > null); > - case JavaTypes.COLLECTION: > - return mgr.newCollectionProxy(fmd.getProxyType(), > - fmd.getElement().getDeclaredType(), > - init instanceof Comparator ? (Comparator) > init : null); > - case JavaTypes.MAP: > - return mgr.newMapProxy(fmd.getProxyType(), > - fmd.getKey().getDeclaredType(), > - fmd.getElement().getDeclaredType(), > - init instanceof Comparator ? (Comparator) > init : null); > - } > - return null; > - } > - > - public boolean isDefaultValue(int field) { > - lock(); > - try { > - _single.clear(); > - provideField(_pc, _single, field); > - boolean ret = _single.isDefaultValue(); > - _single.clear(); > - return ret; > - } finally { > - unlock(); > - } > - } > - > - ///////////////////////////////////////////////////////// > - // Record that the field is dirty (which might load DFG) > - ///////////////////////////////////////////////////////// > - > - public void settingBooleanField(PersistenceCapable pc, int field, > - boolean curVal, boolean newVal, int set) { > - if (set != SET_REMOTE) { > - if (newVal == curVal && _loaded.get(field)) > - return; > - assertNoPrimaryKeyChange(field); > - } > - > - lock(); > - try { > - Boolean stat = dirty(field, Boolean.FALSE, set == > SET_USER); > - _single.storeBooleanField(field, newVal); > - replaceField(pc, _single, field); > - postDirty(stat); > - } finally { > - unlock(); > - } > - } > - > - public void settingByteField(PersistenceCapable pc, int field, > - byte curVal, byte newVal, int set) { > - if (set != SET_REMOTE) { > - if (newVal == curVal && _loaded.get(field)) > - return; > - assertNoPrimaryKeyChange(field); > - } > - > - lock(); > - try { > - Boolean stat = dirty(field, Boolean.FALSE, set == > SET_USER); > - _single.storeByteField(field, newVal); > - replaceField(pc, _single, field); > - postDirty(stat); > - } finally { > - unlock(); > - } > - } > - > - public void settingCharField(PersistenceCapable pc, int field, > - char curVal, char newVal, int set) { > - if (set != SET_REMOTE) { > - if (newVal == curVal && _loaded.get(field)) > - return; > - assertNoPrimaryKeyChange(field); > - } > - > - lock(); > - try { > - Boolean stat = dirty(field, Boolean.FALSE, set == > SET_USER); > - _single.storeCharField(field, newVal); > - replaceField(pc, _single, field); > - postDirty(stat); > - } finally { > - unlock(); > - } > - } > - > - public void settingDoubleField(PersistenceCapable pc, int field, > - double curVal, double newVal, int set) { > - if (set != SET_REMOTE) { > - if (newVal == curVal && _loaded.get(field)) > - return; > - assertNoPrimaryKeyChange(field); > - } > - > - lock(); > - try { > - Boolean stat = dirty(field, Boolean.FALSE, set == > SET_USER); > - _single.storeDoubleField(field, newVal); > - replaceField(pc, _single, field); > - postDirty(stat); > - } finally { > - unlock(); > - } > - } > - > - public void settingFloatField(PersistenceCapable pc, int field, > - float curVal, float newVal, int set) { > - if (set != SET_REMOTE) { > - if (newVal == curVal && _loaded.get(field)) > - return; > - assertNoPrimaryKeyChange(field); > - } > - > - lock(); > - try { > - Boolean stat = dirty(field, Boolean.FALSE, set == > SET_USER); > - _single.storeFloatField(field, newVal); > - replaceField(pc, _single, field); > - postDirty(stat); > - } finally { > - unlock(); > - } > - } > - > - public void settingIntField(PersistenceCapable pc, int field, > - int curVal, int newVal, int set) { > - if (set != SET_REMOTE) { > - if (newVal == curVal && _loaded.get(field)) > - return; > - assertNoPrimaryKeyChange(field); > - } > - > - lock(); > - try { > - Boolean stat = dirty(field, Boolean.FALSE, set == > SET_USER); > - _single.storeIntField(field, newVal); > - replaceField(pc, _single, field); > - postDirty(stat); > - } finally { > - unlock(); > - } > - } > - > - public void settingLongField(PersistenceCapable pc, int field, > - long curVal, long newVal, int set) { > - if (set != SET_REMOTE) { > - if (newVal == curVal && _loaded.get(field)) > - return; > - assertNoPrimaryKeyChange(field); > - } > - > - lock(); > - try { > - Boolean stat = dirty(field, Boolean.FALSE, set == > SET_USER); > - _single.storeLongField(field, newVal); > - replaceField(pc, _single, field); > - postDirty(stat); > - } finally { > - unlock(); > - } > - } > - > - public void settingObjectField(PersistenceCapable pc, int field, > - Object curVal, Object newVal, int set) { > - if (set != SET_REMOTE) { > - FieldMetaData fmd = _meta.getField(field); > - if (_loaded.get(field)) { > - if (newVal == curVal) > - return; > - > - // only compare new to old values if the comparison > is going to > - // be cheap -- don't compare collections, maps, UDTs > - switch (fmd.getDeclaredTypeCode()) { > - case JavaTypes.ARRAY: > - case JavaTypes.COLLECTION: > - case JavaTypes.MAP: > - case JavaTypes.PC: > - case JavaTypes.PC_UNTYPED: > - break; > - default: > - if (newVal != null && newVal.equals(curVal)) > - return; > - } > - } else { > - // if this is a dependent unloaded field, make sure > to load > - // it now > - if (fmd.getCascadeDelete() == > ValueMetaData.CASCADE_AUTO > - || fmd.getKey().getCascadeDelete() > - == ValueMetaData.CASCADE_AUTO > - || fmd.getElement().getCascadeDelete() > - == ValueMetaData.CASCADE_AUTO) > - curVal = fetchObjectField(field); > - } > - > - assertNoPrimaryKeyChange(field); > - if (fmd.getDeclaredTypeCode() == JavaTypes.OID) > - assertNotManagedObjectId(newVal); > - } > - > - lock(); > - try { > - Boolean stat = dirty(field, Boolean.FALSE, set == > SET_USER); > - if (set != SET_REMOTE) { > - _single.storeObjectField(field, curVal); > - _single.unproxy(); > - _single.dereferenceDependent(); > - _single.clear(); > - } > - _single.storeObjectField(field, newVal); > - replaceField(pc, _single, field); > - postDirty(stat); > - } finally { > - unlock(); > - } > - } > - > - public void settingShortField(PersistenceCapable pc, int field, > - short curVal, short newVal, int set) { > - if (set != SET_REMOTE) { > - if (newVal == curVal && _loaded.get(field)) > - return; > - assertNoPrimaryKeyChange(field); > - } > - > - lock(); > - try { > - Boolean stat = dirty(field, Boolean.FALSE, set == > SET_USER); > - _single.storeShortField(field, newVal); > - replaceField(pc, _single, field); > - postDirty(stat); > - } finally { > - unlock(); > - } > - } > - > - public void settingStringField(PersistenceCapable pc, int field, > - String curVal, String newVal, int set) { > - if (set != SET_REMOTE) { > - if (StringUtils.equals(newVal, curVal) && > _loaded.get(field)) > - return; > - assertNoPrimaryKeyChange(field); > - } > - > - lock(); > - try { > - Boolean stat = dirty(field, Boolean.FALSE, set == > SET_USER); > - _single.storeStringField(field, newVal); > - replaceField(pc, _single, field); > - postDirty(stat); > - } finally { > - unlock(); > - } > - } > - > - /** > - * Disallows changing primary key fields for instances. > - */ > - private void assertNoPrimaryKeyChange(int field) { > - if (_oid != null && _meta.getField(field).isPrimaryKey()) > - throw translate(new InvalidStateException(_loc.get > - ("change- > identity")).setFailedObject(getManagedInstance())); > - } > - > - /** > - * Disallows setting an object id field to a managed instance. > - */ > - void assertNotManagedObjectId(Object val) { > - if (val != null > - && (ImplHelper.toPersistenceCapable(val, > - > getContext().getConfiguration())).pcGetGenericContext()!= null) > - throw translate(new InvalidStateException(_loc.get > - ("managed-oid", Exceptions.toString(val), > - Exceptions.toString(getManagedInstance()))). > - setFailedObject(getManagedInstance())); > - } > - > - //////////////////////////// > - // Delegate to FieldManager > - //////////////////////////// > - > - public void providedBooleanField(PersistenceCapable pc, int > field, > - boolean curVal) { > - _fm.storeBooleanField(field, curVal); > - } > - > - public void providedByteField(PersistenceCapable pc, int field, > - byte curVal) { > - _fm.storeByteField(field, curVal); > - } > - > - public void providedCharField(PersistenceCapable pc, int field, > - char curVal) { > - _fm.storeCharField(field, curVal); > - } > - > - public void providedDoubleField(PersistenceCapable pc, int field, > - double curVal) { > - _fm.storeDoubleField(field, curVal); > - } > - > - public void providedFloatField(PersistenceCapable pc, int field, > - float curVal) { > - _fm.storeFloatField(field, curVal); > - } > - > - public void providedIntField(PersistenceCapable pc, int field, > - int curVal) { > - _fm.storeIntField(field, curVal); > - } > - > - public void providedLongField(PersistenceCapable pc, int field, > - long curVal) { > - _fm.storeLongField(field, curVal); > - } > - > - public void providedObjectField(PersistenceCapable pc, int field, > - Object curVal) { > - _fm.storeObjectField(field, curVal); > - } > - > - public void providedShortField(PersistenceCapable pc, int field, > - short curVal) { > - _fm.storeShortField(field, curVal); > - } > - > - public void providedStringField(PersistenceCapable pc, int field, > - String curVal) { > - _fm.storeStringField(field, curVal); > - } > - > - public boolean replaceBooleanField(PersistenceCapable pc, int > field) { > - return _fm.fetchBooleanField(field); > - } > - > - public byte replaceByteField(PersistenceCapable pc, int field) { > - return _fm.fetchByteField(field); > - } > - > - public char replaceCharField(PersistenceCapable pc, int field) { > - return _fm.fetchCharField(field); > - } > - > - public double replaceDoubleField(PersistenceCapable pc, int > field) { > - return _fm.fetchDoubleField(field); > - } > - > - public float replaceFloatField(PersistenceCapable pc, int > field) { > - return _fm.fetchFloatField(field); > - } > - > - public int replaceIntField(PersistenceCapable pc, int field) { > - return _fm.fetchIntField(field); > - } > - > - public long replaceLongField(PersistenceCapable pc, int field) { > - return _fm.fetchLongField(field); > - } > - > - public Object replaceObjectField(PersistenceCapable pc, int > field) { > - return _fm.fetchObjectField(field); > - } > - > - public short replaceShortField(PersistenceCapable pc, int > field) { > - return _fm.fetchShortField(field); > - } > - > - public String replaceStringField(PersistenceCapable pc, int > field) { > - return _fm.fetchStringField(field); > - } > - > - ////////////////////////////////// > - // Implementation of FieldManager > - ////////////////////////////////// > - > - public boolean fetchBoolean(int field) { > - FieldMetaData fmd = _meta.getField(field); > - if (!fmd.isExternalized()) > - return fetchBooleanField(field); > - > - Object val = fetchField(field, false); > - return ((Boolean) fmd.getExternalValue(val, > _broker)).booleanValue(); > - } > - > - public boolean fetchBooleanField(int field) { > - lock(); > - try { > - if (!_loaded.get(field)) > - loadField(field, LockLevels.LOCK_NONE, false, false); > - > - provideField(_pc, _single, field); > - return _single.fetchBooleanField(field); > - } finally { > - unlock(); > - } > - } > - > - public byte fetchByte(int field) { > - FieldMetaData fmd = _meta.getField(field); > - if (!fmd.isExternalized()) > - return fetchByteField(field); > - > - Object val = fetchField(field, false); > - return ((Number) fmd.getExternalValue(val, > _broker)).byteValue(); > - } > - > - public byte fetchByteField(int field) { > - lock(); > - try { > - if (!_loaded.get(field)) > - loadField(field, LockLevels.LOCK_NONE, false, false); > - > - provideField(_pc, _single, field); > - return _single.fetchByteField(field); > - } finally { > - unlock(); > - } > - } > - > - public char fetchChar(int field) { > - FieldMetaData fmd = _meta.getField(field); > - if (!fmd.isExternalized()) > - return fetchCharField(field); > - > - Object val = fetchField(field, false); > - return ((Character) fmd.getExternalValue(val, > _broker)).charValue(); > - } > - > - public char fetchCharField(int field) { > - lock(); > - try { > - if (!_loaded.get(field)) > - loadField(field, LockLevels.LOCK_NONE, false, false); > - > - provideField(_pc, _single, field); > - return _single.fetchCharField(field); > - } finally { > - unlock(); > - } > - } > - > - public double fetchDouble(int field) { > - FieldMetaData fmd = _meta.getField(field); > - if (!fmd.isExternalized()) > - return fetchDoubleField(field); > - > - Object val = fetchField(field, false); > - return ((Number) fmd.getExternalValue(val, > _broker)).doubleValue(); > - } > - > - public double fetchDoubleField(int field) { > - lock(); > - try { > - if (!_loaded.get(field)) > - loadField(field, LockLevels.LOCK_NONE, false, false); > - > - provideField(_pc, _single, field); > - return _single.fetchDoubleField(field); > - } finally { > - unlock(); > - } > - } > - > - public float fetchFloat(int field) { > - FieldMetaData fmd = _meta.getField(field); > - if (!fmd.isExternalized()) > - return fetchFloatField(field); > - > - Object val = fetchField(field, false); > - return ((Number) fmd.getExternalValue(val, > _broker)).floatValue(); > - } > - > - public float fetchFloatField(int field) { > - lock(); > - try { > - if (!_loaded.get(field)) > - loadField(field, LockLevels.LOCK_NONE, false, false); > - > - provideField(_pc, _single, field); > - return _single.fetchFloatField(field); > - } finally { > - unlock(); > - } > - } > - > - public int fetchInt(int field) { > - FieldMetaData fmd = _meta.getField(field); > - if (!fmd.isExternalized()) > - return fetchIntField(field); > - > - Object val = fetchField(field, false); > - return ((Number) fmd.getExternalValue(val, > _broker)).intValue(); > - } > - > - public int fetchIntField(int field) { > - lock(); > - try { > - if (!_loaded.get(field)) > - loadField(field, LockLevels.LOCK_NONE, false, false); > - > - provideField(_pc, _single, field); > - return _single.fetchIntField(field); > - } finally { > - unlock(); > - } > - } > - > - public long fetchLong(int field) { > - FieldMetaData fmd = _meta.getField(field); > - if (!fmd.isExternalized()) > - return fetchLongField(field); > - > - Object val = fetchField(field, false); > - return ((Number) fmd.getExternalValue(val, > _broker)).longValue(); > - } > - > - public long fetchLongField(int field) { > - lock(); > - try { > - if (!_loaded.get(field)) > - loadField(field, LockLevels.LOCK_NONE, false, false); > - > - provideField(_pc, _single, field); > - return _single.fetchLongField(field); > - } finally { > - unlock(); > - } > - } > - > - public Object fetchObject(int field) { > - FieldMetaData fmd = _meta.getField(field); > - if (!fmd.isExternalized()) > - return fetchObjectField(field); > - > - Object val = fetchField(field, false); > - return fmd.getExternalValue(val, _broker); > - } > - > - public Object fetchObjectField(int field) { > - lock(); > - try { > - if (!_loaded.get(field)) > - loadField(field, LockLevels.LOCK_NONE, false, false); > - > - provideField(_pc, _single, field); > - return _single.fetchObjectField(field); > - } finally { > - unlock(); > - } > - } > - > - public short fetchShort(int field) { > - FieldMetaData fmd = _meta.getField(field); > - if (!fmd.isExternalized()) > - return fetchShortField(field); > - > - Object val = fetchField(field, false); > - return ((Number) fmd.getExternalValue(val, > _broker)).shortValue(); > - } > - > - public short fetchShortField(int field) { > - lock(); > - try { > - if (!_loaded.get(field)) > - loadField(field, LockLevels.LOCK_NONE, false, false); > - > - provideField(_pc, _single, field); > - return _single.fetchShortField(field); > - } finally { > - unlock(); > - } > - } > - > - public String fetchString(int field) { > - FieldMetaData fmd = _meta.getField(field); > - if (!fmd.isExternalized()) > - return fetchStringField(field); > - > - Object val = fetchField(field, false); > - return (String) fmd.getExternalValue(val, _broker); > - } > - > - public String fetchStringField(int field) { > - lock(); > - try { > - if (!_loaded.get(field)) > - loadField(field, LockLevels.LOCK_NONE, false, false); > - > - provideField(_pc, _single, field); > - return _single.fetchStringField(field); > - } finally { > - unlock(); > - } > - } > - > - public void storeBoolean(int field, boolean externalVal) { > - FieldMetaData fmd = _meta.getField(field); > - if (!fmd.isExternalized()) > - storeBooleanField(field, externalVal); > - else { > - Object val = (externalVal) ? Boolean.TRUE : > Boolean.FALSE; > - storeField(field, fmd.getFieldValue(val, _broker)); > - } > - } > - > - public void storeBooleanField(int field, boolean curVal) { > - lock(); > - try { > - _single.storeBooleanField(field, curVal); > - replaceField(_pc, _single, field); > - setLoaded(field, true); > - postLoad(field, null); > - } finally { > - unlock(); > - } > - } > - > - public void storeByte(int field, byte externalVal) { > - FieldMetaData fmd = _meta.getField(field); > - if (!fmd.isExternalized()) > - storeByteField(field, externalVal); > - else > - storeField(field, fmd.getFieldValue(new > Byte(externalVal), > - _broker)); > - } > - > - public void storeByteField(int field, byte curVal) { > - lock(); > - try { > - _single.storeByteField(field, curVal); > - replaceField(_pc, _single, field); > - setLoaded(field, true); > - postLoad(field, null); > - } finally { > - unlock(); > - } > - } > - > - public void storeChar(int field, char externalVal) { > - FieldMetaData fmd = _meta.getField(field); > - if (!fmd.isExternalized()) > - storeCharField(field, externalVal); > - else > - storeField(field, fmd.getFieldValue(new > Character(externalVal), > - _broker)); > - } > - > - public void storeCharField(int field, char curVal) { > - lock(); > - try { > - _single.storeCharField(field, curVal); > - replaceField(_pc, _single, field); > - setLoaded(field, true); > - postLoad(field, null); > - } finally { > - unlock(); > - } > - } > - > - public void storeDouble(int field, double externalVal) { > - FieldMetaData fmd = _meta.getField(field); > - if (!fmd.isExternalized()) > - storeDoubleField(field, externalVal); > - else > - storeField(field, fmd.getFieldValue(new > Double(externalVal), > - _broker)); > - } > - > - public void storeDoubleField(int field, double curVal) { > - lock(); > - try { > - _single.storeDoubleField(field, curVal); > - replaceField(_pc, _single, field); > - setLoaded(field, true); > - postLoad(field, null); > - } finally { > - unlock(); > - } > - } > - > - public void storeFloat(int field, float externalVal) { > - FieldMetaData fmd = _meta.getField(field); > - if (!fmd.isExternalized()) > - storeFloatField(field, externalVal); > - else > - storeField(field, fmd.getFieldValue(new > Float(externalVal), > - _broker)); > - } > - > - public void storeFloatField(int field, float curVal) { > - lock(); > - try { > - _single.storeFloatField(field, curVal); > - replaceField(_pc, _single, field); > - setLoaded(field, true); > - postLoad(field, null); > - } finally { > - unlock(); > - } > - } > - > - public void storeInt(int field, int externalVal) { > - FieldMetaData fmd = _meta.getField(field); > - if (!fmd.isExternalized()) > - storeIntField(field, externalVal); > - else > - storeField(field, > fmd.getFieldValue(Numbers.valueOf(externalVal), > - _broker)); > - } > - > - public void storeIntField(int field, int curVal) { > - lock(); > - try { > - _single.storeIntField(field, curVal); > - replaceField(_pc, _single, field); > - setLoaded(field, true); > - postLoad(field, null); > - } finally { > - unlock(); > - } > - } > - > - public void storeLong(int field, long externalVal) { > - FieldMetaData fmd = _meta.getField(field); > - if (!fmd.isExternalized()) > - storeLongField(field, externalVal); > - else > - storeField(field, > fmd.getFieldValue(Numbers.valueOf(externalVal), > - _broker)); > - } > - > - public void storeLongField(int field, long curVal) { > - lock(); > - try { > - _single.storeLongField(field, curVal); > - replaceField(_pc, _single, field); > - setLoaded(field, true); > - postLoad(field, null); > - } finally { > - unlock(); > - } > - } > - > - public void storeObject(int field, Object externalVal) { > - FieldMetaData fmd = _meta.getField(field); > - externalVal = fmd.order(externalVal); > - if (!fmd.isExternalized()) > - storeObjectField(field, externalVal); > - else > - storeField(field, fmd.getFieldValue(externalVal, > _broker)); > - } > - > - public void storeObjectField(int field, Object curVal) { > - lock(); > - try { > - _single.storeObjectField(field, curVal); > - _single.proxy(true, false); > - replaceField(_pc, _single, field); > - setLoaded(field, true); > - postLoad(field, null); > - } finally { > - unlock(); > - } > - } > - > - public void storeShort(int field, short externalVal) { > - FieldMetaData fmd = _meta.getField(field); > - if (!fmd.isExternalized()) > - storeShortField(field, externalVal); > - else > - storeField(field, fmd.getFieldValue(new > Short(externalVal), > - _broker)); > - } > - > - public void storeShortField(int field, short curVal) { > - lock(); > - try { > - _single.storeShortField(field, curVal); > - replaceField(_pc, _single, field); > - setLoaded(field, true); > - postLoad(field, null); > - } finally { > - unlock(); > - } > - } > - > - public void storeString(int field, String externalVal) { > - FieldMetaData fmd = _meta.getField(field); > - if (!fmd.isExternalized()) > - storeStringField(field, externalVal); > - else > - storeField(field, fmd.getFieldValue(externalVal, > _broker)); > - } > - > - public void storeStringField(int field, String curVal) { > - lock(); > - try { > - _single.storeStringField(field, curVal); > - replaceField(_pc, _single, field); > - setLoaded(field, true); > - postLoad(field, null); > - } finally { > - unlock(); > - } > - } > - > - /** > - * Store the given field value into the given field manager. > - */ > - private void storeField(int field, Object val, FieldManager fm) { > - FieldMetaData fmd = _meta.getField(field); > - if (fmd == null) > - throw new UserException(_loc.get("no-field-index", > - String.valueOf(field), _meta.getDescribedType())). > - setFailedObject(getManagedInstance()); > - > - switch (fmd.getDeclaredTypeCode()) { > - case JavaTypes.BOOLEAN: > - boolean bool = val != null && ((Boolean) > val).booleanValue(); > - fm.storeBooleanField(field, bool); > - break; > - case JavaTypes.BYTE: > - byte b = (val == null) ? 0 : ((Number) > val).byteValue(); > - fm.storeByteField(field, b); > - break; > - case JavaTypes.CHAR: > - char c = (val == null) ? 0 : ((Character) > val).charValue(); > - fm.storeCharField(field, c); > - break; > - case JavaTypes.DOUBLE: > - double d = (val == null) ? 0 : ((Number) > val).doubleValue(); > - fm.storeDoubleField(field, d); > - break; > - case JavaTypes.FLOAT: > - float f = (val == null) ? 0 : ((Number) > val).floatValue(); > - fm.storeFloatField(field, f); > - break; > - case JavaTypes.INT: > - int i = (val == null) ? 0 : ((Number) > val).intValue(); > - fm.storeIntField(field, i); > - break; > - case JavaTypes.LONG: > - long l = (val == null) ? 0 : ((Number) > val).longValue(); > - fm.storeLongField(field, l); > - break; > - case JavaTypes.SHORT: > - short s = (val == null) ? 0 : ((Number) > val).shortValue(); > - fm.storeShortField(field, s); > - break; > - case JavaTypes.STRING: > - fm.storeStringField(field, (String) val); > - break; > - default: > - fm.storeObjectField(field, val); > - } > - } > - > - ///////////// > - // Utilities > - ///////////// > - > - /** > - * Erase the fact that this instance has been flushed. > - */ > - void eraseFlush() { > - _flags &= ~FLAG_FLUSHED; > - _flags &= ~FLAG_FLUSHED_DIRTY; > - > - int fmds = _meta.getFields().length; > - for (int i = 0; i < fmds; i++) > - _flush.clear(i); > - } > - > - /** > - * Records that all instance fields are/are not loaded. > - * Primary key and non-persistent fields are not affected. > - */ > - void setLoaded(boolean val) { > - FieldMetaData[] fmds = _meta.getFields(); > - for (int i = 0; i < fmds.length; i++) { > - if (!fmds[i].isPrimaryKey() > - && fmds[i].getManagement() == > fmds[i].MANAGE_PERSISTENT) > - setLoaded(i, val); > - } > - if (!val) { > - _flags &= ~FLAG_LOADED; > - setDirty(false); > - } else > - _flags |= FLAG_LOADED; > - } > - > - /** > - * Records that all instance fields are/are not dirty, > - * and changes the flags of the instance accordingly. > - */ > > [... 3925 lines stripped ...] > Craig L Russell Architect, Sun Java Enterprise System http://db.apache.org/jdo 408 276-5638 mailto:Craig.Russell@sun.com P.S. A good JDO? O, Gasp! --Apple-Mail-95--315197212 Content-Disposition: attachment; filename=smime.p7s Content-Type: application/pkcs7-signature; name=smime.p7s Content-Transfer-Encoding: base64 MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIGUDCCAwkw ggJyoAMCAQICECvOQSuIjHMvOZRC95BRg/wwDQYJKoZIhvcNAQEFBQAwYjELMAkGA1UEBhMCWkEx JTAjBgNVBAoTHFRoYXd0ZSBDb25zdWx0aW5nIChQdHkpIEx0ZC4xLDAqBgNVBAMTI1RoYXd0ZSBQ ZXJzb25hbCBGcmVlbWFpbCBJc3N1aW5nIENBMB4XDTA3MTIxMDE1MjM1MVoXDTA4MTIwOTE1MjM1 MVowbDEQMA4GA1UEBBMHUnVzc2VsbDEUMBIGA1UEKhMLQ3JhaWcgTGFpcmQxHDAaBgNVBAMTE0Ny YWlnIExhaXJkIFJ1c3NlbGwxJDAiBgkqhkiG9w0BCQEWFUNyYWlnLlJ1c3NlbGxAU3VuLkNPTTCC ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKzqGlLUastboCRqc0iBoTz2ODcqpMpEyPUo nYtluchkSIoWzOW63AuoTczRt9sKfhwoK5mope+62B6Li06WJabm2UHqKAaNSuMHLsmyqvOdwbSt enY7/HxOSCMqVoyVBTRJc2M8feCSVgi7ptGq9cM+Maa64R1/p9zqaQNucceU/1uper90bWplsjAT rHgicgr9XJIQb6uYjhjlgxxnY/aispnCvLxMX+CiA2FWeeJTI7AiFlLwibTXYF4v12ToByvXtTiJ knuND8qpwhK3Wp0tL4ae8mZ0nlKjCuNnqh99ZyEyTFHZBfVx8WSWRXkY4qxCG/IDQUo7WUaefOQT 1mECAwEAAaMyMDAwIAYDVR0RBBkwF4EVQ3JhaWcuUnVzc2VsbEBTdW4uQ09NMAwGA1UdEwEB/wQC MAAwDQYJKoZIhvcNAQEFBQADgYEAEqfFNFoch0QPVKWJ4maAZl3MJD10yMeWt5xb+WNSkhYKHD8I 42E8tpdE3kmc5wp2cZrz9JqJF/KCQ/gI4pmDk1qpTs5pvXzFNiD5Lu5eLza4iyxSlTHUXcCnyNC6 4m0qC8p4m/51NEql5hyacj/+vdlEe5dygpyNGUCiyA/SdAswggM/MIICqKADAgECAgENMA0GCSqG SIb3DQEBBQUAMIHRMQswCQYDVQQGEwJaQTEVMBMGA1UECBMMV2VzdGVybiBDYXBlMRIwEAYDVQQH EwlDYXBlIFRvd24xGjAYBgNVBAoTEVRoYXd0ZSBDb25zdWx0aW5nMSgwJgYDVQQLEx9DZXJ0aWZp Y2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uMSQwIgYDVQQDExtUaGF3dGUgUGVyc29uYWwgRnJlZW1h aWwgQ0ExKzApBgkqhkiG9w0BCQEWHHBlcnNvbmFsLWZyZWVtYWlsQHRoYXd0ZS5jb20wHhcNMDMw NzE3MDAwMDAwWhcNMTMwNzE2MjM1OTU5WjBiMQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3Rl IENvbnN1bHRpbmcgKFB0eSkgTHRkLjEsMCoGA1UEAxMjVGhhd3RlIFBlcnNvbmFsIEZyZWVtYWls IElzc3VpbmcgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMSmPFVzVftOucqZWh5owHUE cJ3f6f+jHuy9zfVb8hp2vX8MOmHyv1HOAdTlUAow1wJjWiyJFXCO3cnwK4Vaqj9xVsuvPAsH5/Ef kTYkKhPPK9Xzgnc9A74r/rsYPge/QIACZNenprufZdHFKlSFD0gEf6e20TxhBEAeZBlyYLf7AgMB AAGjgZQwgZEwEgYDVR0TAQH/BAgwBgEB/wIBADBDBgNVHR8EPDA6MDigNqA0hjJodHRwOi8vY3Js LnRoYXd0ZS5jb20vVGhhd3RlUGVyc29uYWxGcmVlbWFpbENBLmNybDALBgNVHQ8EBAMCAQYwKQYD VR0RBCIwIKQeMBwxGjAYBgNVBAMTEVByaXZhdGVMYWJlbDItMTM4MA0GCSqGSIb3DQEBBQUAA4GB AEiM0VCD6gsuzA2jZqxnD3+vrL7CF6FDlpSdf0whuPg2H6otnzYvwPQcUCCTcDz9reFhYsPZOhl+ hLGZGwDFGguCdJ4lUJRix9sncVcljd2pnDmOjCBPZV+V2vf3h9bGCE6u9uo05RAaWzVNd+NWIXiC 3CEZNd4ksdMdRv9dX2VPMYIDEDCCAwwCAQEwdjBiMQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhh d3RlIENvbnN1bHRpbmcgKFB0eSkgTHRkLjEsMCoGA1UEAxMjVGhhd3RlIFBlcnNvbmFsIEZyZWVt YWlsIElzc3VpbmcgQ0ECECvOQSuIjHMvOZRC95BRg/wwCQYFKw4DAhoFAKCCAW8wGAYJKoZIhvcN AQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMDgwOTMwMjAwNTM5WjAjBgkqhkiG9w0B CQQxFgQUi5+xXabRccLHaRfksDbIUEqgF+IwgYUGCSsGAQQBgjcQBDF4MHYwYjELMAkGA1UEBhMC WkExJTAjBgNVBAoTHFRoYXd0ZSBDb25zdWx0aW5nIChQdHkpIEx0ZC4xLDAqBgNVBAMTI1RoYXd0 ZSBQZXJzb25hbCBGcmVlbWFpbCBJc3N1aW5nIENBAhArzkEriIxzLzmUQveQUYP8MIGHBgsqhkiG 9w0BCRACCzF4oHYwYjELMAkGA1UEBhMCWkExJTAjBgNVBAoTHFRoYXd0ZSBDb25zdWx0aW5nIChQ dHkpIEx0ZC4xLDAqBgNVBAMTI1RoYXd0ZSBQZXJzb25hbCBGcmVlbWFpbCBJc3N1aW5nIENBAhAr zkEriIxzLzmUQveQUYP8MA0GCSqGSIb3DQEBAQUABIIBAAwwnBrtcgJj7fX7MKbsunJ24f7seN+L g612SysCi1n1Cb/MjOrLwYqV6TtOe46mhrqr8FX1uSrcjnLhIflB1xqk2r8AUgQdQgFpp2ijoDL1 YIGG0iadQlGAnn9nWEMNbWJKVq3H+2gtUbRqpf+JkSc3W2k+IOZIUBZdLAcq23PRdNGz9e2uFi27 H7rThqMHr49v+RDzp17XgfwIi1sJkfRoo3ZXMhGferw2BdP8paJOyG6khi7OB/0u9mZNE4rFFo/k oTLLS7NujpV0rgrAJyCCgmfWvh4vqMiVXRPkGvz+6/4o1vlf+AUmRwjWo49UMR21mj5lOhF+isfh v/ToPvsAAAAAAAA= --Apple-Mail-95--315197212--