From f3d98b853b048d57dec26b9986b2b8617fe8b5c8 Mon Sep 17 00:00:00 2001 From: "Ricardo J. Parada" Date: Fri, 6 Apr 2012 14:47:00 -0400 Subject: [PATCH] Easy EOEditingContext subclassing via er.extensions.ERXEC.editingContextClassName Uses the value of the er.extensions.ERXEC.editingContextClassName property to get the name of the class to be instantiated and returned by ERXEC.DefaultFactory's _createEditingContext() core method. It should work with ERXObjectStoreCoordinatorPool which installs its own editing context factory which is an instance of MultiOSCFactory which uses the ERXEC factory setup initially to create editing contexts and which happens to be an ERXEC.DefaultFactory. --- .../Sources/er/extensions/eof/ERXEC.java | 76 ++++++++++++++++++- 1 file changed, 73 insertions(+), 3 deletions(-) diff --git a/Frameworks/Core/ERExtensions/Sources/er/extensions/eof/ERXEC.java b/Frameworks/Core/ERExtensions/Sources/er/extensions/eof/ERXEC.java index 8c39d718542..ca3cd6657b6 100644 --- a/Frameworks/Core/ERExtensions/Sources/er/extensions/eof/ERXEC.java +++ b/Frameworks/Core/ERExtensions/Sources/er/extensions/eof/ERXEC.java @@ -8,6 +8,8 @@ import java.io.PrintWriter; import java.io.StringWriter; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; import java.util.Collections; import java.util.Enumeration; import java.util.List; @@ -54,7 +56,10 @@ * interface and you would create a new EC by using: * ERXEC.newEditingContext() You can also install your own * Factory classes. It is recommended to subclass ERXEC.DefaultFactory and - * override _createEditingContext() + * override _createEditingContext() or use the + * er.extensions.ERXEC.editingContextClassName property to specify the name of the + * editing context class to be instantiated by ERXEC.DefaultFactory's + * _createEditingContext() core method. * * @property er.extensions.ERXEC.useSharedEditingContext * @property er.extensions.ERXEC.markOpenLocks @@ -64,6 +69,7 @@ * @property er.extensions.ERXEC.defaultAutomaticLockUnlock * @property er.extensions.ERXEC.defaultCoalesceAutoLocks * @property er.extensions.ERXEC.safeLocking + * @property er.extensions.ERXEC.editingContextClassName */ public class ERXEC extends EOEditingContext { @@ -157,6 +163,16 @@ public class ERXEC extends EOEditingContext { private static final NSSelector EditingContextDidRevertObjectsDelegateSelector = new NSSelector("editingContextDidRevertObjects", new Class[] { EOEditingContext.class, NSArray.class, NSArray.class, NSArray.class }); private static final NSSelector EditingContextDidFailSaveChangesDelegateSelector = new NSSelector("editingContextDidFailSaveChanges", new Class[] { EOEditingContext.class, EOGeneralAdaptorException.class }); + /** + * @return the value of the er.extensions.ERXEC.editingContextClassName property, which + * is the name of the editing context class instantiated by ERXEC.DefaultFactory's _createEditingContext() + * core method. It defaults to the name of the ERXEC class. + * + */ + public static String editingContextClassName() { + return ERXProperties.stringForKeyWithDefault("er.extensions.ERXEC.editingContextClassName", ERXEC.class.getName()); + } + /** * Returns the value of the er.extensions.ERXEC.safeLocking property, which is the * new catch-all setting that turns on all of the recommended locking settings. @@ -1632,12 +1648,66 @@ public EOEditingContext _newEditingContext(EOObjectStore objectStore, boolean va return ec; } + private Constructor _editingContextConstructor; + + /** + * @return The Constructor used by _createEditingContext() to create a new editing context by instantiating + * the class named ERXEC.editingContextClassName(). + */ + protected Constructor editingContextConstructor() { + if (_editingContextConstructor == null) { + Class editingContextClass; + try { + editingContextClass = Class.forName(ERXEC.editingContextClassName()); + } + catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + Class[] parameterTypes = new Class[] { EOObjectStore.class }; + try { + _editingContextConstructor = editingContextClass.getConstructor(parameterTypes); + } + catch (SecurityException e) { + throw new RuntimeException(e); + } + catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } + } + + return _editingContextConstructor; + } + /** * Actual EC creation bottleneck. Override this to return other - * subclasses. + * subclasses or use the er.extensions.ERXEC.editingContextClassName property to + * specify the name of your editing context class to be instantiated and returned by this method. + * + * @param parent The parent EOObjectStore for the editing context created and returned by this method + * @return The editing context created by this method */ protected EOEditingContext _createEditingContext(EOObjectStore parent) { - return new ERXEC(parent == null ? EOEditingContext.defaultParentObjectStore() : parent); + + EOObjectStore arg = (parent == null ? EOEditingContext.defaultParentObjectStore() : parent); + EOEditingContext editingContext; + + try { + editingContext = (EOEditingContext) editingContextConstructor().newInstance(arg); + } + catch (IllegalArgumentException e) { + throw new RuntimeException(e); + } + catch (InstantiationException e) { + throw new RuntimeException(e); + } + catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + catch (InvocationTargetException e) { + throw new RuntimeException(e); + } + + return editingContext; } public boolean useSharedEditingContext() {