}
oid = getKey(query.getParentItem());
}
InstanceList instanceList;
boolean bAdd = true;
if (container == null)
{
instanceList = m_instanceList;
}
else
{
Object value = container.getOldValueDirect(assoc.getOrdinal());
if (value == Undefined.VALUE)
{
if (assoc.isCollection())
{
instanceList = new InstanceArrayList();
instanceList.setAssociation(container, assoc, true);
instanceList.setLazy(false);
container.setOldValueDirect(assoc.getOrdinal(), instanceList);
}
else
{
instanceList = null;
if (oid == null)
{
container.setOldValueDirect(assoc.getOrdinal(), null);
}
}
}
else
{
if (assoc.isCollection() && !(value instanceof Undefined))
{
instanceList = (InstanceList)value;
instanceList.setLazy(false);
}
else
{
instanceList = null;
bAdd = false;
}
}
}
Metaclass metaclass;
if (bIdentity)
{
if (oid == null)
{
if (query.getRoot() == m_query)
{
m_instanceArray[query.getOrdinal()] = null;
}
continue;
}
if (query.getRoot() != m_query && !query.isLazy())
{
if (!bSkipInstance)
{
query.addParentInstance(container, oid);
}
continue;
}
Field field = query.getTypeCodeField();
if (field != null)
{
metaclass = query.getPersistenceMapping().findMetaclassByTypeCode(getValue(field));
if (metaclass == null)
{
m_instanceArray[query.getOrdinal()] = null;
continue;
}
}
else
{
metaclass = getMetaclass(query);
}
}
else
{
metaclass = getMetaclass(query);
}
InstanceRef ref = m_query.getInvocationContext().findInstanceRef(metaclass, oid);
Instance instance = (ref == null) ? null : ref.getInstance();
// Check if the instance has already been retrieved
if (instance != null)
{
// Already retrieved instance
if (instance.isLazy())
{
if (query.isLazy())
{
if (!metaclass.isUpcast(instance.getLazyMetaclass()))
{
instance.setLazyMetaclass(metaclass);
}
}
else
{
instance.setMetaclass(metaclass);
}
}
if (instanceList != null)
{
bAdd = !instanceList.contains(instance);
if (bAdd &&
container == null &&
m_nMaxCount >= 0 &&
instanceList.getCount() == m_nOffset + m_nMaxCount)
{
m_bEOF = bDiscardExtra;
m_bEOP = !bDiscardExtra;
return false;
}
}
if (bAdd)
{
switch (instance.getState())
{
case Instance.DELETED:
bAdd = false;
break;
case Instance.DIRTY:
if (reverse != null)
{
Object reverseValue = instance.getValueDirect(reverse.getOrdinal());
if (reverseValue != Undefined.VALUE && reverseValue != container)
{
bAdd = false;
}
}
break;
}
if (!bAdd && instanceList == null)
{
if (container.getValueDirect(assoc.getOrdinal()) == Undefined.VALUE)
{
// Set the new value to null, old value to the retrieved instance
container.setValueDirect(assoc.getOrdinal(), null);
}
bAdd = true;
}
}
if (m_instanceSet.get(query, instance) == null)
{
// Merge the not yet retrieved attribute values
if (!bSkipInstance)
{
// Overwrite only if the instance is clean
boolean bOverwrite = (instance.getUnitOfWork() == null);
Field lockingField = query.getLockingField();
if (lockingField != null)
{
Attribute lockingAttribute = lockingField.getAttribute();
Object oldValue = instance.getNewValueDirect(lockingAttribute.getOrdinal());
if (oldValue != Undefined.VALUE)
{
// Check the old lock value
Primitive primitive = (Primitive)lockingAttribute.getType();
Object value = getValue(lockingField);
if (((Boolean)primitive.findNEFunction(primitive).invoke(oldValue, value)).booleanValue())
{
// The lock values do not match
// If the instance is dirty/deleted or share-locked, throw an exception
if (!bOverwrite || ref.isLocked())
{
throw new OptimisticLockException(instance);
}
// Discard all the instance attributes
for (int i = 0, n = metaclass.getInstanceAttributeCount(); i != n; ++i)
{
discard(instance, metaclass.getInstanceAttribute(i));
}
instance.setOldValueDirect(lockingAttribute.getOrdinal(), value);
}
else
{
if (bOverwrite)
{
discard(instance, query);
if (reverse != null && bAdd && !instance.isLazy())
{
instance.setValueDirect(reverse.getOrdinal(), container);
}
bOverwrite = false;
}
}
}
else
{
// If the instance is clean, discard the
// instance assocs referenced in this query
if (bOverwrite)
{
discard(instance, query);
}
}
}
else
{
// If the instance is clean, discard the
// instance assocs referenced in this query
if (bOverwrite)
{
discard(instance, query);
}
}
if (bOverwrite && reverse != null && bAdd && !instance.isLazy())
{
instance.setValueDirect(reverse.getOrdinal(), container);
}
addInstance(instance, ref, metaclass, query, bOverwrite);
}
}
}
else
{
// New instance
if (container == null &&
m_nMaxCount >= 0 &&
instanceList.getCount() == m_nOffset + m_nMaxCount)
{
m_bEOF = bDiscardExtra;
m_bEOP = !bDiscardExtra;
return false;
}
instance = new Instance(metaclass, query.isLazy(), m_query.getInvocationContext());
ref = instance.cache(oid);
if (!bSkipInstance)
{
addInstance(instance, ref, metaclass, query, true);
}
}
if (bAdd)
{
if (instanceList != null)
{
instanceList.add(instance, InstanceList.DIRECT);
}
else
{
container.setOldValueDirect(assoc.getOrdinal(), instance);
}