AbstractMemberMetaData mmd = getMetaData(fieldNumber);
ClassLoaderResolver clr = getClassLoaderResolver();
RelationType relationType = mmd.getRelationType(clr);
if (mmd.getEmbeddedMetaData() != null && RelationType.isRelationSingleValued(relationType)) {
// Embedded persistable object
ObjectProvider embeddedOP = getEmbeddedObjectProvider(mmd.getType(), fieldNumber, null);
fieldManagerStateStack.addFirst(new FieldManagerState(embeddedOP, mmd.getEmbeddedMetaData()));
try {
embeddedOP.replaceFields(embeddedOP.getClassMetaData().getAllMemberPositions(), this);
// Checks for whether the member values imply a null object
if (mmd.getEmbeddedMetaData() != null && mmd.getEmbeddedMetaData().getNullIndicatorColumn() != null) {
String nullColumn = mmd.getEmbeddedMetaData().getNullIndicatorColumn();
String nullValue = mmd.getEmbeddedMetaData().getNullIndicatorValue();
AbstractMemberMetaData[] embMmds = mmd.getEmbeddedMetaData().getMemberMetaData();
AbstractMemberMetaData nullMmd = null;
for (int i=0;i<embMmds.length;i++) {
ColumnMetaData[] colmds = embMmds[i].getColumnMetaData();
if (colmds != null && colmds.length > 0 && colmds[0].getName() != null && colmds[0].getName().equals(nullColumn)) {
nullMmd = embMmds[i];
break;
}
}
if (nullMmd != null) {
int nullFieldPos = embeddedOP.getClassMetaData().getAbsolutePositionOfMember(nullMmd.getName());
Object val = embeddedOP.provideField(nullFieldPos);
if (val == null && nullValue == null) {
return null;
} else if (val != null && nullValue != null && val.equals(nullValue)) {
return null;
}
}
return embeddedOP.getObject();
}
else {
return embeddedOP.getObject();
}
} finally {
fieldManagerStateStack.removeFirst();
}
} else if (RelationType.isRelationMultiValued(relationType) && mmd.isEmbedded()) {
// Embedded container
if (mmd.hasCollection()) {
// Embedded collections
String collPropName = getPropertyNameForMember(mmd) + ".size";
Long collSize = (Long)datastoreEntity.getProperty(collPropName);
if (collSize == null || collSize == -1) {
// Size of collection not stored or stored as -1, so null on persist
return null;
}
Class elementType = clr.classForName(mmd.getCollection().getElementType());
AbstractClassMetaData elemCmd = mmd.getCollection().getElementClassMetaData(clr, ec.getMetaDataManager());
EmbeddedMetaData embmd =
mmd.getElementMetaData() != null ? mmd.getElementMetaData().getEmbeddedMetaData() : null;
Collection<Object> coll;
try {
Class instanceType = SCOUtils.getContainerInstanceType(mmd.getType(), mmd.getOrderMetaData() != null);
coll = (Collection<Object>) instanceType.newInstance();
} catch (Exception e) {
throw new NucleusDataStoreException(e.getMessage(), e);
}
// Use discriminator for elements if available
String collDiscName = null;
if (elemCmd.hasDiscriminatorStrategy()) {
collDiscName = elemCmd.getDiscriminatorColumnName();
if (embmd != null && embmd.getDiscriminatorMetaData() != null) {
// Override if specified under <embedded>
DiscriminatorMetaData dismd = embmd.getDiscriminatorMetaData();
ColumnMetaData discolmd = dismd.getColumnMetaData();
if (discolmd != null && discolmd.getName() != null) {
collDiscName = discolmd.getName();
}
}
if (collDiscName == null) {
collDiscName = getPropertyNameForMember(mmd) + ".discrim";
}
}
for (int i=0;i<collSize;i++) {
Class elementCls = elementType;
if (collDiscName != null) {
Object discVal = datastoreEntity.getProperty(collDiscName + "." + i);
String className =
org.datanucleus.metadata.MetaDataUtils.getClassNameFromDiscriminatorValue((String)discVal,
elemCmd.getDiscriminatorMetaDataRoot(), ec);
elementCls = clr.classForName(className);
}
ObjectProvider embeddedOP = getEmbeddedObjectProvider(elementCls, fieldNumber, null);
fieldManagerStateStack.addFirst(new FieldManagerState(embeddedOP, embmd, i));
try {
embeddedOP.replaceFields(embeddedOP.getClassMetaData().getAllMemberPositions(), this);
} finally {
fieldManagerStateStack.removeFirst();
}
coll.add(embeddedOP.getObject());
}
return getObjectProvider().wrapSCOField(fieldNumber, coll, false, false, true);
} else if (mmd.hasArray()) {
// Embedded arrays
String arrPropName = getPropertyNameForMember(mmd) + ".size";
Long arrSize = (Long)datastoreEntity.getProperty(arrPropName);
if (arrSize == null || arrSize == -1) {
// Size of array not stored or stored as -1, so null on persist
return null;
}
Class elementType = clr.classForName(mmd.getArray().getElementType());
AbstractClassMetaData elemCmd = mmd.getArray().getElementClassMetaData(clr, ec.getMetaDataManager());
EmbeddedMetaData embmd =
mmd.getElementMetaData() != null ? mmd.getElementMetaData().getEmbeddedMetaData() : null;
Object value = Array.newInstance(elementType, arrSize.intValue());
// Use discriminator for elements if available
String arrDiscName = null;
if (elemCmd.hasDiscriminatorStrategy()) {
arrDiscName = elemCmd.getDiscriminatorColumnName();
if (embmd != null && embmd.getDiscriminatorMetaData() != null) {
// Override if specified under <embedded>
DiscriminatorMetaData dismd = embmd.getDiscriminatorMetaData();
ColumnMetaData discolmd = dismd.getColumnMetaData();
if (discolmd != null && discolmd.getName() != null) {
arrDiscName = discolmd.getName();
}
}
if (arrDiscName == null) {
arrDiscName = getPropertyNameForMember(mmd) + ".discrim";
}
}
for (int i=0;i<arrSize;i++) {
Class elementCls = elementType;
if (arrDiscName != null) {
Object discVal = datastoreEntity.getProperty(arrDiscName + "." + i);
String className =
org.datanucleus.metadata.MetaDataUtils.getClassNameFromDiscriminatorValue((String)discVal,
elemCmd.getDiscriminatorMetaDataRoot(), ec);
elementCls = clr.classForName(className);
}
ObjectProvider embeddedOP = getEmbeddedObjectProvider(elementCls, fieldNumber, null);
fieldManagerStateStack.addFirst(new FieldManagerState(embeddedOP, embmd, i));
try {
embeddedOP.replaceFields(embeddedOP.getClassMetaData().getAllMemberPositions(), this);
} finally {
fieldManagerStateStack.removeFirst();
}
Array.set(value, i, embeddedOP.getObject());
}
return value;
} else if (mmd.hasMap()) {
// TODO Support embedded maps
throw new NucleusUserException("Don't currently support embedded maps at " + mmd.getFullFieldName());