package er.rest; import com.webobjects.eoaccess.EOAttribute; import com.webobjects.eoaccess.EOEntity; import com.webobjects.eoaccess.EOEntityClassDescription; import com.webobjects.eocontrol.EOClassDescription; import com.webobjects.eocontrol.EOEditingContext; import com.webobjects.eocontrol.EOEnterpriseObject; import com.webobjects.eocontrol.EOGlobalID; import com.webobjects.eocontrol.EOKeyGlobalID; import com.webobjects.eocontrol.EOTemporaryGlobalID; import com.webobjects.foundation.NSArray; import com.webobjects.foundation.NSData; import com.webobjects.foundation._NSUtilities; import er.extensions.eof.ERXEOControlUtilities; import er.extensions.foundation.UUIDUtilities; /** * EODelegate is an implementation of the ERXRestRequestNode.Delegate interface that understands EOF. * * @author mschrag */ public class ERXEORestDelegate extends ERXAbstractRestDelegate { public ERXEORestDelegate() { } @Override public boolean __hasNumericPrimaryKeys(EOClassDescription classDescription) { boolean numericPKs = false; if (classDescription instanceof EOEntityClassDescription) { EOEntity entity = ((EOEntityClassDescription)classDescription).entity(); NSArray<EOAttribute> primaryKeyAttributes = entity.primaryKeyAttributes(); if (primaryKeyAttributes.count() == 1) { EOAttribute primaryKeyAttribute = primaryKeyAttributes.objectAtIndex(0); Class<?> primaryKeyClass = _NSUtilities.classWithName(primaryKeyAttribute.className()); numericPKs = primaryKeyClass != null && Number.class.isAssignableFrom(primaryKeyClass); } } return numericPKs; } private boolean hasUUIDPrimaryKeys(EOClassDescription classDescription) { boolean uuidPK = false; if (classDescription instanceof EOEntityClassDescription) { EOEntity entity = ((EOEntityClassDescription)classDescription).entity(); NSArray<EOAttribute> primaryKeyAttributes = entity.primaryKeyAttributes(); if (primaryKeyAttributes.count() == 1) { EOAttribute primaryKeyAttribute = primaryKeyAttributes.objectAtIndex(0); if(primaryKeyAttribute.adaptorValueType() == EOAttribute.AdaptorBytesType && primaryKeyAttribute.width() == 16) { uuidPK = true; } } } return uuidPK; } @Override public Object createObjectOfEntityWithID(EOClassDescription entity, Object id, ERXRestContext context) { EOEditingContext editingContext = context.editingContext(); if (editingContext == null) { throw new IllegalArgumentException("There was no editing context attached to this rest context."); } editingContext.lock(); try { EOEnterpriseObject eo = entity.createInstanceWithEditingContext(editingContext, null); if (hasUUIDPrimaryKeys(entity) && id != null) { NSData uuid = UUIDUtilities.decodeStringAsNSData((String)id); EOKeyGlobalID gid = EOKeyGlobalID.globalIDWithEntityName(entity.entityName(), new Object[]{uuid}); editingContext.insertObjectWithGlobalID(eo, gid); } else { editingContext.insertObject(eo); } return eo; } finally { editingContext.unlock(); } } @Override public Object primaryKeyForObject(Object obj, ERXRestContext context) { Object pkValue; if (obj == null) { pkValue = null; } else { EOEnterpriseObject eo = (EOEnterpriseObject) obj; EOEditingContext editingContext = eo.editingContext(); if (editingContext != null) { editingContext.lock(); try { pkValue = ERXEOControlUtilities.primaryKeyObjectForObject(eo); if (pkValue == null) { EOGlobalID gid = editingContext.globalIDForObject(eo); if (gid instanceof EOTemporaryGlobalID) { pkValue = new NSData(((EOTemporaryGlobalID) gid)._rawBytes()); } } } finally { editingContext.unlock(); } } else { pkValue = ERXEOControlUtilities.primaryKeyObjectForObject(eo); } } if (pkValue instanceof NSData) { NSData pkData = (NSData) pkValue; if (pkData.length() == 16) { pkValue = UUIDUtilities.encodeAsPrettyString(pkData); } } return pkValue; } @Override public Object objectOfEntityWithID(EOClassDescription entity, Object id, ERXRestContext context) { String strPKValue = String.valueOf(id); EOEditingContext editingContext = context.editingContext(); if (editingContext == null) { throw new IllegalArgumentException("There was no editing context attached to this rest context."); } editingContext.lock(); try { EOGlobalID gid = ERXEOControlUtilities.globalIDForString(editingContext, entity.entityName(), strPKValue); return editingContext.faultForGlobalID(gid, editingContext); } finally { editingContext.unlock(); } } }