From: Jonathan B. L. <le...@ma...> - 2006-02-08 20:58:49
|
On Feb 8, 2006, at 12:04 PM, Kieran Kelleher wrote: > OK, I've been looking at the EOEnterpriseObjectClazz in > ERExtensions and I think (hope) I have my brain wrapped around this > pretty cool design pattern properly so I can take advantage of the > objectCount methods.... > > Help me see if I understand the source/usage correctly ..... > > ...if I have a EOEntity named CTProduct, the inner class would be > declared like this ?.... > > public static class CTProductClazz extends > EOEnterpriseObjectClazz { > > } Correct. The class must be called <entity name>Clazz and can extend EOEnterpriseObjectClazz or ERXGenericRecordClazz or any other clazz class in the hierarchy. > ..... and if I declare no inner class, I get a default CTProduct > specific instance of ERXGenericRecord.ERXGenericRecordClazz which > gives me the usage of all the root class methods in the context of > the entity? ...... Mostly. When you call clazzForEntityNamed("CTProduct"), you end up eventually in classFromEntity on EOEnterpriseObjectClazz: private static EOEnterpriseObjectClazz classFromEntity(EOEntity entity) { EOEnterpriseObjectClazz clazz = null; if(entity == null) { return new EOEnterpriseObjectClazz(); } try { String className = entity.className(); if(className.equals("ERXGenericRecord")) clazz = new ERXGenericRecord.ERXGenericRecordClazz(); else clazz = (EOEnterpriseObjectClazz)Class.forName (className + "$" + entity.name() + "Clazz").newInstance(); } catch (InstantiationException ex) { } catch (ClassNotFoundException ex) { } catch (IllegalAccessException ex) { } if(clazz == null) return classFromEntity(entity.parentEntity ()); return clazz; } If it doesn't find the class, you'll recursively call with the parent entity which, unless you're using entity inheritance, will be null, so you'll end up with an instance of EOEnterpriseObjectClazz not ERXGenericRecordClazz. It always struck me as a bit odd that classFromEntity walked the entity-inheritance lineage instead of the class-inheritance lineage, but that's the way it works. > .... and I can use it something like this if I want in an entity > (or even in my generic subclass of ERXGenericRecord)? ..... > > public EOEnterpriseObjectClazz clazz() { > return EOEnterpriseObjectClazz.clazzForEntityNamed > ( this.entityName() ); > } Correct. And then you effectively have polymorphic static methods (in Obj-C speak, the equivalent of [[self class] myMethod]). One limitation is that the API on your clazzes is somewhat fixed (unless you're willing to cast) because the methods are typed as EOEnterpriseObjectClazz. There are some workarounds, of course, such as declaring a subclass of EOEnterpriseObjectClazz for yourself and introducing new API that returns objects typed to that type. -jbl |