diff --git a/framework/default/ortoo-core/default/classes/fflib-extension/ortoo_AppLogicFactory.cls b/framework/default/ortoo-core/default/classes/fflib-extension/ortoo_AppLogicFactory.cls index 1567378eb4e..98c4d92f40c 100644 --- a/framework/default/ortoo-core/default/classes/fflib-extension/ortoo_AppLogicFactory.cls +++ b/framework/default/ortoo-core/default/classes/fflib-extension/ortoo_AppLogicFactory.cls @@ -15,18 +15,19 @@ public inherited sharing class ortoo_AppLogicFactory // NOPMD: specified a mi */ public ortoo_AppLogicFactory() { - this( new Map() ); + this( new Map() ); } /** * Construct an instance using the given type to implementation mapping * - * @param Map The Type to Implementation mapping + * @param Map The Type to Implementation mapping */ - public ortoo_AppLogicFactory( Map appLogicPerType ) + public ortoo_AppLogicFactory( Map appLogicPerType ) { Contract.requires( appLogicPerType != null, 'ortoo_AppLogicFactory instantiated with a null appLogicPerType' ); - factory = new ortoo_SimpleObjectFactory( appLogicPerType ) + + factory = new ortoo_SimpleObjectFactory( appLogicPerType ) .setTypeName( 'App Logic' ) .setErrorOnUnmappedType( false ); } diff --git a/framework/default/ortoo-core/default/classes/fflib-extension/ortoo_ChildRecordFinderFactory.cls b/framework/default/ortoo-core/default/classes/fflib-extension/ortoo_ChildRecordFinderFactory.cls index 35022cd7dd8..9455b491236 100644 --- a/framework/default/ortoo-core/default/classes/fflib-extension/ortoo_ChildRecordFinderFactory.cls +++ b/framework/default/ortoo-core/default/classes/fflib-extension/ortoo_ChildRecordFinderFactory.cls @@ -15,19 +15,18 @@ public inherited sharing class ortoo_ChildRecordFinderFactory // NOPMD: speci */ public ortoo_ChildRecordFinderFactory() { - this( new Map() ); + this( new Map() ); } /** * Construct an instance using the given type to implementation mapping * - * @param Map The Type to Implementation mapping + * @param Map The Type to Implementation mapping */ - public ortoo_ChildRecordFinderFactory( Map childRecordFinderPerType ) + public ortoo_ChildRecordFinderFactory( Map childRecordFinderPerType ) { Contract.requires( childRecordFinderPerType != null, 'ortoo_ChildRecordFinderFactory instantiated with a null childRecordFinderPerType' ); - factory = new ortoo_SimpleObjectFactory( childRecordFinderPerType ) .setTypeName( 'Child Finder' ) .setErrorOnUnmappedType( false ); diff --git a/framework/default/ortoo-core/default/classes/fflib-extension/ortoo_MessageRendererFactory.cls b/framework/default/ortoo-core/default/classes/fflib-extension/ortoo_MessageRendererFactory.cls index 903a445ecc7..99dd9e1077a 100644 --- a/framework/default/ortoo-core/default/classes/fflib-extension/ortoo_MessageRendererFactory.cls +++ b/framework/default/ortoo-core/default/classes/fflib-extension/ortoo_MessageRendererFactory.cls @@ -15,18 +15,19 @@ public inherited sharing class ortoo_MessageRendererFactory // NOPMD: specifi */ public ortoo_MessageRendererFactory() { - this( new Map() ); + this( new Map() ); } /** * Construct an instance using the given type to implementation mapping * - * @param Map The Type to Implementation mapping + * @param Map The Type to Implementation mapping */ - public ortoo_MessageRendererFactory( Map implementationPerType ) + public ortoo_MessageRendererFactory( Map implementationPerType ) { Contract.requires( implementationPerType != null, 'ortoo_MessageRendererFactory instantiated with a null implementationPerType' ); - factory = new ortoo_SimpleObjectFactory( implementationPerType ) + + factory = new ortoo_SimpleObjectFactory( implementationPerType ) .setTypeName( 'Message Renderer' ) .setErrorOnUnmappedType( false ); } @@ -50,7 +51,7 @@ public inherited sharing class ortoo_MessageRendererFactory // NOPMD: specifi } catch ( TypeException e ) { - throw new Exceptions.DeveloperException( 'Implementation registered for Message Renderer ' + requestedType + ' does not implement MessageRendererEngine.IMessageRenderer', e ) + throw new Exceptions.DeveloperException( 'Implementation registered for Message Renderer ' + requestedType + ' ('+ ObjectUtils.getClassName( rawRenderer ) +') does not implement MessageRendererEngine.IMessageRenderer', e ) .setErrorCode( FrameworkErrorCodes.MR_IMPLEMENTATION_IS_NOT_MR ) .addContext( 'requestedType', requestedType ); } diff --git a/framework/default/ortoo-core/default/classes/fflib-extension/ortoo_SimpleObjectFactory.cls b/framework/default/ortoo-core/default/classes/fflib-extension/ortoo_SimpleObjectFactory.cls index 2172c8bf3ef..9ad14973070 100644 --- a/framework/default/ortoo-core/default/classes/fflib-extension/ortoo_SimpleObjectFactory.cls +++ b/framework/default/ortoo-core/default/classes/fflib-extension/ortoo_SimpleObjectFactory.cls @@ -93,7 +93,7 @@ public inherited sharing class ortoo_SimpleObjectFactory // NOPMD: specified return mockByType.get( requestedType ); } - String requestedTypeName = requestedType.getName(); + String requestedTypeName = ObjectUtils.stripLocalNamespace( requestedType.getName() ); if ( errorOnUnmappedType && ! implementationByType.containsKey( requestedType ) && ! implementationNameByTypeName.containsKey( requestedTypeName ) ) { @@ -110,10 +110,11 @@ public inherited sharing class ortoo_SimpleObjectFactory // NOPMD: specified } else if ( implementationNameByTypeName.containsKey( requestedTypeName ) ) { - typeToConstruct = Type.forName( implementationNameByTypeName.get( requestedTypeName ) ); + String typeToConstructName = implementationNameByTypeName.get( requestedTypeName ); + typeToConstruct = Type.forName( typeToConstructName ); if ( typeToConstruct == null ) { - throw new Exceptions.DeveloperException( 'Invalid implementation registered for ' + typeName + ' ' + requestedTypeName + ': The class does not exist, or is not visible' ) + throw new Exceptions.DeveloperException( 'Invalid implementation registered for ' + typeName + ' ' + requestedTypeName + ': ' + typeToConstructName + ' does not exist, or is not visible' ) .setErrorCode( FrameworkErrorCodes.FACTORY_INVALID_IMPLEMENTATION_REGISTERED ) .addContext( 'typeName', typeName ) .addContext( 'requestedType', requestedType ); @@ -128,7 +129,7 @@ public inherited sharing class ortoo_SimpleObjectFactory // NOPMD: specified } catch ( Exception e ) { - throw new Exceptions.DeveloperException( 'Implementation registered for ' + typeName + ' ' + requestedType + ':' + typeToConstruct + ' does not have parameterless constructor', e ) + throw new Exceptions.DeveloperException( 'Implementation registered for ' + typeName + ' ' + requestedType + ':' + typeToConstruct + ' does not have parameterless constructor or cannot be constructed', e ) .setErrorCode( FrameworkErrorCodes.FACTORY_NO_PARAMETERLESS_CONSTRUCTOR ) .addContext( 'typeName', typeName ) .addContext( 'requestedType', requestedType ) diff --git a/framework/default/ortoo-core/default/classes/fflib-extension/tests/ortoo_AppLogicFactoryTest.cls b/framework/default/ortoo-core/default/classes/fflib-extension/tests/ortoo_AppLogicFactoryTest.cls index be2f4b22499..125d429ac54 100644 --- a/framework/default/ortoo-core/default/classes/fflib-extension/tests/ortoo_AppLogicFactoryTest.cls +++ b/framework/default/ortoo-core/default/classes/fflib-extension/tests/ortoo_AppLogicFactoryTest.cls @@ -18,14 +18,14 @@ private without sharing class ortoo_AppLogicFactoryTest private static void newInstance_whenMappingsAreDefined_willReturnTheMappedType() // NOPMD: Test method name format { ortoo_AppLogicFactory factory = new ortoo_AppLogicFactory( - new Map + new Map { - Object.class => RegisterableType.class + 'ortoo_AppLogicFactoryTest.ClassToRetrieveVia' => 'ortoo_AppLogicFactoryTest.RegisterableType' } ); Test.startTest(); - Object returnedInstance = factory.newInstance( Object.class ); + Object returnedInstance = factory.newInstance( ClassToRetrieveVia.class ); Test.stopTest(); System.assertNotEquals( null, returnedInstance, 'newInstance, when mappings are defined and a mapped type is mapped, will return an instantiated object' ); @@ -40,8 +40,8 @@ private without sharing class ortoo_AppLogicFactoryTest RegisterableType mockInstance = new RegisterableType( 'mockone' ); Test.startTest(); - factory.setMock( Object.class, mockInstance ); - Object returnedInstance = factory.newInstance( Object.class ); + factory.setMock( ClassToRetrieveVia.class, mockInstance ); + Object returnedInstance = factory.newInstance( ClassToRetrieveVia.class ); Test.stopTest(); System.assertEquals( mockInstance, returnedInstance, 'newInstance, when called for a type that has a mock set, will return the registered mock' ); @@ -85,7 +85,9 @@ private without sharing class ortoo_AppLogicFactoryTest ortoo_Asserts.assertContains( 'ortoo_AppLogicFactory instantiated with a null appLogicPerType', exceptionMessage, 'constructor, when called with null, will throw an exception' ); } - private without sharing class RegisterableType + public without sharing class ClassToRetrieveVia {} + + public without sharing class RegisterableType { String name; public RegisterableType() diff --git a/framework/default/ortoo-core/default/classes/fflib-extension/tests/ortoo_ChildRecordFinderFactoryTest.cls b/framework/default/ortoo-core/default/classes/fflib-extension/tests/ortoo_ChildRecordFinderFactoryTest.cls index 8135bb83632..75b867bd50a 100644 --- a/framework/default/ortoo-core/default/classes/fflib-extension/tests/ortoo_ChildRecordFinderFactoryTest.cls +++ b/framework/default/ortoo-core/default/classes/fflib-extension/tests/ortoo_ChildRecordFinderFactoryTest.cls @@ -18,14 +18,14 @@ private without sharing class ortoo_ChildRecordFinderFactoryTest private static void newInstance_whenMappingsAreDefined_willReturnTheMappedType() // NOPMD: Test method name format { ortoo_ChildRecordFinderFactory factory = new ortoo_ChildRecordFinderFactory( - new Map + new Map { - Object.class => RegisterableType.class + 'ortoo_ChildRecordFinderFactoryTest.ClassToRetrieveVia' => 'ortoo_ChildRecordFinderFactoryTest.RegisterableType' } ); Test.startTest(); - IChildRecordFinder returnedInstance = factory.newInstance( Object.class ); + IChildRecordFinder returnedInstance = factory.newInstance( ClassToRetrieveVia.class ); Test.stopTest(); System.assertNotEquals( null, returnedInstance, 'newInstance, when mappings are defined and a mapped type is mapped, will return an instantiated object' ); @@ -40,8 +40,8 @@ private without sharing class ortoo_ChildRecordFinderFactoryTest RegisterableType mockInstance = new RegisterableType( 'mockone' ); Test.startTest(); - factory.setMock( Object.class, mockInstance ); - IChildRecordFinder returnedInstance = factory.newInstance( Object.class ); + factory.setMock( ClassToRetrieveVia.class, mockInstance ); + IChildRecordFinder returnedInstance = factory.newInstance( ClassToRetrieveVia.class ); Test.stopTest(); System.assertEquals( mockInstance, returnedInstance, 'newInstance, when called for a type that has a mock set, will return the registered mock' ); @@ -71,9 +71,9 @@ private without sharing class ortoo_ChildRecordFinderFactoryTest private static void newInstance_whenCalledForAnMappedTypeThatIsNotAChildFinder_willThrowAnException() // NOPMD: Test method name format { ortoo_ChildRecordFinderFactory factory = new ortoo_ChildRecordFinderFactory( - new Map + new Map { - Object.class => NonRegisterableType.class + 'Object' => 'ortoo_ChildRecordFinderFactoryTest.NonRegisterableType' } ); @@ -130,7 +130,9 @@ private without sharing class ortoo_ChildRecordFinderFactoryTest ortoo_Asserts.assertContains( 'ortoo_ChildRecordFinderFactory instantiated with a null childRecordFinderPerType', exceptionMessage, 'constructor, when called with null, will throw an exception' ); } - private without sharing class RegisterableType implements IChildRecordFinder + public without sharing class ClassToRetrieveVia {} + + public without sharing class RegisterableType implements IChildRecordFinder { String name; public RegisterableType() @@ -149,5 +151,5 @@ private without sharing class ortoo_ChildRecordFinderFactoryTest } } - private without sharing class NonRegisterableType {} + public without sharing class NonRegisterableType {} } \ No newline at end of file diff --git a/framework/default/ortoo-core/default/classes/fflib-extension/tests/ortoo_MessageRendererFactoryTest.cls b/framework/default/ortoo-core/default/classes/fflib-extension/tests/ortoo_MessageRendererFactoryTest.cls index 12d8ab52485..40545a20eba 100644 --- a/framework/default/ortoo-core/default/classes/fflib-extension/tests/ortoo_MessageRendererFactoryTest.cls +++ b/framework/default/ortoo-core/default/classes/fflib-extension/tests/ortoo_MessageRendererFactoryTest.cls @@ -25,14 +25,14 @@ private without sharing class ortoo_MessageRendererFactoryTest IRenderableMessageHeader message = (IRenderableMessageHeader)messageController.generateDouble(); ortoo_MessageRendererFactory factory = new ortoo_MessageRendererFactory( - new Map + new Map { - Object.class => RegisterableType.class + 'ortoo_MessageRendererFactoryTest.ClassToRetrieveVia' => 'ortoo_MessageRendererFactoryTest.RegisterableType' } ); Test.startTest(); - MessageRendererEngine returnedInstance = factory.newInstance( Object.class, message ); + MessageRendererEngine returnedInstance = factory.newInstance( ClassToRetrieveVia.class, message ); Test.stopTest(); System.assertNotEquals( null, returnedInstance, 'newInstance, when mappings are defined and a mapped type is passed, will return an instantiated object' ); @@ -95,9 +95,9 @@ private without sharing class ortoo_MessageRendererFactoryTest IRenderableMessageHeader message = (IRenderableMessageHeader)messageController.generateDouble(); ortoo_MessageRendererFactory factory = new ortoo_MessageRendererFactory( - new Map + new Map { - Object.class => NonRegisterableType.class + 'ortoo_MessageRendererFactoryTest.ClassToRetrieveVia' => 'ortoo_MessageRendererFactoryTest.NonRegisterableType' } ); @@ -105,7 +105,7 @@ private without sharing class ortoo_MessageRendererFactoryTest String exceptionMessage; try { - factory.newInstance( Object.class, message ); + factory.newInstance( ClassToRetrieveVia.class, message ); } catch ( Exception e ) { @@ -113,7 +113,7 @@ private without sharing class ortoo_MessageRendererFactoryTest } Test.stopTest(); - ortoo_Asserts.assertContains( 'Object does not implement MessageRendererEngine.IMessageRenderer', exceptionMessage, 'newInstance, when called for a mapped type that does not implement IMessageRenderer, will throw an exception' ); + ortoo_Asserts.assertContains( 'NonRegisterableType) does not implement MessageRendererEngine.IMessageRenderer', exceptionMessage, 'newInstance, when called for a mapped type that does not implement IMessageRenderer, will throw an exception' ); } @isTest @@ -179,7 +179,9 @@ private without sharing class ortoo_MessageRendererFactoryTest ortoo_Asserts.assertContains( 'ortoo_MessageRendererFactory instantiated with a null implementationPerType', exceptionMessage, 'constructor, when called with null, will throw an exception' ); } - private without sharing class RegisterableType implements IMessageRenderer + public without sharing class ClassToRetrieveVia {} + + public without sharing class RegisterableType implements IMessageRenderer { public Boolean render( IRenderableMessageHeader message ) { @@ -187,5 +189,5 @@ private without sharing class ortoo_MessageRendererFactoryTest } } - private without sharing class NonRegisterableType {} + public without sharing class NonRegisterableType {} } \ No newline at end of file diff --git a/framework/default/ortoo-core/default/classes/fflib-extension/tests/ortoo_SimpleObjectFactoryTest.cls b/framework/default/ortoo-core/default/classes/fflib-extension/tests/ortoo_SimpleObjectFactoryTest.cls index 6b884bb69be..7aa3f4fc922 100644 --- a/framework/default/ortoo-core/default/classes/fflib-extension/tests/ortoo_SimpleObjectFactoryTest.cls +++ b/framework/default/ortoo-core/default/classes/fflib-extension/tests/ortoo_SimpleObjectFactoryTest.cls @@ -8,13 +8,13 @@ private without sharing class ortoo_SimpleObjectFactoryTest private static void newInstance_whenCalledWithARegisteredTypeViaType_willReturnTheMappedType() // NOPMD: Test method name format { Map implementationByType = new Map{ - Object.class => RegisterableType.class + ClassToRetrieveVia.class => RegisterableType.class }; ortoo_SimpleObjectFactory factory = new ortoo_SimpleObjectFactory( implementationByType ); Test.startTest(); - Object returnedInstance = factory.newInstance( Object.class ); + Object returnedInstance = factory.newInstance( ClassToRetrieveVia.class ); Test.stopTest(); System.assertNotEquals( null, returnedInstance, 'newInstance, when called with a registered type, will return an instance' ); @@ -25,13 +25,13 @@ private without sharing class ortoo_SimpleObjectFactoryTest private static void newInstance_whenCalledWithARegisteredTypeViaString_willReturnTheMappedType() // NOPMD: Test method name format { Map implementationNameByTypeName = new Map{ - 'Object' => 'ortoo_SimpleObjectFactoryTest.RegisterableType' + 'ortoo_SimpleObjectFactoryTest.ClassToRetrieveVia' => 'ortoo_SimpleObjectFactoryTest.RegisterableType' }; ortoo_SimpleObjectFactory factory = new ortoo_SimpleObjectFactory( implementationNameByTypeName ); Test.startTest(); - Object returnedInstance = factory.newInstance( Object.class ); + Object returnedInstance = factory.newInstance( ClassToRetrieveVia.class ); Test.stopTest(); System.assertNotEquals( null, returnedInstance, 'newInstance, when called with a registered type, will return an instance' ); @@ -43,7 +43,7 @@ private without sharing class ortoo_SimpleObjectFactoryTest { Map implementationByType = new Map{ - Object.class => NonConstructableType.class + ClassToRetrieveVia.class => NonConstructableType.class }; ortoo_SimpleObjectFactory factory = new ortoo_SimpleObjectFactory( implementationByType ); @@ -52,7 +52,7 @@ private without sharing class ortoo_SimpleObjectFactoryTest String exceptionMessage; try { - factory.newInstance( Object.class ); + factory.newInstance( ClassToRetrieveVia.class ); } catch ( Exceptions.DeveloperException e ) { @@ -66,9 +66,8 @@ private without sharing class ortoo_SimpleObjectFactoryTest @isTest private static void newInstance_whenCalledWithATypeViaStringThatCannotBeConstructed_throwsException() // NOPMD: Test method name format { - Map implementationNameByTypeName = new Map{ - 'Object' => 'ortoo_SimpleObjectFactoryTest.NonConstructableType' + 'ortoo_SimpleObjectFactoryTest.ClassToRetrieveVia' => 'ortoo_SimpleObjectFactoryTest.NonConstructableType' }; ortoo_SimpleObjectFactory factory = new ortoo_SimpleObjectFactory( implementationNameByTypeName ); @@ -77,7 +76,7 @@ private without sharing class ortoo_SimpleObjectFactoryTest String exceptionMessage; try { - factory.newInstance( Object.class ); + factory.newInstance( ClassToRetrieveVia.class ); } catch ( Exceptions.DeveloperException e ) { @@ -93,7 +92,7 @@ private without sharing class ortoo_SimpleObjectFactoryTest { Map implementationNameByTypeName = new Map{ - 'Object' => 'NotAValidClass' + 'ortoo_SimpleObjectFactoryTest.ClassToRetrieveVia' => 'NotAValidClass' }; ortoo_SimpleObjectFactory factory = new ortoo_SimpleObjectFactory( implementationNameByTypeName ); @@ -102,7 +101,7 @@ private without sharing class ortoo_SimpleObjectFactoryTest String exceptionMessage; try { - factory.newInstance( Object.class ); + factory.newInstance( ClassToRetrieveVia.class ); } catch ( Exceptions.DeveloperException e ) { @@ -110,7 +109,7 @@ private without sharing class ortoo_SimpleObjectFactoryTest } Test.stopTest(); - ortoo_Asserts.assertContains( 'Invalid implementation registered for Unknown Object: The class does not exist, or is not visible', exceptionMessage, 'newInstance, when called with a type that has an invalid type, will throw an exception' ); + ortoo_Asserts.assertContains( 'Invalid implementation registered for Unknown ortoo_SimpleObjectFactoryTest.ClassToRetrieveVia: NotAValidClass does not exist, or is not visible', exceptionMessage, 'newInstance, when called with a type that has an invalid type, will throw an exception' ); } @isTest @@ -145,7 +144,7 @@ private without sharing class ortoo_SimpleObjectFactoryTest private static void newInstance_whenSetToAllowUnmappedAndCalledWithAnUnmappedViaType_willReturnAnInstance() // NOPMD: Test method name format { Map implementationByType = new Map{ - Object.class => Object.class + ClassToRetrieveVia.class => ClassToRetrieveVia.class }; ortoo_SimpleObjectFactory factory = new ortoo_SimpleObjectFactory( implementationByType ); @@ -163,7 +162,7 @@ private without sharing class ortoo_SimpleObjectFactoryTest private static void newInstance_whenSetToAllowUnmappedAndCalledWithAnUnmappedViaString_willReturnAnInstance() // NOPMD: Test method name format { Map implementationNameByTypeName = new Map{ - 'Unknown' => 'Unknown' + 'ortoo_SimpleObjectFactoryTest.ClassToRetrieveVia' => 'ortoo_SimpleObjectFactoryTest.ClassToRetrieveVia' }; ortoo_SimpleObjectFactory factory = new ortoo_SimpleObjectFactory( implementationNameByTypeName ); @@ -413,6 +412,8 @@ private without sharing class ortoo_SimpleObjectFactoryTest ortoo_Asserts.assertContains( 'ortoo_SimpleObjectFactory instantiated with a null implementationNameByTypeName', exceptionMessage, 'constructor with types, when called with null, will throw an exception' ); } + public without sharing class ClassToRetrieveVia {} + public without sharing class RegisterableType { String name; diff --git a/framework/default/ortoo-core/default/classes/utils/ObjectUtils.cls b/framework/default/ortoo-core/default/classes/utils/ObjectUtils.cls index 4f2adf17b03..c1f1f2ddd32 100644 --- a/framework/default/ortoo-core/default/classes/utils/ObjectUtils.cls +++ b/framework/default/ortoo-core/default/classes/utils/ObjectUtils.cls @@ -86,4 +86,17 @@ public inherited sharing class ObjectUtils return returnType; } + + // TODO: test + // TODO: document + public static String stripLocalNamespace( String className ) + { + Contract.requires( String.isNotBlank( className ), 'stripLocalNamespace called with a blank className' ); + + if ( className.startsWithIgnoreCase( PackageUtils.NAMESPACE_PREFIX + '.' ) ) + { + return className.substringAfter( PackageUtils.NAMESPACE_PREFIX + '.' ); + } + return className; + } } \ No newline at end of file