* @param tobj The transfer object to instantiate.
* @return The instance corresponding to the transfer object.
*/
public Instance instantiate(TransferObject tobj)
{
Instance instance = (Instance)m_identityMap.get(tobj);
if (instance != null)
{
return instance;
}
Metaclass metaclass = m_context.getMetadata().getMetaclass(tobj.getClassName());
Attribute lockingAttribute = (metaclass.getPersistenceMapping() != null) ? metaclass.getPersistenceMapping()
.getLockingAttribute() : null;
OID oid = tobj.getOID();
if (isCached())
{
if (oid == null)
{
instance = null;
}
else
{
instance = m_context.lockInstance(metaclass, oid, tobj.getEventName() != null);
if (instance != null && instance.isLazy())
{
if (tobj.getVersion() >= 0)
{
instance.setMetaclass(metaclass);
}
else if (instance.getLazyMetaclass().isUpcast(metaclass))
{
instance.setLazyMetaclass(metaclass);
}
}
}
if ("create".equals(tobj.getEventName()))
{
if (instance == null)
{
instance = new Instance(metaclass, m_context);
instance.setNew();
instance.setOID(oid);
}
}
else
{
if (instance == null)
{
instance = new Instance(metaclass, tobj.getVersion() < 0, m_context);
m_context.getUnitOfWork().lock(instance.cache(oid), tobj.getEventName() != null);
}
else if ((m_nMode & CACHE) != 0 && instance.isCached())
{
return instance;
}
}
if ((m_nMode & CACHE) != 0)
{
instance.setCached(true);
}
}
else
{
if (oid == null)
{
instance = new Instance(metaclass, m_context);
instance.setNew();
instance.getUnitOfWork().keepChange(instance);
}
else
{
if (m_context.isProtected() && m_context.isSecure())
{
metaclass.checkReadAccess(m_context.getPrivilegeSet());
}
instance = m_context.lockInstance(metaclass, oid, tobj.getEventName() != null);
if (instance == null)
{
PersistenceMapping mapping = metaclass.getPersistenceMapping();
if (mapping != null)
{
Object[] valueArray = oid.getValueArray();
Key key = mapping.getObjectKey();
if (key.getPartCount() != valueArray.length)
{
throw new RequestException("err.rpc.oidPartCount", new Object[]
{
metaclass.getName()
});
}
for (int i = 0; i < valueArray.length; ++i)
{
valueArray[i] = key.getPartType(i).convert(valueArray[i]);
}
}
instance = new Instance(metaclass, m_context);
m_context.getUnitOfWork().lock(instance.cache(oid), tobj.getEventName() != null);
}
}
}
m_identityMap.put(tobj, instance);
if ((m_nMode & STATE) != 0 && tobj.getVersion() >= 0)
{
instance.load();
if (lockingAttribute != null && instance.getState() != Instance.NEW)
{
Object oldValue = instance.getOldValueDirect(lockingAttribute.getOrdinal());
if (!(oldValue instanceof Undefined))
{
Object value = tobj.findValue(lockingAttribute.getName());
if (value != null && !ObjUtil.equal(lockingAttribute.getType().convert(value), oldValue))
{
m_bLockMismatch = true;
if ((m_nMode & LOCK) != 0)
{
throw new OptimisticLockException(instance);
}
if (isCached())
{
return instance;
}
if (m_context.isLocked(instance))
{
throw new OptimisticLockException(instance);
}
}
}
}
TransferObject preObj = null;
if ((m_nMode & PRE) != 0)
{
Object value = tobj.findValue(PRE_NAME);
if (value != null)
{
if (value instanceof TransferObject)
{
preObj = (TransferObject)value;
}
else
{
throw new RequestException("err.rpc.preObjectType");
}
}
}
for (PropertyIterator itr = tobj.getIterator(); itr.hasNext();)
{
String sName = (String)itr.next();
if ((m_nMode & PRE) != 0 && sName.equals(PRE_NAME))
{
continue;
}
Attribute attribute = metaclass.getAttribute(sName);
Object value = itr.getValue();
if (attribute.isStatic())
{
throw new RequestException("err.rpc.staticAttribute", new Object[]
{
attribute.getName(),
metaclass.getName()
});
}
if (isCached())
{
if (!(instance.getOldValueDirect(attribute.getOrdinal()) instanceof Undefined))
{
continue;
}
}
else
{
if (!attribute.isCached())
{
throw new RequestException("err.rpc.uncachedAttribute", new Object[]
{
attribute.getName(),
metaclass.getName()
});
}
if (m_context.isProtected() && m_context.isSecure())
{
attribute.checkReadAccess(m_context.getPrivilegeSet());
}
instance.checkUpdateAccess(attribute);
}
Object pre = (preObj == null) ? Undefined.VALUE : preObj.findValue(sName, Undefined.VALUE);
if (attribute.getType().isPrimitive())
{
value = instantiatePrimitive(value, attribute);
if (pre != Undefined.VALUE)
{
pre = instantiatePrimitive(pre, attribute);
}
}
else
{
if (attribute.isCollection())
{
InstanceList instanceList;
if (pre != Undefined.VALUE)
{
pre = instanceList = instantiateList(pre, attribute);
if (isCached())
{
instanceList.setLazy(false);
}
}
value = instanceList = instantiateList(value, attribute);
if (isCached())
{
instanceList.setLazy(false);
}
else
{
if (attribute.getReverse() != null)
{
instanceList.checkUpdateAccess(attribute.getReverse(), instance);
}
}
instanceList.setAssociation(instance, attribute, true);
}
else
{
Instance inst;
if (pre != Undefined.VALUE)
{
pre = inst = instantiateObject(pre, attribute);
}
value = inst = instantiateObject(value, attribute);
if (isCached() && attribute.getReverse() != null && inst != null && !inst.isLazy())
{
inst.associate(attribute.getReverse().getOrdinal(), instance, true);
}
}
}
if (pre != Undefined.VALUE && ObjUtil.equal(value, pre))