function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
BGrimesBGrimes 

Generics in an Apex Class?

I'm working on some functionality that alters sharing rule on custom objects.  I'm looking to create general methods like:

CreateReadonlyShare(recordId, userId, object) where the calling code injects the object into the method.  Is is possible to create a generic in Apex?  I can't seem to find anything other than sObjects which might work here, but I'm still curious.

 

Thanks.

 

sfdcfoxsfdcfox

 

Check the docs under Dynamic Apex and Dynamic SOQL for full details. That being said, you would indeed use SObject to manipulate records whose data type is unknown until runtime. With your example method you'd like to create below, for example, you would do the following:
public void CreateReadOnlyShare(Id recordId, Id userId, String shareName,String parentField, String accessField) {
  SObject sobj = new SObject(shareName);
  sobj.set('UserOrGroupId',userId);
  sobj.set(parentField,recordId);
  sobj.set(accessField,'Read');
  insert sobj;
}

 

Check the docs under Dynamic Apex and Dynamic SOQL for full details. That being said, you would indeed use SObject to manipulate records whose data type is unknown until runtime. With your example method you'd like to create below, for example, you would do the following:

 

 

public void CreateReadOnlyShare(Id RecordId, Id UserId, String ObjectType)
{
  Sobject shareRecord;
  if(ObjectType.endsWith('__c')) {
    // CustomObject__Share
    shareRecord = new Sobject(ObjectType.substring(0,ObjectType.length()-4)+'Share');
    // Custom share always uses ParentId
    shareRecord.set('ParentId',RecordId);
    // Access level is always 'AccessLevel'
    shareRecord.set('AccessLevel','Read');
  }
  else {
    // AccountShare, OpportunityShare, etc
    shareRecord = new Sobject(ObjectType+'Share');
    // Always ObjectId, such as AccountId, OpportunityId
    shareRecord.set(ObjectType+'Id',RecordId);
    // Always ObjectAccessLevel, such as AccountAccessLevel, OpportunityAccessLevel
    shareRecord.set(ObjectType+'AccessLevel','Read');
  }
  shareRecord.set('UserOrGroupId',userId);
  insert shareRecord;
}

Of course, just like the API, if a given row already exists, it is treated as an update instead of an insert.