Skip to content

Commit 83ac48b

Browse files
Merge pull request #300 from wimvelzeboer/feature/DomainStructure
Add new Domain structure
2 parents ecaeb12 + 52fd335 commit 83ac48b

21 files changed

+1260
-106
lines changed

sfdx-source/apex-common/main/classes/fflib_Application.cls

Lines changed: 79 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -272,9 +272,26 @@ public virtual class fflib_Application
272272
{
273273
protected fflib_Application.SelectorFactory m_selectorFactory;
274274

275-
protected Map<SObjectType, Type> m_sObjectByDomainConstructorType;
275+
protected Map<Object, Type> constructorTypeByObject;
276276

277-
protected Map<SObjectType, fflib_ISObjectDomain> m_sObjectByMockDomain;
277+
protected Map<Object, fflib_IDomain> mockDomainByObject;
278+
279+
/**
280+
* Constructs a Domain factory, using an instance of the Selector Factory
281+
* and a map of Apex classes implementing fflib_ISObjectDomain by SObjectType
282+
* Note this will not check the Apex classes provided actually implement the interfaces
283+
* since this is not possible in the Apex runtime at present
284+
*
285+
* @param selectorFactory , e.g. Application.Selector
286+
* @param constructorTypeByObject Map of Domain classes by ObjectType
287+
**/
288+
public DomainFactory(fflib_Application.SelectorFactory selectorFactory,
289+
Map<Object, Type> constructorTypeByObject)
290+
{
291+
m_selectorFactory = selectorFactory;
292+
this.constructorTypeByObject = constructorTypeByObject;
293+
this.mockDomainByObject = new Map<Object, fflib_IDomain>();
294+
}
278295

279296
/**
280297
* Constructs a Domain factory, using an instance of the Selector Factory
@@ -289,9 +306,9 @@ public virtual class fflib_Application
289306
Map<SObjectType, Type> sObjectByDomainConstructorType)
290307
{
291308
m_selectorFactory = selectorFactory;
292-
m_sObjectByDomainConstructorType = sObjectByDomainConstructorType;
293-
m_sObjectByMockDomain = new Map<SObjectType, fflib_ISObjectDomain>();
294-
}
309+
this.constructorTypeByObject = getConstructorTypeByObject(sObjectByDomainConstructorType);
310+
this.mockDomainByObject = new Map<Object, fflib_IDomain>();
311+
}
295312

296313
/**
297314
* Dynamically constructs an instance of a Domain class for the given record Ids
@@ -301,40 +318,60 @@ public virtual class fflib_Application
301318
* @param recordIds A list of Id's of the same type
302319
* @exception Throws an exception via the Selector Factory if the Ids are not all of the same SObjectType
303320
**/
304-
public virtual fflib_ISObjectDomain newInstance(Set<Id> recordIds)
321+
public virtual fflib_IDomain newInstance(Set<Id> recordIds)
305322
{
306323
return newInstance(m_selectorFactory.selectById(recordIds));
307324

308-
}
325+
}
309326

310327
/**
311328
* Dynamically constructs an instance of the Domain class for the given records
312329
* Will return a Mock implementation if one has been provided via setMock
313330
*
314331
* @param records A concrete list (e.g. List<Account> vs List<SObject>) of records
315-
* @exception Throws an exception if the SObjectType cannot be determined from the list
332+
* @exception Throws an exception if the SObjectType cannot be determined from the list
316333
* or the constructor for Domain class was not registered for the SObjectType
317334
**/
318-
public virtual fflib_ISObjectDomain newInstance(List<SObject> records)
335+
public virtual fflib_IDomain newInstance(List<SObject> records)
319336
{
320337
SObjectType domainSObjectType = records.getSObjectType();
321338
if(domainSObjectType==null)
322339
throw new DeveloperException('Unable to determine SObjectType');
323340

341+
return newInstance((List<Object>) records, (Object) domainSObjectType);
342+
}
343+
344+
public virtual fflib_IDomain newInstance(List<Object> objects, Object objectType)
345+
{
324346
// Mock implementation?
325-
if(m_sObjectByMockDomain.containsKey(domainSObjectType))
326-
return m_sObjectByMockDomain.get(domainSObjectType);
347+
if (mockDomainByObject.containsKey(objectType))
348+
return mockDomainByObject.get(objectType);
327349

328350
// Determine SObjectType and Apex classes for Domain class
329-
Type domainConstructorClass = m_sObjectByDomainConstructorType.get(domainSObjectType);
351+
Type domainConstructorClass = constructorTypeByObject.get(objectType);
330352
if(domainConstructorClass==null)
331-
throw new DeveloperException('Domain constructor class not found for SObjectType ' + domainSObjectType);
353+
throw new DeveloperException('Domain constructor class not found for SObjectType ' + objectType);
332354

333355
// Construct Domain class passing in the queried records
334-
fflib_SObjectDomain.IConstructable domainConstructor =
335-
(fflib_SObjectDomain.IConstructable) domainConstructorClass.newInstance();
336-
return (fflib_ISObjectDomain) domainConstructor.construct(records);
337-
}
356+
Object domainConstructor = domainConstructorClass.newInstance();
357+
358+
// for backwards compatibility
359+
if (domainConstructor instanceof fflib_SObjectDomain.IConstructable2)
360+
{
361+
return (fflib_IDomain)
362+
((fflib_SObjectDomain.IConstructable2) domainConstructor)
363+
.construct((List<SObject>) objects, (SObjectType) objectType);
364+
}
365+
else if (domainConstructor instanceof fflib_SObjectDomain.IConstructable)
366+
{
367+
return (fflib_IDomain)
368+
((fflib_SObjectDomain.IConstructable) domainConstructor)
369+
.construct((List<SObject>) objects);
370+
}
371+
372+
return ((fflib_IDomainConstructor) domainConstructor)
373+
.construct(objects);
374+
}
338375

339376
/**
340377
* Dynamically constructs an instance of the Domain class for the given records and SObjectType
@@ -347,30 +384,40 @@ public virtual class fflib_Application
347384
* @remark Will support List<SObject> but all records in the list will be assumed to be of
348385
* the type specified in sObjectType
349386
**/
350-
public virtual fflib_ISObjectDomain newInstance(List<SObject> records, SObjectType domainSObjectType)
387+
public virtual fflib_IDomain newInstance(List<SObject> records, SObjectType domainSObjectType)
351388
{
352389
if(domainSObjectType==null)
353390
throw new DeveloperException('Must specify sObjectType');
354391

355-
// Mock implementation?
356-
if(m_sObjectByMockDomain.containsKey(domainSObjectType))
357-
return m_sObjectByMockDomain.get(domainSObjectType);
358-
359-
// Determine SObjectType and Apex classes for Domain class
360-
Type domainConstructorClass = m_sObjectByDomainConstructorType.get(domainSObjectType);
361-
if(domainConstructorClass==null)
362-
throw new DeveloperException('Domain constructor class not found for SObjectType ' + domainSObjectType);
363-
364-
// Construct Domain class passing in the queried records
365-
fflib_SObjectDomain.IConstructable2 domainConstructor =
366-
(fflib_SObjectDomain.IConstructable2) domainConstructorClass.newInstance();
367-
return (fflib_ISObjectDomain) domainConstructor.construct(records, domainSObjectType);
392+
return newInstance(
393+
(List<Object>) records,
394+
(Object) domainSObjectType
395+
);
368396
}
369397

370398
@TestVisible
371399
private virtual void setMock(fflib_ISObjectDomain mockDomain)
372400
{
373-
m_sObjectByMockDomain.put(mockDomain.sObjectType(), mockDomain);
401+
mockDomainByObject.put((Object) mockDomain.sObjectType(), (fflib_IDomain) mockDomain);
402+
}
403+
404+
@TestVisible
405+
private virtual void setMock(fflib_IDomain mockDomain)
406+
{
407+
mockDomainByObject.put(mockDomain.getType(), mockDomain);
408+
}
409+
410+
private Map<Object, Type> getConstructorTypeByObject(Map<SObjectType, Type> constructorTypeBySObjectType)
411+
{
412+
Map<Object, Type> result = new Map<Object, Type>();
413+
for (SObjectType sObjectType : constructorTypeBySObjectType.keySet())
414+
{
415+
result.put(
416+
(Object) sObjectType,
417+
constructorTypeBySObjectType.get(sObjectType)
418+
);
419+
}
420+
return result;
374421
}
375422
}
376423

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/**
2+
* Copyright (c), FinancialForce.com, inc
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without modification,
6+
* are permitted provided that the following conditions are met:
7+
*
8+
* - Redistributions of source code must retain the above copyright notice,
9+
* this list of conditions and the following disclaimer.
10+
* - Redistributions in binary form must reproduce the above copyright notice,
11+
* this list of conditions and the following disclaimer in the documentation
12+
* and/or other materials provided with the distribution.
13+
* - Neither the name of the FinancialForce.com, inc nor the names of its contributors
14+
* may be used to endorse or promote products derived from this software without
15+
* specific prior written permission.
16+
*
17+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19+
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
20+
* THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21+
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22+
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23+
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25+
**/
26+
public interface fflib_IDomain
27+
{
28+
Object getType();
29+
List<Object> getObjects();
30+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
3+
<apiVersion>51.0</apiVersion>
4+
<status>Active</status>
5+
</ApexClass>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/**
2+
* Copyright (c), FinancialForce.com, inc
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without modification,
6+
* are permitted provided that the following conditions are met:
7+
*
8+
* - Redistributions of source code must retain the above copyright notice,
9+
* this list of conditions and the following disclaimer.
10+
* - Redistributions in binary form must reproduce the above copyright notice,
11+
* this list of conditions and the following disclaimer in the documentation
12+
* and/or other materials provided with the distribution.
13+
* - Neither the name of the FinancialForce.com, inc nor the names of its contributors
14+
* may be used to endorse or promote products derived from this software without
15+
* specific prior written permission.
16+
*
17+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19+
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
20+
* THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21+
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22+
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23+
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25+
**/
26+
public interface fflib_IDomainConstructor
27+
{
28+
fflib_IDomain construct(List<Object> objects);
29+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
3+
<apiVersion>51.0</apiVersion>
4+
<status>Active</status>
5+
</ApexClass>
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/**
2+
* Copyright (c), FinancialForce.com, inc
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without modification,
6+
* are permitted provided that the following conditions are met:
7+
*
8+
* - Redistributions of source code must retain the above copyright notice,
9+
* this list of conditions and the following disclaimer.
10+
* - Redistributions in binary form must reproduce the above copyright notice,
11+
* this list of conditions and the following disclaimer in the documentation
12+
* and/or other materials provided with the distribution.
13+
* - Neither the name of the FinancialForce.com, inc nor the names of its contributors
14+
* may be used to endorse or promote products derived from this software without
15+
* specific prior written permission.
16+
*
17+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19+
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
20+
* THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21+
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22+
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23+
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25+
**/
26+
public interface fflib_IObjects extends fflib_IDomain
27+
{
28+
/**
29+
* @param value Values to check if they are part of the domain
30+
*
31+
* @return True if the provided value is part of the domain
32+
*/
33+
Boolean contains(Object value);
34+
35+
/**
36+
* @param values Values to check if they are part of the domain
37+
*
38+
* @return True if all the provided values are part of the domain
39+
*/
40+
Boolean containsAll(List<Object> values);
41+
42+
/**
43+
* @param values Values to check if they are part of the domain
44+
*
45+
* @return True if all the provided values are part of the domain
46+
*/
47+
Boolean containsAll(Set<Object> values);
48+
49+
/**
50+
* @param value Value to check if it is part of the domain
51+
*
52+
* @return True if the provided value is not part of the domain
53+
*/
54+
Boolean containsNot(Object value);
55+
56+
/**
57+
* @param values Values to check if they are part of the domain
58+
*
59+
* @return True if all the provided values are not part of the domain
60+
*/
61+
Boolean containsNot(List<Object> values);
62+
63+
/**
64+
* @param values Values to check if they are part of the domain
65+
*
66+
* @return True if all the provided values are not part of the domain
67+
*/
68+
Boolean containsNot(Set<Object> values);
69+
70+
/**
71+
* @return Returns True is the domain is empty
72+
*/
73+
Boolean isEmpty();
74+
75+
/**
76+
* @return Returns True is the domain has objects
77+
*/
78+
Boolean isNotEmpty();
79+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
3+
<apiVersion>51.0</apiVersion>
4+
<status>Active</status>
5+
</ApexClass>

sfdx-source/apex-common/main/classes/fflib_ISObjectDomain.cls

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2525
**/
2626

27-
public interface fflib_ISObjectDomain
27+
public interface fflib_ISObjectDomain extends fflib_IDomain
2828
{
2929
/**
3030
* Returns the SObjectType this Domain class represents
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/**
2+
* Copyright (c), FinancialForce.com, inc
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without modification,
6+
* are permitted provided that the following conditions are met:
7+
*
8+
* - Redistributions of source code must retain the above copyright notice,
9+
* this list of conditions and the following disclaimer.
10+
* - Redistributions in binary form must reproduce the above copyright notice,
11+
* this list of conditions and the following disclaimer in the documentation
12+
* and/or other materials provided with the distribution.
13+
* - Neither the name of the FinancialForce.com, inc nor the names of its contributors
14+
* may be used to endorse or promote products derived from this software without
15+
* specific prior written permission.
16+
*
17+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19+
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
20+
* THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21+
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22+
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23+
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25+
**/
26+
public interface fflib_ISObjects extends fflib_IObjects
27+
{
28+
/**
29+
* @return Return the SObject records contained in the domain
30+
*/
31+
List<SObject> getRecords();
32+
33+
/**
34+
* @return Return the SObject records ids contained in the domain
35+
*/
36+
Set<Id> getRecordIds();
37+
38+
/**
39+
* @return Return the SObjectType of the SObjects contained in the domain
40+
*/
41+
SObjectType getSObjectType();
42+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
3+
<apiVersion>51.0</apiVersion>
4+
<status>Active</status>
5+
</ApexClass>

0 commit comments

Comments
 (0)