/** * */ package com.webobjects.eoaccess; import java.util.regex.Matcher; import java.util.regex.Pattern; import com.webobjects.eocontrol.EOClassDescription; import com.webobjects.eocontrol.EOKeyGlobalID; import com.webobjects.foundation.NSArray; import com.webobjects.foundation.NSDictionary; import com.webobjects.foundation.NSMutableArray; import com.webobjects.foundation.NSMutableDictionary; /** * ERXEntity provides a basic subclass of EOEntity providing * a simple fix for vertical inheritance. * <p> * <b>Note:</b> If you plan on subclassing EOEntity or ERXEntity you * MUST put your subclass in the same package if you want it * to work. There are numerous default and protected instance * methods within EOEntity itself that will fail to resolve at * runtime if your subclass is in another package! * * @see EOEntity * @author ldeck */ public class ERXEntity extends EOEntity { private static final Pattern NeededByEOFPattern = Pattern.compile( "\\QNeededByEOF\\E(\\d+)" ); /** * Creates and returns a new ERXEntity. */ public ERXEntity() { super(); } /** * Creates and returns a new EOEntity initialized from the * property list plist belonging to the EOModel owner. * plist is dictionary containing only property list data * types (that is, NSDictionary, NSArray, NSData, and String). * This constructor is used by EOModeler when it reads in an * EOModel from a file. * * @param plist - A dictionary of property list values from which to initialize the new EOEntity object. * @param owner - The EOModel to which the newly created entity belongs. * * @see EOPropertyListEncoding#encodeIntoPropertyList(NSMutableDictionary propertyList) * @see EOPropertyListEncoding#awakeWithPropertyList(NSDictionary propertyList) */ public ERXEntity(NSDictionary plist, Object owner) { super(plist, owner); } /** * ldeck radar bug#6302622. * <p> * Relating two sub-entities in vertical inheritance can fail to resolve * the foreign key for inserts. i.e., NeededByEOF<index> was not dealt with. * The simple fix is to return the primary key attribute at the given index. * * @see com.webobjects.eoaccess.EOEntity#anyAttributeNamed(java.lang.String) */ @Override public EOAttribute anyAttributeNamed(String name) { Matcher matcher = null; EOAttribute result = super.anyAttributeNamed(name); if (result == null && name != null && (matcher = NeededByEOFPattern.matcher(name)).matches()) { int neededIndex = Integer.valueOf(matcher.group(1)); if (neededIndex >= primaryKeyAttributeNames().count()) { throw new IllegalStateException("No matching primary key found for entity'" + name() + "' with attribute'" + name + "'"); } result = primaryKeyAttributes().objectAtIndex(neededIndex); } return result; } /** * @see com.webobjects.eoaccess.EOEntity#hasExternalName() * @since 5.4.1 */ @Override public boolean hasExternalName() { // (ldeck) radar://6592526 fix for 5.4.3 regression which assumed that any parent entity that is abstract has no external name! return externalName() != null && externalName().trim().length() > 0; } /** * Sets the class description for the instance. * * @param classDescription - the EOClassDescription to associate with the receiver. */ public void setClassDescription(EOClassDescription classDescription) { _classDescription = classDescription; } /** * Overridden through our bottleneck. */ @Override protected EOKeyGlobalID _globalIDWithoutTypeCoercion(Object[] values) { return ERXSingleValueID.globalIDWithEntityName(name(), values); } public NSArray<EOAttribute> classAttributes() { NSMutableArray<EOAttribute> found = new NSMutableArray<>(); for (String name : (NSArray<String>)this.classPropertyNames()) { if (this.attributeNamed(name) != null) found.add(this.attributeNamed(name)); } return found.immutableClone(); } public NSArray<EORelationship> classRelationships() { NSMutableArray<EORelationship> found = new NSMutableArray<>(); for (String name : (NSArray<String>)this.classPropertyNames()) { if (this.relationshipNamed(name) != null) found.add(this.relationshipNamed(name)); } return found.immutableClone(); } }