You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by aw...@apache.org on 2006/07/29 01:48:18 UTC
svn commit: r426710 [5/6] - in /incubator/openjpa/trunk:
openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/
openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/
openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ openjpa-jdbc/sr...
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCDataGenerator.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCDataGenerator.java?rev=426710&r1=426709&r2=426710&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCDataGenerator.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCDataGenerator.java Fri Jul 28 16:48:13 2006
@@ -26,7 +26,6 @@
import org.apache.openjpa.conf.OpenJPAConfiguration;
import org.apache.openjpa.kernel.AbstractPCData;
import org.apache.openjpa.kernel.FetchConfiguration;
-import org.apache.openjpa.kernel.FetchState;
import org.apache.openjpa.kernel.OpenJPAStateManager;
import org.apache.openjpa.kernel.PCData;
import org.apache.openjpa.kernel.StoreContext;
@@ -523,18 +522,12 @@
}
private void addLoadMethod(BCClass bc, ClassMetaData meta) {
- // public void load(OpenJPAStateManager sm, FetchState fetchState,
+ // public void load(OpenJPAStateManager sm, FetchConfiguration fetch,
// Object context)
Code code = addLoadMethod(bc, false);
FieldMetaData[] fmds = meta.getFields();
Collection jumps = new LinkedList();
Collection jumps2;
- // FetchConfiguration fetch = fetchState.getFetchConfiguration();
- int fetch = code.getNextLocalsIndex();
- code.aload().setParam(1);
- code.invokeinterface().setMethod(FetchState.class,
- "getFetchConfiguration", FetchConfiguration.class, null);
- code.astore().setLocal(fetch);
int local = code.getNextLocalsIndex();
code.constant().setNull();
@@ -558,38 +551,22 @@
if (intermediate)
addLoadIntermediate(code, i, objectCount, jumps2, inter);
-
jumps2.add(code.go2());
- // if in DFG, no if statement.
- // else if (fetch.hasFetchGroup(sm.getMetaData().getField(i).
- // getFetchGroups()) || fetch.hasField(fmds[i].getFullName()))
- if (!fmds[i].isInDefaultFetchGroup()) {
- setTarget(code.aload().setLocal(fetch), jumps);
- code.aload().setParam(0);
- code.invokeinterface().setMethod(OpenJPAStateManager.class,
- "getMetaData", ClassMetaData.class, null);
- code.constant().setValue(fmds[i].getIndex());
- code.invokevirtual().setMethod(ClassMetaData.class,
- "getField", FieldMetaData.class, new Class[]{int.class});
- code.invokevirtual().setMethod(FieldMetaData.class,
- "getFetchGroups", Set.class, null);
- code.invokeinterface().setMethod
- (FetchConfiguration.class, "hasAnyFetchGroup",
- boolean.class, new Class[]{ Set.class });
- JumpInstruction ifins = code.ifne();
- code.aload().setLocal(fetch);
- code.constant().setValue(fmds[i].getFullName());
- code.invokeinterface().setMethod
- (FetchConfiguration.class, "hasField", boolean.class,
- new Class[]{ String.class });
- jumps2.add(code.ifeq());
- ifins.setTarget(addLoad(bc, code, fmds[i], objectCount,
- local, false));
- } else {
- setTarget(addLoad(bc, code, fmds[i], objectCount,
- local, false), jumps);
- }
+ // if (fetch.requiresFetch(fmds[i]))
+ setTarget(code.aload().setParam(1), jumps);
+ code.aload().setParam(0);
+ code.invokeinterface().setMethod(OpenJPAStateManager.class,
+ "getMetaData", ClassMetaData.class, null);
+ code.constant().setValue(fmds[i].getIndex());
+ code.invokevirtual().setMethod(ClassMetaData.class,
+ "getField", FieldMetaData.class, new Class[]{int.class});
+ code.invokeinterface().setMethod (FetchConfiguration.class,
+ "requiresFetch", boolean.class,
+ new Class[]{FieldMetaData.class});
+ jumps2.add(code.ifeq());
+ addLoad(bc, code, fmds[i], objectCount, local, false);
+
jumps = jumps2;
if (replaceType(fmds[i]) >= JavaTypes.OBJECT)
objectCount++;
@@ -601,7 +578,7 @@
private void addLoadWithFieldsMethod(BCClass bc, ClassMetaData meta) {
Code code = addLoadMethod(bc, true);
- // public void load(OpenJPAStateManager sm, FetchState fs,
+ // public void load(OpenJPAStateManager sm, FetchConfiguration fetch,
// BitSet fields, Object conn)
FieldMetaData[] fmds = meta.getFields();
Collection jumps = new LinkedList();
@@ -667,10 +644,10 @@
Class[] args = null;
if (fields)
args = new Class[]{ OpenJPAStateManager.class, BitSet.class,
- FetchState.class, Object.class };
+ FetchConfiguration.class, Object.class };
else
args = new Class[]{ OpenJPAStateManager.class,
- FetchState.class, Object.class };
+ FetchConfiguration.class, Object.class };
BCMethod load = bc.declareMethod("load", void.class, args);
Code code = load.getCode(true);
@@ -730,9 +707,9 @@
code.aload().setParam(1 + offset);
code.aload().setParam(2 + offset);
code.invokevirtual().setMethod(bc.getName(), "toField",
- Object.class.getName(), toStrings
- (new Class[]{ OpenJPAStateManager.class, FieldMetaData.class,
- Object.class, FetchState.class, Object.class }));
+ Object.class.getName(), toStrings(new Class[]{
+ OpenJPAStateManager.class, FieldMetaData.class,
+ Object.class, FetchConfiguration.class, Object.class }));
code.invokeinterface().setMethod(OpenJPAStateManager.class,
"storeField", void.class,
new Class[]{ int.class, Object.class });
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractPCData.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractPCData.java?rev=426710&r1=426709&r2=426710&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractPCData.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractPCData.java Fri Jul 28 16:48:13 2006
@@ -64,7 +64,7 @@
* Transform the given data value into its field value.
*/
protected Object toField(OpenJPAStateManager sm, FieldMetaData fmd,
- Object data, FetchState fetchState, Object context) {
+ Object data, FetchConfiguration fetch, Object context) {
if (data == null)
return null;
@@ -74,7 +74,7 @@
Collection c2 = (Collection) sm.newFieldProxy(fmd.getIndex());
for (int i = 0; i < c.size(); i++)
c2.add(toNestedField(sm, fmd.getElement(), c.get(i),
- fetchState, context));
+ fetch, context));
if (c2 instanceof Proxy) {
ChangeTracker ct = ((Proxy) c2).getChangeTracker();
if (ct != null)
@@ -90,9 +90,9 @@
for (Iterator mi = m.entrySet().iterator(); mi.hasNext();) {
e = (Map.Entry) mi.next();
key = toNestedField(sm, fmd.getKey(), e.getKey(),
- fetchState, context);
+ fetch, context);
value = toNestedField(sm, fmd.getElement(), e.getValue(),
- fetchState, context);
+ fetch, context);
m2.put(key, value);
}
return m2;
@@ -102,11 +102,11 @@
l.size());
for (int i = 0; i < l.size(); i++) {
Array.set(a, i, toNestedField(sm, fmd.getElement(),
- l.get(i), fetchState, context));
+ l.get(i), fetch, context));
}
return a;
default:
- return toNestedField(sm, fmd, data, fetchState, context);
+ return toNestedField(sm, fmd, data, fetch, context);
}
}
@@ -115,7 +115,7 @@
* may be a key, value, or element of a map or collection.
*/
protected Object toNestedField(OpenJPAStateManager sm, ValueMetaData vmd,
- Object data, FetchState fetchState, Object context) {
+ Object data, FetchConfiguration fetch, Object context) {
if (data == null)
return null;
@@ -126,11 +126,11 @@
return (Locale) data;
case JavaTypes.PC:
if (vmd.isEmbedded())
- return toEmbeddedField(sm, vmd, data, fetchState, context);
+ return toEmbeddedField(sm, vmd, data, fetch, context);
// no break
case JavaTypes.PC_UNTYPED:
Object ret =
- toRelationField(sm, vmd, data, fetchState, context);
+ toRelationField(sm, vmd, data, fetch, context);
if (ret != null)
return ret;
OrphanedKeyAction action = sm.getContext().getConfiguration().
@@ -146,8 +146,8 @@
* implementation assumes the data is an oid.
*/
protected Object toRelationField(OpenJPAStateManager sm, ValueMetaData vmd,
- Object data, FetchState fetchState, Object context) {
- return sm.getContext().find(data, fetchState, null, null, 0);
+ Object data, FetchConfiguration fetch, Object context) {
+ return sm.getContext().find(data, fetch, null, null, 0);
}
/**
@@ -155,12 +155,12 @@
* implementation assumes the data is an {@link AbstractPCData}.
*/
protected Object toEmbeddedField(OpenJPAStateManager sm, ValueMetaData vmd,
- Object data, FetchState fetchState, Object context) {
+ Object data, FetchConfiguration fetch, Object context) {
AbstractPCData pcdata = (AbstractPCData) data;
OpenJPAStateManager embedded = sm.getContext().embed(null,
pcdata.getId(), sm, vmd);
pcdata.load(embedded, (BitSet) pcdata.getLoaded().clone(),
- fetchState, context);
+ fetch, context);
return embedded.getManagedInstance();
}
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractPCResultObjectProvider.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractPCResultObjectProvider.java?rev=426710&r1=426709&r2=426710&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractPCResultObjectProvider.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractPCResultObjectProvider.java Fri Jul 28 16:48:13 2006
@@ -53,10 +53,10 @@
}
public void initialize(OpenJPAStateManager sm, PCState state,
- FetchState fetchState)
+ FetchConfiguration fetch)
throws Exception {
sm.initialize(getPCType(), state);
- load(sm, fetchState);
+ load(sm, fetch);
}
public Object getResultObject()
@@ -93,7 +93,8 @@
* manager. Remember to call {@link OpenJPAStateManager#setVersion} to set
* the optimistic versioning information, if it has any.
*/
- protected abstract void load(OpenJPAStateManager sm, FetchState fetch)
+ protected abstract void load(OpenJPAStateManager sm,
+ FetchConfiguration fetch)
throws Exception;
/**
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java?rev=426710&r1=426709&r2=426710&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java Fri Jul 28 16:48:13 2006
@@ -694,20 +694,18 @@
int flags = OID_COPY | OID_ALLOW_NEW | OID_NODELETED;
if (!validate)
flags |= OID_NOVALIDATE;
- return find(oid, _fc.newFetchState (), null, null, flags, call);
+ return find(oid, _fc, null, null, flags, call);
}
- public Object find(Object oid, FetchState fetchState, BitSet exclude,
+ public Object find(Object oid, FetchConfiguration fetch, BitSet exclude,
Object edata, int flags) {
- if (fetchState == null)
- fetchState = _fc.newFetchState ();
- return find(oid, fetchState, exclude, edata, flags, null);
+ return find(oid, fetch, exclude, edata, flags, null);
}
/**
* Internal finder.
*/
- protected Object find(Object oid, FetchState fetchState, BitSet exclude,
+ protected Object find(Object oid, FetchConfiguration fetch, BitSet exclude,
Object edata, int flags, FindCallbacks call) {
if (call == null)
call = this;
@@ -717,6 +715,8 @@
throw new ObjectNotFoundException(_loc.get("null-oid"));
return call.processReturn(oid, null);
}
+ if (fetch == null)
+ fetch = _fc;
beginOperation(true);
try {
@@ -732,16 +732,13 @@
if (!sm.isLoading()) {
// make sure all the configured fields are loaded; do this
// after making instance transactional for locking
- if (!sm.isTransactional()
- && useTransactionalState(fetchState.
- getFetchConfiguration()))
+ if (!sm.isTransactional() && useTransactionalState(fetch))
sm.transactional();
boolean loaded = sm.isLoading();
if (!loaded) {
try {
- loaded = sm.load(fetchState,
- StateManagerImpl.LOAD_FGS, exclude, edata,
- false);
+ loaded = sm.load(fetch, StateManagerImpl.LOAD_FGS,
+ exclude, edata, false);
} catch (ObjectNotFoundException onfe) {
if ((flags & OID_NODELETED) != 0
|| (flags & OID_NOVALIDATE) != 0)
@@ -767,8 +764,6 @@
// since the object was cached, we may need to upgrade lock
// if current level is higher than level of initial load
if ((_flags & FLAG_ACTIVE) != 0) {
- FetchConfiguration fetch =
- fetchState.getFetchConfiguration();
int level = fetch.getReadLockLevel();
_lm.lock(sm, level, fetch.getLockTimeout(), edata);
sm.readLocked(level, fetch.getWriteLockLevel());
@@ -784,7 +779,7 @@
// initialize a new state manager for the datastore instance
sm = newStateManagerImpl(oid, (flags & OID_COPY) != 0);
boolean load = requiresLoad(sm, false, edata, flags);
- sm = initialize(sm, load, fetchState, edata);
+ sm = initialize(sm, load, fetch, edata);
if (sm == null) {
if ((flags & OID_NOVALIDATE) != 0)
throw new ObjectNotFoundException(oid);
@@ -794,7 +789,7 @@
// make sure all configured fields were loaded
if (load) {
try {
- sm.load(fetchState, StateManagerImpl.LOAD_FGS, exclude,
+ sm.load(fetch, StateManagerImpl.LOAD_FGS, exclude,
edata, false);
} catch (ObjectNotFoundException onfe) {
if ((flags & OID_NODELETED) != 0
@@ -817,18 +812,16 @@
* Initialize a newly-constructed state manager.
*/
protected StateManagerImpl initialize(StateManagerImpl sm, boolean load,
- FetchState fetchState, Object edata) {
+ FetchConfiguration fetch, Object edata) {
if (!load) {
sm.initialize(sm.getMetaData().getDescribedType(),
PCState.HOLLOW);
} else {
- FetchConfiguration fetch = (fetchState == null)
- ? _fc : fetchState.getFetchConfiguration();
PCState state = (useTransactionalState(fetch))
? PCState.PCLEAN : PCState.PNONTRANS;
sm.setLoading(true);
try {
- if (!_store.initialize(sm, state, fetchState, edata))
+ if (!_store.initialize(sm, state, fetch, edata))
return null;
} finally {
sm.setLoading(false);
@@ -867,6 +860,9 @@
_loading = new HashMap((int) (oids.size() * 1.33 + 1));
if (call == null)
call = this;
+ if (fetch == null)
+ fetch = _fc;
+
beginOperation(true);
try {
assertNontransactionalRead();
@@ -912,7 +908,7 @@
PCState state = (transState) ? PCState.PCLEAN
: PCState.PNONTRANS;
Collection failed = _store.loadAll(load, state,
- StoreManager.FORCE_LOAD_NONE, _fc, edata);
+ StoreManager.FORCE_LOAD_NONE, fetch, edata);
// set failed instances to null
if (failed != null && !failed.isEmpty()) {
@@ -934,7 +930,7 @@
sm = (StateManagerImpl) _loading.get(oid);
if (sm != null && requiresLoad(sm, true, edata, flags)) {
try {
- sm.load(fetch.newFetchState(), StateManagerImpl.LOAD_FGS,
+ sm.load(fetch, StateManagerImpl.LOAD_FGS,
exclude, edata, false);
if (active) {
_lm.lock(sm, level, fetch.getLockTimeout(), edata);
@@ -2482,8 +2478,7 @@
// otherwise make sure pc is fully loaded for when we copy its
// data below
- orig.load(_fc.newFetchState(), StateManagerImpl.LOAD_ALL,
- null, null, false);
+ orig.load(_fc, StateManagerImpl.LOAD_ALL, null, null, false);
}
// create new state manager with embedded metadata
@@ -2698,8 +2693,8 @@
try {
sm.afterRefresh();
- sm.load(_fc.newFetchState(),
- StateManagerImpl.LOAD_FGS, null, null, false);
+ sm.load(_fc, StateManagerImpl.LOAD_FGS, null, null,
+ false);
} catch (OpenJPAException ke) {
exceps = add(exceps, ke);
}
@@ -2739,8 +2734,7 @@
if (sm.isDetached())
throw newDetachedException(obj, "refresh");
else if (sm.beforeRefresh(false)) {
- sm.load(_fc.newFetchState(), StateManagerImpl.LOAD_FGS,
- null, null, false);
+ sm.load(_fc, StateManagerImpl.LOAD_FGS, null, null, false);
sm.afterRefresh();
}
fireLifecycleEvent(sm.getManagedInstance(), null,
@@ -2825,7 +2819,7 @@
: StateManagerImpl.LOAD_ALL;
try {
sm.beforeRead(-1);
- sm.load(_fc.newFetchState(), mode, null, null, false);
+ sm.load(_fc, mode, null, null, false);
} catch (OpenJPAException ke) {
exceps = add(exceps, ke);
}
@@ -2861,7 +2855,7 @@
int mode = (dfgOnly) ? StateManagerImpl.LOAD_FGS
: StateManagerImpl.LOAD_ALL;
sm.beforeRead(-1);
- sm.load(_fc.newFetchState(), mode, null, null, false);
+ sm.load(_fc, mode, null, null, false);
}
} else if (assertPersistenceCapable(obj).pcIsDetached()
== Boolean.TRUE)
@@ -3227,8 +3221,7 @@
if (sm != null && sm.isPersistent()) {
assertActiveTransaction();
sm.transactional();
- sm.load(_fc.newFetchState(), StateManagerImpl.LOAD_FGS, null,
- null, false);
+ sm.load(_fc, StateManagerImpl.LOAD_FGS, null, null, false);
sm.setCheckVersion(true);
if (updateVersion)
sm.setUpdateVersion(true);
@@ -3266,8 +3259,7 @@
try {
sm.transactional();
- sm.load(_fc.newFetchState(), StateManagerImpl.LOAD_FGS, null,
- null, false);
+ sm.load(_fc, StateManagerImpl.LOAD_FGS, null, null, false);
} catch (OpenJPAException ke) {
exceps = add(exceps, ke);
}
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java?rev=426710&r1=426709&r2=426710&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java Fri Jul 28 16:48:13 2006
@@ -189,10 +189,10 @@
}
}
- public Object find(Object oid, FetchState fetchState, BitSet exclude,
+ public Object find(Object oid, FetchConfiguration fetch, BitSet exclude,
Object edata, int flags) {
try {
- return _broker.find(oid, fetchState, exclude, edata, flags);
+ return _broker.find(oid, fetch, exclude, edata, flags);
} catch (RuntimeException re) {
throw translate(re);
}
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingFetchConfiguration.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingFetchConfiguration.java?rev=426710&r1=426709&r2=426710&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingFetchConfiguration.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingFetchConfiguration.java Fri Jul 28 16:48:13 2006
@@ -20,6 +20,7 @@
import org.apache.openjpa.lib.rop.ResultList;
import org.apache.openjpa.lib.rop.ResultObjectProvider;
+import org.apache.openjpa.meta.FieldMetaData;
import org.apache.openjpa.util.RuntimeExceptionTranslator;
///////////////////////////////////////////////////////////////
@@ -229,14 +230,6 @@
}
}
- public boolean hasAnyFetchGroup(Set groups) {
- try {
- return _fetch.hasAnyFetchGroup(groups);
- } catch (RuntimeException re) {
- throw translate(re);
- }
- }
-
public FetchConfiguration addFetchGroup(String group) {
try {
_fetch.addFetchGroup(group);
@@ -411,14 +404,6 @@
}
}
- public FetchState newFetchState() {
- try {
- return _fetch.newFetchState();
- } catch (RuntimeException re) {
- throw translate(re);
- }
- }
-
public void copy(FetchConfiguration fetch) {
try {
_fetch.copy(fetch);
@@ -450,6 +435,22 @@
throw translate(re);
}
}
+
+ public boolean requiresFetch(FieldMetaData fmd) {
+ try {
+ return _fetch.requiresFetch(fmd);
+ } catch (RuntimeException re) {
+ throw translate(re);
+ }
+ }
+
+ public FetchConfiguration traverse(FieldMetaData fmd) {
+ try {
+ return _fetch.traverse(fmd);
+ } catch (RuntimeException re) {
+ throw translate(re);
+ }
+ }
public void lock() {
try {
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingStoreManager.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingStoreManager.java?rev=426710&r1=426709&r2=426710&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingStoreManager.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingStoreManager.java Fri Jul 28 16:48:13 2006
@@ -104,13 +104,13 @@
}
public boolean initialize(OpenJPAStateManager sm, PCState state,
- FetchState fetchState, Object context) {
- return _store.initialize(sm, state, fetchState, context);
+ FetchConfiguration fetch, Object context) {
+ return _store.initialize(sm, state, fetch, context);
}
public boolean load(OpenJPAStateManager sm, BitSet fields,
- FetchState fetchState, int lockLevel, Object context) {
- return _store.load(sm, fields, fetchState, lockLevel, context);
+ FetchConfiguration fetch, int lockLevel, Object context) {
+ return _store.load(sm, fields, fetch, lockLevel, context);
}
public Collection loadAll(Collection sms, PCState state, int load,
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachManager.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachManager.java?rev=426710&r1=426709&r2=426710&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachManager.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachManager.java Fri Jul 28 16:48:13 2006
@@ -148,9 +148,7 @@
exclude = StoreContext.EXCLUDE_ALL;
else if (detachMode == DETACH_ALL)
loadMode = StateManagerImpl.LOAD_ALL;
- FetchState fetchState = broker.getFetchConfiguration().
- newFetchState();
- sm.load(fetchState, loadMode, exclude, null, false);
+ sm.load(broker.getFetchConfiguration(), loadMode, exclude, null, false);
// create bitset of fields to detach; if mode is all we can use
// currently loaded bitset clone, since we know all fields are loaded
@@ -221,12 +219,9 @@
StateManagerImpl sm, BitSet idxs) {
FetchConfiguration fetch = broker.getFetchConfiguration();
FieldMetaData[] fmds = sm.getMetaData().getFields();
- for (int i = 0; i < fmds.length; i++) {
- if (fmds[i].isPrimaryKey() || fmds[i].isInDefaultFetchGroup()
- || fetch.hasAnyFetchGroup(fmds[i].getFetchGroups())
- || fetch.hasField(fmds[i].getFullName()))
+ for (int i = 0; i < fmds.length; i++)
+ if (fmds[i].isPrimaryKey() || fetch.requiresFetch(fmds[i]))
idxs.set(i);
- }
}
/**
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedStateManager.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedStateManager.java?rev=426710&r1=426709&r2=426710&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedStateManager.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedStateManager.java Fri Jul 28 16:48:13 2006
@@ -137,9 +137,7 @@
}
}
FetchConfiguration fc = broker.getFetchConfiguration();
- FetchState fetchState = fc.newFetchState();
- sm.loadFields(load, fetchState, fc.getWriteLockLevel(), null, true);
-
+ sm.loadFields(load, fc, fc.getWriteLockLevel(), null, true);
}
sm.setVersion(_version);
@@ -646,15 +644,15 @@
return ret;
}
- ///////////////////////////////////
+ //////////////////////////////////////
// OpenJPAStateManager implementation
- ///////////////////////////////////
+ //////////////////////////////////////
public void initialize(Class forType, PCState state) {
throw new UnsupportedOperationException();
}
- public void load(FetchState fetchState) {
+ public void load(FetchConfiguration fetch) {
throw new UnsupportedOperationException();
}
@@ -702,7 +700,7 @@
throw new UnsupportedOperationException();
}
- public BitSet getUnloaded(FetchState fetchState) {
+ public BitSet getUnloaded(FetchConfiguration fetch) {
throw new UnsupportedOperationException();
}
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedValueStateManager.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedValueStateManager.java?rev=426710&r1=426709&r2=426710&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedValueStateManager.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedValueStateManager.java Fri Jul 28 16:48:13 2006
@@ -65,7 +65,7 @@
throw new UnsupportedOperationException();
}
- public void load(FetchState fetchState) {
+ public void load(FetchConfiguration fetch) {
throw new UnsupportedOperationException();
}
@@ -113,7 +113,7 @@
throw new UnsupportedOperationException();
}
- public BitSet getUnloaded(FetchState fetchState) {
+ public BitSet getUnloaded(FetchConfiguration fetch) {
throw new UnsupportedOperationException();
}
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfiguration.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfiguration.java?rev=426710&r1=426709&r2=426710&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfiguration.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfiguration.java Fri Jul 28 16:48:13 2006
@@ -21,6 +21,7 @@
import org.apache.openjpa.lib.rop.ResultList;
import org.apache.openjpa.lib.rop.ResultObjectProvider;
+import org.apache.openjpa.meta.FieldMetaData;
/**
* Allows configuration and optimization of how objects are loaded from
@@ -28,7 +29,7 @@
*
* @since 3.0
* @author Abe White
- * @author Patrick Linskey
+ * @author Pinaki Poddar
*/
public interface FetchConfiguration
extends Serializable, Cloneable, LockLevels, QueryFlushModes {
@@ -39,18 +40,6 @@
public static final int DEFAULT = -99;
/**
- * Special fetch group name that is used by OpenJPA to indicate that all
- * fetch groups should be loaded by this configuration.
- */
- public static final String FETCH_GROUP_ALL = "openjpa.FetchGroupAll";
-
- /**
- * Special fetch group name that is used by OpenJPA to denote the default
- * fetch group.
- */
- public static final String FETCH_GROUP_DEFAULT = "default";
-
- /**
* Return the context assiciated with this configuration;
* may be null if it has not been set or this object has been serialized.
*/
@@ -143,13 +132,6 @@
public boolean hasFetchGroup(String group);
/**
- * Return true if any of the given fetch groups has been added.
- *
- * @since 4.1
- */
- public boolean hasAnyFetchGroup(Set groups);
-
- /**
* Adds <code>group</code> to the set of fetch group names to
* use when loading objects.
*/
@@ -228,26 +210,6 @@
public FetchConfiguration clearFields();
/**
- * Root classes for recursive operations. This set is not thread safe.
- */
- public Set getRootClasses();
-
- /**
- * Root classes for recursive operations.
- */
- public FetchConfiguration setRootClasses(Collection classes);
-
- /**
- * Root instances for recursive operations. This set is not thread safe.
- */
- public Set getRootInstances();
-
- /**
- * Root instances for recursive operations.
- */
- public FetchConfiguration setRootInstances(Collection roots);
-
- /**
* The number of milliseconds to wait for an object lock, or -1 for no
* limit.
*
@@ -297,13 +259,6 @@
public ResultList newResultList(ResultObjectProvider rop);
/**
- * Create a new fecth state for the current fetch configuration.
- *
- * @since 4.1
- */
- public FetchState newFetchState();
-
- /**
* Sets an arbitrary query hint that may be utilized during
* execution. The hint may be datastore-specific.
*
@@ -318,12 +273,31 @@
* is not specified.
*
* @param name the hint name
- *
- * @since 4.0
+ * @since 4.0
*/
public Object getHint (String name);
/**
+ * Root classes for recursive operations. This set is not thread safe.
+ */
+ public Set getRootClasses();
+
+ /**
+ * Root classes for recursive operations.
+ */
+ public FetchConfiguration setRootClasses(Collection classes);
+
+ /**
+ * Root instances for recursive operations. This set is not thread safe.
+ */
+ public Set getRootInstances();
+
+ /**
+ * Root instances for recursive operations.
+ */
+ public FetchConfiguration setRootInstances(Collection roots);
+
+ /**
* Synchronize on internal lock if multithreaded is true.
*/
public void lock();
@@ -332,4 +306,21 @@
* Release internal lock if multithreaded is true.
*/
public void unlock();
+
+ /**
+ * Affirms if the given field requires to be fetched in the context
+ * of current fetch operation.
+ *
+ * @since 4.1
+ */
+ public boolean requiresFetch(FieldMetaData fm);
+
+ /**
+ * Traverse the given field to generate (possibly) a new configuration
+ * state.
+ *
+ * @return a new configuration state resulting out of traversal
+ * @since 4.1
+ */
+ public FetchConfiguration traverse(FieldMetaData fm);
}
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfigurationImpl.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfigurationImpl.java?rev=426710&r1=426709&r2=426710&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfigurationImpl.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfigurationImpl.java Fri Jul 28 16:48:13 2006
@@ -15,12 +15,15 @@
*/
package org.apache.openjpa.kernel;
+import java.io.Serializable;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -33,6 +36,9 @@
import org.apache.openjpa.lib.rop.SimpleResultList;
import org.apache.openjpa.lib.rop.WindowResultList;
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.util.InternalException;
import org.apache.openjpa.util.NoTransactionException;
import org.apache.openjpa.util.UserException;
@@ -43,6 +49,7 @@
*
* @since 3.0
* @author Abe White
+ * @author Pinaki Poddar
* @nojavadoc
*/
public class FetchConfigurationImpl
@@ -51,31 +58,52 @@
private static final Localizer _loc = Localizer.forPackage
(FetchConfigurationImpl.class);
- // transient state
- private transient StoreContext _ctx = null;
-
- private int _fetchBatchSize = 0;
- private int _maxFetchDepth = 1;
- private boolean _queryCache = true;
- private int _flushQuery = 0;
- private int _lockTimeout = -1;
- private int _readLockLevel = LOCK_NONE;
- private int _writeLockLevel = LOCK_NONE;
- private Set _fetchGroups = null;
- private Set _fields = null;
- private Set _rootClasses;
- private Set _rootInstances;
- private Map _hints = null;
+ /**
+ * Configurable state shared throughout a traversal chain.
+ */
+ protected static class ConfigurationState
+ implements Serializable
+ {
+ public transient StoreContext ctx = null;
+ public int fetchBatchSize = 0;
+ public int maxFetchDepth = 1;
+ public boolean queryCache = true;
+ public int flushQuery = 0;
+ public int lockTimeout = -1;
+ public int readLockLevel = LOCK_NONE;
+ public int writeLockLevel = LOCK_NONE;
+ public Set fetchGroups = null;
+ public Set fields = null;
+ public Set rootClasses;
+ public Set rootInstances;
+ public Map hints = null;
+ }
+
+ private final ConfigurationState _state;
+ private FetchConfigurationImpl _parent;
+ private String _fromField;
+ private Class _fromType;
+ private int _availableRecursion;
+ private int _availableDepth;
+
+ public FetchConfigurationImpl() {
+ this(null);
+ }
+
+ protected FetchConfigurationImpl(ConfigurationState state) {
+ _state = (state == null) ? new ConfigurationState() : state;
+ _availableDepth = _state.maxFetchDepth;
+ }
public StoreContext getContext() {
- return _ctx;
+ return _state.ctx;
}
public void setContext(StoreContext ctx) {
// can't reset non-null context to another context
- if (ctx != null && _ctx != null && ctx != _ctx)
+ if (ctx != null && _state.ctx != null && ctx != _state.ctx)
throw new InternalException();
- _ctx = ctx;
+ _state.ctx = ctx;
if (ctx == null)
return;
@@ -91,18 +119,22 @@
* Clone this instance.
*/
public Object clone() {
- FetchConfigurationImpl clone = newInstance();
- clone._ctx = _ctx;
+ FetchConfigurationImpl clone = newInstance(null);
+ clone._state.ctx = _state.ctx;
+ clone._parent = _parent;
+ clone._fromField = _fromField;
+ clone._fromType = _fromType;
+ clone._availableRecursion = _availableRecursion;
+ clone._availableDepth = _availableDepth;
clone.copy(this);
return clone;
}
/**
- * Return a new hollow instance. Subclasses should override to return
- * a new instance of their type, with cached permissions set appropriately.
+ * Return a new hollow instance.
*/
- protected FetchConfigurationImpl newInstance() {
- return new FetchConfigurationImpl();
+ protected FetchConfigurationImpl newInstance(ConfigurationState state) {
+ return new FetchConfigurationImpl(state);
}
public void copy(FetchConfiguration fetch) {
@@ -117,86 +149,75 @@
addFields(fetch.getFields());
// don't use setters because require active transaction
- _readLockLevel = fetch.getReadLockLevel();
- _writeLockLevel = fetch.getWriteLockLevel();
+ _state.readLockLevel = fetch.getReadLockLevel();
+ _state.writeLockLevel = fetch.getWriteLockLevel();
}
public int getFetchBatchSize() {
- return _fetchBatchSize;
+ return _state.fetchBatchSize;
}
public FetchConfiguration setFetchBatchSize(int fetchBatchSize) {
- if (fetchBatchSize == DEFAULT && _ctx != null)
- fetchBatchSize = _ctx.getConfiguration().getFetchBatchSize();
+ if (fetchBatchSize == DEFAULT && _state.ctx != null)
+ fetchBatchSize = _state.ctx.getConfiguration().getFetchBatchSize();
if (fetchBatchSize != DEFAULT)
- _fetchBatchSize = fetchBatchSize;
+ _state.fetchBatchSize = fetchBatchSize;
return this;
}
public int getMaxFetchDepth() {
- return _maxFetchDepth;
+ return _state.maxFetchDepth;
}
public FetchConfiguration setMaxFetchDepth(int depth) {
- _maxFetchDepth = depth;
+ _state.maxFetchDepth = depth;
+ if (_parent == null)
+ _availableDepth = depth;
return this;
}
public boolean getQueryCache() {
- return _queryCache;
+ return _state.queryCache;
}
public FetchConfiguration setQueryCache(boolean cache) {
- _queryCache = cache;
+ _state.queryCache = cache;
return this;
}
public int getFlushBeforeQueries() {
- return _flushQuery;
+ return _state.flushQuery;
}
public FetchConfiguration setFlushBeforeQueries(int flush) {
- if (flush == DEFAULT && _ctx != null)
- _flushQuery = _ctx.getConfiguration().
+ if (flush == DEFAULT && _state.ctx != null)
+ _state.flushQuery = _state.ctx.getConfiguration().
getFlushBeforeQueriesConstant();
else if (flush != DEFAULT)
- _flushQuery = flush;
+ _state.flushQuery = flush;
return this;
}
public Set getFetchGroups() {
- return (_fetchGroups == null) ? Collections.EMPTY_SET : _fetchGroups;
+ return (_state.fetchGroups == null) ? Collections.EMPTY_SET
+ : _state.fetchGroups;
}
public boolean hasFetchGroup(String group) {
- return _fetchGroups != null
- && (_fetchGroups.contains(group)
- || _fetchGroups.contains(FETCH_GROUP_ALL));
- }
-
- public boolean hasAnyFetchGroup(Set groups) {
- if (groups == null || groups.isEmpty())
- return false;
- for (Iterator itr = groups.iterator(); itr.hasNext();)
- if (hasFetchGroup((String) itr.next()))
- return true;
- return false;
+ return _state.fetchGroups != null
+ && (_state.fetchGroups.contains(group)
+ || _state.fetchGroups.contains(FetchGroup.NAME_ALL));
}
- /**
- * Adds a fetch group of the given name to this receiver.
- *
- * @param name must not be null or empty.
- */
public FetchConfiguration addFetchGroup(String name) {
if (StringUtils.isEmpty(name))
throw new UserException(_loc.get("null-fg"));
lock();
try {
- if (_fetchGroups == null)
- _fetchGroups = new HashSet();
- _fetchGroups.add(name);
+ if (_state.fetchGroups == null)
+ _state.fetchGroups = new HashSet();
+ _state.fetchGroups.add(name);
} finally {
unlock();
}
@@ -214,8 +235,8 @@
public FetchConfiguration removeFetchGroup(String group) {
lock();
try {
- if (_fetchGroups != null)
- _fetchGroups.remove(group);
+ if (_state.fetchGroups != null)
+ _state.fetchGroups.remove(group);
} finally {
unlock();
}
@@ -225,8 +246,8 @@
public FetchConfiguration removeFetchGroups(Collection groups) {
lock();
try {
- if (_fetchGroups != null)
- _fetchGroups.removeAll(groups);
+ if (_state.fetchGroups != null)
+ _state.fetchGroups.removeAll(groups);
} finally {
unlock();
}
@@ -236,8 +257,8 @@
public FetchConfiguration clearFetchGroups() {
lock();
try {
- if (_fetchGroups != null)
- _fetchGroups.clear();
+ if (_state.fetchGroups != null)
+ _state.fetchGroups.clear();
} finally {
unlock();
}
@@ -246,18 +267,18 @@
public FetchConfiguration resetFetchGroups() {
clearFetchGroups();
- if (_ctx != null)
- addFetchGroups(Arrays.asList(_ctx.getConfiguration().
+ if (_state.ctx != null)
+ addFetchGroups(Arrays.asList(_state.ctx.getConfiguration().
getFetchGroupsList()));
return this;
}
public Set getFields() {
- return (_fields == null) ? Collections.EMPTY_SET : _fields;
+ return (_state.fields == null) ? Collections.EMPTY_SET : _state.fields;
}
public boolean hasField(String field) {
- return _fields != null && _fields.contains(field);
+ return _state.fields != null && _state.fields.contains(field);
}
public FetchConfiguration addField(String field) {
@@ -266,9 +287,9 @@
lock();
try {
- if (_fields == null)
- _fields = new HashSet();
- _fields.add(field);
+ if (_state.fields == null)
+ _state.fields = new HashSet();
+ _state.fields.add(field);
} finally {
unlock();
}
@@ -281,9 +302,9 @@
lock();
try {
- if (_fields == null)
- _fields = new HashSet();
- _fields.addAll(fields);
+ if (_state.fields == null)
+ _state.fields = new HashSet();
+ _state.fields.addAll(fields);
} finally {
unlock();
}
@@ -293,8 +314,8 @@
public FetchConfiguration removeField(String field) {
lock();
try {
- if (_fields != null)
- _fields.remove(field);
+ if (_state.fields != null)
+ _state.fields.remove(field);
} finally {
unlock();
}
@@ -304,8 +325,8 @@
public FetchConfiguration removeFields(Collection fields) {
lock();
try {
- if (_fields != null)
- _fields.removeAll(fields);
+ if (_state.fields != null)
+ _state.fields.removeAll(fields);
} finally {
unlock();
}
@@ -315,8 +336,8 @@
public FetchConfiguration clearFields() {
lock();
try {
- if (_fields != null)
- _fields.clear();
+ if (_state.fields != null)
+ _state.fields.clear();
} finally {
unlock();
}
@@ -324,33 +345,33 @@
}
public int getLockTimeout() {
- return _lockTimeout;
+ return _state.lockTimeout;
}
public FetchConfiguration setLockTimeout(int timeout) {
- if (timeout == DEFAULT && _ctx != null)
- _lockTimeout = _ctx.getConfiguration().getLockTimeout();
+ if (timeout == DEFAULT && _state.ctx != null)
+ _state.lockTimeout = _state.ctx.getConfiguration().getLockTimeout();
else if (timeout != DEFAULT)
- _lockTimeout = timeout;
+ _state.lockTimeout = timeout;
return this;
}
public int getReadLockLevel() {
- return _readLockLevel;
+ return _state.readLockLevel;
}
public FetchConfiguration setReadLockLevel(int level) {
- if (_ctx == null)
+ if (_state.ctx == null)
return this;
lock();
try {
assertActiveTransaction();
if (level == DEFAULT)
- _readLockLevel = _ctx.getConfiguration().
+ _state.readLockLevel = _state.ctx.getConfiguration().
getReadLockLevelConstant();
else
- _readLockLevel = level;
+ _state.readLockLevel = level;
} finally {
unlock();
}
@@ -358,21 +379,21 @@
}
public int getWriteLockLevel() {
- return _writeLockLevel;
+ return _state.writeLockLevel;
}
public FetchConfiguration setWriteLockLevel(int level) {
- if (_ctx == null)
+ if (_state.ctx == null)
return this;
lock();
try {
assertActiveTransaction();
if (level == DEFAULT)
- _writeLockLevel = _ctx.getConfiguration().
+ _state.writeLockLevel = _state.ctx.getConfiguration().
getWriteLockLevelConstant();
else
- _writeLockLevel = level;
+ _state.writeLockLevel = level;
} finally {
unlock();
}
@@ -382,82 +403,51 @@
public ResultList newResultList(ResultObjectProvider rop) {
if (rop instanceof ListResultObjectProvider)
return new SimpleResultList(rop);
- if (_fetchBatchSize < 0)
+ if (_state.fetchBatchSize < 0)
return new EagerResultList(rop);
if (rop.supportsRandomAccess())
return new SimpleResultList(rop);
return new WindowResultList(rop);
}
- public FetchState newFetchState() {
- return new FetchStateImpl(this);
- }
-
/**
* Throw an exception if no transaction is active.
*/
private void assertActiveTransaction() {
- if (_ctx != null && !_ctx.isActive())
+ if (_state.ctx != null && !_state.ctx.isActive())
throw new NoTransactionException(_loc.get("not-active"));
}
- public String toString() {
- if ((_fetchGroups == null || _fetchGroups.isEmpty())
- && (_fields == null || _fields.isEmpty()))
- return "Default";
-
- StringBuffer buf = new StringBuffer();
- lock();
- try {
- if (_fetchGroups != null && !_fetchGroups.isEmpty()) {
- for (Iterator itr = _fetchGroups.iterator(); itr.hasNext();) {
- if (buf.length() > 0)
- buf.append(", ");
- buf.append(itr.next());
- }
- }
- if (_fields != null && !_fields.isEmpty()) {
- for (Iterator itr = _fields.iterator(); itr.hasNext();) {
- if (buf.length() > 0)
- buf.append(", ");
- buf.append(itr.next());
- }
- }
- } finally {
- unlock();
- }
- return buf.toString();
- }
-
public void setHint(String name, Object value) {
lock();
try {
- if (_hints == null)
- _hints = new HashMap();
- _hints.put(name, value);
+ if (_state.hints == null)
+ _state.hints = new HashMap();
+ _state.hints.put(name, value);
} finally {
unlock();
}
}
public Object getHint(String name) {
- return (_hints == null) ? null : _hints.get(name);
+ return (_state.hints == null) ? null : _state.hints.get(name);
}
public Set getRootClasses() {
- return (_rootClasses == null) ? Collections.EMPTY_SET : _rootClasses;
+ return (_state.rootClasses == null) ? Collections.EMPTY_SET
+ : _state.rootClasses;
}
public FetchConfiguration setRootClasses(Collection classes) {
lock();
try {
- if (_rootClasses != null)
- _rootClasses.clear();
+ if (_state.rootClasses != null)
+ _state.rootClasses.clear();
if (classes != null && !classes.isEmpty()) {
- if (_rootClasses == null)
- _rootClasses = new HashSet(classes);
+ if (_state.rootClasses == null)
+ _state.rootClasses = new HashSet(classes);
else
- _rootClasses.addAll(classes);
+ _state.rootClasses.addAll(classes);
}
} finally {
unlock();
@@ -466,20 +456,20 @@
}
public Set getRootInstances() {
- return (_rootInstances == null) ? Collections.EMPTY_SET
- : _rootInstances;
+ return (_state.rootInstances == null) ? Collections.EMPTY_SET
+ : _state.rootInstances;
}
public FetchConfiguration setRootInstances(Collection instances) {
lock();
try {
- if (_rootInstances != null)
- _rootInstances.clear();
+ if (_state.rootInstances != null)
+ _state.rootInstances.clear();
if (instances != null && !instances.isEmpty()) {
- if (_rootInstances == null)
- _rootInstances = new HashSet(instances);
+ if (_state.rootInstances == null)
+ _state.rootInstances = new HashSet(instances);
else
- _rootInstances.addAll(instances);
+ _state.rootInstances.addAll(instances);
}
} finally {
unlock();
@@ -488,12 +478,215 @@
}
public void lock() {
- if (_ctx != null)
- _ctx.lock();
+ if (_state.ctx != null)
+ _state.ctx.lock();
}
public void unlock() {
- if (_ctx != null)
- _ctx.unlock();
+ if (_state.ctx != null)
+ _state.ctx.unlock();
+ }
+
+ /////////////
+ // Traversal
+ /////////////
+
+ public boolean requiresFetch(FieldMetaData fm) {
+ if (!includes(fm))
+ return false;
+
+ Class type = getRelationType(fm);
+ if (type == null)
+ return true;
+ if (_availableDepth == 0)
+ return false;
+
+ // we can skip calculating recursion depth if this is a top-level conf:
+ // the field is in our fetch groups, so can't possibly not select
+ if (_parent == null)
+ return true;
+
+ int rdepth = getAvailableRecursionDepth(fm, type, false);
+ return rdepth == FetchGroup.DEPTH_INFINITE || rdepth > 0;
+ }
+
+ public FetchConfiguration traverse(FieldMetaData fm) {
+ Class type = getRelationType(fm);
+ if (type == null)
+ return this;
+
+ FetchConfigurationImpl clone = newInstance(_state);
+ clone._parent = this;
+ clone._availableDepth = reduce(_availableDepth);
+ clone._fromField = fm.getFullName();
+ clone._fromType = type;
+ clone._availableRecursion = getAvailableRecursionDepth(fm, type, true);
+ return clone;
+ }
+
+ /**
+ * Whether our configuration state includes the given field.
+ */
+ private boolean includes(FieldMetaData fmd) {
+ if ((fmd.isInDefaultFetchGroup()
+ && hasFetchGroup(FetchGroup.NAME_DEFAULT))
+ || hasFetchGroup(FetchGroup.NAME_ALL)
+ || hasField(fmd.getFullName()))
+ return true;
+ String[] fgs = fmd.getCustomFetchGroups();
+ for (int i = 0; i < fgs.length; i++)
+ if (hasFetchGroup(fgs[i]))
+ return true;
+ return false;
+ }
+
+ /**
+ * Return the available recursion depth via the given field for the
+ * given type.
+ *
+ * @param traverse whether we're traversing the field
+ */
+ private int getAvailableRecursionDepth(FieldMetaData fm, Class type,
+ boolean traverse) {
+ // see if there's a previous limit
+ int avail = Integer.MIN_VALUE;
+ for (FetchConfigurationImpl f = this; f != null; f = f._parent) {
+ if (isAssignable(type, f._fromType)) {
+ avail = f._availableRecursion;
+ if (traverse)
+ avail = reduce(avail);
+ break;
+ }
+ }
+ if (avail == 0)
+ return 0;
+
+ // calculate fetch groups max
+ ClassMetaData meta = fm.getDefiningMetaData();
+ int max = Integer.MIN_VALUE;
+ if (fm.isInDefaultFetchGroup())
+ max = meta.getFetchGroup(FetchGroup.NAME_DEFAULT).
+ getRecursionDepth(fm);
+ String[] groups = fm.getCustomFetchGroups();
+ int cur;
+ for (int i = 0; max != FetchGroup.DEPTH_INFINITE
+ && i < groups.length; i++) {
+ cur = meta.getFetchGroup(groups[i]).getRecursionDepth(fm);
+ if (cur == FetchGroup.DEPTH_INFINITE || cur > max)
+ max = cur;
+ }
+ // reduce max if we're traversing a self-type relation
+ if (traverse && max != Integer.MIN_VALUE
+ && isAssignable(meta.getDescribedType(), type))
+ max = reduce(max);
+
+ // take min/defined of previous avail and fetch group max
+ if (avail == Integer.MIN_VALUE && max == Integer.MIN_VALUE) {
+ int def = FetchGroup.RECURSION_DEPTH_DEFAULT;
+ return (traverse && isAssignable(meta.getDescribedType(), type))
+ ? def - 1 : def;
+ }
+ if (avail == Integer.MIN_VALUE || avail == FetchGroup.DEPTH_INFINITE)
+ return max;
+ if (max == Integer.MIN_VALUE || max == FetchGroup.DEPTH_INFINITE)
+ return avail;
+ return Math.min(max, avail);
+ }
+
+ /**
+ * Return the relation type of the given field.
+ */
+ private static Class getRelationType(FieldMetaData fm) {
+ if (fm.isDeclaredTypePC())
+ return fm.getDeclaredType();
+ if (fm.getElement().isDeclaredTypePC())
+ return fm.getElement().getDeclaredType();
+ if (fm.getKey().isDeclaredTypePC())
+ return fm.getKey().getDeclaredType();
+ return null;
+ }
+
+ /**
+ * Whether either of the two types is assignable from the other.
+ */
+ private static boolean isAssignable(Class c1, Class c2) {
+ return c1 != null && c2 != null
+ && (c1.isAssignableFrom(c2) || c2.isAssignableFrom(c1));
+ }
+
+ /**
+ * Reduce the given logical depth by 1.
+ */
+ private static int reduce(int d) {
+ if (d == 0)
+ return 0;
+ if (d != FetchGroup.DEPTH_INFINITE)
+ d--;
+ return d;
+ }
+
+ /////////////////
+ // Debug methods
+ /////////////////
+
+ FetchConfiguration getParent() {
+ return _parent;
+ }
+
+ boolean isRoot() {
+ return _parent == null;
+ }
+
+ FetchConfiguration getRoot() {
+ return (isRoot()) ? this : _parent.getRoot();
+ }
+
+ int getAvailableFetchDepth() {
+ return _availableDepth;
+ }
+
+ int getAvailableRecursionDepth() {
+ return _availableRecursion;
+ }
+
+ String getTraversedFromField() {
+ return _fromField;
+ }
+
+ Class getTraversedFromType() {
+ return _fromType;
+ }
+
+ List getPath() {
+ if (isRoot())
+ return Collections.EMPTY_LIST;
+ return trackPath(new ArrayList());
+ }
+
+ List trackPath(List path) {
+ if (_parent != null)
+ _parent.trackPath(path);
+ path.add(this);
+ return path;
+ }
+
+ public String toString() {
+ return "FetchConfiguration@" + System.identityHashCode(this)
+ + " (" + _availableDepth + ")" + getPathString();
+ }
+
+ private String getPathString()
+ {
+ List path = getPath();
+ if (path.isEmpty())
+ return "";
+ StringBuffer buf = new StringBuffer().append (": ");
+ for (Iterator itr = path.iterator(); itr.hasNext();) {
+ buf.append(((FetchConfigurationImpl) itr.next()).
+ getTraversedFromField());
+ if (itr.hasNext())
+ buf.append("->");
+ }
+ return buf.toString();
}
}
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ObjectIdStateManager.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ObjectIdStateManager.java?rev=426710&r1=426709&r2=426710&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ObjectIdStateManager.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ObjectIdStateManager.java Fri Jul 28 16:48:13 2006
@@ -281,7 +281,7 @@
throw new UnsupportedOperationException();
}
- public void load(FetchState fetchState) {
+ public void load(FetchConfiguration fetch) {
throw new UnsupportedOperationException();
}
@@ -329,7 +329,7 @@
throw new UnsupportedOperationException();
}
- public BitSet getUnloaded(FetchState fetchState) {
+ public BitSet getUnloaded(FetchConfiguration fetch) {
throw new UnsupportedOperationException();
}
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/OpenJPAStateManager.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/OpenJPAStateManager.java?rev=426710&r1=426709&r2=426710&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/OpenJPAStateManager.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/OpenJPAStateManager.java Fri Jul 28 16:48:13 2006
@@ -74,7 +74,7 @@
/**
* Load fetch group fields.
*/
- public void load(FetchState fetchState);
+ public void load(FetchConfiguration fetch);
/**
* Return the managed instance.
@@ -141,13 +141,14 @@
* on the given fetch configuration. Pass in null to retrieve all
* unloaded fields.
*/
- public BitSet getUnloaded(FetchState fetchState);
+ public BitSet getUnloaded(FetchConfiguration fetch);
/**
* Create a new hollow proxy instance for the given field. In cases where
* the field externalizes to an SCO but is declared something else, the
* returned object may not implement {@link Proxy}. In all other cases,
- * this method delegates to the system {@link org.apache.openjpa.util.ProxyManager}
+ * this method delegates to the system
+ * {@link org.apache.openjpa.util.ProxyManager}
* with the correct field information. The returned proxy's owner is
* unset so that modifications to the proxy will not be tracked while its
* state is initialized. Calling {@link #storeField} or {@link #store}
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PCData.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PCData.java?rev=426710&r1=426709&r2=426710&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PCData.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PCData.java Fri Jul 28 16:48:13 2006
@@ -63,11 +63,10 @@
* into the given state manager.
*
* @param sm the state manager to load
- * @param fetchState the fetch configuration to use for loading related
- * objects
+ * @param fetch the fetch configuration to use for loading related objects
* @param context current context information
*/
- public void load(OpenJPAStateManager sm, FetchState fetchState,
+ public void load(OpenJPAStateManager sm, FetchConfiguration fetch,
Object context);
/**
@@ -77,12 +76,11 @@
* @param sm the state manager to load
* @param fields the fields to load; clear the bits for the fields
* that are successfully loaded
- * @param fetchState the fetch configuration to use for loading related
- * objects
+ * @param fetch the fetch configuration to use for loading related objects
* @param context current context information
*/
public void load(OpenJPAStateManager sm, BitSet fields,
- FetchState fetchState, Object context);
+ FetchConfiguration fetch, Object context);
/**
* Store all loaded fields of the state manager.
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PCDataImpl.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PCDataImpl.java?rev=426710&r1=426709&r2=426710&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PCDataImpl.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PCDataImpl.java Fri Jul 28 16:48:13 2006
@@ -127,7 +127,7 @@
_version = version;
}
- public void load(OpenJPAStateManager sm, FetchState fetchState,
+ public void load(OpenJPAStateManager sm, FetchConfiguration fetch,
Object context) {
loadVersion(sm);
loadImplData(sm);
@@ -138,13 +138,13 @@
// fields in configured fetch groups
if (!isLoaded(i))
loadIntermediate(sm, fmds[i]);
- else if (fetchState.requiresLoad(sm, fmds[i]))
- loadField(sm, fmds[i], fetchState, context);
+ else if (!sm.getLoaded().get(i) && fetch.requiresFetch(fmds[i]))
+ loadField(sm, fmds[i], fetch, context);
}
}
public void load(OpenJPAStateManager sm, BitSet fields,
- FetchState fetchState, Object context) {
+ FetchConfiguration fetch, Object context) {
loadVersion(sm);
loadImplData(sm);
@@ -159,7 +159,7 @@
if (!isLoaded(i))
loadIntermediate(sm, fmd);
else {
- loadField(sm, fmd, fetchState, context);
+ loadField(sm, fmd, fetch, context);
loadImplData(sm, fmd);
fields.clear(i);
}
@@ -187,9 +187,9 @@
* Set field-level information into the given state manager.
*/
protected void loadField(OpenJPAStateManager sm, FieldMetaData fmd,
- FetchState fetchState, Object context) {
+ FetchConfiguration fetch, Object context) {
int index = fmd.getIndex();
- Object val = toField(sm, fmd, getData(index), fetchState, context);
+ Object val = toField(sm, fmd, getData(index), fetch, context);
sm.storeField(index, val);
}
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PCResultObjectProvider.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PCResultObjectProvider.java?rev=426710&r1=426709&r2=426710&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PCResultObjectProvider.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PCResultObjectProvider.java Fri Jul 28 16:48:13 2006
@@ -34,6 +34,6 @@
* @see StoreManager#initialize
*/
public void initialize(OpenJPAStateManager sm, PCState state,
- FetchState fetchState)
+ FetchConfiguration fetch)
throws Exception;
}
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ROPStoreManager.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ROPStoreManager.java?rev=426710&r1=426709&r2=426710&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ROPStoreManager.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ROPStoreManager.java Fri Jul 28 16:48:13 2006
@@ -40,11 +40,10 @@
}
public boolean initialize(OpenJPAStateManager sm, PCState state,
- FetchState fetchState, Object context) {
+ FetchConfiguration fetch, Object context) {
if (context instanceof PCResultObjectProvider) {
try {
- ((PCResultObjectProvider) context).initialize
- (sm, state, fetchState);
+ ((PCResultObjectProvider) context).initialize(sm, state, fetch);
} catch (OpenJPAException ke) {
throw ke;
} catch (Exception e) {
@@ -52,7 +51,7 @@
}
return true;
}
- return super.initialize(sm, state, fetchState, context);
+ return super.initialize(sm, state, fetch, context);
}
public boolean syncVersion(OpenJPAStateManager sm, Object context) {
@@ -66,13 +65,13 @@
}
public boolean load(OpenJPAStateManager sm, BitSet fields,
- FetchState fetchState, int lockLevel, Object context) {
+ FetchConfiguration fetch, int lockLevel, Object context) {
// the only way this gets called with a rop context is if the
// rop didn't load the field on initialize, so just null
// it out so we don't get unexpected results when our delegate
// expectes a different context type
if (context instanceof PCResultObjectProvider)
context = null;
- return super.load(sm, fields, fetchState, lockLevel, context);
+ return super.load(sm, fields, fetch, lockLevel, context);
}
}
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java?rev=426710&r1=426709&r2=426710&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java Fri Jul 28 16:48:13 2006
@@ -30,6 +30,7 @@
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;
@@ -69,7 +70,7 @@
private static final int FLAG_SAVE = 2 << 0;
private static final int FLAG_DEREF = 2 << 1;
- private static final int FLAG_DFG = 2 << 2;
+ 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;
@@ -131,7 +132,8 @@
/**
* Constructor; supply id, type metadata, and owning persistence manager.
*/
- protected StateManagerImpl(Object id, ClassMetaData meta, BrokerImpl broker) {
+ protected StateManagerImpl(Object id, ClassMetaData meta,
+ BrokerImpl broker) {
_id = id;
_meta = meta;
_broker = broker;
@@ -304,23 +306,21 @@
_meta, type);
}
- public void load(FetchState fetchState) {
- load(fetchState, LOAD_FGS, null, null, false);
+ 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(FetchState fetchState, int loadMode,
+ protected boolean load(FetchConfiguration fetch, int loadMode,
BitSet exclude, Object sdata, boolean forWrite) {
if (!forWrite && (!isPersistent() || isNew() || isDeleted()))
return false;
- if (fetchState==null)
- fetchState = _broker.getFetchConfiguration().newFetchState();
// if any fields being loaded, do state transitions for read
- BitSet fields = getUnloadedInternal(fetchState, loadMode, exclude);
+ BitSet fields = getUnloadedInternal(fetch, loadMode, exclude);
boolean active = _broker.isActive();
if (!forWrite && fields != null)
beforeRead(-1);
@@ -328,10 +328,8 @@
// 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
- FetchConfiguration fetch = fetchState.getFetchConfiguration();
int lockLevel = calculateLockLevel(active, forWrite, fetch);
- boolean ret = loadFields(fields, fetchState, lockLevel, sdata,
- forWrite);
+ boolean ret = loadFields(fields, fetch, lockLevel, sdata, forWrite);
obtainLocks(active, forWrite, lockLevel, fetch, sdata);
return ret;
}
@@ -380,9 +378,9 @@
return _dirty;
}
- public BitSet getUnloaded(FetchState fetchState) {
+ public BitSet getUnloaded(FetchConfiguration fetch) {
// collect fields to load from data store based on fetch configuration
- BitSet fields = getUnloadedInternal(fetchState, LOAD_FGS, null);
+ BitSet fields = getUnloadedInternal(fetch, LOAD_FGS, null);
return (fields == null) ? new BitSet(0) : fields;
}
@@ -391,7 +389,7 @@
* creating an empty bit set by returning null when there are no unloaded
* fields.
*/
- private BitSet getUnloadedInternal(FetchState fetchState, int mode,
+ private BitSet getUnloadedInternal(FetchConfiguration fetch, int mode,
BitSet exclude) {
if (exclude == StoreContext.EXCLUDE_ALL)
return null;
@@ -408,8 +406,7 @@
load = !fmds[i].isTransient();
break;
case LOAD_FGS:
- load = fetchState == null ||
- fetchState.requiresLoad(this, fmds[i]);
+ load = fetch == null || fetch.requiresFetch(fmds[i]);
break;
default: // LOAD_ALL
load = true;
@@ -1204,8 +1201,8 @@
if (_meta.isDetachable())
return DetachManager.preSerialize(this);
- load(_broker.getFetchConfiguration().newFetchState(),
- LOAD_SERIALIZE, null, null, false);
+ load(_broker.getFetchConfiguration(), LOAD_SERIALIZE, null, null,
+ false);
return false;
} catch (RuntimeException re) {
throw translate(re);
@@ -2412,10 +2409,10 @@
setLoaded(i, val);
}
if (!val) {
- _flags &= ~FLAG_DFG;
+ _flags &= ~FLAG_LOADED;
setDirty(false);
} else
- _flags |= FLAG_DFG;
+ _flags |= FLAG_LOADED;
}
/**
@@ -2438,7 +2435,7 @@
}
if (val)
- _flags |= FLAG_DFG;
+ _flags |= FLAG_LOADED;
}
/**
@@ -2706,7 +2703,7 @@
* Load the given field set from the data store into the instance.
* Return true if any data is loaded, false otherwise.
*/
- boolean loadFields(BitSet fields, FetchState fetchState, int lockLevel,
+ boolean loadFields(BitSet fields, FetchConfiguration fetch, int lockLevel,
Object sdata, boolean forWrite) {
// can't load version field from store
if (fields != null) {
@@ -2721,7 +2718,7 @@
// if any fields given, load them
int len = (fields == null) ? 0 : fields.length();
if (len > 0) {
- if (!_broker.getStoreManager().load(this, fields, fetchState,
+ if (!_broker.getStoreManager().load(this, fields, fetch,
lockLevel, sdata)) {
throw new ObjectNotFoundException(_loc.get("del-instance",
_meta.getDescribedType(), _oid)).
@@ -2748,36 +2745,33 @@
// see if the dfg is now loaded; do this regardless of whether we
// loaded any fields, cause may already have been loaded by
// StoreManager during initialization
- postLoad(-1, fetchState);
+ postLoad(-1, fetch);
return ret;
}
- protected void loadField(int field, int lockLevel, boolean forWrite,
- boolean fgs) {
- FetchConfiguration fc = _broker.getFetchConfiguration();
- loadField(field, fc.newFetchState(),lockLevel, forWrite, fgs);
- }
-
/**
* Load the given field's fetch group; the field itself may already be
* loaded if it is being set by the user.
*/
- protected void loadField(int field, FetchState fetchState, int lockLevel,
- boolean forWrite, boolean fgs) {
+ protected void loadField(int field, int lockLevel, boolean forWrite,
+ boolean fgs) {
+ FetchConfiguration fetch = _broker.getFetchConfiguration();
FieldMetaData fmd = _meta.getField(field);
BitSet fields = null;
// if this is a dfg field or we need to load our dfg, do so
if (fmd.isInDefaultFetchGroup()
- || (fgs && (_flags & FLAG_DFG) == 0)) {
- fields = getUnloadedInternal(fetchState, LOAD_FGS, null);
- }
-
+ || (fgs && (_flags & FLAG_LOADED) == 0))
+ fields = getUnloadedInternal(fetch, LOAD_FGS, null);
+
+ // if not a dfg field, use first custom fetch group as load group
+ //### need to use metadata load-fetch-group
if (!fmd.isInDefaultFetchGroup()) {
- if (fmd.getFetchGroups() != null) {
+ if (fmd.getCustomFetchGroups().length > 0) {
+ String fg = fmd.getCustomFetchGroups()[0];
FieldMetaData[] fmds = _meta.getFields();
for (int i = 0; i < fmds.length; i++) {
if (!_loaded.get(i) && (i == field
- || fmd.fetchGroupOverlapsWith(fmds[i]))) {
+ || fmds[i].isInFetchGroup(fg))) {
if (fields == null)
fields = new BitSet(fmds.length);
fields.set(i);
@@ -2785,7 +2779,7 @@
}
} else if (!_loaded.get(fmd.getIndex())) {
if (fields == null)
- fields = new BitSet(fmd.getIndex());
+ fields = new BitSet();
fields.set(fmd.getIndex());
}
}
@@ -2793,7 +2787,20 @@
// call this method even if there are no unloaded fields; loadFields
// takes care of things like loading version info and setting PC
// flags
- loadFields(fields, fetchState, lockLevel, null, forWrite);
+ loadFields(fields, fetch, lockLevel, null, forWrite);
+ }
+
+ /**
+ * Return whether the second field has any custom fetch groups in common
+ * with the first.
+ */
+ private static boolean sharesCustomFetchGroups(FieldMetaData fmd1,
+ FieldMetaData fmd2) {
+ String[] fgs = fmd1.getCustomFetchGroups();
+ for (int i = 0; i < fgs.length; i++)
+ if (fmd2.isInFetchGroup(fgs[i]))
+ return true;
+ return false;
}
/**
@@ -2848,12 +2855,9 @@
* @param field the field index that was loaded, or -1 to indicate
* that a group of possibly unknown fields was loaded
*/
- private void postLoad(int field, FetchState fetchState) {
+ private void postLoad(int field, FetchConfiguration fetch) {
// no need for postLoad callback?
- if ((_flags & FLAG_DFG) > 0)
- return;
- LifecycleEventManager mgr = _broker.getLifecycleEventManager();
- if (mgr == null || !mgr.hasLoadListeners(getManagedInstance(), _meta))
+ if ((_flags & FLAG_LOADED) != 0)
return;
// in the middle of a group load, after which this method will be
@@ -2861,33 +2865,46 @@
if (field != -1 && isLoading())
return;
- // is this field in the dfg?
- FieldMetaData[] fmds = _meta.getDefaultFetchGroupFields();
+ // no listeners?
+ LifecycleEventManager mgr = _broker.getLifecycleEventManager();
+ if (mgr == null || !mgr.hasLoadListeners(getManagedInstance(), _meta))
+ return;
- // see if any fetch group with postLoad=true is fully loaded
- boolean isLoaded = true;
- for (int i = 0; isLoaded && i < fmds.length; i++)
- if (!_loaded.get(fmds[i].getIndex())
- && requiresPostLoadCallabck(fmds[i], fetchState))
- isLoaded = false;
- if (isLoaded) {
- _flags |= FLAG_DFG;
- fireLifecycleEvent(LifecycleEvent.AFTER_LOAD);
+ // is this field a post-load field?
+ if (field != -1) {
+ FieldMetaData fmd = _meta.getField (field);
+ if (fmd.isInDefaultFetchGroup()
+ && postLoad(_meta.getFetchGroup(FetchGroup.NAME_DEFAULT)))
+ return;
+ String[] fgs = fmd.getCustomFetchGroups();
+ for (int i = 0; i < fgs.length; i++)
+ if (postLoad(_meta.getFetchGroup(fgs[i])))
+ return;
+ } else {
+ if (postLoad(_meta.getFetchGroup(FetchGroup.NAME_DEFAULT)))
+ return;
+ FetchGroup[] fgs = _meta.getCustomFetchGroups();
+ for (int i = 0; i < fgs.length; i++)
+ if (postLoad(fgs[i]))
+ return;
}
}
- private boolean requiresPostLoadCallabck(FieldMetaData fm, FetchState fetchState) {
- if (fm == null)
+ /**
+ * Perform post-load actions if the given fetch group is a post-load group
+ * and is fully loaded.
+ */
+ private boolean postLoad(FetchGroup fg) {
+ if (!fg.isPostLoad())
return false;
- Set fetchGroups = fm.getFetchGroups();
- for (Iterator i = fetchGroups.iterator(); i.hasNext();)
- {
- String fg = i.next().toString();
- if (_broker.getFetchConfiguration().hasFetchGroup(fg)
- && fm.getDeclaringMetaData().getFetchGroup(fg).isPostLoad())
- return true;
- }
- return false;
+ FieldMetaData[] fmds = _meta.getFields();
+ for (int i = 0; i < fmds.length; i++)
+ if (!_loaded.get(i) && fmds[i].isInFetchGroup(fg.getName()))
+ return false;
+
+ _flags |= FLAG_LOADED;
+ fireLifecycleEvent(LifecycleEvent.AFTER_LOAD);
+ return true;
}
/**
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java?rev=426710&r1=426709&r2=426710&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java Fri Jul 28 16:48:13 2006
@@ -135,13 +135,13 @@
* if a cached instance has been deleted concurrently. These options
* are controllable through the given <code>OID_XXX</code> flags.
*/
- public Object find(Object oid, FetchState fetchState, BitSet exclude,
+ public Object find(Object oid, FetchConfiguration fetch, BitSet exclude,
Object edata, int flags);
/**
* Return the objects with the given oids.
*
- * @see #find(Object,FetchState,BitSet,Object,int)
+ * @see #find(Object,FetchConfiguration,BitSet,Object,int)
*/
public Object[] findAll(Collection oids, FetchConfiguration fetch,
BitSet exclude, Object edata, int flags);
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreManager.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreManager.java?rev=426710&r1=426709&r2=426710&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreManager.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreManager.java Fri Jul 28 16:48:13 2006
@@ -129,14 +129,14 @@
*
* @param sm the instance to initialize
* @param state the lifecycle state to initialize the state manager with
- * @param fetchState configuration for how to load the instance
+ * @param fetch configuration for how to load the instance
* @param edata the current execution data, or null if not
* given to the calling method of the broker
* @return true if the matching instance exists in the data
* store, false otherwise
*/
public boolean initialize(OpenJPAStateManager sm, PCState state,
- FetchState fetchState, Object edata);
+ FetchConfiguration fetch, Object edata);
/**
* Load the given state manager.
@@ -153,7 +153,7 @@
* @param sm the instance to load
* @param fields set of fields to load; all field indexes in this
* set must be loaded; this set is mutable
- * @param fetchState the fetch configuration to use when loading
+ * @param fetch the fetch configuration to use when loading
* related objects
* @param lockLevel attempt to load simple fields at this lock level;
* relations should be loaded at the read lock level
@@ -164,7 +164,7 @@
* database, true otherwise
*/
public boolean load(OpenJPAStateManager sm, BitSet fields,
- FetchState fetchState, int lockLevel, Object edata);
+ FetchConfiguration fetch, int lockLevel, Object edata);
/**
* Initialize, load, or validate the existance of all of the given
@@ -192,7 +192,8 @@
* be included outside of refresh invocations if a user calls
* <code>findAll</code> with the <code>validate</code>
* parameter set to <code>true</code>.</li>
- * </ul> Store managers that cannot efficiently batch load can simply test
+ * </ul>
+ * Store managers that cannot efficiently batch load can simply test
* for these conditions and delegate to the proper methods.
*
* @param sms the state manager instances to load
@@ -201,7 +202,7 @@
* instances are included in <code>sms</code>
* @param load one of the FORCE_LOAD_* constants describing the
* fields to force-load if this is a refresh or retrieve action
- * @param fetchState the current fetch configuration to use when loading
+ * @param fetch the current fetch configuration to use when loading
* related objects
* @param edata the current execution data, or null if not
* given to the calling method of the broker